From f9a3c8fcdc85134bd7968de7df87cb4b7a2e1c4c Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 28 Dec 2012 19:42:49 +0530 Subject: [PATCH] added status validation --- .../doctype/purchase_order/purchase_order.py | 11 +- .../purchase_request/purchase_request.py | 8 +- .../supplier_quotation/supplier_quotation.py | 8 +- hr/doctype/appraisal/appraisal.py | 1 + hr/doctype/attendance/attendance.py | 150 ++++---- hr/doctype/employee/employee.py | 19 +- hr/doctype/expense_claim/expense_claim.py | 5 +- .../leave_application/leave_application.py | 5 +- .../salary_structure/salary_structure.py | 159 ++++---- .../production_order/production_order.py | 4 + .../installation_note/installation_note.py | 342 +++++++++--------- selling/doctype/quotation/quotation.py | 4 + selling/doctype/sales_order/sales_order.py | 9 +- stock/doctype/delivery_note/delivery_note.py | 3 + .../purchase_receipt/purchase_receipt.py | 8 +- stock/doctype/serial_no/serial_no.py | 4 + stock/doctype/stock_entry/stock_entry.py | 11 +- .../doctype/customer_issue/customer_issue.py | 5 +- utilities/__init__.py | 9 +- 19 files changed, 410 insertions(+), 355 deletions(-) diff --git a/buying/doctype/purchase_order/purchase_order.py b/buying/doctype/purchase_order/purchase_order.py index 85a11ed813..f589b67503 100644 --- a/buying/doctype/purchase_order/purchase_order.py +++ b/buying/doctype/purchase_order/purchase_order.py @@ -128,9 +128,14 @@ class DocType(TransactionBase): # Validate def validate(self): self.validate_fiscal_year() - # Step 1:=> set status as "Draft" - webnotes.conn.set(self.doc, 'status', 'Draft') - + + if not self.doc.status: + self.doc.status = "Draft" + + import utilities + utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Stopped", + "Cancelled"]) + # Step 2:=> get Purchase Common Obj pc_obj = get_obj(dt='Purchase Common') diff --git a/buying/doctype/purchase_request/purchase_request.py b/buying/doctype/purchase_request/purchase_request.py index 3f7f932c25..0a7ae19812 100644 --- a/buying/doctype/purchase_request/purchase_request.py +++ b/buying/doctype/purchase_request/purchase_request.py @@ -141,8 +141,12 @@ class DocType: self.validate_schedule_date() self.validate_fiscal_year() - # set status as "Draft" - webnotes.conn.set(self.doc, 'status', 'Draft') + if not self.doc.status: + self.doc.status = "Draft" + + import utilities + utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Stopped", + "Cancelled"]) # Get Purchase Common Obj pc_obj = get_obj(dt='Purchase Common') diff --git a/buying/doctype/supplier_quotation/supplier_quotation.py b/buying/doctype/supplier_quotation/supplier_quotation.py index cac4bab5f3..9e62e1303b 100644 --- a/buying/doctype/supplier_quotation/supplier_quotation.py +++ b/buying/doctype/supplier_quotation/supplier_quotation.py @@ -30,10 +30,16 @@ class DocType(TransactionBase): self.doc.name = make_autoname(self.doc.naming_series + ".#####") def validate(self): + if not self.doc.status: + self.doc.status = "Draft" + + import utilities + utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Stopped", + "Cancelled"]) + self.validate_fiscal_year() self.validate_common() self.set_in_words() - self.doc.status = "Draft" def on_submit(self): purchase_controller = webnotes.get_obj("Purchase Common") diff --git a/hr/doctype/appraisal/appraisal.py b/hr/doctype/appraisal/appraisal.py index b4b0e4e8c5..82fb77b2f6 100644 --- a/hr/doctype/appraisal/appraisal.py +++ b/hr/doctype/appraisal/appraisal.py @@ -57,6 +57,7 @@ class DocType: def validate(self): if not self.doc.status: self.doc.status = "Draft" + self.validate_dates() self.validate_existing_appraisal() self.calculate_total() diff --git a/hr/doctype/attendance/attendance.py b/hr/doctype/attendance/attendance.py index d3daeb1dfc..d1ebc97333 100644 --- a/hr/doctype/attendance/attendance.py +++ b/hr/doctype/attendance/attendance.py @@ -8,11 +8,11 @@ # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . from __future__ import unicode_literals import webnotes @@ -28,79 +28,81 @@ sql = webnotes.conn.sql class DocType: - def __init__(self, doc, doclist=[]): - self.doc = doc - self.doclist = doclist - - #autoname function - def autoname(self): - self.doc.name = make_autoname(self.doc.naming_series+'.#####') - - #get employee name based on employee id selected - def get_emp_name(self): - emp_nm = sql("select employee_name from `tabEmployee` where name=%s", self.doc.employee) + def __init__(self, doc, doclist=[]): + self.doc = doc + self.doclist = doclist + + #autoname function + def autoname(self): + self.doc.name = make_autoname(self.doc.naming_series+'.#####') + + #get employee name based on employee id selected + def get_emp_name(self): + emp_nm = sql("select employee_name from `tabEmployee` where name=%s", self.doc.employee) - #this is done because sometimes user entered wrong employee name while uploading employee attendance - webnotes.conn.set(self.doc, 'employee_name', emp_nm and emp_nm[0][0] or '') + #this is done because sometimes user entered wrong employee name while uploading employee attendance + webnotes.conn.set(self.doc, 'employee_name', emp_nm and emp_nm[0][0] or '') - ret = { 'employee_name' : emp_nm and emp_nm[0][0] or ''} - return ret - - #validation for duplicate record - def validate_duplicate_record(self): - res = sql("select name from `tabAttendance` where employee = '%s' and att_date = '%s' and not name = '%s' and docstatus = 1"%(self.doc.employee,self.doc.att_date, self.doc.name)) - if res: - msgprint("Employee's attendance already marked.") - raise Exception - - - #check for already record present in leave transaction for same date - def check_leave_record(self): - if self.doc.status == 'Present': - chk = sql("select name from `tabLeave Application` where employee=%s and (from_date <= %s and to_date >= %s) and docstatus!=2", (self.doc.employee, self.doc.att_date, self.doc.att_date)) - if chk: - msgprint("Leave Application created for employee "+self.doc.employee+" whom you are trying to mark as 'Present' ") - raise Exception - - - def validate_fiscal_year(self): - fy=sql("select year_start_date from `tabFiscal Year` where name='%s'"% self.doc.fiscal_year) - ysd=fy and fy[0][0] or "" - yed=add_days(str(ysd),365) - if str(self.doc.att_date) < str(ysd) or str(self.doc.att_date) > str(yed): - msgprint("'%s' Not Within The Fiscal Year selected"%(self.doc.att_date)) - raise Exception - - def validate_att_date(self): - import datetime - if getdate(self.doc.att_date)>getdate(datetime.datetime.now().date().strftime('%Y-%m-%d')): - msgprint("Attendance can not be marked for future dates") - raise Exception + ret = { 'employee_name' : emp_nm and emp_nm[0][0] or ''} + return ret + + #validation for duplicate record + def validate_duplicate_record(self): + res = sql("select name from `tabAttendance` where employee = '%s' and att_date = '%s' and not name = '%s' and docstatus = 1"%(self.doc.employee,self.doc.att_date, self.doc.name)) + if res: + msgprint("Employee's attendance already marked.") + raise Exception + + + #check for already record present in leave transaction for same date + def check_leave_record(self): + if self.doc.status == 'Present': + chk = sql("select name from `tabLeave Application` where employee=%s and (from_date <= %s and to_date >= %s) and docstatus!=2", (self.doc.employee, self.doc.att_date, self.doc.att_date)) + if chk: + msgprint("Leave Application created for employee "+self.doc.employee+" whom you are trying to mark as 'Present' ") + raise Exception + + + def validate_fiscal_year(self): + fy=sql("select year_start_date from `tabFiscal Year` where name='%s'" % \ + self.doc.fiscal_year) + ysd=fy and fy[0][0] or "" + yed=add_days(str(ysd),365) + if str(self.doc.att_date) < str(ysd) or str(self.doc.att_date) > str(yed): + msgprint("'%s' Not Within The Fiscal Year selected"%(self.doc.att_date)) + raise Exception + + def validate_att_date(self): + import datetime + if getdate(self.doc.att_date)>getdate(datetime.datetime.now().date().strftime('%Y-%m-%d')): + msgprint("Attendance can not be marked for future dates") + raise Exception - # Validate employee - #------------------- - def validate_employee(self): - emp = sql("select name, status from `tabEmployee` where name = '%s'" % self.doc.employee) - if not emp: - msgprint("Employee: %s does not exists in the system" % self.doc.employee, raise_exception=1) - elif emp[0][1] != 'Active': - msgprint("Employee: %s is not Active" % self.doc.employee, raise_exception=1) - - # validate... - def validate(self): - self.validate_fiscal_year() - self.validate_att_date() - self.validate_duplicate_record() - #self.validate_status() - self.check_leave_record() - - def on_update(self): - #self.validate() - - #this is done because sometimes user entered wrong employee name while uploading employee attendance - x=self.get_emp_name() + # Validate employee + #------------------- + def validate_employee(self): + emp = sql("select name, status from `tabEmployee` where name = '%s'" % self.doc.employee) + if not emp: + msgprint("Employee: %s does not exists in the system" % self.doc.employee, raise_exception=1) + elif emp[0][1] != 'Active': + msgprint("Employee: %s is not Active" % self.doc.employee, raise_exception=1) + + def validate(self): + import utilities + utilities.validate_status(self.doc.status, ["Present", "Absent", "Half Day"]) - def on_submit(self): - #this is done because while uploading attendance chnage docstatus to 1 i.e. submit - webnotes.conn.set(self.doc,'docstatus',1) - pass + self.validate_fiscal_year() + self.validate_att_date() + self.validate_duplicate_record() + self.check_leave_record() + + def on_update(self): + #self.validate() + + #this is done because sometimes user entered wrong employee name while uploading employee attendance + x=self.get_emp_name() + + def on_submit(self): + #this is done because while uploading attendance chnage docstatus to 1 i.e. submit + webnotes.conn.set(self.doc,'docstatus',1) + pass diff --git a/hr/doctype/employee/employee.py b/hr/doctype/employee/employee.py index c0f7be3659..ab3f842d22 100644 --- a/hr/doctype/employee/employee.py +++ b/hr/doctype/employee/employee.py @@ -19,7 +19,7 @@ import webnotes from webnotes.utils import getdate, validate_email_add from webnotes.model.doc import make_autoname -from webnotes import msgprint +from webnotes import msgprint, _ sql = webnotes.conn.sql @@ -39,6 +39,16 @@ class DocType: self.doc.name = make_autoname(self.doc.employee_number) self.doc.employee = self.doc.name + + def validate(self): + import utilities + utilities.validate_status(self.doc.status, ["Active", "Left"]) + + self.doc.employee = self.doc.name + self.validate_date() + self.validate_email() + self.validate_name() + self.validate_status() def get_retirement_date(self): import datetime @@ -52,13 +62,6 @@ class DocType: ret_sal_struct=sql("select name from `tabSalary Structure` where employee='%s' and is_active = 'Yes' and docstatus!= 2"%nm) return ret_sal_struct and ret_sal_struct[0][0] or '' - def validate(self): - self.doc.employee = self.doc.name - self.validate_date() - self.validate_email() - self.validate_name() - self.validate_status() - def on_update(self): self.update_user_default() diff --git a/hr/doctype/expense_claim/expense_claim.py b/hr/doctype/expense_claim/expense_claim.py index b3a132ed45..2ba53aa5ed 100644 --- a/hr/doctype/expense_claim/expense_claim.py +++ b/hr/doctype/expense_claim/expense_claim.py @@ -33,9 +33,8 @@ class DocType: # if self.doc.exp_approver == self.doc.owner: # webnotes.msgprint("""Self Approval is not allowed.""", raise_exception=1) - if self.doc.status not in ("Draft", "Approved", "Rejected"): - webnotes.msgprint("Status must be one of 'Draft', 'Approved' or 'Rejected'", - raise_exception=True) + import utilities + utilities.validate_status(self.doc.status, ["Draft", "Approved", "Rejected"]) self.validate_fiscal_year() self.validate_exp_details() diff --git a/hr/doctype/leave_application/leave_application.py b/hr/doctype/leave_application/leave_application.py index e61f7b5137..ebefc0eb15 100755 --- a/hr/doctype/leave_application/leave_application.py +++ b/hr/doctype/leave_application/leave_application.py @@ -33,9 +33,8 @@ class DocType: def validate(self): # if self.doc.leave_approver == self.doc.owner: # webnotes.msgprint("""Self Approval is not allowed.""", raise_exception=1) - if self.doc.status not in ("Open", "Approved", "Rejected"): - webnotes.msgprint("Status must be one of 'Open', 'Approved' or 'Rejected'", - raise_exception=True) + import utilities + utilities.validate_status(self.doc.status, ["Open", "Approved", "Rejected"]) self.validate_to_date() self.validate_balance_leaves() diff --git a/hr/doctype/salary_structure/salary_structure.py b/hr/doctype/salary_structure/salary_structure.py index f310b7b4c8..9c5ad246ef 100644 --- a/hr/doctype/salary_structure/salary_structure.py +++ b/hr/doctype/salary_structure/salary_structure.py @@ -8,11 +8,11 @@ # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . from __future__ import unicode_literals import webnotes @@ -28,87 +28,86 @@ sql = webnotes.conn.sql class DocType: - #init function - def __init__(self,doc,doclist=[]): - self.doc = doc - self.doclist = doclist + #init function + def __init__(self,doc,doclist=[]): + self.doc = doc + self.doclist = doclist - #autoname function - #--------------------------------------------------------- - def autoname(self): - self.doc.name = make_autoname(self.doc.employee + '/.SST' + '/.#####') - - #get employee details - #--------------------------------------------------------- - def get_employee_details(self): - ret = {} - det = sql("select employee_name, branch, designation, department, grade from `tabEmployee` where name = '%s'" %self.doc.employee) - if det: - ret = { - 'employee_name' : cstr(det[0][0]), - 'branch' : cstr(det[0][1]), - 'designation' : cstr(det[0][2]), - 'department' : cstr(det[0][3]), - 'grade' : cstr(det[0][4]), - 'backup_employee': cstr(self.doc.employee) - } - return ret - + #autoname function + #--------------------------------------------------------- + def autoname(self): + self.doc.name = make_autoname(self.doc.employee + '/.SST' + '/.#####') + + #get employee details + #--------------------------------------------------------- + def get_employee_details(self): + ret = {} + det = sql("select employee_name, branch, designation, department, grade from `tabEmployee` where name = '%s'" %self.doc.employee) + if det: + ret = { + 'employee_name': cstr(det[0][0]), + 'branch': cstr(det[0][1]), + 'designation': cstr(det[0][2]), + 'department': cstr(det[0][3]), + 'grade': cstr(det[0][4]), + 'backup_employee': cstr(self.doc.employee) + } + return ret + - # Set Salary structure field values - #--------------------------------------------------------- - def get_ss_values(self,employee): - basic_info = sql("select bank_name, bank_ac_no, esic_card_no, pf_number from `tabEmployee` where name ='%s'" % employee) - ret = {'bank_name' : basic_info and basic_info[0][0] or '', - 'bank_ac_no' : basic_info and basic_info[0][1] or '', - 'esic_no' : basic_info and basic_info[0][2] or '', - 'pf_no' : basic_info and basic_info[0][3] or ''} - return ret - - # Make earning and deduction table - #--------------------------------------------------------- - def make_table(self, doct_name, tab_fname, tab_name): - list1 = sql("select name from `tab%s` where docstatus != 2" % doct_name) - for li in list1: - child = addchild(self.doc, tab_fname, tab_name, self.doclist) - if(tab_fname == 'earning_details'): - child.e_type = cstr(li[0]) - child.modified_value = 0 - elif(tab_fname == 'deduction_details'): - child.d_type = cstr(li[0]) - child.d_modified_amt = 0 - - # add earning & deduction types to table - #--------------------------------------------------------- - def make_earn_ded_table(self): - #Earning List - self.make_table('Earning Type','earning_details','Salary Structure Earning') - - #Deduction List - self.make_table('Deduction Type','deduction_details', 'Salary Structure Deduction') - + # Set Salary structure field values + #--------------------------------------------------------- + def get_ss_values(self,employee): + basic_info = sql("select bank_name, bank_ac_no, esic_card_no, pf_number from `tabEmployee` where name ='%s'" % employee) + ret = {'bank_name': basic_info and basic_info[0][0] or '', + 'bank_ac_no': basic_info and basic_info[0][1] or '', + 'esic_no': basic_info and basic_info[0][2] or '', + 'pf_no': basic_info and basic_info[0][3] or ''} + return ret + + # Make earning and deduction table + #--------------------------------------------------------- + def make_table(self, doct_name, tab_fname, tab_name): + list1 = sql("select name from `tab%s` where docstatus != 2" % doct_name) + for li in list1: + child = addchild(self.doc, tab_fname, tab_name, self.doclist) + if(tab_fname == 'earning_details'): + child.e_type = cstr(li[0]) + child.modified_value = 0 + elif(tab_fname == 'deduction_details'): + child.d_type = cstr(li[0]) + child.d_modified_amt = 0 + + # add earning & deduction types to table + #--------------------------------------------------------- + def make_earn_ded_table(self): + #Earning List + self.make_table('Earning Type','earning_details','Salary Structure Earning') + + #Deduction List + self.make_table('Deduction Type','deduction_details', + 'Salary Structure Deduction') + - # Check if another active ss exists - #--------------------------------------------------------- - def check_existing(self): - ret = sql("select name from `tabSalary Structure` where is_active = 'Yes' and employee = '%s' and name!='%s'" %(self.doc.employee,self.doc.name)) - if ret and self.doc.is_active=='Yes': - msgprint("Another Salary Structure '%s' is active for employee '%s'. Please make its status 'Inactive' to proceed."%(cstr(ret), self.doc.employee)) - raise Exception + # Check if another active ss exists + #--------------------------------------------------------- + def check_existing(self): + ret = sql("select name from `tabSalary Structure` where is_active = 'Yes' and employee = '%s' and name!='%s'" %(self.doc.employee,self.doc.name)) + if ret and self.doc.is_active=='Yes': + msgprint("Another Salary Structure '%s' is active for employee '%s'. Please make its status 'Inactive' to proceed."%(cstr(ret), self.doc.employee)) + raise Exception - # Validate net pay - #--------------------------------------------------------- - def validate_net_pay(self): - if flt(self.doc.net_pay) < 0: - msgprint("Net pay can not be negative") - raise Exception - elif flt(self.doc.net_pay) > flt(self.doc.ctc): - msgprint("Net pay can not be greater than CTC") - raise Exception + # Validate net pay + #--------------------------------------------------------- + def validate_net_pay(self): + if flt(self.doc.net_pay) < 0: + msgprint("Net pay can not be negative") + raise Exception + elif flt(self.doc.net_pay) > flt(self.doc.ctc): + msgprint("Net pay can not be greater than CTC") + raise Exception - # Validate - #--------------------------------------------------------- - def validate(self): - self.check_existing() - self.validate_net_pay() + def validate(self): + self.check_existing() + self.validate_net_pay() diff --git a/manufacturing/doctype/production_order/production_order.py b/manufacturing/doctype/production_order/production_order.py index 3ba368efca..9a09494b92 100644 --- a/manufacturing/doctype/production_order/production_order.py +++ b/manufacturing/doctype/production_order/production_order.py @@ -34,6 +34,10 @@ class DocType: self.doclist = doclist def validate(self): + import utilities + utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Stopped", + "In Process", "Completed", "Cancelled"]) + if self.doc.production_item : item_detail = sql("select name from `tabItem` where name = '%s' and docstatus != 2" % self.doc.production_item, as_dict = 1) diff --git a/selling/doctype/installation_note/installation_note.py b/selling/doctype/installation_note/installation_note.py index 1b8590b1f5..5a997fdc04 100644 --- a/selling/doctype/installation_note/installation_note.py +++ b/selling/doctype/installation_note/installation_note.py @@ -8,11 +8,11 @@ # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . from __future__ import unicode_literals import webnotes @@ -30,178 +30,176 @@ sql = webnotes.conn.sql from utilities.transaction_base import TransactionBase class DocType(TransactionBase): - def __init__(self, doc, doclist=[]): - self.doc = doc - self.doclist = doclist - self.tname = 'Installation Note Item' - self.fname = 'installed_item_details' + def __init__(self, doc, doclist=[]): + self.doc = doc + self.doclist = doclist + self.tname = 'Installation Note Item' + self.fname = 'installed_item_details' - # Autoname - # --------- - def autoname(self): - self.doc.name = make_autoname(self.doc.naming_series+'.#####') + def autoname(self): + self.doc.name = make_autoname(self.doc.naming_series+'.#####') + + def validate(self): + self.validate_fiscal_year() + self.validate_installation_date() + self.check_item_table() + sales_com_obj = get_obj(dt = 'Sales Common') + sales_com_obj.check_active_sales_items(self) + sales_com_obj.get_prevdoc_date(self) + self.validate_mandatory() + self.validate_reference_value() - - #fetch delivery note details - #==================================== - def pull_delivery_note_details(self): - self.validate_prev_docname() - self.doclist = get_obj('DocType Mapper', 'Delivery Note-Installation Note').dt_map('Delivery Note', 'Installation Note', self.doc.delivery_note_no, self.doc, self.doclist, "[['Delivery Note', 'Installation Note'],['Delivery Note Item', 'Installation Note Item']]") - - # Validates that Delivery Note is not pulled twice - #============================================ - def validate_prev_docname(self): - for d in getlist(self.doclist, 'installed_item_details'): - if self.doc.delivery_note_no == d.prevdoc_docname: - msgprint(cstr(self.doc.delivery_note_no) + " delivery note details have already been pulled. ") - raise Exception, "Validation Error. " - - #Fiscal Year Validation - #================================ - def validate_fiscal_year(self): - get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.inst_date,'Installation Date') - - # Validate Mandatory - #=============================== - def validate_mandatory(self): - # Amendment Date - if self.doc.amended_from and not self.doc.amendment_date: - msgprint("Please Enter Amendment Date") - raise Exception, "Validation Error. " - - # Validate values with reference document - #---------------------------------------- - def validate_reference_value(self): - get_obj('DocType Mapper', 'Delivery Note-Installation Note', with_children = 1).validate_reference_value(self, self.doc.name) - - #check if serial no added - #----------------------------- - def is_serial_no_added(self,item_code,serial_no): - ar_required = sql("select has_serial_no from tabItem where name = '%s'" % item_code) - ar_required = ar_required and ar_required[0][0] or '' - if ar_required == 'Yes' and not serial_no: - msgprint("Serial No is mandatory for item: "+ item_code) - raise Exception - elif ar_required != 'Yes' and cstr(serial_no).strip(): - msgprint("If serial no required, please select 'Yes' in 'Has Serial No' in Item :"+item_code) - raise Exception - - #check if serial no exist in system - #------------------------------------- - def is_serial_no_exist(self, item_code, serial_no): - for x in serial_no: - chk = sql("select name from `tabSerial No` where name =%s", x) - if not chk: - msgprint("Serial No "+x+" does not exist in the system") - raise Exception - - #check if serial no already installed - #------------------------------------------ - def is_serial_no_installed(self,cur_s_no,item_code): - for x in cur_s_no: - status = sql("select status from `tabSerial No` where name = %s", x) - status = status and status[0][0] or '' - - if status == 'Installed': - msgprint("Item "+item_code+" with serial no. "+x+" already installed") - raise Exception, "Validation Error." - - #get list of serial no from previous_doc - #---------------------------------------------- - def get_prevdoc_serial_no(self, prevdoc_detail_docname, prevdoc_docname): - from stock.doctype.stock_ledger.stock_ledger import get_sr_no_list - res = sql("select serial_no from `tabDelivery Note Item` where name = '%s' and parent ='%s'" % (prevdoc_detail_docname, prevdoc_docname)) - return get_sr_no_list(res[0][0]) - - #check if all serial nos from current record exist in resp delivery note - #--------------------------------------------------------------------------------- - def is_serial_no_match(self, cur_s_no, prevdoc_s_no, prevdoc_docname): - for x in cur_s_no: - if not(x in prevdoc_s_no): - msgprint("Serial No. "+x+" not present in the Delivery Note "+prevdoc_docname, raise_exception = 1) - raise Exception, "Validation Error." - - #validate serial number - #---------------------------------------- - def validate_serial_no(self): - cur_s_no, prevdoc_s_no, sr_list = [], [], [] - from stock.doctype.stock_ledger.stock_ledger import get_sr_no_list - - for d in getlist(self.doclist, 'installed_item_details'): - self.is_serial_no_added(d.item_code, d.serial_no) - - if d.serial_no: + #fetch delivery note details + #==================================== + def pull_delivery_note_details(self): + self.validate_prev_docname() + self.doclist = get_obj('DocType Mapper', 'Delivery Note-Installation Note').dt_map('Delivery Note', 'Installation Note', self.doc.delivery_note_no, self.doc, self.doclist, "[['Delivery Note', 'Installation Note'],['Delivery Note Item', 'Installation Note Item']]") + + # Validates that Delivery Note is not pulled twice + #============================================ + def validate_prev_docname(self): + for d in getlist(self.doclist, 'installed_item_details'): + if self.doc.delivery_note_no == d.prevdoc_docname: + msgprint(cstr(self.doc.delivery_note_no) + " delivery note details have already been pulled. ") + raise Exception, "Validation Error. " + + #Fiscal Year Validation + #================================ + def validate_fiscal_year(self): + get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.inst_date,'Installation Date') + + # Validate Mandatory + #=============================== + def validate_mandatory(self): + # Amendment Date + if self.doc.amended_from and not self.doc.amendment_date: + msgprint("Please Enter Amendment Date") + raise Exception, "Validation Error. " + + # Validate values with reference document + #---------------------------------------- + def validate_reference_value(self): + get_obj('DocType Mapper', 'Delivery Note-Installation Note', with_children = 1).validate_reference_value(self, self.doc.name) + + #check if serial no added + #----------------------------- + def is_serial_no_added(self,item_code,serial_no): + ar_required = sql("select has_serial_no from tabItem where name = '%s'" % item_code) + ar_required = ar_required and ar_required[0][0] or '' + if ar_required == 'Yes' and not serial_no: + msgprint("Serial No is mandatory for item: "+ item_code) + raise Exception + elif ar_required != 'Yes' and cstr(serial_no).strip(): + msgprint("If serial no required, please select 'Yes' in 'Has Serial No' in Item :"+item_code) + raise Exception + + #check if serial no exist in system + #------------------------------------- + def is_serial_no_exist(self, item_code, serial_no): + for x in serial_no: + chk = sql("select name from `tabSerial No` where name =%s", x) + if not chk: + msgprint("Serial No "+x+" does not exist in the system") + raise Exception + + #check if serial no already installed + #------------------------------------------ + def is_serial_no_installed(self,cur_s_no,item_code): + for x in cur_s_no: + status = sql("select status from `tabSerial No` where name = %s", x) + status = status and status[0][0] or '' + + if status == 'Installed': + msgprint("Item "+item_code+" with serial no. "+x+" already installed") + raise Exception, "Validation Error." + + #get list of serial no from previous_doc + #---------------------------------------------- + def get_prevdoc_serial_no(self, prevdoc_detail_docname, prevdoc_docname): + from stock.doctype.stock_ledger.stock_ledger import get_sr_no_list + + res = sql("select serial_no from `tabDelivery Note Item` where name = '%s' and parent ='%s'" % (prevdoc_detail_docname, prevdoc_docname)) + return get_sr_no_list(res[0][0]) + + #check if all serial nos from current record exist in resp delivery note + #--------------------------------------------------------------------------------- + def is_serial_no_match(self, cur_s_no, prevdoc_s_no, prevdoc_docname): + for x in cur_s_no: + if not(x in prevdoc_s_no): + msgprint("Serial No. "+x+" not present in the Delivery Note "+prevdoc_docname, raise_exception = 1) + raise Exception, "Validation Error." + + #validate serial number + #---------------------------------------- + def validate_serial_no(self): + cur_s_no, prevdoc_s_no, sr_list = [], [], [] + from stock.doctype.stock_ledger.stock_ledger import get_sr_no_list + + for d in getlist(self.doclist, 'installed_item_details'): + self.is_serial_no_added(d.item_code, d.serial_no) + + if d.serial_no: - sr_list = get_sr_no_list(d.serial_no, d.qty, d.item_code) - self.is_serial_no_exist(d.item_code, sr_list) - - prevdoc_s_no = self.get_prevdoc_serial_no(d.prevdoc_detail_docname, d.prevdoc_docname) - if prevdoc_s_no: - self.is_serial_no_match(sr_list, prevdoc_s_no, d.prevdoc_docname) - - self.is_serial_no_installed(sr_list, d.item_code) - return sr_list - - #validate installation date - #------------------------------- - def validate_installation_date(self): - for d in getlist(self.doclist, 'installed_item_details'): - if d.prevdoc_docname: - d_date = sql("select posting_date from `tabDelivery Note` where name=%s", d.prevdoc_docname) - d_date = d_date and d_date[0][0] or '' - - if d_date > getdate(self.doc.inst_date): - msgprint("Installation Date can not be before Delivery Date "+cstr(d_date)+" for item "+d.item_code) - raise Exception - - def validate(self): - self.validate_fiscal_year() - self.validate_installation_date() - self.check_item_table() - sales_com_obj = get_obj(dt = 'Sales Common') - sales_com_obj.check_active_sales_items(self) - sales_com_obj.get_prevdoc_date(self) - self.validate_mandatory() - self.validate_reference_value() - - def check_item_table(self): - if not(getlist(self.doclist, 'installed_item_details')): - msgprint("Please fetch items from Delivery Note selected") - raise Exception - - def on_update(self): - webnotes.conn.set(self.doc, 'status', 'Draft') - - def on_submit(self): - valid_lst = [] - valid_lst = self.validate_serial_no() - - get_obj("Sales Common").update_prevdoc_detail(1,self) - - for x in valid_lst: - wp = sql("select warranty_period from `tabSerial No` where name = '%s'"% x) - wp = wp and wp[0][0] or 0 - if wp: - sql("update `tabSerial No` set maintenance_status = 'Under Warranty' where name = '%s'" % x) - - sql("update `tabSerial No` set status = 'Installed' where name = '%s'" % x) - - webnotes.conn.set(self.doc, 'status', 'Submitted') + sr_list = get_sr_no_list(d.serial_no, d.qty, d.item_code) + self.is_serial_no_exist(d.item_code, sr_list) + + prevdoc_s_no = self.get_prevdoc_serial_no(d.prevdoc_detail_docname, d.prevdoc_docname) + if prevdoc_s_no: + self.is_serial_no_match(sr_list, prevdoc_s_no, d.prevdoc_docname) + + self.is_serial_no_installed(sr_list, d.item_code) + return sr_list + + #validate installation date + #------------------------------- + def validate_installation_date(self): + for d in getlist(self.doclist, 'installed_item_details'): + if d.prevdoc_docname: + d_date = sql("select posting_date from `tabDelivery Note` where name=%s", d.prevdoc_docname) + d_date = d_date and d_date[0][0] or '' + + if d_date > getdate(self.doc.inst_date): + msgprint("Installation Date can not be before Delivery Date "+cstr(d_date)+" for item "+d.item_code) + raise Exception + + def check_item_table(self): + if not(getlist(self.doclist, 'installed_item_details')): + msgprint("Please fetch items from Delivery Note selected") + raise Exception + + def on_update(self): + webnotes.conn.set(self.doc, 'status', 'Draft') + + def on_submit(self): + valid_lst = [] + valid_lst = self.validate_serial_no() + + get_obj("Sales Common").update_prevdoc_detail(1,self) + + for x in valid_lst: + wp = sql("select warranty_period from `tabSerial No` where name = '%s'"% x) + wp = wp and wp[0][0] or 0 + if wp: + sql("update `tabSerial No` set maintenance_status = 'Under Warranty' where name = '%s'" % x) + + sql("update `tabSerial No` set status = 'Installed' where name = '%s'" % x) + + webnotes.conn.set(self.doc, 'status', 'Submitted') - - def on_cancel(self): - cur_s_no = [] - sales_com_obj = get_obj(dt = 'Sales Common') - sales_com_obj.update_prevdoc_detail(0,self) - - for d in getlist(self.doclist, 'installed_item_details'): - if d.serial_no: - #get current list of serial no - cur_serial_no = d.serial_no.replace(' ', '') - cur_s_no = cur_serial_no.split(',') - - for x in cur_s_no: - sql("update `tabSerial No` set status = 'Delivered' where name = '%s'" % x) - - webnotes.conn.set(self.doc, 'status', 'Cancelled') + + def on_cancel(self): + cur_s_no = [] + sales_com_obj = get_obj(dt = 'Sales Common') + sales_com_obj.update_prevdoc_detail(0,self) + + for d in getlist(self.doclist, 'installed_item_details'): + if d.serial_no: + #get current list of serial no + cur_serial_no = d.serial_no.replace(' ', '') + cur_s_no = cur_serial_no.split(',') + + for x in cur_s_no: + sql("update `tabSerial No` set status = 'Delivered' where name = '%s'" % x) + + webnotes.conn.set(self.doc, 'status', 'Cancelled') diff --git a/selling/doctype/quotation/quotation.py b/selling/doctype/quotation/quotation.py index 3b452f18b7..ed09ab03f8 100644 --- a/selling/doctype/quotation/quotation.py +++ b/selling/doctype/quotation/quotation.py @@ -179,6 +179,10 @@ class DocType(TransactionBase): # Validate # -------- def validate(self): + import utilities + utilities.validate_status(self.doc.status, ["Draft", "Submitted", + "Order Confirmed", "Order Lost", "Cancelled"]) + self.validate_fiscal_year() self.validate_mandatory() self.set_last_contact_date() diff --git a/selling/doctype/sales_order/sales_order.py b/selling/doctype/sales_order/sales_order.py index e0ac2ffb57..3e7b03dd83 100644 --- a/selling/doctype/sales_order/sales_order.py +++ b/selling/doctype/sales_order/sales_order.py @@ -226,8 +226,13 @@ class DocType(TransactionBase): self.doc.in_words = sales_com_obj.get_total_in_words(dcc, self.doc.rounded_total) self.doc.in_words_export = sales_com_obj.get_total_in_words(self.doc.currency, self.doc.rounded_total_export) - # set SO status - self.doc.status='Draft' + if not self.doc.status: + self.doc.status = "Draft" + + import utilities + utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Stopped", + "Cancelled"]) + if not self.doc.billing_status: self.doc.billing_status = 'Not Billed' if not self.doc.delivery_status: self.doc.delivery_status = 'Not Delivered' diff --git a/stock/doctype/delivery_note/delivery_note.py b/stock/doctype/delivery_note/delivery_note.py index af4d91e9aa..411ce5c4c0 100644 --- a/stock/doctype/delivery_note/delivery_note.py +++ b/stock/doctype/delivery_note/delivery_note.py @@ -131,6 +131,9 @@ class DocType(TransactionBase): def validate(self): + import utilities + utilities.validate_status(self.doc.status, ["Draft", "submitted", "Cancelled"]) + self.so_required() self.validate_fiscal_year() self.validate_proj_cust() diff --git a/stock/doctype/purchase_receipt/purchase_receipt.py b/stock/doctype/purchase_receipt/purchase_receipt.py index 5e60753a18..8c2ad016e0 100644 --- a/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/stock/doctype/purchase_receipt/purchase_receipt.py @@ -148,7 +148,13 @@ class DocType(TransactionBase): def validate(self): self.po_required() self.validate_fiscal_year() - webnotes.conn.set(self.doc, 'status', 'Draft') # set status as "Draft" + + if not self.doc.status: + self.doc.status = "Draft" + + import utilities + utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Cancelled"]) + self.validate_accepted_rejected_qty() self.validate_inspection() # Validate Inspection get_obj('Stock Ledger').validate_serial_no(self, 'purchase_receipt_details') diff --git a/stock/doctype/serial_no/serial_no.py b/stock/doctype/serial_no/serial_no.py index b6f60f57f3..35308bce17 100644 --- a/stock/doctype/serial_no/serial_no.py +++ b/stock/doctype/serial_no/serial_no.py @@ -65,6 +65,10 @@ class DocType(TransactionBase): # validate # --------- def validate(self): + import utilities + utilities.validate_status(self.doc.status, ["In Store", "Delivered", + "Not in Use", "Purchase Returned"]) + self.validate_warranty_status() self.validate_amc_status() self.validate_warehouse() diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index 2e26a1a86a..18440329ae 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -17,7 +17,7 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import cstr, cint, flt, getdate, now +from webnotes.utils import cstr, cint, flt, getdate, now, comma_or from webnotes.model import db_exists, delete_doc from webnotes.model.doc import Document, addchild from webnotes.model.wrapper import getlist, copy_doclist @@ -35,6 +35,8 @@ class DocType(TransactionBase): self.fname = 'mtn_details' def validate(self): + self.validate_purpose() + self.validate_serial_nos() pro_obj = self.doc.production_order and \ get_obj('Production Order', self.doc.production_order) or None @@ -57,6 +59,13 @@ class DocType(TransactionBase): self.update_stock_ledger(1) # update Production Order self.update_production_order(0) + + def validate_purpose(self): + valid_purposes = ["Material Issue", "Material Receipt", "Material Transfer", + "Manufacture/Repack", "Subcontract", "Sales Return", "Purchase Return"] + if self.doc.purpose not in valid_purposes: + msgprint(_("Purpose must be one of ") + comma_or(valid_purposes), + raise_exception=True) def validate_serial_nos(self): sl_obj = get_obj("Stock Ledger") diff --git a/support/doctype/customer_issue/customer_issue.py b/support/doctype/customer_issue/customer_issue.py index 44ae891c84..0a08d82f38 100644 --- a/support/doctype/customer_issue/customer_issue.py +++ b/support/doctype/customer_issue/customer_issue.py @@ -41,9 +41,8 @@ class DocType(TransactionBase): def validate(self): if session['user'] != 'Guest' and not self.doc.customer: - msgprint("Please select Customer from whom issue is raised") - raise Exception - + msgprint("Please select Customer from whom issue is raised", + raise_exception=True) def on_cancel(self): lst = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent = t1.name and t2.prevdoc_docname = '%s' and t1.docstatus!=2"%(self.doc.name)) diff --git a/utilities/__init__.py b/utilities/__init__.py index 486568d638..7c44ec31dd 100644 --- a/utilities/__init__.py +++ b/utilities/__init__.py @@ -16,7 +16,8 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import cint +from webnotes import _, msgprint +from webnotes.utils import cint, comma_or @webnotes.whitelist() def get_sc_list(arg=None): @@ -52,4 +53,8 @@ def get_report_list(): and ifnull(tabReport.disabled,0) != 1 order by tabReport.name limit %s, %s""" % \ - ("%s", cint(limit_start), cint(limit_page_length)), (module,), as_dict=True) \ No newline at end of file + ("%s", cint(limit_start), cint(limit_page_length)), (module,), as_dict=True) + +def validate_status(status, options): + if status not in options: + msgprint(_("Status must be one of ") + comma_or(options), raise_exception=True)