diff --git a/addons/website_portal_sale/models/payment.py b/addons/website_portal_sale/models/payment.py index d52085ee8f4..3b77d74b51e 100644 --- a/addons/website_portal_sale/models/payment.py +++ b/addons/website_portal_sale/models/payment.py @@ -41,32 +41,42 @@ class PaymentTransaction(models.Model): tx = None res = super(PaymentTransaction, self).form_feedback(data, acquirer_name) - # fetch the tx, check its state, confirm the potential SO - try: - tx_find_method_name = '_%s_form_get_tx_from_data' % acquirer_name - if hasattr(self, tx_find_method_name): - tx = getattr(self, tx_find_method_name)(data) - _logger.info('<%s> transaction processed: tx ref:%s, tx amount: %s', acquirer_name, tx.reference if tx else 'n/a', tx.amount if tx else 'n/a') + # fetch the tx + tx_find_method_name = '_%s_form_get_tx_from_data' % acquirer_name + if hasattr(self, tx_find_method_name): + tx = getattr(self, tx_find_method_name)(data) + _logger.info('<%s> transaction processed: tx ref:%s, tx amount: %s', acquirer_name, tx.reference if tx else 'n/a', tx.amount if tx else 'n/a') - if tx and tx.sale_order_id and tx.sale_order_id.state in ['draft', 'sent']: - # verify SO/TX match, excluding tx.fees which are currently not included in SO - amount_matches = float_compare(tx.amount, tx.sale_order_id.amount_total, 2) == 0 - if amount_matches: - if tx.state == 'authorized' and tx.acquirer_id.auto_confirm == 'authorize': - _logger.info('<%s> transaction authorized, auto-confirming order %s (ID %s)', acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id) - tx.sale_order_id.with_context(send_email=True).action_confirm() - if tx.state == 'done' and tx.acquirer_id.auto_confirm in ['confirm_so', 'generate_and_pay_invoice']: - _logger.info('<%s> transaction completed, auto-confirming order %s (ID %s)', acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id) - tx.sale_order_id.with_context(send_email=True).action_confirm() - - if tx.acquirer_id.auto_confirm == 'generate_and_pay_invoice': - self._generate_and_pay_invoice(tx, acquirer_name) - elif tx.state not in ['cancel', 'error'] and tx.sale_order_id.state == 'draft': - _logger.info('<%s> transaction pending/to confirm manually, sending quote email for order %s (ID %s)', acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id) - tx.sale_order_id.force_quotation_send() - else: - _logger.warning('<%s> transaction MISMATCH for order %s (ID %s)', acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id) - except Exception: - _logger.exception('Fail to confirm the order or send the confirmation email%s', tx and ' for the transaction %s' % tx.reference or '') + if tx: + # Auto-confirm SO if necessary + tx._confirm_so(acquirer_name=acquirer_name) return res + + def _confirm_so(self, acquirer_name=False): + for tx in self: + try: + # check tx state, confirm the potential SO + if tx.sale_order_id and tx.sale_order_id.state in ['draft', 'sent']: + # verify SO/TX match, excluding tx.fees which are currently not included in SO + amount_matches = float_compare(tx.amount, tx.sale_order_id.amount_total, 2) == 0 + if amount_matches: + if not acquirer_name: + acquirer_name = tx.sale_order_id.payment_acquirer_id.provider or 'unknown' + if tx.state == 'authorized' and tx.acquirer_id.auto_confirm == 'authorize': + _logger.info('<%s> transaction authorized, auto-confirming order %s (ID %s)', acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id) + tx.sale_order_id.with_context(send_email=True).action_confirm() + if tx.state == 'done' and tx.acquirer_id.auto_confirm in ['confirm_so', 'generate_and_pay_invoice']: + _logger.info('<%s> transaction completed, auto-confirming order %s (ID %s)', acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id) + tx.sale_order_id.with_context(send_email=True).action_confirm() + + if tx.acquirer_id.auto_confirm == 'generate_and_pay_invoice': + self._generate_and_pay_invoice(tx, acquirer_name) + elif tx.state not in ['cancel', 'error'] and tx.sale_order_id.state == 'draft': + _logger.info('<%s> transaction pending/to confirm manually, sending quote email for order %s (ID %s)', acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id) + tx.sale_order_id.force_quotation_send() + else: + _logger.warning('<%s> transaction MISMATCH for order %s (ID %s)', acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id) + + except Exception: + _logger.exception('Fail to confirm the order or send the confirmation email%s', tx and ' for the transaction %s' % tx.reference or '') diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index 592a3e43c74..6e2c06b3fd1 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -753,7 +753,10 @@ class WebsiteSale(http.Controller): valid_state = 'authorized' if tx.acquirer_id.auto_confirm == 'authorize' else 'done' if not s2s_result or tx.state != valid_state: return dict(success=False, error=_("Payment transaction failed (%s)") % tx.state_message) - return dict(success=True, url='/shop/payment/validate') + else: + # Auto-confirm SO if necessary + tx._confirm_so() + return dict(success=True, url='/shop/payment/validate') except Exception, e: _logger.warning(_("Payment transaction (%s) failed : <%s>") % (tx.id, str(e))) return dict(success=False, error=_("Payment transaction failed (Contact Administrator)"))