From 47a62c623cfbedd297ebc3be723fe7c72dcf4f18 Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Wed, 4 Feb 2015 17:33:55 +0530 Subject: [PATCH] fixes for #2655 --- erpnext/controllers/status_updater.py | 1 + .../doctype/opportunity/opportunity.js | 1 - .../doctype/opportunity/opportunity.json | 5 +- .../doctype/opportunity/opportunity.py | 107 ++++++++++-------- .../selling/doctype/quotation/quotation.py | 2 +- .../doctype/sales_order/sales_order.py | 1 + 6 files changed, 67 insertions(+), 50 deletions(-) diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py index c76ec1cd59..e16c725411 100644 --- a/erpnext/controllers/status_updater.py +++ b/erpnext/controllers/status_updater.py @@ -17,6 +17,7 @@ status_map = { ["Submitted", "eval:self.docstatus==1"], ["Lost", "eval:self.status=='Lost'"], ["Quotation", "has_quotation"], + ["Converted", "has_ordered_quotation"], ["Cancelled", "eval:self.docstatus==2"], ], "Quotation": [ diff --git a/erpnext/selling/doctype/opportunity/opportunity.js b/erpnext/selling/doctype/opportunity/opportunity.js index 2ca187814b..1180793f82 100644 --- a/erpnext/selling/doctype/opportunity/opportunity.js +++ b/erpnext/selling/doctype/opportunity/opportunity.js @@ -28,7 +28,6 @@ erpnext.selling.Opportunity = frappe.ui.form.Controller.extend({ if(!this.frm.doc.fiscal_year && sys_defaults.fiscal_year) set_multiple(cdt, cdn, { fiscal_year:sys_defaults.fiscal_year }); - if(this.frm.doc.customer && !this.frm.doc.customer_name) cur_frm.cscript.customer(this.frm.doc); this.setup_queries(); }, diff --git a/erpnext/selling/doctype/opportunity/opportunity.json b/erpnext/selling/doctype/opportunity/opportunity.json index 96e9773527..980de56db7 100644 --- a/erpnext/selling/doctype/opportunity/opportunity.json +++ b/erpnext/selling/doctype/opportunity/opportunity.json @@ -74,9 +74,10 @@ "read_only": 0 }, { - "depends_on": "eval:doc.customer || doc.lead", + "depends_on": "", "fieldname": "customer_name", "fieldtype": "Data", + "hidden": 1, "label": "Customer / Lead Name", "permlevel": 0, "print_hide": 0, @@ -390,7 +391,7 @@ "icon": "icon-info-sign", "idx": 1, "is_submittable": 1, - "modified": "2015-02-05 05:11:41.732687", + "modified": "2015-02-05 05:11:41.732687", "modified_by": "Administrator", "module": "Selling", "name": "Opportunity", diff --git a/erpnext/selling/doctype/opportunity/opportunity.py b/erpnext/selling/doctype/opportunity/opportunity.py index 001ba3bf64..31af3cdd26 100644 --- a/erpnext/selling/doctype/opportunity/opportunity.py +++ b/erpnext/selling/doctype/opportunity/opportunity.py @@ -10,6 +10,56 @@ from frappe.model.mapper import get_mapped_doc from erpnext.utilities.transaction_base import TransactionBase class Opportunity(TransactionBase): + + def validate(self): + self._prev = frappe._dict({ + "contact_date": frappe.db.get_value("Opportunity", self.name, "contact_date") if \ + (not cint(self.get("__islocal"))) else None, + "contact_by": frappe.db.get_value("Opportunity", self.name, "contact_by") if \ + (not cint(self.get("__islocal"))) else None, + }) + + if not self.enquiry_from: + frappe.throw(_("Opportunity From field is mandatory")) + + self.set_status() + self.validate_item_details() + self.validate_uom_is_integer("uom", "qty") + self.validate_lead_cust() + self.validate_cust_name() + + from erpnext.accounts.utils import validate_fiscal_year + validate_fiscal_year(self.transaction_date, self.fiscal_year, "Opportunity Date") + + def on_submit(self): + if self.lead: + frappe.get_doc("Lead", self.lead).set_status(update=True) + + def on_cancel(self): + if self.has_quotation(): + frappe.throw(_("Cannot Cancel Opportunity as Quotation Exists")) + self.set_status(update=True) + + def declare_enquiry_lost(self,arg): + if not self.has_quotation(): + frappe.db.set(self, 'status', 'Lost') + frappe.db.set(self, 'order_lost_reason', arg) + else: + frappe.throw(_("Cannot declare as lost, because Quotation has been made.")) + + def on_trash(self): + self.delete_events() + + def has_quotation(self): + return frappe.db.get_value("Quotation Item", {"prevdoc_docname": self.name, "docstatus": 1}) + + def has_ordered_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 = 'Ordered'""", self.name) + + def validate_cust_name(self): + self.customer_name = self.customer or self.lead + def get_item_details(self, item_code): item = frappe.db.sql("""select item_name, stock_uom, description_html, description, item_group, brand from `tabItem` where name = %s""", item_code, as_dict=1) @@ -80,52 +130,17 @@ class Opportunity(TransactionBase): frappe.throw(_("Items required")) def validate_lead_cust(self): - if self.enquiry_from == 'Lead' and not self.lead: - frappe.throw(_("Lead must be set if Opportunity is made from Lead")) - elif self.enquiry_from == 'Customer' and not self.customer: - msgprint("Customer is mandatory if 'Opportunity From' is selected as Customer", raise_exception=1) - - def validate(self): - self._prev = frappe._dict({ - "contact_date": frappe.db.get_value("Opportunity", self.name, "contact_date") if \ - (not cint(self.get("__islocal"))) else None, - "contact_by": frappe.db.get_value("Opportunity", self.name, "contact_by") if \ - (not cint(self.get("__islocal"))) else None, - }) - - if not self.enquiry_from: - frappe.throw(_("Opportunity From field is mandatory")) - - self.set_status() - self.validate_item_details() - self.validate_uom_is_integer("uom", "qty") - self.validate_lead_cust() - - from erpnext.accounts.utils import validate_fiscal_year - validate_fiscal_year(self.transaction_date, self.fiscal_year, "Opportunity Date") - - def on_submit(self): - if self.lead: - frappe.get_doc("Lead", self.lead).set_status(update=True) - - def on_cancel(self): - if self.has_quotation(): - frappe.throw(_("Cannot Cancel Opportunity as Quotation Exists")) - self.set_status(update=True) - - def declare_enquiry_lost(self,arg): - if not self.has_quotation(): - frappe.db.set(self, 'status', 'Lost') - frappe.db.set(self, 'order_lost_reason', arg) - else: - frappe.throw(_("Cannot declare as lost, because Quotation has been made.")) - - def on_trash(self): - self.delete_events() - - def has_quotation(self): - return frappe.db.get_value("Quotation Item", {"prevdoc_docname": self.name, "docstatus": 1}) - + if self.enquiry_from == 'Lead': + if not self.lead: + frappe.throw(_("Lead must be set if Opportunity is made from Lead")) + else: + self.customer = None + elif self.enquiry_from == 'Customer': + if not self.customer: + msgprint("Customer is mandatory if 'Opportunity From' is selected as Customer", raise_exception=1) + else: + self.lead = None + @frappe.whitelist() def make_quotation(source_name, target_doc=None): def set_missing_values(source, target): diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index e4d7cc8db5..10a59f4ab7 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -24,7 +24,7 @@ class Quotation(SellingController): def has_sales_order(self): return frappe.db.get_value("Sales Order Item", {"prevdoc_docname": self.name, "docstatus": 1}) - + def validate_for_items(self): chk_dupl_itm = [] for d in self.get('items'): diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index ec3f03888a..d4b92e4f59 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -134,6 +134,7 @@ class SalesOrder(SellingController): frappe.throw(_("Quotation {0} is cancelled").format(quotation)) doc.set_status(update=True) + doc.update_opportunity() def on_submit(self): super(SalesOrder, self).on_submit()