From 5f8b358fd4746394cbe5c349b0e5bd1280c5af3a Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Tue, 19 Mar 2019 11:48:32 +0530 Subject: [PATCH] Website: Product Configurator and Bootstrap 4 (#15965) - Refactored Homepage with customisable Hero Section - New Homepage Section to add content on Homepage as cards or using Custom HTML - Products page at "/all-products" with customisable filters - Item Configure dialog to find an Item Variant filtered by attribute values - Contact Us dialog on Item page - Customisable Item page content using the Website Content field --- erpnext/config/website.py | 10 + erpnext/hooks.py | 3 +- erpnext/hr/doctype/job_opening/job_opening.py | 23 + .../templates/job_opening_row.html | 9 + erpnext/patches.txt | 2 +- .../add_variant_of_in_item_attribute_table.py | 8 + .../v12_0/set_default_homepage_type.py | 4 + erpnext/portal/doctype/homepage/homepage.js | 7 +- erpnext/portal/doctype/homepage/homepage.json | 277 +++- erpnext/portal/doctype/homepage/homepage.py | 2 - .../portal/doctype/homepage/test_homepage.py | 19 + .../doctype/homepage_section/__init__.py | 0 .../homepage_section/homepage_section.js | 6 + .../homepage_section/homepage_section.json | 336 +++++ .../homepage_section/homepage_section.py | 12 + .../homepage_section/test_homepage_section.py | 76 + .../doctype/homepage_section_card/__init__.py | 0 .../homepage_section_card.json | 203 +++ .../homepage_section_card.py | 9 + .../products_settings/products_settings.js | 11 + .../products_settings/products_settings.json | 604 ++++---- .../products_settings/products_settings.py | 21 + .../doctype/website_attribute/__init__.py | 0 .../website_attribute/website_attribute.json | 76 + .../website_attribute/website_attribute.py | 9 + .../doctype/website_filter_field/__init__.py | 0 .../website_filter_field.json | 76 + .../website_filter_field.py | 9 + .../portal/product_configurator/__init__.py | 0 .../item_variants_cache.py | 94 ++ .../test_product_configurator.py | 84 ++ erpnext/portal/product_configurator/utils.py | 402 ++++++ erpnext/public/build.json | 2 +- erpnext/public/js/shopping_cart.js | 10 +- erpnext/public/js/templates/address_list.html | 4 +- erpnext/public/js/templates/contact_list.html | 4 +- erpnext/public/js/website_theme.js | 17 + erpnext/public/less/products.less | 69 + erpnext/public/less/website.less | 29 +- erpnext/public/node_modules | 1 + erpnext/public/scss/website.scss | 53 + .../quotation_item/quotation_item.json | 146 +- .../setup/doctype/item_group/item_group.py | 20 +- .../operations/default_website.py | 2 +- erpnext/shopping_cart/cart.py | 55 +- .../shopping_cart_settings.json | 1238 +++++++++-------- erpnext/shopping_cart/product_info.py | 4 +- erpnext/stock/doctype/item/item.js | 4 + erpnext/stock/doctype/item/item.json | 74 +- erpnext/stock/doctype/item/item.py | 101 +- erpnext/stock/doctype/item/test_records.json | 3 +- .../doctype/item_attribute/item_attribute.js | 6 + .../item_attribute/item_attribute.json | 101 +- .../item_variant_attribute.json | 57 +- erpnext/templates/generators/item.html | 143 -- erpnext/templates/generators/item/item.html | 32 + .../generators/item/item_add_to_cart.html | 67 + .../generators/item/item_configure.html | 23 + .../generators/item/item_configure.js | 318 +++++ .../generators/item/item_details.html | 22 + .../templates/generators/item/item_image.html | 107 ++ .../templates/generators/item/item_inquiry.js | 70 + .../generators/item/item_specifications.html | 16 + erpnext/templates/generators/item_group.html | 41 +- erpnext/templates/includes/address_row.html | 12 +- erpnext/templates/includes/cart.js | 97 +- .../templates/includes/cart/address_card.html | 12 + .../templates/includes/cart/cart_address.html | 161 ++- .../templates/includes/cart/cart_items.html | 69 +- .../includes/footer/footer_extension.html | 17 +- .../includes/footer/footer_powered.html | 3 +- erpnext/templates/includes/macros.html | 43 +- .../includes/navbar/navbar_items.html | 12 +- .../includes/order/order_macros.html | 8 +- .../templates/includes/order/order_taxes.html | 44 +- erpnext/templates/includes/product_page.js | 215 --- erpnext/templates/pages/cart.html | 138 +- erpnext/templates/pages/help.html | 2 +- erpnext/templates/pages/home.css | 9 + erpnext/templates/pages/home.html | 130 +- erpnext/templates/pages/home.py | 45 +- .../pages/material_request_info.html | 4 +- .../pages/non_profit/leave-chapter.html | 2 +- erpnext/templates/pages/order.html | 40 +- erpnext/templates/pages/product_search.html | 2 +- erpnext/templates/pages/projects.html | 4 +- erpnext/templates/pages/task_info.html | 4 +- erpnext/www/all-products/__init__.py | 0 erpnext/www/all-products/index.html | 163 +++ erpnext/www/all-products/index.js | 161 +++ erpnext/www/all-products/index.py | 26 + erpnext/www/all-products/item_row.html | 24 + erpnext/www/all-products/not_found.html | 1 + 93 files changed, 5057 insertions(+), 1622 deletions(-) create mode 100644 erpnext/hr/doctype/job_opening/templates/job_opening_row.html create mode 100644 erpnext/patches/v12_0/add_variant_of_in_item_attribute_table.py create mode 100644 erpnext/patches/v12_0/set_default_homepage_type.py create mode 100644 erpnext/portal/doctype/homepage/test_homepage.py create mode 100644 erpnext/portal/doctype/homepage_section/__init__.py create mode 100644 erpnext/portal/doctype/homepage_section/homepage_section.js create mode 100644 erpnext/portal/doctype/homepage_section/homepage_section.json create mode 100644 erpnext/portal/doctype/homepage_section/homepage_section.py create mode 100644 erpnext/portal/doctype/homepage_section/test_homepage_section.py create mode 100644 erpnext/portal/doctype/homepage_section_card/__init__.py create mode 100644 erpnext/portal/doctype/homepage_section_card/homepage_section_card.json create mode 100644 erpnext/portal/doctype/homepage_section_card/homepage_section_card.py create mode 100644 erpnext/portal/doctype/website_attribute/__init__.py create mode 100644 erpnext/portal/doctype/website_attribute/website_attribute.json create mode 100644 erpnext/portal/doctype/website_attribute/website_attribute.py create mode 100644 erpnext/portal/doctype/website_filter_field/__init__.py create mode 100644 erpnext/portal/doctype/website_filter_field/website_filter_field.json create mode 100644 erpnext/portal/doctype/website_filter_field/website_filter_field.py create mode 100644 erpnext/portal/product_configurator/__init__.py create mode 100644 erpnext/portal/product_configurator/item_variants_cache.py create mode 100644 erpnext/portal/product_configurator/test_product_configurator.py create mode 100644 erpnext/portal/product_configurator/utils.py create mode 100644 erpnext/public/js/website_theme.js create mode 100644 erpnext/public/less/products.less create mode 120000 erpnext/public/node_modules create mode 100644 erpnext/public/scss/website.scss create mode 100644 erpnext/stock/doctype/item_attribute/item_attribute.js delete mode 100644 erpnext/templates/generators/item.html create mode 100644 erpnext/templates/generators/item/item.html create mode 100644 erpnext/templates/generators/item/item_add_to_cart.html create mode 100644 erpnext/templates/generators/item/item_configure.html create mode 100644 erpnext/templates/generators/item/item_configure.js create mode 100644 erpnext/templates/generators/item/item_details.html create mode 100644 erpnext/templates/generators/item/item_image.html create mode 100644 erpnext/templates/generators/item/item_inquiry.js create mode 100644 erpnext/templates/generators/item/item_specifications.html create mode 100644 erpnext/templates/includes/cart/address_card.html delete mode 100644 erpnext/templates/includes/product_page.js create mode 100644 erpnext/templates/pages/home.css create mode 100644 erpnext/www/all-products/__init__.py create mode 100644 erpnext/www/all-products/index.html create mode 100644 erpnext/www/all-products/index.js create mode 100644 erpnext/www/all-products/index.py create mode 100644 erpnext/www/all-products/item_row.html create mode 100644 erpnext/www/all-products/not_found.html diff --git a/erpnext/config/website.py b/erpnext/config/website.py index 59e7d404d4..d31b057881 100644 --- a/erpnext/config/website.py +++ b/erpnext/config/website.py @@ -11,6 +11,16 @@ def get_data(): "name": "Homepage", "description": _("Settings for website homepage"), }, + { + "type": "doctype", + "name": "Homepage Section", + "description": _("Add cards or custom sections on homepage"), + }, + { + "type": "doctype", + "name": "Products Settings", + "description": _("Settings for website product listing"), + }, { "type": "doctype", "name": "Shopping Cart Settings", diff --git a/erpnext/hooks.py b/erpnext/hooks.py index a6876ac1f3..d28666c48b 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -22,7 +22,8 @@ web_include_css = "assets/css/erpnext-web.css" doctype_js = { "Communication": "public/js/communication.js", - "Event": "public/js/event.js" + "Event": "public/js/event.js", + "Website Theme": "public/js/website_theme.js" } welcome_email = "erpnext.setup.utils.welcome_email" diff --git a/erpnext/hr/doctype/job_opening/job_opening.py b/erpnext/hr/doctype/job_opening/job_opening.py index 4fc2ac1ded..00883d75f1 100644 --- a/erpnext/hr/doctype/job_opening/job_opening.py +++ b/erpnext/hr/doctype/job_opening/job_opening.py @@ -53,3 +53,26 @@ class JobOpening(WebsiteGenerator): def get_list_context(context): context.title = _("Jobs") context.introduction = _('Current Job Openings') + context.get_list = get_job_openings + +def get_job_openings(doctype, txt=None, filters=None, limit_start=0, limit_page_length=20, order_by=None): + fields = ['name', 'status', 'job_title', 'description'] + + filters = filters or {} + filters.update({ + 'status': 'Open' + }) + + if txt: + filters.update({ + 'job_title': ['like', '%{0}%'.format(txt)], + 'description': ['like', '%{0}%'.format(txt)] + }) + + return frappe.get_all(doctype, + filters, + fields, + start=limit_start, + page_length=limit_page_length, + order_by=order_by + ) diff --git a/erpnext/hr/doctype/job_opening/templates/job_opening_row.html b/erpnext/hr/doctype/job_opening/templates/job_opening_row.html new file mode 100644 index 0000000000..5da8cc82a2 --- /dev/null +++ b/erpnext/hr/doctype/job_opening/templates/job_opening_row.html @@ -0,0 +1,9 @@ +
+

{{ doc.job_title }}

+

{{ doc.description }}

+
+ + {{ _("Apply Now") }} +
+
diff --git a/erpnext/patches.txt b/erpnext/patches.txt index b7e673da34..cb1e77c73f 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -577,6 +577,7 @@ erpnext.patches.v10_0.item_barcode_childtable_migrate # 16-02-2019 erpnext.patches.v11_0.update_delivery_trip_status erpnext.patches.v11_0.set_missing_gst_hsn_code erpnext.patches.v11_0.rename_bom_wo_fields +erpnext.patches.v12_0.set_default_homepage_type erpnext.patches.v11_0.rename_additional_salary_component_additional_salary erpnext.patches.v11_0.renamed_from_to_fields_in_project erpnext.patches.v11_0.add_permissions_in_gst_settings @@ -584,5 +585,4 @@ erpnext.patches.v11_1.setup_guardian_role execute:frappe.delete_doc('DocType', 'Notification Control') erpnext.patches.v11_0.remove_barcodes_field_from_copy_fields_to_variants erpnext.patches.v12_0.set_task_status -erpnext.patches.v10_0.item_barcode_childtable_migrate # 16-02-2019 erpnext.patches.v11_0.make_italian_localization_fields # 01-03-2019 diff --git a/erpnext/patches/v12_0/add_variant_of_in_item_attribute_table.py b/erpnext/patches/v12_0/add_variant_of_in_item_attribute_table.py new file mode 100644 index 0000000000..bc6119067c --- /dev/null +++ b/erpnext/patches/v12_0/add_variant_of_in_item_attribute_table.py @@ -0,0 +1,8 @@ +import frappe + +def execute(): + frappe.db.sql(''' + UPDATE `tabItem Variant Attribute` t1 + INNER JOIN `tabItem` t2 ON t2.name = t1.parent + SET t1.variant_of = t2.variant_of + ''') diff --git a/erpnext/patches/v12_0/set_default_homepage_type.py b/erpnext/patches/v12_0/set_default_homepage_type.py new file mode 100644 index 0000000000..241e4b9b5e --- /dev/null +++ b/erpnext/patches/v12_0/set_default_homepage_type.py @@ -0,0 +1,4 @@ +import frappe + +def execute(): + frappe.db.set_value('Homepage', 'Homepage', 'hero_section_based_on', 'Default') \ No newline at end of file diff --git a/erpnext/portal/doctype/homepage/homepage.js b/erpnext/portal/doctype/homepage/homepage.js index 0b07814f75..ca34d69576 100644 --- a/erpnext/portal/doctype/homepage/homepage.js +++ b/erpnext/portal/doctype/homepage/homepage.js @@ -11,7 +11,12 @@ frappe.ui.form.on('Homepage', { }, refresh: function(frm) { - + frm.add_custom_button(__('Set Meta Tags'), () => { + frappe.utils.set_meta_tag('home'); + }); + frm.add_custom_button(__('Customize Homepage Sections'), () => { + frappe.set_route('List', 'Homepage Section', 'List'); + }); }, }); diff --git a/erpnext/portal/doctype/homepage/homepage.json b/erpnext/portal/doctype/homepage/homepage.json index 81433b1c5d..ad27278dc6 100644 --- a/erpnext/portal/doctype/homepage/homepage.json +++ b/erpnext/portal/doctype/homepage/homepage.json @@ -1,5 +1,7 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, "autoname": "", @@ -10,18 +12,24 @@ "doctype": "DocType", "document_type": "Setup", "editable_grid": 0, + "engine": "InnoDB", "fields": [ { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "company", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, - "in_list_view": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, "label": "Company", "length": 0, "no_copy": 0, @@ -31,24 +39,63 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "title", - "fieldtype": "Data", + "columns": 0, + "fieldname": "hero_section_based_on", + "fieldtype": "Select", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, - "label": "TItle", + "in_standard_filter": 0, + "label": "Hero Section Based On", + "length": 0, + "no_copy": 0, + "options": "Default\nSlideshow\nHomepage Section", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "column_break_2", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, "length": 0, "no_copy": 0, "permlevel": 0, @@ -56,16 +103,88 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, + "depends_on": "", + "fieldname": "title", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Title", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "", + "fieldname": "section_break_4", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Hero Section", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.hero_section_based_on === 'Default'", "description": "Company Tagline for website homepage", "fieldname": "tag_line", "fieldtype": "Data", @@ -73,7 +192,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, - "in_list_view": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, "label": "Tag Line", "length": 0, "no_copy": 0, @@ -82,16 +203,22 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.hero_section_based_on === 'Default'", "description": "Company Description for website homepage", "fieldname": "description", "fieldtype": "Text", @@ -99,7 +226,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, - "in_list_view": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, "label": "Description", "length": 0, "no_copy": 0, @@ -108,23 +237,133 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.hero_section_based_on === 'Default'", + "fieldname": "hero_image", + "fieldtype": "Attach Image", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Hero Image", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.hero_section_based_on === 'Slideshow'", + "description": "", + "fieldname": "slideshow", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Homepage Slideshow", + "length": 0, + "no_copy": 0, + "options": "Website Slideshow", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.hero_section_based_on === 'Homepage Section'", + "fieldname": "hero_section", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Homepage Section", + "length": 0, + "no_copy": 0, + "options": "Homepage Section", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "", "fieldname": "products_section", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Products", "length": 0, "no_copy": 0, @@ -133,16 +372,21 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "default": "/products", "fieldname": "products_url", "fieldtype": "Data", @@ -150,7 +394,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "URL for \"All Products\"", "length": 0, "no_copy": 0, @@ -159,16 +405,21 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "description": "Products to be shown on website homepage", "fieldname": "products", "fieldtype": "Table", @@ -176,7 +427,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Products", "length": 0, "no_copy": 0, @@ -186,14 +439,17 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "40px" } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "idx": 0, @@ -203,7 +459,7 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2016-08-29 01:28:00.961623", + "modified": "2019-03-02 23:12:59.676202", "modified_by": "Administrator", "module": "Portal", "name": "Homepage", @@ -212,7 +468,6 @@ "permissions": [ { "amend": 0, - "apply_user_permissions": 0, "cancel": 0, "create": 1, "delete": 1, @@ -232,7 +487,6 @@ }, { "amend": 0, - "apply_user_permissions": 0, "cancel": 0, "create": 1, "delete": 1, @@ -254,8 +508,11 @@ "quick_entry": 0, "read_only": 0, "read_only_onload": 0, + "show_name_in_global_search": 0, "sort_field": "modified", "sort_order": "DESC", "title_field": "company", - "track_seen": 0 + "track_changes": 1, + "track_seen": 0, + "track_views": 0 } \ No newline at end of file diff --git a/erpnext/portal/doctype/homepage/homepage.py b/erpnext/portal/doctype/homepage/homepage.py index f8f73fdcd0..4e4d4774ab 100644 --- a/erpnext/portal/doctype/homepage/homepage.py +++ b/erpnext/portal/doctype/homepage/homepage.py @@ -9,8 +9,6 @@ from frappe.website.utils import delete_page_cache class Homepage(Document): def validate(self): - if not self.products: - self.setup_items() if not self.description: self.description = frappe._("This is an example website auto-generated from ERPNext") delete_page_cache('home') diff --git a/erpnext/portal/doctype/homepage/test_homepage.py b/erpnext/portal/doctype/homepage/test_homepage.py new file mode 100644 index 0000000000..b262c4640c --- /dev/null +++ b/erpnext/portal/doctype/homepage/test_homepage.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest +from frappe.tests.test_website import set_request +from frappe.website.render import render + +class TestHomepage(unittest.TestCase): + def test_homepage_load(self): + set_request(method='GET', path='home') + response = render() + + self.assertEquals(response.status_code, 200) + + html = frappe.safe_decode(response.get_data()) + self.assertTrue(' + {% endif %} -{% block style %} - -{% endblock %} + {% for section in homepage_sections %} + {{ render_homepage_section(section) }} + {% endfor %} + +{% endblock %} \ No newline at end of file diff --git a/erpnext/templates/pages/home.py b/erpnext/templates/pages/home.py index 82d525ac77..4b688b13df 100644 --- a/erpnext/templates/pages/home.py +++ b/erpnext/templates/pages/home.py @@ -15,15 +15,38 @@ def get_context(context): if route: item.route = '/' + route - context.title = homepage.title or homepage.company - - # show atleast 3 products - if len(homepage.products) < 3: - for i in range(3 - len(homepage.products)): - homepage.append('products', { - 'item_code': 'product-{0}'.format(i), - 'item_name': frappe._('Product {0}').format(i), - 'route': '#' - }) - + homepage.title = homepage.title or homepage.company + context.title = homepage.title context.homepage = homepage + + if homepage.hero_section_based_on == 'Homepage Section' and homepage.hero_section: + homepage.hero_section_doc = frappe.get_doc('Homepage Section', homepage.hero_section) + + if homepage.slideshow: + doc = frappe.get_doc('Website Slideshow', homepage.slideshow) + context.slideshow = homepage.slideshow + context.slideshow_header = doc.header + context.slides = doc.slideshow_items + + context.blogs = frappe.get_all('Blog Post', + fields=['title', 'blogger', 'blog_intro', 'route'], + filters={ + 'published': 1 + }, + order_by='modified desc', + limit=3 + ) + + # filter out homepage section which is used as hero section + homepage_hero_section = homepage.hero_section_based_on == 'Homepage Section' and homepage.hero_section + homepage_sections = frappe.get_all('Homepage Section', + filters=[['name', '!=', homepage_hero_section]] if homepage_hero_section else None, + order_by='section_order asc' + ) + context.homepage_sections = [frappe.get_doc('Homepage Section', name) for name in homepage_sections] + + context.metatags = context.metatags or frappe._dict({}) + context.metatags.image = homepage.hero_image or None + context.metatags.description = homepage.description or None + + context.explore_link = '/all-products' diff --git a/erpnext/templates/pages/material_request_info.html b/erpnext/templates/pages/material_request_info.html index ff3bd65b67..9d189895b6 100644 --- a/erpnext/templates/pages/material_request_info.html +++ b/erpnext/templates/pages/material_request_info.html @@ -12,7 +12,7 @@ {% endblock %} {% block header_actions %} -{{ _("Print") }} +{{ _("Print") }} {% endblock %} {% block page_content %} @@ -70,5 +70,5 @@ {% endif %} {% endfor %} - + {% endblock %} \ No newline at end of file diff --git a/erpnext/templates/pages/non_profit/leave-chapter.html b/erpnext/templates/pages/non_profit/leave-chapter.html index 009c7af790..bc4242f919 100644 --- a/erpnext/templates/pages/non_profit/leave-chapter.html +++ b/erpnext/templates/pages/non_profit/leave-chapter.html @@ -9,7 +9,7 @@ - diff --git a/erpnext/templates/pages/order.html b/erpnext/templates/pages/order.html index 64fd32a992..67a8fed8ab 100644 --- a/erpnext/templates/pages/order.html +++ b/erpnext/templates/pages/order.html @@ -8,23 +8,22 @@ {% block title %}{{ doc.name }}{% endblock %} {% block header %} -

{{ doc.name }}

+

{{ doc.name }}

{% endblock %} {% block header_actions %} -{{ _("Print") }} +{{ _("Print") }} {% endblock %} {% block page_content %}
-
- +
{{ _(doc.get('indicator_title')) or _(doc.status) or _("Submitted") }}
-
+
{{ frappe.utils.formatdate(doc.transaction_date, 'medium') }} {% if doc.valid_till %}

@@ -34,16 +33,14 @@

-

-{% if doc.doctype == 'Supplier Quotation' %} - {{ doc.supplier_name}} -{% else %} - {{ doc.customer_name}} -{% endif %} -{% if doc.contact_display %} -
- {{ doc.contact_display }} -{% endif %} +

+ {%- set party_name = doc.supplier_name if doc.doctype == 'Supplier Quotation' else doc.customer_name %} + {{ party_name }} + + {% if doc.contact_display and doc.contact_display != party_name %} +
+ {{ doc.contact_display }} + {% endif %}

{% if doc._header %} @@ -55,7 +52,7 @@
-
+
{{ _("Item") }}
@@ -67,7 +64,7 @@
{% for d in doc.items %}
-
+
{{ item_name_and_description(d) }}
@@ -85,11 +82,10 @@
-
-
-
+
+ {% include "erpnext/templates/includes/order/order_taxes.html" %} - +
@@ -115,7 +111,7 @@
- +

Available Points: {{ available_loyalty_points }}

{% endif %} diff --git a/erpnext/templates/pages/product_search.html b/erpnext/templates/pages/product_search.html index f9efd485d3..6a5425bbf8 100644 --- a/erpnext/templates/pages/product_search.html +++ b/erpnext/templates/pages/product_search.html @@ -25,7 +25,7 @@ frappe.ready(function() {
diff --git a/erpnext/templates/pages/projects.html b/erpnext/templates/pages/projects.html index baa2ae62cc..7e294e076b 100644 --- a/erpnext/templates/pages/projects.html +++ b/erpnext/templates/pages/projects.html @@ -20,11 +20,11 @@ aria-valuemin="0" aria-valuemax="100" style="width:{{ doc.percent_complete|round|int }}%;">
-{% endif %} +{% endif %}

diff --git a/erpnext/templates/pages/task_info.html b/erpnext/templates/pages/task_info.html index 6cfac28da6..6cd6a7e51a 100644 --- a/erpnext/templates/pages/task_info.html +++ b/erpnext/templates/pages/task_info.html @@ -20,7 +20,7 @@

- + {{ __("Cancel") }}
@@ -91,7 +91,7 @@ {% endfor %}
- {{ __("Add Comment") }} + {{ __("Add Comment") }}