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
This commit is contained in:
Cédric Krier
2020-12-26 23:55:17 +01:00
parent 3482ad3411
commit a1e56225c4
4 changed files with 71 additions and 7 deletions
+3
View File
@@ -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
+19 -1
View File
@@ -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'
+34 -6
View File
@@ -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:
+15
View File
@@ -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()