Merge pull request #567 from shariquerik/set-address-contact-in-quotation
This commit is contained in:
commit
3b8655b69d
@ -1,22 +1,24 @@
|
|||||||
# Copyright (c) 2024, Frappe and contributors
|
# Copyright (c) 2024, Frappe and contributors
|
||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
|
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.frappeclient import FrappeClient
|
||||||
|
from frappe.model.document import Document
|
||||||
from frappe.utils import get_url_to_form, get_url_to_list
|
from frappe.utils import get_url_to_form, get_url_to_list
|
||||||
import json
|
|
||||||
|
|
||||||
class ERPNextCRMSettings(Document):
|
class ERPNextCRMSettings(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if self.enabled:
|
if self.enabled:
|
||||||
self.validate_if_erpnext_installed()
|
self.validate_if_erpnext_installed()
|
||||||
self.add_quotation_to_option()
|
self.add_quotation_to_option()
|
||||||
self.create_custom_fields()
|
self.create_custom_fields()
|
||||||
self.create_crm_form_script()
|
self.create_crm_form_script()
|
||||||
|
|
||||||
def validate_if_erpnext_installed(self):
|
def validate_if_erpnext_installed(self):
|
||||||
if not self.is_erpnext_in_different_site:
|
if not self.is_erpnext_in_different_site:
|
||||||
if "erpnext" not in frappe.get_installed_apps():
|
if "erpnext" not in frappe.get_installed_apps():
|
||||||
@ -37,6 +39,7 @@ class ERPNextCRMSettings(Document):
|
|||||||
def create_custom_fields(self):
|
def create_custom_fields(self):
|
||||||
if not self.is_erpnext_in_different_site:
|
if not self.is_erpnext_in_different_site:
|
||||||
from erpnext.crm.frappe_crm_api import create_custom_fields_for_frappe_crm
|
from erpnext.crm.frappe_crm_api import create_custom_fields_for_frappe_crm
|
||||||
|
|
||||||
create_custom_fields_for_frappe_crm()
|
create_custom_fields_for_frappe_crm()
|
||||||
else:
|
else:
|
||||||
self.create_custom_fields_in_remote_site()
|
self.create_custom_fields_in_remote_site()
|
||||||
@ -48,22 +51,24 @@ class ERPNextCRMSettings(Document):
|
|||||||
except Exception:
|
except Exception:
|
||||||
frappe.log_error(
|
frappe.log_error(
|
||||||
frappe.get_traceback(),
|
frappe.get_traceback(),
|
||||||
f"Error while creating custom field in the remote erpnext site: {self.erpnext_site_url}"
|
f"Error while creating custom field in the remote erpnext site: {self.erpnext_site_url}",
|
||||||
)
|
)
|
||||||
frappe.throw("Error while creating custom field in ERPNext, check error log for more details")
|
frappe.throw("Error while creating custom field in ERPNext, check error log for more details")
|
||||||
|
|
||||||
def create_crm_form_script(self):
|
def create_crm_form_script(self):
|
||||||
if not frappe.db.exists("CRM Form Script", "Create Quotation from CRM Deal"):
|
if not frappe.db.exists("CRM Form Script", "Create Quotation from CRM Deal"):
|
||||||
script = get_crm_form_script()
|
script = get_crm_form_script()
|
||||||
frappe.get_doc({
|
frappe.get_doc(
|
||||||
"doctype": "CRM Form Script",
|
{
|
||||||
"name": "Create Quotation from CRM Deal",
|
"doctype": "CRM Form Script",
|
||||||
"dt": "CRM Deal",
|
"name": "Create Quotation from CRM Deal",
|
||||||
"view": "Form",
|
"dt": "CRM Deal",
|
||||||
"script": script,
|
"view": "Form",
|
||||||
"enabled": 1,
|
"script": script,
|
||||||
"is_standard": 1
|
"enabled": 1,
|
||||||
}).insert()
|
"is_standard": 1,
|
||||||
|
}
|
||||||
|
).insert()
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def reset_erpnext_form_script(self):
|
def reset_erpnext_form_script(self):
|
||||||
@ -77,14 +82,14 @@ class ERPNextCRMSettings(Document):
|
|||||||
frappe.log_error(frappe.get_traceback(), "Error while resetting form script")
|
frappe.log_error(frappe.get_traceback(), "Error while resetting form script")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_erpnext_site_client(erpnext_crm_settings):
|
def get_erpnext_site_client(erpnext_crm_settings):
|
||||||
site_url = erpnext_crm_settings.erpnext_site_url
|
site_url = erpnext_crm_settings.erpnext_site_url
|
||||||
api_key = erpnext_crm_settings.api_key
|
api_key = erpnext_crm_settings.api_key
|
||||||
api_secret = erpnext_crm_settings.get_password("api_secret", raise_exception=False)
|
api_secret = erpnext_crm_settings.get_password("api_secret", raise_exception=False)
|
||||||
|
|
||||||
return FrappeClient(
|
return FrappeClient(site_url, api_key=api_key, api_secret=api_secret)
|
||||||
site_url, api_key=api_key, api_secret=api_secret
|
|
||||||
)
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_customer_link(crm_deal):
|
def get_customer_link(crm_deal):
|
||||||
@ -107,7 +112,7 @@ def get_customer_link(crm_deal):
|
|||||||
except Exception:
|
except Exception:
|
||||||
frappe.log_error(
|
frappe.log_error(
|
||||||
frappe.get_traceback(),
|
frappe.get_traceback(),
|
||||||
f"Error while fetching customer in remote site: {erpnext_crm_settings.erpnext_site_url}"
|
f"Error while fetching customer in remote site: {erpnext_crm_settings.erpnext_site_url}",
|
||||||
)
|
)
|
||||||
frappe.throw(_("Error while fetching customer in ERPNext, check error log for more details"))
|
frappe.throw(_("Error while fetching customer in ERPNext, check error log for more details"))
|
||||||
|
|
||||||
@ -118,23 +123,28 @@ def get_quotation_url(crm_deal, organization):
|
|||||||
if not erpnext_crm_settings.enabled:
|
if not erpnext_crm_settings.enabled:
|
||||||
frappe.throw(_("ERPNext is not integrated with the CRM"))
|
frappe.throw(_("ERPNext is not integrated with the CRM"))
|
||||||
|
|
||||||
|
contact = get_contact(crm_deal)
|
||||||
|
address = get_organization_address(organization).get("name") if organization else None
|
||||||
|
|
||||||
if not erpnext_crm_settings.is_erpnext_in_different_site:
|
if not erpnext_crm_settings.is_erpnext_in_different_site:
|
||||||
quotation_url = get_url_to_list("Quotation")
|
quotation_url = get_url_to_list("Quotation")
|
||||||
return f"{quotation_url}/new?quotation_to=CRM Deal&crm_deal={crm_deal}&party_name={crm_deal}&company={erpnext_crm_settings.erpnext_company}"
|
return f"{quotation_url}/new?quotation_to=CRM Deal&crm_deal={crm_deal}&party_name={crm_deal}&company={erpnext_crm_settings.erpnext_company}&contact_person={contact}&customer_address={address}"
|
||||||
else:
|
else:
|
||||||
site_url = erpnext_crm_settings.get("erpnext_site_url")
|
site_url = erpnext_crm_settings.get("erpnext_site_url")
|
||||||
quotation_url = f"{site_url}/app/quotation"
|
quotation_url = f"{site_url}/app/quotation"
|
||||||
|
|
||||||
prospect = create_prospect_in_remote_site(crm_deal, erpnext_crm_settings)
|
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}&company={erpnext_crm_settings.erpnext_company}"
|
return f"{quotation_url}/new?quotation_to=Prospect&crm_deal={crm_deal}&party_name={prospect}&company={erpnext_crm_settings.erpnext_company}&contact_person={contact}&customer_address={address}"
|
||||||
|
|
||||||
|
|
||||||
def create_prospect_in_remote_site(crm_deal, erpnext_crm_settings):
|
def create_prospect_in_remote_site(crm_deal, erpnext_crm_settings):
|
||||||
try:
|
try:
|
||||||
client = get_erpnext_site_client(erpnext_crm_settings)
|
client = get_erpnext_site_client(erpnext_crm_settings)
|
||||||
doc = frappe.get_doc("CRM Deal", crm_deal)
|
doc = frappe.get_cached_doc("CRM Deal", crm_deal)
|
||||||
contacts = get_contacts(doc)
|
contacts = get_contacts(doc)
|
||||||
address = get_organization_address(doc.organization)
|
address = get_organization_address(doc.organization)
|
||||||
return client.post_api("erpnext.crm.frappe_crm_api.create_prospect_against_crm_deal",
|
return client.post_api(
|
||||||
|
"erpnext.crm.frappe_crm_api.create_prospect_against_crm_deal",
|
||||||
{
|
{
|
||||||
"organization": doc.organization,
|
"organization": doc.organization,
|
||||||
"lead_name": doc.lead_name,
|
"lead_name": doc.lead_name,
|
||||||
@ -147,32 +157,47 @@ def create_prospect_in_remote_site(crm_deal, erpnext_crm_settings):
|
|||||||
"annual_revenue": doc.annual_revenue,
|
"annual_revenue": doc.annual_revenue,
|
||||||
"contacts": json.dumps(contacts),
|
"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
|
"address": address.as_dict() if address else None,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
frappe.log_error(
|
frappe.log_error(
|
||||||
frappe.get_traceback(),
|
frappe.get_traceback(),
|
||||||
f"Error while creating prospect in remote site: {erpnext_crm_settings.erpnext_site_url}"
|
f"Error while creating prospect in remote site: {erpnext_crm_settings.erpnext_site_url}",
|
||||||
)
|
)
|
||||||
frappe.throw(_("Error while creating prospect in ERPNext, check error log for more details"))
|
frappe.throw(_("Error while creating prospect in ERPNext, check error log for more details"))
|
||||||
|
|
||||||
|
|
||||||
|
def get_contact(crm_deal):
|
||||||
|
doc = frappe.get_cached_doc("CRM Deal", crm_deal)
|
||||||
|
contact = None
|
||||||
|
for c in doc.contacts:
|
||||||
|
if c.is_primary:
|
||||||
|
contact = c.contact
|
||||||
|
break
|
||||||
|
|
||||||
|
return contact
|
||||||
|
|
||||||
|
|
||||||
def get_contacts(doc):
|
def get_contacts(doc):
|
||||||
contacts = []
|
contacts = []
|
||||||
for c in doc.contacts:
|
for c in doc.contacts:
|
||||||
contacts.append({
|
contacts.append(
|
||||||
"contact": c.contact,
|
{
|
||||||
"full_name": c.full_name,
|
"contact": c.contact,
|
||||||
"email": c.email,
|
"full_name": c.full_name,
|
||||||
"mobile_no": c.mobile_no,
|
"email": c.email,
|
||||||
"gender": c.gender,
|
"mobile_no": c.mobile_no,
|
||||||
"is_primary": c.is_primary,
|
"gender": c.gender,
|
||||||
})
|
"is_primary": c.is_primary,
|
||||||
|
}
|
||||||
|
)
|
||||||
return contacts
|
return contacts
|
||||||
|
|
||||||
|
|
||||||
def get_organization_address(organization):
|
def get_organization_address(organization):
|
||||||
address = frappe.db.get_value("CRM Organization", organization, "address")
|
address = frappe.db.get_value("CRM Organization", organization, "address")
|
||||||
address = frappe.get_doc("Address", address) if address else None
|
address = frappe.get_cached_doc("Address", address) if address else None
|
||||||
if not address:
|
if not address:
|
||||||
return None
|
return None
|
||||||
return {
|
return {
|
||||||
@ -188,6 +213,7 @@ def get_organization_address(organization):
|
|||||||
"pincode": address.pincode,
|
"pincode": address.pincode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def create_customer_in_erpnext(doc, method):
|
def create_customer_in_erpnext(doc, method):
|
||||||
erpnext_crm_settings = frappe.get_single("ERPNext CRM Settings")
|
erpnext_crm_settings = frappe.get_single("ERPNext CRM Settings")
|
||||||
if (
|
if (
|
||||||
@ -196,7 +222,7 @@ def create_customer_in_erpnext(doc, method):
|
|||||||
or doc.status != erpnext_crm_settings.deal_status
|
or doc.status != erpnext_crm_settings.deal_status
|
||||||
):
|
):
|
||||||
return
|
return
|
||||||
|
|
||||||
contacts = get_contacts(doc)
|
contacts = get_contacts(doc)
|
||||||
address = get_organization_address(doc.organization)
|
address = get_organization_address(doc.organization)
|
||||||
customer = {
|
customer = {
|
||||||
@ -213,26 +239,26 @@ def create_customer_in_erpnext(doc, method):
|
|||||||
}
|
}
|
||||||
if not erpnext_crm_settings.is_erpnext_in_different_site:
|
if not erpnext_crm_settings.is_erpnext_in_different_site:
|
||||||
from erpnext.crm.frappe_crm_api import create_customer
|
from erpnext.crm.frappe_crm_api import create_customer
|
||||||
|
|
||||||
create_customer(customer)
|
create_customer(customer)
|
||||||
else:
|
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")
|
frappe.publish_realtime("crm_customer_created")
|
||||||
|
|
||||||
|
|
||||||
def 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)
|
client = get_erpnext_site_client(erpnext_crm_settings)
|
||||||
try:
|
try:
|
||||||
client.post_api("erpnext.crm.frappe_crm_api.create_customer", customer)
|
client.post_api("erpnext.crm.frappe_crm_api.create_customer", customer)
|
||||||
except Exception:
|
except Exception:
|
||||||
frappe.log_error(
|
frappe.log_error(frappe.get_traceback(), "Error while creating customer in remote site")
|
||||||
frappe.get_traceback(),
|
|
||||||
"Error while creating customer in remote site"
|
|
||||||
)
|
|
||||||
frappe.throw(_("Error while creating customer in ERPNext, check error log for more details"))
|
frappe.throw(_("Error while creating customer in ERPNext, check error log for more details"))
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_crm_form_script():
|
def get_crm_form_script():
|
||||||
return """
|
return """
|
||||||
async function setupForm({ doc, call, $dialog, updateField, createToast }) {
|
async function setupForm({ doc, call, $dialog, updateField, createToast }) {
|
||||||
let actions = [];
|
let actions = [];
|
||||||
let is_erpnext_integration_enabled = await call("frappe.client.get_single_value", {doctype: "ERPNext CRM Settings", field: "enabled"});
|
let is_erpnext_integration_enabled = await call("frappe.client.get_single_value", {doctype: "ERPNext CRM Settings", field: "enabled"});
|
||||||
|
|||||||
@ -216,7 +216,7 @@ async function startCamera() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function stopStream() {
|
function stopStream() {
|
||||||
stream.value.getTracks().forEach((track) => track.stop())
|
stream.value?.getTracks()?.forEach((track) => track.stop())
|
||||||
showCamera.value = false
|
showCamera.value = false
|
||||||
cameraImage.value = null
|
cameraImage.value = null
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user