diff --git a/addons/sale/models/payment_transaction.py b/addons/sale/models/payment_transaction.py index 0d5d87ff0c7..e48210327a8 100644 --- a/addons/sale/models/payment_transaction.py +++ b/addons/sale/models/payment_transaction.py @@ -97,10 +97,10 @@ class PaymentTransaction(models.Model): # invoice the sale orders if needed self._invoice_sale_orders() res = super()._reconcile_after_done() - if self.env['ir.config_parameter'].sudo().get_param('sale.automatic_invoice'): + if self.env['ir.config_parameter'].sudo().get_param('sale.automatic_invoice') and any(so.state in ('sale', 'done') for so in self.sale_order_ids): default_template = self.env['ir.config_parameter'].sudo().get_param('sale.default_invoice_email_template') if default_template: - for trans in self.filtered(lambda t: t.sale_order_ids): + for trans in self.filtered(lambda t: t.sale_order_ids.filtered(lambda so: so.state in ('sale', 'done'))): trans = trans.with_company(trans.acquirer_id.company_id).with_context( mark_invoice_as_sent=True, company_id=trans.acquirer_id.company_id.id, @@ -114,9 +114,11 @@ class PaymentTransaction(models.Model): for trans in self.filtered(lambda t: t.sale_order_ids): trans = trans.with_company(trans.acquirer_id.company_id)\ .with_context(company_id=trans.acquirer_id.company_id.id) - trans.sale_order_ids._force_lines_to_invoice_policy_order() - invoices = trans.sale_order_ids._create_invoices() - trans.invoice_ids = [(6, 0, invoices.ids)] + confirmed_orders = trans.sale_order_ids.filtered(lambda so: so.state in ('sale', 'done')) + if confirmed_orders: + confirmed_orders._force_lines_to_invoice_policy_order() + invoices = confirmed_orders._create_invoices() + trans.invoice_ids = [(6, 0, invoices.ids)] @api.model def _compute_reference_prefix(self, provider, separator, **values): diff --git a/addons/sale/tests/test_payment_flow.py b/addons/sale/tests/test_payment_flow.py index 54693c6380d..dbcd42be6f0 100644 --- a/addons/sale/tests/test_payment_flow.py +++ b/addons/sale/tests/test_payment_flow.py @@ -157,3 +157,35 @@ class TestSalePayment(PaymentCommon, PaymentHttpCommon): self.assertEqual(tx2_sudo.reference, reference) self.assertEqual(self.order.state, 'draft') self.assertEqual(self.order.transaction_ids, tx_sudo + tx2_sudo) + + def test_13_sale_automatic_partial_payment_link_delivery(self): + """Test that with automatic invoice and invoicing policy based on delivered quantity, a transaction for the partial + amount does not validate the SO.""" + # set automatic invoice + self.env['ir.config_parameter'].sudo().set_param('sale.automatic_invoice', 'True') + # invoicing policy is based on delivered quantity + self.sale_product.invoice_policy = 'delivery' + + self.amount = self.order.amount_total / 2.0 + route_values = self._prepare_pay_values() + route_values['sale_order_id'] = self.order.id + + tx_context = self.get_tx_checkout_context(**route_values) + + route_values.update({ + 'flow': 'direct', + 'payment_option_id': self.acquirer.id, + 'tokenization_requested': False, + 'validation_route': False, + 'reference_prefix': tx_context['reference_prefix'], + 'landing_route': tx_context['landing_route'], + }) + with mute_logger('odoo.addons.payment.models.payment_transaction'): + processing_values = self.get_processing_values(**route_values) + tx_sudo = self._get_tx(processing_values['reference']) + + tx_sudo._set_done() + with mute_logger('odoo.addons.sale.models.payment_transaction'): + tx_sudo._finalize_post_processing() + + self.assertEqual(self.order.state, 'draft', 'a partial transaction with automatic invoice and invoice_policy = delivery should not validate a quote')