From 52653a9d058ffdcbb365341d91af564ceb0418a6 Mon Sep 17 00:00:00 2001 From: "Walid HANNICHE (waha)" Date: Tue, 10 Oct 2023 17:46:28 +0200 Subject: [PATCH] [FIX] sale_purchase: service product preserve variant Steps to reproduce: -Install sale_purchase_stock and sale_product_matrix -Have a Service product that is subcontracted. -Set a variant with a Specification Attribute that has a custom value. -Create a sales order with the Service product, add anything for the specification in the variant. -Confirm the order, this generates a PO. Bug: The PO line only says the name of the product, and doesn't include the specification in the variant. Fix: propagate the description same as: "_prepare_procurement_values" and "_prepare_purchase_order_line_from_procurement" opw-3438125 closes odoo/odoo#138310 X-original-commit: 5b3bcee8f7308621608d91e33bac808586e8c17f Signed-off-by: Walid Hanniche (waha) Signed-off-by: Quentin Wolfs (quwo) --- .../sale_purchase/models/sale_order_line.py | 4 ++ .../sale_purchase/tests/test_sale_purchase.py | 47 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/addons/sale_purchase/models/sale_order_line.py b/addons/sale_purchase/models/sale_order_line.py index 76796327d6d..10a51d6e0d9 100644 --- a/addons/sale_purchase/models/sale_order_line.py +++ b/addons/sale_purchase/models/sale_order_line.py @@ -197,6 +197,10 @@ class SaleOrderLine(models.Model): price_unit, taxes = self._purchase_service_get_price_unit_and_taxes(supplierinfo, purchase_order) name = self._purchase_service_get_product_name(supplierinfo, purchase_order, quantity) + line_description = self.with_context(lang=self.order_id.partner_id.lang)._get_sale_order_line_multiline_description_variants() + if line_description: + name += line_description + return { 'name': name, 'product_qty': purchase_qty_uom, diff --git a/addons/sale_purchase/tests/test_sale_purchase.py b/addons/sale_purchase/tests/test_sale_purchase.py index afd4d238064..0347a70b700 100644 --- a/addons/sale_purchase/tests/test_sale_purchase.py +++ b/addons/sale_purchase/tests/test_sale_purchase.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo import Command from odoo.exceptions import UserError, AccessError from odoo.tests import tagged from odoo.addons.sale_purchase.tests.common import TestCommonSalePurchaseNoChart @@ -258,3 +259,49 @@ class TestSalePurchase(TestCommonSalePurchaseNoChart): po = self.env['purchase.order'].search([('partner_id', '=', self.partner_vendor_service.id)], order='id desc', limit=1) self.assertEqual(po.order_line.name, "[C01] Name01") + + def test_pol_custom_attribute(self): + """ + test that custom atributes are passed from the SO the PO for service products + """ + # Setup service product variants + product_attribute = self.env['product.attribute'].create({ + 'name': 'product attribute', + 'display_type': 'radio', + 'create_variant': 'always' + }) + + product_attribute_value = self.env['product.attribute.value'].create({ + 'name': 'single product attribute value', + 'is_custom': True, + 'attribute_id': product_attribute.id + }) + + product_attribute_line = self.env['product.template.attribute.line'].create({ + 'attribute_id': product_attribute.id, + 'product_tmpl_id': self.service_purchase_1.product_tmpl_id.id, + 'value_ids': [Command.link(product_attribute_value.id)] + }) + + custom_value = "test" + + # create and confirm SO + sale_order = self.env['sale.order'].create({ + 'partner_id': self.partner_a.id, + 'order_line': [ + Command.create({ + 'name': self.service_purchase_1.name, + 'product_id': self.service_purchase_1.id, + 'product_uom_qty': 1, + 'product_custom_attribute_value_ids': [ + Command.create({ + 'custom_product_template_attribute_value_id': product_attribute_line.product_template_value_ids.id, + 'custom_value': custom_value, + }) + ], + }) + ], + }) + sale_order.action_confirm() + pol = sale_order._get_purchase_orders().order_line + self.assertEqual(pol.name, f"{self.service_purchase_1.display_name}\n\n{product_attribute.name}: {product_attribute_value.name}: {custom_value}")