diff --git a/addons/delivery/models/sale_order.py b/addons/delivery/models/sale_order.py index 127b7fa459b..e72971b9da5 100644 --- a/addons/delivery/models/sale_order.py +++ b/addons/delivery/models/sale_order.py @@ -135,10 +135,19 @@ class SaleOrder(models.Model): for order in self: if order.invoice_status in ['no', 'invoiced']: continue - order_lines = order.order_line.filtered(lambda x: not x.is_delivery and not x.is_downpayment and not x.display_type and x.invoice_status != 'invoiced') + order_lines = order._get_lines_impacting_invoice_status() if all(line.product_id.invoice_policy == 'delivery' and line.invoice_status == 'no' for line in order_lines): order.invoice_status = 'no' + def _get_lines_impacting_invoice_status(self): + return self.order_line.filtered( + lambda line: + not line.is_delivery + and not line.is_downpayment + and not line.display_type + and line.invoice_status != 'invoiced' + ) + @api.depends('order_line.product_uom_qty', 'order_line.product_uom') def _compute_shipping_weight(self): for order in self: diff --git a/addons/sale_loyalty_delivery/models/sale_order.py b/addons/sale_loyalty_delivery/models/sale_order.py index baa937f7fd1..2451ebd1a19 100644 --- a/addons/sale_loyalty_delivery/models/sale_order.py +++ b/addons/sale_loyalty_delivery/models/sale_order.py @@ -25,6 +25,11 @@ class SaleOrder(models.Model): return res + self.order_line.filtered( lambda line: line.is_delivery or line.reward_id.reward_type == 'shipping') + def _get_lines_impacting_invoice_status(self): + return super()._get_lines_impacting_invoice_status().filtered( + lambda line: not line.is_reward_line + ) + def _get_reward_values_free_shipping(self, reward, coupon, **kwargs): delivery_line = self.order_line.filtered(lambda l: l.is_delivery) taxes = delivery_line.product_id.taxes_id.filtered(lambda t: t.company_id.id == self.company_id.id) diff --git a/addons/sale_loyalty_delivery/tests/test_free_shipping_reward.py b/addons/sale_loyalty_delivery/tests/test_free_shipping_reward.py index 4d040336e3f..512ee7e9fb8 100644 --- a/addons/sale_loyalty_delivery/tests/test_free_shipping_reward.py +++ b/addons/sale_loyalty_delivery/tests/test_free_shipping_reward.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo import Command from odoo.addons.sale_loyalty.tests.common import TestSaleCouponCommon from odoo.tests import Form, tagged @@ -317,3 +318,42 @@ class TestSaleCouponProgramRules(TestSaleCouponCommon): self._apply_promo_code(order, loyalty_card.code) # Check if there is an error in the sequence # via `_apply_program_reward` in `apply_promo_code` method + + def test_nothing_delivered_nothing_to_invoice(self): + program = self.env['loyalty.program'].create({ + 'name': '10% reduction on all orders', + 'trigger': 'auto', + 'program_type': 'promotion', + 'rule_ids': [Command.create({ + 'minimum_amount': 50, + })], + 'reward_ids': [Command.create({ + 'reward_type': 'discount', + 'discount': 10, + 'discount_mode': 'percent', + 'discount_applicability': 'order', + })] + }) + product = self.env['product.product'].create({ + 'name': 'Test product', + 'type': 'product', + 'list_price': 200.0, + 'invoice_policy': 'delivery', + }) + order = self.empty_order + self.env['sale.order.line'].create({ + 'product_id': product.id, + 'order_id': order.id, + }) + self._auto_rewards(order, program) + self.assertNotEqual(order.reward_amount, 0) + self.assertEqual(order.invoice_status, 'no') + delivery_wizard = Form(self.env['choose.delivery.carrier'].with_context({ + 'default_order_id': order.id, + 'default_carrier_id': self.carrier.id + })) + choose_delivery_carrier = delivery_wizard.save() + choose_delivery_carrier.button_confirm() + order.action_confirm() + self.assertEqual(order.delivery_set, True) + self.assertEqual(order.invoice_status, 'no')