From 48e04dcb970178d80782fa1225daa82dfd040e6c Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Fri, 27 Apr 2018 12:35:25 +0200 Subject: [PATCH] [FIX] sale_payment: catch error at invoice creation - Set up Paypal as described in https://www.odoo.com/documentation/user/11.0/ecommerce/shopper_experience/paypal.html - Buy a product on the eCommerce. The vendor might receive an email mentioning that Instant Payment Notifications (IPN) are failing. When completing the paypent process with Paypal, 2 confirmations of the transaction will occur. The first one is through the route `/payment/paypal/dpn` (Payment Data Transfer (PDT)), which takes place right after the payment validation. The second confirmation comes through the route `/payment/paypal/ipn` (Instant Payment Notification (IPN)), which might arise with some delay (and potentially being run several times). Both confirmations will trigger the method `_generate_and_pay_invoice`, which can raise an error if no invoiceable line is found ('There is no invoiceable line.' in `sale` module). In this case, we should log the error and move forward instead of crashing and stopping the workflow. More information on PDT and IPN at https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNPDTAnAlternativetoIPN/ opw-1837196 --- addons/sale_payment/models/payment.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/addons/sale_payment/models/payment.py b/addons/sale_payment/models/payment.py index 8076addab09..831af37550f 100644 --- a/addons/sale_payment/models/payment.py +++ b/addons/sale_payment/models/payment.py @@ -3,6 +3,7 @@ import logging from odoo import api, fields, models, _ +from odoo.exceptions import UserError from odoo.tools import float_compare _logger = logging.getLogger(__name__) @@ -84,8 +85,16 @@ class PaymentTransaction(models.Model): # force_company needed for company_dependent fields 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) + + # We might fail to create the invoice because there is no invoiceable lines. This will + # raise a UserError and break the workflow. Better catch the error. + try: + 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) + except UserError: + _logger.warning('<%s> transaction completed, could not auto-generate invoice for %s (ID %s)', + self.acquirer_id.provider, self.sale_order_id.name, self.sale_order_id.id, exc_info=True) + return if created_invoice: _logger.info('<%s> transaction completed, auto-generated invoice %s (ID %s) for %s (ID %s)',