[FIX] purchase: compute order line name with supplierinfo
Currently, when creating a purchase order, if the product has multiple vendor lines (with the vendor selected on the PO), the product description uses information from all the vendor lines; instead of using information from the vendor line that is used for the price.
Steps to reproduce:
-------------------
* Go to the **Purchase** App
* Go to **Products**
* Select any product
* Select the **Purchase** tab
* Add `Vendor Product Name` and `Vendor Product Code` in additional line fields
* Add two vendor lines
* Line 1:
`Vendor`: Vendor1
`Vendor Product Name`: P1
`Vendor Product Code`: A
`Price`: 1
* Line 2: <br>
`Vendor`: Vendor 1
`Vendor Product Name`: P1 bis
`Vendor Product Code`: B
`Price`: 5
* Select **Orders** > **Request for quotation**
* Create a new quotation
* Select Vendor 1, add the product for which we just added the two vendor lines
> **Observation**: The description of the product shows information from both vendor lines added.
Why the fix:
------------
This behavior was introduced when `name_get` was removed to use `dispay_name` instead.
* https://github.com/odoo/odoo/pull/122085/commits/a8b15c7ab5e2d850d0551a6eb4213bb20a30b210
When adding a product to the purchase order, the onchange on `product_id` is called. The onchange calls the function `_product_id_change`, which itself calls `_get_product_purchase_description`.
https://github.com/odoo/odoo/blob/7e9b9494a8d6c4bb8b3800cc0e25fcd3596db75d/addons/purchase/models/purchase.py#L1224
https://github.com/odoo/odoo/blob/7e9b9494a8d6c4bb8b3800cc0e25fcd3596db75d/addons/purchase/models/purchase.py#L1401-L1407
The line `name = product_lang.display_name` calls the function `_compute_display_name`.
* We do have a parnter_id in the context as we have selected a vendor on the purchase order.
https://github.com/odoo/odoo/blob/7e9b9494a8d6c4bb8b3800cc0e25fcd3596db75d/addons/product/models/product_product.py#L434
* We don't have a supplierinfo in the context yet but we have multiple supplierinfo with the same partner_id.
https://github.com/odoo/odoo/blob/7e9b9494a8d6c4bb8b3800cc0e25fcd3596db75d/addons/product/models/product_product.py#L466-L467
Here we thus have 2 sellers.
* Ultimately, the display name joins the different display names computer for each seller.
https://github.com/odoo/odoo/blob/7e9b9494a8d6c4bb8b3800cc0e25fcd3596db75d/addons/product/models/product_product.py#L473-L483
Coming back to the line `self.name = self._get_product_purchase_description(product_lang)`, we now have the name of the purchase order line set as the concatenation of display names from the supplierinfo, i.e `'[A] P1, [B] P1 bis'`.
Once the onchange is called, the function `_compute_price_unit_and_date_planned_and_name` is being called.
https://github.com/odoo/odoo/blob/7e9b9494a8d6c4bb8b3800cc0e25fcd3596db75d/addons/purchase/models/purchase.py#L1295
In the current state, we do not meet the if condition. Indeed, the line has a name (`'[A] P1, [B] P1 bis'`) but it isn't in the default_names (`['[A] P1', '[B] P1 bis']`). It somehow corresponds to a setting where the name of the purchase order line was setup by the user.
With this current fix, the call to `_product_id_change` will set the name of the line with the product information from the company; and not the partner. We also need to add this name to the `default_names` in `_compute_price_unit_and_date_planned_and_name` so that the description get recomputed with regards to the seller, if any.
opw-3802182
closes odoo/odoo#160778
X-original-commit: 6974f5303badbc5f5db104270f9492c12a52f220
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Sarah Bellefroid (sbel) <sbel@odoo.com>
This commit is contained in:
@@ -287,7 +287,7 @@ class PurchaseOrderLine(models.Model):
|
||||
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,
|
||||
partner_id=None,
|
||||
company_id=self.company_id.id,
|
||||
)
|
||||
self.name = self._get_product_purchase_description(product_lang)
|
||||
@@ -364,6 +364,8 @@ class PurchaseOrderLine(models.Model):
|
||||
# record product names to avoid resetting custom descriptions
|
||||
default_names = []
|
||||
vendors = line.product_id._prepare_sellers({})
|
||||
product_ctx = {'seller_id': None, 'partner_id': None, 'lang': get_lang(line.env, line.partner_id.lang).code}
|
||||
default_names.append(line._get_product_purchase_description(line.product_id.with_context(product_ctx)))
|
||||
for vendor in vendors:
|
||||
product_ctx = {'seller_id': vendor.id, 'lang': get_lang(line.env, line.partner_id.lang).code}
|
||||
default_names.append(line._get_product_purchase_description(line.product_id.with_context(product_ctx)))
|
||||
|
||||
@@ -572,3 +572,48 @@ class TestPurchase(AccountTestInvoicingCommon):
|
||||
|
||||
self.assertEqual(po1.order_line[0].price_unit, 100)
|
||||
self.assertEqual(po1.order_line[0].discount, 30)
|
||||
|
||||
def test_orderline_supplierinfo_description(self):
|
||||
supplierinfo_vals = {
|
||||
'partner_id': self.partner_a.id,
|
||||
'min_qty': 1,
|
||||
'product_id': self.product_a.id,
|
||||
'product_tmpl_id': self.product_a.product_tmpl_id.id,
|
||||
}
|
||||
|
||||
self.env["product.supplierinfo"].create([
|
||||
{
|
||||
**supplierinfo_vals,
|
||||
'price': 10,
|
||||
'product_name': 'Name 1',
|
||||
'product_code': 'Code 1',
|
||||
},
|
||||
{
|
||||
**supplierinfo_vals,
|
||||
'price': 20,
|
||||
'product_name': 'Name 2',
|
||||
'product_code': 'Code 2',
|
||||
},
|
||||
{
|
||||
'partner_id': self.partner_a.id,
|
||||
'min_qty': 1,
|
||||
'product_id': self.product_b.id,
|
||||
'product_tmpl_id': self.product_b.product_tmpl_id.id,
|
||||
'price': 5,
|
||||
'product_name': 'Name 3',
|
||||
'product_code': 'Code 3',
|
||||
}
|
||||
])
|
||||
|
||||
po_form = Form(self.env['purchase.order'])
|
||||
po_form.partner_id = self.partner_a
|
||||
with po_form.order_line.new() as line:
|
||||
line.product_id = self.product_a
|
||||
line.product_qty = 1
|
||||
po = po_form.save()
|
||||
self.assertEqual(po.order_line.name, '[Code 1] Name 1')
|
||||
|
||||
with po_form.order_line.edit(0) as line:
|
||||
line.product_id = self.product_b
|
||||
po = po_form.save()
|
||||
self.assertEqual(po.order_line.name, '[Code 3] Name 3')
|
||||
|
||||
Reference in New Issue
Block a user