From fcaaa29a58bf9d94cff45d9b531bc3d9b8c1aaec Mon Sep 17 00:00:00 2001 From: Alec Ruiz-Ramon Date: Thu, 9 Jun 2016 14:19:51 -0400 Subject: [PATCH] Status updater for quotation/lost to lead, quotation lost to oppt, and to set conversion as priority in lead cleanup squashed --- erpnext/controllers/status_updater.py | 6 ++++-- erpnext/crm/doctype/lead/lead.json | 2 +- erpnext/crm/doctype/lead/lead.py | 16 ++++++++++++++++ erpnext/crm/doctype/opportunity/opportunity.py | 8 ++++++-- erpnext/selling/doctype/quotation/quotation.py | 11 +++++++++++ 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py index 254d9a6fa5..e791d81a22 100644 --- a/erpnext/controllers/status_updater.py +++ b/erpnext/controllers/status_updater.py @@ -13,15 +13,17 @@ def validate_status(status, options): status_map = { "Lead": [ - ["Converted", "has_customer"], + ["Lost Quotation", "lost_quotation"], ["Opportunity", "has_opportunity"], + ["Quotation", "has_quotation"], + ["Converted", "has_customer"], ], "Opportunity": [ ["Quotation", "has_quotation"], ["Converted", "has_ordered_quotation"], ["Lost", "eval:self.status=='Lost'"], + ["Lost", "has_lost_quotation"], ["Closed", "eval:self.status=='Closed'"] - ], "Quotation": [ ["Draft", None], diff --git a/erpnext/crm/doctype/lead/lead.json b/erpnext/crm/doctype/lead/lead.json index 7cd9d60992..345dc6eeff 100644 --- a/erpnext/crm/doctype/lead/lead.json +++ b/erpnext/crm/doctype/lead/lead.json @@ -181,7 +181,7 @@ "no_copy": 1, "oldfieldname": "status", "oldfieldtype": "Select", - "options": "Lead\nOpen\nReplied\nOpportunity\nInterested\nConverted\nDo Not Contact", + "options": "Lead\nOpen\nReplied\nOpportunity\nQuotation\nLost Quotation\nInterested\nConverted\nDo Not Contact", "permlevel": 0, "print_hide": 0, "print_hide_if_no_value": 0, diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py index 0c3652f7eb..941223a0e2 100644 --- a/erpnext/crm/doctype/lead/lead.py +++ b/erpnext/crm/doctype/lead/lead.py @@ -80,6 +80,22 @@ class Lead(SellingController): def has_opportunity(self): return frappe.db.get_value("Opportunity", {"lead": self.name, "status": ["!=", "Lost"]}) + def has_quotation(self): + return frappe.db.get_value( + "Quotation", { + "lead": self.name, + "status": ["!=", "Lost"], + "status": ["!=", "Cancelled"] + }) + + def lost_quotation(self): + return frappe.db.get_value( + "Quotation", { + "lead": self.name, + "status": ["=", "Lost"] + } + ) + @frappe.whitelist() def make_customer(source_name, target_doc=None): return _make_customer(source_name, target_doc) diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py index b977e26839..33faa7bed5 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.py +++ b/erpnext/crm/doctype/opportunity/opportunity.py @@ -48,8 +48,8 @@ class Opportunity(TransactionBase): if not lead_name: sender_name = get_fullname(self.contact_email) if sender_name == self.contact_email: - sender_name = None - + sender_name = None + account = '' email_name = self.contact_email[0:self.contact_email.index('@')] email_split = email_name.split('.') @@ -84,6 +84,10 @@ class Opportunity(TransactionBase): return frappe.db.sql("""select q.name from `tabQuotation` q, `tabQuotation Item` qi where q.name = qi.parent and q.docstatus=1 and qi.prevdoc_docname =%s and q.status = 'Ordered'""", self.name) + def has_lost_quotation(self): + return frappe.db.sql("""select q.name from `tabQuotation` q, `tabQuotation Item` qi + where q.name = qi.parent and q.docstatus=1 and qi.prevdoc_docname =%s and q.status = 'Lost'""", self.name) + def validate_cust_name(self): if self.customer: self.customer_name = frappe.db.get_value("Customer", self.customer, "customer_name") diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index 6ed188893d..9840e8eaec 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -13,9 +13,14 @@ form_grid_templates = { } class Quotation(SellingController): + def after_insert(self): + self.update_lead() + def validate(self): super(Quotation, self).validate() self.set_status() + self.update_opportunity() + self.update_lead() self.validate_order_type() self.validate_uom_is_integer("stock_uom", "qty") self.validate_quotation_to() @@ -35,6 +40,10 @@ class Quotation(SellingController): elif self.lead: self.quotation_to = "Lead" + def update_lead(self): + if self.lead: + frappe.get_doc("Lead", self.lead).set_status(update=True) + def update_opportunity(self): for opportunity in list(set([d.prevdoc_docname for d in self.get("items")])): if opportunity: @@ -45,6 +54,8 @@ class Quotation(SellingController): frappe.db.set(self, 'status', 'Lost') frappe.db.set(self, 'order_lost_reason', arg) self.update_opportunity() + self.update_lead() + else: frappe.throw(_("Cannot set as Lost as Sales Order is made."))