diff --git a/controllers/selling_controller.py b/controllers/selling_controller.py index f1117ed177..2816524160 100644 --- a/controllers/selling_controller.py +++ b/controllers/selling_controller.py @@ -14,7 +14,10 @@ class SellingController(StockController): def onload_post_render(self): # contact, address, item details and pos details (if applicable) self.set_missing_values() - + + def get_sender(self, comm): + return webnotes.conn.get_value('Sales Email Settings', None, 'email_id') + def set_missing_values(self, for_validate=False): super(SellingController, self).set_missing_values(for_validate) diff --git a/controllers/status_updater.py b/controllers/status_updater.py index 070f200276..07b812a7dc 100644 --- a/controllers/status_updater.py +++ b/controllers/status_updater.py @@ -8,6 +8,51 @@ from webnotes import msgprint from webnotes.model.controller import DocListController +status_map = { + "Contact": [ + ["Replied", "communication_sent"], + ["Open", "communication_received"] + ], + "Job Applicant": [ + ["Replied", "communication_sent"], + ["Open", "communication_received"] + ], + "Lead": [ + ["Replied", "communication_sent"], + ["Converted", "has_customer"], + ["Opportunity", "has_opportunity"], + ["Open", "communication_received"], + ], + "Opportunity": [ + ["Draft", None], + ["Submitted", "eval:self.doc.docstatus==1"], + ["Lost", "eval:self.doc.status=='Lost'"], + ["Quotation", "has_quotation"], + ["Replied", "communication_sent"], + ["Cancelled", "eval:self.doc.docstatus==2"], + ["Open", "communication_received"], + ], + "Quotation": [ + ["Draft", None], + ["Submitted", "eval:self.doc.docstatus==1"], + ["Lost", "eval:self.doc.status=='Lost'"], + ["Ordered", "has_sales_order"], + ["Replied", "communication_sent"], + ["Cancelled", "eval:self.doc.docstatus==2"], + ["Open", "communication_received"], + ], + "Sales Order": [ + ["Draft", None], + ["Submitted", "eval:self.doc.docstatus==1"], + ["Stopped", "eval:self.doc.status=='Stopped'"], + ["Cancelled", "eval:self.doc.docstatus==2"], + ], + "Support Ticket": [ + ["Replied", "communication_sent"], + ["Open", "communication_received"] + ], +} + class StatusUpdater(DocListController): """ Updates the status of the calling records @@ -20,6 +65,39 @@ class StatusUpdater(DocListController): self.update_qty() self.validate_qty() + def set_status(self, update=False): + if self.doc.get("__islocal"): + return + + if self.doc.doctype in status_map.keys(): + for s in status_map[self.doc.doctype].reverse(): + if not s[1]: + self.doc.status = s[0] + break + elif s[1].startwith("eval:"): + if eval(s[1][5:]): + self.doc.status = s[0] + break + elif getattr(self, s[1])(): + self.doc.status = s[0] + break + + if update: + webnotes.conn.set_value(self.doc.doctype, self.doc.name, "status", self.doc.status) + + def on_communication(self): + self.set_status(update=True) + + def communication_received(self): + last_comm = self.doclist.get({"doctype":"Communication"})[-1] + if last_comm: + return last_comm.sent_or_received == "Received" + + def communication_sent(self): + last_comm = self.doclist.get({"doctype":"Communication"})[-1] + if last_comm: + return last_comm.sent_or_received == "Sent" + def validate_qty(self): """ Validates qty at row level diff --git a/hr/doctype/job_applicant/job_applicant.py b/hr/doctype/job_applicant/job_applicant.py index 9bf1b967e7..0ab4ba8612 100644 --- a/hr/doctype/job_applicant/job_applicant.py +++ b/hr/doctype/job_applicant/job_applicant.py @@ -11,14 +11,9 @@ from webnotes.utils import extract_email_id class DocType(TransactionBase): def __init__(self, d, dl): self.doc, self.doclist = d, dl - + def get_sender(self, comm): - return webnotes.conn.get_value('Jobs Email Settings',None,'email_id') - - def on_communication(self, comm): - if webnotes.conn.get_value("Profile", extract_email_id(comm.sender), "user_type")=="System User": - status = "Replied" - else: - status = "Open" - - webnotes.conn.set(self.doc, 'status', status) \ No newline at end of file + return webnotes.conn.get_value('Jobs Email Settings',None,'email_id') + + def validate(self): + self.set_status() \ No newline at end of file diff --git a/patches/october_2013/p02_set_communication_status.py b/patches/october_2013/p02_set_communication_status.py new file mode 100644 index 0000000000..8360fe6cee --- /dev/null +++ b/patches/october_2013/p02_set_communication_status.py @@ -0,0 +1,9 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import webnotes + +def execute(): + webnotes.conn.sql("""update tabCommunication + set sent_or_received= if(ifnull(recipients, '')='', "Received", "Sent")""") \ No newline at end of file diff --git a/patches/october_2013/p03_crm_update_status.py b/patches/october_2013/p03_crm_update_status.py new file mode 100644 index 0000000000..e5b434ce1f --- /dev/null +++ b/patches/october_2013/p03_crm_update_status.py @@ -0,0 +1,32 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import webnotes + +# reason field + +def execute(): + change_map = { + "Lead": [ + ["Lead Lost", "Lead"], + ["Not interested", "Do Not Contact"], + ["Opportunity Made", "Opportunity"], + ["Contacted", "Replied"], + ["Attempted to Contact", "Replied"], + ["Contact in Future", "Interested"], + ], + "Opportunity": [ + ["Quotation Sent", "Quotation"], + ["Order Confirmed", "Quotation"], + ["Opportunity Lost", "Lost"], + ], + "Quotation": [ + ["Order Confirmed", "Ordered"], + ["Order Lost", "Lost"] + ], + "Support Ticket": [ + ["Waiting for Customer", "Replied"], + ["To Reply", "Open"], + ] + } \ No newline at end of file diff --git a/patches/patch_list.py b/patches/patch_list.py index e19afdaf5c..1596a2870b 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -221,4 +221,6 @@ patch_list = [ "patches.september_2013.p05_fix_customer_in_pos", "patches.october_2013.fix_is_cancelled_in_sle", "patches.october_2013.p01_update_delivery_note_prevdocs", + "patches.october_2013.p02_set_communication_status", + "patches.october_2013.p03_crm_update_status", ] \ No newline at end of file diff --git a/selling/doctype/lead/lead.py b/selling/doctype/lead/lead.py index 7a37446bf1..b42a380758 100644 --- a/selling/doctype/lead/lead.py +++ b/selling/doctype/lead/lead.py @@ -26,24 +26,9 @@ class DocType(SellingController): customer = webnotes.conn.get_value("Customer", {"lead_name": self.doc.name}) if customer: self.doc.fields["__is_customer"] = customer - - def on_communication(self, comm): - if comm.sender == self.get_sender(comm) or \ - webnotes.conn.get_value("Profile", extract_email_id(comm.sender), "user_type")=="System User": - status = "Replied" - else: - status = "Open" - - webnotes.conn.set(self.doc, 'status', status) - - def check_status(self): - chk = webnotes.conn.sql("select status from `tabLead` where name=%s", self.doc.name) - chk = chk and chk[0][0] or '' - return cstr(chk) def validate(self): - if self.doc.status == 'Lead Lost' and not self.doc.order_lost_reason: - webnotes.throw("Please Enter Lost Reason under More Info section") + self.set_status() if self.doc.source == 'Campaign' and not self.doc.campaign_name and session['user'] != 'Guest': webnotes.throw("Please specify campaign name") @@ -75,14 +60,18 @@ class DocType(SellingController): webnotes.msgprint(_("""Email Id must be unique, already exists for: """) + \ ", ".join(items), raise_exception=True) - def get_sender(self, comm): - return webnotes.conn.get_value('Sales Email Settings',None,'email_id') - def on_trash(self): webnotes.conn.sql("""update `tabSupport Ticket` set lead='' where lead=%s""", self.doc.name) self.delete_events() + + def has_customer(self): + return webnotes.conn.get_value("Customer", {"lead_name": self.doc.name}) + + def has_opportunity(self): + return webnotes.conn.get_value("Opportunity", {"lead": self.doc.name, "docstatus": 1, + "status": ["!=", "Lost"]}) @webnotes.whitelist() def make_customer(source_name, target_doclist=None): diff --git a/selling/doctype/lead/lead.txt b/selling/doctype/lead/lead.txt index 6044f7994b..4f481b0a5e 100644 --- a/selling/doctype/lead/lead.txt +++ b/selling/doctype/lead/lead.txt @@ -2,7 +2,7 @@ { "creation": "2013-04-10 11:45:37", "docstatus": 0, - "modified": "2013-10-02 14:24:30", + "modified": "2013-10-03 17:24:33", "modified_by": "Administrator", "owner": "Administrator" }, @@ -102,7 +102,7 @@ "fieldtype": "Column Break" }, { - "default": "Open", + "default": "Lead", "doctype": "DocField", "fieldname": "status", "fieldtype": "Select", @@ -112,7 +112,7 @@ "no_copy": 1, "oldfieldname": "status", "oldfieldtype": "Select", - "options": "\nOpen\nReplied\nAttempted to Contact\nContact in Future\nContacted\nOpportunity Made\nInterested\nNot interested\nLead Lost\nConverted\nPassive", + "options": "Lead\nOpen\nReplied\nOpportunity\nInterested\nConverted\nDo Not Contact", "reqd": 1, "search_index": 1 }, @@ -334,18 +334,6 @@ "oldfieldtype": "Column Break", "width": "50%" }, - { - "allow_on_submit": 0, - "depends_on": "eval:doc.status == 'Lead Lost'", - "doctype": "DocField", - "fieldname": "order_lost_reason", - "fieldtype": "Link", - "hidden": 0, - "label": "Lost Reason", - "oldfieldname": "order_lost_reason", - "oldfieldtype": "Link", - "options": "Quotation Lost Reason" - }, { "allow_on_submit": 0, "description": "Your sales person who will contact the lead in future", diff --git a/selling/doctype/opportunity/opportunity.js b/selling/doctype/opportunity/opportunity.js index 25f28bf3fb..d2b866cfbb 100644 --- a/selling/doctype/opportunity/opportunity.js +++ b/selling/doctype/opportunity/opportunity.js @@ -101,20 +101,13 @@ $.extend(cur_frm.cscript, new erpnext.selling.Opportunity({frm: cur_frm})); cur_frm.cscript.refresh = function(doc, cdt, cdn){ erpnext.hide_naming_series(); - - cur_frm.dashboard.reset(doc); - if(!doc.__islocal) { - if(doc.status=="Converted" || doc.status=="Order Confirmed") { - cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-success", "icon-ok-sign"); - } else if(doc.status=="Opportunity Lost") { - cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-danger", "icon-exclamation-sign"); - } - } cur_frm.clear_custom_buttons(); - if(doc.docstatus === 1 && doc.status!=="Opportunity Lost") { + if(doc.docstatus === 1 && doc.status!=="Lost") { cur_frm.add_custom_button('Create Quotation', cur_frm.cscript.create_quotation); - cur_frm.add_custom_button('Opportunity Lost', cur_frm.cscript['Declare Opportunity Lost']); + if(doc.status!=="Quotation") { + cur_frm.add_custom_button('Opportunity Lost', cur_frm.cscript['Declare Opportunity Lost']); + } cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms); } diff --git a/selling/doctype/opportunity/opportunity.py b/selling/doctype/opportunity/opportunity.py index e0be5fa957..e63ce6b060 100644 --- a/selling/doctype/opportunity/opportunity.py +++ b/selling/doctype/opportunity/opportunity.py @@ -6,7 +6,7 @@ import webnotes from webnotes.utils import cstr, getdate, cint from webnotes.model.bean import getlist -from webnotes import msgprint +from webnotes import msgprint, _ from utilities.transaction_base import TransactionBase @@ -67,7 +67,8 @@ class DocType(TransactionBase): 'email_id' : contact and contact[0]['email_id'] or '' } return ret - + + def on_update(self): # Add to calendar if self.doc.contact_date and self.doc.contact_date_ref != self.doc.contact_date: @@ -120,6 +121,7 @@ class DocType(TransactionBase): msgprint("Customer is mandatory if 'Opportunity From' is selected as Customer", raise_exception=1) def validate(self): + self.set_status() self.set_last_contact_date() self.validate_item_details() self.validate_uom_is_integer("uom", "qty") @@ -127,42 +129,29 @@ class DocType(TransactionBase): from accounts.utils import validate_fiscal_year validate_fiscal_year(self.doc.transaction_date, self.doc.fiscal_year, "Opportunity Date") - self.doc.status = "Draft" def on_submit(self): - webnotes.conn.set(self.doc, 'status', 'Submitted') - if self.doc.lead and webnotes.conn.get_value("Lead", self.doc.lead, "status")!="Converted": - webnotes.conn.set_value("Lead", self.doc.lead, "status", "Opportunity Made") + if self.doc.lead: + webnotes.bean("Lead", self.doc.lead).get_controller().set_status(update=True) def on_cancel(self): - chk = webnotes.conn.sql("select t1.name from `tabQuotation` t1, `tabQuotation Item` t2 where t2.parent = t1.name and t1.docstatus=1 and (t1.status!='Order Lost' and t1.status!='Cancelled') and t2.prevdoc_docname = %s",self.doc.name) - if chk: - msgprint("Quotation No. "+cstr(chk[0][0])+" is submitted against this Opportunity. Thus can not be cancelled.") - raise Exception - else: - webnotes.conn.set(self.doc, 'status', 'Cancelled') - if self.doc.lead and webnotes.conn.get_value("Lead", self.doc.lead, - "status")!="Converted": - if webnotes.conn.get_value("Communication", {"parent": self.doc.lead}): - status = "Contacted" - else: - status = "Open" - - webnotes.conn.set_value("Lead", self.doc.lead, "status", status) + if self.has_quotation(): + webnotes.throw(_("Cannot Cancel Opportunity as Quotation Exists")) + self.set_status(update=True) def declare_enquiry_lost(self,arg): - chk = webnotes.conn.sql("select t1.name from `tabQuotation` t1, `tabQuotation Item` t2 where t2.parent = t1.name and t1.docstatus=1 and (t1.status!='Order Lost' and t1.status!='Cancelled') and t2.prevdoc_docname = %s",self.doc.name) - if chk: - msgprint("Quotation No. "+cstr(chk[0][0])+" is submitted against this Opportunity. Thus 'Opportunity Lost' can not be declared against it.") - raise Exception - else: - webnotes.conn.set(self.doc, 'status', 'Opportunity Lost') + if not self.has_quotation(): + webnotes.conn.set(self.doc, 'status', 'Lost') webnotes.conn.set(self.doc, 'order_lost_reason', arg) - return 'true' + else: + webnotes.throw(_("Cannot declare as lost, because Quotation has been made.")) def on_trash(self): self.delete_events() + def has_quotation(self): + return webnotes.conn.get_value("Quotation Item", {"prevdoc_docname": self.doc.name, "docstatus": 1}) + @webnotes.whitelist() def make_quotation(source_name, target_doclist=None): from webnotes.model.mapper import get_mapped_doclist diff --git a/selling/doctype/opportunity/opportunity.txt b/selling/doctype/opportunity/opportunity.txt index 21eae5f723..02caea0a6d 100644 --- a/selling/doctype/opportunity/opportunity.txt +++ b/selling/doctype/opportunity/opportunity.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-07 18:50:30", "docstatus": 0, - "modified": "2013-10-02 14:24:30", + "modified": "2013-10-03 16:30:58", "modified_by": "Administrator", "owner": "Administrator" }, @@ -126,7 +126,7 @@ "no_copy": 1, "oldfieldname": "status", "oldfieldtype": "Select", - "options": "\nDraft\nSubmitted\nQuotation Sent\nOrder Confirmed\nOpportunity Lost\nCancelled", + "options": "Draft\nSubmitted\nQuotation\nLost\nCancelled\nReplied\nOpen", "read_only": 1, "reqd": 1 }, @@ -350,18 +350,6 @@ "options": "Campaign", "read_only": 0 }, - { - "depends_on": "eval:!doc.__islocal", - "doctype": "DocField", - "fieldname": "order_lost_reason", - "fieldtype": "Small Text", - "label": "Quotation Lost Reason", - "no_copy": 1, - "oldfieldname": "order_lost_reason", - "oldfieldtype": "Small Text", - "read_only": 1, - "report_hide": 0 - }, { "doctype": "DocField", "fieldname": "company", @@ -376,6 +364,15 @@ "reqd": 1, "search_index": 1 }, + { + "depends_on": "eval:!doc.__islocal", + "doctype": "DocField", + "fieldname": "order_lost_reason", + "fieldtype": "Text", + "label": "Lost Reason", + "no_copy": 1, + "read_only": 1 + }, { "doctype": "DocField", "fieldname": "column_break2", diff --git a/selling/doctype/quotation/quotation.js b/selling/doctype/quotation/quotation.js index e20308f18e..05feed012b 100644 --- a/selling/doctype/quotation/quotation.js +++ b/selling/doctype/quotation/quotation.js @@ -24,19 +24,10 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({ }, refresh: function(doc, dt, dn) { this._super(doc, dt, dn); - - cur_frm.dashboard.reset(doc); - if(!doc.__islocal) { - if(doc.status=="Converted" || doc.status=="Order Confirmed") { - cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-success", "icon-ok-sign"); - } else if(doc.status==="Order Lost") { - cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-danger", "icon-exclamation-sign"); - } - } - if(doc.docstatus == 1 && doc.status!=='Order Lost') { + if(doc.docstatus == 1 && doc.status!=='Lost') { cur_frm.add_custom_button('Make Sales Order', cur_frm.cscript['Make Sales Order']); - if(doc.status!=="Order Confirmed") { + if(doc.status!=="Ordered") { cur_frm.add_custom_button('Set as Lost', cur_frm.cscript['Declare Order Lost']); } cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms); diff --git a/selling/doctype/quotation/quotation.py b/selling/doctype/quotation/quotation.py index 8a3bef10e9..697f805a2c 100644 --- a/selling/doctype/quotation/quotation.py +++ b/selling/doctype/quotation/quotation.py @@ -47,6 +47,11 @@ class DocType(SellingController): if not doc.fields.get(r): doc.fields[r] = res[r] + + def has_sales_order(self): + return webnotes.conn.get_value("Sales Order Item", {"prevdoc_docname": self.doc.name, "docstatus": 1}) + + # Re-calculates Basic Rate & amount based on Price List Selected # -------------------------------------------------------------- def get_adj_percent(self, arg=''): @@ -108,13 +113,7 @@ class DocType(SellingController): def validate(self): super(DocType, self).validate() - import utilities - if not self.doc.status: - self.doc.status = "Draft" - else: - utilities.validate_status(self.doc.status, ["Draft", "Submitted", - "Order Confirmed", "Order Lost", "Cancelled"]) - + self.set_status() self.set_last_contact_date() self.validate_order_type() self.validate_for_items() @@ -125,42 +124,22 @@ class DocType(SellingController): sales_com_obj.check_active_sales_items(self) sales_com_obj.validate_max_discount(self,'quotation_details') sales_com_obj.check_conversion_rate(self) - - - def on_update(self): - # Set Quotation Status - webnotes.conn.set(self.doc, 'status', 'Draft') - + #update enquiry #------------------ - def update_enquiry(self, flag): - prevdoc='' - for d in getlist(self.doclist, 'quotation_details'): - if d.prevdoc_docname: - prevdoc = d.prevdoc_docname - - if prevdoc: - if flag == 'submit': #on submit - webnotes.conn.sql("update `tabOpportunity` set status = 'Quotation Sent' where name = %s", prevdoc) - elif flag == 'cancel': #on cancel - webnotes.conn.sql("update `tabOpportunity` set status = 'Open' where name = %s", prevdoc) - elif flag == 'order lost': #order lost - webnotes.conn.sql("update `tabOpportunity` set status = 'Opportunity Lost' where name=%s", prevdoc) - elif flag == 'order confirm': #order confirm - webnotes.conn.sql("update `tabOpportunity` set status='Order Confirmed' where name=%s", prevdoc) + def update_opportunity(self): + for opportunity in self.doclist.get_distinct_values("prevdoc_docname"): + webnotes.bean("Opportunity", opportunity).get_controller().set_status(update=True) # declare as order lost #------------------------- def declare_order_lost(self, arg): - chk = webnotes.conn.sql("select t1.name from `tabSales Order` t1, `tabSales Order Item` t2 where t2.parent = t1.name and t1.docstatus=1 and t2.prevdoc_docname = %s",self.doc.name) - if chk: - msgprint("Sales Order No. "+cstr(chk[0][0])+" is submitted against this Quotation. Thus 'Order Lost' can not be declared against it.") - raise Exception - else: - webnotes.conn.set(self.doc, 'status', 'Order Lost') + if not self.has_sales_order(): + webnotes.conn.set(self.doc, 'status', 'Lost') webnotes.conn.set(self.doc, 'order_lost_reason', arg) - self.update_enquiry('order lost') - return 'true' + self.update_opportunity() + else: + webnotes.throw(_("Cannot set as Lost as Sales Order is made.")) #check if value entered in item table #-------------------------------------- @@ -176,21 +155,17 @@ class DocType(SellingController): # Check for Approving Authority get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total, self) - - # Set Quotation Status - webnotes.conn.set(self.doc, 'status', 'Submitted') - + #update enquiry status - self.update_enquiry('submit') + self.update_opportunity() # ON CANCEL # ========================================================================== def on_cancel(self): #update enquiry status - self.update_enquiry('cancel') - - webnotes.conn.set(self.doc,'status','Cancelled') + self.set_status() + self.update_opportunity() # Print other charges # =========================================================================== @@ -202,6 +177,7 @@ class DocType(SellingController): lst1.append(d.total) print_lst.append(lst1) return print_lst + @webnotes.whitelist() def make_sales_order(source_name, target_doclist=None): diff --git a/selling/doctype/quotation/quotation.txt b/selling/doctype/quotation/quotation.txt index 200627f794..8a8b24ba44 100644 --- a/selling/doctype/quotation/quotation.txt +++ b/selling/doctype/quotation/quotation.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 19:29:08", "docstatus": 0, - "modified": "2013-10-02 14:24:35", + "modified": "2013-10-03 16:31:55", "modified_by": "Administrator", "owner": "Administrator" }, @@ -734,7 +734,7 @@ "no_copy": 1, "oldfieldname": "status", "oldfieldtype": "Select", - "options": "\nDraft\nSubmitted\nOrder Confirmed\nOrder Lost\nCancelled", + "options": "Draft\nSubmitted\nOrdered\nLost\nCancelled", "print_hide": 1, "read_only": 1, "reqd": 1, diff --git a/selling/doctype/sales_order/sales_order.js b/selling/doctype/sales_order/sales_order.js index 0c261793e1..bf23b9cb9d 100644 --- a/selling/doctype/sales_order/sales_order.js +++ b/selling/doctype/sales_order/sales_order.js @@ -66,7 +66,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( source_doctype: "Quotation", get_query_filters: { docstatus: 1, - status: ["!=", "Order Lost"], + status: ["!=", "Lost"], order_type: cur_frm.doc.order_type, customer: cur_frm.doc.customer || undefined, company: cur_frm.doc.company diff --git a/selling/doctype/sales_order/sales_order.py b/selling/doctype/sales_order/sales_order.py index 8fc728fccd..d3ac7ad339 100644 --- a/selling/doctype/sales_order/sales_order.py +++ b/selling/doctype/sales_order/sales_order.py @@ -165,36 +165,20 @@ class DocType(SellingController): }) - def check_prev_docstatus(self): - for d in getlist(self.doclist, 'sales_order_details'): - cancel_quo = webnotes.conn.sql("select name from `tabQuotation` where docstatus = 2 and name = '%s'" % d.prevdoc_docname) - if cancel_quo: - msgprint("Quotation :" + cstr(cancel_quo[0][0]) + " is already cancelled !") - raise Exception , "Validation Error. " - def update_enquiry_status(self, prevdoc, flag): enq = webnotes.conn.sql("select t2.prevdoc_docname from `tabQuotation` t1, `tabQuotation Item` t2 where t2.parent = t1.name and t1.name=%s", prevdoc) if enq: webnotes.conn.sql("update `tabOpportunity` set status = %s where name=%s",(flag,enq[0][0])) - def update_prevdoc_status(self, flag): - for d in getlist(self.doclist, 'sales_order_details'): - if d.prevdoc_docname: - if flag=='submit': - webnotes.conn.sql("update `tabQuotation` set status = 'Order Confirmed' where name=%s",d.prevdoc_docname) - - #update enquiry - self.update_enquiry_status(d.prevdoc_docname, 'Order Confirmed') - elif flag == 'cancel': - chk = webnotes.conn.sql("select t1.name from `tabSales Order` t1, `tabSales Order Item` t2 where t2.parent = t1.name and t2.prevdoc_docname=%s and t1.name!=%s and t1.docstatus=1", (d.prevdoc_docname,self.doc.name)) - if not chk: - webnotes.conn.sql("update `tabQuotation` set status = 'Submitted' where name=%s",d.prevdoc_docname) - - #update enquiry - self.update_enquiry_status(d.prevdoc_docname, 'Quotation Sent') + def update_prevdoc_status(self, flag): + for quotation in self.doclist.get_distinct_values("prevdoc_docname"): + bean = webnotes.bean("Quotation", quotation) + if bean.doc.docstatus==2: + webnotes.throw(d.prevdoc_docname + ": " + webnotes._("Quotation is cancelled.")) + + bean.get_controller().set_status(update=True) def on_submit(self): - self.check_prev_docstatus() self.update_stock_ledger(update_stock = 1) get_obj('Sales Common').check_credit(self,self.doc.grand_total) diff --git a/support/doctype/support_ticket/get_support_mails.py b/support/doctype/support_ticket/get_support_mails.py index 4dcb59e4fe..4b61352fae 100644 --- a/support/doctype/support_ticket/get_support_mails.py +++ b/support/doctype/support_ticket/get_support_mails.py @@ -54,7 +54,7 @@ Original Query: def auto_close_tickets(self): webnotes.conn.sql("""update `tabSupport Ticket` set status = 'Closed' - where status = 'Waiting for Customer' + where status = 'Replied' and date_sub(curdate(),interval 15 Day) > modified""") def get_support_mails(): diff --git a/support/doctype/support_ticket/support_ticket.py b/support/doctype/support_ticket/support_ticket.py index bf2a9fbabe..eb68ff3bea 100644 --- a/support/doctype/support_ticket/support_ticket.py +++ b/support/doctype/support_ticket/support_ticket.py @@ -14,7 +14,7 @@ class DocType(TransactionBase): def get_sender(self, comm): return webnotes.conn.get_value('Email Settings',None,'support_email') - + def get_subject(self, comm): return '[' + self.doc.name + '] ' + (comm.subject or 'No Subject Specified') @@ -35,16 +35,7 @@ class DocType(TransactionBase): if self.doc.status == "Closed": from webnotes.widgets.form.assign_to import clear clear(self.doc.doctype, self.doc.name) - - def on_communication(self, comm): - if comm.sender == self.get_sender(comm) or \ - webnotes.conn.get_value("Profile", extract_email_id(comm.sender), "user_type")=="System User": - self.doc.status = "Waiting for Customer" - else: - self.doc.status = "Open" - self.update_status() - self.doc.save() - + def set_lead_contact(self, email_id): import email.utils email_id = email.utils.parseaddr(email_id) diff --git a/support/doctype/support_ticket/support_ticket.txt b/support/doctype/support_ticket/support_ticket.txt index 9f385b2d25..76d9dcfb1e 100644 --- a/support/doctype/support_ticket/support_ticket.txt +++ b/support/doctype/support_ticket/support_ticket.txt @@ -2,7 +2,7 @@ { "creation": "2013-02-01 10:36:25", "docstatus": 0, - "modified": "2013-09-10 10:54:02", + "modified": "2013-10-03 16:45:41", "modified_by": "Administrator", "owner": "Administrator" }, @@ -71,7 +71,7 @@ "no_copy": 1, "oldfieldname": "status", "oldfieldtype": "Select", - "options": "\nOpen\nTo Reply\nWaiting for Customer\nHold\nClosed", + "options": "Open\nReplied\nHold\nClosed", "read_only": 0, "reqd": 0, "search_index": 1 diff --git a/utilities/doctype/contact/contact.py b/utilities/doctype/contact/contact.py index 58437f1a62..db233fb68d 100644 --- a/utilities/doctype/contact/contact.py +++ b/utilities/doctype/contact/contact.py @@ -12,14 +12,6 @@ class DocType(TransactionBase): self.doc = doc self.doclist = doclist - def on_communication(self, comm): - if webnotes.conn.get_value("Profile", extract_email_id(comm.sender), "user_type")=="System User": - status = "Replied" - else: - status = "Open" - - webnotes.conn.set(self.doc, 'status', status) - def autoname(self): # concat first and last name self.doc.name = " ".join(filter(None, @@ -32,6 +24,7 @@ class DocType(TransactionBase): break def validate(self): + self.set_status() self.validate_primary_contact() def validate_primary_contact(self): diff --git a/utilities/doctype/contact/contact.txt b/utilities/doctype/contact/contact.txt index 92dcf2ef02..db23410820 100644 --- a/utilities/doctype/contact/contact.txt +++ b/utilities/doctype/contact/contact.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:32", "docstatus": 0, - "modified": "2013-09-10 10:50:27", + "modified": "2013-10-03 16:44:08", "modified_by": "Administrator", "owner": "Administrator" }, @@ -70,11 +70,12 @@ "fieldtype": "Column Break" }, { + "default": "Passive", "doctype": "DocField", "fieldname": "status", "fieldtype": "Select", "label": "Status", - "options": "\nOpen\nReplied" + "options": "Passive\nOpen\nReplied" }, { "doctype": "DocField",