From ec12df154a800ad68d75d53f5908bc4e3afa4e91 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 12 Sep 2024 19:17:57 +0530 Subject: [PATCH 01/28] feat: Create Quotation, Contact and Customer in ERPNext from Deal --- .../doctype/erpnext_crm_settings/__init__.py | 0 .../erpnext_crm_settings.js | 0 .../erpnext_crm_settings.json | 97 +++++++++ .../erpnext_crm_settings.py | 194 ++++++++++++++++++ .../test_erpnext_crm_settings.py | 9 + crm/hooks.py | 3 + frontend/src/components/Icons/ERPNextIcon.vue | 20 ++ .../components/Settings/ERPNextSettings.vue | 6 + .../src/components/Settings/SettingsModal.vue | 7 + .../src/components/Settings/SettingsPage.vue | 6 +- 10 files changed, 341 insertions(+), 1 deletion(-) create mode 100644 crm/fcrm/doctype/erpnext_crm_settings/__init__.py create mode 100644 crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.js create mode 100644 crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.json create mode 100644 crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.py create mode 100644 crm/fcrm/doctype/erpnext_crm_settings/test_erpnext_crm_settings.py create mode 100644 frontend/src/components/Icons/ERPNextIcon.vue create mode 100644 frontend/src/components/Settings/ERPNextSettings.vue diff --git a/crm/fcrm/doctype/erpnext_crm_settings/__init__.py b/crm/fcrm/doctype/erpnext_crm_settings/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.js b/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.js new file mode 100644 index 000000000..e69de29bb diff --git a/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.json b/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.json new file mode 100644 index 000000000..6d71314ef --- /dev/null +++ b/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.json @@ -0,0 +1,97 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2024-07-02 15:23:17.022214", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "enabled", + "is_erpnext_in_the_current_site", + "column_break_vfru", + "erpnext_company", + "section_break_oubd", + "erpnext_site_url", + "column_break_fllx", + "api_key", + "api_secret" + ], + "fields": [ + { + "depends_on": "eval:!doc.is_erpnext_in_the_current_site", + "fieldname": "api_key", + "fieldtype": "Data", + "label": "API Key", + "mandatory_depends_on": "eval:!doc.is_erpnext_in_the_current_site" + }, + { + "depends_on": "eval:!doc.is_erpnext_in_the_current_site", + "fieldname": "api_secret", + "fieldtype": "Data", + "label": "API Secret", + "mandatory_depends_on": "eval:!doc.is_erpnext_in_the_current_site" + }, + { + "depends_on": "enabled", + "fieldname": "section_break_oubd", + "fieldtype": "Section Break" + }, + { + "fieldname": "column_break_fllx", + "fieldtype": "Column Break" + }, + { + "depends_on": "eval:!doc.is_erpnext_in_the_current_site", + "fieldname": "erpnext_site_url", + "fieldtype": "Data", + "label": "ERPNext Site URL", + "mandatory_depends_on": "eval:!doc.is_erpnext_in_the_current_site" + }, + { + "depends_on": "enabled", + "fieldname": "erpnext_company", + "fieldtype": "Data", + "label": "Company in ERPNext Site", + "mandatory_depends_on": "enabled" + }, + { + "fieldname": "column_break_vfru", + "fieldtype": "Column Break" + }, + { + "default": "0", + "depends_on": "enabled", + "fieldname": "is_erpnext_in_the_current_site", + "fieldtype": "Check", + "label": "Is ERPNext in the current site?" + }, + { + "default": "0", + "fieldname": "enabled", + "fieldtype": "Check", + "label": "Enabled" + } + ], + "index_web_pages_for_search": 1, + "issingle": 1, + "links": [], + "modified": "2024-09-12 18:14:44.323068", + "modified_by": "Administrator", + "module": "FCRM", + "name": "ERPNext CRM Settings", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "creation", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.py b/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.py new file mode 100644 index 000000000..20f994bce --- /dev/null +++ b/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.py @@ -0,0 +1,194 @@ +# Copyright (c) 2024, Frappe and contributors +# For license information, please see license.txt + +import frappe +from frappe import _ +from frappe.custom.doctype.property_setter.property_setter import make_property_setter +from frappe.model.document import Document +from frappe.frappeclient import FrappeClient +from frappe.utils import get_url_to_form +from erpnext.crm.frappe_crm_api import create_custom_fields_for_frappe_crm, create_customer +import json + +class ERPNextCRMSettings(Document): + def validate(self): + if self.enabled: + self.validate_if_erpnext_installed() + self.add_quotation_to_option() + self.create_custom_fields() + self.create_crm_form_script() + + def validate_if_erpnext_installed(self): + if self.is_erpnext_in_the_current_site: + if "erpnext" not in frappe.get_installed_apps(): + frappe.throw(_("ERPNext is not installed in the current site")) + + def add_quotation_to_option(self): + if self.is_erpnext_in_the_current_site: + if not frappe.db.exists("Property Setter", {"name": "Quotation-quotation_to-link_filters"}): + make_property_setter( + doctype="Quotation", + fieldname="quotation_to", + property="link_filters", + value='[["DocType","name","in", ["Customer", "Lead", "Prospect", "Frappe CRM Deal"]]]', + property_type="JSON", + validate_fields_for_doctype=False, + ) + + def create_custom_fields(self): + if self.is_erpnext_in_the_current_site: + create_custom_fields_for_frappe_crm() + else: + self.create_custom_fields_in_remote_site() + + def create_custom_fields_in_remote_site(self): + client = get_erpnext_site_client(self) + try: + client.post_api("erpnext.crm.frappe_crm_api.create_custom_fields_for_frappe_crm") + except Exception as e: + frappe.log_error( + frappe.get_traceback(), + f"Error while creating custom field in the remote erpnext site: {self.erpnext_site_url}" + ) + frappe.throw("Error while creating custom field in the remote erpnext site, check error log for more details") + + def create_crm_form_script(self): + if not frappe.db.exists("CRM Form Script", "Create Quotation from CRM Deal"): + script = get_crm_form_script() + frappe.get_doc({ + "doctype": "CRM Form Script", + "name": "Create Quotation from CRM Deal", + "dt": "CRM Deal", + "view": "Form", + "script": script, + "enabled": 1, + "is_standard": 1 + }).insert() + +def get_erpnext_site_client(erpnext_crm_settings): + site_url = erpnext_crm_settings.erpnext_site_url + api_key = erpnext_crm_settings.api_key + api_secret = erpnext_crm_settings.api_secret + + return FrappeClient( + site_url, api_key=api_key, api_secret=api_secret + ) + +@frappe.whitelist() +def get_quotation_url(crm_deal, organization): + erpnext_crm_settings = frappe.get_single("ERPNext CRM Settings") + if not erpnext_crm_settings.enabled: + frappe.throw(_("ERPNext is not integrated with the CRM")) + + if erpnext_crm_settings.is_erpnext_in_the_current_site: + quotation_url = get_url_to_form("Quotation") + return f"{quotation_url}/new?quotation_to=CRM Deal&crm_deal={crm_deal}&party_name={crm_deal}" + else: + site_url = erpnext_crm_settings.get("erpnext_site_url") + quotation_url = f"{site_url}/app/quotation" + + prospect = create_prospect_in_remote_site(crm_deal, erpnext_crm_settings) + return f"{quotation_url}/new?quotation_to=Prospect&crm_deal={crm_deal}&party_name={prospect}" + +def create_prospect_in_remote_site(crm_deal, erpnext_crm_settings): + try: + client = get_erpnext_site_client(erpnext_crm_settings) + doc = frappe.get_doc("CRM Deal", crm_deal) + contacts = get_contacts(doc) + return client.post_api("erpnext.crm.frappe_crm_api.create_prospect_against_crm_deal", + { + "organization": doc.organization, + "lead_name": doc.lead_name, + "no_of_employees": doc.no_of_employees, + "deal_owner": doc.deal_owner, + "crm_deal": doc.name, + "territory": doc.territory, + "industry": doc.industry, + "website": doc.website, + "annual_revenue": doc.annual_revenue, + "contacts": json.dumps(contacts), + "erpnext_company": erpnext_crm_settings.erpnext_company + }, + ) + except Exception as e: + frappe.log_error( + frappe.get_traceback(), + f"Error while creating prospect in remote site: {erpnext_crm_settings.erpnext_site_url}" + ) + raise + pass + +def get_contacts(doc): + contacts = [] + for c in doc.contacts: + contacts.append({ + "contact": c.contact, + "full_name": c.full_name, + "email": c.email, + "mobile_no": c.mobile_no, + "gender": c.gender, + "is_primary": c.is_primary, + }) + return contacts + +def create_customer_in_erpnext(doc, method): + erpnext_crm_settings = frappe.get_single("ERPNext CRM Settings") + if not erpnext_crm_settings.enabled or doc.status != "Won": + return + + contacts = get_contacts(doc) + customer = { + "customer_name": doc.organization, + "customer_group": "All Customer Groups", + "customer_type": "Company", + "territory": doc.territory, + "default_currency": doc.currency, + "industry": doc.industry, + "website": doc.website, + "crm_deal": doc.name, + "contacts": json.dumps(contacts), + } + if erpnext_crm_settings.is_erpnext_in_the_current_site: + create_customer(customer) + else: + create_customer_in_remote_site(customer, erpnext_crm_settings) + +def create_customer_in_remote_site(customer, erpnext_crm_settings): + client = get_erpnext_site_client(erpnext_crm_settings) + try: + client.post_api("erpnext.crm.frappe_crm_api.create_customer", customer) + except Exception as e: + frappe.log_error( + frappe.get_traceback(), + "Error while creating customer in remote site" + ) + pass + +def get_crm_form_script(): + return """ +function setupForm({ doc, call, $dialog, updateField, createToast }) { + let actions = []; + if (!["Lost", "Won"].includes(doc?.status)) { + actions.push({ + label: __("Create Quotation"), + onClick: async () => { + let quotation_url = await call( + "crm.fcrm.doctype.erpnext_crm_settings.erpnext_crm_settings.get_quotation_url", + { + crm_deal: doc.name, + organization: doc.organization + } + ); + + if (quotation_url) { + window.open(quotation_url, '_blank'); + } + } + }) + } + + return { + actions: actions, + }; +} +""" diff --git a/crm/fcrm/doctype/erpnext_crm_settings/test_erpnext_crm_settings.py b/crm/fcrm/doctype/erpnext_crm_settings/test_erpnext_crm_settings.py new file mode 100644 index 000000000..17ae02845 --- /dev/null +++ b/crm/fcrm/doctype/erpnext_crm_settings/test_erpnext_crm_settings.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestERPNextCRMSettings(FrappeTestCase): + pass diff --git a/crm/hooks.py b/crm/hooks.py index e53fc8aa6..fa7e606a8 100644 --- a/crm/hooks.py +++ b/crm/hooks.py @@ -152,6 +152,9 @@ "validate": ["crm.api.whatsapp.validate"], "on_update": ["crm.api.whatsapp.on_update"], }, + "CRM Deal": { + "on_update": ["crm.fcrm.doctype.erpnext_crm_settings.erpnext_crm_settings.create_customer_in_erpnext"], + }, } # Scheduled Tasks diff --git a/frontend/src/components/Icons/ERPNextIcon.vue b/frontend/src/components/Icons/ERPNextIcon.vue new file mode 100644 index 000000000..e512b92db --- /dev/null +++ b/frontend/src/components/Icons/ERPNextIcon.vue @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/frontend/src/components/Settings/ERPNextSettings.vue b/frontend/src/components/Settings/ERPNextSettings.vue new file mode 100644 index 000000000..e8a4518c7 --- /dev/null +++ b/frontend/src/components/Settings/ERPNextSettings.vue @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/frontend/src/components/Settings/SettingsModal.vue b/frontend/src/components/Settings/SettingsModal.vue index 16487387b..2bbe99223 100644 --- a/frontend/src/components/Settings/SettingsModal.vue +++ b/frontend/src/components/Settings/SettingsModal.vue @@ -39,10 +39,12 @@ \ No newline at end of file From cb33d2d3f2dab2b4898fa4c67309bbb878e04463 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 16 Sep 2024 18:45:12 +0530 Subject: [PATCH 06/28] fix: get organization address and pass it to link it with prospect and customer while creation --- .../erpnext_crm_settings/erpnext_crm_settings.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.py b/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.py index 0b8bd013d..c3143d776 100644 --- a/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.py +++ b/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.py @@ -95,6 +95,7 @@ def create_prospect_in_remote_site(crm_deal, erpnext_crm_settings): client = get_erpnext_site_client(erpnext_crm_settings) doc = frappe.get_doc("CRM Deal", crm_deal) contacts = get_contacts(doc) + address = get_organization_address(doc.organization) return client.post_api("erpnext.crm.frappe_crm_api.create_prospect_against_crm_deal", { "organization": doc.organization, @@ -107,7 +108,8 @@ def create_prospect_in_remote_site(crm_deal, erpnext_crm_settings): "website": doc.website, "annual_revenue": doc.annual_revenue, "contacts": json.dumps(contacts), - "erpnext_company": erpnext_crm_settings.erpnext_company + "erpnext_company": erpnext_crm_settings.erpnext_company, + "address": address.as_dict() if address else None }, ) except Exception: @@ -130,12 +132,18 @@ def get_contacts(doc): }) return contacts +def get_organization_address(organization): + address = frappe.get_value("CRM Organization", organization, "address") + address = frappe.get_doc("Address", address) if address else None + return address + def create_customer_in_erpnext(doc, method): erpnext_crm_settings = frappe.get_single("ERPNext CRM Settings") if not erpnext_crm_settings.enabled or doc.status != "Won": return contacts = get_contacts(doc) + address = get_organization_address(doc.organization) customer = { "customer_name": doc.organization, "customer_group": "All Customer Groups", @@ -146,6 +154,7 @@ def create_customer_in_erpnext(doc, method): "website": doc.website, "crm_deal": doc.name, "contacts": json.dumps(contacts), + "address": address.as_dict() if address else None, } if not erpnext_crm_settings.is_erpnext_in_different_site: from erpnext.crm.frappe_crm_api import create_customer From 979ef27a9defa304b5917d19707214dc9f5daae7 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 16 Sep 2024 19:30:53 +0530 Subject: [PATCH 07/28] fix: option to create customer on status change --- .../erpnext_crm_settings.json | 30 +++++++++++++++++-- .../erpnext_crm_settings.py | 10 +++++-- frontend/src/pages/Deal.vue | 22 ++++++++++++-- frontend/src/pages/Lead.vue | 7 ++++- 4 files changed, 62 insertions(+), 7 deletions(-) diff --git a/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.json b/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.json index 99fb35dc1..1f19b7ef4 100644 --- a/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.json +++ b/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.json @@ -13,7 +13,11 @@ "erpnext_site_url", "column_break_fllx", "api_key", - "api_secret" + "api_secret", + "section_break_jnbn", + "create_customer_on_status_change", + "column_break_kbhw", + "deal_status" ], "fields": [ { @@ -69,12 +73,34 @@ "fieldname": "is_erpnext_in_different_site", "fieldtype": "Check", "label": "Is ERPNext installed on a different site?" + }, + { + "fieldname": "section_break_jnbn", + "fieldtype": "Section Break" + }, + { + "default": "0", + "depends_on": "enabled", + "fieldname": "create_customer_on_status_change", + "fieldtype": "Check", + "label": "Create customer on status change" + }, + { + "fieldname": "column_break_kbhw", + "fieldtype": "Column Break" + }, + { + "depends_on": "create_customer_on_status_change", + "fieldname": "deal_status", + "fieldtype": "Link", + "label": "Deal Status", + "options": "CRM Deal Status" } ], "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2024-09-16 13:51:35.141503", + "modified": "2024-09-16 19:01:28.694010", "modified_by": "Administrator", "module": "FCRM", "name": "ERPNext CRM Settings", diff --git a/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.py b/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.py index c3143d776..6cbef5f46 100644 --- a/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.py +++ b/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.py @@ -139,7 +139,11 @@ def get_organization_address(organization): def create_customer_in_erpnext(doc, method): erpnext_crm_settings = frappe.get_single("ERPNext CRM Settings") - if not erpnext_crm_settings.enabled or doc.status != "Won": + if ( + not erpnext_crm_settings.enabled + or not erpnext_crm_settings.create_customer_on_status_change + or doc.status != erpnext_crm_settings.deal_status + ): return contacts = get_contacts(doc) @@ -160,7 +164,9 @@ def create_customer_in_erpnext(doc, method): from erpnext.crm.frappe_crm_api import create_customer create_customer(customer) else: - create_customer_in_remote_site(customer, erpnext_crm_settings) + create_customer_in_remote_site(customer, erpnext_crm_settings) + + frappe.publish_realtime("crm_customer_created") def create_customer_in_remote_site(customer, erpnext_crm_settings): client = get_erpnext_site_client(erpnext_crm_settings) diff --git a/frontend/src/pages/Deal.vue b/frontend/src/pages/Deal.vue index 27a8f3c57..d21c2508b 100644 --- a/frontend/src/pages/Deal.vue +++ b/frontend/src/pages/Deal.vue @@ -361,10 +361,10 @@ import { call, usePageMeta, } from 'frappe-ui' -import { ref, computed, h, onMounted } from 'vue' +import { ref, computed, h, onMounted, onBeforeUnmount } from 'vue' import { useRoute, useRouter } from 'vue-router' -const { $dialog, makeCall } = globalStore() +const { $dialog, $socket, makeCall } = globalStore() const { organizations, getOrganization } = organizationsStore() const { statusOptions, getDealStatus } = statusesStore() const { isManager } = usersStore() @@ -386,10 +386,16 @@ const deal = createResource({ let obj = { doc: data, $dialog, + $socket, router, updateField, createToast, deleteDoc: deleteDeal, + resource: { + deal, + deal_contacts, + fieldsLayout, + }, call, } setupAssignees(data) @@ -399,10 +405,22 @@ const deal = createResource({ }) onMounted(() => { + $socket.on('crm_customer_created', () => { + createToast({ + title: __('Customer created successfully'), + icon: 'check', + iconClasses: 'text-green-600', + }) + }) + if (deal.data) return deal.fetch() }) +onBeforeUnmount(() => { + $socket.off('crm_customer_created') +}) + const reload = ref(false) const showOrganizationModal = ref(false) const showAssignmentModal = ref(false) diff --git a/frontend/src/pages/Lead.vue b/frontend/src/pages/Lead.vue index d89a9be06..728f45f72 100644 --- a/frontend/src/pages/Lead.vue +++ b/frontend/src/pages/Lead.vue @@ -335,7 +335,7 @@ import { import { ref, computed, onMounted, watch } from 'vue' import { useRouter, useRoute } from 'vue-router' -const { $dialog, makeCall } = globalStore() +const { $dialog, $socket, makeCall } = globalStore() const { getContactByName, contacts } = contactsStore() const { organizations } = organizationsStore() const { statusOptions, getLeadStatus } = statusesStore() @@ -358,10 +358,15 @@ const lead = createResource({ let obj = { doc: data, $dialog, + $socket, router, updateField, createToast, deleteDoc: deleteLead, + resource: { + lead, + fieldsLayout, + }, call, } setupAssignees(data) From 0d5d34f2affe120a2eaab8703eacc14acc0aa1b4 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 16 Sep 2024 19:45:31 +0530 Subject: [PATCH 08/28] fix: hide enable check in form script --- crm/fcrm/doctype/crm_form_script/crm_form_script.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crm/fcrm/doctype/crm_form_script/crm_form_script.json b/crm/fcrm/doctype/crm_form_script/crm_form_script.json index 1cc14d9a3..9246913a0 100644 --- a/crm/fcrm/doctype/crm_form_script/crm_form_script.json +++ b/crm/fcrm/doctype/crm_form_script/crm_form_script.json @@ -35,6 +35,7 @@ "default": "0", "fieldname": "enabled", "fieldtype": "Check", + "hidden": 1, "label": "Enabled" }, { @@ -64,7 +65,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2024-09-11 12:56:09.288849", + "modified": "2024-09-16 19:40:19.340948", "modified_by": "Administrator", "module": "FCRM", "name": "CRM Form Script", From 37c031b38c770245ff5b78897302a2bf5f994106 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 16 Sep 2024 19:46:24 +0530 Subject: [PATCH 09/28] fix: show title in link field for CRM Lead & CRM Deal --- crm/fcrm/doctype/crm_deal/crm_deal.json | 4 +++- crm/fcrm/doctype/crm_lead/crm_lead.json | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/crm/fcrm/doctype/crm_deal/crm_deal.json b/crm/fcrm/doctype/crm_deal/crm_deal.json index e5c973d8c..6338f56d6 100644 --- a/crm/fcrm/doctype/crm_deal/crm_deal.json +++ b/crm/fcrm/doctype/crm_deal/crm_deal.json @@ -339,7 +339,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2024-06-20 12:55:41.602364", + "modified": "2024-09-16 19:44:19.553715", "modified_by": "Administrator", "module": "FCRM", "name": "CRM Deal", @@ -371,8 +371,10 @@ "write": 1 } ], + "show_title_field_in_link": 1, "sort_field": "modified", "sort_order": "DESC", "states": [], + "title_field": "organization", "track_changes": 1 } \ No newline at end of file diff --git a/crm/fcrm/doctype/crm_lead/crm_lead.json b/crm/fcrm/doctype/crm_lead/crm_lead.json index ced8e3cb4..e9e77c89b 100644 --- a/crm/fcrm/doctype/crm_lead/crm_lead.json +++ b/crm/fcrm/doctype/crm_lead/crm_lead.json @@ -291,7 +291,7 @@ "image_field": "image", "index_web_pages_for_search": 1, "links": [], - "modified": "2024-02-05 00:58:07.321058", + "modified": "2024-09-16 19:46:01.307171", "modified_by": "Administrator", "module": "FCRM", "name": "CRM Lead", @@ -325,6 +325,7 @@ ], "sender_field": "email", "sender_name_field": "first_name", + "show_title_field_in_link": 1, "sort_field": "modified", "sort_order": "DESC", "states": [], From 321c0d81bf6b95593683ea27737639166a86c86a Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 16 Sep 2024 20:52:40 +0530 Subject: [PATCH 10/28] fix: show deal status only if erpnext crm settings enabled --- .../doctype/erpnext_crm_settings/erpnext_crm_settings.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.json b/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.json index 1f19b7ef4..bbea596fc 100644 --- a/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.json +++ b/crm/fcrm/doctype/erpnext_crm_settings/erpnext_crm_settings.json @@ -90,7 +90,7 @@ "fieldtype": "Column Break" }, { - "depends_on": "create_customer_on_status_change", + "depends_on": "eval:doc.enabled && doc.create_customer_on_status_change", "fieldname": "deal_status", "fieldtype": "Link", "label": "Deal Status", @@ -100,7 +100,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2024-09-16 19:01:28.694010", + "modified": "2024-09-16 20:51:17.148493", "modified_by": "Administrator", "module": "FCRM", "name": "ERPNext CRM Settings", From 084ff543a43e664aed0eab23336dc7ffec7d9f17 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 16 Sep 2024 20:53:32 +0530 Subject: [PATCH 11/28] fix: render async form custom actions & statuses --- frontend/src/pages/Deal.vue | 42 +++++++++++++-------------- frontend/src/pages/Lead.vue | 20 ++++++------- frontend/src/pages/MobileDeal.vue | 46 ++++++++++++++--------------- frontend/src/pages/MobileLead.vue | 35 +++++++++++----------- frontend/src/utils/index.js | 48 +++++++++++-------------------- 5 files changed, 85 insertions(+), 106 deletions(-) diff --git a/frontend/src/pages/Deal.vue b/frontend/src/pages/Deal.vue index d21c2508b..892b4a416 100644 --- a/frontend/src/pages/Deal.vue +++ b/frontend/src/pages/Deal.vue @@ -8,19 +8,14 @@