[FIX] purchase: set the correct price in alternative PO
Steps to reproduce the bug:
- Create a storable product “P1”:
- Price at “Wood corner”:
- $5, min qty =1
- Price at “Open wood:
- $6, min qty = 1
- $4, min qty = 10
- Create a purchase order at wood corner:
- 100 units
> the price is automatically computed at $500
- Go to Alternative tab in the PO:
- Create a one for “Openwood” and copy lines
Problem:
The price for 100 units is computed as $600 instead of $400.
When we create the alternative purchase order, in the "create" function
of “purchase.order.line,” we receive only the quantity as "qty=100" in
the values. Therefore, the missing fields should be prepared.
https://github.com/odoo/odoo/blob/a9cbd2a2ae2e21f1ba14379aecd908c44497b8ab/addons/purchase/models/purchase.py#L1102
https://github.com/odoo/odoo/blob/a9cbd2a2ae2e21f1ba14379aecd908c44497b8ab/addons/purchase/models/purchase.py#L1102
First, the line is created with the received values (“qty=100”), and
the price_unit is computed correctly as $4.
https://github.com/odoo/odoo/blob/a9cbd2a2ae2e21f1ba14379aecd908c44497b8ab/addons/purchase/models/purchase.py#L1400
So, the price_unit is computed correctly at $4
However, the “onchange_product_id” function is then called, resetting
the price_unit and product_qty to 0.
https://github.com/odoo/odoo/blob/a9cbd2a2ae2e21f1ba14379aecd908c44497b8ab/addons/purchase/models/purchase.py#L1401
https://github.com/odoo/odoo/blob/a9cbd2a2ae2e21f1ba14379aecd908c44497b8ab/addons/purchase/models/purchase.py#L1176
Afterward, the “_suggest_quantity()” function is called
https://github.com/odoo/odoo/blob/a9cbd2a2ae2e21f1ba14379aecd908c44497b8ab/addons/purchase/models/purchase.py#L1180
suggesting a minimal quantity based on the seller (so=1).
https://github.com/odoo/odoo/blob/a9cbd2a2ae2e21f1ba14379aecd908c44497b8ab/addons/purchase/models/purchase.py#L1363
Therefore, the price_unit is computed based on qty=1, resulting in $6.
Finally, the price is returned because it is the only missing field.
opw-3497825
closes odoo/odoo#137774
X-original-commit: 0781198f1b5e5d6a4e2722ea3c663b74fb131bc3
Signed-off-by: Djamel Touati (otd) <otd@odoo.com>
This commit is contained in:
@@ -1165,7 +1165,8 @@ class PurchaseOrderLine(models.Model):
|
||||
|
||||
@api.onchange('product_id')
|
||||
def onchange_product_id(self):
|
||||
if not self.product_id:
|
||||
# TODO: Remove when onchanges are replaced with computes
|
||||
if not self.product_id or (self.env.context.get('origin_po_id') and self.product_qty):
|
||||
return
|
||||
|
||||
# Reset date, price and quantity since _onchange_quantity will provide default values
|
||||
@@ -1179,9 +1180,7 @@ class PurchaseOrderLine(models.Model):
|
||||
if not self.product_id:
|
||||
return
|
||||
|
||||
# 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
|
||||
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,
|
||||
|
||||
@@ -431,3 +431,43 @@ class TestPurchaseRequisition(TestPurchaseRequisitionCommon):
|
||||
# alt_po is cheaper than orig_po
|
||||
self.assertEqual(best_price_ids[0], po_alt.order_line.id)
|
||||
self.assertEqual(best_price_unit_ids[0], po_alt.order_line.id)
|
||||
|
||||
def test_alternative_po_with_multiple_price_list(self):
|
||||
vendor_a = self.env["res.partner"].create({
|
||||
"name": "Supplier A",
|
||||
})
|
||||
vendor_b = self.env["res.partner"].create({
|
||||
"name": "Supplier B",
|
||||
})
|
||||
product = self.env['product.product'].create({
|
||||
'name': 'Product',
|
||||
'seller_ids': [(0, 0, {
|
||||
'partner_id': vendor_a.id,
|
||||
'price': 5,
|
||||
}), (0, 0, {
|
||||
'partner_id': vendor_b.id,
|
||||
'price': 4,
|
||||
'min_qty': 10,
|
||||
}), (0, 0, {
|
||||
'partner_id': vendor_b.id,
|
||||
'price': 6,
|
||||
'min_qty': 1,
|
||||
}),
|
||||
]
|
||||
})
|
||||
po_form = Form(self.env['purchase.order'])
|
||||
po_form.partner_id = vendor_a
|
||||
with po_form.order_line.new() as line:
|
||||
line.product_id = product
|
||||
line.product_qty = 100
|
||||
po_orig = po_form.save()
|
||||
self.assertEqual(po_orig.order_line.price_unit, 5)
|
||||
# Creates an alternative PO
|
||||
action = po_orig.action_create_alternative()
|
||||
alt_po_wizard_form = Form(self.env['purchase.requisition.create.alternative'].with_context(**action['context']))
|
||||
alt_po_wizard_form.partner_id = vendor_b
|
||||
alt_po_wizard_form.copy_products = True
|
||||
alt_po_wizard = alt_po_wizard_form.save()
|
||||
alt_po_wizard.action_create_alternative()
|
||||
po_alt = po_orig.alternative_po_ids - po_orig
|
||||
self.assertEqual(po_alt.order_line.price_unit, 4)
|
||||
|
||||
Reference in New Issue
Block a user