From 8e733b22f84bc2f71a8a85d4c2373741717090a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 15 May 2017 15:44:05 +0200 Subject: [PATCH] [REF] sale_payment: clean code related to so confirmation and invoice generation Indeed this code is difficult to understand and uses unnecessary variables. Both confirm_so and generate_and_pay_invoice methods now work on payment.transaction records as they belong to that model. Finally less code is put in the try/except of confirm_so to avoid hiding real errors and issues. One interesting thing would be to correctly manage so confirmation errors and mail sending errors. This is currently not done and will maybe be done in future commits. --- addons/sale_payment/models/payment.py | 66 +++++++++++++-------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/addons/sale_payment/models/payment.py b/addons/sale_payment/models/payment.py index 47bcd456413..ca0bdb59a22 100644 --- a/addons/sale_payment/models/payment.py +++ b/addons/sale_payment/models/payment.py @@ -33,61 +33,61 @@ class PaymentTransaction(models.Model): if tx: # Auto-confirm SO if necessary - tx._confirm_so(acquirer_name=acquirer_name) + tx._confirm_so() return res - def _confirm_so(self, acquirer_name=False): + def _confirm_so(self): for tx in self: + # check tx state, confirm the potential SO + if not tx.sale_order_id or tx.sale_order_id.state not in ['draft', 'sent']: + # _logger.warning('<%s> transaction incorrect sale order %s (ID %s, state %s)', tx.acquirer_id.provider, tx.sale_order_id.name, tx.sale_order_id.id, tx.sale_order_id.state) + continue + if not float_compare(tx.amount, tx.sale_order_id.amount_total, 2) == 0: + _logger.warning('<%s> transaction MISMATCH for order %s (ID %s)', tx.acquirer_id.provider, tx.sale_order_id.name, tx.sale_order_id.id) + continue 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.capture_manually: - _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': - _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() - 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) + if tx.state == 'authorized' and tx.acquirer_id.capture_manually: + _logger.info('<%s> transaction authorized, auto-confirming order %s (ID %s)', tx.acquirer_id.provider, 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': + _logger.info('<%s> transaction completed, auto-confirming order %s (ID %s)', tx.acquirer_id.provider, tx.sale_order_id.name, tx.sale_order_id.id) + tx.sale_order_id.with_context(send_email=True).action_confirm() + tx._generate_and_pay_invoice() + 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)', tx.acquirer_id.provider, 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)', tx.acquirer_id.provider, 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 '') - def _generate_and_pay_invoice(self, tx, acquirer_name): - tx.sale_order_id._force_lines_to_invoice_policy_order() + def _generate_and_pay_invoice(self): + self.sale_order_id._force_lines_to_invoice_policy_order() # force company to ensure journals/accounts etc. are correct # company_id needed for default_get on account.journal # force_company needed for company_dependent fields - ctx_company = {'company_id': tx.sale_order_id.company_id.id, - 'force_company': tx.sale_order_id.company_id.id} - created_invoice = tx.sale_order_id.with_context(**ctx_company).action_invoice_create() + ctx_company = {'company_id': self.sale_order_id.company_id.id, + 'force_company': self.sale_order_id.company_id.id} + created_invoice = self.sale_order_id.with_context(**ctx_company).action_invoice_create() created_invoice = self.env['account.invoice'].browse(created_invoice).with_context(**ctx_company) if created_invoice: _logger.info('<%s> transaction completed, auto-generated invoice %s (ID %s) for %s (ID %s)', - acquirer_name, created_invoice.name, created_invoice.id, tx.sale_order_id.name, tx.sale_order_id.id) + self.acquirer_id.provider, created_invoice.name, created_invoice.id, self.sale_order_id.name, self.sale_order_id.id) created_invoice.action_invoice_open() - if not tx.acquirer_id.journal_id: + if not self.acquirer_id.journal_id: default_journal = self.env['account.journal'].search([('type', '=', 'bank')], limit=1) if not default_journal: _logger.warning('<%s> transaction completed, could not auto-generate payment for %s (ID %s) (no journal set on acquirer)', - acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id) - tx.acquirer_id.journal_id = default_journal - created_invoice.pay_and_reconcile(tx.acquirer_id.journal_id, pay_amount=created_invoice.amount_total) + self.acquirer_id.provider, self.sale_order_id.name, self.sale_order_id.id) + self.acquirer_id.journal_id = default_journal + created_invoice.pay_and_reconcile(self.acquirer_id.journal_id, pay_amount=created_invoice.amount_total) if created_invoice.payment_ids: - created_invoice.payment_ids[0].payment_transaction_id = tx + created_invoice.payment_ids[0].payment_transaction_id = self else: _logger.warning('<%s> transaction completed, could not auto-generate invoice for %s (ID %s)', - acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id) + self.acquirer_id.provider, self.sale_order_id.name, self.sale_order_id.id)