diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py index da09e26dd5..096bb2df71 100644 --- a/erpnext/controllers/status_updater.py +++ b/erpnext/controllers/status_updater.py @@ -14,15 +14,17 @@ def validate_status(status, options): status_map = { "Lead": [ - ["Converted", "has_customer"], + ["Lost Quotation", "has_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 d4a02e6342..99d41af4a1 100644 --- a/erpnext/crm/doctype/lead/lead.json +++ b/erpnext/crm/doctype/lead/lead.json @@ -203,7 +203,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, @@ -1014,7 +1014,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-11-07 05:16:25.037080", + "modified": "2016-12-15 05:16:25.037080", "modified_by": "Administrator", "module": "CRM", "name": "Lead", diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py index 18c0db44e0..ee3f96f15b 100644 --- a/erpnext/crm/doctype/lead/lead.py +++ b/erpnext/crm/doctype/lead/lead.py @@ -82,6 +82,21 @@ 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, + "docstatus": 1, + "status": ["!=", "Lost"] + + }) + + def has_lost_quotation(self): + return frappe.db.get_value("Quotation", { + "lead": self.name, + "docstatus": 1, + "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 6ee9003608..91118307e3 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.py +++ b/erpnext/crm/doctype/opportunity/opportunity.py @@ -91,6 +91,14 @@ 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..56a365edc6 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -16,6 +16,7 @@ class Quotation(SellingController): def validate(self): super(Quotation, self).validate() self.set_status() + self.update_opportunity() self.validate_order_type() self.validate_uom_is_integer("stock_uom", "qty") self.validate_quotation_to() @@ -35,6 +36,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 +50,7 @@ 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.")) @@ -60,11 +66,13 @@ class Quotation(SellingController): #update enquiry status self.update_opportunity() + self.update_lead() def on_cancel(self): #update enquiry status self.set_status(update=True) self.update_opportunity() + self.update_lead() def print_other_charges(self,docname): print_lst = []