[IMP] product*: create product and variant by xml file

before this commit:
===================
you can not create xml record for product.template and product.product and link them for same product
if you like to achieve it you need to do it like

```
<record id="product_template_1" model="product.template">
    <field name="name">Box</field>
    .
    .
    .
    <field name="list_price">8000.0</field>
</record>
<record id="product_template_attribute_line_1" model="product.template.attribute.line">
    <field name="product_tmpl_id" ref="product_template_1"/>
    <field name="attribute_id" ref="product_attribute_color"/>
    <field name="value_ids" eval="[(6, 0, [ref('product.product_attribute_value_1'), ref('product.product_attribute_value_2')])]"/>
</record>

<function model="ir.model.data" name="_update_xmlids">
    <value model="base" eval="[{
        'xml_id': 'product.product_template_attribute_value_1',
        'record': obj().env.ref('product.product_template_attribute_line_1').product_template_value_ids[0],
        'noupdate': True,
    }, {
        'xml_id': 'product.product_template_attribute_value_2',
        'record': obj().env.ref('product.product_template_attribute_line_1').product_template_value_ids[1],
        'noupdate': True,
    },]"/>
</function>

<function model="ir.model.data" name="_update_xmlids">
    <value model="base" eval="[{
        'xml_id': 'product.product_product_red',
        'record': obj().env.ref('product.product_template_1')._get_variant_for_combination( obj().env.ref('product.product_template_attribute_value_1')),
        'noupdate': True,
    }, {
        'xml_id': 'product.product_product_4b',
        'record': obj().env.ref('product.product_template_1')._get_variant_for_combination( obj().env.ref('product.product_template_attribute_value_2')),
        'noupdate': True,
    }]"/>
</function>
```

after this commit:
==================
you can create product.tempalte and product.product from xml file and link it manully by attribute value

like
```
<record id="product_template_1" model="product.template" context="{'create_product_product': False}">
    <field name="name">Box</field>
    .
    .
    .
    <field name="list_price">8000.0</field>
</record>

<record id="product_template_attribute_line_1" model="product.template.attribute.line" context="{'create_product_product': False}">
    <field name="product_tmpl_id" ref="product_template_1"/>
    <field name="attribute_id" ref="product_attribute_color"/>
    <field name="value_ids" eval="[(6, 0, [ref('product_attribute_value_blue'), ref('product_attribute_value_red')])]"/>
</record>

<record id="product_template_attribute_value_1" model="product.template.attribute.value">
    <field name="attribute_line_id" ref="product_template_attribute_line_1"/>
    <field name="product_tmpl_id" ref="product_template_1"/>
    <field name="attribute_id" ref="product_attribute_color"/>
    <field name="product_attribute_value_id" ref="product_attribute_value_blue"/>
</record>

<record id="product_product_blue" model="product.product">
    <field name="product_tmpl_id" ref="software_reseller.product_template_1"/>
    .
    .
    .
    <field name="product_template_variant_value_ids" eval="[(6, 0, [ref('product_template_attribute_value_1')])]"/>
</record>

<record id="product_template_attribute_value_2" model="product.template.attribute.value">
    <field name="attribute_line_id" ref="product_template_attribute_line_1"/>
    <field name="product_tmpl_id" ref="product_template_1"/>
    <field name="attribute_id" ref="product_attribute_color"/>
    <field name="product_attribute_value_id" ref="product_attribute_value_red"/>
</record>

<record id="product_product_red" model="product.product">
    <field name="product_tmpl_id" ref="software_reseller.product_template_1"/>
    .
    .
    .
    <field name="product_template_variant_value_ids" eval="[(6, 0, [ref('product_template_attribute_value_2')])]"/>
</record>
```

closes odoo/odoo#139669

Signed-off-by: Pierre Masereel (pim) <pim@odoo.com>
This commit is contained in:
Jigar Vaghela
2023-10-25 19:37:26 +00:00
parent 96e3f27424
commit 7389345696
6 changed files with 13 additions and 9 deletions
+1 -1
View File
@@ -356,7 +356,7 @@ class ProductProduct(models.Model):
def create(self, vals_list):
for vals in vals_list:
self.product_tmpl_id._sanitize_vals(vals)
products = super(ProductProduct, self.with_context(create_product_product=True)).create(vals_list)
products = super(ProductProduct, self.with_context(create_product_product=False)).create(vals_list)
# `_get_variant_id_for_combination` depends on existing variants
self.env.registry.clear_cache()
return products
+2 -3
View File
@@ -462,7 +462,7 @@ class ProductTemplate(models.Model):
for vals in vals_list:
self._sanitize_vals(vals)
templates = super(ProductTemplate, self).create(vals_list)
if "create_product_product" not in self._context:
if self._context.get("create_product_product", True):
templates._create_variant_ids()
# This is needed to set given values to first variant after creation
@@ -484,7 +484,7 @@ class ProductTemplate(models.Model):
if uom_id and uom_po_id and uom_id.category_id != uom_po_id.category_id:
vals['uom_po_id'] = uom_id.id
res = super(ProductTemplate, self).write(vals)
if 'attribute_line_ids' in vals or (vals.get('active') and len(self.product_variant_ids) == 0):
if self._context.get("create_product_product", True) and 'attribute_line_ids' in vals or (vals.get('active') and len(self.product_variant_ids) == 0):
self._create_variant_ids()
if 'active' in vals and not vals.get('active'):
self.with_context(active_test=False).mapped('product_variant_ids').write({'active': vals.get('active')})
@@ -672,7 +672,6 @@ class ProductTemplate(models.Model):
def _create_variant_ids(self):
if not self:
return
self.env.flush_all()
Product = self.env["product.product"]
@@ -103,7 +103,8 @@ class ProductTemplateAttributeLine(models.Model):
else:
create_values.append(value)
res = activated_lines + super().create(create_values)
res._update_product_template_attribute_values()
if self._context.get("create_product_product", True):
res._update_product_template_attribute_values()
return res
def write(self, values):
@@ -71,7 +71,7 @@ class ProductTemplateAttributeValue(models.Model):
@api.constrains('attribute_line_id', 'product_attribute_value_id')
def _check_valid_values(self):
for ptav in self:
if ptav.product_attribute_value_id not in ptav.attribute_line_id.value_ids:
if ptav.ptav_active and ptav.product_attribute_value_id not in ptav.attribute_line_id.value_ids:
raise ValidationError(_(
"The value %(value)s is not defined for the attribute %(attribute)s"
" on the product %(product)s.",
+4
View File
@@ -229,6 +229,10 @@ class TestVariants(ProductVariantsCommon):
self.assertEqual(template_dyn.name, 'Test Dynamical')
variant_dyn = template_dyn._create_product_variant(template_dyn._get_first_possible_combination())
if 'create_product_product' in variant_dyn._context:
new_context = dict(variant_dyn._context)
new_context.pop('create_product_product')
variant_dyn = variant_dyn.with_context(new_context)
self.assertEqual(len(template_dyn.product_variant_ids), 1)
variant_dyn_copy = variant_dyn.copy()
@@ -91,7 +91,7 @@ class TestWebsiteSaleImage(odoo.tests.HttpCase):
image_png = base64.b64encode(f.read())
# create the template, without creating the variants
template = self.env['product.template'].with_context(create_product_product=True).create({
template = self.env['product.template'].with_context(create_product_product=False).create({
'name': 'A Colorful Image',
'product_template_image_ids': [(0, 0, {'name': 'image 1', 'image_1920': image_gif}), (0, 0, {'name': 'image 4', 'image_1920': image_svg})],
})
@@ -301,7 +301,7 @@ class TestWebsiteSaleImage(odoo.tests.HttpCase):
}])
# create the template, without creating the variants
template = self.env['product.template'].with_context(create_product_product=True).create({
template = self.env['product.template'].with_context(create_product_product=False).create({
'name': 'Test subject',
})
@@ -380,7 +380,7 @@ class TestEnvironmentWebsiteSaleImage(odoo.tests.HttpCase):
f.seek(0)
blue_image = base64.b64encode(f.read())
self.template = self.env['product.template'].with_context(create_product_product=True).create({
self.template = self.env['product.template'].with_context(create_product_product=False).create({
'name': 'Test Remove Image',
'image_1920': blue_image,
})