From a306af8c089a07d3ac8f65439868997a5cd5f37c Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 6 Aug 2020 20:52:02 +0530 Subject: [PATCH 01/23] fix: Add help link in navbar settings --- erpnext/patches.txt | 1 + .../v13_0/add_standard_navbar_items.py | 7 +++ erpnext/public/js/conf.js | 26 ----------- erpnext/setup/install.py | 45 ++++++++++++++++++- 4 files changed, 52 insertions(+), 27 deletions(-) create mode 100644 erpnext/patches/v13_0/add_standard_navbar_items.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 3bd416952f..3f63bf651b 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -718,3 +718,4 @@ erpnext.patches.v13_0.delete_report_requested_items_to_order erpnext.patches.v12_0.update_item_tax_template_company erpnext.patches.v13_0.move_branch_code_to_bank_account erpnext.patches.v13_0.healthcare_lab_module_rename_doctypes +erpnext.patches.v13_0.add_standard_navbar_items #4 diff --git a/erpnext/patches/v13_0/add_standard_navbar_items.py b/erpnext/patches/v13_0/add_standard_navbar_items.py new file mode 100644 index 0000000000..5de99a5abc --- /dev/null +++ b/erpnext/patches/v13_0/add_standard_navbar_items.py @@ -0,0 +1,7 @@ +from __future__ import unicode_literals +import frappe +from erpnext.setup.install import add_standard_navbar_items + +def execute(): + # Add standard navbar items for ERPNext in Navbar Settings + add_standard_navbar_items() \ No newline at end of file diff --git a/erpnext/public/js/conf.js b/erpnext/public/js/conf.js index 9870f81910..2af9140f9e 100644 --- a/erpnext/public/js/conf.js +++ b/erpnext/public/js/conf.js @@ -3,32 +3,6 @@ frappe.provide('erpnext'); -// add toolbar icon -$(document).bind('toolbar_setup', function() { - frappe.app.name = "ERPNext"; - - frappe.help_feedback_link = '

Feedback

' - - - $('[data-link="docs"]').attr("href", "https://erpnext.com/docs") - $('[data-link="issues"]').attr("href", "https://github.com/frappe/erpnext/issues") - - - // default documentation goes to erpnext - // $('[data-link-type="documentation"]').attr('data-path', '/erpnext/manual/index'); - - // additional help links for erpnext - var $help_menu = $('.dropdown-help ul .documentation-links'); - $('
  • '+__('Documentation')+'
  • ').insertBefore($help_menu); - $('
  • '+__('User Forum')+'
  • ').insertBefore($help_menu); - $('
  • '+__('Report an Issue')+'
  • ').insertBefore($help_menu); - -}); - // preferred modules for breadcrumbs $.extend(frappe.breadcrumbs.preferred, { "Item Group": "Stock", diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py index aa9fbc0a92..b2f0fa2ed6 100644 --- a/erpnext/setup/install.py +++ b/erpnext/setup/install.py @@ -25,12 +25,13 @@ def after_install(): create_default_success_action() create_default_energy_point_rules() add_company_to_session_defaults() + add_standard_navbar_items() frappe.db.commit() def check_setup_wizard_not_completed(): if frappe.db.get_default('desktop:home_page') != 'setup-wizard': - message = """ERPNext can only be installed on a fresh site where the setup wizard is not completed. + message = """ERPNext can only be installed on a fresh site where the setup wizard is not completed. You can reinstall this site (after saving your data) using: bench --site [sitename] reinstall""" frappe.throw(message) @@ -103,3 +104,45 @@ def add_company_to_session_defaults(): "ref_doctype": "Company" }) settings.save() + +def add_standard_navbar_items(): + navbar_settings = frappe.get_single("Navbar Settings") + + erpnext_navbar_items = [ + { + 'item_label': 'Documentation', + 'item_type': 'Route', + 'route': 'https://erpnext.com/docs/user/manual', + 'is_standard': 1 + }, + { + 'item_label': 'User Forum', + 'item_type': 'Route', + 'route': 'https://discuss.erpnext.com', + 'is_standard': 1 + }, + { + 'item_label': 'Report an Issue', + 'item_type': 'Route', + 'route': 'https://github.com/frappe/erpnext/issues', + 'is_standard': 1 + } + ] + + current_nabvar_items = navbar_settings.help_dropdown + navbar_settings.set('help_dropdown', []) + + for item in erpnext_navbar_items: + navbar_settings.append('help_dropdown', item) + + for item in current_nabvar_items: + navbar_settings.append('help_dropdown', { + 'item_label': item.item_label, + 'item_type': item.item_type, + 'route': item.route, + 'action': item.action, + 'is_standard': item.is_standard, + 'hidden': item.hidden + }) + + navbar_settings.save() From 2c26144a6b5f22e8c2f2fd9a2e8930e440ae76a1 Mon Sep 17 00:00:00 2001 From: Raffael Meyer <14891507+barredterra@users.noreply.github.com> Date: Wed, 19 Aug 2020 18:55:06 +0200 Subject: [PATCH 02/23] Update erpnext/patches/v13_0/add_standard_navbar_items.py --- erpnext/patches/v13_0/add_standard_navbar_items.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/patches/v13_0/add_standard_navbar_items.py b/erpnext/patches/v13_0/add_standard_navbar_items.py index 5de99a5abc..d05b258db0 100644 --- a/erpnext/patches/v13_0/add_standard_navbar_items.py +++ b/erpnext/patches/v13_0/add_standard_navbar_items.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals -import frappe +# import frappe from erpnext.setup.install import add_standard_navbar_items def execute(): # Add standard navbar items for ERPNext in Navbar Settings - add_standard_navbar_items() \ No newline at end of file + add_standard_navbar_items() From 42092cc3776ff8d36ce39607555bb8b2bac5911d Mon Sep 17 00:00:00 2001 From: Anupam K Date: Tue, 25 Aug 2020 15:29:18 +0530 Subject: [PATCH 03/23] fix: Homepage Featured Product image fetch issue --- erpnext/portal/doctype/homepage/homepage.js | 28 -- .../homepage_featured_product.json | 383 +++++------------- 2 files changed, 99 insertions(+), 312 deletions(-) diff --git a/erpnext/portal/doctype/homepage/homepage.js b/erpnext/portal/doctype/homepage/homepage.js index ca34d69576..c7c66e0055 100644 --- a/erpnext/portal/doctype/homepage/homepage.js +++ b/erpnext/portal/doctype/homepage/homepage.js @@ -21,34 +21,6 @@ frappe.ui.form.on('Homepage', { }); frappe.ui.form.on('Homepage Featured Product', { - item_code: function(frm, cdt, cdn) { - var featured_product = frappe.model.get_doc(cdt, cdn); - if (featured_product.item_code) { - frappe.call({ - method: 'frappe.client.get_value', - args: { - 'doctype': 'Item', - 'filters': {'name': featured_product.item_code}, - 'fieldname': [ - 'item_name', - 'web_long_description', - 'description', - 'image', - 'thumbnail' - ] - }, - callback: function(r) { - if (!r.exc) { - $.extend(featured_product, r.message); - if (r.message.web_long_description) { - featured_product.description = r.message.web_long_description; - } - frm.refresh_field('products'); - } - } - }); - } - }, view: function(frm, cdt, cdn){ var child= locals[cdt][cdn] diff --git a/erpnext/portal/doctype/homepage_featured_product/homepage_featured_product.json b/erpnext/portal/doctype/homepage_featured_product/homepage_featured_product.json index c8b4ae9b74..01c32efec9 100644 --- a/erpnext/portal/doctype/homepage_featured_product/homepage_featured_product.json +++ b/erpnext/portal/doctype/homepage_featured_product/homepage_featured_product.json @@ -1,301 +1,116 @@ { - "allow_copy": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "hash", - "beta": 0, - "creation": "2016-04-22 05:57:06.261401", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "Document", - "editable_grid": 1, + "actions": [], + "autoname": "hash", + "creation": "2016-04-22 05:57:06.261401", + "doctype": "DocType", + "document_type": "Document", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "item_code", + "col_break1", + "item_name", + "view", + "section_break_5", + "description", + "column_break_7", + "image", + "thumbnail", + "route" + ], "fields": [ { - "allow_on_submit": 0, - "bold": 1, - "collapsible": 0, - "fieldname": "item_code", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 1, - "in_list_view": 1, - "label": "Item Code", - "length": 0, - "no_copy": 0, - "oldfieldname": "item_code", - "oldfieldtype": "Link", - "options": "Item", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "150px", - "read_only": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 1, - "set_only_once": 0, - "unique": 0, + "bold": 1, + "fieldname": "item_code", + "fieldtype": "Link", + "in_filter": 1, + "in_list_view": 1, + "label": "Item Code", + "oldfieldname": "item_code", + "oldfieldtype": "Link", + "options": "Item", + "print_width": "150px", + "reqd": 1, + "search_index": 1, "width": "150px" - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "col_break1", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "col_break1", + "fieldtype": "Column Break" + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "item_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 1, - "label": "Item Name", - "length": 0, - "no_copy": 0, - "oldfieldname": "item_name", - "oldfieldtype": "Data", - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 1, - "print_hide_if_no_value": 0, - "print_width": "150", - "read_only": 1, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0, + "fetch_from": "item_code.item_name", + "fetch_if_empty": 1, + "fieldname": "item_name", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Item Name", + "oldfieldname": "item_name", + "oldfieldtype": "Data", + "print_hide": 1, + "print_width": "150", + "read_only": 1, + "reqd": 1, "width": "150" - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "view", - "fieldtype": "Button", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 1, - "label": "View", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "view", + "fieldtype": "Button", + "in_list_view": 1, + "label": "View" + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "fieldname": "section_break_5", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Description", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "collapsible": 1, + "fieldname": "section_break_5", + "fieldtype": "Section Break", + "label": "Description" + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "description", - "fieldtype": "Text Editor", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 1, - "in_list_view": 1, - "label": "Description", - "length": 0, - "no_copy": 0, - "oldfieldname": "description", - "oldfieldtype": "Small Text", - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "300px", - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0, + "fetch_from": "item_code.web_long_description", + "fieldname": "description", + "fieldtype": "Text Editor", + "in_filter": 1, + "in_list_view": 1, + "label": "Description", + "oldfieldname": "description", + "oldfieldtype": "Small Text", + "print_width": "300px", "width": "300px" - }, + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "column_break_7", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "column_break_7", + "fieldtype": "Column Break" + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "image", - "fieldtype": "Attach Image", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Image", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fetch_from": "item_code.website_image", + "fetch_if_empty": 1, + "fieldname": "image", + "fieldtype": "Attach Image", + "label": "Image" + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "thumbnail", - "fieldtype": "Attach Image", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Thumbnail", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "fieldname": "thumbnail", + "fieldtype": "Attach Image", + "hidden": 1, + "label": "Thumbnail" + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "route", - "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "route", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 + "fieldname": "route", + "fieldtype": "Small Text", + "label": "route", + "read_only": 1 } - ], - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2016-08-09 06:09:34.731971", - "modified_by": "Administrator", - "module": "Portal", - "name": "Homepage Featured Product", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_seen": 0 + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2020-08-25 15:27:49.573537", + "modified_by": "Administrator", + "module": "Portal", + "name": "Homepage Featured Product", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC" } \ No newline at end of file From d43d1408cfcd674107613d1f1f1310cd6b1f7a57 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Tue, 25 Aug 2020 17:13:05 +0530 Subject: [PATCH 04/23] fix: conversion factor for BOM exploded item rate --- erpnext/manufacturing/doctype/bom/bom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index c51f655a66..3189433837 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -494,7 +494,7 @@ class BOM(WebsiteGenerator): 'image' : d.image, 'stock_uom' : d.stock_uom, 'stock_qty' : flt(d.stock_qty), - 'rate' : flt(d.base_rate) / flt(d.conversion_factor), + 'rate' : flt(d.base_rate) / (flt(d.conversion_factor) or 1.0), 'include_item_in_manufacturing': d.include_item_in_manufacturing })) From d888a59bd1684890b4db52e9c470cc93f7da78a7 Mon Sep 17 00:00:00 2001 From: bhavesh95863 <34086262+bhavesh95863@users.noreply.github.com> Date: Wed, 26 Aug 2020 12:44:20 +0530 Subject: [PATCH 05/23] fix: set company filter in condition --- .../hr/report/employee_leave_balance/employee_leave_balance.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py index db1d191758..1b92358184 100644 --- a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py +++ b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py @@ -132,6 +132,9 @@ def get_conditions(filters): if filters.get('employee'): conditions['name'] = filters.get('employee') + if filters.get('company'): + conditions['company'] = filters.get('company') + return conditions def get_department_leave_approver_map(department=None): From 38fad588340e30a11137a123330cb03f64fad887 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 25 Aug 2020 16:30:09 +0530 Subject: [PATCH 06/23] fix(patch) --- erpnext/patches/v12_0/create_irs_1099_field_united_states.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/patches/v12_0/create_irs_1099_field_united_states.py b/erpnext/patches/v12_0/create_irs_1099_field_united_states.py index 43bd0ccdd7..bce4ab10b3 100644 --- a/erpnext/patches/v12_0/create_irs_1099_field_united_states.py +++ b/erpnext/patches/v12_0/create_irs_1099_field_united_states.py @@ -7,6 +7,7 @@ def execute(): frappe.reload_doc('accounts', 'doctype', 'allowed_to_transact_with', force=True) frappe.reload_doc('accounts', 'doctype', 'pricing_rule_detail', force=True) frappe.reload_doc('crm', 'doctype', 'lost_reason_detail', force=True) + frappe.reload_doc('crm', 'doctype', 'quotation_lost_reason_detail', force=True) company = frappe.get_all('Company', filters = {'country': 'United States'}) if not company: From 544d18327c67c95bceb9d8b9b11b4958da3ff27c Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 25 Aug 2020 20:01:31 +0530 Subject: [PATCH 07/23] fix(patch): quotation_lost_reason_detail --- erpnext/patches/v12_0/create_irs_1099_field_united_states.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/patches/v12_0/create_irs_1099_field_united_states.py b/erpnext/patches/v12_0/create_irs_1099_field_united_states.py index bce4ab10b3..7feaffdf40 100644 --- a/erpnext/patches/v12_0/create_irs_1099_field_united_states.py +++ b/erpnext/patches/v12_0/create_irs_1099_field_united_states.py @@ -7,7 +7,7 @@ def execute(): frappe.reload_doc('accounts', 'doctype', 'allowed_to_transact_with', force=True) frappe.reload_doc('accounts', 'doctype', 'pricing_rule_detail', force=True) frappe.reload_doc('crm', 'doctype', 'lost_reason_detail', force=True) - frappe.reload_doc('crm', 'doctype', 'quotation_lost_reason_detail', force=True) + frappe.reload_doc('setup', 'doctype', 'quotation_lost_reason_detail', force=True) company = frappe.get_all('Company', filters = {'country': 'United States'}) if not company: From a163d8bc843296bed1095f55c19fd0e3a210e1ae Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 26 Aug 2020 12:00:45 +0530 Subject: [PATCH 08/23] fix(minor): rename_lost_reason_detail --- erpnext/patches/v12_0/rename_lost_reason_detail.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/patches/v12_0/rename_lost_reason_detail.py b/erpnext/patches/v12_0/rename_lost_reason_detail.py index 044d0232e0..d0dc356bd0 100644 --- a/erpnext/patches/v12_0/rename_lost_reason_detail.py +++ b/erpnext/patches/v12_0/rename_lost_reason_detail.py @@ -3,6 +3,7 @@ import frappe def execute(): if frappe.db.exists("DocType", "Lost Reason Detail"): + frappe.reload_doc("crm", "doctype", "opportunity_lost_reason") frappe.reload_doc("crm", "doctype", "opportunity_lost_reason_detail") frappe.reload_doc("setup", "doctype", "quotation_lost_reason_detail") @@ -10,8 +11,8 @@ def execute(): frappe.db.sql("""INSERT INTO `tabQuotation Lost Reason Detail` SELECT * FROM `tabLost Reason Detail` WHERE `parenttype` = 'Quotation'""") - frappe.db.sql("""INSERT INTO `tabQuotation Lost Reason` (`name`, `creation`, `modified`, `modified_by`, `owner`, `docstatus`, `parent`, `parentfield`, `parenttype`, `idx`, `_comments`, `_assign`, `_user_tags`, `_liked_by`, `order_lost_reason`) - SELECT o.`name`, o.`creation`, o.`modified`, o.`modified_by`, o.`owner`, o.`docstatus`, o.`parent`, o.`parentfield`, o.`parenttype`, o.`idx`, o.`_comments`, o.`_assign`, o.`_user_tags`, o.`_liked_by`, o.`lost_reason` + frappe.db.sql("""INSERT INTO `tabQuotation Lost Reason` (`name`, `creation`, `modified`, `modified_by`, `owner`, `docstatus`, `parent`, `parentfield`, `parenttype`, `idx`, `_comments`, `_assign`, `_user_tags`, `_liked_by`, `order_lost_reason`) + SELECT o.`name`, o.`creation`, o.`modified`, o.`modified_by`, o.`owner`, o.`docstatus`, o.`parent`, o.`parentfield`, o.`parenttype`, o.`idx`, o.`_comments`, o.`_assign`, o.`_user_tags`, o.`_liked_by`, o.`lost_reason` FROM `tabOpportunity Lost Reason` o LEFT JOIN `tabQuotation Lost Reason` q ON q.name = o.name WHERE q.name IS NULL""") - + frappe.delete_doc("DocType", "Lost Reason Detail") \ No newline at end of file From 73f648473f9ac70afd469d845b3103cd3f9e9829 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 26 Aug 2020 13:09:58 +0530 Subject: [PATCH 09/23] fix(minor): update_start_end_date_for_old_shift_assignment.py --- .../v13_0/update_start_end_date_for_old_shift_assignment.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/patches/v13_0/update_start_end_date_for_old_shift_assignment.py b/erpnext/patches/v13_0/update_start_end_date_for_old_shift_assignment.py index 7c07b987f3..0f521cb57a 100644 --- a/erpnext/patches/v13_0/update_start_end_date_for_old_shift_assignment.py +++ b/erpnext/patches/v13_0/update_start_end_date_for_old_shift_assignment.py @@ -7,4 +7,7 @@ import frappe def execute(): frappe.reload_doc('hr', 'doctype', 'shift_assignment') - frappe.db.sql("update `tabShift Assignment` set end_date=date, start_date=date where date IS NOT NULL and start_date IS NULL and end_date IS NULL;") + if frappe.db.has_column('Shift Assignment', 'date'): + frappe.db.sql("""update `tabShift Assignment` + set end_date=date, start_date=date + where date IS NOT NULL and start_date IS NULL and end_date IS NULL;""") From 9766adbf4eaf6abf990746bbbabfabf928dd4819 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Wed, 26 Aug 2020 14:53:23 +0530 Subject: [PATCH 10/23] fix: don't overwrite appointment duration if already specified --- .../doctype/patient_appointment/patient_appointment.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js index f7ed31bfea..2d6b64532b 100644 --- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js +++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js @@ -226,7 +226,9 @@ let check_and_set_availability = function(frm) { primary_action_label: __('Book'), primary_action: function() { frm.set_value('appointment_time', selected_slot); - frm.set_value('duration', duration); + if (!frm.doc.duration) { + frm.set_value('duration', duration); + } frm.set_value('practitioner', d.get_value('practitioner')); frm.set_value('department', d.get_value('department')); frm.set_value('appointment_date', d.get_value('appointment_date')); From c7830f71072509cb7fb751b9836bd8f4d6a9e65d Mon Sep 17 00:00:00 2001 From: Anupam K Date: Wed, 26 Aug 2020 15:28:22 +0530 Subject: [PATCH 11/23] feat: Added phone field in product Inquiry --- erpnext/templates/generators/item/item_inquiry.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/erpnext/templates/generators/item/item_inquiry.js b/erpnext/templates/generators/item/item_inquiry.js index 52ddae2624..e7db3a368d 100644 --- a/erpnext/templates/generators/item/item_inquiry.js +++ b/erpnext/templates/generators/item/item_inquiry.js @@ -20,6 +20,13 @@ frappe.ready(() => { options: 'Email', reqd: 1 }, + { + fieldtype: 'Data', + label: __('Phone Number'), + fieldname: 'phone', + options: 'Phone', + reqd: 1 + }, { fieldtype: 'Data', label: __('Subject'), From 733fd5f03c7c855457c27600285fd2d0ace4bad6 Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 26 Aug 2020 18:23:12 +0530 Subject: [PATCH 12/23] fix: get_applied_pricing_rule in taxes_and_totals --- erpnext/controllers/taxes_and_totals.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py index 2a14be8532..92cfdb7f1a 100644 --- a/erpnext/controllers/taxes_and_totals.py +++ b/erpnext/controllers/taxes_and_totals.py @@ -9,6 +9,7 @@ from frappe.utils import cint, flt, round_based_on_smallest_currency_fraction from erpnext.controllers.accounts_controller import validate_conversion_rate, \ validate_taxes_and_charges, validate_inclusive_tax from erpnext.stock.get_item_details import _get_item_tax_template +from erpnext.accounts.doctype.pricing_rule.utils import get_applied_pricing_rules class calculate_taxes_and_totals(object): def __init__(self, doc): @@ -209,7 +210,7 @@ class calculate_taxes_and_totals(object): elif tax.charge_type == "On Previous Row Total": current_tax_fraction = (tax_rate / 100.0) * \ self.doc.get("taxes")[cint(tax.row_id) - 1].grand_total_fraction_for_current_item - + elif tax.charge_type == "On Item Quantity": inclusive_tax_amount_per_qty = flt(tax_rate) @@ -607,7 +608,7 @@ class calculate_taxes_and_totals(object): base_rate_with_margin = 0.0 if item.price_list_rate: if item.pricing_rules and not self.doc.ignore_pricing_rule: - for d in json.loads(item.pricing_rules): + for d in get_applied_pricing_rules(item.pricing_rules): pricing_rule = frappe.get_cached_doc('Pricing Rule', d) if (pricing_rule.margin_type == 'Amount' and pricing_rule.currency == self.doc.currency)\ From bb5d886930da4caf37ba0ea5de38ede957155752 Mon Sep 17 00:00:00 2001 From: bhavesh95863 <34086262+bhavesh95863@users.noreply.github.com> Date: Wed, 26 Aug 2020 18:23:21 +0530 Subject: [PATCH 13/23] fix: account & cost center filter by company --- .../doctype/shipping_rule/shipping_rule.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.js b/erpnext/accounts/doctype/shipping_rule/shipping_rule.js index 53ee08a773..d0904eec3e 100644 --- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.js +++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.js @@ -3,6 +3,22 @@ frappe.ui.form.on('Shipping Rule', { refresh: function(frm) { + frm.set_query("cost_center", function() { + return { + filters: { + company: frm.doc.company + } + } + }) + + frm.set_query("account", function() { + return { + filters: { + company: frm.doc.company + } + } + }) + frm.trigger('toggle_reqd'); }, calculate_based_on: function(frm) { @@ -12,4 +28,4 @@ frappe.ui.form.on('Shipping Rule', { frm.toggle_reqd("shipping_amount", frm.doc.calculate_based_on === 'Fixed'); frm.toggle_reqd("conditions", frm.doc.calculate_based_on !== 'Fixed'); } -}); \ No newline at end of file +}); From 1bd83e69eeb3cb62afa2b6bbd80f5af80b6658c8 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Thu, 27 Aug 2020 13:06:52 +0530 Subject: [PATCH 14/23] feat: added Installation Note and Warranty Claim links to Customer dashboard (#23183) --- erpnext/selling/doctype/customer/customer_dashboard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/customer/customer_dashboard.py b/erpnext/selling/doctype/customer/customer_dashboard.py index cf234650c8..532c11b86e 100644 --- a/erpnext/selling/doctype/customer/customer_dashboard.py +++ b/erpnext/selling/doctype/customer/customer_dashboard.py @@ -33,7 +33,7 @@ def get_data(): }, { 'label': _('Support'), - 'items': ['Issue', 'Maintenance Visit'] + 'items': ['Issue', 'Maintenance Visit', 'Installation Note', 'Warranty Claim'] }, { 'label': _('Projects'), From ead2f6abf0a8d11700ad16f022abdd99273666c1 Mon Sep 17 00:00:00 2001 From: michellealva Date: Thu, 27 Aug 2020 13:57:15 +0530 Subject: [PATCH 15/23] fix: Chage fiedtype of Customer's PO in Sales Invoice --- erpnext/accounts/doctype/sales_invoice/sales_invoice.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 31613e50b0..2397b7d0cb 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -447,7 +447,7 @@ { "allow_on_submit": 1, "fieldname": "po_no", - "fieldtype": "Small Text", + "fieldtype": "Data", "hide_days": 1, "hide_seconds": 1, "label": "Customer's Purchase Order", @@ -1946,7 +1946,7 @@ "idx": 181, "is_submittable": 1, "links": [], - "modified": "2020-08-03 23:31:12.675040", + "modified": "2020-08-27 01:56:28.532140", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", From c8eea556d178607f2b4f09f1b683c64eed7f2bfc Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Thu, 27 Aug 2020 18:54:25 +0530 Subject: [PATCH 16/23] fix: BOM Update Tool failing due to Too Many Writes error --- .../manufacturing/doctype/bom_update_tool/bom_update_tool.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py index e6c10ad12b..742d18c4cd 100644 --- a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py +++ b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py @@ -90,6 +90,7 @@ def update_latest_price_in_all_boms(): update_cost() def replace_bom(args): + frappe.db.auto_commit_on_many_writes = 1 args = frappe._dict(args) doc = frappe.get_doc("BOM Update Tool") @@ -97,6 +98,8 @@ def replace_bom(args): doc.new_bom = args.new_bom doc.replace_bom() + frappe.db.auto_commit_on_many_writes = 0 + def update_cost(): frappe.db.auto_commit_on_many_writes = 1 bom_list = get_boms_in_bottom_up_order() From 33f984c7af1f6b140b8306f0c8d5ee690bdf4805 Mon Sep 17 00:00:00 2001 From: bhavesh95863 <34086262+bhavesh95863@users.noreply.github.com> Date: Thu, 27 Aug 2020 21:49:21 +0530 Subject: [PATCH 17/23] fix: can't multiply sequence by non-int of type 'float --- erpnext/selling/page/point_of_sale/pos_item_cart.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/selling/page/point_of_sale/pos_item_cart.js b/erpnext/selling/page/point_of_sale/pos_item_cart.js index c23a6ad58f..62fc4163e1 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_cart.js +++ b/erpnext/selling/page/point_of_sale/pos_item_cart.js @@ -356,7 +356,7 @@ erpnext.PointOfSale.ItemCart = class { onchange: function() { if (this.value || this.value == 0) { const frm = me.events.get_frm(); - frappe.model.set_value(frm.doc.doctype, frm.doc.name, 'additional_discount_percentage', this.value); + frappe.model.set_value(frm.doc.doctype, frm.doc.name, 'additional_discount_percentage', parseFloat(this.value)); me.hide_discount_control(this.value); } }, @@ -948,4 +948,4 @@ erpnext.PointOfSale.ItemCart = class { show ? this.$component.removeClass('d-none') : this.$component.addClass('d-none'); } -} \ No newline at end of file +} From 3e9f493f15b05c364a6a2df11b11113899d0006c Mon Sep 17 00:00:00 2001 From: bhavesh95863 <34086262+bhavesh95863@users.noreply.github.com> Date: Fri, 28 Aug 2020 11:15:02 +0530 Subject: [PATCH 18/23] fix: change parseFloat to flt --- erpnext/selling/page/point_of_sale/pos_item_cart.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/page/point_of_sale/pos_item_cart.js b/erpnext/selling/page/point_of_sale/pos_item_cart.js index 62fc4163e1..eadeb8fde8 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_cart.js +++ b/erpnext/selling/page/point_of_sale/pos_item_cart.js @@ -356,7 +356,7 @@ erpnext.PointOfSale.ItemCart = class { onchange: function() { if (this.value || this.value == 0) { const frm = me.events.get_frm(); - frappe.model.set_value(frm.doc.doctype, frm.doc.name, 'additional_discount_percentage', parseFloat(this.value)); + frappe.model.set_value(frm.doc.doctype, frm.doc.name, 'additional_discount_percentage', flt(this.value)); me.hide_discount_control(this.value); } }, From 6887382937874ee962336c43674acf715852cce8 Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Fri, 28 Aug 2020 11:52:00 +0530 Subject: [PATCH 19/23] fix: Ignore cpmpany and bank account doctype while deleting company transactions (#22953) --- erpnext/setup/doctype/company/delete_company_transactions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/setup/doctype/company/delete_company_transactions.py b/erpnext/setup/doctype/company/delete_company_transactions.py index 8ecc13b2fb..c94831ef93 100644 --- a/erpnext/setup/doctype/company/delete_company_transactions.py +++ b/erpnext/setup/doctype/company/delete_company_transactions.py @@ -26,7 +26,8 @@ def delete_company_transactions(company_name): tabDocField where fieldtype='Link' and options='Company'"""): if doctype not in ("Account", "Cost Center", "Warehouse", "Budget", "Party Account", "Employee", "Sales Taxes and Charges Template", - "Purchase Taxes and Charges Template", "POS Profile", 'BOM'): + "Purchase Taxes and Charges Template", "POS Profile", "BOM", + "Company", "Bank Account"): delete_for_doctype(doctype, company_name) # reset company values From e9274283bd27415bfb410d5b1991730ea147272d Mon Sep 17 00:00:00 2001 From: marination Date: Fri, 28 Aug 2020 12:21:10 +0530 Subject: [PATCH 20/23] fix: Raise Error on over receipt/consumption for sub-contrcated PR --- erpnext/controllers/buying_controller.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index f982700c01..ac567b7dea 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -276,6 +276,9 @@ class BuyingController(StockController): qty_to_be_received_map = get_qty_to_be_received(purchase_orders) for item in self.get('items'): + if not item.purchase_order: + continue + # reset raw_material cost item.rm_supp_cost = 0 @@ -288,6 +291,12 @@ class BuyingController(StockController): fg_yet_to_be_received = qty_to_be_received_map.get(item_key) + if not fg_yet_to_be_received: + frappe.throw(_("Row #{0}: Item {1} is already fully received in Purchase Order {2}") + .format(item.idx, frappe.bold(item.item_code), + frappe.utils.get_link_to_form("Purchase Order", item.purchase_order)), + title=_("Limit Crossed")) + transferred_batch_qty_map = get_transferred_batch_qty_map(item.purchase_order, item.item_code) backflushed_batch_qty_map = get_backflushed_batch_qty_map(item.purchase_order, item.item_code) From 731bae170e58da232972f621d9436b397c909411 Mon Sep 17 00:00:00 2001 From: marination Date: Fri, 28 Aug 2020 14:09:02 +0530 Subject: [PATCH 21/23] fix: Test for Over Receipt via PRs on a PO --- .../purchase_receipt/test_purchase_receipt.py | 68 ++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index 4a8236dd11..67161aa6dd 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals import unittest +import json import frappe, erpnext import frappe.defaults from frappe.utils import cint, flt, cstr, today, random_string @@ -152,13 +153,78 @@ class TestPurchaseReceipt(unittest.TestCase): qty=100, basic_rate=100, company="_Test Company with perpetual inventory") pr = make_purchase_receipt(item_code="_Test FG Item", qty=10, rate=0, is_subcontracted="Yes", company="_Test Company with perpetual inventory", warehouse='Stores - TCP1', supplier_warehouse='Work In Progress - TCP1') - + gl_entries = get_gl_entries("Purchase Receipt", pr.name) self.assertFalse(gl_entries) set_perpetual_inventory(0) + def test_subcontracting_over_receipt(self): + """ + Behaviour: Raise multiple PRs against one PO that in total + receive more than the required qty in the PO. + Expected Result: Error Raised for Over Receipt against PO. + """ + from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry + from erpnext.buying.doctype.purchase_order.test_purchase_order import (update_backflush_based_on, + make_subcontracted_item, create_purchase_order) + from erpnext.buying.doctype.purchase_order.purchase_order import (make_purchase_receipt, + make_rm_stock_entry as make_subcontract_transfer_entry) + + update_backflush_based_on("Material Transferred for Subcontract") + item_code = "_Test Subcontracted FG Item 1" + make_subcontracted_item(item_code) + + po = create_purchase_order(item_code=item_code, qty=1, + is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") + + #stock raw materials in a warehouse before transfer + make_stock_entry(target="_Test Warehouse - _TC", + item_code="_Test Item Home Desktop 100", qty=1, basic_rate=100) + make_stock_entry(target="_Test Warehouse - _TC", + item_code = "Test Extra Item 1", qty=1, basic_rate=100) + make_stock_entry(target="_Test Warehouse - _TC", + item_code = "_Test Item", qty=1, basic_rate=100) + + rm_items = [ + { + "item_code": item_code, + "rm_item_code": po.supplied_items[0].rm_item_code, + "item_name": "_Test Item", + "qty": po.supplied_items[0].required_qty, + "warehouse": "_Test Warehouse - _TC", + "stock_uom": "Nos" + }, + { + "item_code": item_code, + "rm_item_code": po.supplied_items[1].rm_item_code, + "item_name": "Test Extra Item 1", + "qty": po.supplied_items[1].required_qty, + "warehouse": "_Test Warehouse - _TC", + "stock_uom": "Nos" + }, + { + "item_code": item_code, + "rm_item_code": po.supplied_items[2].rm_item_code, + "item_name": "_Test Item Home Desktop 100", + "qty": po.supplied_items[2].required_qty, + "warehouse": "_Test Warehouse - _TC", + "stock_uom": "Nos" + } + ] + rm_item_string = json.dumps(rm_items) + se = frappe.get_doc(make_subcontract_transfer_entry(po.name, rm_item_string)) + se.to_warehouse = "_Test Warehouse 1 - _TC" + se.save() + se.submit() + + pr1 = make_purchase_receipt(po.name) + pr2 = make_purchase_receipt(po.name) + + pr1.submit() + self.assertRaises(frappe.ValidationError, pr2.submit) + def test_serial_no_supplier(self): pr = make_purchase_receipt(item_code="_Test Serialized Item With Series", qty=1) self.assertEqual(frappe.db.get_value("Serial No", pr.get("items")[0].serial_no, "supplier"), From b23840bf7b668971364ac05cb2425d396b617dd5 Mon Sep 17 00:00:00 2001 From: Syed Mujeer Hashmi Date: Sat, 29 Aug 2020 12:48:48 +0530 Subject: [PATCH 22/23] fix: Filter out cancelled entries in customer ledger summary Signed-off-by: Syed Mujeer Hashmi --- .../report/customer_ledger_summary/customer_ledger_summary.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py b/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py index 2cb10b11e1..10b32fea56 100644 --- a/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py +++ b/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py @@ -173,7 +173,7 @@ class PartyLedgerSummaryReport(object): from `tabGL Entry` gle {join} where - gle.docstatus < 2 and gle.party_type=%(party_type)s and ifnull(gle.party, '') != '' + gle.docstatus < 2 and gle.is_cancelled = 0 and gle.party_type=%(party_type)s and ifnull(gle.party, '') != '' and gle.posting_date <= %(to_date)s {conditions} order by gle.posting_date """.format(join=join, join_field=join_field, conditions=conditions), self.filters, as_dict=True) @@ -248,7 +248,7 @@ class PartyLedgerSummaryReport(object): from `tabGL Entry` where - docstatus < 2 + docstatus < 2 and is_cancelled = 0 and (voucher_type, voucher_no) in ( select voucher_type, voucher_no from `tabGL Entry` gle, `tabAccount` acc where acc.name = gle.account and acc.account_type = '{income_or_expense}' From e268d294b3390daad2a6031db22bdc264a3fda53 Mon Sep 17 00:00:00 2001 From: marination Date: Sun, 30 Aug 2020 21:01:34 +0530 Subject: [PATCH 23/23] fix: Better error feedback on creating SO from Quotation --- erpnext/selling/doctype/quotation/quotation.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index ab095ebfe0..20ae19f5db 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -285,9 +285,17 @@ def _make_customer(source_name, ignore_permissions=False): return customer else: raise - except frappe.MandatoryError: + except frappe.MandatoryError as e: + mandatory_fields = e.args[0].split(':')[1].split(',') + mandatory_fields = [customer.meta.get_label(field.strip()) for field in mandatory_fields] + frappe.local.message_log = [] - frappe.throw(_("Please create Customer from Lead {0}").format(lead_name)) + lead_link = frappe.utils.get_link_to_form("Lead", lead_name) + message = _("Could not auto create Customer due to the following missing mandatory field(s):") + "
    " + message += "
    • " + "
    • ".join(mandatory_fields) + "
    " + message += _("Please create Customer from Lead {0}.").format(lead_link) + + frappe.throw(message, title=_("Mandatory Missing")) else: return customer_name else: