2019-03-19 06:18:32 +00:00
|
|
|
import frappe
|
|
|
|
|
2021-09-02 11:14:59 +00:00
|
|
|
|
2019-03-19 06:18:32 +00:00
|
|
|
class ItemVariantsCacheManager:
|
|
|
|
def __init__(self, item_code):
|
|
|
|
self.item_code = item_code
|
|
|
|
|
|
|
|
def get_item_variants_data(self):
|
|
|
|
val = frappe.cache().hget('item_variants_data', self.item_code)
|
|
|
|
|
|
|
|
if not val:
|
|
|
|
self.build_cache()
|
|
|
|
|
|
|
|
return frappe.cache().hget('item_variants_data', self.item_code)
|
|
|
|
|
|
|
|
|
|
|
|
def get_attribute_value_item_map(self):
|
|
|
|
val = frappe.cache().hget('attribute_value_item_map', self.item_code)
|
|
|
|
|
|
|
|
if not val:
|
|
|
|
self.build_cache()
|
|
|
|
|
|
|
|
return frappe.cache().hget('attribute_value_item_map', self.item_code)
|
|
|
|
|
|
|
|
|
|
|
|
def get_item_attribute_value_map(self):
|
|
|
|
val = frappe.cache().hget('item_attribute_value_map', self.item_code)
|
|
|
|
|
|
|
|
if not val:
|
|
|
|
self.build_cache()
|
|
|
|
|
|
|
|
return frappe.cache().hget('item_attribute_value_map', self.item_code)
|
|
|
|
|
|
|
|
|
|
|
|
def get_optional_attributes(self):
|
|
|
|
val = frappe.cache().hget('optional_attributes', self.item_code)
|
|
|
|
|
|
|
|
if not val:
|
|
|
|
self.build_cache()
|
|
|
|
|
|
|
|
return frappe.cache().hget('optional_attributes', self.item_code)
|
|
|
|
|
2019-04-15 17:49:44 +00:00
|
|
|
def get_ordered_attribute_values(self):
|
|
|
|
val = frappe.cache().get_value('ordered_attribute_values_map')
|
|
|
|
if val: return val
|
|
|
|
|
|
|
|
all_attribute_values = frappe.db.get_all('Item Attribute Value',
|
|
|
|
['attribute_value', 'idx', 'parent'], order_by='idx asc')
|
|
|
|
|
|
|
|
ordered_attribute_values_map = frappe._dict({})
|
|
|
|
for d in all_attribute_values:
|
|
|
|
ordered_attribute_values_map.setdefault(d.parent, []).append(d.attribute_value)
|
|
|
|
|
|
|
|
frappe.cache().set_value('ordered_attribute_values_map', ordered_attribute_values_map)
|
|
|
|
return ordered_attribute_values_map
|
2019-03-19 06:18:32 +00:00
|
|
|
|
|
|
|
def build_cache(self):
|
|
|
|
parent_item_code = self.item_code
|
|
|
|
|
|
|
|
attributes = [a.attribute for a in frappe.db.get_all('Item Variant Attribute',
|
|
|
|
{'parent': parent_item_code}, ['attribute'], order_by='idx asc')
|
|
|
|
]
|
|
|
|
|
|
|
|
item_variants_data = frappe.db.get_all('Item Variant Attribute',
|
|
|
|
{'variant_of': parent_item_code}, ['parent', 'attribute', 'attribute_value'],
|
2019-04-29 17:11:24 +00:00
|
|
|
order_by='name',
|
2019-03-19 06:18:32 +00:00
|
|
|
as_list=1
|
|
|
|
)
|
|
|
|
|
2021-09-15 08:30:14 +00:00
|
|
|
unpublished_items = set([i.item_code for i in frappe.db.get_all('Website Item', filters={'published': 0}, fields=["item_code"])])
|
2019-05-01 12:49:24 +00:00
|
|
|
|
2019-03-19 06:18:32 +00:00
|
|
|
attribute_value_item_map = frappe._dict({})
|
|
|
|
item_attribute_value_map = frappe._dict({})
|
|
|
|
|
2021-09-15 08:30:14 +00:00
|
|
|
# dont consider variants that are unpublished
|
|
|
|
# (either have no Website Item or are unpublished in Website Item)
|
|
|
|
item_variants_data = [r for r in item_variants_data if r[0] not in unpublished_items]
|
|
|
|
item_variants_data = [r for r in item_variants_data if frappe.db.exists("Website Item", {"item_code": r[0]})]
|
|
|
|
|
2019-03-19 06:18:32 +00:00
|
|
|
for row in item_variants_data:
|
|
|
|
item_code, attribute, attribute_value = row
|
|
|
|
# (attr, value) => [item1, item2]
|
|
|
|
attribute_value_item_map.setdefault((attribute, attribute_value), []).append(item_code)
|
|
|
|
# item => {attr1: value1, attr2: value2}
|
|
|
|
item_attribute_value_map.setdefault(item_code, {})[attribute] = attribute_value
|
|
|
|
|
|
|
|
optional_attributes = set()
|
|
|
|
for item_code, attr_dict in item_attribute_value_map.items():
|
|
|
|
for attribute in attributes:
|
|
|
|
if attribute not in attr_dict:
|
|
|
|
optional_attributes.add(attribute)
|
|
|
|
|
|
|
|
frappe.cache().hset('attribute_value_item_map', parent_item_code, attribute_value_item_map)
|
|
|
|
frappe.cache().hset('item_attribute_value_map', parent_item_code, item_attribute_value_map)
|
|
|
|
frappe.cache().hset('item_variants_data', parent_item_code, item_variants_data)
|
|
|
|
frappe.cache().hset('optional_attributes', parent_item_code, optional_attributes)
|
|
|
|
|
|
|
|
def clear_cache(self):
|
|
|
|
keys = ['attribute_value_item_map', 'item_attribute_value_map', 'item_variants_data', 'optional_attributes']
|
|
|
|
|
|
|
|
for key in keys:
|
|
|
|
frappe.cache().hdel(key, self.item_code)
|
|
|
|
|
2019-05-04 17:08:13 +00:00
|
|
|
def rebuild_cache(self):
|
|
|
|
self.clear_cache()
|
|
|
|
enqueue_build_cache(self.item_code)
|
|
|
|
|
2019-03-19 06:18:32 +00:00
|
|
|
|
|
|
|
def build_cache(item_code):
|
|
|
|
frappe.cache().hset('item_cache_build_in_progress', item_code, 1)
|
|
|
|
i = ItemVariantsCacheManager(item_code)
|
|
|
|
i.build_cache()
|
|
|
|
frappe.cache().hset('item_cache_build_in_progress', item_code, 0)
|
|
|
|
|
|
|
|
def enqueue_build_cache(item_code):
|
|
|
|
if frappe.cache().hget('item_cache_build_in_progress', item_code):
|
|
|
|
return
|
2019-07-04 13:22:32 +00:00
|
|
|
frappe.enqueue(build_cache, item_code=item_code, queue='long')
|