From 16abfd4410480055bd351d3e6979e83e92cda479 Mon Sep 17 00:00:00 2001 From: marination Date: Thu, 8 Jul 2021 12:52:57 +0530 Subject: [PATCH] fix: Sync Website Items on Item Change, Short Website Description - Added Short Description in Website Item for List View - Update Website Item on Item info change - Un-publish Web Item if Item is disabled - Removed unnecessary dependency on Item from query engine - Rearranged item detail fields in Website Item - Added Link to Website Item on Item Dashboard --- .../doctype/website_item/website_item.json | 20 +++++-- .../doctype/website_item/website_item.py | 59 +++++++++++-------- erpnext/e_commerce/product_list.js | 2 +- erpnext/e_commerce/product_query.py | 12 ++-- erpnext/stock/doctype/item/item.json | 8 ++- erpnext/stock/doctype/item/item.py | 24 ++++++++ 6 files changed, 87 insertions(+), 38 deletions(-) diff --git a/erpnext/e_commerce/doctype/website_item/website_item.json b/erpnext/e_commerce/doctype/website_item/website_item.json index f5eb2ddb53..9581539d2e 100644 --- a/erpnext/e_commerce/doctype/website_item/website_item.json +++ b/erpnext/e_commerce/doctype/website_item/website_item.json @@ -19,6 +19,8 @@ "item_name", "item_group", "stock_uom", + "column_break_11", + "description", "brand", "image", "display_section", @@ -28,12 +30,12 @@ "slideshow", "thumbnail", "section_break_17", + "short_description", + "web_long_description", + "column_break_27", "website_warehouse", - "description", "website_specifications", "copy_from_item_group", - "column_break_27", - "web_long_description", "display_additional_information_section", "show_tabbed_section", "tabs", @@ -300,13 +302,23 @@ "fieldtype": "Table", "label": "Offers to Display", "options": "Website Offer" + }, + { + "fieldname": "column_break_11", + "fieldtype": "Column Break" + }, + { + "description": "Short Description for List View", + "fieldname": "short_description", + "fieldtype": "Data", + "label": "Short Website Description" } ], "has_web_view": 1, "image_field": "image", "index_web_pages_for_search": 1, "links": [], - "modified": "2021-04-22 15:29:13.541145", + "modified": "2021-07-08 12:22:23.466598", "modified_by": "Administrator", "module": "E-commerce", "name": "Website Item", diff --git a/erpnext/e_commerce/doctype/website_item/website_item.py b/erpnext/e_commerce/doctype/website_item/website_item.py index 954ab0f273..3331532ec1 100644 --- a/erpnext/e_commerce/doctype/website_item/website_item.py +++ b/erpnext/e_commerce/doctype/website_item/website_item.py @@ -44,9 +44,16 @@ class WebsiteItem(WebsiteGenerator): self.publish_unpublish_desk_item(publish=True) if not self.get("__islocal"): - self.old_website_item_groups = frappe.db.sql_list("""select item_group - from `tabWebsite Item Group` - where parentfield='website_item_groups' and parenttype='Item' and parent=%s""", self.name) + self.old_website_item_groups = frappe.db.sql_list(""" + select + item_group + from + `tabWebsite Item Group` + where + parentfield='website_item_groups' + and parenttype='Website Item' + and parent=%s + """, self.name) def on_update(self): invalidate_cache_for_web_item(self) @@ -389,6 +396,28 @@ def invalidate_cache_for_web_item(doc): invalidate_item_variants_cache_for_website(doc) +def on_doctype_update(): + # since route is a Text column, it needs a length for indexing + frappe.db.add_index("Website Item", ["route(500)"]) + +def check_if_user_is_customer(user=None): + from frappe.contacts.doctype.contact.contact import get_contact_name + + if not user: + user = frappe.session.user + + contact_name = get_contact_name(user) + customer = None + + if contact_name: + contact = frappe.get_doc('Contact', contact_name) + for link in contact.links: + if link.link_doctype == "Customer": + customer = link.link_name + break + + return True if customer else False + @frappe.whitelist() def make_website_item(doc, save=True): if not doc: @@ -417,26 +446,4 @@ def make_website_item(doc, save=True): # Add to search cache insert_item_to_index(website_item) - return [website_item.name, website_item.web_item_name] - -def on_doctype_update(): - # since route is a Text column, it needs a length for indexing - frappe.db.add_index("Website Item", ["route(500)"]) - -def check_if_user_is_customer(user=None): - from frappe.contacts.doctype.contact.contact import get_contact_name - - if not user: - user = frappe.session.user - - contact_name = get_contact_name(user) - customer = None - - if contact_name: - contact = frappe.get_doc('Contact', contact_name) - for link in contact.links: - if link.link_doctype == "Customer": - customer = link.link_name - break - - return True if customer else False \ No newline at end of file + return [website_item.name, website_item.web_item_name] \ No newline at end of file diff --git a/erpnext/e_commerce/product_list.js b/erpnext/e_commerce/product_list.js index 6c7d7ff7dc..8fc8da8050 100644 --- a/erpnext/e_commerce/product_list.js +++ b/erpnext/e_commerce/product_list.js @@ -102,7 +102,7 @@ erpnext.ProductList = class { Item Code : ${ item.item_code }

- ${ item.description || '' } + ${ item.short_description || '' }
${ item.formatted_price || '' } diff --git a/erpnext/e_commerce/product_query.py b/erpnext/e_commerce/product_query.py index 8c7ab1fad1..e5af7e1bec 100644 --- a/erpnext/e_commerce/product_query.py +++ b/erpnext/e_commerce/product_query.py @@ -23,7 +23,7 @@ class ProductQuery: self.page_length = self.settings.products_per_page or 20 self.fields = ['web_item_name', 'name', 'item_name', 'item_code', 'website_image', 'variant_of', 'has_variants', 'item_group', 'image', 'web_long_description', - 'description', 'route', 'website_warehouse', 'ranking'] + 'short_description', 'route', 'website_warehouse', 'ranking'] self.filters = [["published", "=", 1]] self.or_filters = [] @@ -178,7 +178,7 @@ class ProductQuery: continue # handle multiselect fields in filter addition - meta = frappe.get_meta('Item', cached=True) + meta = frappe.get_meta('Website Item', cached=True) df = meta.get_field(field) if df.fieldtype == 'Table MultiSelect': child_doctype = df.options @@ -200,16 +200,16 @@ class ProductQuery: search_term (str): Search candidate """ # Default fields to search from - default_fields = {'name', 'item_name', 'description', 'item_group'} + default_fields = {'item_code', 'item_name', 'web_long_description', 'item_group'} # Get meta search fields - meta = frappe.get_meta("Item") + meta = frappe.get_meta("Website Item") meta_fields = set(meta.get_search_fields()) # Join the meta fields and default fields set search_fields = default_fields.union(meta_fields) - if frappe.db.count('Item', cache=True) > 50000: - search_fields.discard('description') + if frappe.db.count('Website Item', cache=True) > 50000: + search_fields.discard('web_long_description') # Build or filters for query search = '%{}%'.format(search_term) diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json index 50e9f0af27..63243e6b31 100644 --- a/erpnext/stock/doctype/item/item.json +++ b/erpnext/stock/doctype/item/item.json @@ -899,7 +899,13 @@ "idx": 2, "image_field": "image", "index_web_pages_for_search": 1, - "links": [], + "links": [ + { + "group": "E-commerce", + "link_doctype": "Website Item", + "link_fieldname": "item_code" + } + ], "max_attachments": 1, "modified": "2021-10-27 21:04:00.324786", "modified_by": "Administrator", diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index 82eef26973..410e8ac68a 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -136,6 +136,7 @@ class Item(Document): invalidate_cache_for_item(self) self.update_variants() self.update_item_price() + self.update_website_item() def validate_description(self): '''Clean HTML description if set''' @@ -234,6 +235,29 @@ class Item(Document): [self.remove(d) for d in to_remove] + def update_website_item(self): + """Update Website Item if change in Item impacts it.""" + web_item = frappe.db.exists("Website Item", {"item_code": self.item_code}) + + if web_item: + changed = {} + editable_fields = ["item_name", "item_group", "stock_uom", "brand", "description", + "disabled"] + doc_before_save = self.get_doc_before_save() + + for field in editable_fields: + if doc_before_save.get(field) != self.get(field): + if field == "disabled": + changed["published"] = not self.get(field) + else: + changed[field] = self.get(field) + + if not changed: return + + web_item_doc = frappe.get_doc("Website Item", web_item) + web_item_doc.update(changed) + web_item_doc.save() + def validate_item_tax_net_rate_range(self): for tax in self.get('taxes'): if flt(tax.maximum_net_rate) < flt(tax.minimum_net_rate):