[FIX] purchase_stock: update the move price after changing the PO line price
Steps to reproduce the bug:
- Create a storable product “P1”:
- Standard price: 20$
- Add vendor in the Purchase tab:
- name: Azure Interior
- min qty: 10
- price: $15
- Create a PO:
- Vendor: "Azure Interior"
- Product line: “P1”
Automatically, the Quantity field will automatically get populated as 10 Units
and price:$15 as per the pricelist
- Confirm the PO
A picking will be created containing a stock_move with a price of $15 and a QTY of 10
- Edit the Quantity to 9 Units and save the PO
The price will be updated to $20 on the PO line, but not in the `stock.move`
Problem:
When we update the qty in the PO line, a new move with a quantity of “-1” and
a price of “$20” will be created.
Then, it will be merged with the initial move, but since they are not identical in the price,
we can't merge them, so a new picking is created:
https://github.com/odoo/odoo/blob/dda9700d8236091626cbd78efc0ca4116e1e1acd/addons/stock/models/stock_move.py#L869-L881
Solution:
when the price is updated in a PO line, the price of its linked `stock.move` must also be updated
opw-2825160
closes odoo/odoo#92208
X-original-commit: c8d74a1cb4bfed8226e52e0bc6f243b4e483fc98
Signed-off-by: Djamel Touati (otd) <otd@odoo.com>
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
This commit is contained in:
@@ -366,6 +366,8 @@ class PurchaseOrderLine(models.Model):
|
||||
lines = self.filtered(lambda l: l.order_id.state == 'purchase')
|
||||
previous_product_qty = {line.id: line.product_uom_qty for line in lines}
|
||||
result = super(PurchaseOrderLine, self).write(values)
|
||||
if 'price_unit' in values:
|
||||
self.move_ids.price_unit = self.price_unit
|
||||
if 'product_qty' in values:
|
||||
lines.with_context(previous_product_qty=previous_product_qty)._create_or_update_picking()
|
||||
return result
|
||||
|
||||
@@ -600,3 +600,44 @@ class TestCreatePicking(common.TestProductCommon):
|
||||
self.assertEqual(purchase_order_line.product_qty, 45, 'The demand on the Purchase Order should not have been increased since it is has been confirmed.')
|
||||
purchase_orders = self.env['purchase.order'].search([('partner_id', '=', partner.id)])
|
||||
self.assertEqual(len(purchase_orders), 2, 'A new RFQ should have been created for missing demand.')
|
||||
|
||||
def test_update_qty_purchased(self):
|
||||
"""
|
||||
Test that the price unit in the purchase order line and the move is updated
|
||||
according to the pricelist defined in the product, and that the "stock.moves"
|
||||
are merged correctly when changing the qty purchased.
|
||||
"""
|
||||
# add vendor to the product
|
||||
self.product_id_1.seller_ids = [(0, 0, {
|
||||
'partner_id': self.partner_id.id,
|
||||
'min_qty': 10,
|
||||
'price': 15,
|
||||
})]
|
||||
|
||||
# Create PO
|
||||
po_form = Form(self.env['purchase.order'])
|
||||
po_form.partner_id = self.partner_id
|
||||
with po_form.order_line.new() as po_line:
|
||||
po_line.product_id = self.product_id_1
|
||||
po_line.product_qty = 10
|
||||
purchase_order = po_form.save()
|
||||
|
||||
# Confirm Purchase order
|
||||
purchase_order.button_confirm()
|
||||
# Check purchase order state, it should be "purchase".
|
||||
self.assertEqual(purchase_order.state, 'purchase', 'Purchase order should be in purchase state.')
|
||||
# Make sure that picking has been created
|
||||
self.assertEqual(len(purchase_order.picking_ids), 1)
|
||||
# check that the price list has been applied
|
||||
self.assertEqual(purchase_order.order_line.price_unit, 15)
|
||||
self.assertEqual(purchase_order.picking_ids.move_ids.price_unit, 15)
|
||||
# update the product qty purchased
|
||||
with po_form.order_line.edit(0) as po_line:
|
||||
po_line.product_qty = 9
|
||||
purchase_order = po_form.save()
|
||||
# verify that the move for the decreased qty has been merged with the initial move
|
||||
self.assertEqual(len(purchase_order.picking_ids), 1)
|
||||
self.assertEqual(len(purchase_order.picking_ids.move_ids), 1)
|
||||
# check that the price has been updated in the purchase order line and in the stock.move
|
||||
self.assertEqual(purchase_order.order_line.price_unit, 0)
|
||||
self.assertEqual(purchase_order.picking_ids.move_ids.price_unit, 0)
|
||||
|
||||
@@ -88,8 +88,6 @@ class TestStockValuation(TransactionCase):
|
||||
# update the unit price on the purchase order line
|
||||
po1.order_line.price_unit = 200
|
||||
|
||||
# the unit price on the stock move is not directly updated
|
||||
self.assertEqual(move1.price_unit, 100)
|
||||
|
||||
# validate the receipt
|
||||
res_dict = picking1.button_validate()
|
||||
|
||||
Reference in New Issue
Block a user