From 4a529f8039ccf594628494e15f18744b785cba68 Mon Sep 17 00:00:00 2001 From: Anupam Date: Tue, 24 Aug 2021 09:35:59 +0530 Subject: [PATCH 01/20] feat: Prospect --- erpnext/crm/doctype/lead/lead.js | 2 +- erpnext/crm/doctype/lead/lead.py | 10 ++ erpnext/crm/doctype/lead/lead_list.js | 36 ++++ .../crm/doctype/opportunity/opportunity.js | 10 +- .../crm/doctype/opportunity/opportunity.json | 6 +- erpnext/crm/doctype/prospect/__init__.py | 0 erpnext/crm/doctype/prospect/prospect.js | 39 +++++ erpnext/crm/doctype/prospect/prospect.json | 165 ++++++++++++++++++ erpnext/crm/doctype/prospect/prospect.py | 45 +++++ erpnext/crm/doctype/prospect/test_prospect.py | 8 + erpnext/crm/doctype/prospect_lead/__init__.py | 0 .../doctype/prospect_lead/prospect_lead.json | 71 ++++++++ .../doctype/prospect_lead/prospect_lead.py | 8 + .../selling/doctype/customer/customer.json | 12 +- 14 files changed, 396 insertions(+), 16 deletions(-) create mode 100644 erpnext/crm/doctype/lead/lead_list.js create mode 100644 erpnext/crm/doctype/prospect/__init__.py create mode 100644 erpnext/crm/doctype/prospect/prospect.js create mode 100644 erpnext/crm/doctype/prospect/prospect.json create mode 100644 erpnext/crm/doctype/prospect/prospect.py create mode 100644 erpnext/crm/doctype/prospect/test_prospect.py create mode 100644 erpnext/crm/doctype/prospect_lead/__init__.py create mode 100644 erpnext/crm/doctype/prospect_lead/prospect_lead.json create mode 100644 erpnext/crm/doctype/prospect_lead/prospect_lead.py diff --git a/erpnext/crm/doctype/lead/lead.js b/erpnext/crm/doctype/lead/lead.js index 75af937990..9c21099088 100644 --- a/erpnext/crm/doctype/lead/lead.js +++ b/erpnext/crm/doctype/lead/lead.js @@ -51,7 +51,7 @@ erpnext.LeadController = class LeadController extends frappe.ui.form.Controller make_customer () { frappe.model.open_mapped_doc({ - method: "erpnext.crm.doctype.lead.lead.make_customer", + method: "erpnext.crm.doctype.lead.lead.make_prospect", frm: cur_frm }) } diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py index 7f028cb316..ecf6a41e6c 100644 --- a/erpnext/crm/doctype/lead/lead.py +++ b/erpnext/crm/doctype/lead/lead.py @@ -190,6 +190,16 @@ class Lead(SellingController): return contact +@frappe.whitelist() +def make_prospect(source_name, target_doc=None, leads=None): + print("``````````````````````````") + print(source_name) + print("``````````````````````````") + print(target_doc) + print("``````````````````````````") + print(leads) + print("``````````````````````````") + @frappe.whitelist() def make_customer(source_name, target_doc=None): return _make_customer(source_name, target_doc) diff --git a/erpnext/crm/doctype/lead/lead_list.js b/erpnext/crm/doctype/lead/lead_list.js new file mode 100644 index 0000000000..5cbbf76480 --- /dev/null +++ b/erpnext/crm/doctype/lead/lead_list.js @@ -0,0 +1,36 @@ +frappe.listview_settings['Lead'] = { + onload: function(listview) { + if (frappe.boot.user.can_create.includes("Prospect")) { + listview.page.add_action_item(__("Create Prospect"), function() { + let leads = listview.get_checked_items(); + console.log(listview.get_checked_items()); + frappe.model.open_mapped_doc({ + method: "erpnext.crm.doctype.lead.lead.make_prospect", + frm: cur_frm, + leads: leads + }) + + // listview.call_for_selected_items(method, {"status": "Open"}); + // let prospect_lead = [] + // leads.forEach(lead => { + // prospect_lead.push({ + // "lead": lead.name + // }); + // }); + // console.log("check"); + // console.log(prospect_lead); + // frappe.new_doc("Prospect", { + // "company_name": leads[0].company_name, + // "industry": leads[0].industry, + // "market_segment": leads[0].market_segment, + // "territory": leads[0].territory, + // "no_of_employees": leads[0].no_of_employees, + // "fax": leads[0].fax, + // "website": leads[0].website, + // "prospect_owner": leads[0].lead_owner, + // "prospect_lead": prospect_lead + // }); + }); + } + } +}; diff --git a/erpnext/crm/doctype/opportunity/opportunity.js b/erpnext/crm/doctype/opportunity/opportunity.js index e9a7a95fc7..bcfae11a05 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.js +++ b/erpnext/crm/doctype/opportunity/opportunity.js @@ -10,15 +10,7 @@ frappe.ui.form.on("Opportunity", { frm.custom_make_buttons = { 'Quotation': 'Quotation', 'Supplier Quotation': 'Supplier Quotation' - }, - - frm.set_query("opportunity_from", function() { - return{ - "filters": { - "name": ["in", ["Customer", "Lead"]], - } - } - }); + }; if (frm.doc.opportunity_from && frm.doc.party_name){ frm.trigger('set_contact_link'); diff --git a/erpnext/crm/doctype/opportunity/opportunity.json b/erpnext/crm/doctype/opportunity/opportunity.json index 4ba4140244..e4b0e47309 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.json +++ b/erpnext/crm/doctype/opportunity/opportunity.json @@ -78,13 +78,13 @@ }, { "fieldname": "opportunity_from", - "fieldtype": "Link", + "fieldtype": "Select", "in_list_view": 1, "in_standard_filter": 1, "label": "Opportunity From", "oldfieldname": "enquiry_from", "oldfieldtype": "Select", - "options": "DocType", + "options": "\nLead\nProspect\nCustomer", "print_hide": 1, "reqd": 1 }, @@ -430,7 +430,7 @@ "icon": "fa fa-info-sign", "idx": 195, "links": [], - "modified": "2021-06-04 10:11:22.831139", + "modified": "2021-08-23 14:43:09.484227", "modified_by": "Administrator", "module": "CRM", "name": "Opportunity", diff --git a/erpnext/crm/doctype/prospect/__init__.py b/erpnext/crm/doctype/prospect/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/crm/doctype/prospect/prospect.js b/erpnext/crm/doctype/prospect/prospect.js new file mode 100644 index 0000000000..793afccf3d --- /dev/null +++ b/erpnext/crm/doctype/prospect/prospect.js @@ -0,0 +1,39 @@ +// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Prospect', { + refresh () { + if (!cur_frm.is_new() && frappe.boot.user.can_create.includes("Customer")) { + cur_frm.add_custom_button(__("Customer"), function() { + frappe.model.open_mapped_doc({ + method: "erpnext.crm.doctype.prospect.prospect.make_customer", + frm: cur_frm + }) + }, __("Create")); + } + if (!cur_frm.is_new() && frappe.boot.user.can_create.includes("Opportunity")) { + cur_frm.add_custom_button(__("Opportunity"), function() { + frappe.model.open_mapped_doc({ + method: "erpnext.crm.doctype.prospect.prospect.make_opportunity", + frm: cur_frm + }) + }, __("Create")); + } + }, + + make_customer () { + console.log("Make Customer"); + frappe.model.open_mapped_doc({ + method: "erpnext.crm.doctype.prospect.prospect.make_customer", + frm: cur_frm + }) + }, + + make_opportunity () { + console.log("Make Opportunity"); + // frappe.model.open_mapped_doc({ + // method: "erpnext.crm.doctype.lead.lead.make_opportunity", + // frm: cur_frm + // }) + } +}); diff --git a/erpnext/crm/doctype/prospect/prospect.json b/erpnext/crm/doctype/prospect/prospect.json new file mode 100644 index 0000000000..6f476a6b65 --- /dev/null +++ b/erpnext/crm/doctype/prospect/prospect.json @@ -0,0 +1,165 @@ +{ + "actions": [], + "autoname": "field:company_name", + "creation": "2021-08-19 00:21:06.995448", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "company_name", + "industry", + "market_segment", + "customer_group", + "territory", + "column_break_6", + "no_of_employees", + "currency", + "annual_revenue", + "fax", + "website", + "prospect_owner", + "leads_section", + "prospect_lead", + "addresses_and_contacts_section", + "address_html", + "column_break_17", + "contact_html", + "notes_section", + "notes" + ], + "fields": [ + { + "fieldname": "company_name", + "fieldtype": "Data", + "label": "Company Name", + "unique": 1 + }, + { + "fieldname": "industry", + "fieldtype": "Link", + "label": "Industry", + "options": "Industry Type" + }, + { + "fieldname": "market_segment", + "fieldtype": "Link", + "label": "Market Segment", + "options": "Market Segment" + }, + { + "fieldname": "customer_group", + "fieldtype": "Link", + "label": "Customer Group", + "options": "Customer Group" + }, + { + "fieldname": "territory", + "fieldtype": "Link", + "label": "Territory", + "options": "Territory" + }, + { + "fieldname": "column_break_6", + "fieldtype": "Column Break" + }, + { + "fieldname": "no_of_employees", + "fieldtype": "Int", + "label": "No. of Employees" + }, + { + "fieldname": "currency", + "fieldtype": "Link", + "label": "Currency", + "options": "Currency" + }, + { + "fieldname": "annual_revenue", + "fieldtype": "Currency", + "label": "Annual Revenue", + "options": "currency" + }, + { + "fieldname": "fax", + "fieldtype": "Data", + "label": "Fax", + "options": "Phone" + }, + { + "fieldname": "website", + "fieldtype": "Data", + "label": "Website", + "options": "URL" + }, + { + "fieldname": "prospect_owner", + "fieldtype": "Link", + "label": "Prospect Owner", + "options": "User" + }, + { + "fieldname": "leads_section", + "fieldtype": "Section Break", + "label": "Leads" + }, + { + "fieldname": "prospect_lead", + "fieldtype": "Table", + "options": "Prospect Lead" + }, + { + "depends_on": "eval: !doc.__islocal", + "fieldname": "addresses_and_contacts_section", + "fieldtype": "Section Break", + "label": "Addresses and Contacts" + }, + { + "fieldname": "address_html", + "fieldtype": "HTML", + "label": "Address HTML" + }, + { + "fieldname": "column_break_17", + "fieldtype": "Column Break" + }, + { + "fieldname": "contact_html", + "fieldtype": "HTML", + "label": "Contact HTML" + }, + { + "collapsible": 1, + "fieldname": "notes_section", + "fieldtype": "Section Break", + "label": "Notes" + }, + { + "fieldname": "notes", + "fieldtype": "Text Editor" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2021-08-19 00:29:00.767038", + "modified_by": "Administrator", + "module": "CRM", + "name": "Prospect", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/crm/doctype/prospect/prospect.py b/erpnext/crm/doctype/prospect/prospect.py new file mode 100644 index 0000000000..a0175cd310 --- /dev/null +++ b/erpnext/crm/doctype/prospect/prospect.py @@ -0,0 +1,45 @@ +# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +import frappe +from frappe.model.document import Document +from frappe.model.mapper import get_mapped_doc + +class Prospect(Document): + pass + +@frappe.whitelist() +def make_customer(source_name, target_doc=None): + def set_missing_values(source, target): + target.customer_type = "Company" + target.company_name = source.name + target.customer_group = source.customer_group or frappe.db.get_default("Customer Group") + + doclist = get_mapped_doc("Prospect", source_name, + {"Prospect": { + "doctype": "Customer", + "field_map": { + "company_name": "customer_name", + "currency": "default_currency", + "fax": "fax" + } + }}, target_doc, set_missing_values, ignore_permissions=False) + + return doclist + +@frappe.whitelist() +def make_opportunity(source_name, target_doc=None): + def set_missing_values(source, target): + target.opportunity_from = "Prospect" + target.customer_name = source.company_name + target.customer_group = source.customer_group or frappe.db.get_default("Customer Group") + + doclist = get_mapped_doc("Prospect", source_name, + {"Prospect": { + "doctype": "Opportunity", + "field_map": { + "name": "party_name", + } + }}, target_doc, set_missing_values, ignore_permissions=False) + + return doclist diff --git a/erpnext/crm/doctype/prospect/test_prospect.py b/erpnext/crm/doctype/prospect/test_prospect.py new file mode 100644 index 0000000000..f266a50593 --- /dev/null +++ b/erpnext/crm/doctype/prospect/test_prospect.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +# import frappe +import unittest + +class TestProspect(unittest.TestCase): + pass diff --git a/erpnext/crm/doctype/prospect_lead/__init__.py b/erpnext/crm/doctype/prospect_lead/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/crm/doctype/prospect_lead/prospect_lead.json b/erpnext/crm/doctype/prospect_lead/prospect_lead.json new file mode 100644 index 0000000000..1797712a55 --- /dev/null +++ b/erpnext/crm/doctype/prospect_lead/prospect_lead.json @@ -0,0 +1,71 @@ +{ + "actions": [], + "creation": "2021-08-19 00:14:14.857421", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "lead", + "lead_name", + "status", + "email", + "mobile_no" + ], + "fields": [ + { + "fieldname": "lead", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Lead", + "options": "Lead", + "reqd": 1 + }, + { + "fetch_from": "lead.lead_name", + "fetch_if_empty": 1, + "fieldname": "lead_name", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Lead Name" + }, + { + "fetch_from": "lead.status", + "fetch_if_empty": 1, + "fieldname": "status", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Status", + "options": "Lead\nOpen\nReplied\nOpportunity\nQuotation\nLost Quotation\nInterested\nConverted\nDo Not Contact" + }, + { + "fetch_from": "lead.email_id", + "fetch_if_empty": 1, + "fieldname": "email", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Email", + "options": "Email" + }, + { + "fetch_from": "lead.mobile_no", + "fetch_if_empty": 1, + "fieldname": "mobile_no", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Mobile No", + "options": "Phone" + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2021-08-20 01:58:39.387874", + "modified_by": "Administrator", + "module": "CRM", + "name": "Prospect Lead", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/crm/doctype/prospect_lead/prospect_lead.py b/erpnext/crm/doctype/prospect_lead/prospect_lead.py new file mode 100644 index 0000000000..2be5a5f39a --- /dev/null +++ b/erpnext/crm/doctype/prospect_lead/prospect_lead.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + +class ProspectLead(Document): + pass diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json index cd94ee101a..608b703862 100644 --- a/erpnext/selling/doctype/customer/customer.json +++ b/erpnext/selling/doctype/customer/customer.json @@ -20,6 +20,7 @@ "tax_withholding_category", "default_bank_account", "lead_name", + "prospect", "image", "column_break0", "account_manager", @@ -212,8 +213,7 @@ "fieldtype": "Link", "ignore_user_permissions": 1, "label": "Represents Company", - "options": "Company", - "unique": 1 + "options": "Company" }, { "depends_on": "represents_company", @@ -493,6 +493,12 @@ "fieldtype": "Link", "label": "Tax Withholding Category", "options": "Tax Withholding Category" + }, + { + "fieldname": "prospect", + "fieldtype": "Link", + "label": "Prospect", + "options": "Prospect" } ], "icon": "fa fa-user", @@ -500,7 +506,7 @@ "image_field": "image", "index_web_pages_for_search": 1, "links": [], - "modified": "2021-01-28 12:54:57.258959", + "modified": "2021-08-23 14:40:15.214350", "modified_by": "Administrator", "module": "Selling", "name": "Customer", From 797b19a14a4b201a2b03dca6a17978793225a22a Mon Sep 17 00:00:00 2001 From: Anupam Date: Tue, 24 Aug 2021 15:50:15 +0530 Subject: [PATCH 02/20] feat: creation of prospect from lead --- erpnext/crm/doctype/lead/lead.js | 8 ++++ erpnext/crm/doctype/lead/lead.py | 19 +++++---- erpnext/crm/doctype/lead/lead_dashboard.py | 2 +- erpnext/crm/doctype/lead/lead_list.js | 46 +++++++++------------- erpnext/crm/doctype/prospect/prospect.py | 21 +++++++++- 5 files changed, 57 insertions(+), 39 deletions(-) diff --git a/erpnext/crm/doctype/lead/lead.js b/erpnext/crm/doctype/lead/lead.js index 9c21099088..f6eb3f4836 100644 --- a/erpnext/crm/doctype/lead/lead.js +++ b/erpnext/crm/doctype/lead/lead.js @@ -39,6 +39,7 @@ erpnext.LeadController = class LeadController extends frappe.ui.form.Controller this.frm.add_custom_button(__("Customer"), this.make_customer, __("Create")); this.frm.add_custom_button(__("Opportunity"), this.make_opportunity, __("Create")); this.frm.add_custom_button(__("Quotation"), this.make_quotation, __("Create")); + this.frm.add_custom_button(__("Prospect"), this.make_prospect, __("Create")); } if (!this.frm.is_new()) { @@ -70,6 +71,13 @@ erpnext.LeadController = class LeadController extends frappe.ui.form.Controller }) } + make_prospect () { + frappe.model.open_mapped_doc({ + method: "erpnext.crm.doctype.lead.lead.make_prospect", + frm: cur_frm + }) + } + company_name () { if (!this.frm.doc.lead_name) { this.frm.set_value("lead_name", this.frm.doc.company_name); diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py index ecf6a41e6c..f76595e978 100644 --- a/erpnext/crm/doctype/lead/lead.py +++ b/erpnext/crm/doctype/lead/lead.py @@ -190,16 +190,6 @@ class Lead(SellingController): return contact -@frappe.whitelist() -def make_prospect(source_name, target_doc=None, leads=None): - print("``````````````````````````") - print(source_name) - print("``````````````````````````") - print(target_doc) - print("``````````````````````````") - print(leads) - print("``````````````````````````") - @frappe.whitelist() def make_customer(source_name, target_doc=None): return _make_customer(source_name, target_doc) @@ -272,6 +262,15 @@ def make_quotation(source_name, target_doc=None): return target_doc +@frappe.whitelist() +def make_prospect(source_name, target_doc=None): + target_doc = get_mapped_doc("Lead", source_name, + {"Lead": { + "doctype": "Prospect", + }}, target_doc) + + return target_doc + def _set_missing_values(source, target): address = frappe.get_all('Dynamic Link', { 'link_doctype': source.doctype, diff --git a/erpnext/crm/doctype/lead/lead_dashboard.py b/erpnext/crm/doctype/lead/lead_dashboard.py index 69d8ca7092..6038811a66 100644 --- a/erpnext/crm/doctype/lead/lead_dashboard.py +++ b/erpnext/crm/doctype/lead/lead_dashboard.py @@ -13,7 +13,7 @@ def get_data(): }, 'transactions': [ { - 'items': ['Opportunity', 'Quotation'] + 'items': ['Opportunity', 'Quotation', 'Prospect'] }, ] } \ No newline at end of file diff --git a/erpnext/crm/doctype/lead/lead_list.js b/erpnext/crm/doctype/lead/lead_list.js index 5cbbf76480..75208fa64b 100644 --- a/erpnext/crm/doctype/lead/lead_list.js +++ b/erpnext/crm/doctype/lead/lead_list.js @@ -2,34 +2,26 @@ frappe.listview_settings['Lead'] = { onload: function(listview) { if (frappe.boot.user.can_create.includes("Prospect")) { listview.page.add_action_item(__("Create Prospect"), function() { - let leads = listview.get_checked_items(); - console.log(listview.get_checked_items()); - frappe.model.open_mapped_doc({ - method: "erpnext.crm.doctype.lead.lead.make_prospect", - frm: cur_frm, - leads: leads - }) + frappe.model.with_doctype("Prospect", function() { + let prospect = frappe.model.get_new_doc("Prospect"); + let leads = listview.get_checked_items(); + frappe.db.get_value("Lead", leads[0].name, ["company_name", "no_of_employees", "industry", "market_segment", "territory", "fax", "website", "lead_owner"], (r) => { + prospect.company_name = r.company_name; + prospect.no_of_employees = r.no_of_employees; + prospect.industry = r.industry; + prospect.market_segment = r.market_segment; + prospect.territory = r.territory; + prospect.fax = r.fax; + prospect.website = r.website; + prospect.prospect_owner = r.lead_owner; - // listview.call_for_selected_items(method, {"status": "Open"}); - // let prospect_lead = [] - // leads.forEach(lead => { - // prospect_lead.push({ - // "lead": lead.name - // }); - // }); - // console.log("check"); - // console.log(prospect_lead); - // frappe.new_doc("Prospect", { - // "company_name": leads[0].company_name, - // "industry": leads[0].industry, - // "market_segment": leads[0].market_segment, - // "territory": leads[0].territory, - // "no_of_employees": leads[0].no_of_employees, - // "fax": leads[0].fax, - // "website": leads[0].website, - // "prospect_owner": leads[0].lead_owner, - // "prospect_lead": prospect_lead - // }); + leads.forEach(function(lead) { + let lead_prospect_row = frappe.model.add_child(prospect, 'prospect_lead'); + lead_prospect_row.lead = lead.name; + }); + frappe.set_route("Form", "Prospect", prospect.name); + }); + }); }); } } diff --git a/erpnext/crm/doctype/prospect/prospect.py b/erpnext/crm/doctype/prospect/prospect.py index a0175cd310..80e2459a90 100644 --- a/erpnext/crm/doctype/prospect/prospect.py +++ b/erpnext/crm/doctype/prospect/prospect.py @@ -6,7 +6,26 @@ from frappe.model.document import Document from frappe.model.mapper import get_mapped_doc class Prospect(Document): - pass + def validate(self): + self.link_with_lead_contact_and_address() + + def link_with_lead_contact_and_address(self): + for row in self.prospect_lead: + links = frappe.get_all('Dynamic Link', filters={'link_doctype': 'Lead', 'link_name': row.lead}, fields=['parent', 'parenttype']) + for link in links: + linked_doc = frappe.get_doc(link['parenttype'], link['parent']) + exists = False + + for d in linked_doc.get('links'): + if d.link_doctype == self.doctype and d.link_name == self.name: + exists = True + + if not exists: + linked_doc.append('links', { + 'link_doctype': self.doctype, + 'link_name': self.name + }) + linked_doc.save(ignore_permissions=True) @frappe.whitelist() def make_customer(source_name, target_doc=None): From 3610882077d5108a0fbc402254026c8f60685359 Mon Sep 17 00:00:00 2001 From: Anupam Date: Tue, 24 Aug 2021 15:51:57 +0530 Subject: [PATCH 03/20] fix: reverting local chnages --- erpnext/crm/doctype/lead/lead.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/crm/doctype/lead/lead.js b/erpnext/crm/doctype/lead/lead.js index f6eb3f4836..0bf2ab9615 100644 --- a/erpnext/crm/doctype/lead/lead.js +++ b/erpnext/crm/doctype/lead/lead.js @@ -52,7 +52,7 @@ erpnext.LeadController = class LeadController extends frappe.ui.form.Controller make_customer () { frappe.model.open_mapped_doc({ - method: "erpnext.crm.doctype.lead.lead.make_prospect", + method: "erpnext.crm.doctype.lead.lead.make_customer", frm: cur_frm }) } From 0c6212189ebe7ff08e7d30b05ff904fb11fc4002 Mon Sep 17 00:00:00 2001 From: Anupam Date: Tue, 24 Aug 2021 16:49:53 +0530 Subject: [PATCH 04/20] feat: link lead communication to prospect --- erpnext/crm/doctype/lead/lead.py | 10 ++++++++++ erpnext/crm/doctype/prospect/prospect.py | 22 +++++++++++++++++++++- erpnext/hooks.py | 3 +++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py index f76595e978..693fc6a160 100644 --- a/erpnext/crm/doctype/lead/lead.py +++ b/erpnext/crm/doctype/lead/lead.py @@ -362,3 +362,13 @@ def daily_open_lead(): leads = frappe.get_all("Lead", filters = [["contact_date", "Between", [nowdate(), nowdate()]]]) for lead in leads: frappe.db.set_value("Lead", lead.name, "status", "Open") + +def add_prospect_link_in_communication(communication, method): + if communication.get('reference_doctype') == "Lead": + links = frappe.get_all('Prospect Lead', filters={'lead': communication.get('reference_name')}, fields=['parent', 'parenttype']) + + for link in links: + communication.append('timeline_links', { + 'link_doctype': link['parenttype'], + 'link_name': link['parent'] + }) diff --git a/erpnext/crm/doctype/prospect/prospect.py b/erpnext/crm/doctype/prospect/prospect.py index 80e2459a90..bd278dca35 100644 --- a/erpnext/crm/doctype/prospect/prospect.py +++ b/erpnext/crm/doctype/prospect/prospect.py @@ -6,9 +6,12 @@ from frappe.model.document import Document from frappe.model.mapper import get_mapped_doc class Prospect(Document): - def validate(self): + def after_save(self): self.link_with_lead_contact_and_address() + def on_trash(self): + self.unlink_dynamic_links() + def link_with_lead_contact_and_address(self): for row in self.prospect_lead: links = frappe.get_all('Dynamic Link', filters={'link_doctype': 'Lead', 'link_name': row.lead}, fields=['parent', 'parenttype']) @@ -27,6 +30,23 @@ class Prospect(Document): }) linked_doc.save(ignore_permissions=True) + def unlink_dynamic_links(self): + links = frappe.get_all('Dynamic Link', filters={'link_doctype': self.doctype, 'link_name': self.name}, fields=['parent', 'parenttype']) + + for link in links: + linked_doc = frappe.get_doc(link['parenttype'], link['parent']) + + if len(linked_doc.get('links')) == 1: + linked_doc.delete(ignore_permissions=True) + else: + to_remove = None + for d in linked_doc.get('links'): + if d.link_doctype == self.doctype and d.link_name == self.name: + to_remove = d + if to_remove: + linked_doc.remove(to_remove) + linked_doc.save(ignore_permissions=True) + @frappe.whitelist() def make_customer(source_name, target_doc=None): def set_missing_values(source, target): diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 8f7c7db208..8069a1566f 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -249,6 +249,9 @@ doc_events = { "on_update": [ "erpnext.support.doctype.service_level_agreement.service_level_agreement.update_hold_time", "erpnext.support.doctype.issue.issue.set_first_response_time" + ], + "after_insert": [ + "erpnext.crm.doctype.lead.lead.add_prospect_link_in_communication" ] }, ("Sales Taxes and Charges Template", 'Price List'): { From dfcac64b442b60fd329586f01b60b262d1be40de Mon Sep 17 00:00:00 2001 From: Anupam Date: Wed, 25 Aug 2021 16:24:46 +0530 Subject: [PATCH 05/20] fix: review chnages --- erpnext/crm/doctype/lead/lead.js | 51 +++++++++++++++++-- erpnext/crm/doctype/lead/lead.py | 35 +++++++------ .../crm/doctype/opportunity/opportunity.js | 29 +++++++++-- .../crm/doctype/opportunity/opportunity.json | 6 +-- .../crm/doctype/opportunity/opportunity.py | 20 ++++++++ erpnext/crm/doctype/prospect/prospect.js | 21 +++----- erpnext/crm/doctype/prospect/prospect.py | 13 ++++- .../doctype/prospect_lead/prospect_lead.json | 22 ++++---- erpnext/hooks.py | 3 -- 9 files changed, 140 insertions(+), 60 deletions(-) diff --git a/erpnext/crm/doctype/lead/lead.js b/erpnext/crm/doctype/lead/lead.js index 0bf2ab9615..7f5f1a4cb4 100644 --- a/erpnext/crm/doctype/lead/lead.js +++ b/erpnext/crm/doctype/lead/lead.js @@ -40,6 +40,9 @@ erpnext.LeadController = class LeadController extends frappe.ui.form.Controller this.frm.add_custom_button(__("Opportunity"), this.make_opportunity, __("Create")); this.frm.add_custom_button(__("Quotation"), this.make_quotation, __("Create")); this.frm.add_custom_button(__("Prospect"), this.make_prospect, __("Create")); + this.frm.add_custom_button(__('Add to Prospect'), function() { + cur_frm.trigger('add_lead_to_prospect') + }, __('Action')); } if (!this.frm.is_new()) { @@ -50,6 +53,34 @@ erpnext.LeadController = class LeadController extends frappe.ui.form.Controller } } + add_lead_to_prospect () { + frappe.prompt([ + { + fieldname: 'prospect', + label: __('Prospect'), + fieldtype: 'Link', + options: 'Prospect', + reqd: 1 + } + ], + function(data) { + frappe.call({ + method: 'erpnext.crm.doctype.lead.lead.add_lead_to_prospect', + args: { + 'lead': cur_frm.doc.name, + 'prospect': data.prospect + }, + callback: function(r) { + if (!r.exc) { + cur_frm.reload_doc(); + } + }, + freeze: true, + freeze_message: __('...Adding Lead to Prospect') + }) + }, __('Add Lead to Prospect'), __('Add')); + } + make_customer () { frappe.model.open_mapped_doc({ method: "erpnext.crm.doctype.lead.lead.make_customer", @@ -72,10 +103,22 @@ erpnext.LeadController = class LeadController extends frappe.ui.form.Controller } make_prospect () { - frappe.model.open_mapped_doc({ - method: "erpnext.crm.doctype.lead.lead.make_prospect", - frm: cur_frm - }) + frappe.model.with_doctype("Prospect", function() { + let prospect = frappe.model.get_new_doc("Prospect"); + prospect.company_name = cur_frm.doc.company_name; + prospect.no_of_employees = cur_frm.doc.no_of_employees; + prospect.industry = cur_frm.doc.industry; + prospect.market_segment = cur_frm.doc.market_segment; + prospect.territory = cur_frm.doc.territory; + prospect.fax = cur_frm.doc.fax; + prospect.website = cur_frm.doc.website; + prospect.prospect_owner = cur_frm.doc.lead_owner; + + let lead_prospect_row = frappe.model.add_child(prospect, 'prospect_lead'); + lead_prospect_row.lead = cur_frm.doc.name; + + frappe.set_route("Form", "Prospect", prospect.name); + }); } company_name () { diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py index 693fc6a160..c6115ee438 100644 --- a/erpnext/crm/doctype/lead/lead.py +++ b/erpnext/crm/doctype/lead/lead.py @@ -62,6 +62,7 @@ class Lead(SellingController): def on_update(self): self.add_calendar_event() + self.update_prospects() def before_insert(self): self.contact_doc = self.create_contact() @@ -88,6 +89,12 @@ class Lead(SellingController): "description": ('Contact ' + cstr(self.lead_name)) + (self.contact_by and ('. By : ' + cstr(self.contact_by)) or '') }, force) + def update_prospects(self): + prospects = frappe.get_all('Prospect Lead', filters={'lead': self.name}, fields=['parent']) + for row in prospects: + prospect = frappe.get_doc('Prospect', row.parent) + prospect.save(ignore_permissions=True) + def check_email_id_is_unique(self): if self.email_id: # validate email is unique @@ -262,15 +269,6 @@ def make_quotation(source_name, target_doc=None): return target_doc -@frappe.whitelist() -def make_prospect(source_name, target_doc=None): - target_doc = get_mapped_doc("Lead", source_name, - {"Lead": { - "doctype": "Prospect", - }}, target_doc) - - return target_doc - def _set_missing_values(source, target): address = frappe.get_all('Dynamic Link', { 'link_doctype': source.doctype, @@ -363,12 +361,13 @@ def daily_open_lead(): for lead in leads: frappe.db.set_value("Lead", lead.name, "status", "Open") -def add_prospect_link_in_communication(communication, method): - if communication.get('reference_doctype') == "Lead": - links = frappe.get_all('Prospect Lead', filters={'lead': communication.get('reference_name')}, fields=['parent', 'parenttype']) - - for link in links: - communication.append('timeline_links', { - 'link_doctype': link['parenttype'], - 'link_name': link['parent'] - }) +@frappe.whitelist() +def add_lead_to_prospect(lead, prospect): + prospect = frappe.get_doc('Prospect', prospect) + prospect.append('prospect_lead', { + 'lead': lead + }) + prospect.save(ignore_permissions=True) + frappe.msgprint(_('Lead {0} has been added to prospect {1}.').format(frappe.bold(lead), frappe.bold(prospect.name)), + title=_('Lead Added'), indicator='green') + \ No newline at end of file diff --git a/erpnext/crm/doctype/opportunity/opportunity.js b/erpnext/crm/doctype/opportunity/opportunity.js index bcfae11a05..80588ee002 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.js +++ b/erpnext/crm/doctype/opportunity/opportunity.js @@ -12,6 +12,14 @@ frappe.ui.form.on("Opportunity", { 'Supplier Quotation': 'Supplier Quotation' }; + frm.set_query("opportunity_from", function() { + return{ + "filters": { + "name": ["in", ["Customer", "Lead", "Prospect"]], + } + } + }); + if (frm.doc.opportunity_from && frm.doc.party_name){ frm.trigger('set_contact_link'); } @@ -87,10 +95,18 @@ frappe.ui.form.on("Opportunity", { }, __('Create')); } - frm.add_custom_button(__('Quotation'), - cur_frm.cscript.create_quotation, __('Create')); + if (frm.doc.opportunity_from != "Customer") { + frm.add_custom_button(__('Customer'), + function() { + frm.trigger("make_customer") + }, __('Create')); + } - } + frm.add_custom_button(__('Quotation'), + function() { + frm.trigger("create_quotation") + }, __('Create')); + } if(!frm.doc.__islocal && frm.perm[0].write && frm.doc.docstatus==0) { if(frm.doc.status==="Open") { @@ -187,6 +203,13 @@ erpnext.crm.Opportunity = class Opportunity extends frappe.ui.form.Controller { frm: cur_frm }) } + + make_customer() { + frappe.model.open_mapped_doc({ + method: "erpnext.crm.doctype.opportunity.opportunity.make_customer", + frm: cur_frm + }) + } }; extend_cscript(cur_frm.cscript, new erpnext.crm.Opportunity({frm: cur_frm})); diff --git a/erpnext/crm/doctype/opportunity/opportunity.json b/erpnext/crm/doctype/opportunity/opportunity.json index e4b0e47309..12a564a9cb 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.json +++ b/erpnext/crm/doctype/opportunity/opportunity.json @@ -78,13 +78,13 @@ }, { "fieldname": "opportunity_from", - "fieldtype": "Select", + "fieldtype": "Link", "in_list_view": 1, "in_standard_filter": 1, "label": "Opportunity From", "oldfieldname": "enquiry_from", "oldfieldtype": "Select", - "options": "\nLead\nProspect\nCustomer", + "options": "DocType", "print_hide": 1, "reqd": 1 }, @@ -430,7 +430,7 @@ "icon": "fa fa-info-sign", "idx": 195, "links": [], - "modified": "2021-08-23 14:43:09.484227", + "modified": "2021-08-25 10:28:24.923543", "modified_by": "Administrator", "module": "CRM", "name": "Opportunity", diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py index 23ad98a282..9e620312b9 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.py +++ b/erpnext/crm/doctype/opportunity/opportunity.py @@ -265,6 +265,26 @@ def make_quotation(source_name, target_doc=None): return doclist +@frappe.whitelist() +def make_customer(source_name, target_doc=None): + def set_missing_values(source, target): + if source.opportunity_from == "Lead": + target.lead_name = source.party_name + if source.opportunity_from == "Prospect": + target.prospect = source.party_name + + doclist = get_mapped_doc("Opportunity", source_name, { + "Opportunity": { + "doctype": "Customer", + "field_map": { + "currency": "default_currency", + "customer_name": "customer_name" + } + } + }, target_doc, set_missing_values) + + return doclist + @frappe.whitelist() def make_request_for_quotation(source_name, target_doc=None): def update_item(obj, target, source_parent): diff --git a/erpnext/crm/doctype/prospect/prospect.js b/erpnext/crm/doctype/prospect/prospect.js index 793afccf3d..64256cf31f 100644 --- a/erpnext/crm/doctype/prospect/prospect.js +++ b/erpnext/crm/doctype/prospect/prospect.js @@ -19,21 +19,12 @@ frappe.ui.form.on('Prospect', { }) }, __("Create")); } - }, - make_customer () { - console.log("Make Customer"); - frappe.model.open_mapped_doc({ - method: "erpnext.crm.doctype.prospect.prospect.make_customer", - frm: cur_frm - }) - }, - - make_opportunity () { - console.log("Make Opportunity"); - // frappe.model.open_mapped_doc({ - // method: "erpnext.crm.doctype.lead.lead.make_opportunity", - // frm: cur_frm - // }) + if (!cur_frm.is_new()) { + frappe.contacts.render_address_and_contact(cur_frm); + cur_frm.trigger('render_contact_day_html'); + } else { + frappe.contacts.clear_address_and_contact(cur_frm); + } } }); diff --git a/erpnext/crm/doctype/prospect/prospect.py b/erpnext/crm/doctype/prospect/prospect.py index bd278dca35..dc165af825 100644 --- a/erpnext/crm/doctype/prospect/prospect.py +++ b/erpnext/crm/doctype/prospect/prospect.py @@ -6,12 +6,23 @@ from frappe.model.document import Document from frappe.model.mapper import get_mapped_doc class Prospect(Document): - def after_save(self): + def validate(self): + self.update_lead_details() + + def on_update(self): self.link_with_lead_contact_and_address() def on_trash(self): self.unlink_dynamic_links() + def update_lead_details(self): + for row in self.get('prospect_lead'): + lead = frappe.get_value('Lead', row.lead, ['lead_name', 'status', 'email_id', 'mobile_no'], as_dict=True) + row.lead_name = lead.lead_name + row.status = lead.status + row.email = lead.email_id + row.mobile_no = lead.mobile_no + def link_with_lead_contact_and_address(self): for row in self.prospect_lead: links = frappe.get_all('Dynamic Link', filters={'link_doctype': 'Lead', 'link_name': row.lead}, fields=['parent', 'parenttype']) diff --git a/erpnext/crm/doctype/prospect_lead/prospect_lead.json b/erpnext/crm/doctype/prospect_lead/prospect_lead.json index 1797712a55..3c160d9e80 100644 --- a/erpnext/crm/doctype/prospect_lead/prospect_lead.json +++ b/erpnext/crm/doctype/prospect_lead/prospect_lead.json @@ -21,45 +21,41 @@ "reqd": 1 }, { - "fetch_from": "lead.lead_name", - "fetch_if_empty": 1, "fieldname": "lead_name", "fieldtype": "Data", "in_list_view": 1, - "label": "Lead Name" + "label": "Lead Name", + "read_only": 1 }, { - "fetch_from": "lead.status", - "fetch_if_empty": 1, "fieldname": "status", "fieldtype": "Select", "in_list_view": 1, "label": "Status", - "options": "Lead\nOpen\nReplied\nOpportunity\nQuotation\nLost Quotation\nInterested\nConverted\nDo Not Contact" + "options": "Lead\nOpen\nReplied\nOpportunity\nQuotation\nLost Quotation\nInterested\nConverted\nDo Not Contact", + "read_only": 1 }, { - "fetch_from": "lead.email_id", - "fetch_if_empty": 1, "fieldname": "email", "fieldtype": "Data", "in_list_view": 1, "label": "Email", - "options": "Email" + "options": "Email", + "read_only": 1 }, { - "fetch_from": "lead.mobile_no", - "fetch_if_empty": 1, "fieldname": "mobile_no", "fieldtype": "Data", "in_list_view": 1, "label": "Mobile No", - "options": "Phone" + "options": "Phone", + "read_only": 1 } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-08-20 01:58:39.387874", + "modified": "2021-08-25 12:58:24.638054", "modified_by": "Administrator", "module": "CRM", "name": "Prospect Lead", diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 8069a1566f..8f7c7db208 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -249,9 +249,6 @@ doc_events = { "on_update": [ "erpnext.support.doctype.service_level_agreement.service_level_agreement.update_hold_time", "erpnext.support.doctype.issue.issue.set_first_response_time" - ], - "after_insert": [ - "erpnext.crm.doctype.lead.lead.add_prospect_link_in_communication" ] }, ("Sales Taxes and Charges Template", 'Price List'): { From c644fbb1023029edd1a30003e14f3dfb5ef4e1fa Mon Sep 17 00:00:00 2001 From: Anupam Date: Wed, 25 Aug 2021 16:35:34 +0530 Subject: [PATCH 06/20] fix: sider issues --- erpnext/crm/doctype/lead/lead.js | 6 ++--- erpnext/crm/doctype/prospect/prospect.js | 4 ++-- erpnext/crm/doctype/prospect/prospect.json | 27 +++++++++++++++------- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/erpnext/crm/doctype/lead/lead.js b/erpnext/crm/doctype/lead/lead.js index 7f5f1a4cb4..dfb3b094dc 100644 --- a/erpnext/crm/doctype/lead/lead.js +++ b/erpnext/crm/doctype/lead/lead.js @@ -40,9 +40,7 @@ erpnext.LeadController = class LeadController extends frappe.ui.form.Controller this.frm.add_custom_button(__("Opportunity"), this.make_opportunity, __("Create")); this.frm.add_custom_button(__("Quotation"), this.make_quotation, __("Create")); this.frm.add_custom_button(__("Prospect"), this.make_prospect, __("Create")); - this.frm.add_custom_button(__('Add to Prospect'), function() { - cur_frm.trigger('add_lead_to_prospect') - }, __('Action')); + this.frm.add_custom_button(__('Add to Prospect'), this.add_lead_to_prospect, __('Action')); } if (!this.frm.is_new()) { @@ -77,7 +75,7 @@ erpnext.LeadController = class LeadController extends frappe.ui.form.Controller }, freeze: true, freeze_message: __('...Adding Lead to Prospect') - }) + }); }, __('Add Lead to Prospect'), __('Add')); } diff --git a/erpnext/crm/doctype/prospect/prospect.js b/erpnext/crm/doctype/prospect/prospect.js index 64256cf31f..814fc2b6db 100644 --- a/erpnext/crm/doctype/prospect/prospect.js +++ b/erpnext/crm/doctype/prospect/prospect.js @@ -8,7 +8,7 @@ frappe.ui.form.on('Prospect', { frappe.model.open_mapped_doc({ method: "erpnext.crm.doctype.prospect.prospect.make_customer", frm: cur_frm - }) + }); }, __("Create")); } if (!cur_frm.is_new() && frappe.boot.user.can_create.includes("Opportunity")) { @@ -16,7 +16,7 @@ frappe.ui.form.on('Prospect', { frappe.model.open_mapped_doc({ method: "erpnext.crm.doctype.prospect.prospect.make_opportunity", frm: cur_frm - }) + }); }, __("Create")); } diff --git a/erpnext/crm/doctype/prospect/prospect.json b/erpnext/crm/doctype/prospect/prospect.json index 6f476a6b65..2eb7cde02d 100644 --- a/erpnext/crm/doctype/prospect/prospect.json +++ b/erpnext/crm/doctype/prospect/prospect.json @@ -15,12 +15,14 @@ "no_of_employees", "currency", "annual_revenue", + "more_details_section", "fax", "website", + "column_break_13", "prospect_owner", "leads_section", "prospect_lead", - "addresses_and_contacts_section", + "address_and_contact_section", "address_html", "column_break_17", "contact_html", @@ -107,12 +109,6 @@ "fieldtype": "Table", "options": "Prospect Lead" }, - { - "depends_on": "eval: !doc.__islocal", - "fieldname": "addresses_and_contacts_section", - "fieldtype": "Section Break", - "label": "Addresses and Contacts" - }, { "fieldname": "address_html", "fieldtype": "HTML", @@ -136,11 +132,26 @@ { "fieldname": "notes", "fieldtype": "Text Editor" + }, + { + "fieldname": "more_details_section", + "fieldtype": "Section Break", + "label": "More Details" + }, + { + "fieldname": "column_break_13", + "fieldtype": "Column Break" + }, + { + "depends_on": "eval: !doc.__islocal", + "fieldname": "address_and_contact_section", + "fieldtype": "Section Break", + "label": "Address and Contact" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2021-08-19 00:29:00.767038", + "modified": "2021-08-25 12:35:00.759909", "modified_by": "Administrator", "module": "CRM", "name": "Prospect", From 5ad8afcc8d6f06c62685f3cf24155cca4e172bf4 Mon Sep 17 00:00:00 2001 From: Anupam Date: Wed, 25 Aug 2021 17:36:53 +0530 Subject: [PATCH 07/20] revert: creation of customer from opportunity --- .../crm/doctype/opportunity/opportunity.js | 14 ------------- .../crm/doctype/opportunity/opportunity.py | 20 ------------------- 2 files changed, 34 deletions(-) diff --git a/erpnext/crm/doctype/opportunity/opportunity.js b/erpnext/crm/doctype/opportunity/opportunity.js index 80588ee002..6ebb0dab57 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.js +++ b/erpnext/crm/doctype/opportunity/opportunity.js @@ -95,13 +95,6 @@ frappe.ui.form.on("Opportunity", { }, __('Create')); } - if (frm.doc.opportunity_from != "Customer") { - frm.add_custom_button(__('Customer'), - function() { - frm.trigger("make_customer") - }, __('Create')); - } - frm.add_custom_button(__('Quotation'), function() { frm.trigger("create_quotation") @@ -203,13 +196,6 @@ erpnext.crm.Opportunity = class Opportunity extends frappe.ui.form.Controller { frm: cur_frm }) } - - make_customer() { - frappe.model.open_mapped_doc({ - method: "erpnext.crm.doctype.opportunity.opportunity.make_customer", - frm: cur_frm - }) - } }; extend_cscript(cur_frm.cscript, new erpnext.crm.Opportunity({frm: cur_frm})); diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py index 9e620312b9..23ad98a282 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.py +++ b/erpnext/crm/doctype/opportunity/opportunity.py @@ -265,26 +265,6 @@ def make_quotation(source_name, target_doc=None): return doclist -@frappe.whitelist() -def make_customer(source_name, target_doc=None): - def set_missing_values(source, target): - if source.opportunity_from == "Lead": - target.lead_name = source.party_name - if source.opportunity_from == "Prospect": - target.prospect = source.party_name - - doclist = get_mapped_doc("Opportunity", source_name, { - "Opportunity": { - "doctype": "Customer", - "field_map": { - "currency": "default_currency", - "customer_name": "customer_name" - } - } - }, target_doc, set_missing_values) - - return doclist - @frappe.whitelist() def make_request_for_quotation(source_name, target_doc=None): def update_item(obj, target, source_parent): From fbac5149298332b9ea893080e9ffbc895c4edea8 Mon Sep 17 00:00:00 2001 From: Anupam Date: Thu, 26 Aug 2021 12:14:29 +0530 Subject: [PATCH 08/20] feat: prospect permission --- erpnext/crm/doctype/prospect/prospect.json | 25 ++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/erpnext/crm/doctype/prospect/prospect.json b/erpnext/crm/doctype/prospect/prospect.json index 2eb7cde02d..237c4255c7 100644 --- a/erpnext/crm/doctype/prospect/prospect.json +++ b/erpnext/crm/doctype/prospect/prospect.json @@ -151,7 +151,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2021-08-25 12:35:00.759909", + "modified": "2021-08-26 12:10:49.191839", "modified_by": "Administrator", "module": "CRM", "name": "Prospect", @@ -159,7 +159,6 @@ "permissions": [ { "create": 1, - "delete": 1, "email": 1, "export": 1, "print": 1, @@ -168,9 +167,31 @@ "role": "System Manager", "share": 1, "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Sales Manager", + "share": 1, + "write": 1 + }, + { + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Sales User", + "share": 1 } ], "sort_field": "modified", "sort_order": "DESC", + "title_field": "company_name", "track_changes": 1 } \ No newline at end of file From de488f68c02654cdd29d2148b1be9919c8d07274 Mon Sep 17 00:00:00 2001 From: Anupam Date: Thu, 26 Aug 2021 14:23:44 +0530 Subject: [PATCH 09/20] adding test cases --- erpnext/crm/doctype/prospect/test_prospect.py | 50 ++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/erpnext/crm/doctype/prospect/test_prospect.py b/erpnext/crm/doctype/prospect/test_prospect.py index f266a50593..0fffad1939 100644 --- a/erpnext/crm/doctype/prospect/test_prospect.py +++ b/erpnext/crm/doctype/prospect/test_prospect.py @@ -1,8 +1,54 @@ # Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors # See license.txt -# import frappe +import frappe import unittest +from frappe.utils import random_string +from erpnext.crm.doctype.lead.test_lead import make_lead +from erpnext.crm.doctype.lead.lead import add_lead_to_prospect + class TestProspect(unittest.TestCase): - pass + def test_add_lead_to_prospect_and_address_linking(self): + lead_doc = make_lead() + address_doc = make_address(address_title=lead_doc.name) + address_doc.append('links', { + "link_doctype": lead_doc.doctype, + "link_name": lead_doc.name + }) + address_doc.save() + prospect_doc = make_prospect() + add_lead_to_prospect(lead_doc.name, prospect_doc.name) + prospect_doc.reload() + lead_exists_in_prosoect = False + for rec in prospect_doc.get('prospect_lead'): + if rec.lead == lead_doc.name: + lead_exists_in_prosoect = True + self.assertEqual(lead_exists_in_prosoect, True) + address_doc.reload() + self.assertEqual(address_doc.has_link('Prospect', prospect_doc.name), True) + + +def make_prospect(**args): + args = frappe._dict(args) + + prospect_doc = frappe.get_doc({ + "doctype": "Prospect", + "company_name": args.company_name or "_Test Company {}".format(random_string(3)), + }).insert() + + return prospect_doc + +def make_address(**args): + args = frappe._dict(args) + + address_doc = frappe.get_doc({ + "doctype": "Address", + "address_title": args.address_title or "Address Title", + "address_type": args.address_type or "Billing", + "city": args.city or "Mumbai", + "address_line1": args.address_line1 or "Vidya Vihar West", + "country": args.country or "India" + }).insert() + + return address_doc From d701ad5313bf2f33a9e8125f24bbf4c9b49a8525 Mon Sep 17 00:00:00 2001 From: Anupam Date: Fri, 27 Aug 2021 13:09:52 +0530 Subject: [PATCH 10/20] fix: using frm instead of cur_frm --- erpnext/crm/doctype/lead/lead.js | 38 ++++++++++++------------ erpnext/crm/doctype/prospect/prospect.js | 21 +++++++------ erpnext/crm/doctype/prospect/prospect.py | 4 +++ 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/erpnext/crm/doctype/lead/lead.js b/erpnext/crm/doctype/lead/lead.js index dfb3b094dc..95cf03241b 100644 --- a/erpnext/crm/doctype/lead/lead.js +++ b/erpnext/crm/doctype/lead/lead.js @@ -51,7 +51,7 @@ erpnext.LeadController = class LeadController extends frappe.ui.form.Controller } } - add_lead_to_prospect () { + add_lead_to_prospect (frm) { frappe.prompt([ { fieldname: 'prospect', @@ -65,12 +65,12 @@ erpnext.LeadController = class LeadController extends frappe.ui.form.Controller frappe.call({ method: 'erpnext.crm.doctype.lead.lead.add_lead_to_prospect', args: { - 'lead': cur_frm.doc.name, + 'lead': frm.doc.name, 'prospect': data.prospect }, callback: function(r) { if (!r.exc) { - cur_frm.reload_doc(); + frm.reload_doc(); } }, freeze: true, @@ -79,41 +79,41 @@ erpnext.LeadController = class LeadController extends frappe.ui.form.Controller }, __('Add Lead to Prospect'), __('Add')); } - make_customer () { + make_customer (frm) { frappe.model.open_mapped_doc({ method: "erpnext.crm.doctype.lead.lead.make_customer", - frm: cur_frm + frm: frm }) } - make_opportunity () { + make_opportunity (frm) { frappe.model.open_mapped_doc({ method: "erpnext.crm.doctype.lead.lead.make_opportunity", - frm: cur_frm + frm: frm }) } - make_quotation () { + make_quotation (frm) { frappe.model.open_mapped_doc({ method: "erpnext.crm.doctype.lead.lead.make_quotation", - frm: cur_frm + frm: frm }) } - make_prospect () { + make_prospect (frm) { frappe.model.with_doctype("Prospect", function() { let prospect = frappe.model.get_new_doc("Prospect"); - prospect.company_name = cur_frm.doc.company_name; - prospect.no_of_employees = cur_frm.doc.no_of_employees; - prospect.industry = cur_frm.doc.industry; - prospect.market_segment = cur_frm.doc.market_segment; - prospect.territory = cur_frm.doc.territory; - prospect.fax = cur_frm.doc.fax; - prospect.website = cur_frm.doc.website; - prospect.prospect_owner = cur_frm.doc.lead_owner; + prospect.company_name = frm.doc.company_name; + prospect.no_of_employees = frm.doc.no_of_employees; + prospect.industry = frm.doc.industry; + prospect.market_segment = frm.doc.market_segment; + prospect.territory = frm.doc.territory; + prospect.fax = frm.doc.fax; + prospect.website = frm.doc.website; + prospect.prospect_owner = frm.doc.lead_owner; let lead_prospect_row = frappe.model.add_child(prospect, 'prospect_lead'); - lead_prospect_row.lead = cur_frm.doc.name; + lead_prospect_row.lead = frm.doc.name; frappe.set_route("Form", "Prospect", prospect.name); }); diff --git a/erpnext/crm/doctype/prospect/prospect.js b/erpnext/crm/doctype/prospect/prospect.js index 814fc2b6db..67018e1ef9 100644 --- a/erpnext/crm/doctype/prospect/prospect.js +++ b/erpnext/crm/doctype/prospect/prospect.js @@ -2,29 +2,28 @@ // For license information, please see license.txt frappe.ui.form.on('Prospect', { - refresh () { - if (!cur_frm.is_new() && frappe.boot.user.can_create.includes("Customer")) { - cur_frm.add_custom_button(__("Customer"), function() { + refresh (frm) { + if (!frm.is_new() && frappe.boot.user.can_create.includes("Customer")) { + frm.add_custom_button(__("Customer"), function() { frappe.model.open_mapped_doc({ method: "erpnext.crm.doctype.prospect.prospect.make_customer", - frm: cur_frm + frm: frm }); }, __("Create")); } - if (!cur_frm.is_new() && frappe.boot.user.can_create.includes("Opportunity")) { - cur_frm.add_custom_button(__("Opportunity"), function() { + if (!frm.is_new() && frappe.boot.user.can_create.includes("Opportunity")) { + frm.add_custom_button(__("Opportunity"), function() { frappe.model.open_mapped_doc({ method: "erpnext.crm.doctype.prospect.prospect.make_opportunity", - frm: cur_frm + frm: frm }); }, __("Create")); } - if (!cur_frm.is_new()) { - frappe.contacts.render_address_and_contact(cur_frm); - cur_frm.trigger('render_contact_day_html'); + if (!frm.is_new()) { + frappe.contacts.render_address_and_contact(frm); } else { - frappe.contacts.clear_address_and_contact(cur_frm); + frappe.contacts.clear_address_and_contact(frm); } } }); diff --git a/erpnext/crm/doctype/prospect/prospect.py b/erpnext/crm/doctype/prospect/prospect.py index dc165af825..5f5815de5e 100644 --- a/erpnext/crm/doctype/prospect/prospect.py +++ b/erpnext/crm/doctype/prospect/prospect.py @@ -4,8 +4,12 @@ import frappe from frappe.model.document import Document from frappe.model.mapper import get_mapped_doc +from frappe.contacts.address_and_contact import load_address_and_contact class Prospect(Document): + def onload(self): + load_address_and_contact(self) + def validate(self): self.update_lead_details() From 987746592c73b7c163df11e8f97e4a94c984ec6c Mon Sep 17 00:00:00 2001 From: Saqib Date: Fri, 27 Aug 2021 15:41:26 +0530 Subject: [PATCH 11/20] fix: period closing voucher tests (#27198) --- .../test_period_closing_voucher.py | 142 ++++++++---------- 1 file changed, 60 insertions(+), 82 deletions(-) diff --git a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py index 2d1939131c..2a636bb338 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py +++ b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py @@ -13,59 +13,49 @@ from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sal class TestPeriodClosingVoucher(unittest.TestCase): def test_closing_entry(self): - year_start_date = get_fiscal_year(today(), company="_Test Company")[1] - - make_journal_entry("_Test Bank - _TC", "Sales - _TC", 400, - "_Test Cost Center - _TC", posting_date=now(), submit=True) - - make_journal_entry("_Test Account Cost for Goods Sold - _TC", - "_Test Bank - _TC", 600, "_Test Cost Center - _TC", posting_date=now(), submit=True) - - random_expense_account = frappe.db.sql(""" - select t1.account, - sum(t1.debit) - sum(t1.credit) as balance, - sum(t1.debit_in_account_currency) - sum(t1.credit_in_account_currency) \ - as balance_in_account_currency - from `tabGL Entry` t1, `tabAccount` t2 - where t1.account = t2.name and t2.root_type = 'Expense' - and t2.docstatus < 2 and t2.company = '_Test Company' - and t1.posting_date between %s and %s - group by t1.account - having sum(t1.debit) > sum(t1.credit) - limit 1""", (year_start_date, today()), as_dict=True) - - profit_or_loss = frappe.db.sql("""select sum(t1.debit) - sum(t1.credit) as balance - from `tabGL Entry` t1, `tabAccount` t2 - where t1.account = t2.name and t2.report_type = 'Profit and Loss' - and t2.docstatus < 2 and t2.company = '_Test Company' - and t1.posting_date between %s and %s""", (year_start_date, today())) - - profit_or_loss = flt(profit_or_loss[0][0]) if profit_or_loss else 0 + frappe.db.sql("delete from `tabGL Entry` where company='Test PCV Company'") - pcv = self.make_period_closing_voucher() + company = create_company() + cost_center = create_cost_center('Test Cost Center 1') - # Check value for closing account - gle_amount_for_closing_account = frappe.db.sql("""select debit - credit - from `tabGL Entry` where voucher_type='Period Closing Voucher' and voucher_no=%s - and account = '_Test Account Reserves and Surplus - _TC'""", pcv.name) + jv1 = make_journal_entry( + amount=400, + account1="Cash - TPC", + account2="Sales - TPC", + cost_center=cost_center, + posting_date=now(), + save=False + ) + jv1.company = company + jv1.save() + jv1.submit() + + jv2 = make_journal_entry( + amount=600, + account1="Cost of Goods Sold - TPC", + account2="Cash - TPC", + cost_center=cost_center, + posting_date=now(), + save=False + ) + jv2.company = company + jv2.save() + jv2.submit() - gle_amount_for_closing_account = flt(gle_amount_for_closing_account[0][0]) \ - if gle_amount_for_closing_account else 0 + pcv = self.make_period_closing_voucher() + surplus_account = pcv.closing_account_head - self.assertEqual(gle_amount_for_closing_account, profit_or_loss) + expected_gle = ( + ('Cost of Goods Sold - TPC', 0.0, 600.0), + (surplus_account, 600.0, 400.0), + ('Sales - TPC', 400.0, 0.0) + ) - if random_expense_account: - # Check posted value for teh above random_expense_account - gle_for_random_expense_account = frappe.db.sql(""" - select sum(debit - credit) as amount, - sum(debit_in_account_currency - credit_in_account_currency) as amount_in_account_currency - from `tabGL Entry` - where voucher_type='Period Closing Voucher' and voucher_no=%s and account =%s""", - (pcv.name, random_expense_account[0].account), as_dict=True) + pcv_gle = frappe.db.sql(""" + select account, debit, credit from `tabGL Entry` where voucher_no=%s order by account + """, (pcv.name)) - self.assertEqual(gle_for_random_expense_account[0].amount, -1*random_expense_account[0].balance) - self.assertEqual(gle_for_random_expense_account[0].amount_in_account_currency, - -1*random_expense_account[0].balance_in_account_currency) + self.assertEqual(pcv_gle, expected_gle) def test_cost_center_wise_posting(self): frappe.db.sql("delete from `tabGL Entry` where company='Test PCV Company'") @@ -93,31 +83,23 @@ class TestPeriodClosingVoucher(unittest.TestCase): debit_to="Debtors - TPC" ) - pcv = frappe.get_doc({ - "transaction_date": today(), - "posting_date": today(), - "fiscal_year": get_fiscal_year(today())[0], - "company": "Test PCV Company", - "cost_center_wise_pnl": 1, - "closing_account_head": surplus_account, - "remarks": "Test", - "doctype": "Period Closing Voucher" - }) - pcv.insert() - pcv.submit() + pcv = self.make_period_closing_voucher() + surplus_account = pcv.closing_account_head expected_gle = ( - ('Sales - TPC', 200.0, 0.0, cost_center2), + (surplus_account, 0.0, 400.0, cost_center1), (surplus_account, 0.0, 200.0, cost_center2), ('Sales - TPC', 400.0, 0.0, cost_center1), - (surplus_account, 0.0, 400.0, cost_center1) + ('Sales - TPC', 200.0, 0.0, cost_center2), ) pcv_gle = frappe.db.sql(""" - select account, debit, credit, cost_center from `tabGL Entry` where voucher_no=%s + select account, debit, credit, cost_center + from `tabGL Entry` where voucher_no=%s + order by account, cost_center """, (pcv.name)) - self.assertTrue(pcv_gle, expected_gle) + self.assertEqual(pcv_gle, expected_gle) def test_period_closing_with_finance_book_entries(self): frappe.db.sql("delete from `tabGL Entry` where company='Test PCV Company'") @@ -146,39 +128,35 @@ class TestPeriodClosingVoucher(unittest.TestCase): jv.save() jv.submit() - pcv = frappe.get_doc({ - "transaction_date": today(), - "posting_date": today(), - "fiscal_year": get_fiscal_year(today())[0], - "company": company, - "closing_account_head": surplus_account, - "remarks": "Test", - "doctype": "Period Closing Voucher" - }) - pcv.insert() - pcv.submit() + pcv = self.make_period_closing_voucher() + surplus_account = pcv.closing_account_head expected_gle = ( - (surplus_account, 0.0, 400.0, ''), + (surplus_account, 0.0, 400.0, None), (surplus_account, 0.0, 400.0, jv.finance_book), - ('Sales - TPC', 400.0, 0.0, ''), + ('Sales - TPC', 400.0, 0.0, None), ('Sales - TPC', 400.0, 0.0, jv.finance_book) ) pcv_gle = frappe.db.sql(""" - select account, debit, credit, finance_book from `tabGL Entry` where voucher_no=%s + select account, debit, credit, finance_book + from `tabGL Entry` where voucher_no=%s + order by account, finance_book """, (pcv.name)) - self.assertTrue(pcv_gle, expected_gle) + self.assertEqual(pcv_gle, expected_gle) def make_period_closing_voucher(self): + surplus_account = create_account() + cost_center = create_cost_center("Test Cost Center 1") pcv = frappe.get_doc({ "doctype": "Period Closing Voucher", - "closing_account_head": "_Test Account Reserves and Surplus - _TC", - "company": "_Test Company", - "fiscal_year": get_fiscal_year(today(), company="_Test Company")[0], + "transaction_date": today(), "posting_date": today(), - "cost_center": "_Test Cost Center - _TC", + "company": "Test PCV Company", + "fiscal_year": get_fiscal_year(today(), company="Test PCV Company")[0], + "cost_center": cost_center, + "closing_account_head": surplus_account, "remarks": "test" }) pcv.insert() From a285b5b78b8080cda0a917cd45cc06e7de4e6ff9 Mon Sep 17 00:00:00 2001 From: Kamal Johnson Date: Fri, 27 Aug 2021 15:47:11 +0530 Subject: [PATCH 12/20] feat: Accounts, Selling & Assets Onboarding cleanup (#27112) * refactor: company form fields arrangement * refactor: accounts onboarding steps * refactor: re-arrange fields & modify labels in company form * feat: onbording steps for accounts module * fix: updated onboarding steps for selling module * fix: remove unwanted steps from accounts * feat: add more onboarding steps * feat: Refactor onboarding-module for accounting workspace * feat: Add basic asset onboarding steps * feat: Add basic asset item form tour * feat: Add basic selling onboarding-steps * feat: Add basic form tour for purchase recipt * feat: Add basic form tour for existing asset * feat: Adding asset category form tour * feat: Add form tour for asset category * feat: Refactor sales taxes and charges template form tour with new method * refactor: Remove old form tour for accounts settings * refactor: Change asset category form tour with new tour method * refactor: Change asset item form tour with new tour method * refactor: Change purchase receipt form tour with new tour method * refactor: Change asset form tour with new tour method * refactor: Remove old form tour for selling settings * refactor: general fix/typo in onboarding steps * Apply suggestions from code review Co-authored-by: Nabin Hait * refactor: Remove old form tour method for sales order. * fix: removed duplicate section break * fix: Removed duplicate fields Co-authored-by: Saqib Ansari Co-authored-by: Anuja Co-authored-by: Afshan <33727827+AfshanKhan@users.noreply.github.com> Co-authored-by: Nabin Hait --- .../accounts_settings/accounts_settings.js | 43 ------ .../sales_taxes_and_charges_template.js | 22 --- .../accounts_settings/accounts_settings.json | 113 ++++++++++++++++ .../purchase_invoice/purchase_invoice.json | 96 ++++++++++++++ .../sales_taxes_and_charges_template.json | 65 +++++++++ .../module_onboarding/accounts/accounts.json | 16 +-- .../accounts_settings/accounts_settings.json | 21 +++ .../chart_of_accounts/chart_of_accounts.json | 11 +- .../onboarding_step/company/company.json | 22 +++ ...cost_centers_for_report_and_budgeting.json | 21 +++ .../create_your_first_purchase_invoice.json | 7 +- .../financial_statements.json | 23 ++++ .../setup_taxes/setup_taxes.json | 8 +- .../updating_opening_balances.json | 22 +++ erpnext/assets/form_tour/asset/asset.json | 125 ++++++++++++++++++ .../asset_category/asset_category.json | 65 +++++++++ .../module_onboarding/assets/assets.json | 12 +- .../asset_category/asset_category.json | 21 +++ .../asset_item/asset_item.json | 21 +++ .../asset_purchase/asset_purchase.json | 21 +++ .../existing_asset/existing_asset.json | 21 +++ .../fixed_asset_accounts.json | 21 +++ .../selling_settings/selling_settings.js | 23 ---- .../form_tour/sales_order/sales_order.json | 97 ++++++++++++++ .../selling_settings/selling_settings.json | 65 +++++++++ .../module_onboarding/selling/selling.json | 21 +-- .../create_a_customer/create_a_customer.json | 2 +- .../create_a_product/create_a_product.json | 4 +- .../create_a_quotation.json | 2 +- .../create_a_sales_order.json | 21 +++ .../introduction_to_selling.json | 2 +- .../sales_order/sales_order.json | 21 +++ .../selling_settings/selling_settings.json | 8 +- .../setup_your_warehouse.json | 4 +- erpnext/setup/doctype/company/company.json | 20 +-- erpnext/stock/form_tour/item/item.json | 89 +++++++++++++ .../purchase_receipt/purchase_receipt.json | 41 ++++++ 37 files changed, 1065 insertions(+), 152 deletions(-) create mode 100644 erpnext/accounts/form_tour/accounts_settings/accounts_settings.json create mode 100644 erpnext/accounts/form_tour/purchase_invoice/purchase_invoice.json create mode 100644 erpnext/accounts/form_tour/sales_taxes_and_charges_template/sales_taxes_and_charges_template.json create mode 100644 erpnext/accounts/onboarding_step/accounts_settings/accounts_settings.json create mode 100644 erpnext/accounts/onboarding_step/company/company.json create mode 100644 erpnext/accounts/onboarding_step/cost_centers_for_report_and_budgeting/cost_centers_for_report_and_budgeting.json create mode 100644 erpnext/accounts/onboarding_step/financial_statements/financial_statements.json create mode 100644 erpnext/accounts/onboarding_step/updating_opening_balances/updating_opening_balances.json create mode 100644 erpnext/assets/form_tour/asset/asset.json create mode 100644 erpnext/assets/form_tour/asset_category/asset_category.json create mode 100644 erpnext/assets/onboarding_step/asset_category/asset_category.json create mode 100644 erpnext/assets/onboarding_step/asset_item/asset_item.json create mode 100644 erpnext/assets/onboarding_step/asset_purchase/asset_purchase.json create mode 100644 erpnext/assets/onboarding_step/existing_asset/existing_asset.json create mode 100644 erpnext/assets/onboarding_step/fixed_asset_accounts/fixed_asset_accounts.json create mode 100644 erpnext/selling/form_tour/sales_order/sales_order.json create mode 100644 erpnext/selling/form_tour/selling_settings/selling_settings.json create mode 100644 erpnext/selling/onboarding_step/create_a_sales_order/create_a_sales_order.json create mode 100644 erpnext/selling/onboarding_step/sales_order/sales_order.json create mode 100644 erpnext/stock/form_tour/item/item.json create mode 100644 erpnext/stock/form_tour/purchase_receipt/purchase_receipt.json diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.js b/erpnext/accounts/doctype/accounts_settings/accounts_settings.js index e44af3a916..0627675de7 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.js +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.js @@ -6,46 +6,3 @@ frappe.ui.form.on('Accounts Settings', { } }); - -frappe.tour['Accounts Settings'] = [ - { - fieldname: "acc_frozen_upto", - title: "Accounts Frozen Upto", - description: __("Freeze accounting transactions up to specified date, nobody can make/modify entry except the specified Role."), - }, - { - fieldname: "frozen_accounts_modifier", - title: "Role Allowed to Set Frozen Accounts & Edit Frozen Entries", - description: __("Users with this Role are allowed to set frozen accounts and create/modify accounting entries against frozen accounts.") - }, - { - fieldname: "determine_address_tax_category_from", - title: "Determine Address Tax Category From", - description: __("Tax category can be set on Addresses. An address can be Shipping or Billing address. Set which addres to select when applying Tax Category.") - }, - { - fieldname: "over_billing_allowance", - title: "Over Billing Allowance Percentage", - description: __("The percentage by which you can overbill transactions. For example, if the order value is $100 for an Item and percentage here is set as 10% then you are allowed to bill for $110.") - }, - { - fieldname: "credit_controller", - title: "Credit Controller", - description: __("Select the role that is allowed to submit transactions that exceed credit limits set. The credit limit can be set in the Customer form.") - }, - { - fieldname: "make_payment_via_journal_entry", - title: "Make Payment via Journal Entry", - description: __("When checked, if user proceeds to make payment from an invoice, the system will open a Journal Entry instead of a Payment Entry.") - }, - { - fieldname: "unlink_payment_on_cancellation_of_invoice", - title: "Unlink Payment on Cancellation of Invoice", - description: __("If checked, system will unlink the payment against the respective invoice.") - }, - { - fieldname: "unlink_advance_payment_on_cancelation_of_order", - title: "Unlink Advance Payment on Cancellation of Order", - description: __("Similar to the previous option, this unlinks any advance payments made against Purchase/Sales Orders.") - } -]; diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js index 0e011883b1..97a6fdd336 100644 --- a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js +++ b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js @@ -5,25 +5,3 @@ cur_frm.cscript.tax_table = "Sales Taxes and Charges"; {% include "erpnext/public/js/controllers/accounts.js" %} -frappe.tour['Sales Taxes and Charges Template'] = [ - { - fieldname: "title", - title: __("Title"), - description: __("A name by which you will identify this template. You can change this later."), - }, - { - fieldname: "company", - title: __("Company"), - description: __("Company for which this tax template will be applicable"), - }, - { - fieldname: "is_default", - title: __("Is this Default?"), - description: __("Set this template as the default for all sales transactions"), - }, - { - fieldname: "taxes", - title: __("Taxes Table"), - description: __("You can add a row for a tax rule here. These rules can be applied on the net total, or can be a flat amount."), - } -]; diff --git a/erpnext/accounts/form_tour/accounts_settings/accounts_settings.json b/erpnext/accounts/form_tour/accounts_settings/accounts_settings.json new file mode 100644 index 0000000000..e2bf50d20a --- /dev/null +++ b/erpnext/accounts/form_tour/accounts_settings/accounts_settings.json @@ -0,0 +1,113 @@ +{ + "creation": "2021-06-29 17:00:18.273054", + "docstatus": 0, + "doctype": "Form Tour", + "idx": 0, + "is_standard": 1, + "modified": "2021-06-29 17:00:26.145996", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Accounts Settings", + "owner": "Administrator", + "reference_doctype": "Accounts Settings", + "save_on_complete": 0, + "steps": [ + { + "description": "The percentage by which you can overbill transactions. For example, if the order value is $100 for an Item and percentage here is set as 10% then you are allowed to bill for $110.", + "field": "", + "fieldname": "over_billing_allowance", + "fieldtype": "Currency", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Over Billing Allowance (%)", + "parent_field": "", + "position": "Right", + "title": "Over Billing Allowance Percentage" + }, + { + "description": "Select the role that is allowed to overbill a transactions.", + "field": "", + "fieldname": "role_allowed_to_over_bill", + "fieldtype": "Link", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Role Allowed to Over Bill ", + "parent_field": "", + "position": "Right", + "title": "Role Allowed to Over Bill" + }, + { + "description": "If checked, system will unlink the payment against the respective invoice.", + "field": "", + "fieldname": "unlink_payment_on_cancellation_of_invoice", + "fieldtype": "Check", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Unlink Payment on Cancellation of Invoice", + "parent_field": "", + "position": "Bottom", + "title": "Unlink Payment on Cancellation of Invoice" + }, + { + "description": "Similar to the previous option, this unlinks any advance payments made against Purchase/Sales Orders.", + "field": "", + "fieldname": "unlink_advance_payment_on_cancelation_of_order", + "fieldtype": "Check", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Unlink Advance Payment on Cancellation of Order", + "parent_field": "", + "position": "Bottom", + "title": "Unlink Advance Payment on Cancellation of Order" + }, + { + "description": "Tax category can be set on Addresses. An address can be Shipping or Billing address. Set which addres to select when applying Tax Category.", + "field": "", + "fieldname": "determine_address_tax_category_from", + "fieldtype": "Select", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Determine Address Tax Category From", + "parent_field": "", + "position": "Right", + "title": "Determine Address Tax Category From" + }, + { + "description": "Freeze accounting transactions up to specified date, nobody can make/modify entry except the specified Role.", + "field": "", + "fieldname": "acc_frozen_upto", + "fieldtype": "Date", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Accounts Frozen Till Date", + "parent_field": "", + "position": "Right", + "title": "Accounts Frozen Upto" + }, + { + "description": "Users with this Role are allowed to set frozen accounts and create/modify accounting entries against frozen accounts.", + "field": "", + "fieldname": "frozen_accounts_modifier", + "fieldtype": "Link", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Role Allowed to Set Frozen Accounts and Edit Frozen Entries", + "parent_field": "", + "position": "Right", + "title": "Role Allowed to Set Frozen Accounts & Edit Frozen Entries" + }, + { + "description": "Select the role that is allowed to submit transactions that exceed credit limits set. The credit limit can be set in the Customer form.", + "field": "", + "fieldname": "credit_controller", + "fieldtype": "Link", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Credit Controller", + "parent_field": "", + "position": "Left", + "title": "Credit Controller" + } + ], + "title": "Accounts Settings" +} \ No newline at end of file diff --git a/erpnext/accounts/form_tour/purchase_invoice/purchase_invoice.json b/erpnext/accounts/form_tour/purchase_invoice/purchase_invoice.json new file mode 100644 index 0000000000..2dffcd1c0e --- /dev/null +++ b/erpnext/accounts/form_tour/purchase_invoice/purchase_invoice.json @@ -0,0 +1,96 @@ +{ + "creation": "2021-06-29 16:31:48.558826", + "docstatus": 0, + "doctype": "Form Tour", + "idx": 0, + "is_standard": 1, + "modified": "2021-06-29 16:31:48.558826", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Purchase Invoice", + "owner": "Administrator", + "reference_doctype": "Purchase Invoice", + "save_on_complete": 1, + "steps": [ + { + "description": "Select Supplier", + "field": "", + "fieldname": "supplier", + "fieldtype": "Link", + "has_next_condition": 1, + "is_table_field": 0, + "label": "Supplier", + "next_step_condition": "supplier", + "parent_field": "", + "position": "Right", + "title": "Select Supplier" + }, + { + "description": "Add items in the table", + "field": "", + "fieldname": "items", + "fieldtype": "Table", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Items", + "parent_field": "", + "position": "Bottom", + "title": "List of Items" + }, + { + "child_doctype": "Purchase Invoice Item", + "description": "Select an item", + "field": "", + "fieldname": "item_code", + "fieldtype": "Link", + "has_next_condition": 0, + "is_table_field": 1, + "label": "Item", + "parent_field": "", + "parent_fieldname": "items", + "position": "Right", + "title": "Select Item" + }, + { + "child_doctype": "Purchase Invoice Item", + "description": "Enter the quantity", + "field": "", + "fieldname": "qty", + "fieldtype": "Float", + "has_next_condition": 0, + "is_table_field": 1, + "label": "Accepted Qty", + "parent_field": "", + "parent_fieldname": "items", + "position": "Right", + "title": "Enter Quantity" + }, + { + "child_doctype": "Purchase Invoice Item", + "description": "Enter rate of the item", + "field": "", + "fieldname": "rate", + "fieldtype": "Currency", + "has_next_condition": 0, + "is_table_field": 1, + "label": "Rate", + "parent_field": "", + "parent_fieldname": "items", + "position": "Right", + "title": "Enter Rate" + }, + { + "description": "You can add taxes here", + "field": "", + "fieldname": "taxes", + "fieldtype": "Table", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Purchase Taxes and Charges", + "parent_field": "", + "position": "Bottom", + "title": "Select taxes" + } + ], + "title": "Purchase Invoice" +} \ No newline at end of file diff --git a/erpnext/accounts/form_tour/sales_taxes_and_charges_template/sales_taxes_and_charges_template.json b/erpnext/accounts/form_tour/sales_taxes_and_charges_template/sales_taxes_and_charges_template.json new file mode 100644 index 0000000000..7de9ae1539 --- /dev/null +++ b/erpnext/accounts/form_tour/sales_taxes_and_charges_template/sales_taxes_and_charges_template.json @@ -0,0 +1,65 @@ +{ + "creation": "2021-08-24 12:28:18.044902", + "docstatus": 0, + "doctype": "Form Tour", + "idx": 0, + "is_standard": 1, + "modified": "2021-08-24 12:28:18.044902", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Sales Taxes and Charges Template", + "owner": "Administrator", + "reference_doctype": "Sales Taxes and Charges Template", + "save_on_complete": 0, + "steps": [ + { + "description": "A name by which you will identify this template. You can change this later.", + "field": "", + "fieldname": "title", + "fieldtype": "Data", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Title", + "parent_field": "", + "position": "Bottom", + "title": "Title" + }, + { + "description": "Company for which this tax template will be applicable", + "field": "", + "fieldname": "company", + "fieldtype": "Link", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Company", + "parent_field": "", + "position": "Bottom", + "title": "Company" + }, + { + "description": "Set this template as the default for all sales transactions", + "field": "", + "fieldname": "is_default", + "fieldtype": "Check", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Default", + "parent_field": "", + "position": "Bottom", + "title": "Is this Default Tax Template?" + }, + { + "description": "You can add a row for a tax rule here. These rules can be applied on the net total, or can be a flat amount.", + "field": "", + "fieldname": "taxes", + "fieldtype": "Table", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Sales Taxes and Charges", + "parent_field": "", + "position": "Bottom", + "title": "Taxes Table" + } + ], + "title": "Sales Taxes and Charges Template" +} \ No newline at end of file diff --git a/erpnext/accounts/module_onboarding/accounts/accounts.json b/erpnext/accounts/module_onboarding/accounts/accounts.json index 6b5c5a1db8..2e0ab4305d 100644 --- a/erpnext/accounts/module_onboarding/accounts/accounts.json +++ b/erpnext/accounts/module_onboarding/accounts/accounts.json @@ -13,12 +13,15 @@ "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/accounts", "idx": 0, "is_complete": 0, - "modified": "2020-10-30 15:41:15.547225", + "modified": "2021-08-13 11:59:35.690443", "modified_by": "Administrator", "module": "Accounts", "name": "Accounts", "owner": "Administrator", "steps": [ + { + "step": "Company" + }, { "step": "Chart of Accounts" }, @@ -26,22 +29,19 @@ "step": "Setup Taxes" }, { - "step": "Create a Product" + "step": "Accounts Settings" }, { - "step": "Create a Supplier" + "step": "Cost Centers for Report and Budgeting" }, { "step": "Create Your First Purchase Invoice" }, { - "step": "Create a Customer" - }, - { - "step": "Create Your First Sales Invoice" + "step": "Updating Opening Balances" }, { - "step": "Configure Account Settings" + "step": "Financial Statements" } ], "subtitle": "Accounts, Invoices, Taxation, and more.", diff --git a/erpnext/accounts/onboarding_step/accounts_settings/accounts_settings.json b/erpnext/accounts/onboarding_step/accounts_settings/accounts_settings.json new file mode 100644 index 0000000000..3f44a73685 --- /dev/null +++ b/erpnext/accounts/onboarding_step/accounts_settings/accounts_settings.json @@ -0,0 +1,21 @@ +{ + "action": "Show Form Tour", + "action_label": "Take a quick walk-through of Accounts Settings", + "creation": "2021-06-29 16:42:03.400731", + "description": "# Account Settings\n\nIn ERPNext, Accounting features are configurable as per your business needs. Accounts Settings is the place to define some of your accounting preferences like:\n\n - Credit Limit and over billing settings\n - Taxation preferences\n - Deferred accounting preferences\n", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_single": 1, + "is_skipped": 0, + "modified": "2021-08-13 11:50:06.227835", + "modified_by": "Administrator", + "name": "Accounts Settings", + "owner": "Administrator", + "reference_document": "Accounts Settings", + "show_form_tour": 0, + "show_full_form": 0, + "title": "Accounts Settings", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json b/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json index fc49bd652b..67553baec7 100644 --- a/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json +++ b/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json @@ -1,10 +1,10 @@ { - "action": "Go to Page", - "action_label": "View Chart of Accounts", + "action": "Watch Video", + "action_label": "Learn more about Chart of Accounts", "callback_message": "You can continue with the onboarding after exploring this page", "callback_title": "Awesome Work", "creation": "2020-05-13 19:58:20.928127", - "description": "# Chart Of Accounts\n\nThe Chart of Accounts is the blueprint of the accounts in your organization.\nIt is a tree view of the names of the Accounts (Ledgers and Groups) that a Company requires to manage its books of accounts. ERPNext sets up a simple chart of accounts for each Company you create, but you can modify it according to your needs and legal requirements.\n\nFor each company, Chart of Accounts signifies the way to classify the accounting entries, mostly\nbased on statutory (tax, compliance to government regulations) requirements.\n\nThere's a brief video tutorial about chart of accounts in the next step.", + "description": "# Chart Of Accounts\n\nERPNext sets up a simple chart of accounts for each Company you create, but you can modify it according to business and legal requirements.", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, @@ -12,7 +12,7 @@ "is_complete": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-10-30 14:35:59.474920", + "modified": "2021-08-13 11:46:25.878506", "modified_by": "Administrator", "name": "Chart of Accounts", "owner": "Administrator", @@ -21,5 +21,6 @@ "show_form_tour": 0, "show_full_form": 0, "title": "Review Chart of Accounts", - "validate_action": 0 + "validate_action": 0, + "video_url": "https://www.youtube.com/embed/AcfMCT7wLLo" } \ No newline at end of file diff --git a/erpnext/accounts/onboarding_step/company/company.json b/erpnext/accounts/onboarding_step/company/company.json new file mode 100644 index 0000000000..4992e4d018 --- /dev/null +++ b/erpnext/accounts/onboarding_step/company/company.json @@ -0,0 +1,22 @@ +{ + "action": "Go to Page", + "action_label": "Let's Review your Company", + "creation": "2021-06-29 14:47:42.497318", + "description": "# Company\n\nIn ERPNext, you can also create multiple companies, and establish relationships (group/subsidiary) among them.\n\nWithin the company master, you can capture various default accounts for that Company and set crucial settings related to the accounting methodology followed for a company. \n", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2021-08-13 11:43:35.767341", + "modified_by": "Administrator", + "name": "Company", + "owner": "Administrator", + "path": "app/company", + "reference_document": "Company", + "show_form_tour": 0, + "show_full_form": 0, + "title": "Review Company", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/accounts/onboarding_step/cost_centers_for_report_and_budgeting/cost_centers_for_report_and_budgeting.json b/erpnext/accounts/onboarding_step/cost_centers_for_report_and_budgeting/cost_centers_for_report_and_budgeting.json new file mode 100644 index 0000000000..252b075697 --- /dev/null +++ b/erpnext/accounts/onboarding_step/cost_centers_for_report_and_budgeting/cost_centers_for_report_and_budgeting.json @@ -0,0 +1,21 @@ +{ + "action": "Go to Page", + "action_label": "View Cost Center Tree", + "creation": "2021-07-12 12:02:05.726608", + "description": "# Cost Centers for Budgeting and Analysis\n\nWhile your Books of Accounts are framed to fulfill statutory requirements, you can set up Cost Center and Accounting Dimensions to address your companies reporting and budgeting requirements.\n\nClick here to learn more about how [Cost Center](https://docs.erpnext.com/docs/v13/user/manual/en/accounts/cost-center) and [Dimensions](https://docs.erpnext.com/docs/v13/user/manual/en/accounts/accounting-dimensions) allow you to get advanced financial analytics reports from ERPNext.", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2021-08-13 11:55:08.510366", + "modified_by": "Administrator", + "name": "Cost Centers for Report and Budgeting", + "owner": "Administrator", + "path": "cost-center/view/tree", + "show_form_tour": 0, + "show_full_form": 0, + "title": "Cost Centers for Budgeting and Analysis", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json b/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json index ddbc89ec0a..f4e298e701 100644 --- a/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json +++ b/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json @@ -1,14 +1,15 @@ { - "action": "Create Entry", + "action": "Show Form Tour", + "action_label": "Let\u2019s create your first Purchase Invoice", "creation": "2020-05-14 22:10:07.049704", - "description": "# What's a Purchase Invoice?\n\nA Purchase Invoice is a bill you receive from your Suppliers against which you need to make the payment.\nPurchase Invoice is the exact opposite of your Sales Invoice. Here you accrue expenses to your Supplier. \n\nThe following is what a typical purchase cycle looks like, however you can create a purchase invoice directly as well.\n\n![Purchase Flow](https://docs.erpnext.com/docs/assets/img/accounts/pi-flow.png)\n\n", + "description": "# Create your first Purchase Invoice\n\nA Purchase Invoice is a bill received from a Supplier for a product(s) or service(s) delivery to your company. You can track payables through Purchase Invoice and process Payment Entries against it.\n\nPurchase Invoices can also be created against a Purchase Order or Purchase Receipt.", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, "is_complete": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-10-30 15:30:26.337773", + "modified": "2021-08-13 11:56:11.677253", "modified_by": "Administrator", "name": "Create Your First Purchase Invoice", "owner": "Administrator", diff --git a/erpnext/accounts/onboarding_step/financial_statements/financial_statements.json b/erpnext/accounts/onboarding_step/financial_statements/financial_statements.json new file mode 100644 index 0000000000..85cf9cdd7c --- /dev/null +++ b/erpnext/accounts/onboarding_step/financial_statements/financial_statements.json @@ -0,0 +1,23 @@ +{ + "action": "View Report", + "creation": "2021-07-12 12:08:47.026115", + "description": "# Financial Statements\n\nIn ERPNext, you can get crucial financial reports like [Balance Sheet] and [Profit and Loss] statements with a click of a button. You can run in the report for a different period and plot analytics charts premised on statement data. For more reports, check sections like Financial Statements, General Ledger, and Profitability reports.\n\n[Check Accounting reports](https://docs.erpnext.com/docs/v13/user/manual/en/accounts/accounting-reports)", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2021-08-13 11:59:18.767407", + "modified_by": "Administrator", + "name": "Financial Statements", + "owner": "Administrator", + "reference_report": "General Ledger", + "report_description": "General Ledger", + "report_reference_doctype": "GL Entry", + "report_type": "Script Report", + "show_form_tour": 0, + "show_full_form": 0, + "title": "Financial Statements", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json b/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json index a4922013da..9f4c873e34 100644 --- a/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json +++ b/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json @@ -1,21 +1,21 @@ { "action": "Create Entry", - "action_label": "Make a Sales Tax Template", + "action_label": "Manage Sales Tax Templates", "creation": "2020-05-13 19:29:43.844463", - "description": "# Setting up Taxes\n\nAny sophisticated accounting system, including ERPNext will have automatic tax calculations for your transactions. These calculations are based on user defined rules in compliance to local rules and regulations.\n\nERPNext allows this via *Tax Templates*. These templates can be used in Sales Orders and Sales Invoices. Other types of charges that may apply to your invoices (like shipping, insurance etc.) can also be configured as taxes.\n\nFor Tax Accounts that you want to use in the tax templates, go to:\n\n`> Accounting > Taxes > Sales Taxes and Charges Template`\n\nYou can read more about these templates in our documentation [here](https://docs.erpnext.com/docs/user/manual/en/selling/sales-taxes-and-charges-template)\n", + "description": "# Setting up Taxes\n\nERPNext lets you configure your taxes so that they are automatically applied in your buying and selling transactions. You can configure them globally or even on Items. ERPNext taxes are pre-configured for most regions.\n", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, "is_complete": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-10-30 14:54:18.087383", + "modified": "2021-08-13 11:48:37.238610", "modified_by": "Administrator", "name": "Setup Taxes", "owner": "Administrator", "reference_document": "Sales Taxes and Charges Template", "show_form_tour": 1, "show_full_form": 1, - "title": "Lets create a Tax Template for Sales ", + "title": "Setting up Taxes", "validate_action": 0 } \ No newline at end of file diff --git a/erpnext/accounts/onboarding_step/updating_opening_balances/updating_opening_balances.json b/erpnext/accounts/onboarding_step/updating_opening_balances/updating_opening_balances.json new file mode 100644 index 0000000000..c0849a4ef5 --- /dev/null +++ b/erpnext/accounts/onboarding_step/updating_opening_balances/updating_opening_balances.json @@ -0,0 +1,22 @@ +{ + "action": "Watch Video", + "action_label": "Learn how to update opening balances", + "creation": "2021-07-12 11:53:50.525030", + "description": "# Updating Opening Balances\n\nOnce you close the financial statement in previous accounting software, you can update the same as opening in your ERPNext's Balance Sheet accounts. This will allow you to get complete financial statements from ERPNext in the coming years, and discontinue the parallel accounting system right away.", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "intro_video_url": "https://www.youtube.com/embed/U5wPIvEn-0c", + "is_complete": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2021-08-13 11:56:45.483418", + "modified_by": "Administrator", + "name": "Updating Opening Balances", + "owner": "Administrator", + "show_form_tour": 0, + "show_full_form": 0, + "title": "Updating Opening Balances", + "validate_action": 1, + "video_url": "https://www.youtube.com/embed/U5wPIvEn-0c" +} \ No newline at end of file diff --git a/erpnext/assets/form_tour/asset/asset.json b/erpnext/assets/form_tour/asset/asset.json new file mode 100644 index 0000000000..7c47a38bd1 --- /dev/null +++ b/erpnext/assets/form_tour/asset/asset.json @@ -0,0 +1,125 @@ +{ + "creation": "2021-08-24 16:55:10.923434", + "docstatus": 0, + "doctype": "Form Tour", + "idx": 0, + "is_standard": 1, + "modified": "2021-08-24 16:55:10.923434", + "modified_by": "Administrator", + "module": "Assets", + "name": "Asset", + "owner": "Administrator", + "reference_doctype": "Asset", + "save_on_complete": 0, + "steps": [ + { + "description": "Select Naming Series based on which Asset ID will be generated", + "field": "", + "fieldname": "naming_series", + "fieldtype": "Select", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Naming Series", + "parent_field": "", + "position": "Bottom", + "title": "Naming Series" + }, + { + "description": "Select an Asset Item", + "field": "", + "fieldname": "item_code", + "fieldtype": "Link", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Item Code", + "parent_field": "", + "position": "Bottom", + "title": "Item Code" + }, + { + "description": "Select a Location", + "field": "", + "fieldname": "location", + "fieldtype": "Link", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Location", + "parent_field": "", + "position": "Bottom", + "title": "Location" + }, + { + "description": "Check Is Existing Asset", + "field": "", + "fieldname": "is_existing_asset", + "fieldtype": "Check", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Is Existing Asset", + "parent_field": "", + "position": "Bottom", + "title": "Is Existing Asset?" + }, + { + "description": "Set Available for use date", + "field": "", + "fieldname": "available_for_use_date", + "fieldtype": "Date", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Available-for-use Date", + "parent_field": "", + "position": "Bottom", + "title": "Available For Use Date" + }, + { + "description": "Set Gross purchase amount", + "field": "", + "fieldname": "gross_purchase_amount", + "fieldtype": "Currency", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Gross Purchase Amount", + "parent_field": "", + "position": "Bottom", + "title": "Gross Purchase Amount" + }, + { + "description": "Set Purchase Date", + "field": "", + "fieldname": "purchase_date", + "fieldtype": "Date", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Purchase Date", + "parent_field": "", + "position": "Bottom", + "title": "Purchase Date" + }, + { + "description": "Check Calculate Depreciation", + "field": "", + "fieldname": "calculate_depreciation", + "fieldtype": "Check", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Calculate Depreciation", + "parent_field": "", + "position": "Bottom", + "title": "Calculate Depreciation" + }, + { + "description": "Enter depreciation which has already been booked for this asset", + "field": "", + "fieldname": "opening_accumulated_depreciation", + "fieldtype": "Currency", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Opening Accumulated Depreciation", + "parent_field": "", + "position": "Bottom", + "title": "Accumulated Depreciation" + } + ], + "title": "Asset" +} \ No newline at end of file diff --git a/erpnext/assets/form_tour/asset_category/asset_category.json b/erpnext/assets/form_tour/asset_category/asset_category.json new file mode 100644 index 0000000000..02834447a5 --- /dev/null +++ b/erpnext/assets/form_tour/asset_category/asset_category.json @@ -0,0 +1,65 @@ +{ + "creation": "2021-08-24 12:48:20.763173", + "docstatus": 0, + "doctype": "Form Tour", + "idx": 0, + "is_standard": 1, + "modified": "2021-08-24 12:48:20.763173", + "modified_by": "Administrator", + "module": "Assets", + "name": "Asset Category", + "owner": "Administrator", + "reference_doctype": "Asset Category", + "save_on_complete": 0, + "steps": [ + { + "description": "Name Asset category. You can create categories based on Asset Types like Furniture, Property, Electronics etc.", + "field": "", + "fieldname": "asset_category_name", + "fieldtype": "Data", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Asset Category Name", + "parent_field": "", + "position": "Bottom", + "title": "Asset Category Name" + }, + { + "description": "Check to enable Capital Work in Progress accounting", + "field": "", + "fieldname": "enable_cwip_accounting", + "fieldtype": "Check", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Enable Capital Work in Progress Accounting", + "parent_field": "", + "position": "Bottom", + "title": "Enable CWIP Accounting" + }, + { + "description": "Add a row to define Depreciation Method and other details. Note that you can leave Finance Book blank to have it's accounting done in the primary books of accounts.", + "field": "", + "fieldname": "finance_books", + "fieldtype": "Table", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Finance Books", + "parent_field": "", + "position": "Bottom", + "title": "Finance Book Detail" + }, + { + "description": "Select the Fixed Asset and Depreciation accounts applicable for this Asset Category type", + "field": "", + "fieldname": "accounts", + "fieldtype": "Table", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Accounts", + "parent_field": "", + "position": "Bottom", + "title": "Accounts" + } + ], + "title": "Asset Category" +} \ No newline at end of file diff --git a/erpnext/assets/module_onboarding/assets/assets.json b/erpnext/assets/module_onboarding/assets/assets.json index 1086ab4bcd..e6df88b000 100644 --- a/erpnext/assets/module_onboarding/assets/assets.json +++ b/erpnext/assets/module_onboarding/assets/assets.json @@ -13,26 +13,26 @@ "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/asset", "idx": 0, "is_complete": 0, - "modified": "2020-07-08 14:05:51.828497", + "modified": "2021-08-24 17:50:41.573281", "modified_by": "Administrator", "module": "Assets", "name": "Assets", "owner": "Administrator", "steps": [ { - "step": "Introduction to Assets" + "step": "Fixed Asset Accounts" }, { - "step": "Create a Fixed Asset Item" + "step": "Asset Category" }, { - "step": "Create an Asset Category" + "step": "Asset Item" }, { - "step": "Purchase an Asset Item" + "step": "Asset Purchase" }, { - "step": "Create an Asset" + "step": "Existing Asset" } ], "subtitle": "Assets, Depreciations, Repairs, and more.", diff --git a/erpnext/assets/onboarding_step/asset_category/asset_category.json b/erpnext/assets/onboarding_step/asset_category/asset_category.json new file mode 100644 index 0000000000..033e86669c --- /dev/null +++ b/erpnext/assets/onboarding_step/asset_category/asset_category.json @@ -0,0 +1,21 @@ +{ + "action": "Show Form Tour", + "action_label": "Let's review existing Asset Category", + "creation": "2021-08-13 14:26:18.656303", + "description": "# Asset Category\n\nAn Asset Category classifies different assets of a Company.\n\nYou can create an Asset Category based on the type of assets. For example, all your desktops and laptops can be part of an Asset Category named \"Electronic Equipments\". Create a separate category for furniture. Also, you can update default properties for each category, like:\n - Depreciation type and duration\n - Fixed asset account\n - Depreciation account\n", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2021-08-24 12:49:37.665239", + "modified_by": "Administrator", + "name": "Asset Category", + "owner": "Administrator", + "reference_document": "Asset Category", + "show_form_tour": 0, + "show_full_form": 0, + "title": "Define Asset Category", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/assets/onboarding_step/asset_item/asset_item.json b/erpnext/assets/onboarding_step/asset_item/asset_item.json new file mode 100644 index 0000000000..8a174c5b77 --- /dev/null +++ b/erpnext/assets/onboarding_step/asset_item/asset_item.json @@ -0,0 +1,21 @@ +{ + "action": "Show Form Tour", + "action_label": "Let's create a new Asset item", + "creation": "2021-08-13 14:27:07.277167", + "description": "# Asset Item\n\nAsset items are created based on Asset Category. You can create one or multiple items against once Asset Category. The sales and purchase transaction for Asset is done via Asset Item. ", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2021-08-16 13:59:18.362233", + "modified_by": "Administrator", + "name": "Asset Item", + "owner": "Administrator", + "reference_document": "Item", + "show_form_tour": 0, + "show_full_form": 0, + "title": "Create an Asset Item", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/assets/onboarding_step/asset_purchase/asset_purchase.json b/erpnext/assets/onboarding_step/asset_purchase/asset_purchase.json new file mode 100644 index 0000000000..54611edc29 --- /dev/null +++ b/erpnext/assets/onboarding_step/asset_purchase/asset_purchase.json @@ -0,0 +1,21 @@ +{ + "action": "Show Form Tour", + "action_label": "Let's create a Purchase Receipt", + "creation": "2021-08-13 14:27:53.678621", + "description": "# Purchase an Asset\n\nAssets purchases process if done following the standard Purchase cycle. If capital work in progress is enabled in Asset Category, Asset will be created as soon as Purchase Receipt is created for it. You can quickly create a Purchase Receipt for Asset and see its impact on books of accounts.", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2021-08-24 17:26:57.180637", + "modified_by": "Administrator", + "name": "Asset Purchase", + "owner": "Administrator", + "reference_document": "Purchase Receipt", + "show_form_tour": 0, + "show_full_form": 0, + "title": "Purchase an Asset", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/assets/onboarding_step/existing_asset/existing_asset.json b/erpnext/assets/onboarding_step/existing_asset/existing_asset.json new file mode 100644 index 0000000000..052d5e8d77 --- /dev/null +++ b/erpnext/assets/onboarding_step/existing_asset/existing_asset.json @@ -0,0 +1,21 @@ +{ + "action": "Show Form Tour", + "action_label": "Add an existing Asset", + "creation": "2021-08-13 14:28:30.650459", + "description": "# Add an Existing Asset\n\nIf you are just starting with ERPNext, you will need to enter Assets you already possess. You can add them as existing fixed assets in ERPNext. Please note that you will have to make a Journal Entry separately updating the opening balance in the fixed asset account.", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2021-08-16 14:03:48.850471", + "modified_by": "Administrator", + "name": "Existing Asset", + "owner": "Administrator", + "reference_document": "Asset", + "show_form_tour": 0, + "show_full_form": 0, + "title": "Add an Existing Asset", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/assets/onboarding_step/fixed_asset_accounts/fixed_asset_accounts.json b/erpnext/assets/onboarding_step/fixed_asset_accounts/fixed_asset_accounts.json new file mode 100644 index 0000000000..cebee7a7ea --- /dev/null +++ b/erpnext/assets/onboarding_step/fixed_asset_accounts/fixed_asset_accounts.json @@ -0,0 +1,21 @@ +{ + "action": "Go to Page", + "action_label": "Let's walk-through Chart of Accounts to review setup", + "creation": "2021-08-13 14:23:09.297765", + "description": "# Fixed Asset Accounts\n\nWith the company, a host of fixed asset accounts are pre-configured. To ensure your asset transactions are leading to correct accounting entries, you can review and set up following asset accounts as per your business requirements.\n - Fixed asset accounts (Asset account)\n - Accumulated depreciation\n - Capital Work in progress (CWIP) account\n - Asset Depreciation account (Expense account)", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2021-08-24 17:46:37.646174", + "modified_by": "Administrator", + "name": "Fixed Asset Accounts", + "owner": "Administrator", + "path": "app/account/view/tree", + "show_form_tour": 0, + "show_full_form": 0, + "title": "Review Fixed Asset Accounts", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.js b/erpnext/selling/doctype/selling_settings/selling_settings.js index d8d30515f8..cf6fb2806e 100644 --- a/erpnext/selling/doctype/selling_settings/selling_settings.js +++ b/erpnext/selling/doctype/selling_settings/selling_settings.js @@ -6,26 +6,3 @@ frappe.ui.form.on('Selling Settings', { } }); - -frappe.tour['Selling Settings'] = [ - { - fieldname: "cust_master_name", - title: "Customer Naming By", - description: __("By default, the Customer Name is set as per the Full Name entered. If you want Customers to be named by a ") + "Naming Series" + __(" choose the 'Naming Series' option."), - }, - { - fieldname: "selling_price_list", - title: "Default Selling Price List", - description: __("Configure the default Price List when creating a new Sales transaction. Item prices will be fetched from this Price List.") - }, - { - fieldname: "so_required", - title: "Sales Order Required for Sales Invoice & Delivery Note Creation", - description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Sales Invoice or Delivery Note without creating a Sales Order first. This configuration can be overridden for a particular Customer by enabling the 'Allow Sales Invoice Creation Without Sales Order' checkbox in the Customer master.") - }, - { - fieldname: "dn_required", - title: "Delivery Note Required for Sales Invoice Creation", - description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Sales Invoice without creating a Delivery Note first. This configuration can be overridden for a particular Customer by enabling the 'Allow Sales Invoice Creation Without Delivery Note' checkbox in the Customer master.") - } -]; diff --git a/erpnext/selling/form_tour/sales_order/sales_order.json b/erpnext/selling/form_tour/sales_order/sales_order.json new file mode 100644 index 0000000000..a81eb4a043 --- /dev/null +++ b/erpnext/selling/form_tour/sales_order/sales_order.json @@ -0,0 +1,97 @@ +{ + "creation": "2021-06-29 21:13:36.089054", + "docstatus": 0, + "doctype": "Form Tour", + "idx": 0, + "is_standard": 1, + "modified": "2021-06-29 21:13:36.089054", + "modified_by": "Administrator", + "module": "Selling", + "name": "Sales Order", + "owner": "Administrator", + "reference_doctype": "Sales Order", + "save_on_complete": 1, + "steps": [ + { + "description": "Select a customer.", + "field": "", + "fieldname": "customer", + "fieldtype": "Link", + "has_next_condition": 1, + "is_table_field": 0, + "label": "Customer", + "next_step_condition": "customer", + "parent_field": "", + "position": "Right", + "title": "Select Customer" + }, + { + "description": "You can add items here.", + "field": "", + "fieldname": "items", + "fieldtype": "Table", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Items", + "parent_field": "", + "position": "Bottom", + "title": "List of items" + }, + { + "child_doctype": "Sales Order Item", + "description": "Select an item.", + "field": "", + "fieldname": "item_code", + "fieldtype": "Link", + "has_next_condition": 1, + "is_table_field": 1, + "label": "Item Code", + "next_step_condition": "eval: doc.item_code", + "parent_field": "", + "parent_fieldname": "items", + "position": "Right", + "title": "Select Item" + }, + { + "child_doctype": "Sales Order Item", + "description": "Enter quantity.", + "field": "", + "fieldname": "qty", + "fieldtype": "Float", + "has_next_condition": 0, + "is_table_field": 1, + "label": "Quantity", + "parent_field": "", + "parent_fieldname": "items", + "position": "Right", + "title": "Enter Quantity" + }, + { + "child_doctype": "Sales Order Item", + "description": "Enter rate of the item.", + "field": "", + "fieldname": "rate", + "fieldtype": "Currency", + "has_next_condition": 0, + "is_table_field": 1, + "label": "Rate", + "parent_field": "", + "parent_fieldname": "items", + "position": "Right", + "title": "Enter Rate" + }, + { + "description": "You can add sales taxes and charges here.", + "field": "", + "fieldname": "taxes", + "fieldtype": "Table", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Sales Taxes and Charges", + "parent_field": "", + "position": "Bottom", + "title": "Add Sales Taxes and Charges" + } + ], + "title": "Sales Order" +} \ No newline at end of file diff --git a/erpnext/selling/form_tour/selling_settings/selling_settings.json b/erpnext/selling/form_tour/selling_settings/selling_settings.json new file mode 100644 index 0000000000..20c718f8c0 --- /dev/null +++ b/erpnext/selling/form_tour/selling_settings/selling_settings.json @@ -0,0 +1,65 @@ +{ + "creation": "2021-06-29 20:39:19.408763", + "docstatus": 0, + "doctype": "Form Tour", + "idx": 0, + "is_standard": 1, + "modified": "2021-06-29 20:49:01.359489", + "modified_by": "Administrator", + "module": "Selling", + "name": "Selling Settings", + "owner": "Administrator", + "reference_doctype": "Selling Settings", + "save_on_complete": 0, + "steps": [ + { + "description": "By default, the Customer Name is set as per the Full Name entered. If you want Customers to be named by a Naming Series. Choose the 'Naming Series' option.", + "field": "", + "fieldname": "cust_master_name", + "fieldtype": "Select", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Customer Naming By", + "parent_field": "", + "position": "Right", + "title": "Customer Naming By" + }, + { + "description": "If this option is configured 'Yes', ERPNext will prevent you from creating a Sales Invoice or Delivery Note without creating a Sales Order first. This configuration can be overridden for a particular Customer by enabling the 'Allow Sales Invoice Creation Without Sales Order' checkbox in the Customer master.", + "field": "", + "fieldname": "so_required", + "fieldtype": "Select", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Is Sales Order Required for Sales Invoice & Delivery Note Creation?", + "parent_field": "", + "position": "Left", + "title": "Sales Order Required for Sales Invoice & Delivery Note Creation" + }, + { + "description": "If this option is configured 'Yes', ERPNext will prevent you from creating a Sales Invoice without creating a Delivery Note first. This configuration can be overridden for a particular Customer by enabling the 'Allow Sales Invoice Creation Without Delivery Note' checkbox in the Customer master.", + "field": "", + "fieldname": "dn_required", + "fieldtype": "Select", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Is Delivery Note Required for Sales Invoice Creation?", + "parent_field": "", + "position": "Left", + "title": "Delivery Note Required for Sales Invoice Creation" + }, + { + "description": "Configure the default Price List when creating a new Sales transaction. Item prices will be fetched from this Price List.", + "field": "", + "fieldname": "selling_price_list", + "fieldtype": "Link", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Default Price List", + "parent_field": "", + "position": "Right", + "title": "Default Selling Price List" + } + ], + "title": "Selling Settings" +} \ No newline at end of file diff --git a/erpnext/selling/module_onboarding/selling/selling.json b/erpnext/selling/module_onboarding/selling/selling.json index 160208ff68..c02f444b05 100644 --- a/erpnext/selling/module_onboarding/selling/selling.json +++ b/erpnext/selling/module_onboarding/selling/selling.json @@ -19,32 +19,17 @@ "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/selling", "idx": 0, "is_complete": 0, - "modified": "2020-07-08 14:05:37.669753", + "modified": "2021-08-24 18:12:38.052434", "modified_by": "Administrator", "module": "Selling", "name": "Selling", "owner": "Administrator", "steps": [ { - "step": "Introduction to Selling" - }, - { - "step": "Create a Customer" - }, - { - "step": "Setup your Warehouse" - }, - { - "step": "Create a Product" - }, - { - "step": "Create a Quotation" - }, - { - "step": "Create your first Sales Order" + "step": "Selling Settings" }, { - "step": "Selling Settings" + "step": "Sales Order" } ], "subtitle": "Products, Sales, Analysis, and more.", diff --git a/erpnext/selling/onboarding_step/create_a_customer/create_a_customer.json b/erpnext/selling/onboarding_step/create_a_customer/create_a_customer.json index 5a403b06cf..64defbfe3d 100644 --- a/erpnext/selling/onboarding_step/create_a_customer/create_a_customer.json +++ b/erpnext/selling/onboarding_step/create_a_customer/create_a_customer.json @@ -5,7 +5,6 @@ "doctype": "Onboarding Step", "idx": 0, "is_complete": 0, - "is_mandatory": 0, "is_single": 0, "is_skipped": 0, "modified": "2020-06-01 13:16:19.731719", @@ -13,6 +12,7 @@ "name": "Create a Customer", "owner": "Administrator", "reference_document": "Customer", + "show_form_tour": 0, "show_full_form": 0, "title": "Create a Customer", "validate_action": 1 diff --git a/erpnext/selling/onboarding_step/create_a_product/create_a_product.json b/erpnext/selling/onboarding_step/create_a_product/create_a_product.json index d2068e167b..52a5861551 100644 --- a/erpnext/selling/onboarding_step/create_a_product/create_a_product.json +++ b/erpnext/selling/onboarding_step/create_a_product/create_a_product.json @@ -5,14 +5,14 @@ "doctype": "Onboarding Step", "idx": 0, "is_complete": 0, - "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-05-12 18:30:02.489949", + "modified": "2020-10-14 14:53:00.133574", "modified_by": "Administrator", "name": "Create a Product", "owner": "Administrator", "reference_document": "Item", + "show_form_tour": 0, "show_full_form": 0, "title": "Create a Product", "validate_action": 1 diff --git a/erpnext/selling/onboarding_step/create_a_quotation/create_a_quotation.json b/erpnext/selling/onboarding_step/create_a_quotation/create_a_quotation.json index 27253d15b6..6f1837e24c 100644 --- a/erpnext/selling/onboarding_step/create_a_quotation/create_a_quotation.json +++ b/erpnext/selling/onboarding_step/create_a_quotation/create_a_quotation.json @@ -5,7 +5,6 @@ "doctype": "Onboarding Step", "idx": 0, "is_complete": 0, - "is_mandatory": 0, "is_single": 0, "is_skipped": 0, "modified": "2020-06-01 13:34:58.958641", @@ -13,6 +12,7 @@ "name": "Create a Quotation", "owner": "Administrator", "reference_document": "Quotation", + "show_form_tour": 0, "show_full_form": 1, "title": "Create a Quotation", "validate_action": 1 diff --git a/erpnext/selling/onboarding_step/create_a_sales_order/create_a_sales_order.json b/erpnext/selling/onboarding_step/create_a_sales_order/create_a_sales_order.json new file mode 100644 index 0000000000..378f295f0c --- /dev/null +++ b/erpnext/selling/onboarding_step/create_a_sales_order/create_a_sales_order.json @@ -0,0 +1,21 @@ +{ + "action": "Create Entry", + "action_label": "Create Sales Order", + "creation": "2021-06-29 21:22:54.204880", + "description": "A Sales Order is a confirmation of an order from your customer. It is also referred to as Proforma Invoice.\n\nSales Order at the heart of your sales and purchase transactions. Sales Orders are linked in Delivery Note, Sales Invoices, Material Request, and Maintenance transactions. Through Sales Order, you can track fulfillment of the overall deal towards the customer.", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2021-06-29 21:22:54.204880", + "modified_by": "Administrator", + "name": "Create a Sales Order", + "owner": "Administrator", + "reference_document": "Sales Order", + "show_form_tour": 1, + "show_full_form": 1, + "title": "Create a Sales Order", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/selling/onboarding_step/introduction_to_selling/introduction_to_selling.json b/erpnext/selling/onboarding_step/introduction_to_selling/introduction_to_selling.json index d21c1f4954..636453363b 100644 --- a/erpnext/selling/onboarding_step/introduction_to_selling/introduction_to_selling.json +++ b/erpnext/selling/onboarding_step/introduction_to_selling/introduction_to_selling.json @@ -5,13 +5,13 @@ "doctype": "Onboarding Step", "idx": 0, "is_complete": 0, - "is_mandatory": 0, "is_single": 0, "is_skipped": 0, "modified": "2020-06-01 13:29:13.703177", "modified_by": "Administrator", "name": "Introduction to Selling", "owner": "Administrator", + "show_form_tour": 0, "show_full_form": 0, "title": "Introduction to Selling", "validate_action": 1, diff --git a/erpnext/selling/onboarding_step/sales_order/sales_order.json b/erpnext/selling/onboarding_step/sales_order/sales_order.json new file mode 100644 index 0000000000..d616fae066 --- /dev/null +++ b/erpnext/selling/onboarding_step/sales_order/sales_order.json @@ -0,0 +1,21 @@ +{ + "action": "Show Form Tour", + "action_label": "Let\u2019s convert your first Sales Order against a Quotation", + "creation": "2021-08-13 14:03:49.217866", + "description": "# Sales Order\n\nA Sales Order is a confirmation of an order from your customer. It is also referred to as Proforma Invoice.\n\nSales Order at the heart of your sales and purchase transactions. Sales Orders are linked in Delivery Note, Sales Invoices, Material Request, and Maintenance transactions. Through Sales Order, you can track fulfillment of the overall deal towards the customer.", + "docstatus": 0, + "doctype": "Onboarding Step", + "idx": 0, + "is_complete": 0, + "is_single": 0, + "is_skipped": 0, + "modified": "2021-08-24 18:12:32.394992", + "modified_by": "Administrator", + "name": "Sales Order", + "owner": "Administrator", + "reference_document": "Sales Order", + "show_form_tour": 0, + "show_full_form": 0, + "title": "Sales Order", + "validate_action": 1 +} \ No newline at end of file diff --git a/erpnext/selling/onboarding_step/selling_settings/selling_settings.json b/erpnext/selling/onboarding_step/selling_settings/selling_settings.json index 7996d7b159..ec30fd3033 100644 --- a/erpnext/selling/onboarding_step/selling_settings/selling_settings.json +++ b/erpnext/selling/onboarding_step/selling_settings/selling_settings.json @@ -1,19 +1,21 @@ { "action": "Show Form Tour", + "action_label": "Let\u2019s walk-through Selling Settings", "creation": "2020-06-01 13:01:45.615189", + "description": "# Selling Settings\n\nCRM and Selling module\u2019s features are configurable as per your business needs. Selling Settings is the place where you can set your preferences for:\n - Customer naming and default values\n - Billing and shipping preference in sales transactions\n", "docstatus": 0, "doctype": "Onboarding Step", "idx": 0, "is_complete": 0, - "is_mandatory": 0, "is_single": 1, "is_skipped": 0, - "modified": "2020-06-01 13:04:14.980743", + "modified": "2021-08-24 18:11:21.264335", "modified_by": "Administrator", "name": "Selling Settings", "owner": "Administrator", "reference_document": "Selling Settings", + "show_form_tour": 0, "show_full_form": 0, - "title": "Configure Selling Settings.", + "title": "Selling Settings", "validate_action": 0 } \ No newline at end of file diff --git a/erpnext/selling/onboarding_step/setup_your_warehouse/setup_your_warehouse.json b/erpnext/selling/onboarding_step/setup_your_warehouse/setup_your_warehouse.json index 9457deee26..1e20eb0eba 100644 --- a/erpnext/selling/onboarding_step/setup_your_warehouse/setup_your_warehouse.json +++ b/erpnext/selling/onboarding_step/setup_your_warehouse/setup_your_warehouse.json @@ -5,15 +5,15 @@ "doctype": "Onboarding Step", "idx": 0, "is_complete": 0, - "is_mandatory": 0, "is_single": 0, "is_skipped": 0, - "modified": "2020-07-04 12:33:16.970031", + "modified": "2020-10-14 14:53:25.538900", "modified_by": "Administrator", "name": "Setup your Warehouse", "owner": "Administrator", "path": "Tree/Warehouse", "reference_document": "Warehouse", + "show_form_tour": 0, "show_full_form": 0, "title": "Set up your Warehouse", "validate_action": 1 diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json index e4ee3ecea7..58cb52c04d 100644 --- a/erpnext/setup/doctype/company/company.json +++ b/erpnext/setup/doctype/company/company.json @@ -715,6 +715,15 @@ "label": "Default Payment Discount Account", "options": "Account" }, + { + "fieldname": "hr_settings_section", + "fieldtype": "Section Break", + "label": "HR & Payroll Settings" + }, + { + "fieldname": "column_break_26", + "fieldtype": "Column Break" + }, { "collapsible": 1, "fieldname": "fixed_asset_defaults", @@ -731,15 +740,6 @@ "fieldname": "section_break_28", "fieldtype": "Section Break", "label": "Chart of Accounts" - }, - { - "fieldname": "hr_settings_section", - "fieldtype": "Section Break", - "label": "HR & Payroll Settings" - }, - { - "fieldname": "column_break_26", - "fieldtype": "Column Break" } ], "icon": "fa fa-building", @@ -808,4 +808,4 @@ "sort_field": "modified", "sort_order": "ASC", "track_changes": 1 -} \ No newline at end of file +} diff --git a/erpnext/stock/form_tour/item/item.json b/erpnext/stock/form_tour/item/item.json new file mode 100644 index 0000000000..821e91b28d --- /dev/null +++ b/erpnext/stock/form_tour/item/item.json @@ -0,0 +1,89 @@ +{ + "creation": "2021-08-24 17:56:40.754909", + "docstatus": 0, + "doctype": "Form Tour", + "idx": 0, + "is_standard": 1, + "modified": "2021-08-24 18:04:50.928431", + "modified_by": "Administrator", + "module": "Stock", + "name": "Item", + "owner": "Administrator", + "reference_doctype": "Item", + "save_on_complete": 0, + "steps": [ + { + "description": "Enter code for Asset Item", + "field": "", + "fieldname": "item_code", + "fieldtype": "Data", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Item Code", + "parent_field": "", + "position": "Bottom", + "title": "Asset Item Code" + }, + { + "description": "Enter name for Asset Item", + "field": "", + "fieldname": "item_name", + "fieldtype": "Data", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Item Name", + "parent_field": "", + "position": "Bottom", + "title": "Asset Item Name" + }, + { + "description": "Check this field to make this an Asset Item", + "field": "", + "fieldname": "is_fixed_asset", + "fieldtype": "Check", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Is Fixed Asset", + "parent_field": "", + "position": "Bottom", + "title": "Is this a Fixed Asset?" + }, + { + "description": "On checking it, the system will create an Asset automatically on purchase", + "field": "", + "fieldname": "auto_create_assets", + "fieldtype": "Check", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Auto Create Assets on Purchase", + "parent_field": "", + "position": "Bottom", + "title": "Auto Create Asset on Purchase" + }, + { + "description": "Select an Asset Category for this Asset Item", + "field": "", + "fieldname": "asset_category", + "fieldtype": "Link", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Asset Category", + "parent_field": "", + "position": "Bottom", + "title": "Asset Category" + }, + { + "description": "Select a naming series which will be used to create an Asset automatically", + "field": "", + "fieldname": "asset_naming_series", + "fieldtype": "Select", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Asset Naming Series", + "parent_field": "", + "position": "Bottom", + "title": "Asset Naming Series" + } + ], + "title": "Item" +} diff --git a/erpnext/stock/form_tour/purchase_receipt/purchase_receipt.json b/erpnext/stock/form_tour/purchase_receipt/purchase_receipt.json new file mode 100644 index 0000000000..6fba3f4d68 --- /dev/null +++ b/erpnext/stock/form_tour/purchase_receipt/purchase_receipt.json @@ -0,0 +1,41 @@ +{ + "creation": "2021-08-24 13:03:21.333088", + "docstatus": 0, + "doctype": "Form Tour", + "idx": 0, + "is_standard": 1, + "modified": "2021-08-24 13:03:21.333088", + "modified_by": "Administrator", + "module": "Stock", + "name": "Purchase Receipt", + "owner": "Administrator", + "reference_doctype": "Purchase Receipt", + "save_on_complete": 0, + "steps": [ + { + "description": "Select Asset Supplier", + "field": "", + "fieldname": "supplier", + "fieldtype": "Link", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Supplier", + "parent_field": "", + "position": "Bottom", + "title": "Supplier" + }, + { + "description": "Select an Asset Item, Enter rate and quantity", + "field": "", + "fieldname": "items", + "fieldtype": "Table", + "has_next_condition": 0, + "is_table_field": 0, + "label": "Items", + "parent_field": "", + "position": "Bottom", + "title": "Items" + } + ], + "title": "Purchase Receipt" +} \ No newline at end of file From e170ad2df362f2b7fe086e5f0062896c3371fda3 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 27 Aug 2021 16:26:12 +0530 Subject: [PATCH 13/20] chore: add more fields to Prospect list view --- erpnext/crm/doctype/prospect/prospect.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/erpnext/crm/doctype/prospect/prospect.json b/erpnext/crm/doctype/prospect/prospect.json index 237c4255c7..3d6fba5123 100644 --- a/erpnext/crm/doctype/prospect/prospect.json +++ b/erpnext/crm/doctype/prospect/prospect.json @@ -39,6 +39,8 @@ { "fieldname": "industry", "fieldtype": "Link", + "in_list_view": 1, + "in_standard_filter": 1, "label": "Industry", "options": "Industry Type" }, @@ -57,6 +59,8 @@ { "fieldname": "territory", "fieldtype": "Link", + "in_list_view": 1, + "in_standard_filter": 1, "label": "Territory", "options": "Territory" }, @@ -72,12 +76,14 @@ { "fieldname": "currency", "fieldtype": "Link", + "in_list_view": 1, "label": "Currency", "options": "Currency" }, { "fieldname": "annual_revenue", "fieldtype": "Currency", + "in_list_view": 1, "label": "Annual Revenue", "options": "currency" }, @@ -151,7 +157,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2021-08-26 12:10:49.191839", + "modified": "2021-08-27 16:24:42.961967", "modified_by": "Administrator", "module": "CRM", "name": "Prospect", From 17e0fa7a8b8c7d6471a13dc50b4556d82d6c8592 Mon Sep 17 00:00:00 2001 From: Shadrak Gurupnor <30501401+shadrak98@users.noreply.github.com> Date: Fri, 27 Aug 2021 16:42:25 +0530 Subject: [PATCH 14/20] fix: patches were breaking while migrating (#27195) * fix: patches were breaking while migrating * fix: Removed duplicate function Co-authored-by: Nabin Hait --- erpnext/patches.txt | 2 +- .../patches/v13_0/check_is_income_tax_component.py | 4 ++-- erpnext/patches/v13_0/delete_old_purchase_reports.py | 11 +++++++++++ erpnext/patches/v13_0/delete_old_sales_reports.py | 2 ++ erpnext/patches/v13_0/rename_issue_doctype_fields.py | 3 +++ erpnext/patches/v13_0/update_returned_qty_in_pr_dn.py | 1 + 6 files changed, 20 insertions(+), 3 deletions(-) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 0f6a606cb1..ade19ff1d5 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -214,6 +214,7 @@ erpnext.patches.v13_0.delete_old_sales_reports execute:frappe.delete_doc_if_exists("DocType", "Bank Reconciliation") erpnext.patches.v13_0.move_doctype_reports_and_notification_from_hr_to_payroll #22-06-2020 erpnext.patches.v13_0.move_payroll_setting_separately_from_hr_settings #22-06-2020 +erpnext.patches.v12_0.create_itc_reversal_custom_fields erpnext.patches.v13_0.check_is_income_tax_component #22-06-2020 erpnext.patches.v13_0.loyalty_points_entry_for_pos_invoice #22-07-2020 erpnext.patches.v12_0.add_taxjar_integration_field @@ -266,7 +267,6 @@ erpnext.patches.v13_0.rename_discharge_date_in_ip_record erpnext.patches.v12_0.create_taxable_value_field erpnext.patches.v12_0.add_gst_category_in_delivery_note erpnext.patches.v12_0.purchase_receipt_status -erpnext.patches.v12_0.create_itc_reversal_custom_fields erpnext.patches.v13_0.fix_non_unique_represents_company erpnext.patches.v12_0.add_document_type_field_for_italy_einvoicing erpnext.patches.v13_0.make_non_standard_user_type #13-04-2021 diff --git a/erpnext/patches/v13_0/check_is_income_tax_component.py b/erpnext/patches/v13_0/check_is_income_tax_component.py index ebae3ad715..7a52dc88d2 100644 --- a/erpnext/patches/v13_0/check_is_income_tax_component.py +++ b/erpnext/patches/v13_0/check_is_income_tax_component.py @@ -19,10 +19,10 @@ def execute(): ] for doctype in doctypes: - frappe.reload_doc('Payroll', 'doctype', doctype) + frappe.reload_doc('Payroll', 'doctype', doctype, force=True) - reports = ['Professional Tax Deductions', 'Provident Fund Deductions'] + reports = ['Professional Tax Deductions', 'Provident Fund Deductions', 'E-Invoice Summary'] for report in reports: frappe.reload_doc('Regional', 'Report', report) frappe.reload_doc('Regional', 'Report', report) diff --git a/erpnext/patches/v13_0/delete_old_purchase_reports.py b/erpnext/patches/v13_0/delete_old_purchase_reports.py index c17aad06c7..360a82e5c0 100644 --- a/erpnext/patches/v13_0/delete_old_purchase_reports.py +++ b/erpnext/patches/v13_0/delete_old_purchase_reports.py @@ -13,6 +13,7 @@ def execute(): for report in reports_to_delete: if frappe.db.exists("Report", report): delete_auto_email_reports(report) + check_linked_reports(report) frappe.delete_doc("Report", report) @@ -21,3 +22,13 @@ def delete_auto_email_reports(report): auto_email_reports = frappe.db.get_values("Auto Email Report", {"report": report}, ["name"]) for auto_email_report in auto_email_reports: frappe.delete_doc("Auto Email Report", auto_email_report[0]) + +def check_linked_reports(report): + """ Check if reports are referenced in Desktop Icon """ + icons = frappe.get_all("Desktop Icon", + fields = ['name'], + filters = { + "_report": report + }) + if icons: + frappe.delete_doc("Desktop Icon", icons) \ No newline at end of file diff --git a/erpnext/patches/v13_0/delete_old_sales_reports.py b/erpnext/patches/v13_0/delete_old_sales_reports.py index 671c012c8a..69493e2c00 100644 --- a/erpnext/patches/v13_0/delete_old_sales_reports.py +++ b/erpnext/patches/v13_0/delete_old_sales_reports.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals import frappe +from erpnext.patches.v13_0.delete_old_purchase_reports import check_linked_reports def execute(): reports_to_delete = ["Ordered Items To Be Delivered", "Ordered Items To Be Billed"] @@ -11,6 +12,7 @@ def execute(): for report in reports_to_delete: if frappe.db.exists("Report", report): delete_auto_email_reports(report) + check_linked_reports(report) frappe.delete_doc("Report", report) diff --git a/erpnext/patches/v13_0/rename_issue_doctype_fields.py b/erpnext/patches/v13_0/rename_issue_doctype_fields.py index 41c51c36dc..4885c0b7af 100644 --- a/erpnext/patches/v13_0/rename_issue_doctype_fields.py +++ b/erpnext/patches/v13_0/rename_issue_doctype_fields.py @@ -41,6 +41,7 @@ def execute(): rename_field('Opportunity', 'mins_to_first_response', 'first_response_time') # change fieldtype to duration + frappe.reload_doc('crm', 'doctype', 'opportunity', force=True) count = 0 for entry in opportunities: mins_to_first_response = convert_to_seconds(entry.mins_to_first_response, 'Minutes') @@ -58,6 +59,8 @@ def execute(): def convert_to_seconds(value, unit): seconds = 0 + if value == 0: + return seconds if unit == 'Hours': seconds = value * 3600 if unit == 'Minutes': diff --git a/erpnext/patches/v13_0/update_returned_qty_in_pr_dn.py b/erpnext/patches/v13_0/update_returned_qty_in_pr_dn.py index e642547ef8..a5769d2957 100644 --- a/erpnext/patches/v13_0/update_returned_qty_in_pr_dn.py +++ b/erpnext/patches/v13_0/update_returned_qty_in_pr_dn.py @@ -8,6 +8,7 @@ def execute(): frappe.reload_doc('stock', 'doctype', 'purchase_receipt_item') frappe.reload_doc('stock', 'doctype', 'delivery_note') frappe.reload_doc('stock', 'doctype', 'delivery_note_item') + frappe.reload_doc('stock', 'doctype', 'stock_settings') def update_from_return_docs(doctype): for return_doc in frappe.get_all(doctype, filters={'is_return' : 1, 'docstatus' : 1}): From 743375748980426b1b7fe82141ce4f0de1ecc8c6 Mon Sep 17 00:00:00 2001 From: Shadrak Gurupnor <30501401+shadrak98@users.noreply.github.com> Date: Fri, 27 Aug 2021 18:00:16 +0530 Subject: [PATCH 15/20] fix: patches were breaking during migration (#27200) * fix: patches were breaking during migrating * fix: patches were breaking during migration --- erpnext/accounts/utils.py | 11 ++++++++ erpnext/patches.txt | 3 ++- .../move_item_tax_to_item_tax_template.py | 3 ++- .../v13_0/delete_old_purchase_reports.py | 13 ++-------- .../patches/v13_0/delete_old_sales_reports.py | 4 +-- .../v13_0/validate_options_for_data_field.py | 25 +++++++++++++++++++ 6 files changed, 44 insertions(+), 15 deletions(-) create mode 100644 erpnext/patches/v13_0/validate_options_for_data_field.py diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 118f628abe..5ed4a1947c 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -1086,3 +1086,14 @@ def get_journal_entry(account, stock_adjustment_account, amount): db_or_cr_stock_adjustment_account : abs(amount) }] } + +def check_and_delete_linked_reports(report): + """ Check if reports are referenced in Desktop Icon """ + icons = frappe.get_all("Desktop Icon", + fields = ['name'], + filters = { + "_report": report + }) + if icons: + for icon in icons: + frappe.delete_doc("Desktop Icon", icon) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index ade19ff1d5..05c385b6ba 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -299,4 +299,5 @@ erpnext.patches.v13_0.migrate_stripe_api erpnext.patches.v13_0.reset_clearance_date_for_intracompany_payment_entries erpnext.patches.v13_0.einvoicing_deprecation_warning erpnext.patches.v14_0.delete_einvoicing_doctypes -erpnext.patches.v13_0.set_operation_time_based_on_operating_cost \ No newline at end of file +erpnext.patches.v13_0.set_operation_time_based_on_operating_cost +erpnext.patches.v13_0.validate_options_for_data_field \ No newline at end of file diff --git a/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py b/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py index a6471eb53c..5c3fa5991c 100644 --- a/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py +++ b/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py @@ -91,8 +91,9 @@ def get_item_tax_template(item_tax_templates, item_tax_map, item_code, parenttyp item_tax_template.title = make_autoname("Item Tax Template-.####") for tax_type, tax_rate in iteritems(item_tax_map): - account_details = frappe.db.get_value("Account", tax_type, ['name', 'account_type'], as_dict=1) + account_details = frappe.db.get_value("Account", tax_type, ['name', 'account_type', 'company'], as_dict=1) if account_details: + item_tax_template.company = account_details.company if account_details.account_type not in ('Tax', 'Chargeable', 'Income Account', 'Expense Account', 'Expenses Included In Valuation'): frappe.db.set_value('Account', account_details.name, 'account_type', 'Chargeable') else: diff --git a/erpnext/patches/v13_0/delete_old_purchase_reports.py b/erpnext/patches/v13_0/delete_old_purchase_reports.py index 360a82e5c0..57620d3e98 100644 --- a/erpnext/patches/v13_0/delete_old_purchase_reports.py +++ b/erpnext/patches/v13_0/delete_old_purchase_reports.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals import frappe +from erpnext.accounts.utils import check_and_delete_linked_reports def execute(): reports_to_delete = ["Requested Items To Be Ordered", @@ -13,7 +14,7 @@ def execute(): for report in reports_to_delete: if frappe.db.exists("Report", report): delete_auto_email_reports(report) - check_linked_reports(report) + check_and_delete_linked_reports(report) frappe.delete_doc("Report", report) @@ -22,13 +23,3 @@ def delete_auto_email_reports(report): auto_email_reports = frappe.db.get_values("Auto Email Report", {"report": report}, ["name"]) for auto_email_report in auto_email_reports: frappe.delete_doc("Auto Email Report", auto_email_report[0]) - -def check_linked_reports(report): - """ Check if reports are referenced in Desktop Icon """ - icons = frappe.get_all("Desktop Icon", - fields = ['name'], - filters = { - "_report": report - }) - if icons: - frappe.delete_doc("Desktop Icon", icons) \ No newline at end of file diff --git a/erpnext/patches/v13_0/delete_old_sales_reports.py b/erpnext/patches/v13_0/delete_old_sales_reports.py index 69493e2c00..905a42c0c4 100644 --- a/erpnext/patches/v13_0/delete_old_sales_reports.py +++ b/erpnext/patches/v13_0/delete_old_sales_reports.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe -from erpnext.patches.v13_0.delete_old_purchase_reports import check_linked_reports +from erpnext.accounts.utils import check_and_delete_linked_reports def execute(): reports_to_delete = ["Ordered Items To Be Delivered", "Ordered Items To Be Billed"] @@ -12,7 +12,7 @@ def execute(): for report in reports_to_delete: if frappe.db.exists("Report", report): delete_auto_email_reports(report) - check_linked_reports(report) + check_and_delete_linked_reports(report) frappe.delete_doc("Report", report) diff --git a/erpnext/patches/v13_0/validate_options_for_data_field.py b/erpnext/patches/v13_0/validate_options_for_data_field.py new file mode 100644 index 0000000000..568d1a4b0c --- /dev/null +++ b/erpnext/patches/v13_0/validate_options_for_data_field.py @@ -0,0 +1,25 @@ +# Copyright (c) 2021, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model import data_field_options + +def execute(): + + for field in frappe.get_all('Custom Field', + fields = ['name'], + filters = { + 'fieldtype': 'Data', + 'options': ['!=', None] + }): + + if field not in data_field_options: + frappe.db.sql(""" + UPDATE + `tabCustom Field` + SET + options=NULL + WHERE + name=%s + """, (field)) From 072151e16d6c0003d71c9a889ac8f00c10a7869c Mon Sep 17 00:00:00 2001 From: Devin Slauenwhite Date: Fri, 27 Aug 2021 10:14:57 -0400 Subject: [PATCH 16/20] feat: Payment reconciliation on accounts module workspace (#25925) * feat: add payment reconciliation to accounting workspace * fix: update modified and duplicate the link Co-authored-by: Ankush Menat --- .../workspace/accounting/accounting.json | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/workspace/accounting/accounting.json b/erpnext/accounts/workspace/accounting/accounting.json index b5bd14d137..2b26ac5090 100644 --- a/erpnext/accounts/workspace/accounting/accounting.json +++ b/erpnext/accounts/workspace/accounting/accounting.json @@ -233,6 +233,15 @@ "onboard": 0, "type": "Link" }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Payment Reconciliation", + "link_to": "Payment Reconciliation", + "link_type": "DocType", + "onboard": 0, + "type": "Link" + }, { "dependencies": "Sales Invoice", "hidden": 0, @@ -340,6 +349,15 @@ "onboard": 0, "type": "Link" }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Payment Reconciliation", + "link_to": "Payment Reconciliation", + "link_type": "DocType", + "onboard": 0, + "type": "Link" + }, { "dependencies": "Purchase Invoice", "hidden": 0, @@ -1188,7 +1206,7 @@ "type": "Link" } ], - "modified": "2021-08-05 12:15:52.872470", + "modified": "2021-08-27 12:15:52.872470", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting", @@ -1249,4 +1267,4 @@ } ], "title": "Accounting" -} \ No newline at end of file +} From 2caa09099101a304c3152f814a9b3e9df8fd25ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Aug 2021 19:59:36 +0530 Subject: [PATCH 17/20] chore(deps): bump tar from 6.1.0 to 6.1.11 (#27203) Bumps [tar](https://github.com/npm/node-tar) from 6.1.0 to 6.1.11. - [Release notes](https://github.com/npm/node-tar/releases) - [Changelog](https://github.com/npm/node-tar/blob/main/CHANGELOG.md) - [Commits](https://github.com/npm/node-tar/compare/v6.1.0...v6.1.11) --- updated-dependencies: - dependency-name: tar dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 82e98215d1..0a49c52f0e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3244,9 +3244,9 @@ tar-stream@^2.1.0: readable-stream "^3.1.1" tar@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" - integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== + version "6.1.11" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" + integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" From 327071cb9078840aa463fa3c2d80ac2ef8a6ab8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20de=20Ryckel?= Date: Sat, 28 Aug 2021 12:25:11 +0300 Subject: [PATCH 18/20] replace cur_frm with frm (#27210) --- erpnext/accounts/doctype/account/account.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/account/account.js b/erpnext/accounts/doctype/account/account.js index f7f1a5fb15..7a1d735948 100644 --- a/erpnext/accounts/doctype/account/account.js +++ b/erpnext/accounts/doctype/account/account.js @@ -74,7 +74,7 @@ frappe.ui.form.on('Account', { }); } else if (cint(frm.doc.is_group) == 0 && frappe.boot.user.can_read.indexOf("GL Entry") !== -1) { - cur_frm.add_custom_button(__('Ledger'), function () { + frm.add_custom_button(__('Ledger'), function () { frappe.route_options = { "account": frm.doc.name, "from_date": frappe.sys_defaults.year_start_date, From f5cdbf161d2b03e088ac6882553d381c39ed5ba7 Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Sat, 28 Aug 2021 14:55:51 +0530 Subject: [PATCH 19/20] fix: LTV ratio comparison (#27207) --- .../doctype/loan_repayment/loan_repayment.py | 13 +++++++------ .../loan_security_shortfall.py | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py index 57aec2e5c9..b67b4c4842 100644 --- a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py +++ b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py @@ -107,12 +107,13 @@ class LoanRepayment(AccountsController): lia = frappe.db.get_value('Loan Interest Accrual', {'process_loan_interest_accrual': process}, ['name', 'interest_amount', 'payable_principal_amount'], as_dict=1) - self.append('repayment_details', { - 'loan_interest_accrual': lia.name, - 'paid_interest_amount': flt(self.total_interest_paid - self.interest_payable, precision), - 'paid_principal_amount': 0.0, - 'accrual_type': 'Repayment' - }) + if lia: + self.append('repayment_details', { + 'loan_interest_accrual': lia.name, + 'paid_interest_amount': flt(self.total_interest_paid - self.interest_payable, precision), + 'paid_principal_amount': 0.0, + 'accrual_type': 'Repayment' + }) def update_paid_amount(self): loan = frappe.get_doc("Loan", self.against_loan) diff --git a/erpnext/loan_management/doctype/loan_security_shortfall/loan_security_shortfall.py b/erpnext/loan_management/doctype/loan_security_shortfall/loan_security_shortfall.py index cd7694b7b1..61f1778048 100644 --- a/erpnext/loan_management/doctype/loan_security_shortfall/loan_security_shortfall.py +++ b/erpnext/loan_management/doctype/loan_security_shortfall/loan_security_shortfall.py @@ -71,7 +71,7 @@ def check_for_ltv_shortfall(process_loan_security_shortfall): - flt(loan.total_principal_paid) pledged_securities = get_pledged_security_qty(loan.name) - ltv_ratio = '' + ltv_ratio = 0.0 security_value = 0.0 for security, qty in pledged_securities.items(): From e5e00700e5415d9abc91ef5e119649a17c347d9a Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 30 Aug 2021 12:07:11 +0530 Subject: [PATCH 20/20] ci: use node action instead of apt (#27220) --- .github/helper/install.sh | 7 +------ .github/workflows/patch.yml | 8 +++++++- .github/workflows/server-tests.yml | 6 ++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/.github/helper/install.sh b/.github/helper/install.sh index 455ab861f9..ac623e947d 100644 --- a/.github/helper/install.sh +++ b/.github/helper/install.sh @@ -4,11 +4,7 @@ set -e cd ~ || exit -sudo apt-get install redis-server - -sudo apt install nodejs - -sudo apt install npm +sudo apt-get install redis-server libcups2-dev pip install frappe-bench @@ -32,7 +28,6 @@ wget -O /tmp/wkhtmltox.tar.xz https://github.com/frappe/wkhtmltopdf/raw/master/w tar -xf /tmp/wkhtmltox.tar.xz -C /tmp sudo mv /tmp/wkhtmltox/bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf sudo chmod o+x /usr/local/bin/wkhtmltopdf -sudo apt-get install libcups2-dev cd ~/frappe-bench || exit diff --git a/.github/workflows/patch.yml b/.github/workflows/patch.yml index 72d4028ce6..f65b0001fe 100644 --- a/.github/workflows/patch.yml +++ b/.github/workflows/patch.yml @@ -31,7 +31,13 @@ jobs: - name: Setup Python uses: actions/setup-python@v2 with: - python-version: 3.6 + python-version: 3.7 + + - name: Setup Node + uses: actions/setup-node@v2 + with: + node-version: 14 + check-latest: true - name: Add to Hosts run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts diff --git a/.github/workflows/server-tests.yml b/.github/workflows/server-tests.yml index 3a1ecd399c..0a73d74d6b 100644 --- a/.github/workflows/server-tests.yml +++ b/.github/workflows/server-tests.yml @@ -43,6 +43,12 @@ jobs: with: python-version: 3.7 + - name: Setup Node + uses: actions/setup-node@v2 + with: + node-version: 14 + check-latest: true + - name: Add to Hosts run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts