[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:
Sarah Bellefroid
2024-04-08 14:37:50 +00:00
parent 8b5e912137
commit 82bf645341
2 changed files with 48 additions and 1 deletions
@@ -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)))
+45
View File
@@ -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')