changeset 9a412a372f78 in modules/account_payment_stripe:default
details: 
https://hg.tryton.org/modules/account_payment_stripe?cmd=changeset;node=9a412a372f78
description:
        Add preferred locales and update Stripe Customer

        The Stripe Customer is updated each time the party is modified in such 
way that
        the parameters are also changed. We do not manage any retry on the 
update
        because it is just a best effort.

        issue9887
        review305021002
diffstat:

 CHANGELOG                                 |   3 ++
 party.py                                  |  20 ++++++++++++++-
 payment.py                                |  40 ++++++++++++++++++++++++++----
 tests/scenario_account_payment_stripe.rst |  15 +++++++++++
 4 files changed, 71 insertions(+), 7 deletions(-)

diffs (143 lines):

diff -r 7063b7e4e146 -r 9a412a372f78 CHANGELOG
--- a/CHANGELOG Sat Dec 19 17:08:44 2020 +0100
+++ b/CHANGELOG Sat Dec 26 23:55:17 2020 +0100
@@ -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 -r 7063b7e4e146 -r 9a412a372f78 party.py
--- a/party.py  Sat Dec 19 17:08:44 2020 +0100
+++ b/party.py  Sat Dec 26 23:55:17 2020 +0100
@@ -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 @@
     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 -r 7063b7e4e146 -r 9a412a372f78 payment.py
--- a/payment.py        Sat Dec 19 17:08:44 2020 +0100
+++ b/payment.py        Sat Dec 26 23:55:17 2020 +0100
@@ -1522,9 +1522,8 @@
             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 @@
             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 @@
                 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 -r 7063b7e4e146 -r 9a412a372f78 tests/scenario_account_payment_stripe.rst
--- a/tests/scenario_account_payment_stripe.rst Sat Dec 19 17:08:44 2020 +0100
+++ b/tests/scenario_account_payment_stripe.rst Sat Dec 26 23:55:17 2020 +0100
@@ -73,7 +73,9 @@
 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 @@
     >>> bool(stripe_customer.stripe_customer_id)
     True
 
+Update customer::
+
+    >>> contact = customer.contact_mechanisms.new()
+    >>> contact.type = 'email'
+    >>> contact.value = '[email protected]'
+    >>> customer.save()
+
+    >>> cus = stripe.Customer.retrieve(stripe_customer.stripe_customer_id)
+    >>> cus.email
+    '[email protected]'
+    >>> cus.preferred_locales
+    ['en']
+
 Make payment with customer::
 
     >>> payment, = payment.duplicate()

Reply via email to