From 8267482ee97c9c9190d45646df6071b92dfc96b8 Mon Sep 17 00:00:00 2001 From: diptanilsaha Date: Fri, 27 Feb 2026 15:13:04 +0530 Subject: [PATCH] refactor(crm): type annotations for whitelisted methods --- .../doctype/contract_template/contract_template.py | 2 +- erpnext/crm/doctype/lead/lead.py | 14 ++++++++++---- erpnext/crm/doctype/opportunity/opportunity.py | 12 ++++++++---- erpnext/crm/doctype/prospect/prospect.py | 2 +- erpnext/crm/doctype/utils.py | 2 +- erpnext/crm/frappe_crm_api.py | 2 +- erpnext/crm/utils.py | 8 ++++---- 7 files changed, 26 insertions(+), 16 deletions(-) diff --git a/erpnext/crm/doctype/contract_template/contract_template.py b/erpnext/crm/doctype/contract_template/contract_template.py index 700197500fb..d2a77e426f4 100644 --- a/erpnext/crm/doctype/contract_template/contract_template.py +++ b/erpnext/crm/doctype/contract_template/contract_template.py @@ -34,7 +34,7 @@ class ContractTemplate(Document): @frappe.whitelist() -def get_contract_template(template_name, doc): +def get_contract_template(template_name: str, doc: str | dict | Document): if isinstance(doc, str): doc = json.loads(doc) diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py index 54df89ac607..83baeceaa77 100644 --- a/erpnext/crm/doctype/lead/lead.py +++ b/erpnext/crm/doctype/lead/lead.py @@ -13,6 +13,7 @@ from frappe.email.inbox import link_communication_to_document from frappe.model.document import Document from frappe.model.mapper import get_mapped_doc from frappe.utils import comma_and, get_link_to_form, has_gravatar, validate_email_address +from frappe.utils.data import DateTimeLikeObject from erpnext.accounts.party import set_taxes from erpnext.controllers.selling_controller import SellingController @@ -241,7 +242,7 @@ class Lead(SellingController, CRMNote): return frappe.db.get_value("Quotation", {"party_name": self.name, "docstatus": 1, "status": "Lost"}) @frappe.whitelist() - def create_prospect_and_contact(self, data): + def create_prospect_and_contact(self, data: dict): data = frappe._dict(data) if data.create_contact: self.create_contact() @@ -443,7 +444,12 @@ def _set_missing_values(source, target): @frappe.whitelist() -def get_lead_details(lead, posting_date=None, company=None, doctype=None): +def get_lead_details( + lead: str, + posting_date: DateTimeLikeObject | None = None, + company: str | None = None, + doctype: str | None = None, +): if not lead: return {} @@ -482,7 +488,7 @@ def get_lead_details(lead, posting_date=None, company=None, doctype=None): @frappe.whitelist() -def make_lead_from_communication(communication, ignore_communication_links=False): +def make_lead_from_communication(communication: str, ignore_communication_links: bool = False): """raise a issue from email""" doc = frappe.get_doc("Communication", communication) @@ -531,7 +537,7 @@ def get_lead_with_phone_number(number): @frappe.whitelist() -def add_lead_to_prospect(lead, prospect): +def add_lead_to_prospect(lead: str, prospect: str): prospect = frappe.get_doc("Prospect", prospect) prospect.append("leads", {"lead": lead}) prospect.save(ignore_permissions=True) diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py index 8872f0a3f98..992330f8fb5 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.py +++ b/erpnext/crm/doctype/opportunity/opportunity.py @@ -262,7 +262,9 @@ class Opportunity(TransactionBase, CRMNote): self.party_name = lead_name @frappe.whitelist() - def declare_enquiry_lost(self, lost_reasons_list, competitors, detailed_reason=None): + def declare_enquiry_lost( + self, lost_reasons_list: list, competitors: list, detailed_reason: str | None = None + ): if not self.has_active_quotation(): self.status = "Lost" self.lost_reasons = [] @@ -363,7 +365,7 @@ class Opportunity(TransactionBase, CRMNote): @frappe.whitelist() -def get_item_details(item_code): +def get_item_details(item_code: str): item = frappe.db.sql( """select item_name, stock_uom, image, description, item_group, brand from `tabItem` where name = %s""", @@ -495,7 +497,7 @@ def make_supplier_quotation(source_name: str, target_doc: str | Document | None @frappe.whitelist() -def set_multiple_status(names, status): +def set_multiple_status(names: str | list[str], status: str): names = json.loads(names) for name in names: opp = frappe.get_doc("Opportunity", name) @@ -525,7 +527,9 @@ def auto_close_opportunity(): @frappe.whitelist() -def make_opportunity_from_communication(communication, company, ignore_communication_links=False): +def make_opportunity_from_communication( + communication: str, company: str, ignore_communication_links: bool = False +): from erpnext.crm.doctype.lead.lead import make_lead_from_communication doc = frappe.get_doc("Communication", communication) diff --git a/erpnext/crm/doctype/prospect/prospect.py b/erpnext/crm/doctype/prospect/prospect.py index 85205540709..e7022323f8a 100644 --- a/erpnext/crm/doctype/prospect/prospect.py +++ b/erpnext/crm/doctype/prospect/prospect.py @@ -136,7 +136,7 @@ def make_opportunity(source_name: str, target_doc: str | Document | None = None) @frappe.whitelist() -def get_opportunities(prospect): +def get_opportunities(prospect: str): return frappe.get_all( "Opportunity", filters={"opportunity_from": "Prospect", "party_name": prospect}, diff --git a/erpnext/crm/doctype/utils.py b/erpnext/crm/doctype/utils.py index c42db1757b9..25239c2309e 100644 --- a/erpnext/crm/doctype/utils.py +++ b/erpnext/crm/doctype/utils.py @@ -2,7 +2,7 @@ import frappe @frappe.whitelist() -def get_last_interaction(contact=None, lead=None): +def get_last_interaction(contact: str | None = None, lead: str | None = None): if not contact and not lead: return diff --git a/erpnext/crm/frappe_crm_api.py b/erpnext/crm/frappe_crm_api.py index d1375165e14..a65a22e3fbc 100644 --- a/erpnext/crm/frappe_crm_api.py +++ b/erpnext/crm/frappe_crm_api.py @@ -151,7 +151,7 @@ def contact_exists(email, mobile_no): @frappe.whitelist() -def create_customer(customer_data=None): +def create_customer(customer_data: dict | None = None): if not customer_data: customer_data = frappe.form_dict diff --git a/erpnext/crm/utils.py b/erpnext/crm/utils.py index 8a6ce8311b1..c16a610c15d 100644 --- a/erpnext/crm/utils.py +++ b/erpnext/crm/utils.py @@ -144,7 +144,7 @@ def link_open_events(ref_doctype, ref_docname, doc): @frappe.whitelist() -def get_open_activities(ref_doctype, ref_docname): +def get_open_activities(ref_doctype: str, ref_docname: str): tasks = get_open_todos(ref_doctype, ref_docname) events = get_open_events(ref_doctype, ref_docname) tasks_history = get_closed_todos(ref_doctype, ref_docname) @@ -242,20 +242,20 @@ def open_leads_opportunities_based_on_todays_event(): class CRMNote(Document): @frappe.whitelist() - def add_note(self, note): + def add_note(self, note: str): self.append("notes", {"note": note, "added_by": frappe.session.user, "added_on": now()}) self.save() notify_mentions(self.doctype, self.name, note) @frappe.whitelist() - def edit_note(self, note, row_id): + def edit_note(self, note: str, row_id: str): for d in self.notes: if cstr(d.name) == row_id: d.note = note d.db_update() @frappe.whitelist() - def delete_note(self, row_id): + def delete_note(self, row_id: str): for d in self.notes: if cstr(d.name) == row_id: self.remove(d)