[FIX] purchase: compute the price with correct UoM in PO alternative
Steps to reproduce the bug:
- install the `purchase_requisition` module
- Create a storable product “P1”:
- UoM: unit
- cost: 10
- Create a PO:
- Add 1 unit of “P1”:
- Change the UoM from unit to Dozen
- the unit price will be updated from 10 to 120
- Save the PO
- Create a Po alternative
Problem:
The “Unit of measure” is correctly copied, but the unit price is wrongly
computed “10” instead of 120.
When creating the PO alternative, we copy the uom of the original
lines in the vals:
https://github.com/odoo/odoo/blob/4c2163d2b195a0c829d4e24a7afc3347e7c3401a/addons/purchase_requisition/wizard/purchase_requisition_create_alternative.py#L84
then, The line is created with the correct UoM, but we force the call
to `onchange_product_id`:
https://github.com/odoo/odoo/blob/c677f45dcb050ce7e6f755b71e56c9b9120bf613/addons/purchase/models/purchase.py#L1371-L1372
So `_product_id_change` will be called:
https://github.com/odoo/odoo/blob/c677f45dcb050ce7e6f755b71e56c9b9120bf613/addons/purchase/models/purchase.py#L1163
And the product UoM “Unit” will be set in the `purchase.order.line`:
https://github.com/odoo/odoo/blob/c677f45dcb050ce7e6f755b71e56c9b9120bf613/addons/purchase/models/purchase.py#L1171
Therefore, the unit price will be calculated with Unit instead of dozen:
https://github.com/odoo/odoo/blob/c677f45dcb050ce7e6f755b71e56c9b9120bf613/addons/purchase/models/purchase.py#L1225
Solution:
We have to ensure that the values only created by onchanges and not
provided during the alternative PO creation are still created via the
`onchange_product_id`. Therefore we avoid the incorrect uom reassignment
during the calculation of the unit price when creation is from an alt
PO creation with uom included.
closes odoo/odoo#117808
X-original-commit: 93769b9b51196c0aed74fc74cca1fcacdc59f789
Signed-off-by: Tiffany Chang <tic@odoo.com>
Signed-off-by: Djamel Touati (otd) <otd@odoo.com>
This commit is contained in:
@@ -1179,7 +1179,9 @@ class PurchaseOrderLine(models.Model):
|
||||
if not self.product_id:
|
||||
return
|
||||
|
||||
self.product_uom = self.product_id.uom_po_id or self.product_id.uom_id
|
||||
# TODO: Remove when onchanges are replaced with computes
|
||||
if not (self.env.context.get('origin_po_id') and self.product_uom and self.product_id.uom_id.category_id == self.product_uom_category_id):
|
||||
self.product_uom = self.product_id.uom_po_id or self.product_id.uom_id
|
||||
product_lang = self.product_id.with_context(
|
||||
lang=get_lang(self.env, self.partner_id.lang).code,
|
||||
partner_id=self.partner_id.id,
|
||||
|
||||
@@ -285,6 +285,32 @@ class TestPurchaseRequisition(TestPurchaseRequisitionCommon):
|
||||
po_1.order_line.price_unit, 16,
|
||||
"Line's unit price from the original PO shouldn't be changed")
|
||||
|
||||
def test_10_alternative_po_line_price_unit_different_uom(self):
|
||||
""" Check that the uom is copied in the alternative PO, and the "unit_price"
|
||||
is calculated according to this uom and not that of the product """
|
||||
# Creates a first Purchase Order.
|
||||
po_form = Form(self.env['purchase.order'])
|
||||
self.product_09.standard_price = 10
|
||||
po_form.partner_id = self.res_partner_1
|
||||
with po_form.order_line.new() as line:
|
||||
line.product_id = self.product_09
|
||||
line.product_qty = 1
|
||||
line.product_uom = self.env.ref('uom.product_uom_dozen')
|
||||
po_1 = po_form.save()
|
||||
self.assertEqual(po_1.order_line[0].price_unit, 120)
|
||||
|
||||
# Creates an alternative PO.
|
||||
action = po_1.action_create_alternative()
|
||||
alt_po_wizard_form = Form(self.env['purchase.requisition.create.alternative'].with_context(**action['context']))
|
||||
alt_po_wizard_form.partner_id = self.res_partner_1
|
||||
alt_po_wizard_form.copy_products = True
|
||||
alt_po_wizard = alt_po_wizard_form.save()
|
||||
alt_po_wizard.action_create_alternative()
|
||||
|
||||
po_2 = po_1.alternative_po_ids - po_1
|
||||
self.assertEqual(po_2.order_line[0].product_uom, po_1.order_line[0].product_uom)
|
||||
self.assertEqual(po_2.order_line[0].price_unit, 120)
|
||||
|
||||
def test_11_alternative_po_from_po_with_requisition_id(self):
|
||||
"""Create a purchase order from a blanket order, then check that the alternative purchase order
|
||||
can be created and that the requisition_id is not set on it.
|
||||
|
||||
Reference in New Issue
Block a user