diff --git a/accounts/doctype/fiscal_year/fiscal_year.py b/accounts/doctype/fiscal_year/fiscal_year.py index 6dd4f2ca90..6b2dfdedec 100644 --- a/accounts/doctype/fiscal_year/fiscal_year.py +++ b/accounts/doctype/fiscal_year/fiscal_year.py @@ -21,31 +21,34 @@ class DocType: def __init__(self, d, dl): self.doc, self.doclist = d,dl - def repost(self): + def repost(self, account = ''): if not self.doc.company: msgprint("Please select company", raise_exception=1) if not in_transaction: sql("start transaction") - self.clear_account_balances() - self.create_account_balances() - self.update_opening() - self.post_entries() + self.clear_account_balances(account) + self.create_account_balances(account) + self.update_opening(account) + self.post_entries(account) sql("commit") - msgprint("Account balance reposted") + + msg_cond = account and " and account: " + account or "" + msgprint("Account balance reposted for fiscal year: " + self.doc.name + msg_cond) - def clear_account_balances(self): + def clear_account_balances(self, account = ''): # balances clear - `tabAccount Balance` for fiscal year - sql("update `tabAccount Balance` set opening=0, balance=0, debit=0, credit=0 where fiscal_year=%s", self.doc.name) + cond = account and (" and account = '" + account + "'") or '' + sql("update `tabAccount Balance` set opening=0, balance=0, debit=0, credit=0 where fiscal_year=%s %s", (self.doc.name, cond)) - def create_account_balances(self): + def create_account_balances(self, account = ''): # get periods period_list = self.get_period_list() cnt = 0 # get accounts - al = sql("select name from tabAccount") + al = account and [[account]] or sql("select name from tabAccount") for a in al: # check @@ -80,9 +83,14 @@ class DocType: return periods # ==================================================================================== - def update_opening(self): - # set opening from last year closing - abl = sql("select t1.account, t1.balance from `tabAccount Balance` t1, tabAccount t2 where t1.period=%s and t2.company=%s and ifnull(t2.is_pl_account, 'No') = 'No' and t1.account = t2.name for update", (self.doc.past_year, self.doc.company)) + def update_opening(self, account = ''): + """ + set opening from last year closing + + """ + cond = account and (" and t2.name = '" + account + "'") or '' + + abl = sql("select t1.account, t1.balance from `tabAccount Balance` t1, tabAccount t2 where t1.period= '%s' and t2.company= '%s' and ifnull(t2.is_pl_account, 'No') = 'No' and t1.account = t2.name %s for update" % (self.doc.past_year, self.doc.company, cond)) cnt = 0 for ab in abl: @@ -100,10 +108,11 @@ class DocType: return sql("select debit_or_credit, lft, rgt, is_pl_account from tabAccount where name=%s", account)[0] # ==================================================================================== - def post_entries(self): + def post_entries(self, account = ''): sql("LOCK TABLE `tabGL Entry` WRITE") + cond = account and (" and account = '" + account + "'") or '' # post each gl entry (batch or complete) - gle = sql("select name, account, debit, credit, is_opening, posting_date from `tabGL Entry` where fiscal_year=%s and ifnull(is_cancelled,'No')='No' and company=%s", (self.doc.name, self.doc.company)) + gle = sql("select name, account, debit, credit, is_opening, posting_date from `tabGL Entry` where fiscal_year=%s and ifnull(is_cancelled,'No')='No' and company=%s %s", (self.doc.name, self.doc.company, cond)) account_details = {} cnt = 0 @@ -153,7 +162,6 @@ class DocType: sql("UNLOCK TABLES") - # Clear PV/RV outstanding # ==================================================================================== def clear_outstanding(self): diff --git a/accounts/doctype/form_16a/form_16a.py b/accounts/doctype/form_16a/form_16a.py index 7d569b70d8..292c52a2da 100644 --- a/accounts/doctype/form_16a/form_16a.py +++ b/accounts/doctype/form_16a/form_16a.py @@ -18,85 +18,92 @@ convert_to_lists = webnotes.conn.convert_to_lists from utilities.transaction_base import TransactionBase class DocType(TransactionBase): - def __init__(self,d,dl): - self.doc, self.doclist = d, dl - - def autoname(self): - self.doc.name = make_autoname('Form 16A' + '/.#####') + def __init__(self,d,dl): + self.doc, self.doclist = d, dl + + def autoname(self): + self.doc.name = make_autoname('Form 16A' + '/.#####') - # Get pan no and tan no from company - #------------------------------------- - def get_registration_details(self): - comp_det=sql("Select address,registration_details from `tabCompany` where name = '%s'"%(self.doc.company)) - if not comp_det: - msgprint("Registration Details is not mentioned in comapny") - ret = { - 'company_address':'', - 'registration_details': '' - } - else: - ret = { - 'company_address': cstr(comp_det[0][0]), - 'registration_details': cstr(comp_det[0][1]) - } - return cstr(ret) - - # Get party details - #------------------ - def get_party_det(self): - party_det=sql("Select pan_number, address from `tabAccount` where name = '%s'" % self.doc.party_name) - ret = { - 'pan_number': cstr(party_det[0][0]) , - 'party_address': cstr(party_det[0][1]) - } - return cstr(ret) - - # Get TDS Return acknowledgement - #------------------------------- - def get_return_ack_details(self): - self.doc.clear_table(self.doclist, 'form_16A_ack_details') - if not (self.doc.from_date and self.doc.to_date): - msgprint("Please enter From Date, To Date") - else: - ack = sql("select quarter, acknowledgement_no from `tabTDS Return Acknowledgement` where date_of_receipt>='%s' and date_of_receipt<='%s' and tds_category = '%s' order by date_of_receipt ASC" % (self.doc.from_date, self.doc.to_date, self.doc.tds_category)) - for d in ack: - ch = addchild(self.doc, 'form_16A_ack_details', 'Form 16A Ack Detail', 1, self.doclist) - ch.quarter = d[0] - ch.ack_no = d[1] - - # Get tds payment details - #------------------------------- - def get_tds(self): - self.doc.clear_table(self.doclist,'form_16A_tax_details') - import datetime - if self.doc.from_date and self.doc.to_date and self.doc.tds_category: - tot=0.0 - party_tds_list=sql("select t2.amount_paid,t2.date_of_payment,t2.tds_amount,t2.cess_on_tds, t2.total_tax_amount, t1.cheque_no, t1.bsr_code, t1.date_of_receipt, t1.challan_id from `tabTDS Payment` t1, `tabTDS Payment Detail` t2 where t1.tds_category='%s' and t2.party_name='%s' and t1.from_date >= '%s' and t1.to_date <= '%s' and t2.total_tax_amount>0 and t2.parent=t1.name and t1.docstatus=1" % (self.doc.tds_category,self.doc.party_name,self.doc.from_date,self.doc.to_date)) - for s in party_tds_list: - child = addchild(self.doc, 'form_16A_tax_details', 'Form 16A Tax Detail', 1, self.doclist) - child.amount_paid = s and flt(s[0]) or '' - child.date_of_payment =s and s[1].strftime('%Y-%m-%d') or '' - child.tds_main = s and flt(s[2]) or '' - child.surcharge = 0 - child.cess_on_tds = s and flt(s[3]) or '' - child.total_tax_deposited = s and flt(s[4]) or '' - child.cheque_no = s and s[5] or '' - child.bsr_code = s and s[6] or '' - child.tax_deposited_date = s and s[7].strftime('%Y-%m-%d') or '' - child.challan_no = s and s[8] or '' - tot=flt(tot)+flt(s[4]) - self.doc.total_amount = flt(tot) - else: - msgprint("Plaese enter from date, to date and TDS category") + # Get pan no and tan no from company + #------------------------------------- + def get_registration_details(self): + comp_det=sql("Select address,registration_details from `tabCompany` where name = '%s'"%(self.doc.company)) + if not comp_det: + msgprint("Registration Details is not mentioned in comapny") + ret = { + 'company_address':'', + 'registration_details': '' + } + else: + ret = { + 'company_address': cstr(comp_det[0][0]), + 'registration_details': cstr(comp_det[0][1]) + } + return cstr(ret) - - # validate - #---------------- - def validate(self): - tot=0.0 - for d in getlist(self.doclist,'form_16A_tax_details'): - tot=flt(tot)+flt(d.total_tax_deposited) - - dcc = TransactionBase().get_company_currency(self.doc.company) - self.doc.total_amount = flt(tot) - self.doc.in_words = get_obj('Sales Common').get_total_in_words(dcc, self.doc.total_amount) + # Get party details + #------------------ + def get_party_det(self): + party_det=sql("select master_type, master_name from `tabAccount` where name='%s'" % self.doc.party_name) + if party_det and party_det[0][0]=='Supplier': + try: + rec = sql("select name, address_line1, address_line2, city, country, pincode, state from `tabAddress` where supplier = '%s' and docstatus != 2 order by is_primary_address desc limit 1" %(party_det[0][1]), as_dict = 1) + address_display = cstr((rec[0]['address_line1'] and rec[0]['address_line1'] or '')) + cstr((rec[0]['address_line2'] and '\n' + rec[0]['address_line2'] or '')) + cstr((rec[0]['city'] and '\n'+rec[0]['city'] or '')) + cstr((rec[0]['pincode'] and '\n' + rec[0]['pincode'] or '')) + cstr((rec[0]['state'] and '\n'+rec[0]['state'] or '')) + cstr((rec[0]['country'] and '\n'+rec[0]['country'] or '')) + except: + address_display = '' + + ret = { + 'party_address': cstr(address_display) + } + + return cstr(ret) + + # Get TDS Return acknowledgement + #------------------------------- + def get_return_ack_details(self): + self.doc.clear_table(self.doclist, 'form_16A_ack_details') + if not (self.doc.from_date and self.doc.to_date): + msgprint("Please enter From Date, To Date") + else: + ack = sql("select quarter, acknowledgement_no from `tabTDS Return Acknowledgement` where date_of_receipt>='%s' and date_of_receipt<='%s' and tds_category = '%s' order by date_of_receipt ASC" % (self.doc.from_date, self.doc.to_date, self.doc.tds_category)) + for d in ack: + ch = addchild(self.doc, 'form_16A_ack_details', 'Form 16A Ack Detail', 1, self.doclist) + ch.quarter = d[0] + ch.ack_no = d[1] + + # Get tds payment details + #------------------------------- + def get_tds(self): + self.doc.clear_table(self.doclist,'form_16A_tax_details') + import datetime + if self.doc.from_date and self.doc.to_date and self.doc.tds_category: + tot=0.0 + party_tds_list=sql("select t2.amount_paid,t2.date_of_payment,t2.tds_amount,t2.cess_on_tds, t2.total_tax_amount, t1.cheque_no, t1.bsr_code, t1.date_of_receipt, t1.challan_id from `tabTDS Payment` t1, `tabTDS Payment Detail` t2 where t1.tds_category='%s' and t2.party_name='%s' and t1.from_date >= '%s' and t1.to_date <= '%s' and t2.total_tax_amount>0 and t2.parent=t1.name and t1.docstatus=1" % (self.doc.tds_category,self.doc.party_name,self.doc.from_date,self.doc.to_date)) + for s in party_tds_list: + child = addchild(self.doc, 'form_16A_tax_details', 'Form 16A Tax Detail', 1, self.doclist) + child.amount_paid = s and flt(s[0]) or '' + child.date_of_payment =s and s[1].strftime('%Y-%m-%d') or '' + child.tds_main = s and flt(s[2]) or '' + child.surcharge = 0 + child.cess_on_tds = s and flt(s[3]) or '' + child.total_tax_deposited = s and flt(s[4]) or '' + child.cheque_no = s and s[5] or '' + child.bsr_code = s and s[6] or '' + child.tax_deposited_date = s and s[7].strftime('%Y-%m-%d') or '' + child.challan_no = s and s[8] or '' + tot=flt(tot)+flt(s[4]) + self.doc.total_amount = flt(tot) + else: + msgprint("Plaese enter from date, to date and TDS category") + + + # validate + #---------------- + def validate(self): + tot=0.0 + for d in getlist(self.doclist,'form_16A_tax_details'): + tot=flt(tot)+flt(d.total_tax_deposited) + + dcc = TransactionBase().get_company_currency(self.doc.company) + self.doc.total_amount = flt(tot) + self.doc.in_words = get_obj('Sales Common').get_total_in_words(dcc, self.doc.total_amount) diff --git a/accounts/doctype/gl_control/gl_control.py b/accounts/doctype/gl_control/gl_control.py index b7129e37e8..5ec8ecd22c 100644 --- a/accounts/doctype/gl_control/gl_control.py +++ b/accounts/doctype/gl_control/gl_control.py @@ -405,18 +405,23 @@ In Account := %s User := %s has Repaired Outstanding Amount For %s : %s and foll Find vouchers that are not cancelled correctly and repost them """ vl = sql(""" - select voucher_type, voucher_no, sum(debit) as sum_debit, sum(credit) as sum_credit - from `tabGL Entry` - where is_cancelled='Yes' and creation > %s - group by voucher_type, voucher_no - """, after_date, as_dict=1)) + select voucher_type, voucher_no, account, sum(debit) as sum_debit, sum(credit) as sum_credit + from `tabGL Entry` + where is_cancelled='Yes' and creation > %s + group by voucher_type, voucher_no, account + """, after_date, as_dict=1) + ac_list = [] for v in vl: - if c['sum_debit'] != 0 or c['sum_credit'] != 0: - ac_list += [a[0] for a in sql(""" - select distinct account from `tabGL Entry` - where voucher_type=%s and voucher_no = %s - """, (c['voucher_type'], c['voucher_no']))] + if v['sum_debit'] != 0 or v['sum_credit'] != 0: + ac_list.append(v['account']) + + fy_list = sql("""select name from `tabFiscal Year` + where (%s between year_start_date and date_sub(date_add(year_start_date,interval 1 year), interval 1 day)) + or year_start_date > %s + order by year_start_date ASC""", (after_date, after_date)) - for a in set(ac_list): - get_obj('Account', a).respost() \ No newline at end of file + for fy in fy_list: + fy_obj = get_obj('Fiscal Year', fy[0]) + for a in set(ac_list): + fy_obj.repost(a) diff --git a/accounts/doctype/payable_voucher/payable_voucher.py b/accounts/doctype/payable_voucher/payable_voucher.py index 7e90d71d0c..0e930e32d4 100644 --- a/accounts/doctype/payable_voucher/payable_voucher.py +++ b/accounts/doctype/payable_voucher/payable_voucher.py @@ -19,489 +19,489 @@ convert_to_lists = webnotes.conn.convert_to_lists from utilities.transaction_base import TransactionBase class DocType(TransactionBase): - def __init__(self,d,dl): - self.doc, self.doclist = d, dl - self.tname = 'PV Detail' - self.fname = 'entries' + def __init__(self,d,dl): + self.doc, self.doclist = d, dl + self.tname = 'PV Detail' + self.fname = 'entries' - # Autoname - # --------- - def autoname(self): - self.doc.name = make_autoname(self.doc.naming_series+'.####') + # Autoname + # --------- + def autoname(self): + self.doc.name = make_autoname(self.doc.naming_series+'.####') # ************************** Trigger Functions **************************** - # Credit To - # ---------- - def get_credit_to(self): - acc_head = sql("select name, credit_days from `tabAccount` where (name = %s or (master_name = %s and master_type = 'supplier')) and docstatus != 2", (cstr(self.doc.supplier) + " - " + self.get_company_abbr(),self.doc.supplier)) - #supp_detail = sql("select supplier_name,address from `tabSupplier` where name = %s", self.doc.supplier, as_dict =1) - #ret = { - # 'supplier_name' : supp_detail and supp_detail[0]['supplier_name'] or '', - # 'supplier_address': supp_detail and supp_detail[0]['address'] or '' - #} - ret = {} - if acc_head and acc_head[0][0]: - ret['credit_to'] = acc_head[0][0] - if not self.doc.due_date: - ret['due_date'] = add_days(cstr(self.doc.posting_date), acc_head and cint(acc_head[0][1]) or 0) - elif not acc_head: - msgprint("%s does not have an Account Head in %s. You must first create it from the Supplier Master" % (self.doc.supplier, self.doc.company)) - return cstr(ret) - - def get_cust(self): - ret = {} - if self.doc.credit_to: - ret['supplier'] = get_value('Account',self.doc.credit_to,'master_name') - - return cstr(ret) + # Credit To + # ---------- + def get_credit_to(self): + acc_head = sql("select name, credit_days from `tabAccount` where (name = %s or (master_name = %s and master_type = 'supplier')) and docstatus != 2", (cstr(self.doc.supplier) + " - " + self.get_company_abbr(),self.doc.supplier)) + #supp_detail = sql("select supplier_name,address from `tabSupplier` where name = %s", self.doc.supplier, as_dict =1) + #ret = { + # 'supplier_name' : supp_detail and supp_detail[0]['supplier_name'] or '', + # 'supplier_address': supp_detail and supp_detail[0]['address'] or '' + #} + ret = {} + if acc_head and acc_head[0][0]: + ret['credit_to'] = acc_head[0][0] + if not self.doc.due_date: + ret['due_date'] = add_days(cstr(self.doc.posting_date), acc_head and cint(acc_head[0][1]) or 0) + elif not acc_head: + msgprint("%s does not have an Account Head in %s. You must first create it from the Supplier Master" % (self.doc.supplier, self.doc.company)) + return cstr(ret) + + def get_cust(self): + ret = {} + if self.doc.credit_to: + ret['supplier'] = get_value('Account',self.doc.credit_to,'master_name') + + return cstr(ret) - # Get Default Cost Center and Expense Head from Item Master - # ---------------------------------------------------------- - def get_default_values(self,args): - args = eval(args) - ret = {} - if sql("select name from `tabItem` where name = '%s'" % args['item_code']): - if not args['expense_head'] or args['expense_head'] == 'undefined': - expense_head = sql("select name from `tabAccount` where account_name in (select purchase_account from `tabItem` where name = '%s')" % args['item_code']) - ret['expense_head'] = expense_head and expense_head[0][0] or '' - if not args['cost_center'] or args['cost_center'] == 'undefined': - cost_center = sql("select cost_center from `tabItem` where name = '%s'" % args['item_code']) - ret['cost_center'] = cost_center and cost_center[0][0] or '' - return cstr(ret) - - - # Get Items based on PO or PR - # ---------------------------- - def pull_details(self): - if self.doc.purchase_receipt_main: - self.validate_duplicate_docname('purchase_receipt') - self.doclist = get_obj('DocType Mapper', 'Purchase Receipt-Payable Voucher').dt_map('Purchase Receipt', 'Payable Voucher', self.doc.purchase_receipt_main, self.doc, self.doclist, "[['Purchase Receipt', 'Payable Voucher'],['Purchase Receipt Detail', 'PV Detail']]") + # Get Default Cost Center and Expense Head from Item Master + # ---------------------------------------------------------- + def get_default_values(self,args): + args = eval(args) + ret = {} + if sql("select name from `tabItem` where name = '%s'" % args['item_code']): + if not args['expense_head'] or args['expense_head'] == 'undefined': + expense_head = sql("select name from `tabAccount` where account_name in (select purchase_account from `tabItem` where name = '%s')" % args['item_code']) + ret['expense_head'] = expense_head and expense_head[0][0] or '' + if not args['cost_center'] or args['cost_center'] == 'undefined': + cost_center = sql("select cost_center from `tabItem` where name = '%s'" % args['item_code']) + ret['cost_center'] = cost_center and cost_center[0][0] or '' + return cstr(ret) + + + # Get Items based on PO or PR + # ---------------------------- + def pull_details(self): + if self.doc.purchase_receipt_main: + self.validate_duplicate_docname('purchase_receipt') + self.doclist = get_obj('DocType Mapper', 'Purchase Receipt-Payable Voucher').dt_map('Purchase Receipt', 'Payable Voucher', self.doc.purchase_receipt_main, self.doc, self.doclist, "[['Purchase Receipt', 'Payable Voucher'],['Purchase Receipt Detail', 'PV Detail']]") - elif self.doc.purchase_order_main: - self.validate_duplicate_docname('purchase_order') - self.doclist = get_obj('DocType Mapper', 'Purchase Order-Payable Voucher').dt_map('Purchase Order', 'Payable Voucher', self.doc.purchase_order_main, self.doc, self.doclist, "[['Purchase Order', 'Payable Voucher'],['PO Detail', 'PV Detail']]") - - ret = eval(self.get_credit_to()) - #self.doc.supplier_name = ret['supplier_name'] - #self.doc.supplier_address = ret['supplier_address'] - - #self.doc.cst_no =ret['cst_no'] - #self.doc.bst_no = ret['bst_no'] - #self.doc.vat_tin_no = ret['vat_tin_no'] + elif self.doc.purchase_order_main: + self.validate_duplicate_docname('purchase_order') + self.doclist = get_obj('DocType Mapper', 'Purchase Order-Payable Voucher').dt_map('Purchase Order', 'Payable Voucher', self.doc.purchase_order_main, self.doc, self.doclist, "[['Purchase Order', 'Payable Voucher'],['PO Detail', 'PV Detail']]") + + ret = eval(self.get_credit_to()) + #self.doc.supplier_name = ret['supplier_name'] + #self.doc.supplier_address = ret['supplier_address'] + + #self.doc.cst_no =ret['cst_no'] + #self.doc.bst_no = ret['bst_no'] + #self.doc.vat_tin_no = ret['vat_tin_no'] - if ret.has_key('credit_to'): - self.doc.credit_to = ret['credit_to'] - + if ret.has_key('credit_to'): + self.doc.credit_to = ret['credit_to'] + - # Get Item Details - # ----------------- - def get_item_details(self,arg): - item_det = sql("select item_name, brand, description, item_group,purchase_account,cost_center from tabItem where name=%s",arg,as_dict=1) - tax = sql("select tax_type, tax_rate from `tabItem Tax` where parent = %s" , arg) - t = {} - for x in tax: t[x[0]] = flt(x[1]) - ret = { - 'item_name' : item_det and item_det[0]['item_name'] or '', - 'brand' : item_det and item_det[0]['brand'] or '', - 'description' : item_det and item_det[0]['description'] or '', - 'item_group' : item_det and item_det[0]['item_group'] or '', - 'rate' : 0.00, - 'qty' : 0.00, - 'amount' : 0.00, - 'expense_head' : item_det and item_det[0]['purchase_account'] or '', - 'cost_center' : item_det and item_det[0]['cost_center'] or '', - 'item_tax_rate' : str(t) - } - return cstr(ret) - - # Advance Allocation - # ------------------- - def get_advances(self): - get_obj('GL Control').get_advances( self, self.doc.credit_to, 'Advance Allocation Detail','advance_allocation_details','debit') - - - # ============= OTHER CHARGES ==================== - - # Get Tax rate if account type is TAX - # ------------------------------------ - def get_rate(self,arg): - return get_obj('Purchase Common').get_rate(arg,self) + # Get Item Details + # ----------------- + def get_item_details(self,arg): + item_det = sql("select item_name, brand, description, item_group,purchase_account,cost_center from tabItem where name=%s",arg,as_dict=1) + tax = sql("select tax_type, tax_rate from `tabItem Tax` where parent = %s" , arg) + t = {} + for x in tax: t[x[0]] = flt(x[1]) + ret = { + 'item_name' : item_det and item_det[0]['item_name'] or '', + 'brand' : item_det and item_det[0]['brand'] or '', + 'description' : item_det and item_det[0]['description'] or '', + 'item_group' : item_det and item_det[0]['item_group'] or '', + 'rate' : 0.00, + 'qty' : 0.00, + 'amount' : 0.00, + 'expense_head' : item_det and item_det[0]['purchase_account'] or '', + 'cost_center' : item_det and item_det[0]['cost_center'] or '', + 'item_tax_rate' : str(t) + } + return cstr(ret) + + # Advance Allocation + # ------------------- + def get_advances(self): + get_obj('GL Control').get_advances( self, self.doc.credit_to, 'Advance Allocation Detail','advance_allocation_details','debit') + + + # ============= OTHER CHARGES ==================== + + # Get Tax rate if account type is TAX + # ------------------------------------ + def get_rate(self,arg): + return get_obj('Purchase Common').get_rate(arg,self) - # Pull details from other charges master (Get Other Charges) - # ----------------------------------------------------------- - def get_purchase_tax_details(self): - return get_obj('Purchase Common').get_purchase_tax_details(self) + # Pull details from other charges master (Get Other Charges) + # ----------------------------------------------------------- + def get_purchase_tax_details(self): + return get_obj('Purchase Common').get_purchase_tax_details(self) - def get_rate1(self,acc): - rate = sql("select tax_rate from `tabAccount` where name='%s'"%(acc)) - ret={'add_tax_rate' :rate and flt(rate[0][0]) or 0 } - return cstr(ret) - + def get_rate1(self,acc): + rate = sql("select tax_rate from `tabAccount` where name='%s'"%(acc)) + ret={'add_tax_rate' :rate and flt(rate[0][0]) or 0 } + return cstr(ret) + # *************************** Server Utility Functions ***************************** - # Get Company abbr - # ----------------- - def get_company_abbr(self): - return sql("select abbr from tabCompany where name=%s", self.doc.company)[0][0] + # Get Company abbr + # ----------------- + def get_company_abbr(self): + return sql("select abbr from tabCompany where name=%s", self.doc.company)[0][0] - # Check whether PO or PR is already fetched - # ------------------------------------------ - def validate_duplicate_docname(self,doctype): - for d in getlist(self.doclist, 'entries'): - if doctype == 'purchase_receipt' and cstr(self.doc.purchase_receipt_main) == cstr(d.purchase_receipt): - msgprint(cstr(self.doc.purchase_receipt_main) + " purchase receipt details have already been pulled.") - raise Exception , " Validation Error. " + # Check whether PO or PR is already fetched + # ------------------------------------------ + def validate_duplicate_docname(self,doctype): + for d in getlist(self.doclist, 'entries'): + if doctype == 'purchase_receipt' and cstr(self.doc.purchase_receipt_main) == cstr(d.purchase_receipt): + msgprint(cstr(self.doc.purchase_receipt_main) + " purchase receipt details have already been pulled.") + raise Exception , " Validation Error. " - if doctype == 'purchase_order' and cstr(self.doc.purchase_order_main) == cstr(d.purchase_order) and not d.purchase_receipt: - msgprint(cstr(self.doc.purchase_order_main) + " purchase order details have already been pulled.") - raise Exception , " Validation Error. " + if doctype == 'purchase_order' and cstr(self.doc.purchase_order_main) == cstr(d.purchase_order) and not d.purchase_receipt: + msgprint(cstr(self.doc.purchase_order_main) + " purchase order details have already been pulled.") + raise Exception , " Validation Error. " - + # **************************** VALIDATE ******************************** - # Check for Item.is_Purchase_item = 'Yes' and Item is active - # ------------------------------------------------------------------ - def check_active_purchase_items(self): - for d in getlist(self.doclist, 'entries'): - if d.item_code: # extra condn coz item_code is not mandatory in PV - valid_item = sql("select docstatus,is_purchase_item from tabItem where name = %s",d.item_code) - if valid_item[0][0] == 2: - msgprint("Item : '%s' is Inactive, you can restore it from Trash" %(d.item_code)) - raise Exception - if not valid_item[0][1] == 'Yes': - msgprint("Item : '%s' is not Purchase Item"%(d.item_code)) - raise Exception - - # Check Conversion Rate - # ---------------------- - def check_conversion_rate(self): - default_currency = get_obj('Manage Account').doc.default_currency - if not default_currency: - msgprint('Message: Please enter default currency in Manage Account') - raise Exception - if (self.doc.currency == default_currency and flt(self.doc.conversion_rate) != 1.00) or not self.doc.conversion_rate or (self.doc.currency != default_currency and flt(self.doc.conversion_rate) == 1.00): - msgprint("Message: Please Enter Appropriate Conversion Rate.") - raise Exception + # Check for Item.is_Purchase_item = 'Yes' and Item is active + # ------------------------------------------------------------------ + def check_active_purchase_items(self): + for d in getlist(self.doclist, 'entries'): + if d.item_code: # extra condn coz item_code is not mandatory in PV + valid_item = sql("select docstatus,is_purchase_item from tabItem where name = %s",d.item_code) + if valid_item[0][0] == 2: + msgprint("Item : '%s' is Inactive, you can restore it from Trash" %(d.item_code)) + raise Exception + if not valid_item[0][1] == 'Yes': + msgprint("Item : '%s' is not Purchase Item"%(d.item_code)) + raise Exception + + # Check Conversion Rate + # ---------------------- + def check_conversion_rate(self): + default_currency = TransactionBase().get_company_currency(self.doc.company) + if not default_currency: + msgprint('Message: Please enter default currency in Company Master') + raise Exception + if (self.doc.currency == default_currency and flt(self.doc.conversion_rate) != 1.00) or not self.doc.conversion_rate or (self.doc.currency != default_currency and flt(self.doc.conversion_rate) == 1.00): + msgprint("Message: Please Enter Appropriate Conversion Rate.") + raise Exception - # 1. Check whether bill is already booked against this bill no. or not - # 2. Add Remarks - # --------------------------------------------------------------------- - def validate_bill_no(self): - if self.doc.bill_no and self.doc.bill_no.lower().strip() not in ['na', 'not applicable', 'none']: - b_no = sql("select bill_no, name, ifnull(is_opening,'') from `tabPayable Voucher` where bill_no = '%s' and credit_to = '%s' and docstatus = 1 and name != '%s' " % (self.doc.bill_no, self.doc.credit_to, self.doc.name)) - if b_no and cstr(b_no[0][2]) == cstr(self.doc.is_opening): - msgprint("Please check you have already booked expense against Bill No. %s in Purchase Invoice %s" % (cstr(b_no[0][0]), cstr(b_no[0][1]))) - raise Exception , "Validation Error" - if not self.doc.remarks: - self.doc.remarks = (self.doc.remarks or '') + "\n" + ("Against Bill %s dated %s" % (self.doc.bill_no, formatdate(self.doc.bill_date))) - if self.doc.ded_amount: - self.doc.remarks = (self.doc.remarks or '') + "\n" + ("Grand Total: %s, Tax Deduction Amount: %s" %(self.doc.grand_total, self.doc.ded_amount)) - else: - if not self.doc.remarks: - self.doc.remarks = "No Remarks" - - # Validate Bill No Date - # --------------------- - def validate_bill_no_date(self): - if self.doc.bill_no and not self.doc.bill_date and self.doc.bill_no.lower().strip() not in ['na', 'not applicable', 'none']: - msgprint("Please enter Bill Date") - raise Exception + # 1. Check whether bill is already booked against this bill no. or not + # 2. Add Remarks + # --------------------------------------------------------------------- + def validate_bill_no(self): + if self.doc.bill_no and self.doc.bill_no.lower().strip() not in ['na', 'not applicable', 'none']: + b_no = sql("select bill_no, name, ifnull(is_opening,'') from `tabPayable Voucher` where bill_no = '%s' and credit_to = '%s' and docstatus = 1 and name != '%s' " % (self.doc.bill_no, self.doc.credit_to, self.doc.name)) + if b_no and cstr(b_no[0][2]) == cstr(self.doc.is_opening): + msgprint("Please check you have already booked expense against Bill No. %s in Purchase Invoice %s" % (cstr(b_no[0][0]), cstr(b_no[0][1]))) + raise Exception , "Validation Error" + if not self.doc.remarks: + self.doc.remarks = (self.doc.remarks or '') + "\n" + ("Against Bill %s dated %s" % (self.doc.bill_no, formatdate(self.doc.bill_date))) + if self.doc.ded_amount: + self.doc.remarks = (self.doc.remarks or '') + "\n" + ("Grand Total: %s, Tax Deduction Amount: %s" %(self.doc.grand_total, self.doc.ded_amount)) + else: + if not self.doc.remarks: + self.doc.remarks = "No Remarks" + + # Validate Bill No Date + # --------------------- + def validate_bill_no_date(self): + if self.doc.bill_no and not self.doc.bill_date and self.doc.bill_no.lower().strip() not in ['na', 'not applicable', 'none']: + msgprint("Please enter Bill Date") + raise Exception - # Clear Advances - # --------------- - def clear_advances(self): - get_obj('GL Control').clear_advances( self, 'Advance Allocation Detail','advance_allocation_details') + # Clear Advances + # --------------- + def clear_advances(self): + get_obj('GL Control').clear_advances( self, 'Advance Allocation Detail','advance_allocation_details') - # 1. Credit To Account Exists - # 2. Is a Credit Account - # 3. Is not a PL Account - # ---------------------------- - def validate_credit_acc(self): - acc = sql("select debit_or_credit, is_pl_account from tabAccount where name = '%s'" % self.doc.credit_to) - if not acc: - msgprint("Account: "+ self.doc.credit_to + "does not exist") - raise Exception - elif acc[0][0] and acc[0][0] != 'Credit': - msgprint("Account: "+ self.doc.credit_to + "is not a credit account") - raise Exception - elif acc[0][1] and acc[0][1] != 'No': - msgprint("Account: "+ self.doc.credit_to + "is a pl account") - raise Exception - - # Validate Acc Head of Supplier and Credit To Account entered - # ------------------------------------------------------------ - def check_for_acc_head_of_supplier(self): - acc_head = sql("select name from `tabAccount` where name = %s", (cstr(self.doc.supplier) + " - " + self.get_company_abbr())) - if self.doc.supplier: - if acc_head and acc_head[0][0]: - if not cstr(acc_head[0][0]) == cstr(self.doc.credit_to): - msgprint("Credit To: %s do not match with Supplier: %s for Company: %s i.e. %s" %(self.doc.credit_to,self.doc.supplier,self.doc.company,cstr(acc_head[0][0]))) - raise Exception, "Validation Error " - if not acc_head: - msgprint("Supplier %s does not have an Account Head in %s. You must first create it from the Supplier Master" % (self.doc.supplier, self.doc.company)) - raise Exception, "Validation Error " - - # Check for Stopped PO - # --------------------- - def check_for_stopped_status(self): - check_list = [] - for d in getlist(self.doclist,'entries'): - if d.purchase_order and not d.purchase_order in check_list and not d.purchase_receipt: - check_list.append(d.purhcase_order) - stopped = sql("select name from `tabPurchase Order` where status = 'Stopped' and name = '%s'" % d.purchase_order) - if stopped: - msgprint("One cannot do any transaction against 'Purchase Order' : %s, it's status is 'Stopped'" % (d.purhcase_order)) - raise Exception - - # Validate Supplier - # ----------------- - def validate_supplier(self, d): - supplier = '' - if d.purchase_order and not d.purchase_order in self.po_list: - supplier = sql("select supplier from `tabPurchase Order` where name = '%s'" % d.purchase_order)[0][0] - doctype = 'purchase order' - doctype_no = cstr(d.purchase_order) - if supplier and not cstr(self.doc.supplier) == cstr(supplier): - msgprint("Supplier name %s do not match with supplier name of %s %s." %(self.doc.supplier,doctype,doctype_no)) - raise Exception , " Validation Error " + # 1. Credit To Account Exists + # 2. Is a Credit Account + # 3. Is not a PL Account + # ---------------------------- + def validate_credit_acc(self): + acc = sql("select debit_or_credit, is_pl_account from tabAccount where name = '%s'" % self.doc.credit_to) + if not acc: + msgprint("Account: "+ self.doc.credit_to + "does not exist") + raise Exception + elif acc[0][0] and acc[0][0] != 'Credit': + msgprint("Account: "+ self.doc.credit_to + "is not a credit account") + raise Exception + elif acc[0][1] and acc[0][1] != 'No': + msgprint("Account: "+ self.doc.credit_to + "is a pl account") + raise Exception + + # Validate Acc Head of Supplier and Credit To Account entered + # ------------------------------------------------------------ + def check_for_acc_head_of_supplier(self): + acc_head = sql("select name from `tabAccount` where name = %s", (cstr(self.doc.supplier) + " - " + self.get_company_abbr())) + if self.doc.supplier: + if acc_head and acc_head[0][0]: + if not cstr(acc_head[0][0]) == cstr(self.doc.credit_to): + msgprint("Credit To: %s do not match with Supplier: %s for Company: %s i.e. %s" %(self.doc.credit_to,self.doc.supplier,self.doc.company,cstr(acc_head[0][0]))) + raise Exception, "Validation Error " + if not acc_head: + msgprint("Supplier %s does not have an Account Head in %s. You must first create it from the Supplier Master" % (self.doc.supplier, self.doc.company)) + raise Exception, "Validation Error " + + # Check for Stopped PO + # --------------------- + def check_for_stopped_status(self): + check_list = [] + for d in getlist(self.doclist,'entries'): + if d.purchase_order and not d.purchase_order in check_list and not d.purchase_receipt: + check_list.append(d.purhcase_order) + stopped = sql("select name from `tabPurchase Order` where status = 'Stopped' and name = '%s'" % d.purchase_order) + if stopped: + msgprint("One cannot do any transaction against 'Purchase Order' : %s, it's status is 'Stopped'" % (d.purhcase_order)) + raise Exception + + # Validate Supplier + # ----------------- + def validate_supplier(self, d): + supplier = '' + if d.purchase_order and not d.purchase_order in self.po_list: + supplier = sql("select supplier from `tabPurchase Order` where name = '%s'" % d.purchase_order)[0][0] + doctype = 'purchase order' + doctype_no = cstr(d.purchase_order) + if supplier and not cstr(self.doc.supplier) == cstr(supplier): + msgprint("Supplier name %s do not match with supplier name of %s %s." %(self.doc.supplier,doctype,doctype_no)) + raise Exception , " Validation Error " - if d.purchase_receipt and not d.purchase_receipt in self.pr_list: - supplier = sql("select supplier from `tabPurchase Receipt` where name = '%s'" % d.purchase_receipt)[0][0] - doctype = 'purchase receipt' - doctype_no = cstr(d.purchase_receipt) - if supplier and not cstr(self.doc.supplier) == cstr(supplier): - msgprint("Supplier name %s do not match with supplier name of %s %s." %(self.doc.supplier,doctype,doctype_no)) - raise Exception , " Validation Error " + if d.purchase_receipt and not d.purchase_receipt in self.pr_list: + supplier = sql("select supplier from `tabPurchase Receipt` where name = '%s'" % d.purchase_receipt)[0][0] + doctype = 'purchase receipt' + doctype_no = cstr(d.purchase_receipt) + if supplier and not cstr(self.doc.supplier) == cstr(supplier): + msgprint("Supplier name %s do not match with supplier name of %s %s." %(self.doc.supplier,doctype,doctype_no)) + raise Exception , " Validation Error " - # Validate values with reference document - #---------------------------------------- - def validate_reference_value(self): - get_obj('DocType Mapper', 'Purchase Order-Payable Voucher', with_children = 1).validate_reference_value(self, self.doc.name) + # Validate values with reference document + #---------------------------------------- + def validate_reference_value(self): + get_obj('DocType Mapper', 'Purchase Order-Payable Voucher', with_children = 1).validate_reference_value(self, self.doc.name) - - # Validate PO and PR - # ------------------- - def validate_po_pr(self, d): - # check po / pr for qty and rates and currency and conversion rate + + # Validate PO and PR + # ------------------- + def validate_po_pr(self, d): + # check po / pr for qty and rates and currency and conversion rate - # always import_rate must be equal to import_rate of purchase order - if d.purchase_order and not d.purchase_order in self.po_list: - # currency - currency = cstr(sql("select currency from `tabPurchase Order` where name = '%s'" % d.purchase_order)[0][0]) - if not cstr(currency) == cstr(self.doc.currency): - msgprint("Purchase Order: " + cstr(d.purchase_order) + " currency : " + cstr(currency) + " does not match with currency of current document.") - raise Exception - # import_rate - rate = flt(sql('select import_rate from `tabPO Detail` where item_code=%s and parent=%s and name = %s', (d.item_code, d.purchase_order, d.po_detail))[0][0]) - if abs(rate - flt(d.import_rate)) > 1: - msgprint("Import Rate for %s in the Purchase Order is %s. Rate must be same as Purchase Order Rate" % (d.item_code,rate)) - raise Exception - - if d.purchase_receipt and not d.purchase_receipt in self.pr_list: - # currency , conversion_rate - data = sql("select currency, conversion_rate from `tabPurchase Receipt` where name = '%s'" % d.purchase_receipt, as_dict = 1) - if not cstr(data[0]['currency']) == cstr(self.doc.currency): - msgprint("Purchase Receipt: " + cstr(d.purchase_receipt) + " currency : " + cstr(data[0]['currency']) + " does not match with currency of current document.") - raise Exception - if not flt(data[0]['conversion_rate']) == flt(self.doc.conversion_rate): - msgprint("Purchase Receipt: " + cstr(d.purchase_receipt) + " conversion_rate : " + cstr(data[0]['conversion_rate']) + " does not match with conversion_rate of current document.") - raise Exception - - # Build tds table if applicable - #------------------------------ - def get_tds(self): - if cstr(self.doc.is_opening) != 'Yes': - if not self.doc.credit_to: - msgprint("Please Enter Credit To account first") - raise Exception - else: - tds_applicable = sql("select tds_applicable from tabAccount where name = '%s'" % self.doc.credit_to) - if tds_applicable and cstr(tds_applicable[0][0]) == 'Yes': - if not self.doc.tds_applicable: - msgprint("Please enter whether TDS Applicable or not") - raise Exception - if self.doc.tds_applicable == 'Yes': - if not self.doc.tds_category: - msgprint("Please select TDS Category") - raise Exception - else: - get_obj('TDS Control').get_tds_amount(self) - self.doc.total_tds_on_voucher = self.doc.ded_amount - self.doc.total_amount_to_pay=flt(self.doc.grand_total)-flt(self.doc.ded_amount)-flt(self.doc.other_tax_deducted) - elif self.doc.tds_applicable == 'No': - self.doc.tds_category = '' - self.doc.tax_code = '' - self.doc.rate = 0 - self.doc.ded_amount = 0 - self.doc.total_tds_on_voucher = 0 + # always import_rate must be equal to import_rate of purchase order + if d.purchase_order and not d.purchase_order in self.po_list: + # currency + currency = cstr(sql("select currency from `tabPurchase Order` where name = '%s'" % d.purchase_order)[0][0]) + if not cstr(currency) == cstr(self.doc.currency): + msgprint("Purchase Order: " + cstr(d.purchase_order) + " currency : " + cstr(currency) + " does not match with currency of current document.") + raise Exception + # import_rate + rate = flt(sql('select import_rate from `tabPO Detail` where item_code=%s and parent=%s and name = %s', (d.item_code, d.purchase_order, d.po_detail))[0][0]) + if abs(rate - flt(d.import_rate)) > 1: + msgprint("Import Rate for %s in the Purchase Order is %s. Rate must be same as Purchase Order Rate" % (d.item_code,rate)) + raise Exception + + if d.purchase_receipt and not d.purchase_receipt in self.pr_list: + # currency , conversion_rate + data = sql("select currency, conversion_rate from `tabPurchase Receipt` where name = '%s'" % d.purchase_receipt, as_dict = 1) + if not cstr(data[0]['currency']) == cstr(self.doc.currency): + msgprint("Purchase Receipt: " + cstr(d.purchase_receipt) + " currency : " + cstr(data[0]['currency']) + " does not match with currency of current document.") + raise Exception + if not flt(data[0]['conversion_rate']) == flt(self.doc.conversion_rate): + msgprint("Purchase Receipt: " + cstr(d.purchase_receipt) + " conversion_rate : " + cstr(data[0]['conversion_rate']) + " does not match with conversion_rate of current document.") + raise Exception + + # Build tds table if applicable + #------------------------------ + def get_tds(self): + if cstr(self.doc.is_opening) != 'Yes': + if not self.doc.credit_to: + msgprint("Please Enter Credit To account first") + raise Exception + else: + tds_applicable = sql("select tds_applicable from tabAccount where name = '%s'" % self.doc.credit_to) + if tds_applicable and cstr(tds_applicable[0][0]) == 'Yes': + if not self.doc.tds_applicable: + msgprint("Please enter whether TDS Applicable or not") + raise Exception + if self.doc.tds_applicable == 'Yes': + if not self.doc.tds_category: + msgprint("Please select TDS Category") + raise Exception + else: + get_obj('TDS Control').get_tds_amount(self) + self.doc.total_tds_on_voucher = self.doc.ded_amount + self.doc.total_amount_to_pay=flt(self.doc.grand_total)-flt(self.doc.ded_amount)-flt(self.doc.other_tax_deducted) + elif self.doc.tds_applicable == 'No': + self.doc.tds_category = '' + self.doc.tax_code = '' + self.doc.rate = 0 + self.doc.ded_amount = 0 + self.doc.total_tds_on_voucher = 0 - # get tds rate - # ------------- - def get_tds_rate(self): - return str({'rate' : flt(get_value('Account', self.doc.tax_code, 'tax_rate'))}) + # get tds rate + # ------------- + def get_tds_rate(self): + return str({'rate' : flt(get_value('Account', self.doc.tax_code, 'tax_rate'))}) - # set aging date - #------------------- - def set_aging_date(self): - if self.doc.is_opening != 'Yes': - self.doc.aging_date = self.doc.posting_date - elif not self.doc.aging_date: - msgprint("Aging Date is mandatory for opening entry") - raise Exception - + # set aging date + #------------------- + def set_aging_date(self): + if self.doc.is_opening != 'Yes': + self.doc.aging_date = self.doc.posting_date + elif not self.doc.aging_date: + msgprint("Aging Date is mandatory for opening entry") + raise Exception + - # Set against account for debit to account - #------------------------------------------ - def set_against_expense_account(self): - against_acc = [] - for d in getlist(self.doclist, 'entries'): - if d.expense_account not in against_acc: - against_acc.append(d.expense_account) - self.doc.against_expense_account = ','.join(against_acc) + # Set against account for debit to account + #------------------------------------------ + def set_against_expense_account(self): + against_acc = [] + for d in getlist(self.doclist, 'entries'): + if d.expense_account not in against_acc: + against_acc.append(d.expense_account) + self.doc.against_expense_account = ','.join(against_acc) - #check in manage account if purchase order required or not. - # ==================================================================================== - def po_required(self): - res = sql("select value from `tabSingles` where doctype = 'Manage Account' and field = 'po_required'") - if res and res[0][0] == 'Yes': - for d in getlist(self.doclist,'entries'): - if not d.purchase_order: - msgprint("Purchse Order No. required against item %s"%d.item_code) - raise Exception + #check in manage account if purchase order required or not. + # ==================================================================================== + def po_required(self): + res = sql("select value from `tabSingles` where doctype = 'Manage Account' and field = 'po_required'") + if res and res[0][0] == 'Yes': + for d in getlist(self.doclist,'entries'): + if not d.purchase_order: + msgprint("Purchse Order No. required against item %s"%d.item_code) + raise Exception - #check in manage account if purchase receipt required or not. - # ==================================================================================== - def pr_required(self): - res = sql("select value from `tabSingles` where doctype = 'Manage Account' and field = 'pr_required'") - if res and res[0][0] == 'Yes': - for d in getlist(self.doclist,'entries'): - if not d.purchase_receipt: - msgprint("Purchase Receipt No. required against item %s"%d.item_code) - raise Exception + #check in manage account if purchase receipt required or not. + # ==================================================================================== + def pr_required(self): + res = sql("select value from `tabSingles` where doctype = 'Manage Account' and field = 'pr_required'") + if res and res[0][0] == 'Yes': + for d in getlist(self.doclist,'entries'): + if not d.purchase_receipt: + msgprint("Purchase Receipt No. required against item %s"%d.item_code) + raise Exception - # VALIDATE - # ==================================================================================== - def validate(self): - self.po_required() - self.pr_required() - self.check_active_purchase_items() - self.check_conversion_rate() - self.validate_bill_no_date() - self.validate_bill_no() - self.validate_reference_value() - self.clear_advances() - self.validate_credit_acc() - self.check_for_acc_head_of_supplier() - self.check_for_stopped_status() + # VALIDATE + # ==================================================================================== + def validate(self): + self.po_required() + self.pr_required() + self.check_active_purchase_items() + self.check_conversion_rate() + self.validate_bill_no_date() + self.validate_bill_no() + self.validate_reference_value() + self.clear_advances() + self.validate_credit_acc() + self.check_for_acc_head_of_supplier() + self.check_for_stopped_status() - self.po_list, self.pr_list = [], [] - for d in getlist(self.doclist, 'entries'): - self.validate_supplier(d) - self.validate_po_pr(d) - if not d.purchase_order in self.po_list: - self.po_list.append(d.purchase_order) - if not d.purhcase_receipt in self.pr_list: - self.pr_list.append(d.purchase_receipt) - # tds - get_obj('TDS Control').validate_first_entry(self) - if not flt(self.doc.ded_amount): - self.get_tds() - self.doc.save() + self.po_list, self.pr_list = [], [] + for d in getlist(self.doclist, 'entries'): + self.validate_supplier(d) + self.validate_po_pr(d) + if not d.purchase_order in self.po_list: + self.po_list.append(d.purchase_order) + if not d.purhcase_receipt in self.pr_list: + self.pr_list.append(d.purchase_receipt) + # tds + get_obj('TDS Control').validate_first_entry(self) + if not flt(self.doc.ded_amount): + self.get_tds() + self.doc.save() - if not self.doc.is_opening: - self.doc.is_opening = 'No' + if not self.doc.is_opening: + self.doc.is_opening = 'No' - self.set_aging_date() + self.set_aging_date() - #set against account for credit to - self.set_against_expense_account() + #set against account for credit to + self.set_against_expense_account() - #FY validation - get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.posting_date,'Posting Date') - - #get Purchase Common Obj - pc_obj = get_obj(dt='Purchase Common') - - # get total in words - self.doc.in_words = pc_obj.get_total_in_words('Rs', self.doc.grand_total) - self.doc.in_words_import = pc_obj.get_total_in_words(self.doc.currency, self.doc.grand_total_import) + #FY validation + get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.posting_date,'Posting Date') + + #get Purchase Common Obj + pc_obj = get_obj(dt='Purchase Common') + + # get total in words + self.doc.in_words = pc_obj.get_total_in_words('Rs', self.doc.grand_total) + self.doc.in_words_import = pc_obj.get_total_in_words(self.doc.currency, self.doc.grand_total_import) # ***************************** SUBMIT ***************************** - # Check Ref Document docstatus - # ----------------------------- - def check_prev_docstatus(self): - for d in getlist(self.doclist,'entries'): - if d.purchase_order: - submitted = sql("select name from `tabPurchase Order` where docstatus = 1 and name = '%s'" % d.purchase_order) - if not submitted: - msgprint("Purchase Order : "+ cstr(d.purchase_order) +" is not submitted") - raise Exception , "Validation Error." - if d.purchase_receipt: - submitted = sql("select name from `tabPurchase Receipt` where docstatus = 1 and name = '%s'" % d.purchase_receipt) - if not submitted: - msgprint("Purchase Receipt : "+ cstr(d.purchase_receipt) +" is not submitted") - raise Exception , "Validation Error." + # Check Ref Document docstatus + # ----------------------------- + def check_prev_docstatus(self): + for d in getlist(self.doclist,'entries'): + if d.purchase_order: + submitted = sql("select name from `tabPurchase Order` where docstatus = 1 and name = '%s'" % d.purchase_order) + if not submitted: + msgprint("Purchase Order : "+ cstr(d.purchase_order) +" is not submitted") + raise Exception , "Validation Error." + if d.purchase_receipt: + submitted = sql("select name from `tabPurchase Receipt` where docstatus = 1 and name = '%s'" % d.purchase_receipt) + if not submitted: + msgprint("Purchase Receipt : "+ cstr(d.purchase_receipt) +" is not submitted") + raise Exception , "Validation Error." - def update_against_document_in_jv(self, against_document_no, against_document_doctype): - get_obj('GL Control').update_against_document_in_jv( self,'advance_allocation_details', against_document_no, against_document_doctype, self.doc.credit_to, 'debit',self.doc.doctype) + def update_against_document_in_jv(self, against_document_no, against_document_doctype): + get_obj('GL Control').update_against_document_in_jv( self,'advance_allocation_details', against_document_no, against_document_doctype, self.doc.credit_to, 'debit',self.doc.doctype) - # On Submit - # ---------- - def on_submit(self): - self.check_prev_docstatus() - - # Check for Approving Authority - get_obj('Authorization Control').validate_approving_authority(self.doc.doctype,self.doc.company, self.doc.grand_total) - - - # this sequence because outstanding may get -negative - get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist) - self.update_against_document_in_jv(self.doc.name, self.doc.doctype) - get_obj(dt = 'Purchase Common').update_prevdoc_detail(self, is_submit = 1) + # On Submit + # ---------- + def on_submit(self): + self.check_prev_docstatus() + + # Check for Approving Authority + get_obj('Authorization Control').validate_approving_authority(self.doc.doctype,self.doc.company, self.doc.grand_total) + + + # this sequence because outstanding may get -negative + get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist) + self.update_against_document_in_jv(self.doc.name, self.doc.doctype) + get_obj(dt = 'Purchase Common').update_prevdoc_detail(self, is_submit = 1) # ********************************* CANCEL ********************************* - # Check Next Document's docstatus - # -------------------------------- - def check_next_docstatus(self): - submit_jv = sql("select t1.name from `tabJournal Voucher` t1,`tabJournal Voucher Detail` t2 where t1.name = t2.parent and t2.against_voucher = '%s' and t1.docstatus = 1" % (self.doc.name)) - if submit_jv: - msgprint("Journal Voucher : " + cstr(submit_jv[0][0]) + " has been created against " + cstr(self.doc.doctype) + ". So " + cstr(self.doc.doctype) + " cannot be Cancelled.") - raise Exception, "Validation Error." - - # On Cancel - # ---------- - def on_cancel(self): - self.check_next_docstatus() + # Check Next Document's docstatus + # -------------------------------- + def check_next_docstatus(self): + submit_jv = sql("select t1.name from `tabJournal Voucher` t1,`tabJournal Voucher Detail` t2 where t1.name = t2.parent and t2.against_voucher = '%s' and t1.docstatus = 1" % (self.doc.name)) + if submit_jv: + msgprint("Journal Voucher : " + cstr(submit_jv[0][0]) + " has been created against " + cstr(self.doc.doctype) + ". So " + cstr(self.doc.doctype) + " cannot be Cancelled.") + raise Exception, "Validation Error." + + # On Cancel + # ---------- + def on_cancel(self): + self.check_next_docstatus() - # Check whether tds payment voucher has been created against this voucher - self.check_tds_payment_voucher() - - get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist, cancel=1) - get_obj(dt = 'Purchase Common').update_prevdoc_detail(self, is_submit = 0) + # Check whether tds payment voucher has been created against this voucher + self.check_tds_payment_voucher() + + get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist, cancel=1) + get_obj(dt = 'Purchase Common').update_prevdoc_detail(self, is_submit = 0) - # Check whether tds payment voucher has been created against this voucher - #--------------------------------------------------------------------------- - def check_tds_payment_voucher(self): - tdsp = sql("select parent from `tabTDS Payment Detail` where voucher_no = '%s' and docstatus = 1 and parent not like 'old%'") - if tdsp: - msgprint("TDS Payment voucher '%s' has been made against this voucher. Please cancel the payment voucher to proceed." % (tdsp and tdsp[0][0] or '')) - raise Exception + # Check whether tds payment voucher has been created against this voucher + #--------------------------------------------------------------------------- + def check_tds_payment_voucher(self): + tdsp = sql("select parent from `tabTDS Payment Detail` where voucher_no = '%s' and docstatus = 1 and parent not like 'old%'") + if tdsp: + msgprint("TDS Payment voucher '%s' has been made against this voucher. Please cancel the payment voucher to proceed." % (tdsp and tdsp[0][0] or '')) + raise Exception - # on update - def on_update(self): - pass - + # on update + def on_update(self): + pass + ######################################################################## # Repair Outstanding ####################################################################### - def repair_pv_outstanding(self): - get_obj(dt = 'GL Control').repair_voucher_outstanding(self) + def repair_pv_outstanding(self): + get_obj(dt = 'GL Control').repair_voucher_outstanding(self) diff --git a/buying/doctype/purchase_common/purchase_common.py b/buying/doctype/purchase_common/purchase_common.py index 2350d7c1d5..fe8c8e69a7 100644 --- a/buying/doctype/purchase_common/purchase_common.py +++ b/buying/doctype/purchase_common/purchase_common.py @@ -15,9 +15,9 @@ in_transaction = webnotes.conn.in_transaction convert_to_lists = webnotes.conn.convert_to_lists # ----------------------------------------------------------------------------------------- +from utilities.transaction_base import TransactionBase - -class DocType: +class DocType(TransactionBase): def __init__(self, doc, doclist=[]): self.doc = doc self.doclist = doclist @@ -268,14 +268,11 @@ class DocType: # validate conversion rate def validate_conversion_rate(self, obj): - default_currency = get_obj('Manage Account').doc.default_currency + default_currency = TransactionBase().get_company_currency(obj.doc.company) if not default_currency: - msgprint('Message: Please enter default currency in Global Defaults') + msgprint('Message: Please enter default currency in Company Master') raise Exception - - company_currency = sql("select default_currency from `tabCompany` where name = '%s'" % obj.doc.company) - curr = company_currency and cstr(company_currency[0][0]) or default_currency - if (obj.doc.currency == curr and flt(obj.doc.conversion_rate) != 1.00) or not obj.doc.conversion_rate or (obj.doc.currency != curr and flt(obj.doc.conversion_rate) == 1.00): + if (obj.doc.currency == default_currency and flt(obj.doc.conversion_rate) != 1.00) or not obj.doc.conversion_rate or (obj.doc.currency != default_currency and flt(obj.doc.conversion_rate) == 1.00): msgprint("Message: Please Enter Appropriate Conversion Rate.") raise Exception diff --git a/home/__init__.py b/home/__init__.py index c254c8e777..9e807dfc80 100644 --- a/home/__init__.py +++ b/home/__init__.py @@ -91,7 +91,7 @@ def update_feed1(doc): subject = subject % doc.fields make_feed(doc, subject, color) -def update_feed(doc, method): +def update_feed(doc, method=None): "adds a new feed" if method=='validate': return diff --git a/hr/doctype/leave_application/leave_application.txt b/hr/doctype/leave_application/leave_application.txt index a95f4ce89a..11d01e6ba1 100644 --- a/hr/doctype/leave_application/leave_application.txt +++ b/hr/doctype/leave_application/leave_application.txt @@ -3,16 +3,16 @@ # These values are common in all dictionaries { - 'creation': '2011-02-10 14:10:08', + 'creation': '2011-02-17 13:25:56', 'docstatus': 0, - 'modified': '2011-02-17 13:44:37', + 'modified': '2011-07-08 13:28:15', 'modified_by': 'Administrator', 'owner': 'Administrator' }, # These values are common for all DocType { - '_last_update': '1305714022', + '_last_update': '1310019491', 'autoname': 'LAP/.#####', 'colour': 'White:FFF', 'doctype': 'DocType', @@ -24,7 +24,7 @@ 'show_in_menu': 0, 'subject': 'From %(employee_name)s, %(designation)s', 'tag_fields': 'leave_type', - 'version': 18 + 'version': 17 }, # These values are common for all DocField @@ -54,37 +54,24 @@ # DocPerm { - 'amend': 1, - 'cancel': 1, + 'amend': 0, + 'cancel': 0, 'create': 1, 'doctype': 'DocPerm', 'idx': 1, - 'match': 'owner', 'permlevel': 0, - 'submit': 1, + 'role': 'Employee', + 'submit': 0, 'write': 1 }, - # DocPerm - { - 'amend': 0, - 'cancel': 0, - 'create': 0, - 'doctype': 'DocPerm', - 'idx': 2, - 'match': 'owner', - 'permlevel': 0, - 'submit': 0, - 'write': 0 - }, - # DocPerm { 'amend': 1, 'cancel': 1, 'create': 1, 'doctype': 'DocPerm', - 'idx': 3, + 'idx': 2, 'permlevel': 0, 'role': 'HR User', 'submit': 1, @@ -97,7 +84,7 @@ 'cancel': 1, 'create': 1, 'doctype': 'DocPerm', - 'idx': 4, + 'idx': 3, 'permlevel': 0, 'role': 'HR Manager', 'submit': 1, @@ -106,24 +93,33 @@ # DocPerm { + 'amend': 0, + 'cancel': 0, + 'create': 0, 'doctype': 'DocPerm', - 'idx': 5, + 'idx': 4, 'permlevel': 1, - 'role': 'HR User' + 'role': 'HR User', + 'submit': 0, + 'write': 0 }, # DocPerm { + 'amend': 0, + 'cancel': 0, + 'create': 0, 'doctype': 'DocPerm', - 'idx': 6, + 'idx': 5, 'permlevel': 1, - 'role': 'HR Manager' + 'role': 'HR Manager', + 'submit': 0, + 'write': 0 }, # DocField { 'doctype': 'DocField', - 'fieldname': 'column_break1', 'fieldtype': 'Column Break', 'idx': 1, 'permlevel': 0, @@ -211,7 +207,6 @@ # DocField { 'doctype': 'DocField', - 'fieldname': 'column_break8', 'fieldtype': 'Column Break', 'idx': 8, 'permlevel': 0, @@ -275,12 +270,23 @@ 'width': '300px' }, + # DocField + { + 'doctype': 'DocField', + 'fieldname': 'letter_head', + 'fieldtype': 'Link', + 'idx': 14, + 'label': 'Letter Head', + 'options': 'Letter Head', + 'permlevel': 0 + }, + # DocField { 'doctype': 'DocField', 'fieldname': 'amended_from', 'fieldtype': 'Data', - 'idx': 14, + 'idx': 15, 'label': 'Amended From', 'permlevel': 1 }, @@ -290,7 +296,7 @@ 'doctype': 'DocField', 'fieldname': 'amendment_date', 'fieldtype': 'Date', - 'idx': 15, + 'idx': 16, 'label': 'Amendment Date', 'permlevel': 1 } diff --git a/patches/index_patch.py b/patches/index_patch.py new file mode 100644 index 0000000000..8f6c4f2d81 --- /dev/null +++ b/patches/index_patch.py @@ -0,0 +1,292 @@ +""" + This patch removes wrong indexs and add proper indexes in tables +""" + + +def create_proper_index(): + from webnotes.modules.export_module import export_to_files + + dt_index_fields={ + 'Purchase Receipt Detail': ['prevdoc_docname', 'item_code', 'warehouse', 'prevdoc_detail_docname'], + 'Period Closing Voucher': ['closing_account_head', 'fiscal_year'], + 'Lead': ['lead_name', 'status', 'transaction_date'], + 'Time Sheet Detail': ['app_name'], + 'Item Specification Detail': [], + 'Budget Detail': ['fiscal_year', 'account'], + 'Grade': [], + 'RV Tax Detail': ['parenttype', 'account_head'], + 'TDS Category Account': ['account_head'], + 'Role': [], + 'Leave Allocation': ['leave_type', 'employee', 'fiscal_year'], + 'Branch': [], + 'Department': [], + 'Contact Detail': [], + 'Territory': ['lft', 'rgt', 'parent_territory'], + 'Item Tax': ['tax_type'], + 'Bin': ['warehouse', 'item_code'], + 'PPW Detail': ['warehouse'], + 'Sales Partner': ['partner_name'], + 'Default Home Page': ['home_page', 'role'], + 'Custom Field': ['dt'], + 'DocFormat': ['format'], + 'DocType Mapper': ['from_doctype', 'to_doctype'], + 'Brand': [], + 'Order Lost Reason': [], + 'Journal Voucher': ['posting_date', 'voucher_type'], + 'TDS Return Acknowledgement': ['date_of_receipt', 'acknowledgement'], + 'BOM Report Detail': ['item_code'], + 'Quotation Detail': ['item_code'], + 'Update Delivery Date Detail': ['sales_order_no'], + 'Advance Adjustment Detail': ['journal_voucher'], + 'Authorization Rule': ['approving_user', 'system_user', 'system_role', 'approving_role'], + 'DocPerm': ['permlevel', 'role'], + 'Stock Entry Detail': ['item_code', 't_warehouse', 's_warehouse'], + 'Stock Entry': ['posting_date', 'delivery_note_no', 'purchase_receipt_no', 'production_order'], + 'Price List': [], + 'KRA Sheet': [], + 'Production Order': ['status', 'project_name', 'production_item'], + 'Account': ['lft', 'rgt', 'parent_account'], + 'Earn Deduction Detail': [], + 'Indent': ['status', 'transaction_date'], + 'Tag Detail': [], + 'SS Deduction Detail': ['d_type'], + 'Batch': ['item'], + 'Deduction Type': [], + 'Project': ['project_name', 'customer'], + 'UserRole': ['role'], + 'DocField': ['label', 'fieldtype', 'fieldname'], + 'Property Setter': ['doc_type', 'doc_name', 'property'], + 'Appraisal': ['status', 'employee'], + 'Letter Head': [], + 'Follow up': ['follow_up_by'], + 'Project Cost Breakup': [], + 'Table Mapper Detail': [], + 'Campaign': [], + 'Static Parameter Detail': [], + 'Leave Type': [], + 'Account Balance': ['period', 'start_date', 'end_date', 'account'], + 'Absent Days Detail': [], + 'Tag': [], + 'Raw Materials Supplied': ['raw_material'], + 'Project Activity Update': [], + 'PR Raw Material Detail': [], + 'Bank Reconciliation Detail': ['voucher_id'], + 'Sales Order': ['quotation_no', 'project_name', 'customer', 'posting_date'], + 'Chapter VI A Detail': [], + 'Experience In Company Detail': [], + 'Order Reconciliation Detail': ['sales_order_no'], + 'Attendance': ['employee', 'att_date'], + 'Previous Experience Detail': [], + 'Earning Detail': ['e_type'], + 'Sales Order Detail': ['item_code', 'prevdoc_docname', 'reserved_warehouse'], + 'KRA Template': [], + 'Budget Distribution': ['fiscal_year'], + 'Workstation': ['warehouse'], + 'Period': [], + 'Training Session Details': [], + 'Other Charges': [], + 'State': [], + 'Bulk Rename Tool': [], + 'Landed Cost Master Detail': [], + 'Employee': ['employee_name', 'designation', 'department'], + 'Terms And Conditions': [], + 'TC Detail': [], + 'UOM': [], + 'Supplier Type': [], + 'Project Milestone': [], + 'Landed Cost Master': [], + 'Budget Distribution Detail': [], + 'Form 16A Ack Detail': [], + 'Campaign Expense': [], + 'Time Sheet': ['employee_name', 'time_sheet_date'], + 'File Group': ['parent_group'], + 'Maintenance Visit Detail': ['item_code', 'service_person'], + 'Support Ticket Response': [], + 'PV Detail': ['item_code', 'purchase_order', 'po_detail', 'purchase_receipt', 'pr_detail', 'expense_head', 'cost_center'], + 'Timesheet Detail': ['project_name', 'task_id', 'customer_name'], + 'Holiday List Detail': [], + 'Workflow Rule Detail': [], + 'Module Def': ['module_seq', 'module_page'], + 'Term': [], + 'PF Detail': ['item_code'], + 'POS Setting': ['user', 'territory'], + 'QA Specification Detail': [], + 'Support Ticket': ['customer', 'allocated_to', 'status'], + 'Project Activity': ['project'], + 'Customer Group': ['lft', 'rgt', 'parent_customer_group'], + 'Return Detail': ['item_code'], + 'Series Detail': [], + 'Event Role': ['role'], + 'Contact': ['employee_id'], + 'BOM Material': ['item_code', 'bom_no'], + 'Invest 80 Declaration Detail': [], + 'PO Raw Material Detail': [], + 'Industry Type': [], + 'Declaration Detail': [], + 'Holiday List': ['fiscal_year'], + 'Sales Person': ['lft', 'rgt', 'parent_sales_person'], + 'RV Detail': ['item_code', 'sales_order', 'so_detail', 'delivery_note', 'dn_detail', 'cost_center', 'income_account'], + 'Module Def Item': [], + 'TDS Category': [], + 'DocTrigger': [], + 'Print Format': ['standard'], + 'Installed Item Details': ['prevdoc_docname', 'item_code'], + 'Form 16A Tax Detail': [], + 'Event': ['event_date', 'event_type'], + 'Currency': [], + 'Service Quotation Detail': ['item_code'], + 'Warehouse Type': ['warehouse_type'], + 'Sales BOM': ['item_group'], + 'IT Checklist': ['employee'], + 'Purchase Other Charges': [], + 'Company': [], + 'Call Log': [], + 'Professional Training Details': [], + 'Warehouse': ['warehouse_type'], + 'Competitor': [], + 'Mode of Payment': [], + 'Training Session': ['customer'], + 'Cost Center': ['lft', 'rgt', 'parent_cost_center'], + 'Timesheet': ['status', 'timesheet_date'], + 'Form 16A': ['party_no'], + 'Sales BOM Detail': ['item_code'], + 'Answer': ['question'], + 'Supplier': [], + 'Installation Note': ['delivery_note_no', 'customer', 'inst_date'], + 'Expense Voucher': ['approval_status', 'employee'], + 'Target Detail': ['from_date', 'to_date', 'fiscal_year'], + 'Page Role': ['role'], + 'Partner Target Detail': ['fiscal_year', 'item_group'], + 'Shipping Address': ['customer'], + 'Indent Detail': ['item_code', 'warehouse'], + 'TDS Payment Detail': [], + 'Market Segment': [], + 'Comment Widget Record': [], + 'Service Order Detail': ['item_code', 'prevdoc_docname'], + 'TDS Payment': ['from_date', 'to_date', 'tds_category'], + 'Lead Email CC Detail': [], + 'User Setting-Role User': [], + 'Salary Slip': ['month', 'year', 'employee'], + 'Maintenance Schedule Detail': ['item_code', 'scheduled_date'], + 'Employment Type': [], + 'Advance Allocation Detail': ['journal_voucher'], + 'Quotation': ['customer', 'transaction_date'], + 'Deduction Detail': ['d_type'], + 'Bill Of Materials': ['item', 'project_name'], + 'Earning Type': [], + 'Designation': [], + 'BOM Replace Utility Detail': ['parent_bom'], + 'Question': [], + 'Stock Ledger Entry': ['item_code', 'warehouse', 'posting_date', 'posting_time'], + 'Educational Qualifications Detail': [], + 'BOM Operation': [], + 'Item Group': ['lft', 'rgt', 'parent_item_group'], + 'Workflow Action Detail': [], + 'User Setting-Profile': [], + 'Customer Issue': ['item_code', 'customer', 'complaint_date'], + 'Feed': [], + 'Purchase Tax Detail': ['account_head'], + 'GL Mapper Detail': [], + 'TDS Detail': [], + 'PRO Detail': ['item_code', 'source_warehouse'], + 'DocType Label': [], + 'Receivable Voucher': ['posting_date', 'debit_to', 'project_name'], + 'GL Entry': ['posting_date', 'account', 'voucher_no'], + 'Serial No': ['status', 'warehouse'], + 'Delivery Note': ['posting_date', 'project_name', 'customer'], + 'UOM Conversion Detail': ['uom'], + 'Search Criteria': ['criteria_name'], + 'Salary Structure': [], + 'Educational Qualifications': ['qualification'], + 'TDS Rate Chart': ['applicable_from', 'applicable_to'], + 'GL Mapper': [], + 'Announcement': [], + 'Call Log Details': [], + 'Enquiry': ['lead', 'customer', 'transaction_date'], + 'Flat BOM Detail': ['item_code'], + 'Landed Cost Detail': ['account_head'], + 'Field Mapper Detail': ['from_field', 'to_field'], + 'File Data': [], + 'Question Tag': [], + 'QA Inspection Report': ['item_code', 'purchase_receipt_no', 'report_date'], + 'Appraisal Detail': [], + 'POS Settings': ['territory'], + 'Delivery Note Detail': ['item_code', 'prevdoc_docname', 'warehouse', 'prevdoc_detail_docname'], + 'Profile': [], + 'Other Income Detail': [], + 'Product': ['item_code', 'stock_warehouse'], + 'PO Detail': ['prevdoc_docname', 'item_code', 'prevdoc_detail_docname', 'warehouse'], + 'Module Def Role': ['role'], + 'Sales Team': ['sales_person'], + 'Enquiry Detail': ['item_code'], + 'DocType': [], + 'Compaint Note': ['nature_of_complaint', 'compliance_date'], + 'Maintenance Schedule': ['customer', 'sales_order_no'], + 'Event User': ['person'], + 'Stock Reconciliation': ['reconciliation_date'], + 'Purchase Receipt': ['posting_date', 'supplier', 'project_name'], + 'Complaint Detail': ['item_name'], + 'Address': ['customer', 'supplier'], + 'Ticket': ['request_date', 'allocated_to', 'category', 'customer', 'project'], + 'Territory Target Detail': ['month', 'fiscal_year'], + 'LC PR Detail': ['purchase_receipt_no'], + 'Customer': ['customer_name', 'customer_group'], + 'PP SO Detail': [], + 'PP Detail': ['document_date', 'item_code', 'parent_item'], + 'User Setting-Role Permission': [], + 'Custom Script': ['dt'], + 'Country': [], + 'DefaultValue': [], + 'Ledger Detail': [], + 'SS Earning Detail': ['e_type'], + 'SMS Log': [], + 'Expense Type': [], + 'Item': ['item_group'], + 'Fiscal Year': [], + 'ToDo Item': ['role'], + 'Payable Voucher': ['posting_date', 'credit_to', 'project_name', 'supplier'], + 'Journal Voucher Detail': ['account', 'against_voucher', 'against_invoice', 'against_jv'], + 'Online Contact': [], + 'Page': ['module'], + 'Leave Application': ['employee', 'leave_type', 'from_date', 'to_date'], + 'Expense Voucher Detail': ['expense_type'], + 'Maintenance Visit': ['customer', 'sales_order_no', 'customer_issue_no'], + 'Ref Rate Detail': ['price_list_name', 'ref_currency'], + 'Receiver Detail': [], + 'Naming Series Options': ['doc_type'], + 'Activity Type': [], + 'PRO PP Detail': [], + 'Delivery Note Packing Detail': ['item_code', 'parent_item', 'warehouse'], + 'Workflow Rule': ['select_form'], + 'File': ['file_group'], + 'Item Maintenance Detail': ['item_code', 'start_date', 'end_date', 'prevdoc_docname'], + 'Purchase Order': ['supplier', 'project_name', 'posting_date'], + 'Print Heading': [], + 'TDS Rate Detail': ['category'] + } + + for dt in dt_index_fields.keys(): + current_index = sql("show indexes from `tab%s`" % dt) + + proper_index = dt_index_fields[dt] + + for d in current_index: + if d[4] not in ['name', 'parent', 'parenttype']: + if d[4] not in proper_index: + sql("ALTER TABLE `tab%s` DROP INDEX %s" % (dt, d[4])) + sql("start transaction") + sql("UPDATE `tabDocField` SET search_index = 0 WHERE fieldname = '%s' AND parent = '%s'" % (d[4], dt)) + sql("commit") + else: + proper_index.remove(d[4]) + + for d in proper_index: + sql("ALTER TABLE `tab%s` ADD INDEX ( `%s` ) " % (dt, d)) + sql("start transaction") + sql("UPDATE `tabDocField` SET search_index = 1 WHERE fieldname = '%s' AND parent = '%s'" % (d, dt)) + sql("commit") + + sql("start transaction") + dt_module = sql("select module from `tabDocType` where name = '%s'" % dt)[0][0] + export_to_files(record_list = [['DocType', dt]], record_module = dt_module) + sql("commit") diff --git a/patches/patch.py b/patches/patch.py index 8c839e13d0..9783de5a3e 100644 --- a/patches/patch.py +++ b/patches/patch.py @@ -1,7 +1,7 @@ # REMEMBER to update this # ======================== -last_patch = 315 +last_patch = 323 #------------------------------------------- @@ -1271,3 +1271,21 @@ def execute(patch_no): m.parenttype = 'Module Def' m.parentfield = 'roles' m.save(1) + elif patch_no == 316: + pass + elif patch_no == 317: + sql("update `tabPage` set name = 'profile-settings' where page_name = 'Profile Settings'") + elif patch_no == 318: + reload_doc('utilities', 'doctype', 'bulk_rename_tool') + elif patch_no == 319: + sql("delete from tabFeed where doc_name like 'New %'") + elif patch_no == 320: + reload_doc('setup', 'doctype', 'series_detail') + elif patch_no == 321: + reload_doc('hr','doctype','leave_application') + elif patch_no == 322: + sql("delete from `tabDocField` where parent = 'Leave Application' and fieldname = 'latter_head'") + elif patch_no == 323: + reload_doc('stock', 'doctype', 'stock_entry') + sql("update `tabDocField` set options = 'get_stock_and_rate' where parent = 'Stock Entry' and label = 'Get Stock and Rate'") + sql("delete from `tabDocField` where label = 'Get Current Stock' and parent = 'Stock Entry'") diff --git a/selling/doctype/sales_common/sales_common.py b/selling/doctype/sales_common/sales_common.py index 3f0735f9fa..25dd960bdc 100644 --- a/selling/doctype/sales_common/sales_common.py +++ b/selling/doctype/sales_common/sales_common.py @@ -15,8 +15,9 @@ convert_to_lists = webnotes.conn.convert_to_lists # ----------------------------------------------------------------------------------------- +from utilities.transaction_base import TransactionBase -class DocType: +class DocType(TransactionBase): def __init__(self,d,dl): self.doc, self.doclist = d,dl @@ -262,10 +263,11 @@ class DocType: # Check Conversion Rate (i.e. it will not allow conversion rate to be 1 for Currency other than default currency set in Global Defaults) # =========================================================================== def check_conversion_rate(self, obj): - default_currency = get_obj('Manage Account').doc.default_currency - company_currency = sql("select default_currency from `tabCompany` where name = '%s'" % obj.doc.company) - curr = company_currency and cstr(company_currency[0][0]) or default_currency - if (obj.doc.currency == curr and flt(obj.doc.conversion_rate) != 1.00) or not obj.doc.conversion_rate or (obj.doc.currency != curr and flt(obj.doc.conversion_rate) == 1.00): + default_currency = TransactionBase().get_company_currency(obj.doc.company) + if not default_currency: + msgprint('Message: Please enter default currency in Company Master') + raise Exception + if (obj.doc.currency == default_currency and flt(obj.doc.conversion_rate) != 1.00) or not obj.doc.conversion_rate or (obj.doc.currency != default_currency and flt(obj.doc.conversion_rate) == 1.00): msgprint("Please Enter Appropriate Conversion Rate.") raise Exception diff --git a/setup/doctype/series_detail/__init__.py b/setup/doctype/series_detail/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/setup/doctype/series_detail/series_detail.txt b/setup/doctype/series_detail/series_detail.txt new file mode 100644 index 0000000000..a6df55d8a2 --- /dev/null +++ b/setup/doctype/series_detail/series_detail.txt @@ -0,0 +1,63 @@ +# DocType, Series Detail +[ + + # These values are common in all dictionaries + { + 'creation': '2011-07-08 13:20:10', + 'docstatus': 0, + 'modified': '2011-07-08 13:20:34', + 'modified_by': 'Administrator', + 'owner': 'Administrator' + }, + + # These values are common for all DocType + { + 'colour': 'White:FFF', + 'doctype': 'DocType', + 'istable': 1, + 'module': 'Setup', + 'name': '__common__', + 'section_style': 'Tray', + 'show_in_menu': 0, + 'version': 3 + }, + + # These values are common for all DocField + { + 'doctype': 'DocField', + 'name': '__common__', + 'parent': 'Series Detail', + 'parentfield': 'fields', + 'parenttype': 'DocType', + 'permlevel': 0 + }, + + # DocType, Series Detail + { + 'doctype': 'DocType', + 'name': 'Series Detail' + }, + + # DocField + { + 'doctype': 'DocField', + 'fieldname': 'series', + 'fieldtype': 'Read Only', + 'idx': 1, + 'label': 'Series', + 'oldfieldname': 'series', + 'oldfieldtype': 'Read Only' + }, + + # DocField + { + 'doctype': 'DocField', + 'fieldname': 'remove', + 'fieldtype': 'Check', + 'idx': 2, + 'label': 'Remove', + 'oldfieldname': 'remove', + 'oldfieldtype': 'Check', + 'trigger': 'Client' + } +] \ No newline at end of file diff --git a/setup/doctype/setup_control/setup_control.py b/setup/doctype/setup_control/setup_control.py index 62c39c9ba6..e01e60ae58 100644 --- a/setup/doctype/setup_control/setup_control.py +++ b/setup/doctype/setup_control/setup_control.py @@ -57,7 +57,8 @@ class DocType: # Company master_dict = {'Company':{'company_name':company_name, - 'abbr':comp_abbr + 'abbr':comp_abbr, + 'default_currency':currency }} self.create_records(master_dict) @@ -73,7 +74,9 @@ class DocType: 'pr_required':'No', 'emp_created_by':'Naming Series', 'cust_master_name':'Customer Name', - 'supp_master_name':'Supplier Name'} + 'supp_master_name':'Supplier Name', + 'default_currency_format': (currency=='INR') and 'Lacs' or 'Millions' + } # Set self.set_defaults(def_args) diff --git a/stock/doctype/item/item.js b/stock/doctype/item/item.js index 115ced545a..3c0262979e 100644 --- a/stock/doctype/item/item.js +++ b/stock/doctype/item/item.js @@ -1,6 +1,18 @@ cur_frm.cscript.refresh = function(doc) { - if(cint(doc.is_local) && doc.has_serial_no) set_field_permlevel('has_serial_no', 1); - if(cint(doc.is_local) && doc.is_stock_item) set_field_permlevel('is_stock_item', 1); + // make sensitive fields(has_serial_no, is_stock_item, valuation_method) + // read only if any stock ledger entry exists + + if ((!doc.__islocal) && (doc.is_stock_item == 'Yes')) { + var callback = function(r, rt) { + if (r.message == 'exists') permlevel = 1; + else permlevel = 0; + + set_field_permlevel('has_serial_no', permlevel); + set_field_permlevel('is_stock_item', permlevel); + set_field_permlevel('valuation_method', permlevel); + } + $c_obj(make_doclist(doc.doctype, doc.name),'check_if_sle_exists','',callback); + } } diff --git a/stock/doctype/item/item.py b/stock/doctype/item/item.py index a2fbf0123c..ae677493b5 100644 --- a/stock/doctype/item/item.py +++ b/stock/doctype/item/item.py @@ -170,3 +170,11 @@ Total Available Qty: %s } return str(ret) + + def check_if_sle_exists(self): + """ + checks if any stock ledger entry exists for this item + """ + + 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' diff --git a/stock/doctype/purchase_receipt/purchase_receipt.py b/stock/doctype/purchase_receipt/purchase_receipt.py index 44cd2c762b..0eda680cae 100644 --- a/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/stock/doctype/purchase_receipt/purchase_receipt.py @@ -140,7 +140,8 @@ class DocType(TransactionBase): self.check_for_stopped_status(pc_obj) # get total in words - self.doc.in_words = pc_obj.get_total_in_words(get_defaults().get('currency') or 'INR', self.doc.grand_total) + dcc = TransactionBase().get_company_currency(self.doc.company) + self.doc.in_words = pc_obj.get_total_in_words(dcc, self.doc.grand_total) self.doc.in_words_import = pc_obj.get_total_in_words(self.doc.currency, self.doc.grand_total_import) # update valuation rate self.update_valuation_rate() diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index a07f7698d5..b380995b34 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -250,9 +250,9 @@ class DocType: if self.doc.production_order: pro_obj = get_obj('Production Order', self.doc.production_order) self.validate_for_production_order(pro_obj) + self.get_stock_and_rate(pro_obj and pro_obj.doc.bom_no or '') self.validate_incoming_rate() self.validate_warehouse(pro_obj) - self.get_stock_and_rate(pro_obj and pro_obj.doc.bom_no or '') self.calc_amount() get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.posting_date,'Posting Date') diff --git a/stock/doctype/stock_entry/stock_entry.txt b/stock/doctype/stock_entry/stock_entry.txt index 6959d4d8e3..951986fea3 100644 --- a/stock/doctype/stock_entry/stock_entry.txt +++ b/stock/doctype/stock_entry/stock_entry.txt @@ -3,9 +3,9 @@ # These values are common in all dictionaries { - 'creation': '2010-08-08 17:09:25', + 'creation': '2009-05-12 16:46:45', 'docstatus': 0, - 'modified': '2011-06-14 12:50:12', + 'modified': '2011-07-10 14:12:39', 'modified_by': 'Administrator', 'owner': 'Administrator' }, @@ -13,17 +13,33 @@ # These values are common for all DocType { '_last_update': '1308741898', + 'allow_attach': 0, + 'allow_copy': 0, + 'allow_email': 0, + 'allow_print': 0, + 'allow_rename': 0, + 'allow_trash': 0, 'colour': 'White:FFF', 'doctype': 'DocType', + 'hide_heading': 0, + 'hide_toolbar': 0, + 'in_create': 0, + 'in_dialog': 0, + 'is_transaction_doc': 0, + 'issingle': 0, + 'max_attachments': 0, 'module': 'Stock', 'name': '__common__', 'print_outline': 'No', + 'read_only': 0, + 'read_only_onload': 0, 'search_fields': 'transfer_date, from_warehouse, to_warehouse, purpose, remarks', 'section_style': 'Tabbed', 'server_code_error': ' ', 'show_in_menu': 0, 'subject': '%(remarks)s', 'tag_fields': 'purpose', + 'use_template': 0, 'version': 243 }, @@ -60,7 +76,7 @@ 'doctype': 'DocPerm', 'idx': 1, 'permlevel': 0, - 'role': 'Material Manager', + 'role': 'Material User', 'submit': 1, 'write': 1 }, @@ -73,35 +89,28 @@ 'doctype': 'DocPerm', 'idx': 2, 'permlevel': 1, - 'role': 'Material Manager', + 'role': 'Material User', 'submit': 0, 'write': 0 }, # DocPerm { - 'amend': 1, - 'cancel': 1, - 'create': 1, + 'create': 0, 'doctype': 'DocPerm', 'idx': 3, - 'permlevel': 0, - 'role': 'Material User', - 'submit': 1, + 'permlevel': 2, + 'role': 'Production User', 'write': 1 }, # DocPerm { - 'amend': 0, - 'cancel': 0, - 'create': 0, 'doctype': 'DocPerm', 'idx': 4, - 'permlevel': 1, - 'role': 'Material User', - 'submit': 0, - 'write': 0 + 'permlevel': 2, + 'role': 'Production Manager', + 'write': 1 }, # DocPerm @@ -125,23 +134,13 @@ 'role': 'Production User' }, - # DocPerm - { - 'create': 0, - 'doctype': 'DocPerm', - 'idx': 7, - 'permlevel': 2, - 'role': 'Production User', - 'write': 1 - }, - # DocPerm { 'amend': 1, 'cancel': 1, 'create': 1, 'doctype': 'DocPerm', - 'idx': 8, + 'idx': 7, 'permlevel': 0, 'role': 'Production Manager', 'submit': 1, @@ -151,17 +150,34 @@ # DocPerm { 'doctype': 'DocPerm', - 'idx': 9, + 'idx': 8, 'permlevel': 1, 'role': 'Production Manager' }, # DocPerm { + 'amend': 0, + 'cancel': 0, + 'create': 0, + 'doctype': 'DocPerm', + 'idx': 9, + 'permlevel': 1, + 'role': 'Material Manager', + 'submit': 0, + 'write': 0 + }, + + # DocPerm + { + 'amend': 1, + 'cancel': 1, + 'create': 1, 'doctype': 'DocPerm', 'idx': 10, - 'permlevel': 2, - 'role': 'Production Manager', + 'permlevel': 0, + 'role': 'Material Manager', + 'submit': 1, 'write': 1 }, @@ -187,85 +203,114 @@ # DocField { + 'allow_on_submit': 0, 'colour': 'White:FFF', 'description': 'To manage multiple series please go to Setup > Manage Series', 'doctype': 'DocField', 'fieldname': 'naming_series', 'fieldtype': 'Select', + 'hidden': 0, 'idx': 3, + 'in_filter': 0, 'label': 'Series', 'no_copy': 1, 'oldfieldname': 'naming_series', 'oldfieldtype': 'Select', - 'options': 'STE', + 'options': '\nSTE', 'permlevel': 0, 'print_hide': 1, - 'reqd': 1 + 'report_hide': 0, + 'reqd': 1, + 'search_index': 0 }, # DocField { + 'allow_on_submit': 0, 'description': 'The date at which current entry is corrected in the system.', 'doctype': 'DocField', 'fieldname': 'amendment_date', 'fieldtype': 'Date', + 'hidden': 0, 'idx': 4, + 'in_filter': 0, 'label': 'Amendment Date', 'no_copy': 1, 'oldfieldname': 'amendment_date', 'oldfieldtype': 'Date', 'permlevel': 0, - 'print_hide': 1 + 'print_hide': 1, + 'report_hide': 0, + 'reqd': 0, + 'search_index': 0 }, # DocField { + 'allow_on_submit': 0, 'colour': 'White:FFF', 'doctype': 'DocField', 'fieldname': 'purpose', 'fieldtype': 'Select', + 'hidden': 0, 'idx': 5, 'in_filter': 1, 'label': 'Purpose', + 'no_copy': 0, 'oldfieldname': 'purpose', 'oldfieldtype': 'Select', 'options': 'Material Issue\nMaterial Receipt\nMaterial Transfer\nSales Return\nPurchase Return\nSubcontracting\nProduction Order', 'permlevel': 0, + 'print_hide': 0, + 'report_hide': 0, 'reqd': 1, + 'search_index': 0, 'trigger': 'Client' }, # DocField { + 'allow_on_submit': 0, 'colour': 'White:FFF', 'doctype': 'DocField', 'fieldname': 'delivery_note_no', 'fieldtype': 'Link', 'hidden': 1, 'idx': 6, + 'in_filter': 0, 'label': 'Delivery Note No', + 'no_copy': 0, 'oldfieldname': 'delivery_note_no', 'oldfieldtype': 'Link', 'options': 'Delivery Note', 'permlevel': 0, 'print_hide': 1, + 'report_hide': 0, + 'reqd': 0, + 'search_index': 0, 'trigger': 'Client' }, # DocField { + 'allow_on_submit': 0, 'colour': 'White:FFF', 'doctype': 'DocField', 'fieldname': 'purchase_receipt_no', 'fieldtype': 'Link', 'hidden': 1, 'idx': 7, + 'in_filter': 0, 'label': 'Purchase Receipt No', + 'no_copy': 0, 'oldfieldname': 'purchase_receipt_no', 'oldfieldtype': 'Link', 'options': 'Purchase Receipt', 'permlevel': 0, 'print_hide': 1, + 'report_hide': 0, + 'reqd': 0, + 'search_index': 0, 'trigger': 'Client' }, @@ -284,93 +329,135 @@ # DocField { + 'allow_on_submit': 0, 'colour': 'White:FFF', 'doctype': 'DocField', 'fieldname': 'supplier', 'fieldtype': 'Link', 'hidden': 1, 'idx': 9, + 'in_filter': 0, 'label': 'Supplier', + 'no_copy': 0, 'oldfieldname': 'supplier', 'oldfieldtype': 'Link', 'options': 'Supplier', 'permlevel': 0, 'print_hide': 1, + 'report_hide': 0, + 'reqd': 0, + 'search_index': 0, 'trigger': 'Client' }, # DocField { + 'allow_on_submit': 0, 'doctype': 'DocField', 'fieldname': 'supplier_name', 'fieldtype': 'Data', + 'hidden': 0, 'idx': 10, + 'in_filter': 0, 'label': 'Supplier Name', + 'no_copy': 0, 'oldfieldname': 'supplier_name', 'oldfieldtype': 'Data', - 'permlevel': 1 + 'permlevel': 1, + 'print_hide': 0, + 'report_hide': 0, + 'reqd': 0, + 'search_index': 0 }, # DocField { + 'allow_on_submit': 0, 'colour': 'White:FFF', 'doctype': 'DocField', 'fieldname': 'supplier_address', 'fieldtype': 'Small Text', 'hidden': 1, 'idx': 11, + 'in_filter': 0, 'label': 'Supplier Address', + 'no_copy': 0, 'oldfieldname': 'supplier_address', 'oldfieldtype': 'Small Text', 'permlevel': 0, + 'print_hide': 0, + 'report_hide': 0, + 'reqd': 0, + 'search_index': 0, 'trigger': 'Client' }, # DocField { + 'allow_on_submit': 0, 'colour': 'White:FFF', 'doctype': 'DocField', 'fieldname': 'customer', 'fieldtype': 'Link', 'hidden': 1, 'idx': 12, + 'in_filter': 0, 'label': 'Customer', + 'no_copy': 0, 'oldfieldname': 'customer', 'oldfieldtype': 'Link', 'options': 'Customer', 'permlevel': 0, 'print_hide': 1, + 'report_hide': 0, + 'reqd': 0, + 'search_index': 0, 'trigger': 'Client' }, # DocField { + 'allow_on_submit': 0, 'doctype': 'DocField', 'fieldname': 'customer_name', 'fieldtype': 'Data', 'hidden': 1, 'idx': 13, + 'in_filter': 0, 'label': 'Customer Name', + 'no_copy': 0, 'oldfieldname': 'customer_name', 'oldfieldtype': 'Data', - 'permlevel': 1 + 'permlevel': 1, + 'print_hide': 0, + 'report_hide': 0, + 'reqd': 0, + 'search_index': 0 }, # DocField { + 'allow_on_submit': 0, 'doctype': 'DocField', 'fieldname': 'customer_address', 'fieldtype': 'Small Text', 'hidden': 1, 'idx': 14, + 'in_filter': 0, 'label': 'Customer Address', + 'no_copy': 0, 'oldfieldname': 'customer_address', 'oldfieldtype': 'Small Text', - 'permlevel': 0 + 'permlevel': 0, + 'print_hide': 0, + 'report_hide': 0, + 'reqd': 0, + 'search_index': 0 }, # DocField { + 'allow_on_submit': 0, 'colour': 'White:FFF', 'doctype': 'DocField', 'fieldname': 'process', @@ -379,16 +466,21 @@ 'idx': 15, 'in_filter': 1, 'label': 'Process', + 'no_copy': 0, 'oldfieldname': 'process', 'oldfieldtype': 'Select', 'options': '\nMaterial Transfer\nBackflush', 'permlevel': 2, 'print_hide': 1, + 'report_hide': 0, + 'reqd': 0, + 'search_index': 0, 'trigger': 'Client' }, # DocField { + 'allow_on_submit': 0, 'colour': 'White:FFF', 'doctype': 'DocField', 'fieldname': 'production_order', @@ -397,25 +489,36 @@ 'idx': 16, 'in_filter': 1, 'label': 'Production Order', + 'no_copy': 0, 'oldfieldname': 'production_order', 'oldfieldtype': 'Link', 'options': 'Production Order', 'permlevel': 2, 'print_hide': 1, + 'report_hide': 0, + 'reqd': 0, + 'search_index': 0, 'trigger': 'Client' }, # DocField { + 'allow_on_submit': 0, 'doctype': 'DocField', 'fieldname': 'fg_completed_qty', 'fieldtype': 'Currency', + 'hidden': 0, 'idx': 17, + 'in_filter': 0, 'label': 'FG Completed Qty', + 'no_copy': 0, 'oldfieldname': 'fg_completed_qty', 'oldfieldtype': 'Currency', 'permlevel': 2, 'print_hide': 1, + 'report_hide': 0, + 'reqd': 0, + 'search_index': 0, 'trigger': 'Client' }, @@ -424,47 +527,59 @@ 'colour': 'White:FFF', 'doctype': 'DocField', 'fieldtype': 'HTML', + 'hidden': 0, 'idx': 18, 'label': 'Warehouse HTML', 'no_copy': 0, 'oldfieldtype': 'HTML', 'options': "