diff --git a/CHANGELOG b/CHANGELOG index b13237360b..7d647cc527 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +* Update Stripe Customer +* Add preferred locales to Customer + Version 5.8.0 - 2020-11-02 * Bug fixes (see mercurial logs for details) * Remove support for Python 3.5 diff --git a/party.py b/party.py index 9dd800813e..ea0d6aee4b 100644 --- a/party.py +++ b/party.py @@ -1,6 +1,6 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. -from trytond.pool import PoolMeta +from trytond.pool import PoolMeta, Pool from trytond.model import fields @@ -10,6 +10,24 @@ class Party(metaclass=PoolMeta): stripe_customers = fields.One2Many( 'account.payment.stripe.customer', 'party', "Stripe Customers") + @classmethod + def write(cls, *args): + pool = Pool() + Customer = pool.get('account.payment.stripe.customer') + + parties = sum(args[0:None:2], []) + customers = sum((p.stripe_customers for p in parties), ()) + customer2params = {c: c._customer_parameters() for c in customers} + + super().write(*args) + + to_update = [] + for customer, params in customer2params.items(): + if customer._customer_parameters() != params: + to_update.append(customer) + if to_update: + Customer.__queue__.stripe_update(to_update) + class Replace(metaclass=PoolMeta): __name__ = 'party.replace' diff --git a/payment.py b/payment.py index 92b9366db4..b39002ee6a 100644 --- a/payment.py +++ b/payment.py @@ -1522,9 +1522,8 @@ class Customer(CheckoutMixin, DeactivableMixin, ModelSQL, ModelView): try: cu = stripe.Customer.create( api_key=customer.stripe_account.secret_key, - description=customer.rec_name, - email=customer.party.email, - source=customer.stripe_token) + source=customer.stripe_token, + **customer._customer_parameters()) except (stripe.error.RateLimitError, stripe.error.APIConnectionError) as e: logger.warning(str(e)) @@ -1549,6 +1548,36 @@ class Customer(CheckoutMixin, DeactivableMixin, ModelSQL, ModelView): customer.save() Transaction().commit() + def _customer_parameters(self): + locales = [pl.lang.code for pl in self.party.langs if pl.lang] + return { + 'email': self.party.email, + 'name': self.party.name, + 'phone': self.party.phone, + 'preferred_locales': locales, + } + + @classmethod + def stripe_update(cls, customers): + for customer in customers: + try: + stripe.Customer.modify( + customer.stripe_customer_id, + api_key=customer.stripe_account.secret_key, + **customer._customer_parameters() + ) + except (stripe.error.RateLimitError, + stripe.error.APIConnectionError) as e: + logger.warning(str(e)) + except Exception as e: + if (isinstance(e, stripe.error.StripeError) + and e.code in RETRY_CODES): + logger.warning(str(e)) + else: + logger.error( + "Error when updating customer %d", customer.id, + exc_info=True) + @classmethod def stripe_delete(cls, customers=None): """Delete customer @@ -1731,9 +1760,8 @@ class Customer(CheckoutMixin, DeactivableMixin, ModelSQL, ModelView): else: cu = stripe.Customer.create( api_key=customer.stripe_account.secret_key, - description=customer.rec_name, - email=customer.party.email, - payment_method=setup_intent.payment_method) + payment_method=setup_intent.payment_method, + **customer._customer_parameters()) customer.stripe_customer_id = cu.id except (stripe.error.RateLimitError, stripe.error.APIConnectionError) as e: diff --git a/tests/scenario_account_payment_stripe.rst b/tests/scenario_account_payment_stripe.rst index 8ed2b045e8..5778b59d40 100644 --- a/tests/scenario_account_payment_stripe.rst +++ b/tests/scenario_account_payment_stripe.rst @@ -73,7 +73,9 @@ Create payment journal:: Create party:: >>> Party = Model.get('party.party') + >>> Lang = Model.get('ir.lang') >>> customer = Party(name='Customer') + >>> customer.lang, = Lang.find([('code', '=', 'en')]) >>> customer.save() Create approved payment:: @@ -195,6 +197,19 @@ Run cron:: >>> bool(stripe_customer.stripe_customer_id) True +Update customer:: + + >>> contact = customer.contact_mechanisms.new() + >>> contact.type = 'email' + >>> contact.value = 'customer@example.com' + >>> customer.save() + + >>> cus = stripe.Customer.retrieve(stripe_customer.stripe_customer_id) + >>> cus.email + 'customer@example.com' + >>> cus.preferred_locales + ['en'] + Make payment with customer:: >>> payment, = payment.duplicate()