From 4a2f8c8179f6fe9205cdfb2d17e9ec12dffd3800 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 5 Aug 2011 11:07:45 +0530 Subject: [PATCH 01/11] serial no removed from mandatory --- stock/doctype/stock_entry_detail/stock_entry_detail.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stock/doctype/stock_entry_detail/stock_entry_detail.txt b/stock/doctype/stock_entry_detail/stock_entry_detail.txt index 1d2408bf88..50b7154a0e 100644 --- a/stock/doctype/stock_entry_detail/stock_entry_detail.txt +++ b/stock/doctype/stock_entry_detail/stock_entry_detail.txt @@ -253,7 +253,8 @@ 'no_copy': 1, 'oldfieldname': 'serial_no', 'oldfieldtype': 'Text', - 'permlevel': 0 + 'permlevel': 0, + 'reqd': 0 }, # DocField @@ -280,4 +281,4 @@ 'oldfieldtype': 'Currency', 'permlevel': 1 } -] \ No newline at end of file +] From 71f2bd97b644b2d8601d3ab2087872d4dbc08e6b Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 5 Aug 2011 11:08:42 +0530 Subject: [PATCH 02/11] level was not adding in add_permission() --- utilities/doctype/patch_util/patch_util.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utilities/doctype/patch_util/patch_util.py b/utilities/doctype/patch_util/patch_util.py index f26d110aa6..8413fc0747 100644 --- a/utilities/doctype/patch_util/patch_util.py +++ b/utilities/doctype/patch_util/patch_util.py @@ -85,7 +85,8 @@ class DocType: d.parent = doctype d.parenttype = 'DocType' d.parentfield = 'permissions' - + + d.level = level d.role = role d.read = read d.write = write From a819f6f8abe32b82c02eb39414e4c23a00b0582e Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 5 Aug 2011 11:09:25 +0530 Subject: [PATCH 03/11] rename function added in item --- stock/doctype/item/item.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/stock/doctype/item/item.py b/stock/doctype/item/item.py index ae677493b5..7f0d3c2f69 100644 --- a/stock/doctype/item/item.py +++ b/stock/doctype/item/item.py @@ -178,3 +178,7 @@ Total Available Qty: %s sle = sql("select name from `tabStock Ledger Entry` where item_code = %s and ifnull(is_cancelled, 'No') = 'No'", self.doc.name) return sle and 'exists' or 'not exists' + + def on_rename(self,newdn,olddn): + sql("update tabItem set item_code = %s where name = %s", (newdn, olddn)) + From 812e71894ceda99072461d5399cec8e58d06dfb6 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 5 Aug 2011 11:10:30 +0530 Subject: [PATCH 04/11] permission to system manager in role, dt mapper and print format --- patches/patch.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/patches/patch.py b/patches/patch.py index 86fcff6290..1635382a1e 100644 --- a/patches/patch.py +++ b/patches/patch.py @@ -1,7 +1,7 @@ # REMEMBER to update this # ======================== -last_patch = 332 +last_patch = 333 #------------------------------------------- @@ -1336,3 +1336,10 @@ def execute(patch_no): p.add_permission('Lease Agreement', 'Accounts Manager', 1, read = 1) elif patch_no == 332: sql("update `tabDocField` set permlevel=1, hidden = 1 where parent = 'Bulk Rename Tool' and fieldname = 'file_list'") + elif patch_no == 333: + sql("update `tabDocPerm` set create =1 where role = 'Accounts Manager' and parent = 'Lease Agreement'") + + p = get_obj('Patch Util') + p.add_permission('DocType Mapper', 'System Manager', 0, read = 1, write=1, create=1) + p.add_permission('Role', 'System Manager', 0, read = 1, write=1, create=1) + p.add_permission('Print Format', 'System Manager', 0, read = 1, write=1, create=1) From d8b7f8eb77003e22300d97798f180346222da524 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 5 Aug 2011 11:13:27 +0530 Subject: [PATCH 05/11] fn reordered in sales common --- selling/doctype/sales_common/sales_common.py | 42 ++++++++++---------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/selling/doctype/sales_common/sales_common.py b/selling/doctype/sales_common/sales_common.py index 25dd960bdc..7a1af22448 100644 --- a/selling/doctype/sales_common/sales_common.py +++ b/selling/doctype/sales_common/sales_common.py @@ -329,6 +329,28 @@ class DocType(TransactionBase): il.append([warehouse, d.item_code, qty, reserved_qty, d.stock_uom, d.batch_no, d.serial_no]) return il + # --------------------------------------------------------------------------------------------- + # get qty, amount already billed or delivered against curr line item for current doctype + # For Eg: SO-RV get total qty, amount from SO and also total qty, amount against that SO in RV + # --------------------------------------------------------------------------------------------- + def get_curr_and_ref_doc_details(self, curr_doctype, ref_tab_fname, ref_tab_dn, ref_doc_tname, curr_parent_name, curr_parent_doctype): + # Get total qty, amt of current doctype (eg RV) except for qty, amt of this transaction + if curr_parent_doctype == 'Installation Note': + curr_det = sql("select sum(qty) from `tab%s` where %s = '%s' and docstatus = 1 and parent != '%s'"% (curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name)) + qty, amt = curr_det and flt(curr_det[0][0]) or 0, 0 + else: + curr_det = sql("select sum(qty), sum(amount) from `tab%s` where %s = '%s' and docstatus = 1 and parent != '%s'"% (curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name)) + qty, amt = curr_det and flt(curr_det[0][0]) or 0, curr_det and flt(curr_det[0][1]) or 0 + + # get total qty of ref doctype + ref_det = sql("select qty, amount from `tab%s` where name = '%s' and docstatus = 1"% (ref_doc_tname, ref_tab_dn)) + max_qty, max_amt = ref_det and flt(ref_det[0][0]) or 0, ref_det and flt(ref_det[0][1]) or 0 + + return qty, max_qty, amt, max_amt + + + + # ----------------------- # add packing list items @@ -458,26 +480,6 @@ class DocType(TransactionBase): def update_prevdoc_detail(self, is_submit, obj): StatusUpdater(obj, is_submit).update() - # --------------------------------------------------------------------------------------------- - # get qty, amount already billed or delivered against curr line item for current doctype - # For Eg: SO-RV get total qty, amount from SO and also total qty, amount against that SO in RV - # --------------------------------------------------------------------------------------------- - def get_curr_and_ref_doc_details(self, curr_doctype, ref_tab_fname, ref_tab_dn, ref_doc_tname, curr_parent_name, curr_parent_doctype): - # Get total qty, amt of current doctype (eg RV) except for qty, amt of this transaction - if curr_parent_doctype == 'Installation Note': - curr_det = sql("select sum(qty) from `tab%s` where %s = '%s' and docstatus = 1 and parent != '%s'"% (curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name)) - qty, amt = curr_det and flt(curr_det[0][0]) or 0, 0 - else: - curr_det = sql("select sum(qty), sum(amount) from `tab%s` where %s = '%s' and docstatus = 1 and parent != '%s'"% (curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name)) - qty, amt = curr_det and flt(curr_det[0][0]) or 0, curr_det and flt(curr_det[0][1]) or 0 - - # get total qty of ref doctype - ref_det = sql("select qty, amount from `tab%s` where name = '%s' and docstatus = 1"% (ref_doc_tname, ref_tab_dn)) - max_qty, max_amt = ref_det and flt(ref_det[0][0]) or 0, ref_det and flt(ref_det[0][1]) or 0 - - return qty, max_qty, amt, max_amt - - From b24ba8ef520b1aded9bce644ec2511242a1e2ee5 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 5 Aug 2011 11:15:07 +0530 Subject: [PATCH 06/11] indentation replaced by tab --- selling/doctype/sales_order/sales_order.py | 818 ++++++++++----------- 1 file changed, 409 insertions(+), 409 deletions(-) diff --git a/selling/doctype/sales_order/sales_order.py b/selling/doctype/sales_order/sales_order.py index 11842fb079..9dee82eb05 100644 --- a/selling/doctype/sales_order/sales_order.py +++ b/selling/doctype/sales_order/sales_order.py @@ -19,470 +19,470 @@ convert_to_lists = webnotes.conn.convert_to_lists from utilities.transaction_base import TransactionBase class DocType(TransactionBase): - def __init__(self, doc, doclist=[]): - self.doc = doc - self.doclist = doclist - self.tname = 'Sales Order Detail' - self.fname = 'sales_order_details' - self.person_tname = 'Target Detail' - self.partner_tname = 'Partner Target Detail' - self.territory_tname = 'Territory Target Detail' + def __init__(self, doc, doclist=[]): + self.doc = doc + self.doclist = doclist + self.tname = 'Sales Order Detail' + self.fname = 'sales_order_details' + self.person_tname = 'Target Detail' + self.partner_tname = 'Partner Target Detail' + self.territory_tname = 'Territory Target Detail' # 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+'.#####') - + # DOCTYPE TRIGGER FUNCTIONS # ============================= - # Pull Quotation Details - # ----------------------- - def pull_quotation_details(self): - self.doc.clear_table(self.doclist, 'other_charges') - self.doc.clear_table(self.doclist, 'sales_order_details') - self.doc.clear_table(self.doclist, 'sales_team') - self.doc.clear_table(self.doclist, 'tc_details') - if self.doc.quotation_no: - get_obj('DocType Mapper', 'Quotation-Sales Order').dt_map('Quotation', 'Sales Order', self.doc.quotation_no, self.doc, self.doclist, "[['Quotation', 'Sales Order'],['Quotation Detail', 'Sales Order Detail'],['RV Tax Detail','RV Tax Detail'],['Sales Team','Sales Team'],['TC Detail','TC Detail']]") - else: - msgprint("Please select Quotation whose details need to pull") + # Pull Quotation Details + # ----------------------- + def pull_quotation_details(self): + self.doc.clear_table(self.doclist, 'other_charges') + self.doc.clear_table(self.doclist, 'sales_order_details') + self.doc.clear_table(self.doclist, 'sales_team') + self.doc.clear_table(self.doclist, 'tc_details') + if self.doc.quotation_no: + get_obj('DocType Mapper', 'Quotation-Sales Order').dt_map('Quotation', 'Sales Order', self.doc.quotation_no, self.doc, self.doclist, "[['Quotation', 'Sales Order'],['Quotation Detail', 'Sales Order Detail'],['RV Tax Detail','RV Tax Detail'],['Sales Team','Sales Team'],['TC Detail','TC Detail']]") + else: + msgprint("Please select Quotation whose details need to pull") - return cstr(self.doc.quotation_no) - - #pull project customer - #------------------------- - def pull_project_customer(self): - res = sql("select customer from `tabProject` where name = '%s'"%self.doc.project_name) - if res: - get_obj('DocType Mapper', 'Project-Sales Order').dt_map('Project', 'Sales Order', self.doc.project_name, self.doc, self.doclist, "[['Project', 'Sales Order']]") - - - # Get Customer Details - # --------------------- - #def get_customer_details(self): - # sales_com_obj = get_obj('Sales Common') - # sales_com_obj.get_customer_details(self) - # sales_com_obj.get_shipping_details(self) + return cstr(self.doc.quotation_no) + + #pull project customer + #------------------------- + def pull_project_customer(self): + res = sql("select customer from `tabProject` where name = '%s'"%self.doc.project_name) + if res: + get_obj('DocType Mapper', 'Project-Sales Order').dt_map('Project', 'Sales Order', self.doc.project_name, self.doc, self.doclist, "[['Project', 'Sales Order']]") + + + # Get Customer Details + # --------------------- + #def get_customer_details(self): + # sales_com_obj = get_obj('Sales Common') + # sales_com_obj.get_customer_details(self) + # sales_com_obj.get_shipping_details(self) - # Get contact person details based on customer selected - # ------------------------------------------------------ - def get_contact_details(self): - get_obj('Sales Common').get_contact_details(self,0) + # Get contact person details based on customer selected + # ------------------------------------------------------ + def get_contact_details(self): + get_obj('Sales Common').get_contact_details(self,0) - # Get Commission rate of Sales Partner - # ------------------------------------- - def get_comm_rate(self, sales_partner): - return get_obj('Sales Common').get_comm_rate(sales_partner, self) + # Get Commission rate of Sales Partner + # ------------------------------------- + def get_comm_rate(self, sales_partner): + return get_obj('Sales Common').get_comm_rate(sales_partner, self) - # Clear Sales Order Details Table - # -------------------------------- - def clear_sales_order_details(self): - self.doc.clear_table(self.doclist, 'sales_order_details') - + # Clear Sales Order Details Table + # -------------------------------- + def clear_sales_order_details(self): + self.doc.clear_table(self.doclist, 'sales_order_details') + # SALES ORDER DETAILS TRIGGER FUNCTIONS # ================================================================================ - # Get Item Details - # ---------------- - def get_item_details(self, item_code): - return get_obj('Sales Common').get_item_details(item_code, self) + # Get Item Details + # ---------------- + def get_item_details(self, item_code): + return get_obj('Sales Common').get_item_details(item_code, self) - # Re-calculates Basic Rate & amount based on Price List Selected - # -------------------------------------------------------------- - def get_adj_percent(self, arg=''): - get_obj('Sales Common').get_adj_percent(self) + # Re-calculates Basic Rate & amount based on Price List Selected + # -------------------------------------------------------------- + def get_adj_percent(self, arg=''): + get_obj('Sales Common').get_adj_percent(self) - # Get projected qty of item based on warehouse selected - # ----------------------------------------------------- - def get_available_qty(self,args): - args = eval(args) - tot_avail_qty = sql("select projected_qty, actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], args['warehouse']), as_dict=1) - ret = { - 'projected_qty' : tot_avail_qty and flt(tot_avail_qty[0]['projected_qty']) or 0, - 'actual_qty' : tot_avail_qty and flt(tot_avail_qty[0]['actual_qty']) or 0 - } - return cstr(ret) - - + # Get projected qty of item based on warehouse selected + # ----------------------------------------------------- + def get_available_qty(self,args): + args = eval(args) + tot_avail_qty = sql("select projected_qty, actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], args['warehouse']), as_dict=1) + ret = { + 'projected_qty' : tot_avail_qty and flt(tot_avail_qty[0]['projected_qty']) or 0, + 'actual_qty' : tot_avail_qty and flt(tot_avail_qty[0]['actual_qty']) or 0 + } + return cstr(ret) + + # OTHER CHARGES TRIGGER FUNCTIONS # ==================================================================================== - - # Get Tax rate if account type is TAX - # ------------------------------------ - def get_rate(self,arg): - return get_obj('Sales Common').get_rate(arg) + + # Get Tax rate if account type is TAX + # ------------------------------------ + def get_rate(self,arg): + return get_obj('Sales Common').get_rate(arg) - # Load Default Charges - # ---------------------------------------------------------- - def load_default_taxes(self): - return get_obj('Sales Common').load_default_taxes(self) + # Load Default Charges + # ---------------------------------------------------------- + def load_default_taxes(self): + return get_obj('Sales Common').load_default_taxes(self) - # Pull details from other charges master (Get Other Charges) - # ---------------------------------------------------------- - def get_other_charges(self): - return get_obj('Sales Common').get_other_charges(self) + # Pull details from other charges master (Get Other Charges) + # ---------------------------------------------------------- + def get_other_charges(self): + return get_obj('Sales Common').get_other_charges(self) # GET TERMS & CONDITIONS # ===================================================================================== - def get_tc_details(self): - return get_obj('Sales Common').get_tc_details(self) + def get_tc_details(self): + return get_obj('Sales Common').get_tc_details(self) #check if maintenance schedule already generated #============================================ - def check_maintenance_schedule(self): - nm = sql("select t1.name from `tabMaintenance Schedule` t1, `tabItem Maintenance Detail` t2 where t2.parent=t1.name and t2.prevdoc_docname=%s and t1.docstatus=1", self.doc.name) - nm = nm and nm[0][0] or '' - - if not nm: - return cstr('No') + def check_maintenance_schedule(self): + nm = sql("select t1.name from `tabMaintenance Schedule` t1, `tabItem Maintenance Detail` t2 where t2.parent=t1.name and t2.prevdoc_docname=%s and t1.docstatus=1", self.doc.name) + nm = nm and nm[0][0] or '' + + if not nm: + return cstr('No') #check if maintenance visit already generated #============================================ - def check_maintenance_visit(self): - nm = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Detail` t2 where t2.parent=t1.name and t2.prevdoc_docname=%s and t1.docstatus=1 and t1.completion_status='Fully Completed'", self.doc.name) - nm = nm and nm[0][0] or '' - - if not nm: - return cstr('No') + def check_maintenance_visit(self): + nm = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Detail` t2 where t2.parent=t1.name and t2.prevdoc_docname=%s and t1.docstatus=1 and t1.completion_status='Fully Completed'", self.doc.name) + nm = nm and nm[0][0] or '' + + if not nm: + return cstr('No') # VALIDATE # ===================================================================================== - # Fiscal Year Validation - # ---------------------- - def validate_fiscal_year(self): - get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.transaction_date,'Sales Order Date') - - # Validate values with reference document - #---------------------------------------- - def validate_reference_value(self): - get_obj('DocType Mapper', 'Quotation-Sales Order', with_children = 1).validate_reference_value(self, self.doc.name) + # Fiscal Year Validation + # ---------------------- + def validate_fiscal_year(self): + get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.transaction_date,'Sales Order Date') + + # Validate values with reference document + #---------------------------------------- + def validate_reference_value(self): + get_obj('DocType Mapper', 'Quotation-Sales Order', with_children = 1).validate_reference_value(self, self.doc.name) - # Validate Mandatory - # ------------------- - def validate_mandatory(self): - # validate transaction date v/s delivery date - if self.doc.delivery_date: - if getdate(self.doc.transaction_date) > getdate(self.doc.delivery_date): - msgprint("Expected Delivery Date cannot be before Sales Order Date") - raise Exception + # Validate Mandatory + # ------------------- + def validate_mandatory(self): + # validate transaction date v/s delivery date + if self.doc.delivery_date: + if getdate(self.doc.transaction_date) > getdate(self.doc.delivery_date): + msgprint("Expected Delivery Date cannot be before Sales Order Date") + raise Exception - # Validate P.O Date - # ------------------ - def validate_po_date(self): - # validate p.o date v/s delivery date - if self.doc.po_date and self.doc.delivery_date and getdate(self.doc.po_date) >= getdate(self.doc.delivery_date): - msgprint("Expected Delivery Date cannot be before Purchase Order Date") - raise Exception - # amendment date is necessary if document is amended - if self.doc.amended_from and not self.doc.amendment_date: - msgprint("Please Enter Amendment Date") - raise Exception - - # Validations of Details Table - # ----------------------------- - def validate_for_items(self): - check_list,flag = [],0 - chk_dupl_itm = [] - # Sales Order Details Validations - for d in getlist(self.doclist, 'sales_order_details'): - if cstr(self.doc.quotation_no) == cstr(d.prevdoc_docname): - flag = 1 - if d.prevdoc_docname: - if self.doc.quotation_date and getdate(self.doc.quotation_date) > getdate(self.doc.transaction_date): - msgprint("Sales Order Date cannot be before Quotation Date") - raise Exception - # validates whether quotation no in doctype and in table is same - if not cstr(d.prevdoc_docname) == cstr(self.doc.quotation_no): - msgprint("Items in table does not belong to the Quotation No mentioned.") - raise Exception + # Validate P.O Date + # ------------------ + def validate_po_date(self): + # validate p.o date v/s delivery date + if self.doc.po_date and self.doc.delivery_date and getdate(self.doc.po_date) >= getdate(self.doc.delivery_date): + msgprint("Expected Delivery Date cannot be before Purchase Order Date") + raise Exception + # amendment date is necessary if document is amended + if self.doc.amended_from and not self.doc.amendment_date: + msgprint("Please Enter Amendment Date") + raise Exception + + # Validations of Details Table + # ----------------------------- + def validate_for_items(self): + check_list,flag = [],0 + chk_dupl_itm = [] + # Sales Order Details Validations + for d in getlist(self.doclist, 'sales_order_details'): + if cstr(self.doc.quotation_no) == cstr(d.prevdoc_docname): + flag = 1 + if d.prevdoc_docname: + if self.doc.quotation_date and getdate(self.doc.quotation_date) > getdate(self.doc.transaction_date): + msgprint("Sales Order Date cannot be before Quotation Date") + raise Exception + # validates whether quotation no in doctype and in table is same + if not cstr(d.prevdoc_docname) == cstr(self.doc.quotation_no): + msgprint("Items in table does not belong to the Quotation No mentioned.") + raise Exception - # validates whether item is not entered twice - e = [d.item_code, d.description, d.reserved_warehouse, d.prevdoc_docname or ''] - f = [d.item_code, d.description] + # validates whether item is not entered twice + e = [d.item_code, d.description, d.reserved_warehouse, d.prevdoc_docname or ''] + f = [d.item_code, d.description] - #check item is stock item - st_itm = sql("select is_stock_item from `tabItem` where name = '%s'"%d.item_code) + #check item is stock item + st_itm = sql("select is_stock_item from `tabItem` where name = '%s'"%d.item_code) - if st_itm and st_itm[0][0] == 'Yes': - if e in check_list: - msgprint("Item %s has been entered twice." % d.item_code) - else: - check_list.append(e) - elif st_itm and st_itm[0][0]== 'No': - if f in chk_dupl_itm: - msgprint("Item %s has been entered twice." % d.item_code) - else: - chk_dupl_itm.append(f) + if st_itm and st_itm[0][0] == 'Yes': + if e in check_list: + msgprint("Item %s has been entered twice." % d.item_code) + else: + check_list.append(e) + elif st_itm and st_itm[0][0]== 'No': + if f in chk_dupl_itm: + msgprint("Item %s has been entered twice." % d.item_code) + else: + chk_dupl_itm.append(f) - # used for production plan - d.transaction_date = self.doc.transaction_date - d.delivery_date = self.doc.delivery_date + # used for production plan + d.transaction_date = self.doc.transaction_date + d.delivery_date = self.doc.delivery_date - # gets total projected qty of item in warehouse selected (this case arises when warehouse is selected b4 item) - tot_avail_qty = sql("select projected_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (d.item_code,d.reserved_warehouse)) - d.projected_qty = tot_avail_qty and flt(tot_avail_qty[0][0]) or 0 - - if flag == 0: - msgprint("There are no items of the quotation selected.") - raise Exception + # gets total projected qty of item in warehouse selected (this case arises when warehouse is selected b4 item) + tot_avail_qty = sql("select projected_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (d.item_code,d.reserved_warehouse)) + d.projected_qty = tot_avail_qty and flt(tot_avail_qty[0][0]) or 0 + + if flag == 0: + msgprint("There are no items of the quotation selected.") + raise Exception - # validate sales/ service item against order type - #---------------------------------------------------- - def validate_sales_mntc_item(self): - if self.doc.order_type == 'Maintenance': - item_field = 'is_service_item' - order_type = 'Maintenance Order' - item_type = 'service item' - else : - item_field = 'is_sales_item' - order_type = 'Sales Order' - item_type = 'sales item' - - for d in getlist(self.doclist, 'sales_order_details'): - res = sql("select %s from `tabItem` where name='%s'"% (item_field,d.item_code)) - res = res and res[0][0] or 'No' - - if res == 'No': - msgprint("You can not select non "+item_type+" "+d.item_code+" in "+order_type) - raise Exception - - # validate sales/ maintenance quotation against order type - #------------------------------------------------------------------ - def validate_sales_mntc_quotation(self): - for d in getlist(self.doclist, 'sales_order_details'): - if d.prevdoc_docname: - res = sql("select order_type from `tabQuotation` where name=%s", (d.prevdoc_docname)) - res = res and res[0][0] or '' - - if self.doc.order_type== 'Maintenance' and res != 'Maintenance': - msgprint("You can not select non Maintenance Quotation against Maintenance Order") - raise Exception - elif self.doc.order_type != 'Maintenance' and res == 'Maintenance': - msgprint("You can not select non Sales Quotation against Sales Order") - raise Exception + # validate sales/ service item against order type + #---------------------------------------------------- + def validate_sales_mntc_item(self): + if self.doc.order_type == 'Maintenance': + item_field = 'is_service_item' + order_type = 'Maintenance Order' + item_type = 'service item' + else : + item_field = 'is_sales_item' + order_type = 'Sales Order' + item_type = 'sales item' + + for d in getlist(self.doclist, 'sales_order_details'): + res = sql("select %s from `tabItem` where name='%s'"% (item_field,d.item_code)) + res = res and res[0][0] or 'No' + + if res == 'No': + msgprint("You can not select non "+item_type+" "+d.item_code+" in "+order_type) + raise Exception + + # validate sales/ maintenance quotation against order type + #------------------------------------------------------------------ + def validate_sales_mntc_quotation(self): + for d in getlist(self.doclist, 'sales_order_details'): + if d.prevdoc_docname: + res = sql("select order_type from `tabQuotation` where name=%s", (d.prevdoc_docname)) + res = res and res[0][0] or '' + + if self.doc.order_type== 'Maintenance' and res != 'Maintenance': + msgprint("You can not select non Maintenance Quotation against Maintenance Order") + raise Exception + elif self.doc.order_type != 'Maintenance' and res == 'Maintenance': + msgprint("You can not select non Sales Quotation against Sales Order") + raise Exception - #do not allow sales item/quotation in maintenance order and service item/quotation in sales order - #----------------------------------------------------------------------------------------------- - def validate_order_type(self): - #validate delivery date - if self.doc.order_type != 'Maintenance' and not self.doc.delivery_date: - msgprint("Please enter 'Expected Delivery Date'") - raise Exception - - self.validate_sales_mntc_quotation() - self.validate_sales_mntc_item() + #do not allow sales item/quotation in maintenance order and service item/quotation in sales order + #----------------------------------------------------------------------------------------------- + def validate_order_type(self): + #validate delivery date + if self.doc.order_type != 'Maintenance' and not self.doc.delivery_date: + msgprint("Please enter 'Expected Delivery Date'") + raise Exception + + self.validate_sales_mntc_quotation() + self.validate_sales_mntc_item() - #check for does customer belong to same project as entered.. - #------------------------------------------------------------------------------------------------- - def validate_proj_cust(self): - if self.doc.project_name and self.doc.customer_name: - res = sql("select name from `tabProject` where name = '%s' and (customer = '%s' or ifnull(customer,'')='')"%(self.doc.project_name, self.doc.customer)) - if not res: - msgprint("Customer - %s does not belong to project - %s. \n\nIf you want to use project for multiple customers then please make customer details blank in project - %s."%(self.doc.customer,self.doc.project_name,self.doc.project_name)) - raise Exception - + #check for does customer belong to same project as entered.. + #------------------------------------------------------------------------------------------------- + def validate_proj_cust(self): + if self.doc.project_name and self.doc.customer_name: + res = sql("select name from `tabProject` where name = '%s' and (customer = '%s' or ifnull(customer,'')='')"%(self.doc.project_name, self.doc.customer)) + if not res: + msgprint("Customer - %s does not belong to project - %s. \n\nIf you want to use project for multiple customers then please make customer details blank in project - %s."%(self.doc.customer,self.doc.project_name,self.doc.project_name)) + raise Exception + - # Validate - # --------- - def validate(self): - self.validate_fiscal_year() - self.validate_order_type() - self.validate_mandatory() - self.validate_proj_cust() - self.validate_po_date() - #self.validate_reference_value() - self.validate_for_items() - sales_com_obj = get_obj(dt = 'Sales Common') - sales_com_obj.check_active_sales_items(self) - sales_com_obj.check_conversion_rate(self) + # Validate + # --------- + def validate(self): + self.validate_fiscal_year() + self.validate_order_type() + self.validate_mandatory() + self.validate_proj_cust() + self.validate_po_date() + #self.validate_reference_value() + self.validate_for_items() + sales_com_obj = get_obj(dt = 'Sales Common') + sales_com_obj.check_active_sales_items(self) + sales_com_obj.check_conversion_rate(self) - # verify whether rate is not greater than max_discount - sales_com_obj.validate_max_discount(self,'sales_order_details') - # this is to verify that the allocated % of sales persons is 100% - sales_com_obj.get_allocated_sum(self) - sales_com_obj.make_packing_list(self,'sales_order_details') - - # get total in words - dcc = TransactionBase().get_company_currency(self.doc.company) - 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.billing_status: self.doc.billing_status = 'Not Billed' - if not self.doc.delivery_status: self.doc.delivery_status = 'Not Delivered' - + # verify whether rate is not greater than max_discount + sales_com_obj.validate_max_discount(self,'sales_order_details') + # this is to verify that the allocated % of sales persons is 100% + sales_com_obj.get_allocated_sum(self) + sales_com_obj.make_packing_list(self,'sales_order_details') + + # get total in words + dcc = TransactionBase().get_company_currency(self.doc.company) + 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.billing_status: self.doc.billing_status = 'Not Billed' + if not self.doc.delivery_status: self.doc.delivery_status = 'Not Delivered' + # ON SUBMIT # =============================================================================================== - # Checks Quotation Status - # ------------------------ - def check_prev_docstatus(self): - for d in getlist(self.doclist, 'sales_order_details'): - cancel_quo = 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 = sql("select t2.prevdoc_docname from `tabQuotation` t1, `tabQuotation Detail` t2 where t2.parent = t1.name and t1.name=%s", prevdoc) - if enq: - sql("update `tabEnquiry` set status = %s where name=%s",(flag,enq[0][0])) + # Checks Quotation Status + # ------------------------ + def check_prev_docstatus(self): + for d in getlist(self.doclist, 'sales_order_details'): + cancel_quo = 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 = sql("select t2.prevdoc_docname from `tabQuotation` t1, `tabQuotation Detail` t2 where t2.parent = t1.name and t1.name=%s", prevdoc) + if enq: + sql("update `tabEnquiry` set status = %s where name=%s",(flag,enq[0][0])) - #update status of quotation, enquiry - #---------------------------------------- - def update_prevdoc_status(self, flag): - for d in getlist(self.doclist, 'sales_order_details'): - if d.prevdoc_docname: - if flag=='submit': - 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 = sql("select t1.name from `tabSales Order` t1, `tabSales Order Detail` 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: - sql("update `tabQuotation` set status = 'Submitted' where name=%s",d.prevdoc_docname) - - #update enquiry - self.update_enquiry_status(d.prevdoc_docname, 'Quotation Sent') - - # Submit - # ------- - def on_submit(self): - self.check_prev_docstatus() - self.update_stock_ledger(update_stock = 1) - self.set_sms_msg(1) - # update customer's last sales order no. - update_customer = sql("update `tabCustomer` set last_sales_order = '%s', modified = '%s' where name = '%s'" %(self.doc.name, self.doc.modified, self.doc.customer)) - get_obj('Sales Common').check_credit(self,self.doc.grand_total) - - # Check for Approving Authority - get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.grand_total, self) - - #update prevdoc status - self.update_prevdoc_status('submit') - # set SO status - set(self.doc, 'status', 'Submitted') - - # on submit notification - if self.doc.email_id: - get_obj('Notification Control').notify_contact('Sales Order',self.doc.doctype,self.doc.name, self.doc.email_id, self.doc.contact_person) - + #update status of quotation, enquiry + #---------------------------------------- + def update_prevdoc_status(self, flag): + for d in getlist(self.doclist, 'sales_order_details'): + if d.prevdoc_docname: + if flag=='submit': + 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 = sql("select t1.name from `tabSales Order` t1, `tabSales Order Detail` 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: + sql("update `tabQuotation` set status = 'Submitted' where name=%s",d.prevdoc_docname) + + #update enquiry + self.update_enquiry_status(d.prevdoc_docname, 'Quotation Sent') + + # Submit + # ------- + def on_submit(self): + self.check_prev_docstatus() + self.update_stock_ledger(update_stock = 1) + self.set_sms_msg(1) + # update customer's last sales order no. + update_customer = sql("update `tabCustomer` set last_sales_order = '%s', modified = '%s' where name = '%s'" %(self.doc.name, self.doc.modified, self.doc.customer)) + get_obj('Sales Common').check_credit(self,self.doc.grand_total) + + # Check for Approving Authority + get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.grand_total, self) + + #update prevdoc status + self.update_prevdoc_status('submit') + # set SO status + set(self.doc, 'status', 'Submitted') + + # on submit notification + if self.doc.email_id: + get_obj('Notification Control').notify_contact('Sales Order',self.doc.doctype,self.doc.name, self.doc.email_id, self.doc.contact_person) + # ON CANCEL # =============================================================================================== - def on_cancel(self): - # Cannot cancel stopped SO - if self.doc.status == 'Stopped': - msgprint("Sales Order : '%s' cannot be cancelled as it is Stopped. Unstop it for any further transactions" %(self.doc.name)) - raise Exception - self.check_nextdoc_docstatus() - self.update_stock_ledger(update_stock = -1) - self.set_sms_msg() - - #update prevdoc status - self.update_prevdoc_status('cancel') - - # ::::::::: SET SO STATUS :::::::::: - set(self.doc, 'status', 'Cancelled') - - # CHECK NEXT DOCSTATUS - # does not allow to cancel document if DN or RV made against it is SUBMITTED - # ---------------------------------------------------------------------------- - def check_nextdoc_docstatus(self): - # Checks Delivery Note - submit_dn = sql("select t1.name from `tabDelivery Note` t1,`tabDelivery Note Detail` t2 where t1.name = t2.parent and t2.prevdoc_docname = '%s' and t1.docstatus = 1" % (self.doc.name)) - if submit_dn: - msgprint("Delivery Note : " + cstr(submit_dn[0][0]) + " has been submitted against " + cstr(self.doc.doctype) + ". Please cancel Delivery Note : " + cstr(submit_dn[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1) - # Checks Receivable Voucher - submit_rv = sql("select t1.name from `tabReceivable Voucher` t1,`tabRV Detail` t2 where t1.name = t2.parent and t2.sales_order = '%s' and t1.docstatus = 1" % (self.doc.name)) - if submit_rv: - msgprint("Sales Invoice : " + cstr(submit_rv[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Sales Invoice : "+ cstr(submit_rv[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1) - #check maintenance schedule - submit_ms = sql("select t1.name from `tabMaintenance Schedule` t1, `tabItem Maintenance Detail` t2 where t2.parent=t1.name and t2.prevdoc_docname = %s and t1.docstatus = 1",self.doc.name) - if submit_ms: - msgprint("Maintenance Schedule : " + cstr(submit_ms[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Maintenance Schedule : "+ cstr(submit_ms[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1) - submit_mv = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Detail` t2 where t2.parent=t1.name and t2.prevdoc_docname = %s and t1.docstatus = 1",self.doc.name) - if submit_mv: - msgprint("Maintenance Visit : " + cstr(submit_mv[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Maintenance Visit : " + cstr(submit_mv[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1) + def on_cancel(self): + # Cannot cancel stopped SO + if self.doc.status == 'Stopped': + msgprint("Sales Order : '%s' cannot be cancelled as it is Stopped. Unstop it for any further transactions" %(self.doc.name)) + raise Exception + self.check_nextdoc_docstatus() + self.update_stock_ledger(update_stock = -1) + self.set_sms_msg() + + #update prevdoc status + self.update_prevdoc_status('cancel') + + # ::::::::: SET SO STATUS :::::::::: + set(self.doc, 'status', 'Cancelled') + + # CHECK NEXT DOCSTATUS + # does not allow to cancel document if DN or RV made against it is SUBMITTED + # ---------------------------------------------------------------------------- + def check_nextdoc_docstatus(self): + # Checks Delivery Note + submit_dn = sql("select t1.name from `tabDelivery Note` t1,`tabDelivery Note Detail` t2 where t1.name = t2.parent and t2.prevdoc_docname = '%s' and t1.docstatus = 1" % (self.doc.name)) + if submit_dn: + msgprint("Delivery Note : " + cstr(submit_dn[0][0]) + " has been submitted against " + cstr(self.doc.doctype) + ". Please cancel Delivery Note : " + cstr(submit_dn[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1) + # Checks Receivable Voucher + submit_rv = sql("select t1.name from `tabReceivable Voucher` t1,`tabRV Detail` t2 where t1.name = t2.parent and t2.sales_order = '%s' and t1.docstatus = 1" % (self.doc.name)) + if submit_rv: + msgprint("Sales Invoice : " + cstr(submit_rv[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Sales Invoice : "+ cstr(submit_rv[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1) + #check maintenance schedule + submit_ms = sql("select t1.name from `tabMaintenance Schedule` t1, `tabItem Maintenance Detail` t2 where t2.parent=t1.name and t2.prevdoc_docname = %s and t1.docstatus = 1",self.doc.name) + if submit_ms: + msgprint("Maintenance Schedule : " + cstr(submit_ms[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Maintenance Schedule : "+ cstr(submit_ms[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1) + submit_mv = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Detail` t2 where t2.parent=t1.name and t2.prevdoc_docname = %s and t1.docstatus = 1",self.doc.name) + if submit_mv: + msgprint("Maintenance Visit : " + cstr(submit_mv[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Maintenance Visit : " + cstr(submit_mv[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1) - def check_modified_date(self): - mod_db = sql("select modified from `tabSales Order` where name = '%s'" % self.doc.name) - date_diff = sql("select TIMEDIFF('%s', '%s')" % ( mod_db[0][0],cstr(self.doc.modified))) - - if date_diff and date_diff[0][0]: - msgprint(cstr(self.doc.doctype) +" => "+ cstr(self.doc.name) +" has been modified. Please Refresh. ") - raise Exception + def check_modified_date(self): + mod_db = sql("select modified from `tabSales Order` where name = '%s'" % self.doc.name) + date_diff = sql("select TIMEDIFF('%s', '%s')" % ( mod_db[0][0],cstr(self.doc.modified))) + + if date_diff and date_diff[0][0]: + msgprint(cstr(self.doc.doctype) +" => "+ cstr(self.doc.name) +" has been modified. Please Refresh. ") + raise Exception - # STOP SALES ORDER - # ============================================================================================== - # Stops Sales Order & no more transactions will be created against this Sales Order - def stop_sales_order(self): - self.check_modified_date() - self.update_stock_ledger(update_stock = -1,clear = 1) - # ::::::::: SET SO STATUS :::::::::: - set(self.doc, 'status', 'Stopped') - msgprint(self.doc.doctype + ": " + self.doc.name + " has been Stopped. To make transactions against this Sales Order you need to Unstop it.") + # STOP SALES ORDER + # ============================================================================================== + # Stops Sales Order & no more transactions will be created against this Sales Order + def stop_sales_order(self): + self.check_modified_date() + self.update_stock_ledger(update_stock = -1,clear = 1) + # ::::::::: SET SO STATUS :::::::::: + set(self.doc, 'status', 'Stopped') + msgprint(self.doc.doctype + ": " + self.doc.name + " has been Stopped. To make transactions against this Sales Order you need to Unstop it.") - # UNSTOP SALES ORDER - # ============================================================================================== - # Unstops Sales Order & now transactions can be continued against this Sales Order - def unstop_sales_order(self): - self.check_modified_date() - self.update_stock_ledger(update_stock = 1,clear = 1) - # ::::::::: SET SO STATUS :::::::::: - set(self.doc, 'status', 'Submitted') - msgprint(self.doc.doctype + ": " + self.doc.name + " has been Unstopped.") + # UNSTOP SALES ORDER + # ============================================================================================== + # Unstops Sales Order & now transactions can be continued against this Sales Order + def unstop_sales_order(self): + self.check_modified_date() + self.update_stock_ledger(update_stock = 1,clear = 1) + # ::::::::: SET SO STATUS :::::::::: + set(self.doc, 'status', 'Submitted') + msgprint(self.doc.doctype + ": " + self.doc.name + " has been Unstopped.") - # UPDATE STOCK LEDGER - # =============================================================================================== - def update_stock_ledger(self, update_stock, clear = 0): - for d in self.get_item_list(clear): - stock_item = sql("SELECT is_stock_item FROM tabItem where name = '%s'"%(d[1]),as_dict = 1) # stock ledger will be updated only if it is a stock item - if stock_item and stock_item[0]['is_stock_item'] == "Yes": - if not d[0]: - msgprint("Message: Please enter Reserved Warehouse for item %s as it is stock item."% d[1]) - raise Exception - bin = get_obj('Warehouse', d[0]).update_bin( 0, flt(update_stock) * flt(d[2]), 0, 0, 0, d[1], self.doc.transaction_date) + # UPDATE STOCK LEDGER + # =============================================================================================== + def update_stock_ledger(self, update_stock, clear = 0): + for d in self.get_item_list(clear): + stock_item = sql("SELECT is_stock_item FROM tabItem where name = '%s'"%(d[1]),as_dict = 1) # stock ledger will be updated only if it is a stock item + if stock_item and stock_item[0]['is_stock_item'] == "Yes": + if not d[0]: + msgprint("Message: Please enter Reserved Warehouse for item %s as it is stock item."% d[1]) + raise Exception + bin = get_obj('Warehouse', d[0]).update_bin( 0, flt(update_stock) * flt(d[2]), 0, 0, 0, d[1], self.doc.transaction_date) + + # Gets Items from packing list + #================================= + def get_item_list(self, clear): + return get_obj('Sales Common').get_item_list( self, clear) + + # SET MESSAGE FOR SMS + #====================== + def set_sms_msg(self, is_submitted = 0): + if is_submitted: + if not self.doc.amended_from: + msg = 'Sales Order: '+self.doc.name+' has been made against PO no: '+cstr(self.doc.po_no) + set(self.doc, 'message', msg) + else: + msg = 'Sales Order has been amended. New SO no:'+self.doc.name + set(self.doc, 'message', msg) + else: + msg = 'Sales Order: '+self.doc.name+' has been cancelled.' + set(self.doc, 'message', msg) + + # SEND SMS + # ========= + def send_sms(self): + if not self.doc.customer_mobile_no: + msgprint("Please enter customer mobile no") + elif not self.doc.message: + msgprint("Please enter the message you want to send") + else: + msgprint(get_obj("SMS Control", "SMS Control").send_sms([self.doc.customer_mobile_no,], self.doc.message)) - # Gets Items from packing list - #================================= - def get_item_list(self, clear): - return get_obj('Sales Common').get_item_list( self, clear) - - # SET MESSAGE FOR SMS - #====================== - def set_sms_msg(self, is_submitted = 0): - if is_submitted: - if not self.doc.amended_from: - msg = 'Sales Order: '+self.doc.name+' has been made against PO no: '+cstr(self.doc.po_no) - set(self.doc, 'message', msg) - else: - msg = 'Sales Order has been amended. New SO no:'+self.doc.name - set(self.doc, 'message', msg) - else: - msg = 'Sales Order: '+self.doc.name+' has been cancelled.' - set(self.doc, 'message', msg) - - # SEND SMS - # ========= - def send_sms(self): - if not self.doc.customer_mobile_no: - msgprint("Please enter customer mobile no") - elif not self.doc.message: - msgprint("Please enter the message you want to send") - else: - msgprint(get_obj("SMS Control", "SMS Control").send_sms([self.doc.customer_mobile_no,], self.doc.message)) + # on update + def on_update(self): + pass - # on update - def on_update(self): - pass - - # Repair Sales Order - # =========================================== - def repair_sales_order(self): - get_obj('Sales Common', 'Sales Common').repair_curr_doctype_details(self) + # Repair Sales Order + # =========================================== + def repair_sales_order(self): + get_obj('Sales Common', 'Sales Common').repair_curr_doctype_details(self) From bff6e2873d8c6cd6871bdb885fca217391e440fe Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 5 Aug 2011 11:17:40 +0530 Subject: [PATCH 07/11] removed uncompleted testcase for delivery note --- stock/doctype/delivery_note/tests.py | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 stock/doctype/delivery_note/tests.py diff --git a/stock/doctype/delivery_note/tests.py b/stock/doctype/delivery_note/tests.py deleted file mode 100644 index df04c417fa..0000000000 --- a/stock/doctype/delivery_note/tests.py +++ /dev/null @@ -1,25 +0,0 @@ -import unittest -import webnotes - -from webnotes.model.code import get_obj - -class SubmissionTest(unittest.TestCase): - def setUp(self): - self.dn = webnotes.testing.create('Delivery Note') - self.dn_items = [] - - # get a line item for testing - for d in self.dn.doclist: - if d.doctype=='Delivery Note Detail': - self.dn_items.append(d) - - self.old_bin = get_obj('Warehouse', self.line_item[0].warehouse).get_bin(self.line_item[0].item_code) - self.dn.on_submit() - - def test_bin_is_updated(self): - "tests if bin quantity is affected when on submission" - bin = get_obj('Warehouse', self.line_item.warehouse).get_bin(self.line_item[0].item_code) - self.assertTrue(bin.actual_qty == self.old_bin.actual_qty - self.line_item[0].qty) - - def test_sales_order_is_updated(self): - "tests if" \ No newline at end of file From c4e579c90116673184af5914f429f6912ff821b3 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 5 Aug 2011 11:21:35 +0530 Subject: [PATCH 08/11] reloaded answer doctype --- patches/patch.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/patches/patch.py b/patches/patch.py index 1635382a1e..40e7d3a004 100644 --- a/patches/patch.py +++ b/patches/patch.py @@ -1,7 +1,7 @@ # REMEMBER to update this # ======================== -last_patch = 333 +last_patch = 334 #------------------------------------------- @@ -1343,3 +1343,5 @@ def execute(patch_no): p.add_permission('DocType Mapper', 'System Manager', 0, read = 1, write=1, create=1) p.add_permission('Role', 'System Manager', 0, read = 1, write=1, create=1) p.add_permission('Print Format', 'System Manager', 0, read = 1, write=1, create=1) + elif patch_no == 334: + reload_doc('knowledge_base', 'doctype', 'answer') From f82b1cc4bd04ab9be4f30882b0ce538e510d12b3 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 5 Aug 2011 13:23:14 +0530 Subject: [PATCH 09/11] old_parent field in account is linked to Account now, it will fix account renaming bug --- accounts/doctype/account/account.txt | 5 +++-- patches/patch.py | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/accounts/doctype/account/account.txt b/accounts/doctype/account/account.txt index b29c61782f..bf48a24d0c 100644 --- a/accounts/doctype/account/account.txt +++ b/accounts/doctype/account/account.txt @@ -455,7 +455,8 @@ 'description': "Don't delete this field at any cost", 'doctype': 'DocField', 'fieldname': 'old_parent', - 'fieldtype': 'Data', + 'fieldtype': 'Link', + 'options': 'Account', 'hidden': 1, 'idx': 24, 'label': 'Old Parent', @@ -517,4 +518,4 @@ 'oldfieldtype': 'Small Text', 'permlevel': 1 } -] \ No newline at end of file +] diff --git a/patches/patch.py b/patches/patch.py index 40e7d3a004..be26d717f6 100644 --- a/patches/patch.py +++ b/patches/patch.py @@ -1,7 +1,7 @@ # REMEMBER to update this # ======================== -last_patch = 334 +last_patch = 335 #------------------------------------------- @@ -1345,3 +1345,5 @@ def execute(patch_no): p.add_permission('Print Format', 'System Manager', 0, read = 1, write=1, create=1) elif patch_no == 334: reload_doc('knowledge_base', 'doctype', 'answer') + elif patch_no == 335: + sql("update `tabDocField` set fieldtype = 'Link', options = 'Account' where fieldname = 'old_parent' and parent = 'Account'") From 2c0ab739483a5b4491412696cccab999f04d4822 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 5 Aug 2011 13:40:04 +0530 Subject: [PATCH 10/11] old_parent field is Link to parent dt now in account, cost center, item group, cust group, territory. It will fix renaming bug --- patches/patch.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/patches/patch.py b/patches/patch.py index be26d717f6..eed12c4f79 100644 --- a/patches/patch.py +++ b/patches/patch.py @@ -1346,4 +1346,5 @@ def execute(patch_no): elif patch_no == 334: reload_doc('knowledge_base', 'doctype', 'answer') elif patch_no == 335: - sql("update `tabDocField` set fieldtype = 'Link', options = 'Account' where fieldname = 'old_parent' and parent = 'Account'") + for dt in ['Account', 'Cost Center', 'Territory', 'Item Group', 'Customer Group']: + sql("update `tabDocField` set fieldtype = 'Link', options = %s where fieldname = 'old_parent' and parent = %s", (dt, dt)) From 3cb7b165d1cb3a0708c05c9c28ca70ef6f36ed8f Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 8 Aug 2011 14:58:38 +0530 Subject: [PATCH 11/11] considered half day lwp in sal slip --- .../budget_variance_report.py | 3 +- .../leave_application/leave_application.js | 6 +- hr/doctype/salary_slip/salary_slip.js | 2 +- hr/doctype/salary_slip/salary_slip.py | 399 +++++++++--------- 4 files changed, 209 insertions(+), 201 deletions(-) diff --git a/accounts/search_criteria/budget_variance_report/budget_variance_report.py b/accounts/search_criteria/budget_variance_report/budget_variance_report.py index 2efca2833e..182f9e5356 100644 --- a/accounts/search_criteria/budget_variance_report/budget_variance_report.py +++ b/accounts/search_criteria/budget_variance_report/budget_variance_report.py @@ -51,7 +51,6 @@ for r in res: q1 = "select sum(t1.budget_allocated) from `tabBudget Detail` t1, `tab%s` t2, `tabAccount` t3 where " cond2 = " t3.is_pl_account = 'Yes' and t3.debit_or_credit = 'Debit' and t3.name = t1.account and t1.docstatus != 2 and " if ch: - qur = q1+cond2+cond1+" and t2.name = '%s'" ret_amt = sql(qur%(based_on,fiscal_year,based_on,r[0].strip())) @@ -170,4 +169,4 @@ for r in res: r.append(actual) # ================ Variance =================================================== r.append(r[idx] - r[idx + 1]) - count = count +1 \ No newline at end of file + count = count +1 diff --git a/hr/doctype/leave_application/leave_application.js b/hr/doctype/leave_application/leave_application.js index ba00a31a7c..9fc1e428a8 100755 --- a/hr/doctype/leave_application/leave_application.js +++ b/hr/doctype/leave_application/leave_application.js @@ -52,12 +52,12 @@ cur_frm.cscript.from_date = function(doc, dt, dn) { // to date // -------- cur_frm.cscript.to_date = function(doc, dt, dn) { - if(cint(doc.half_day) == 1 && doc.from_date && doc.from_date != doc.to_date){ + if(cint(doc.half_day) == 1 && cstr(doc.from_date) && doc.from_date != doc.to_date){ msgprint("To Date should be same as From Date for Half Day leave"); - return; + set_multiple(dt,dn,{to_date:doc.from_date}); } if(cint(doc.half_day) == 1){ - set_multiple(dt,dn,{to_date:doc.from_date}); + } calculate_total_days(doc, dt, dn); } diff --git a/hr/doctype/salary_slip/salary_slip.js b/hr/doctype/salary_slip/salary_slip.js index 8c76b1e7c9..8f953e61ca 100644 --- a/hr/doctype/salary_slip/salary_slip.js +++ b/hr/doctype/salary_slip/salary_slip.js @@ -29,7 +29,7 @@ cur_frm.cscript.month = cur_frm.cscript.employee = cur_frm.cscript.fiscal_year; // Calculate total if lwp exists // ------------------------------------------------------------------------ cur_frm.cscript.leave_without_pay = function(doc,dt,dn){ - doc.payment_days = cint(doc.total_days_in_month) - cint(doc.leave_without_pay); + doc.payment_days = flt(doc.total_days_in_month) - flt(doc.leave_without_pay); refresh_field('payment_days'); calculate_all(doc, dt, dn); } diff --git a/hr/doctype/salary_slip/salary_slip.py b/hr/doctype/salary_slip/salary_slip.py index 9c94885963..af55956149 100644 --- a/hr/doctype/salary_slip/salary_slip.py +++ b/hr/doctype/salary_slip/salary_slip.py @@ -18,210 +18,219 @@ convert_to_lists = webnotes.conn.convert_to_lists from utilities.transaction_base import TransactionBase class DocType(TransactionBase): - def __init__(self,doc,doclist=[]): - self.doc = doc - self.doclist = doclist - - - # autoname - #======================================================= - def autoname(self): - self.doc.name = make_autoname('Sal Slip/' +self.doc.employee + '/.#####') + def __init__(self,doc,doclist=[]): + self.doc = doc + self.doclist = doclist + + + # autoname + #======================================================= + def autoname(self): + self.doc.name = make_autoname('Sal Slip/' +self.doc.employee + '/.#####') - # Get employee details - #======================================================= - def get_emp_and_leave_details(self): - # Get payment days - if self.doc.fiscal_year and self.doc.month: - self.get_leave_details() + # Get employee details + #======================================================= + def get_emp_and_leave_details(self): + # Get payment days + if self.doc.fiscal_year and self.doc.month: + self.get_leave_details() - # check sal structure - if self.doc.employee: - struct = self.check_sal_struct() - if struct: - self.pull_sal_struct(struct) + # check sal structure + if self.doc.employee: + struct = self.check_sal_struct() + if struct: + self.pull_sal_struct(struct) - # Check sal structure - #======================================================= - def check_sal_struct(self): - struct = sql("select name from `tabSalary Structure` where employee ='%s' and is_active = 'Yes' "%self.doc.employee) - if not struct: - msgprint("Please create Salary Structure for employee '%s'"%self.doc.employee) - self.doc.employee = '' - return struct and struct[0][0] or '' + # Check sal structure + #======================================================= + def check_sal_struct(self): + struct = sql("select name from `tabSalary Structure` where employee ='%s' and is_active = 'Yes' "%self.doc.employee) + if not struct: + msgprint("Please create Salary Structure for employee '%s'"%self.doc.employee) + self.doc.employee = '' + return struct and struct[0][0] or '' - # Pull struct details - #======================================================= - def pull_sal_struct(self, struct): - self.doc.clear_table(self.doclist, 'earning_details') - self.doc.clear_table(self.doclist, 'deduction_details') + # Pull struct details + #======================================================= + def pull_sal_struct(self, struct): + self.doc.clear_table(self.doclist, 'earning_details') + self.doc.clear_table(self.doclist, 'deduction_details') - get_obj('DocType Mapper', 'Salary Structure-Salary Slip').dt_map('Salary Structure', 'Salary Slip', struct, self.doc, self.doclist, "[['Salary Structure', 'Salary Slip'],['Earning Detail', 'SS Earning Detail'],['Deduction Detail','SS Deduction Detail']]") + get_obj('DocType Mapper', 'Salary Structure-Salary Slip').dt_map('Salary Structure', 'Salary Slip', struct, self.doc, self.doclist, "[['Salary Structure', 'Salary Slip'],['Earning Detail', 'SS Earning Detail'],['Deduction Detail','SS Deduction Detail']]") - basic_info = sql("select bank_name, bank_ac_no, esic_card_no, pf_number from `tabEmployee` where name ='%s'" % self.doc.employee) - self.doc.bank_name = basic_info[0][0] - self.doc.bank_account_no = basic_info[0][1] - self.doc.esic_no = basic_info[0][2] - self.doc.pf_no = basic_info[0][3] + basic_info = sql("select bank_name, bank_ac_no, esic_card_no, pf_number from `tabEmployee` where name ='%s'" % self.doc.employee) + self.doc.bank_name = basic_info[0][0] + self.doc.bank_account_no = basic_info[0][1] + self.doc.esic_no = basic_info[0][2] + self.doc.pf_no = basic_info[0][3] - # Get leave details - #======================================================= - def get_leave_details(self): - m = self.get_month_details() - lwp = self.calculate_lwp(m) - self.doc.total_days_in_month = m[3] - self.doc.leave_without_pay = lwp - self.doc.payment_days = flt(m[3]) - flt(lwp) + # Get leave details + #======================================================= + def get_leave_details(self): + m = self.get_month_details() + lwp = self.calculate_lwp(m) + self.doc.total_days_in_month = m[3] + self.doc.leave_without_pay = lwp + self.doc.payment_days = flt(m[3]) - flt(lwp) - # Get month details - #======================================================= - def get_month_details(self): - ysd = sql("select year_start_date from `tabFiscal Year` where name ='%s'"%self.doc.fiscal_year)[0][0] - if ysd: - from dateutil.relativedelta import relativedelta - import calendar, datetime - mnt = int(self.doc.month) - diff_mnt = int(mnt)-int(ysd.month) - if diff_mnt<0: - diff_mnt = 12-int(ysd.month)+int(mnt) - msd = ysd + relativedelta(months=diff_mnt) # month start date - month_days = cint(calendar.monthrange(cint(msd.year) ,cint(self.doc.month))[1]) # days in month - med = datetime.date(msd.year, cint(self.doc.month), month_days) # month end date - return msd.year, msd, med, month_days + # Get month details + #======================================================= + def get_month_details(self): + ysd = sql("select year_start_date from `tabFiscal Year` where name ='%s'"%self.doc.fiscal_year)[0][0] + if ysd: + from dateutil.relativedelta import relativedelta + import calendar, datetime + mnt = int(self.doc.month) + diff_mnt = int(mnt)-int(ysd.month) + if diff_mnt<0: + diff_mnt = 12-int(ysd.month)+int(mnt) + msd = ysd + relativedelta(months=diff_mnt) # month start date + month_days = cint(calendar.monthrange(cint(msd.year) ,cint(self.doc.month))[1]) # days in month + med = datetime.date(msd.year, cint(self.doc.month), month_days) # month end date + return msd.year, msd, med, month_days - # Calculate LWP - #======================================================= - def calculate_lwp(self, m): - holidays = sql("select t1.holiday_date from `tabHoliday List Detail` t1, tabEmployee t2 where t1.parent = t2.holiday_list and t2.name = '%s' and t1.holiday_date between '%s' and '%s'" % (self.doc.employee, m[1], m[2])) - if not holidays: - holidays = sql("select t1.holiday_date from `tabHoliday List Detail` t1, `tabHoliday List` t2 where t1.parent = t2.name and ifnull(t2.is_default, 0) = 1 and t2.fiscal_year = '%s'" % self.doc.fiscal_year) - holidays = [cstr(i[0]) for i in holidays] - lwp = 0 - for d in range(m[3]): - dt = add_days(cstr(m[1]), d) - if dt not in holidays: - if sql("select t1.name from `tabLeave Application` t1, `tabLeave Type` t2 where t2.name = t1.leave_type and ifnull(t2.is_lwp, 0) = 1 and t1.docstatus = 1 and t1.employee = '%s' and '%s' between from_date and to_date"%(self.doc.employee, dt)): - lwp += 1 - return lwp - - # Check existing - #======================================================= - def check_existing(self): - ret_exist = sql("select name from `tabSalary Slip` where month = '%s' and fiscal_year = '%s' and docstatus != 2 and employee = '%s' and name !='%s'" % (self.doc.month,self.doc.fiscal_year,self.doc.employee,self.doc.name)) - if ret_exist: - msgprint("Salary Slip of employee '%s' already created for this month" % self.doc.employee) - self.doc.employee = '' - raise Exception + # Calculate LWP + #======================================================= + def calculate_lwp(self, m): + holidays = sql("select t1.holiday_date from `tabHoliday List Detail` t1, tabEmployee t2 where t1.parent = t2.holiday_list and t2.name = '%s' and t1.holiday_date between '%s' and '%s'" % (self.doc.employee, m[1], m[2])) + if not holidays: + holidays = sql("select t1.holiday_date from `tabHoliday List Detail` t1, `tabHoliday List` t2 where t1.parent = t2.name and ifnull(t2.is_default, 0) = 1 and t2.fiscal_year = '%s'" % self.doc.fiscal_year) + holidays = [cstr(i[0]) for i in holidays] + lwp = 0 + for d in range(m[3]): + dt = add_days(cstr(m[1]), d) + if dt not in holidays: + leave = sql(""" + select t1.name, t1.half_day + from `tabLeave Application` t1, `tabLeave Type` t2 + where t2.name = t1.leave_type + and ifnull(t2.is_lwp, 0) = 1 + and t1.docstatus = 1 + and t1.employee = '%s' + and '%s' between from_date and to_date + """%(self.doc.employee, dt)) + if leave: + lwp = cint(leave[0][1]) and lwp + 0.5 or lwp + 1 + return lwp + + # Check existing + #======================================================= + def check_existing(self): + ret_exist = sql("select name from `tabSalary Slip` where month = '%s' and fiscal_year = '%s' and docstatus != 2 and employee = '%s' and name !='%s'" % (self.doc.month,self.doc.fiscal_year,self.doc.employee,self.doc.name)) + if ret_exist: + msgprint("Salary Slip of employee '%s' already created for this month" % self.doc.employee) + self.doc.employee = '' + raise Exception - # Validate - #======================================================= - def validate(self): - self.check_existing() - dcc = TransactionBase().get_company_currency(self.doc.company) - self.doc.total_in_words = get_obj('Sales Common').get_total_in_words(dcc, self.doc.rounded_total) - - # ON SUBMIT - #======================================================= - def on_submit(self): - if(self.doc.email_check == 1): - self.send_mail_funct() + # Validate + #======================================================= + def validate(self): + self.check_existing() + dcc = TransactionBase().get_company_currency(self.doc.company) + self.doc.total_in_words = get_obj('Sales Common').get_total_in_words(dcc, self.doc.rounded_total) + + # ON SUBMIT + #======================================================= + def on_submit(self): + if(self.doc.email_check == 1): + self.send_mail_funct() - # Send mail - #======================================================= - def send_mail_funct(self): - emailid_ret=sql("select company_email from `tabEmployee` where name = '%s'"%self.doc.employee) - if emailid_ret: - receiver = cstr(emailid_ret[0][0]) - subj = 'Salary Slip ' + cstr(self.doc.month) +' '+cstr(self.doc.year) - earn_ret=sql("select e_type,e_amount from `tabSS Earning Detail` where parent = '%s'"%self.doc.name) - ded_ret=sql("select d_type,d_amount from `tabSS Deduction Detail` where parent = '%s'"%self.doc.name) - - earn_table = '' - ded_table = '' - if earn_ret: - - earn_table += "" - - for e in earn_ret: - if not e[1]: - earn_table +=''%(cstr(e[0])) - else: - earn_table +=''%(cstr(e[0]),cstr(e[1])) - earn_table += '
%s0.00
%s%s
' - - if ded_ret: - - ded_table += "" - - for d in ded_ret: - if not d[1]: - ded_table +=''%(cstr(d[0])) - else: - ded_table +=''%(cstr(d[0]),cstr(d[1])) - ded_table += '
%s0.00
%s%s
' - - letter_head = sql("select value from `tabSingles` where field = 'letter_head' and doctype = 'Control Panel'") - - if not letter_head: - letter_head = '' - - msg = ''' %s
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - -
- - - - - - - - -

Salary Slip

Employee Code : %sEmployee Name : %s
Month : %sYear : %sFiscal Year : %s
Department : %sBranch : %sDesignation : %s
Grade : %sBank Account No. : %sBank Name : %s
PF No. : %sESIC No. : %sArrear Amount : %s
Total days in month : %sLeave Without Pay : %sPayment days : %s
EarningDeduction
%s%s
Gross Pay : %sTotal Deduction : %s
Net Pay : %sNet Pay (in words) : %s
'''%(cstr(letter_head[0][0]),cstr(self.doc.employee),self.doc.employee_name,cstr(self.doc.month),cstr(self.doc.year),cstr(self.doc.fiscal_year),self.doc.department,self.doc.branch,self.doc.designation,self.doc.grade,cstr(self.doc.bank_account_no),self.doc.bank_name,cstr(self.doc.pf_no),cstr(self.doc.esic_no),cstr(self.doc.arrear_amount),cstr(self.doc.total_days_in_month),cstr(self.doc.leave_without_pay),cstr(self.doc.payment_days),earn_table,ded_table,cstr(self.doc.gross_pay),cstr(self.doc.total_deduction),cstr(self.doc.net_pay),cstr(self.doc.net_pay_in_words)) - sendmail([receiver], sender='automail@webnotestech.com', subject=subj, parts=[['text/plain', msg]]) - else: - msgprint("Company Email ID not found.") + # Send mail + #======================================================= + def send_mail_funct(self): + emailid_ret=sql("select company_email from `tabEmployee` where name = '%s'"%self.doc.employee) + if emailid_ret: + receiver = cstr(emailid_ret[0][0]) + subj = 'Salary Slip ' + cstr(self.doc.month) +' '+cstr(self.doc.year) + earn_ret=sql("select e_type,e_amount from `tabSS Earning Detail` where parent = '%s'"%self.doc.name) + ded_ret=sql("select d_type,d_amount from `tabSS Deduction Detail` where parent = '%s'"%self.doc.name) + + earn_table = '' + ded_table = '' + if earn_ret: + + earn_table += "" + + for e in earn_ret: + if not e[1]: + earn_table +=''%(cstr(e[0])) + else: + earn_table +=''%(cstr(e[0]),cstr(e[1])) + earn_table += '
%s0.00
%s%s
' + + if ded_ret: + + ded_table += "" + + for d in ded_ret: + if not d[1]: + ded_table +=''%(cstr(d[0])) + else: + ded_table +=''%(cstr(d[0]),cstr(d[1])) + ded_table += '
%s0.00
%s%s
' + + letter_head = sql("select value from `tabSingles` where field = 'letter_head' and doctype = 'Control Panel'") + + if not letter_head: + letter_head = '' + + msg = ''' %s
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + + + + + + + +
+ + + + + + + + +

Salary Slip

Employee Code : %sEmployee Name : %s
Month : %sYear : %sFiscal Year : %s
Department : %sBranch : %sDesignation : %s
Grade : %sBank Account No. : %sBank Name : %s
PF No. : %sESIC No. : %sArrear Amount : %s
Total days in month : %sLeave Without Pay : %sPayment days : %s
EarningDeduction
%s%s
Gross Pay : %sTotal Deduction : %s
Net Pay : %sNet Pay (in words) : %s
'''%(cstr(letter_head[0][0]),cstr(self.doc.employee),self.doc.employee_name,cstr(self.doc.month),cstr(self.doc.year),cstr(self.doc.fiscal_year),self.doc.department,self.doc.branch,self.doc.designation,self.doc.grade,cstr(self.doc.bank_account_no),self.doc.bank_name,cstr(self.doc.pf_no),cstr(self.doc.esic_no),cstr(self.doc.arrear_amount),cstr(self.doc.total_days_in_month),cstr(self.doc.leave_without_pay),cstr(self.doc.payment_days),earn_table,ded_table,cstr(self.doc.gross_pay),cstr(self.doc.total_deduction),cstr(self.doc.net_pay),cstr(self.doc.net_pay_in_words)) + sendmail([receiver], sender='automail@webnotestech.com', subject=subj, parts=[['text/plain', msg]]) + else: + msgprint("Company Email ID not found.")