Merge pull request #7236 from rohitwaghchaure/item_variant_issue

[Fix] Timeout error in item attribute validation
This commit is contained in:
Nabin Hait 2016-12-20 11:31:50 +05:30 committed by GitHub
commit 778c1a022d
2 changed files with 36 additions and 22 deletions

View File

@ -41,30 +41,37 @@ def validate_item_variant_attributes(item, args=None):
if attribute.lower() in numeric_values: if attribute.lower() in numeric_values:
numeric_attribute = numeric_values[attribute.lower()] numeric_attribute = numeric_values[attribute.lower()]
validate_is_incremental(numeric_attribute, attribute, value, item.name)
from_range = numeric_attribute.from_range else:
to_range = numeric_attribute.to_range attributes_list = attribute_values.get(attribute.lower(), [])
increment = numeric_attribute.increment validate_item_attribute_value(attributes_list, attribute, value, item.name)
if increment == 0: def validate_is_incremental(numeric_attribute, attribute, value, item):
# defensive validation to prevent ZeroDivisionError from_range = numeric_attribute.from_range
frappe.throw(_("Increment for Attribute {0} cannot be 0").format(attribute)) to_range = numeric_attribute.to_range
increment = numeric_attribute.increment
is_in_range = from_range <= flt(value) <= to_range if increment == 0:
precision = max(len(cstr(v).split(".")[-1].rstrip("0")) for v in (value, increment)) # defensive validation to prevent ZeroDivisionError
#avoid precision error by rounding the remainder frappe.throw(_("Increment for Attribute {0} cannot be 0").format(attribute))
remainder = flt((flt(value) - from_range) % increment, precision)
is_incremental = remainder==0 or remainder==increment is_in_range = from_range <= flt(value) <= to_range
precision = max(len(cstr(v).split(".")[-1].rstrip("0")) for v in (value, increment))
#avoid precision error by rounding the remainder
remainder = flt((flt(value) - from_range) % increment, precision)
if not (is_in_range and is_incremental): is_incremental = remainder==0 or remainder==increment
frappe.throw(_("Value for Attribute {0} must be within the range of {1} to {2} in the increments of {3} for Item {4}")\
.format(attribute, from_range, to_range, increment, item.name),
InvalidItemAttributeValueError, title=_('Invalid Attribute'))
elif value not in attribute_values.get(attribute.lower(), []): if not (is_in_range and is_incremental):
frappe.throw(_("Value {0} for Attribute {1} does not exist in the list of valid Item Attribute Values for Item {2}").format( frappe.throw(_("Value for Attribute {0} must be within the range of {1} to {2} in the increments of {3} for Item {4}")\
value, attribute, item.name), InvalidItemAttributeValueError, title=_('Invalid Attribute')) .format(attribute, from_range, to_range, increment, item),
InvalidItemAttributeValueError, title=_('Invalid Attribute'))
def validate_item_attribute_value(attributes_list, attribute, attribute_value, item):
if attribute_value not in attributes_list:
frappe.throw(_("Value {0} for Attribute {1} does not exist in the list of valid Item Attribute Values for Item {2}").format(
attribute_value, attribute, item), InvalidItemAttributeValueError, title=_('Invalid Attribute'))
def get_attribute_values(): def get_attribute_values():
if not frappe.flags.attribute_values: if not frappe.flags.attribute_values:

View File

@ -6,7 +6,8 @@ import frappe
from frappe.model.document import Document from frappe.model.document import Document
from frappe import _ from frappe import _
from erpnext.controllers.item_variant import validate_item_variant_attributes, InvalidItemAttributeValueError from erpnext.controllers.item_variant import (validate_is_incremental,
validate_item_attribute_value, InvalidItemAttributeValueError)
class ItemAttributeIncrementError(frappe.ValidationError): pass class ItemAttributeIncrementError(frappe.ValidationError): pass
@ -25,9 +26,15 @@ class ItemAttribute(Document):
def validate_exising_items(self): def validate_exising_items(self):
'''Validate that if there are existing items with attributes, they are valid''' '''Validate that if there are existing items with attributes, they are valid'''
for item in frappe.db.sql('''select distinct i.name from `tabItem Variant Attribute` iva, `tabItem` i attributes_list = [d.attribute_value for d in self.item_attribute_values]
where iva.attribute = %s and iva.parent = i.name and i.has_variants = 0''', self.name):
validate_item_variant_attributes(item[0]) for item in frappe.db.sql('''select i.name, iva.attribute_value as value
from `tabItem Variant Attribute` iva, `tabItem` i where iva.attribute = %s
and iva.parent = i.name and i.has_variants = 0''', self.name, as_dict=1):
if self.numeric_values:
validate_is_incremental(self, self.name, item.value, item.name)
else:
validate_item_attribute_value(attributes_list, self.name, item.value, item.name)
def validate_numeric(self): def validate_numeric(self):
if self.numeric_values: if self.numeric_values: