Skip to content
This repository was archived by the owner on Apr 28, 2022. It is now read-only.

[ENH] New copy functionality. #65

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions product_configurator/models/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,10 +472,8 @@ def name_search(self, name='', args=None, operator='ilike', limit=100):
def create_variant_ids(self):
""" Prevent configurable products from creating variants as these serve
only as a template for the product configurator"""
for product in self:
if self.config_ok:
return None
return super(ProductTemplate, self).create_variant_ids()
regular_templates = self.filtered(lambda t: not t.config_ok)
return super(ProductTemplate, regular_templates).create_variant_ids()

@api.multi
def unlink(self):
Expand Down Expand Up @@ -606,3 +604,18 @@ def _compute_name(self):
product.config_name = product.get_config_name()
else:
product.config_name = product.name

@api.multi
def copy_configurable(self):
""" Creates a new product.variant with the same attributes, needed to
ensure custom_values are correctly recreated and not just pointed
to by the original"""
self.ensure_one()
assert self.config_ok

attribute_values = self.attribute_value_ids.ids
custom_vals = {v.attribute_id.id: v.value or v.attachment_ids.ids
for v in self.value_custom_ids}
new_product = self.product_tmpl_id.create_variant(
attribute_values, custom_vals)
return new_product
15 changes: 13 additions & 2 deletions product_configurator/models/sale.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-

from odoo import models, fields

from odoo import models, fields, api

# class sale_order_line_attribute(models.Model):
# _name = 'sale.order.line.attribute'
Expand All @@ -21,3 +20,15 @@ class SaleOrderLine(models.Model):
)

product_id = fields.Many2one(domain=[('config_ok', '=', False)])

@api.multi
def copy(self, default=None):
""" Ensure when a line is copied, it creates to a new configuration,
not just points to the original. Without this, changing one
configuration changes everywhere it appears.
"""
if default is None:
default = {}
if 'product_id' not in default and self.product_id.config_ok:
default['product_id'] = self.product_id.copy_configurable().id
return super(SaleOrderLine, self).copy(default=default)
2 changes: 1 addition & 1 deletion product_configurator/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-

from . import test_configuration_rules
from . import test_configuration_rules, test_product
53 changes: 53 additions & 0 deletions product_configurator/tests/test_product.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-

from odoo.tests.common import TransactionCase


class ProductVariant(TransactionCase):

def setUp(self):
super(ProductVariant, self).setUp()
self.cfg_tmpl = self.env.ref('product_configurator.bmw_2_series')

attribute_vals = self.cfg_tmpl.attribute_line_ids.mapped('value_ids')

self.attr_val_ext_ids = {
v: k for k, v in attribute_vals.get_external_id().iteritems()
}

def get_attr_val_ids(self, ext_ids):
"""Return a list of database ids using the external_ids
passed via ext_ids argument"""

value_ids = []

attr_val_prefix = 'product_configurator.product_attribute_value_%s'

for ext_id in ext_ids:
if ext_id in self.attr_val_ext_ids:
value_ids.append(self.attr_val_ext_ids[ext_id])
elif attr_val_prefix % ext_id in self.attr_val_ext_ids:
value_ids.append(
self.attr_val_ext_ids[attr_val_prefix % ext_id]
)

return value_ids

def test_product_create_and_copy(self):
"""Test creation and copy of a variant"""

conf = [
'gasoline', '228i', 'model_luxury_line', 'silver', 'rims_384',
'tapistry_black', 'steptronic', 'smoker_package', 'tow_hook'
]

attr_val_ids = self.get_attr_val_ids(conf)
product = self.cfg_tmpl.create_variant(attr_val_ids)
self.assertTrue(
set(attr_val_ids) == set(product.attribute_value_ids.ids),
"Product not created with correct attributes")
product2 = product.copy_configurable()
self.assertTrue(
set(product.attribute_value_ids.ids) ==
set(product2.attribute_value_ids.ids),
"Product configuration copy failed")