[FIX] mrp_subcontracting : generates BOM for dynamic attributes

Current Behavior:

Traceback when printing the BOM overview.

Expected behavior:

Generates a PDF of the BOM overview even if the information displayed
is entirely relevant.

Steps to reproduce:

Inventory > Configuration > Products > Attributes

Create an attribute with Variants Creation Mode set to "Dynamically".

Create a new product with this single attribute and multiple values.

Create a BOM for this product with BOM Type set to "Subcontracting".

Print the BOM overview.

Cause of the issue:

Creating such a product generates a 'product.template' that is not
associated to any variant and hence does not correspond to any
'product.product'. As a result the function_get_bom_data made can not
apply the method _select_seller properly in that case.

Notes:

 - There is no error if a variant was manually created for that product.
 - If the Variants Creation Mode set to "Dynamically" a variant is still
   automatically created to be associated to the product tempalte so
   that the erro does not rise.

Fix:

As the _select_seller method is only defined for product.product
and not for product.template, we can not not apply it here.
Furhtermore, since the additional informations provided by the
override of the method get_bom_data in the the BOM overview will
not be relevant without the existence of a variant, we skip this part of
the code when the argument of _select_seller is not valid.

opw-3698050

closes odoo/odoo#156346

X-original-commit: b983026f004d4958d2a47a0dac9b1b54e24ab04c
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Lancelot Semal (lase) <lase@odoo.com>
This commit is contained in:
lase@odoo.com
2024-03-05 14:22:22 +00:00
parent bd1c5a2699
commit 6fcd31cc21
2 changed files with 39 additions and 1 deletions
@@ -22,7 +22,10 @@ class ReportBomStructure(models.AbstractModel):
def _get_bom_data(self, bom, warehouse, product=False, line_qty=False, bom_line=False, level=0, parent_bom=False, parent_product=False, index=0, product_info=False, ignore_stock=False):
res = super()._get_bom_data(bom, warehouse, product, line_qty, bom_line, level, parent_bom, parent_product, index, product_info, ignore_stock)
if bom.type == 'subcontract' and not self.env.context.get('minimized', False):
seller = res['product']._select_seller(quantity=res['quantity'], uom_id=bom.product_uom_id, params={'subcontractor_ids': bom.subcontractor_ids})
if not res['product']:
seller = bom.product_tmpl_id.seller_ids.filtered(lambda s: s.partner_id in bom.subcontractor_ids)[:1]
else:
seller = res['product']._select_seller(quantity=res['quantity'], uom_id=bom.product_uom_id, params={'subcontractor_ids': bom.subcontractor_ids})
if seller:
res['subcontracting'] = self._get_subcontracting_line(bom, seller, level + 1, res['quantity'])
if not self.env.context.get('minimized', False):
@@ -1572,3 +1572,38 @@ class TestSubcontractingSerialMassReceipt(TransactionCase):
self.assertEqual(picking_receipt.state, 'done')
self.assertEqual(self.env['stock.quant']._get_available_quantity(self.raw_material, self.env.ref('stock.stock_location_stock')), 0)
self.assertEqual(self.env['stock.quant']._get_available_quantity(self.raw_material, self.subcontractor.property_stock_subcontractor, allow_negative=True), -quantity)
def test_bom_subcontracting_product_dynamic_attribute(self):
"""
Test that the report BOM data is available for a product with an dynamic attribute
but without variant.
"""
dynamic_attribute = self.env['product.attribute'].create({
'name': 'flavour',
'create_variant': 'dynamic',
})
value_1 = self.env['product.attribute.value'].create({
'name': 'Vanilla',
'attribute_id': dynamic_attribute.id,
})
value_2 = self.env['product.attribute.value'].create({
'name': 'Chocolate',
'attribute_id': dynamic_attribute.id,
})
product_template = self.env['product.template'].create({
'name': 'Cake',
'uom_id': self.env.ref('uom.product_uom_unit').id,
'detailed_type': 'product',
})
self.env['product.template.attribute.line'].create({
'product_tmpl_id': product_template.id,
'attribute_id': dynamic_attribute.id,
'value_ids': [Command.set([value_1.id, value_2.id])],
})
bom = self.env['mrp.bom'].create({
'product_tmpl_id': product_template.id,
'type': 'subcontract',
'subcontractor_ids': [Command.set([self.subcontractor.id])],
})
report_values = self.env['report.mrp.report_bom_structure']._get_report_data(bom_id=bom.id, searchVariant=False)
self.assertTrue(report_values)