[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:
@@ -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
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user