diff --git a/addons/sale/models/sale_order_line.py b/addons/sale/models/sale_order_line.py index 9de364a3a99..e214b31b8a7 100644 --- a/addons/sale/models/sale_order_line.py +++ b/addons/sale/models/sale_order_line.py @@ -479,16 +479,17 @@ class SaleOrderLine(models.Model): # amount and not zero. Since we compute untaxed amount, we can use directly the price # reduce (to include discount) without using `compute_all()` method on taxes. price_subtotal = 0.0 - umo_qty_to_consider = line.qty_delivered if line.product_id.invoice_policy == 'delivery' else line.product_uom_qty - price_subtotal = line.price_reduce * umo_qty_to_consider + uom_qty_to_consider = line.qty_delivered if line.product_id.invoice_policy == 'delivery' else line.product_uom_qty + price_reduce = line.price_unit * (1 - (line.discount or 0.0) / 100.0) + price_subtotal = price_reduce * uom_qty_to_consider if len(line.tax_id.filtered(lambda tax: tax.price_include)) > 0: # As included taxes are not excluded from the computed subtotal, `compute_all()` method # has to be called to retrieve the subtotal without them. # `price_reduce_taxexcl` cannot be used as it is computed from `price_subtotal` field. (see upper Note) price_subtotal = line.tax_id.compute_all( - line.price_reduce, + price_reduce, currency=line.order_id.currency_id, - quantity=umo_qty_to_consider, + quantity=uom_qty_to_consider, product=line.product_id, partner=line.order_id.partner_shipping_id)['total_excluded'] diff --git a/addons/sale/tests/test_sale_order.py b/addons/sale/tests/test_sale_order.py index 05009fd9f94..803c2f7a720 100644 --- a/addons/sale/tests/test_sale_order.py +++ b/addons/sale/tests/test_sale_order.py @@ -697,3 +697,42 @@ class TestSaleOrder(TestSaleCommon): self.sale_order.action_unlock() self.assertEqual(self.sale_order.state, 'sale') + + def test_discount_and_untaxed_subtotal(self): + """When adding a discount on a SO line, this test ensures that the untaxed amount to invoice is + equal to the untaxed subtotal""" + self.product_a.invoice_policy = 'delivery' + sale_order = self.env['sale.order'].create({ + 'partner_id': self.partner_a.id, + 'order_line': [(0, 0, { + 'product_id': self.product_a.id, + 'product_uom_qty': 38, + 'price_unit': 541.26, + 'discount': 2.00, + })] + }) + sale_order.action_confirm() + line = sale_order.order_line + self.assertEqual(line.untaxed_amount_to_invoice, 0) + + line.qty_delivered = 38 + # (541.26 - 0.02 * 541.26) * 38 = 20156.5224 ~= 20156.52 + self.assertEqual(line.price_subtotal, 20156.52) + self.assertEqual(line.untaxed_amount_to_invoice, line.price_subtotal) + + # Same with an included-in-price tax + sale_order = sale_order.copy() + line = sale_order.order_line + line.tax_id = [(0, 0, { + 'name': 'Super Tax', + 'amount_type': 'percent', + 'amount': 15.0, + 'price_include': True, + })] + sale_order.action_confirm() + self.assertEqual(line.untaxed_amount_to_invoice, 0) + + line.qty_delivered = 38 + # (541,26 / 1,15) * ,98 * 38 = 17527,410782609 ~= 17527.41 + self.assertEqual(line.price_subtotal, 17527.41) + self.assertEqual(line.untaxed_amount_to_invoice, line.price_subtotal)