0003-lingo-make-BasketItem-creation-idempotent-for-paid-i.patch
combo/apps/lingo/models.py | ||
---|---|---|
857 | 857 |
for item_id in items.split(','): |
858 | 858 |
try: |
859 | 859 |
remote_item = regie.get_invoice(user=self.user, invoice_id=item_id, raise_4xx=True) |
860 |
with atomic(savepoint=False): |
|
861 |
self.items.add(self.create_paid_invoice_basket_item(item_id, remote_item)) |
|
860 | 862 |
regie.pay_invoice(item_id, self.order_id, self.bank_transaction_date or self.end_date) |
861 | 863 |
except ObjectDoesNotExist: |
862 | 864 |
# 4xx error |
... | ... | |
879 | 881 |
) |
880 | 882 |
else: |
881 | 883 |
logger.info('notified payment for remote item %s from transaction %s', item_id, self) |
882 |
self.items.add(self.create_paid_invoice_basket_item(remote_item)) |
|
883 | 884 | |
884 | 885 |
self.to_be_paid_remote_items = ','.join(to_be_paid_remote_items) or None |
885 | 886 |
self.save(update_fields=['to_be_paid_remote_items']) |
886 | 887 | |
887 |
def create_paid_invoice_basket_item(self, remote_item): |
|
888 |
def create_paid_invoice_basket_item(self, item_id, remote_item):
|
|
888 | 889 |
subject = _('Invoice #%s') % remote_item.display_id |
889 |
return BasketItem.objects.create( |
|
890 |
user=self.user, |
|
891 |
regie=remote_item.regie, |
|
892 |
source_url='', |
|
893 |
subject=subject, |
|
894 |
amount=remote_item.amount, |
|
895 |
payment_date=self.end_date, |
|
890 |
basket_item, created = BasketItem.objects.get_or_create( |
|
891 |
remote_item_id=item_id, |
|
892 |
defaults=dict( |
|
893 |
user=self.user, |
|
894 |
regie=remote_item.regie, |
|
895 |
source_url='', |
|
896 |
subject=subject, |
|
897 |
amount=remote_item.amount, |
|
898 |
payment_date=self.end_date, |
|
899 |
), |
|
896 | 900 |
) |
901 |
return basket_item |
|
897 | 902 | |
898 | 903 |
def handle_backend_response(self, response, callback=True): |
899 | 904 |
logger.debug('lingo: regie "%s" handling response for transaction "%%s"' % self.regie, self.order_id) |
tests/test_lingo_payment.py | ||
---|---|---|
1120 | 1120 |
mock_err = mock.Mock(status_code=200) |
1121 | 1121 |
mock_err.json.return_url = {'err': 1} |
1122 | 1122 | |
1123 |
assert transaction.items.count() == 0 |
|
1124 | ||
1123 | 1125 |
# error on get invoice |
1124 | 1126 |
mock_request.side_effect = [ |
1125 | 1127 |
ConnectionError('where is my hostname?'), # get invoice 42 |
... | ... | |
1128 | 1130 |
] |
1129 | 1131 |
appconfig.update_transactions() |
1130 | 1132 |
transaction.refresh_from_db() |
1133 |
assert transaction.items.count() == 1 # only 35 was found |
|
1134 |
assert set(transaction.items.values_list('remote_item_id', flat=True)) == {'35'} |
|
1131 | 1135 |
assert transaction.to_be_paid_remote_items == '42' # retry for first one |
1132 | 1136 | |
1133 | 1137 |
# error on pay invoice |
... | ... | |
1140 | 1144 |
] |
1141 | 1145 |
appconfig.update_transactions() |
1142 | 1146 |
transaction.refresh_from_db() |
1147 |
assert transaction.items.count() == 2 # both were updated now that get_invoice worked for 42 |
|
1148 |
assert set(transaction.items.values_list('remote_item_id', flat=True)) == {'35', '42'} |
|
1143 | 1149 |
assert transaction.to_be_paid_remote_items == '42' # retry for first one |
1144 | 1150 | |
1145 | 1151 |
# unknown error on get invoice |
1146 |
- |