From 37a246e7388f3c9020a17684ef51cf53798f39ec Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 23 Feb 2021 14:06:38 +0530 Subject: [PATCH] chore: Patches for Website Item - Patch to make website item from item - Patch to move Products and Shopping Cart Settings into E Commerce Settings - Patch to move products in Homepage from Item to Website Item - Minor cleanup, replacing/removing references to Item website fields (obsolete) --- .../doctype/coupon_code/test_coupon_code.py | 1 - .../e_commerce_settings.py | 5 ++ .../doctype/website_item/website_item.py | 13 +++-- erpnext/patches.txt | 3 + erpnext/patches/v13_0/create_website_items.py | 45 ++++++++++++++ .../make_homepage_products_website_items.py | 13 +++++ .../v13_0/populate_e_commerce_settings.py | 58 +++++++++++++++++++ erpnext/portal/doctype/homepage/homepage.py | 10 ++-- erpnext/shopping_cart/cart.py | 2 +- .../item_variant_settings.py | 3 +- erpnext/templates/pages/home.py | 2 +- 11 files changed, 142 insertions(+), 13 deletions(-) create mode 100644 erpnext/patches/v13_0/create_website_items.py create mode 100644 erpnext/patches/v13_0/make_homepage_products_website_items.py create mode 100644 erpnext/patches/v13_0/populate_e_commerce_settings.py diff --git a/erpnext/accounts/doctype/coupon_code/test_coupon_code.py b/erpnext/accounts/doctype/coupon_code/test_coupon_code.py index b27f4eb503..9d34cc2fbb 100644 --- a/erpnext/accounts/doctype/coupon_code/test_coupon_code.py +++ b/erpnext/accounts/doctype/coupon_code/test_coupon_code.py @@ -41,7 +41,6 @@ def test_create_test_data(): "selling_cost_center": "Main - _TC", "income_account": "Sales - _TC" }], - "route":"-test-tesla-car", }) item.insert() # create test item price diff --git a/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.py b/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.py index 3fabc1a9b5..a6e21b5f47 100644 --- a/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.py +++ b/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.py @@ -22,6 +22,7 @@ class ECommerceSettings(Document): self.validate_field_filters() self.validate_attribute_filters() + self.validate_checkout() if self.enabled: self.validate_exchange_rates_exist() @@ -43,6 +44,10 @@ class ECommerceSettings(Document): # if attribute filters are enabled, hide_variants should be disabled self.hide_variants = 0 + def validate_checkout(self): + if self.enable_checkout and not self.payment_gateway_account: + self.enable_checkout = 0 + def validate_exchange_rates_exist(self): """check if exchange rates exist for all Price List currencies (to company's currency)""" company_currency = frappe.get_cached_value('Company', self.company, "default_currency") diff --git a/erpnext/e_commerce/doctype/website_item/website_item.py b/erpnext/e_commerce/doctype/website_item/website_item.py index 64655716b4..5587af7fd3 100644 --- a/erpnext/e_commerce/doctype/website_item/website_item.py +++ b/erpnext/e_commerce/doctype/website_item/website_item.py @@ -6,6 +6,7 @@ from __future__ import unicode_literals import frappe import json import itertools +from six import string_types from frappe import _ from frappe.website.website_generator import WebsiteGenerator @@ -340,10 +341,11 @@ def invalidate_cache_for_web_item(doc): invalidate_item_variants_cache_for_website(doc) @frappe.whitelist() -def make_website_item(doc): - if not doc: - return - doc = json.loads(doc) +def make_website_item(doc, save=True): + if not doc: return + + if isinstance(doc, string_types): + doc = json.loads(doc) if frappe.db.exists("Website Item", {"item_code": doc.get("item_code")}): message = _("Website Item already exists against {0}").format(frappe.bold(doc.get("item_code"))) @@ -357,6 +359,9 @@ def make_website_item(doc): for field in fields_to_map: website_item.update({field: doc.get(field)}) + if not save: + return website_item + website_item.save() return [website_item.name, website_item.web_item_name] diff --git a/erpnext/patches.txt b/erpnext/patches.txt index f15c65e707..6895932b8b 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -303,3 +303,6 @@ erpnext.patches.v13_0.modify_invalid_gain_loss_gl_entries #2 erpnext.patches.v13_0.fix_additional_cost_in_mfg_stock_entry erpnext.patches.v13_0.set_status_in_maintenance_schedule_table erpnext.patches.v13_0.add_default_interview_notification_templates +erpnext.patches.v13_0.create_website_items +erpnext.patches.v13_0.populate_e_commerce_settings +erpnext.patches.v13_0.make_homepage_products_website_items diff --git a/erpnext/patches/v13_0/create_website_items.py b/erpnext/patches/v13_0/create_website_items.py new file mode 100644 index 0000000000..a3b07517f5 --- /dev/null +++ b/erpnext/patches/v13_0/create_website_items.py @@ -0,0 +1,45 @@ +from __future__ import unicode_literals +import frappe + +from erpnext.e_commerce.doctype.website_item.website_item import make_website_item + +def execute(): + frappe.reload_doc("e_commerce", "doctype", "website_item") + frappe.reload_doc("stock", "doctype", "item") + + web_fields_to_map = ["route", "slideshow", "website_image", "website_image_alt", + "website_warehouse", "web_long_description", "website_content"] + + items = frappe.db.sql(""" + Select + item_code, item_name, item_group, stock_uom, brand, image, + has_variants, variant_of, description, weightage, + route, slideshow, website_image_alt, + website_warehouse, web_long_description, website_content + from + `tabItem` + where + show_in_website = 1 + or show_variant_in_website = 1""", as_dict=1) + + for item in items: + if frappe.db.exists("Website Item", {"item_code": item.item_code}): + continue + + # make website item from item (publish item) + website_item = make_website_item(item, save=False) + website_item.ranking = item.get("weightage") + for field in web_fields_to_map: + website_item.update({field: item.get(field)}) + website_item.save() + + # move Website Item Group & Website Specification table to Website Item + for doc in ("Website Item Group", "Item Website Specification"): + frappe.db.sql("""Update `tab{doctype}` + set + parenttype = 'Website Item', + parent = '{web_item}' + where + parenttype = 'Item' + and parent = '{item}' + """.format(doctype=doc, web_item=website_item.name, item=item.item_code)) \ No newline at end of file diff --git a/erpnext/patches/v13_0/make_homepage_products_website_items.py b/erpnext/patches/v13_0/make_homepage_products_website_items.py new file mode 100644 index 0000000000..67cccdf023 --- /dev/null +++ b/erpnext/patches/v13_0/make_homepage_products_website_items.py @@ -0,0 +1,13 @@ +from __future__ import unicode_literals +import frappe + +def execute(): + homepage = frappe.get_doc("Homepage") + + for row in homepage.products: + web_item = frappe.db.get_value("Website Item", {"item_code": row.item_code}, "name") + if not web_item: continue + + row.item_code = web_item + + homepage.save() \ No newline at end of file diff --git a/erpnext/patches/v13_0/populate_e_commerce_settings.py b/erpnext/patches/v13_0/populate_e_commerce_settings.py new file mode 100644 index 0000000000..94dcd9a3ed --- /dev/null +++ b/erpnext/patches/v13_0/populate_e_commerce_settings.py @@ -0,0 +1,58 @@ +from __future__ import unicode_literals +import frappe +from frappe.utils import cint + +def execute(): + frappe.reload_doc("e_commerce", "doctype", "e_commerce_settings") + + products_settings_fields = [ + "hide_variants", "home_page_is_products", "products_per_page", + "show_availability_status", "enable_attribute_filters", "enable_field_filters" + ] + + shopping_cart_settings_fields = [ + "enabled", "show_attachments", "show_price", + "show_stock_availability", "enable_variants", "show_contact_us_button", + "show_quantity_in_website", "show_apply_coupon_code_in_website", + "allow_items_not_in_stock", "company", "price_list", "default_customer_group", + "quotation_series", "enable_checkout", "payment_success_url", + "payment_gateway_account", "save_quotations_as_draft" + ] + + settings = frappe.get_doc("E Commerce Settings") + + def map_into_e_commerce_settings(doctype, fields): + data = frappe.db.sql(""" + Select + field, value + from `tabSingles` + where + doctype='{doctype}' + and field in ({fields}) + """.format( + doctype=doctype, + fields=(",").join(['%s'] * len(fields)) + ), tuple(fields), as_dict=1, debug=1) + + # {'enable_attribute_filters': '1', ...} + mapper = {row.field: row.value for row in data} + + for key, value in mapper.items(): + value = cint(value) if (value and value.isdigit()) else value + settings.update({key: value}) + + settings.save() + + # shift data to E Commerce Settings + map_into_e_commerce_settings("Products Settings", products_settings_fields) + map_into_e_commerce_settings("Shopping Cart Settings", shopping_cart_settings_fields) + + # move filters and attributes tables to E Commerce Settings from Products Settings + for doctype in ("Website Filter Field", "Website Attribute"): + frappe.db.sql("""Update `tab{doctype}` + set + parenttype = 'E Commerce Settings', + parent = 'E Commerce Settings' + where + parent = 'Products Settings' + """.format(doctype=doctype)) \ No newline at end of file diff --git a/erpnext/portal/doctype/homepage/homepage.py b/erpnext/portal/doctype/homepage/homepage.py index 4477011817..74e04894c6 100644 --- a/erpnext/portal/doctype/homepage/homepage.py +++ b/erpnext/portal/doctype/homepage/homepage.py @@ -16,12 +16,14 @@ class Homepage(Document): delete_page_cache('home') def setup_items(self): - for d in frappe.get_all('Item', fields=['name', 'item_name', 'description', 'image'], - filters={'published_in_website': 1}, limit=3): + for d in frappe.get_all('Website Item', fields=['name', 'item_name', 'description', 'image', 'route'], + filters={'published': 1}, limit=3): - doc = frappe.get_doc('Item', d.name) + doc = frappe.get_doc('Website Item', d.name) if not doc.route: # set missing route doc.save() self.append('products', dict(item_code=d.name, - item_name=d.item_name, description=d.description, image=d.image)) + item_name=d.item_name, description=d.description, + image=d.image, route=d.route)) + diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py index cd9f1e8767..a5f38c69ea 100644 --- a/erpnext/shopping_cart/cart.py +++ b/erpnext/shopping_cart/cart.py @@ -264,7 +264,7 @@ def guess_territory(): def decorate_quotation_doc(doc): for d in doc.get("items", []): - d.update(frappe.db.get_value("Item", d.item_code, + d.update(frappe.db.get_value("Website Item", {"item_code": d.item_code}, ["thumbnail", "website_image", "description", "route"], as_dict=True)) return doc diff --git a/erpnext/stock/doctype/item_variant_settings/item_variant_settings.py b/erpnext/stock/doctype/item_variant_settings/item_variant_settings.py index bd9e9b9d55..115bdaa888 100644 --- a/erpnext/stock/doctype/item_variant_settings/item_variant_settings.py +++ b/erpnext/stock/doctype/item_variant_settings/item_variant_settings.py @@ -14,9 +14,8 @@ class ItemVariantSettings(Document): self.fields = [] fields = frappe.get_meta('Item').fields exclude_fields = {"naming_series", "item_code", "item_name", "published_in_website", - "show_variant_in_website", "standard_rate", "opening_stock", "image", "description", + "standard_rate", "opening_stock", "image", "description", "variant_of", "valuation_rate", "description", "barcodes", - "website_image", "thumbnail", "website_specifiations", "web_long_description", "has_variants", "attributes"} for d in fields: diff --git a/erpnext/templates/pages/home.py b/erpnext/templates/pages/home.py index 97a66fc4bb..3e23fc7253 100644 --- a/erpnext/templates/pages/home.py +++ b/erpnext/templates/pages/home.py @@ -11,7 +11,7 @@ def get_context(context): homepage = frappe.get_doc('Homepage') for item in homepage.products: - route = frappe.db.get_value('Item', item.item_code, 'route') + route = frappe.db.get_value('Website Item', {"item_code": item.item_code}, 'route') if route: item.route = '/' + route