From 896ef2ad77ba10e5501445ae66c5b72092a238b9 Mon Sep 17 00:00:00 2001 From: MerlinGuillaume Date: Wed, 20 Jul 2022 14:44:30 +0000 Subject: [PATCH] [FIX] sale_stock_margin: do not recompute purchase_price on confirm The cost (purchase_price) of a sale order line is recomputed when the sale order is confirmed, overwriting the potentially edited value Steps to reproduce: 1. Install sale_stock_margin module 2. Create a quotation, add any customer and two lines: a service (e.g. Deposit) and any other storable product (e.g. Large Cabinet) 3. Activate 'Cost (purchase_price)' column in the order lines view 4. Edit the cost of Deposit and confirm the quotation 5. The cost resets to the original product cost Solution: Modify the dependency of `_compute_purchase_price` to trigger it only when the sale order line's related picking has changed state Problem: The dependency on order_id.picking_ids.state makes it that the purchase price is recomputed for all sale order lines when any of the picking of the related sale order has a modified state (but we want to recompute it only for the sale order line that had its picking's state modified) opw-2904500 FW-port of 9947b617a15a340a6d8127250918d8ea06a5354e to 16.0+ X-original-commit: 5287c0851cf7b3432427af17d3cc59c19306c417 Part-of: odoo/odoo#107909 --- .../models/sale_order_line.py | 2 +- .../tests/test_sale_stock_margin.py | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/addons/sale_stock_margin/models/sale_order_line.py b/addons/sale_stock_margin/models/sale_order_line.py index c9cc59c55ef..16db4ef4242 100644 --- a/addons/sale_stock_margin/models/sale_order_line.py +++ b/addons/sale_stock_margin/models/sale_order_line.py @@ -7,7 +7,7 @@ from odoo import api, fields, models class SaleOrderLine(models.Model): _inherit = 'sale.order.line' - @api.depends('move_ids', 'move_ids.stock_valuation_layer_ids', 'order_id.picking_ids.state') + @api.depends('move_ids', 'move_ids.stock_valuation_layer_ids', 'move_ids.picking_id.state') def _compute_purchase_price(self): lines_without_moves = self.browse() for line in self: diff --git a/addons/sale_stock_margin/tests/test_sale_stock_margin.py b/addons/sale_stock_margin/tests/test_sale_stock_margin.py index 7fa377337aa..d153b53a762 100644 --- a/addons/sale_stock_margin/tests/test_sale_stock_margin.py +++ b/addons/sale_stock_margin/tests/test_sale_stock_margin.py @@ -166,6 +166,36 @@ class TestSaleStockMargin(TestStockValuationCommon): self.assertAlmostEqual(order_line_2.margin, 30) # (20 - 12.5) * 4 self.assertAlmostEqual(sale_order.margin, 64) + def test_sale_stock_margin_6(self): + """ Test that the purchase price doesn't change when there is a service product in the SO""" + service = self.env['product.product'].create({ + 'name': 'Service', + 'type': 'service', + 'list_price': 100.0, + 'standard_price': 50.0}) + self.product1.list_price = 80.0 + self.product1.standard_price = 40.0 + sale_order = self._create_sale_order() + order_line_1 = self._create_sale_order_line(sale_order, service, 1, 100) + order_line_2 = self._create_sale_order_line(sale_order, self.product1, 1, 80) + + self.assertEqual(order_line_1.purchase_price, 50, "Sales order line cost should be 50.00") + self.assertEqual(order_line_2.purchase_price, 40, "Sales order line cost should be 40.00") + + self.assertEqual(order_line_1.margin, 50, "Sales order line profit should be 50.00") + self.assertEqual(order_line_2.margin, 40, "Sales order line profit should be 40.00") + self.assertEqual(sale_order.margin, 90, "Sales order profit should be 90.00") + + # Change the purchase price of the service product. + order_line_1.purchase_price = 100.0 + self.assertEqual(order_line_1.purchase_price, 100, "Sales order line cost should be 100.00") + + # Confirm the sales order. + sale_order.action_confirm() + + self.assertEqual(order_line_1.purchase_price, 100, "Sales order line cost should be 100.00") + self.assertEqual(order_line_2.purchase_price, 40, "Sales order line cost should be 40.00") + def test_so_and_multicurrency(self): ResCurrencyRate = self.env['res.currency.rate'] company_currency = self.env.company.currency_id