[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
This commit is contained in:
MerlinGuillaume
2022-12-14 17:17:51 +01:00
committed by Victor Feyens
parent 91b80fbb5c
commit 896ef2ad77
2 changed files with 31 additions and 1 deletions
@@ -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:
@@ -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