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

Commit

Permalink
[ENH] Raise more meaningful configuration warnings.
Browse files Browse the repository at this point in the history
  • Loading branch information
Richard deMeester committed Mar 22, 2017
1 parent ac44da3 commit aa7f406
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 15 deletions.
42 changes: 29 additions & 13 deletions product_configurator/models/product.py
Expand Up @@ -340,7 +340,7 @@ def create_variant(self, value_ids, custom_values=None):
"""
if custom_values is None:
custom_values = {}
valid = self.validate_configuration(value_ids, custom_values)
valid = self.validate_configuration(value_ids, custom_values, do_raise=True)
if not valid:
raise ValidationError(_('Invalid Configuration'))
# TODO: Add all custom values to order line instead of product
Expand All @@ -353,7 +353,7 @@ def create_variant(self, value_ids, custom_values=None):
# also a better method for building the domain using the logical
# operators is required
@api.multi
def value_available(self, attr_val_id, value_ids):
def value_available(self, attr_val_id, value_ids, do_raise=False):
"""Determines whether the attr_value from the product_template
is available for selection given the configuration ids and the
dependencies set on the product template
Expand All @@ -369,19 +369,25 @@ def value_available(self, attr_val_id, value_ids):
lambda l: attr_val_id in l.value_ids.ids
)

domains = config_lines.mapped('domain_id').compute_domain()

for domain in domains:
if domain[1] == 'in':
if not set(domain[2]) & set(value_ids):
return False
else:
if set(domain[2]) & set(value_ids):
return False
for config_line in config_lines:
domains = config_line.mapped('domain_id').compute_domain()
for domain in domains:
if domain[1] == 'in':
if not set(domain[2]) & set(value_ids):
# Don't break if the module has not been upgraded...
if do_raise and 'rule_description' in config_line._fields and config_line.rule_description:
raise ValidationError(config_line.rule_description)
return False
else:
if set(domain[2]) & set(value_ids):
# Don't break if the module has not been upgraded...
if do_raise and 'rule_description' in config_line._fields and config_line.rule_description:
raise ValidationError(config_line.rule_description)
return False
return True

@api.multi
def validate_configuration(self, value_ids, custom_vals=None, final=True):
def validate_configuration(self, value_ids, custom_vals=None, final=True, do_raise=False):
""" Verifies if the configuration values passed via value_ids and custom_vals
are valid
Expand All @@ -407,21 +413,31 @@ def validate_configuration(self, value_ids, custom_vals=None, final=True):
common_vals = set(value_ids) & set(line.value_ids.ids)
custom_val = custom_vals.get(attr.id)
if line.required and not common_vals and not custom_val:
if do_raise:
raise ValidationError(_("No value provided for %s") % line.attribute.name)
# TODO: Verify custom value type to be correct
return False

# Check if all all the values passed are not restricted
for val in value_ids:
available = self.value_available(
val, [v for v in value_ids if v != val])
val, [v for v in value_ids if v != val], do_raise=do_raise)
if not available:
# if do_raise is True, we may have already raised a specific error message.
# if not, then raise a more generic one...
if do_raise:
attr_val = self.env['product.attribute.value'].browse(val)
raise ValidationError(_("%s can not be selected for %s") % (attr_val.name, attr_val.attribute_id.name))
return False

# Check if custom values are allowed
custom_attr_ids = self.attribute_line_ids.filtered(
'custom').mapped('attribute_id').ids

if not set(custom_vals.keys()) <= set(custom_attr_ids):
if do_raise:
# TODO: Provide a proper error description for this.
raise ValidationError(_())
return False

# Check if there are multiple values passed for non-multi attributes
Expand Down
6 changes: 4 additions & 2 deletions product_configurator/models/product_config.py
Expand Up @@ -121,6 +121,8 @@ def _get_domain_operators(self):
class ProductConfigLine(models.Model):
_name = 'product.config.line'

rule_description = fields.Char(string='Rule Description', help='User Displayed error if rule is broken')

# TODO: Prevent config lines having dependencies that are not set in other
# config lines
# TODO: Prevent circular depdencies: Length -> Color, Color -> Length
Expand Down Expand Up @@ -211,7 +213,7 @@ def _check_value_ids(self):
if not valid:
raise ValidationError(
_("Values entered for line '%s' generate "
"a incompatible configuration" % cfg_img.name)
"an incompatible configuration" % cfg_img.name)
)


Expand Down Expand Up @@ -433,7 +435,7 @@ def write(self, vals):
for x in self.custom_value_ids
}
valid = self.product_tmpl_id.validate_configuration(
self.value_ids.ids, custom_val_dict, final=False)
self.value_ids.ids, custom_val_dict, final=False, do_raise=True)
if not valid:
raise ValidationError(_('Invalid Configuration'))
return res
Expand Down
1 change: 1 addition & 0 deletions product_configurator/views/product_view.xml
Expand Up @@ -63,6 +63,7 @@
options="{'no_create': True, 'no_create_edit': True}"
context="{'show_attribute': False}"/>
<field name="domain_id"/>
<field name="rule_description" />
</tree>
</field>
<separator colspan="4" string="Configuration Steps"/>
Expand Down

0 comments on commit aa7f406

Please sign in to comment.