Merge pull request #120 from nabinhait/master
internal reco, fixes and testcase for stock entry
This commit is contained in:
commit
af0b889da2
@ -5,7 +5,7 @@
|
||||
{
|
||||
'creation': '2010-09-25 10:50:37',
|
||||
'docstatus': 0,
|
||||
'modified': '2011-09-12 13:22:15',
|
||||
'modified': '2011-09-27 12:44:04',
|
||||
'modified_by': 'Administrator',
|
||||
'owner': 'Administrator'
|
||||
},
|
||||
@ -128,6 +128,15 @@
|
||||
'doctype': 'Module Def Item'
|
||||
},
|
||||
|
||||
# Module Def Item
|
||||
{
|
||||
'description': 'Link your invoices and payment vouchers to clear/update outstanding amount',
|
||||
'display_name': 'Internal Reconciliation',
|
||||
'doc_name': 'Internal Reconciliation',
|
||||
'doc_type': 'Single DocType',
|
||||
'doctype': 'Module Def Item'
|
||||
},
|
||||
|
||||
# Module Def Item
|
||||
{
|
||||
'display_name': 'TDS Payment',
|
||||
|
@ -1,367 +0,0 @@
|
||||
class DocType:
|
||||
def __init__(self,d,dl):
|
||||
self.doc, self.doclist = d, dl
|
||||
self.entries = []
|
||||
|
||||
# Get Company List
|
||||
# ----------------
|
||||
def get_companies(self,arg=''):
|
||||
d = get_defaults()
|
||||
ret = sql("select name, abbr from tabCompany where docstatus != 2")
|
||||
pl = {}
|
||||
for r in ret:
|
||||
inc = get_value('Account','Income - '+r[1], 'balance')
|
||||
exp = get_value('Account','Expenses - '+r[1], 'balance')
|
||||
pl[r[0]] = flt(flt(inc) - flt(exp))
|
||||
return {'cl':[r[0] for r in ret], 'pl':pl}
|
||||
|
||||
# Get current balance
|
||||
# --------------------
|
||||
def get_bal(self,arg):
|
||||
ac, fy = arg.split('~~~')
|
||||
det = sql("select t1.balance, t2.debit_or_credit from `tabAccount Balance` t1, `tabAccount` t2 where t1.period = %s and t2.name=%s and t1.parent = t2.name", (fy, ac))
|
||||
bal = det and flt(det[0][0]) or 0
|
||||
dr_or_cr = det and flt(det[0][1]) or ''
|
||||
return fmt_money(bal) + ' ' + dr_or_cr
|
||||
|
||||
def get_period_balance(self,arg):
|
||||
acc, f, t = arg.split('~~~')
|
||||
c, fy = '', get_defaults()['fiscal_year']
|
||||
|
||||
det = sql("select debit_or_credit, lft, rgt, is_pl_account from tabAccount where name=%s", acc)
|
||||
if f: c += (' and t1.posting_date >= "%s"' % f)
|
||||
if t: c += (' and t1.posting_date <= "%s"' % t)
|
||||
bal = sql("select sum(ifnull(t1.debit,0))-sum(ifnull(t1.credit,0)) from `tabGL Entry` t1 where t1.account='%s' and ifnull(is_opening, 'No') = 'No' %s" % (acc, c))
|
||||
bal = bal and flt(bal[0][0]) or 0
|
||||
|
||||
if det[0][0] != 'Debit':
|
||||
bal = (-1) * bal
|
||||
|
||||
# add opening for balance sheet accounts
|
||||
if det[0][3] == 'No':
|
||||
opening = flt(sql("select opening from `tabAccount Balance` where parent=%s and period=%s", (acc, fy))[0][0])
|
||||
bal = bal + opening
|
||||
|
||||
return flt(bal)
|
||||
|
||||
|
||||
def get_period_difference(self,arg, cost_center =''):
|
||||
# used in General Ledger Page Report
|
||||
# used for Budget where cost center passed as extra argument
|
||||
acc, f, t = arg.split('~~~')
|
||||
c, fy = '', get_defaults()['fiscal_year']
|
||||
|
||||
det = sql("select debit_or_credit, lft, rgt, is_pl_account from tabAccount where name=%s", acc)
|
||||
if f: c += (' and t1.posting_date >= "%s"' % f)
|
||||
if t: c += (' and t1.posting_date <= "%s"' % t)
|
||||
if cost_center: c += (' and t1.cost_center = "%s"' % cost_center)
|
||||
bal = sql("select sum(ifnull(t1.debit,0))-sum(ifnull(t1.credit,0)) from `tabGL Entry` t1 where t1.account='%s' %s" % (acc, c))
|
||||
bal = bal and flt(bal[0][0]) or 0
|
||||
|
||||
if det[0][0] != 'Debit':
|
||||
bal = (-1) * bal
|
||||
|
||||
return flt(bal)
|
||||
|
||||
# Get Children (for tree)
|
||||
# -----------------------
|
||||
def get_cl(self, arg):
|
||||
fy = get_defaults()['fiscal_year']
|
||||
parent, parent_acc_name, company, type = arg.split(',')
|
||||
|
||||
# get children account details
|
||||
if type=='Account':
|
||||
if parent=='Root':
|
||||
cl = sql("select t1.name, t1.group_or_ledger, t1.debit_or_credit, t2.balance, t1.account_name from tabAccount t1, `tabAccount Balance` t2 where t1.parent_account is NULL or t1.parent_account='' and t1.docstatus != 2 and t1.company=%s and t1.name = t2.parent and t2.period = %s order by t1.name asc", (company, fy),as_dict=1)
|
||||
else:
|
||||
cl = sql("select t1.name, t1.group_or_ledger, t1.debit_or_credit, t2.balance, t1.account_name from tabAccount t1, `tabAccount Balance` t2 where t1.parent_account=%s and t1.docstatus != 2 and t1.company=%s and t1.name = t2.parent and t2.period = %s order by t1.name asc",(parent, company, fy) ,as_dict=1)
|
||||
|
||||
# remove Decimals
|
||||
for c in cl: c['balance'] = flt(c['balance'])
|
||||
|
||||
# get children cost center details
|
||||
elif type=='Cost Center':
|
||||
if parent=='Root':
|
||||
cl = sql("select name,group_or_ledger, cost_center_name from `tabCost Center` where parent_cost_center is NULL or parent_cost_center='' and docstatus != 2 and company_name=%s order by name asc",(company),as_dict=1)
|
||||
else:
|
||||
cl = sql("select name,group_or_ledger,cost_center_name from `tabCost Center` where parent_cost_center=%s and docstatus != 2 and company_name=%s order by name asc",(parent,company),as_dict=1)
|
||||
|
||||
return {'parent':parent, 'parent_acc_name':parent_acc_name, 'cl':cl}
|
||||
|
||||
# Add a new account
|
||||
# -----------------
|
||||
def add_ac(self,arg):
|
||||
arg = eval(arg)
|
||||
ac = Document('Account')
|
||||
for d in arg.keys():
|
||||
ac.fields[d] = arg[d]
|
||||
ac.old_parent = ''
|
||||
ac_obj = get_obj(doc=ac)
|
||||
ac_obj.validate()
|
||||
ac_obj.doc.save(1)
|
||||
ac_obj.on_update()
|
||||
|
||||
return ac_obj.doc.name
|
||||
|
||||
# Add a new cost center
|
||||
#----------------------
|
||||
def add_cc(self,arg):
|
||||
arg = eval(arg)
|
||||
cc = Document('Cost Center')
|
||||
# map fields
|
||||
for d in arg.keys():
|
||||
cc.fields[d] = arg[d]
|
||||
# map company abbr
|
||||
other_info = sql("select company_abbr from `tabCost Center` where name='%s'"%arg['parent_cost_center'])
|
||||
cc.company_abbr = other_info and other_info[0][0] or arg['company_abbr']
|
||||
|
||||
cc_obj = get_obj(doc=cc)
|
||||
cc_obj.validate()
|
||||
cc_obj.doc.save(1)
|
||||
cc_obj.on_update()
|
||||
|
||||
return cc_obj.doc.name
|
||||
|
||||
|
||||
|
||||
# Get field values from the voucher
|
||||
#------------------------------------------
|
||||
def get_val(self, src, d, parent=None):
|
||||
if not src:
|
||||
return None
|
||||
if src.startswith('parent:'):
|
||||
return parent.fields[src.split(':')[1]]
|
||||
elif src.startswith('value:'):
|
||||
return eval(src.split(':')[1])
|
||||
elif src:
|
||||
return d.fields.get(src)
|
||||
|
||||
def check_if_in_list(self, le):
|
||||
for e in self.entries:
|
||||
if e.account == le.account and (cstr(e.against_voucher)==cstr(le.against_voucher)) and (cstr(e.against_voucher_type)==cstr(le.against_voucher_type)) and (cstr(e.cost_center)==cstr(le.cost_center)):
|
||||
return [e]
|
||||
return 0
|
||||
|
||||
# Make a dictionary(le) for every gl entry and append to a list(self.entries)
|
||||
#----------------------------------------------------------------------------
|
||||
def make_single_entry(self,parent,d,le_map,cancel):
|
||||
if self.get_val(le_map['account'], d, parent) and (self.get_val(le_map['debit'], d, parent) or self.get_val(le_map['credit'], d, parent)):
|
||||
flist = ['account','cost_center','against','debit','credit','remarks','voucher_type','voucher_no','transaction_date','posting_date','fiscal_year','against_voucher','against_voucher_type','company','is_opening', 'aging_date']
|
||||
|
||||
# Check budget before gl entry
|
||||
#check budget only if account is expense account
|
||||
is_expense_acct = sql("select name from tabAccount where is_pl_account='Yes' and debit_or_credit='Debit' and name=%s",self.get_val(le_map['account'], d, parent))
|
||||
if is_expense_acct and self.get_val(le_map['cost_center'], d, parent):
|
||||
get_obj('Budget Control').check_budget([self.get_val(le_map[k], d, parent) for k in flist if k in ['account','cost_center','debit','credit','posting_date','fiscal_year','company']],cancel)
|
||||
|
||||
# Create new GL entry object and map values
|
||||
le = Document('GL Entry')
|
||||
for k in flist:
|
||||
le.fields[k] = self.get_val(le_map[k], d, parent)
|
||||
|
||||
# if there is already an entry in this account then just add it to that entry
|
||||
same_head = self.check_if_in_list(le)
|
||||
if same_head:
|
||||
same_head = same_head[0]
|
||||
same_head.debit = flt(same_head.debit) + flt(le.debit)
|
||||
same_head.credit = flt(same_head.credit) + flt(le.credit)
|
||||
else:
|
||||
self.entries.append(le)
|
||||
|
||||
# Save GL Entries
|
||||
# ----------------
|
||||
def save_entries(self, cancel, adv_adj):
|
||||
for le in self.entries:
|
||||
# cancel
|
||||
if cancel:
|
||||
tmp=le.debit
|
||||
le.debit, le.credit = le.credit, tmp
|
||||
|
||||
le_obj = get_obj(doc=le)
|
||||
# validate except on_cancel
|
||||
if not cancel:
|
||||
le_obj.validate()
|
||||
|
||||
# save
|
||||
le.save(1)
|
||||
le_obj.on_update(adv_adj)
|
||||
|
||||
# update total debit / credit
|
||||
self.td += flt(le.debit)
|
||||
self.tc += flt(le.credit)
|
||||
|
||||
# Make Multiple Entries
|
||||
# ---------------------
|
||||
def make_gl_entries(self, doc, doclist, cancel=0, adv_adj = 0):
|
||||
# get entries
|
||||
le_map_list = sql("select * from `tabGL Mapper Detail` where parent = %s", doc.doctype, as_dict=1)
|
||||
|
||||
self.td, self.tc = 0.0, 0.0
|
||||
|
||||
for le_map in le_map_list:
|
||||
if le_map['table_field']:
|
||||
for d in getlist(doclist,le_map['table_field']):
|
||||
# purchase_tax_details is the table of other charges in purchase cycle
|
||||
if le_map['table_field'] != 'purchase_tax_details' or (le_map['table_field'] == 'purchase_tax_details' and d.fields.get('category') != 'For Valuation'):
|
||||
self.make_single_entry(doc,d,le_map,cancel)
|
||||
else:
|
||||
self.make_single_entry(None,doc,le_map,cancel)
|
||||
|
||||
# save entries
|
||||
self.save_entries(cancel,adv_adj)
|
||||
|
||||
# check total debit / credit
|
||||
# Due to old wrong entries (total debit != total credit) some voucher could be cancelled
|
||||
if abs(self.td - self.tc) > 0.001 and not cancel:
|
||||
msgprint("Debit and Credit not equal for this voucher: Diff (Debit) is %s" % (self.td-self.tc))
|
||||
raise Exception
|
||||
|
||||
# set as cancelled
|
||||
if cancel:
|
||||
vt, vn = self.get_val(le_map['voucher_type'], doc, doc), self.get_val(le_map['voucher_no'], doc, doc)
|
||||
sql("update `tabGL Entry` set is_cancelled='Yes' where voucher_type=%s and voucher_no=%s", (vt, vn))
|
||||
|
||||
# Get account balance on any date
|
||||
# -------------------------------
|
||||
|
||||
def get_as_on_balance(self, account_name, fiscal_year, as_on, credit_or_debit, is_pl, lft, rgt, ysd):
|
||||
# get total transaction value for the current year
|
||||
bal = bal = sql("select SUM(t1.debit), SUM(t1.credit) from `tabGL Entry` t1, `tabAccount` t2 WHERE t1.posting_date >= %s AND t1.posting_date <= %s and t1.is_opening = 'No' AND t1.account = t2.name AND t2.lft >= %s AND t2.rgt <= %s and t1.is_cancelled = 'No'", (ysd,as_on,lft, rgt))
|
||||
bal = bal and (flt(bal[0][0]) - flt(bal[0][1])) or 0
|
||||
|
||||
if credit_or_debit == 'Credit' and bal:
|
||||
bal = -bal
|
||||
|
||||
# Add opening balance with the transaction value
|
||||
if is_pl=='No':
|
||||
op = sql("select opening from `tabAccount Balance` where parent=%s and period=%s", (account_name, fiscal_year))
|
||||
op = op and op[0][0] or 0
|
||||
bal += flt(op)
|
||||
return flt(bal)
|
||||
|
||||
# ADVANCE ALLOCATION
|
||||
#-------------------
|
||||
def get_advances(self, obj, account_head, table_name,table_field_name, dr_or_cr):
|
||||
jv_detail = sql("select t1.name, t1.remark, t2.%s, t2.name, t1.ded_amount from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 where t1.name = t2.parent and (t2.against_voucher is null or t2.against_voucher = '') and (t2.against_invoice is null or t2.against_invoice = '') and t2.account = '%s' and t2.is_advance = 'Yes' and t1.docstatus = 1 order by t1.voucher_date " % (dr_or_cr,account_head))
|
||||
# clear advance table
|
||||
obj.doc.clear_table(obj.doclist,table_field_name)
|
||||
# Create advance table
|
||||
for d in jv_detail:
|
||||
add = addchild(obj.doc, table_field_name, table_name, 1, obj.doclist)
|
||||
add.journal_voucher = d[0]
|
||||
add.jv_detail_no = d[3]
|
||||
add.remarks = d[1]
|
||||
add.advance_amount = flt(d[2])
|
||||
add.allocate_amount = 0
|
||||
if table_name == 'Advance Allocation Detail':
|
||||
add.tds_amount = flt(d[4])
|
||||
|
||||
# Clear rows which is not adjusted
|
||||
#-------------------------------------
|
||||
def clear_advances(self, obj,table_name,table_field_name):
|
||||
for d in getlist(obj.doclist,table_field_name):
|
||||
if not flt(d.allocated_amount):
|
||||
sql("update `tab%s` set parent = '' where name = '%s' and parent = '%s'" % (table_name, d.name, d.parent))
|
||||
d.parent = ''
|
||||
|
||||
# Update aginst document in journal voucher
|
||||
#------------------------------------------
|
||||
def update_against_document_in_jv(self, obj, table_field_name, against_document_no, against_document_doctype, account_head, dr_or_cr,doctype):
|
||||
for d in getlist(obj.doclist, table_field_name):
|
||||
self.validate_jv_entry(d, account_head, dr_or_cr)
|
||||
if flt(d.advance_amount) == flt(d.allocated_amount):
|
||||
# cancel JV
|
||||
jv_obj = get_obj('Journal Voucher', d.journal_voucher, with_children=1)
|
||||
get_obj(dt='GL Control').make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel =1, adv_adj =1)
|
||||
|
||||
# update ref in JV Detail
|
||||
sql("update `tabJournal Voucher Detail` set %s = '%s' where name = '%s'" % (doctype=='Payable Voucher' and 'against_voucher' or 'against_invoice', cstr(against_document_no), d.jv_detail_no))
|
||||
|
||||
# re-submit JV
|
||||
jv_obj = get_obj('Journal Voucher', d.journal_voucher, with_children =1)
|
||||
get_obj(dt='GL Control').make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel = 0, adv_adj =1)
|
||||
|
||||
elif flt(d.advance_amount) > flt(d.allocated_amount):
|
||||
# cancel JV
|
||||
jv_obj = get_obj('Journal Voucher', d.journal_voucher, with_children=1)
|
||||
get_obj(dt='GL Control').make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel =1, adv_adj = 1)
|
||||
|
||||
# add extra entries
|
||||
self.add_extra_entry(jv_obj, d.journal_voucher, d.jv_detail_no, flt(d.allocated_amount), account_head, doctype, dr_or_cr, against_document_no)
|
||||
|
||||
# re-submit JV
|
||||
jv_obj = get_obj('Journal Voucher', d.journal_voucher, with_children =1)
|
||||
get_obj(dt='GL Control').make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel = 0, adv_adj = 1)
|
||||
else:
|
||||
msgprint("Allocation amount cannot be greater than advance amount")
|
||||
raise Exception
|
||||
|
||||
# Add extra row in jv detail for unadjusted amount
|
||||
#--------------------------------------------------
|
||||
def add_extra_entry(self,jv_obj,jv,jv_detail_no, allocate, account_head, doctype, dr_or_cr, against_document_no):
|
||||
# get old entry details
|
||||
|
||||
jvd = sql("select %s, cost_center, balance, against_account from `tabJournal Voucher Detail` where name = '%s'" % (dr_or_cr,jv_detail_no))
|
||||
advance = jvd and flt(jvd[0][0]) or 0
|
||||
balance = flt(advance) - flt(allocate)
|
||||
|
||||
# update old entry
|
||||
sql("update `tabJournal Voucher Detail` set %s = '%s', %s = '%s' where name = '%s'" % (dr_or_cr, flt(allocate), doctype == "Payable Voucher" and 'against_voucher' or 'against_invoice',cstr(against_document_no), jv_detail_no))
|
||||
|
||||
# new entry with balance amount
|
||||
add = addchild(jv_obj.doc, 'entries', 'Journal Voucher Detail', 1, jv_obj.doclist)
|
||||
add.account = account_head
|
||||
add.cost_center = cstr(jvd[0][1])
|
||||
add.balance = cstr(jvd[0][2])
|
||||
add.fields[dr_or_cr] = balance
|
||||
add.against_account = cstr(jvd[0][3])
|
||||
add.is_advance = 'Yes'
|
||||
add.save(1)
|
||||
|
||||
# check if advance entries are still valid
|
||||
# ----------------------------------------
|
||||
def validate_jv_entry(self, d, account_head, dr_or_cr):
|
||||
# 1. check if there is already a voucher reference
|
||||
# 2. check if amount is same
|
||||
# 3. check if is_advance is 'Yes'
|
||||
# 4. check if jv is submitted
|
||||
ret = sql("select t2.%s from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 where t1.name = t2.parent and (t2.against_voucher = '' || t2.against_voucher is null) and (t2.against_invoice = '' || t2.against_invoice is null) and t2.account = '%s' and t1.name = '%s' and t2.name = '%s' and t2.is_advance = 'Yes' and t1.docstatus=1 and t2.%s = %s" % ( dr_or_cr, account_head, d.journal_voucher, d.jv_detail_no, dr_or_cr, d.advance_amount))
|
||||
if (not ret):
|
||||
msgprint("Please click on 'Get Advances Paid' button as the advance entries have been changed.")
|
||||
raise Exception
|
||||
return
|
||||
|
||||
##############################################################################
|
||||
# Repair Outstanding Amount
|
||||
##############################################################################
|
||||
def repair_voucher_outstanding(self, voucher_obj):
|
||||
msg = []
|
||||
|
||||
# Get Balance from GL Entries
|
||||
bal = sql("select sum(debit)-sum(credit) from `tabGL Entry` where against_voucher=%s and against_voucher_type=%s", (voucher_obj.doc.name , voucher_obj.doc.doctype))
|
||||
bal = bal and flt(bal[0][0]) or 0.0
|
||||
if cstr(voucher_obj.doc.doctype) == 'Payable Voucher':
|
||||
bal = -bal
|
||||
|
||||
# Check outstanding Amount
|
||||
if flt(voucher_obj.doc.outstanding_amount) != flt(bal):
|
||||
msgprint('<div style="color: RED"> Difference found in Outstanding Amount of %s : %s (Before : %s; After : %s) </div>' % (voucher_obj.doc.doctype, voucher_obj.doc.name, voucher_obj.doc.outstanding_amount, bal))
|
||||
msg.append('<div style="color: RED"> Difference found in Outstanding Amount of %s : %s (Before : %s; After : %s) </div>' % (voucher_obj.doc.doctype, voucher_obj.doc.name, voucher_obj.doc.outstanding_amount, bal))
|
||||
|
||||
# set voucher balance
|
||||
#sql("update `tab%s` set outstanding_amount=%s where name='%s'" % (voucher_obj.doc.doctype, bal, voucher_obj.doc.name))
|
||||
set(voucher_obj.doc, 'outstanding_amount', flt(bal))
|
||||
|
||||
# Send Mail
|
||||
if msg:
|
||||
email_msg = """ Dear Administrator,
|
||||
|
||||
In Account := %s User := %s has Repaired Outstanding Amount For %s : %s and following was found:-
|
||||
|
||||
%s
|
||||
|
||||
""" % (get_value('Control Panel', None,'account_id'), session['user'], voucher_obj.doc.doctype, voucher_obj.doc.name, '\n'.join(msg))
|
||||
|
||||
sendmail(['jai@webnotestech.com'], subject='Repair Outstanding Amount', parts = [('text/plain', email_msg)])
|
||||
# Acknowledge User
|
||||
msgprint(cstr(voucher_obj.doc.doctype) + " : " + cstr(voucher_obj.doc.name) + " has been checked" + cstr(msg and " and repaired successfully." or ". No changes Found."))
|
@ -1,202 +0,0 @@
|
||||
class DocType:
|
||||
def __init__(self,d,dl):
|
||||
self.doc, self.doclist = d, dl
|
||||
|
||||
# Validate mandatory
|
||||
#-------------------
|
||||
def check_mandatory(self):
|
||||
# Following fields are mandatory in GL Entry
|
||||
mandatory = ['account','remarks','voucher_type','voucher_no','fiscal_year','company']
|
||||
for k in mandatory:
|
||||
if not self.doc.fields.get(k):
|
||||
msgprint("%s is mandatory for GL Entry" % k)
|
||||
raise Exception
|
||||
|
||||
# Zero value transaction is not allowed
|
||||
if not (flt(self.doc.debit) or flt(self.doc.credit)):
|
||||
msgprint("GL Entry: Debit or Credit amount is mandatory for %s" % self.doc.account)
|
||||
raise Exception
|
||||
|
||||
# Debit and credit can not done at the same time
|
||||
if flt(self.doc.credit) != 0 and flt(self.doc.debit) != 0:
|
||||
msgprint("Sorry you cannot credit and debit under same account head.")
|
||||
raise Exception, "Validation Error."
|
||||
|
||||
# Cost center is required only if transaction made against pl account
|
||||
#--------------------------------------------------------------------
|
||||
def pl_must_have_cost_center(self):
|
||||
if sql("select name from tabAccount where name=%s and is_pl_account='Yes'", self.doc.account):
|
||||
if not self.doc.cost_center and not self.doc.voucher_type != 'Period Closing Entry':
|
||||
msgprint("Error: Cost Center must be specified for PL Account: %s" % self.doc.account_name)
|
||||
raise Exception
|
||||
else: # not pl
|
||||
if self.doc.cost_center:
|
||||
self.doc.cost_center = ''
|
||||
|
||||
# Account must be ledger, active and not freezed
|
||||
#-----------------------------------------------
|
||||
def validate_account_details(self, adv_adj):
|
||||
ret = sql("select group_or_ledger, docstatus, freeze_account, company from tabAccount where name=%s", self.doc.account)
|
||||
|
||||
# 1. Checks whether Account type is group or ledger
|
||||
if ret and ret[0][0]=='Group':
|
||||
msgprint("Error: All accounts must be Ledgers. Account %s is a group" % self.doc.account)
|
||||
raise Exception
|
||||
|
||||
# 2. Checks whether Account is active
|
||||
if ret and ret[0][1]==2:
|
||||
msgprint("Error: All accounts must be Active. Account %s moved to Trash" % self.doc.account)
|
||||
raise Exception
|
||||
|
||||
# 3. Account has been freezed for other users except account manager
|
||||
if ret and ret[0][2]== 'Yes' and not adv_adj and not 'Accounts Manager' in session['data']['roles']:
|
||||
msgprint("Error: Account %s has been freezed. Only Accounts Manager can do transaction against this account." % self.doc.account)
|
||||
raise Exception
|
||||
|
||||
# 4. Check whether account is within the company
|
||||
if ret and ret[0][3] != self.doc.company:
|
||||
msgprint("Account: %s does not belong to the company: %s" % (self.doc.account, self.doc.company))
|
||||
raise Exception
|
||||
|
||||
# Posting date must be in selected fiscal year and fiscal year is active
|
||||
#-------------------------------------------------------------------------
|
||||
def validate_posting_date(self):
|
||||
fy = sql("select docstatus, year_start_date from `tabFiscal Year` where name=%s ", self.doc.fiscal_year)
|
||||
ysd = fy[0][1]
|
||||
yed = get_last_day(get_first_day(ysd,0,11))
|
||||
pd = getdate(self.doc.posting_date)
|
||||
if fy[0][0] == 2:
|
||||
msgprint("Fiscal Year is not active. You can restore it from Trash")
|
||||
raise Exception
|
||||
if pd < ysd or pd > yed:
|
||||
msgprint("Posting date must be in the Selected Financial Year")
|
||||
raise Exception
|
||||
|
||||
|
||||
# Nobody can do GL Entries where posting date is before freezing date except 'Accounts Manager'
|
||||
#----------------------------------------------------------------------------------------------
|
||||
def check_freezing_date(self, adv_adj):
|
||||
if not adv_adj:
|
||||
pd,fd = getdate(self.doc.posting_date),0
|
||||
acc_frozen_upto = get_obj(dt = 'Manage Account').doc.acc_frozen_upto or ''
|
||||
if acc_frozen_upto:
|
||||
fd = getdate(acc_frozen_upto)
|
||||
|
||||
bde_auth_role = get_value( 'Manage Account', None,'bde_auth_role')
|
||||
if fd and pd <= fd and (bde_auth_role and not bde_auth_role in session['data']['roles']):
|
||||
msgprint("Message:You are not authorized to do back dated entries for account: %s before %s." % (self.doc.account, str(fd)))
|
||||
raise Exception
|
||||
|
||||
# create new bal if not exists
|
||||
#-----------------------------
|
||||
def create_new_balances(self, ac_obj, p, amt):
|
||||
ac = addchild(ac_obj.doc, 'account_balances', 'Account Balance', 1)
|
||||
ac.period = p[0]
|
||||
ac.start_date = p[1].strftime('%Y-%m-%d')
|
||||
ac.end_date = p[2].strftime('%Y-%m-%d')
|
||||
ac.fiscal_year = p[3]
|
||||
ac.opening = 0
|
||||
ac.balance = amt
|
||||
ac.save()
|
||||
|
||||
# Post Balance
|
||||
# ------------
|
||||
def post_balance(self, acc):
|
||||
# get details
|
||||
lft = sql("select lft, rgt, debit_or_credit from `tabAccount` where name='%s'" % acc)
|
||||
|
||||
# amount to debit
|
||||
amt = flt(self.doc.debit) - flt(self.doc.credit)
|
||||
if lft[0][2] == 'Credit': amt = -amt
|
||||
|
||||
# get periods
|
||||
periods = self.get_period_list(self.doc.posting_date, self.doc.fiscal_year)
|
||||
|
||||
acc_obj = get_obj('Account', self.doc.account)
|
||||
for p in periods:
|
||||
if not sql("select name from `tabAccount Balance` where parent=%s and period=%s", (self.doc.account, p[0])):
|
||||
self.create_new_balances(acc_obj, p, amt)
|
||||
else:
|
||||
# update current
|
||||
pl = sql("update `tabAccount Balance` t1, `tabAccount` t2 set t1.balance = t1.balance + %s where t2.lft<=%s and t2.rgt>=%s and t1.parent = t2.name and t1.period = '%s'" % (amt, cint(lft[0][0]), cint(lft[0][1]), p[0]))
|
||||
|
||||
# update opening
|
||||
if self.doc.is_opening=='Yes':
|
||||
pl = sql("update `tabAccount Balance` t1, `tabAccount` t2 set t1.opening = ifnull(t1.opening,0) + %s where t2.lft<=%s and t2.rgt>=%s and t1.parent = t2.name and t1.period = '%s'" % (amt, cint(lft[0][0]), cint(lft[0][1]), self.doc.fiscal_year))
|
||||
|
||||
# Get periods(month and year)
|
||||
#-----------------------------
|
||||
def get_period_list(self, dt, fy):
|
||||
pl = sql("SELECT name, start_date, end_date, fiscal_year FROM tabPeriod WHERE end_date >='%s' and fiscal_year = '%s' and period_type in ('Month', 'Year')" % (dt,fy))
|
||||
return pl
|
||||
|
||||
# Voucher Balance
|
||||
# ---------------
|
||||
def update_outstanding_amt(self):
|
||||
# get final outstanding amt
|
||||
bal = flt(sql("select sum(debit)-sum(credit) from `tabGL Entry` where against_voucher=%s and against_voucher_type=%s and ifnull(is_cancelled,'No') = 'No'", (self.doc.against_voucher, self.doc.against_voucher_type))[0][0] or 0.0)
|
||||
tds = 0
|
||||
|
||||
if self.doc.against_voucher_type=='Payable Voucher':
|
||||
# amount to debit
|
||||
bal = -bal
|
||||
|
||||
# Check if tds applicable
|
||||
tds = sql("select total_tds_on_voucher from `tabPayable Voucher` where name = '%s'" % self.doc.against_voucher)
|
||||
tds = tds and flt(tds[0][0]) or 0
|
||||
|
||||
# Validation : Outstanding can not be negative
|
||||
if bal < 0 and not tds and self.doc.is_cancelled == 'No':
|
||||
msgprint("Outstanding for Voucher %s will become %s. Outstanding cannot be less than zero. Please match exact outstanding." % (self.doc.against_voucher, fmt_money(bal)))
|
||||
raise Exception
|
||||
|
||||
# Update outstanding amt on against voucher
|
||||
sql("update `tab%s` set outstanding_amount=%s where name='%s'"% (self.doc.against_voucher_type,bal,self.doc.against_voucher))
|
||||
|
||||
|
||||
# Total outstanding can not be greater than credit limit for any time for any customer
|
||||
#---------------------------------------------------------------------------------------------
|
||||
def check_credit_limit(self):
|
||||
#check for user role Freezed
|
||||
master_type=sql("select master_type from `tabAccount` where name='%s' " %self.doc.account)
|
||||
tot_outstanding = 0 #needed when there is no GL Entry in the system for that acc head
|
||||
if (self.doc.voucher_type=='Journal Voucher' or self.doc.voucher_type=='Receivable Voucher') and (master_type and master_type[0][0]=='Customer'):
|
||||
dbcr=sql("select sum(debit),sum(credit) from `tabGL Entry` where account = '%s' and is_cancelled='No'" % self.doc.account)
|
||||
if dbcr:
|
||||
tot_outstanding = flt(dbcr[0][0])-flt(dbcr[0][1])+flt(self.doc.debit)-flt(self.doc.credit)
|
||||
get_obj('Account',self.doc.account).check_credit_limit(self.doc.account, self.doc.company, tot_outstanding)
|
||||
|
||||
#for opening entry account can not be pl account
|
||||
#-----------------------------------------------
|
||||
def check_pl_account(self):
|
||||
if self.doc.is_opening=='Yes':
|
||||
is_pl_account=sql("select is_pl_account from `tabAccount` where name='%s'"%(self.doc.account))
|
||||
if is_pl_account and is_pl_account[0][0]=='Yes':
|
||||
msgprint("For opening balance entry account can not be a PL account")
|
||||
raise Exception
|
||||
|
||||
# Validate
|
||||
# --------
|
||||
def validate(self): # not called on cancel
|
||||
self.check_mandatory()
|
||||
self.pl_must_have_cost_center()
|
||||
self.validate_posting_date()
|
||||
self.doc.is_cancelled = 'No' # will be reset by GL Control if cancelled
|
||||
self.check_credit_limit()
|
||||
self.check_pl_account()
|
||||
|
||||
# On Update
|
||||
#----------
|
||||
def on_update(self,adv_adj):
|
||||
# Account must be ledger, active and not freezed
|
||||
self.validate_account_details(adv_adj)
|
||||
|
||||
# Posting date must be after freezing date
|
||||
self.check_freezing_date(adv_adj)
|
||||
|
||||
# Update current account balance
|
||||
self.post_balance(self.doc.account)
|
||||
|
||||
# Update outstanding amt on against voucher
|
||||
if self.doc.against_voucher:
|
||||
self.update_outstanding_amt()
|
@ -447,12 +447,38 @@ class DocType(TransactionBase):
|
||||
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):
|
||||
"""
|
||||
Links invoice and advance voucher:
|
||||
1. cancel advance voucher
|
||||
2. split into multiple rows if partially adjusted, assign against voucher
|
||||
3. submit advance voucher
|
||||
"""
|
||||
|
||||
lst = []
|
||||
for d in getlist(self.doclist, 'advance_allocation_details'):
|
||||
if flt(d.allocated_amount) > 0:
|
||||
args = {
|
||||
'voucher_no' : d.journal_voucher,
|
||||
'voucher_detail_no' : d.jv_detail_no,
|
||||
'against_voucher_type' : 'Payable Voucher',
|
||||
'against_voucher' : self.doc.name,
|
||||
'account' : self.doc.credit_to,
|
||||
'is_advance' : 'Yes',
|
||||
'dr_or_cr' : 'debit',
|
||||
'unadjusted_amt' : flt(d.advance_amount),
|
||||
'allocated_amt' : flt(d.allocated_amount)
|
||||
}
|
||||
lst.append(args)
|
||||
|
||||
if lst:
|
||||
get_obj('GL Control').reconcile_against_document(lst)
|
||||
|
||||
# On Submit
|
||||
# ----------
|
||||
#--------------------------------------------------------------------
|
||||
def on_submit(self):
|
||||
self.check_prev_docstatus()
|
||||
|
||||
@ -462,7 +488,9 @@ class DocType(TransactionBase):
|
||||
|
||||
# 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)
|
||||
|
||||
self.update_against_document_in_jv()
|
||||
|
||||
get_obj(dt = 'Purchase Common').update_prevdoc_detail(self, is_submit = 1)
|
||||
|
||||
|
||||
|
@ -1,38 +1,109 @@
|
||||
cur_frm.cscript.onload = function(doc,cdt,cdn){
|
||||
$c_obj(make_doclist(cdt,cdn),'get_series','',function(r,rt){
|
||||
if(r.message) set_field_options('naming_series', r.message);
|
||||
});
|
||||
|
||||
|
||||
//--------- ONLOAD -------------
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
|
||||
}
|
||||
|
||||
// Settings Module
|
||||
|
||||
cur_frm.cscript.refresh = function(doc,cdt,cdn){
|
||||
|
||||
|
||||
if(doc.based_on == 'Grand Total' || doc.based_on == 'Average Discount' || doc.based_on == 'Total Claimed Amount' || doc.based_on == 'Not Applicable') hide_field('master_name');
|
||||
else unhide_field('master_name');
|
||||
|
||||
if(doc.based_on == 'Not Applicable') hide_field('value');
|
||||
else unhide_field('value');
|
||||
|
||||
if(doc.transaction == 'Expense Voucher' || doc.transaction == 'Appraisal'){
|
||||
hide_field(['master_name','system_role', 'system_user']);
|
||||
unhide_field(['to_emp','to_designation']);
|
||||
if(doc.transaction == 'Appraisal') hide_field('value');
|
||||
else unhide_field('value');
|
||||
}
|
||||
else {
|
||||
unhide_field(['master_name','system_role', 'system_user','value']);
|
||||
hide_field(['to_emp','to_designation']);
|
||||
}
|
||||
}
|
||||
|
||||
//cash bank account
|
||||
//------------------------------------
|
||||
cur_frm.fields_dict['cash_bank_account'].get_query = function(doc,cdt,cdn) {
|
||||
return 'SELECT tabAccount.name FROM tabAccount WHERE tabAccount.debit_or_credit="Debit" AND tabAccount.is_pl_account = "No" AND tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus!=2 AND tabAccount.company="'+doc.company+'" AND tabAccount.%(key)s LIKE "%s"'
|
||||
cur_frm.cscript.based_on = function(doc){
|
||||
if(doc.based_on == 'Grand Total' || doc.based_on == 'Average Discount' || doc.based_on == 'Total Claimed Amount' || doc.based_on == 'Not Applicable'){
|
||||
doc.master_name = '';
|
||||
refresh_field('master_name');
|
||||
hide_field('master_name');
|
||||
}
|
||||
else{
|
||||
unhide_field('master_name');
|
||||
}
|
||||
|
||||
if(doc.based_on == 'Not Applicable') {
|
||||
doc.value =0;
|
||||
refresh_field('value');
|
||||
hide_field('value');
|
||||
}
|
||||
else unhide_field('value');
|
||||
}
|
||||
|
||||
// Income Account
|
||||
// --------------------------------
|
||||
cur_frm.fields_dict['income_account'].get_query = function(doc,cdt,cdn) {
|
||||
return 'SELECT tabAccount.name FROM tabAccount WHERE tabAccount.debit_or_credit="Credit" AND tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus!=2 AND tabAccount.company="'+doc.company+'" AND tabAccount.account_type ="Income Account" AND tabAccount.%(key)s LIKE "%s"'
|
||||
cur_frm.cscript.transaction = function(doc,cdt,cdn){
|
||||
if(doc.transaction == 'Expense Voucher' || doc.transaction == 'Appraisal'){
|
||||
doc.master_name = doc.system_role = doc.system_user = '';
|
||||
refresh_many(['master_name','system_role', 'system_user']);
|
||||
hide_field(['master_name','system_role', 'system_user']);
|
||||
unhide_field(['to_emp','to_designation']);
|
||||
if(doc.transaction == 'Appraisal') {
|
||||
doc.value =0;
|
||||
refresh_many('value');
|
||||
hide_field('value');
|
||||
}
|
||||
else unhide_field('value');
|
||||
}
|
||||
else {
|
||||
unhide_field(['master_name','system_role', 'system_user','value']);
|
||||
hide_field(['to_emp','to_designation']);
|
||||
}
|
||||
|
||||
if(doc.transaction == 'Expense Voucher') doc.based_on = 'Total Claimed Amount';
|
||||
if(doc.transaction == 'Appraisal') doc.based_on == 'Not Applicable';
|
||||
}
|
||||
|
||||
|
||||
// Cost Center
|
||||
// -----------------------------
|
||||
cur_frm.fields_dict['cost_center'].get_query = function(doc,cdt,cdn) {
|
||||
return 'SELECT `tabCost Center`.`name` FROM `tabCost Center` WHERE `tabCost Center`.`company_name` = "' +doc.company+'" AND `tabCost Center`.%(key)s LIKE "%s" AND `tabCost Center`.`group_or_ledger` = "Ledger" AND `tabCost Center`.`docstatus`!= 2 ORDER BY `tabCost Center`.`name` ASC LIMIT 50';
|
||||
}
|
||||
|
||||
//get query select Territory
|
||||
//=================================================================
|
||||
cur_frm.fields_dict['territory'].get_query = function(doc,cdt,cdn) {
|
||||
return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s" ORDER BY `tabTerritory`.`name` ASC LIMIT 50';
|
||||
// System User Trigger
|
||||
// -------------------
|
||||
cur_frm.fields_dict['system_user'].get_query = function(doc) {
|
||||
return 'SELECT tabProfile.name, tabProfile.first_name FROM tabProfile WHERE tabProfile.name not in ("Administrator","Guest") AND tabProfile.docstatus != 2 AND tabProfile.%(key)s LIKE "%s" LIMIT 50'
|
||||
}
|
||||
|
||||
|
||||
// ------------------ Get Print Heading ------------------------------------
|
||||
cur_frm.fields_dict['select_print_heading'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT `tabPrint Heading`.name FROM `tabPrint Heading` WHERE `tabPrint Heading`.docstatus !=2 AND `tabPrint Heading`.name LIKE "%s" ORDER BY `tabPrint Heading`.name ASC LIMIT 50';
|
||||
// System Role Trigger
|
||||
// -----------------------
|
||||
cur_frm.fields_dict['system_role'].get_query = function(doc) {
|
||||
return 'SELECT tabRole.name FROM tabRole WHERE tabRole.name not in ("Administrator","Guest","All") AND tabRole.docstatus != 2 AND tabRole.%(key)s LIKE "%s" LIMIT 50'
|
||||
}
|
||||
|
||||
|
||||
// Approving User Trigger
|
||||
// -----------------------
|
||||
cur_frm.fields_dict['approving_user'].get_query = function(doc) {
|
||||
return 'SELECT tabProfile.name, tabProfile.first_name FROM tabProfile WHERE tabProfile.name not in ("Administrator","Guest") AND tabProfile.docstatus != 2 AND tabProfile.%(key)s LIKE "%s" LIMIT 50'
|
||||
}
|
||||
|
||||
|
||||
// Approving Role Trigger
|
||||
// -----------------------
|
||||
cur_frm.fields_dict['approving_role'].get_query = function(doc) {
|
||||
return 'SELECT tabRole.name FROM tabRole WHERE tabRole.name not in ("Administrator","Guest","All") AND tabRole.docstatus != 2 AND tabRole.%(key)s LIKE "%s" LIMIT 50'
|
||||
}
|
||||
|
||||
|
||||
// Master Name Trigger
|
||||
// --------------------
|
||||
cur_frm.fields_dict['master_name'].get_query = function(doc){
|
||||
if(doc.based_on == 'Customerwise Discount')
|
||||
return 'SELECT `tabCustomer`.`name` FROM `tabCustomer` WHERE `tabCustomer`.docstatus !=2 and `tabCustomer`.`name` LIKE "%s" ORDER BY `tabCustomer`.`name` DESC LIMIT 50';
|
||||
else if(doc.based_on == 'Itemwise Discount')
|
||||
return 'SELECT `tabItem`.`name` FROM `tabItem` WHERE (IFNULL(`tabItem`.`end_of_life`,"") = "" OR `tabItem`.`end_of_life` = "0000-00-00" OR `tabItem`.`end_of_life` > NOW()) and `tabItem`.is_sales_item = "Yes" and tabItem.%(key)s LIKE "%s" ORDER BY `tabItem`.`name` DESC LIMIT 50';
|
||||
else
|
||||
return 'SELECT `tabItem`.`name` FROM `tabItem` WHERE `tabItem`.`name` = "cheating done to avoid null" ORDER BY `tabItem`.`name` DESC LIMIT 50';
|
||||
}
|
||||
|
@ -225,40 +225,47 @@ class DocType(TransactionBase):
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
# ADVANCE ALLOCATION
|
||||
#-----------------------------------------------------------------
|
||||
def update_against_document_in_jv(self,against_document_no, against_document_doctype):
|
||||
get_obj('GL Control').update_against_document_in_jv( self, 'advance_adjustment_details', against_document_no, against_document_doctype, self.doc.debit_to, 'credit', self.doc.doctype)
|
||||
def update_against_document_in_jv(self):
|
||||
"""
|
||||
Links invoice and advance voucher:
|
||||
1. cancel advance voucher
|
||||
2. split into multiple rows if partially adjusted, assign against voucher
|
||||
3. submit advance voucher
|
||||
"""
|
||||
|
||||
lst = []
|
||||
for d in getlist(self.doclist, 'advance_adjustment_details'):
|
||||
if flt(d.allocated_amount) > 0:
|
||||
args = {
|
||||
'voucher_no' : d.journal_voucher,
|
||||
'voucher_detail_no' : d.jv_detail_no,
|
||||
'against_voucher_type' : 'Receivable Voucher',
|
||||
'against_voucher' : self.doc.name,
|
||||
'account' : self.doc.debit_to,
|
||||
'is_advance' : 'Yes',
|
||||
'dr_or_cr' : 'credit',
|
||||
'unadjusted_amt' : flt(d.advance_amount),
|
||||
'allocated_amt' : flt(d.allocated_amount)
|
||||
}
|
||||
lst.append(args)
|
||||
|
||||
if lst:
|
||||
get_obj('GL Control').reconcile_against_document(lst)
|
||||
|
||||
|
||||
|
||||
# ************************************* VALIDATE **********************************************
|
||||
# Get Customer Name and address based on Debit To Account selected
|
||||
# This case arises in case of direct RV where user doesn't enter customer name.
|
||||
# Hence it should be fetched from Account Head.
|
||||
# -----------------------------------------------------------------------------
|
||||
#def get_customer_details(self):
|
||||
# get_obj('Sales Common').get_customer_details(self, inv_det_reqd = 1)
|
||||
# self.get_cust_and_due_date()
|
||||
|
||||
|
||||
# Validate Customer Name with SO or DN if items are fetched from SO or DN
|
||||
# ------------------------------------------------------------------------
|
||||
def validate_customer(self):
|
||||
"""
|
||||
Validate customer name with SO and DN
|
||||
"""
|
||||
for d in getlist(self.doclist,'entries'):
|
||||
customer = ''
|
||||
if d.sales_order:
|
||||
customer = sql("select customer from `tabSales Order` where name = '%s'" % d.sales_order)[0][0]
|
||||
doctype = 'sales order'
|
||||
doctype_no = cstr(d.sales_order)
|
||||
if d.delivery_note:
|
||||
customer = sql("select customer from `tabDelivery Note` where name = '%s'" % d.delivery_note)[0][0]
|
||||
doctype = 'delivery note'
|
||||
doctype_no = cstr(d.delivery_note)
|
||||
if customer and not cstr(self.doc.customer) == cstr(customer):
|
||||
msgprint("Customer %s do not match with customer of %s %s." %(self.doc.customer,doctype,doctype_no))
|
||||
raise Exception , " Validation Error "
|
||||
|
||||
dt = d.delivery_note and 'Delivery Note' or d.sales_order and 'Sales Order' or ''
|
||||
if dt:
|
||||
dt_no = d.delivery_note or d.sales_order
|
||||
cust = sql("select customer from `tab%s` where name = %s" % (dt, '%s'), dt_no)
|
||||
if cust and cstr(cust[0][0]) != cstr(self.doc.customer):
|
||||
msgprint("Customer %s does not match with customer of %s: %s." %(self.doc.customer, dt, dt_no), raise_exception=1)
|
||||
|
||||
|
||||
# Validates Debit To Account and Customer Matches
|
||||
# ------------------------------------------------
|
||||
@ -545,7 +552,7 @@ class DocType(TransactionBase):
|
||||
self.make_gl_entries()
|
||||
|
||||
if not cint(self.doc.is_pos) == 1:
|
||||
self.update_against_document_in_jv(self.doc.name, self.doc.doctype)
|
||||
self.update_against_document_in_jv()
|
||||
|
||||
# on submit notification
|
||||
# get_obj('Notification Control').notify_contact('Sales Invoice', self.doc.doctype,self.doc.name, self.doc.email_id, self.doc.contact_person)
|
||||
|
@ -1,7 +1,7 @@
|
||||
# REMEMBER to update this
|
||||
# ========================
|
||||
|
||||
last_patch = 372
|
||||
last_patch = 374
|
||||
|
||||
#-------------------------------------------
|
||||
|
||||
@ -382,3 +382,7 @@ def execute(patch_no):
|
||||
sql("delete from `tabDocField` where label = 'View Ledger Entry' and parent = 'Journal Voucher' and fieldtype = 'Button' limit 1")
|
||||
if sql("select count(name) from `tabDocField` where label = 'Get Balance' and parent = 'Journal Voucher' and fieldtype = 'Button'")[0][0] > 1:
|
||||
sql("delete from `tabDocField` where label = 'Get Balance' and parent = 'Journal Voucher' and fieldtype = 'Button' limit 1")
|
||||
elif patch_no == 374:
|
||||
reload_doc('accounts', 'doctype', 'internal_reconciliation')
|
||||
reload_doc('accounts', 'doctype', 'ir_payment_detail')
|
||||
reload_doc('accounts', 'Module Def', 'Accounts')
|
||||
|
0
erpnext/sandbox/__init__.py
Normal file
0
erpnext/sandbox/__init__.py
Normal file
110
erpnext/sandbox/test_stock_entry.py
Normal file
110
erpnext/sandbox/test_stock_entry.py
Normal file
@ -0,0 +1,110 @@
|
||||
import unittest
|
||||
|
||||
import webnotes
|
||||
import webnotes.profile
|
||||
webnotes.user = webnotes.profile.Profile()
|
||||
|
||||
|
||||
from webnotes.model.doc import Document
|
||||
from webnotes.model.code import get_obj
|
||||
from webnotes.utils import cstr, flt
|
||||
sql = webnotes.conn.sql
|
||||
|
||||
from sandbox.testdata.masters import *
|
||||
from sandbox.testdata import stock_entry
|
||||
#----------------------------------------------------------
|
||||
|
||||
class TestStockEntry(unittest.TestCase):
|
||||
def setUp(self):
|
||||
print "====================================="
|
||||
webnotes.conn.begin()
|
||||
|
||||
create_master_records()
|
||||
print 'Master Data Created'
|
||||
|
||||
for each in stock_entry.mr:
|
||||
each.save(1)
|
||||
|
||||
for t in stock_entry.mr[1:]:
|
||||
sql("update `tabStock Entry Detail` set parent = '%s' where name = '%s'" % (stock_entry.mr[0].name, t.name))
|
||||
print "Stock Entry Created"
|
||||
|
||||
|
||||
#===========================================================================
|
||||
def test_stock_entry_onsubmit(self):
|
||||
print "Test Case: Stock Entry submission"
|
||||
self.submit_stock_entry()
|
||||
|
||||
expected_sle = (('Stock Entry', stock_entry.mr[0].name, 10, 10, 100, 'No'),)
|
||||
self.check_sle(expected_sle)
|
||||
|
||||
self.check_bin_qty(10)
|
||||
self.check_serial_no('submit', 10)
|
||||
|
||||
#===========================================================================
|
||||
def test_stock_entry_oncancel(self):
|
||||
print "Test Case: Stock Entry Cancellation"
|
||||
self.cancel_stock_entry()
|
||||
|
||||
expected_sle = (
|
||||
('Stock Entry', stock_entry.mr[0].name, 10, 10, 100, 'Yes'),
|
||||
('Stock Entry', stock_entry.mr[0].name, -10, None, None, 'Yes'),
|
||||
)
|
||||
self.check_sle(expected_sle)
|
||||
|
||||
self.check_bin_qty(0)
|
||||
self.check_serial_no('cancel', 10)
|
||||
|
||||
|
||||
#===========================================================================
|
||||
def submit_stock_entry(self):
|
||||
ste1 = get_obj('Stock Entry', stock_entry.mr[0].name, with_children=1)
|
||||
ste1.validate()
|
||||
ste1.on_submit()
|
||||
|
||||
ste1.doc.docstatus = 1
|
||||
ste1.doc.save()
|
||||
|
||||
print "Stock Entry Submitted"
|
||||
|
||||
|
||||
#===========================================================================
|
||||
def cancel_stock_entry(self):
|
||||
self.submit_stock_entry()
|
||||
|
||||
ste1 = get_obj('Stock Entry', stock_entry.mr[0].name, with_children=1)
|
||||
ste1.on_cancel()
|
||||
|
||||
ste1.doc.cancel_reason = "testing"
|
||||
ste1.doc.docstatus = 2
|
||||
ste1.doc.save()
|
||||
|
||||
print "Stock Entry Cancelled"
|
||||
|
||||
#===========================================================================
|
||||
def check_sle(self, expected):
|
||||
print "Checking stock ledger entry........."
|
||||
sle = sql("select voucher_type, voucher_no, actual_qty, bin_aqat, valuation_rate, is_cancelled from `tabStock Ledger Entry` where item_code = 'it' and warehouse = 'wh1'")
|
||||
self.assertTrue(sle == expected)
|
||||
|
||||
#===========================================================================
|
||||
def check_bin_qty(self, expected_qty):
|
||||
print "Checking Bin qty........."
|
||||
bin_qty = sql("select actual_qty from tabBin where item_code = 'it' and warehouse = 'wh1'")
|
||||
self.assertTrue(bin_qty[0][0] == expected_qty)
|
||||
|
||||
#===========================================================================
|
||||
def check_serial_no(self, action, cnt):
|
||||
print "Checking serial nos........"
|
||||
if action == 'submit':
|
||||
status, wh, docstatus = 'In Store', 'wh1', 0
|
||||
else:
|
||||
status, wh, docstatus = 'Not in Use', '', 2
|
||||
|
||||
ser = sql("select count(name) from `tabSerial No` where item_code = 'it' and warehouse = '%s' and status = '%s' and docstatus = %s" % (wh, status, docstatus))
|
||||
|
||||
self.assertTrue(ser[0][0] == cnt)
|
||||
|
||||
#===========================================================================
|
||||
def tearDown(self):
|
||||
webnotes.conn.rollback()
|
0
erpnext/sandbox/testdata/__init__.py
vendored
Normal file
0
erpnext/sandbox/testdata/__init__.py
vendored
Normal file
282
erpnext/sandbox/testdata/masters.py
vendored
Normal file
282
erpnext/sandbox/testdata/masters.py
vendored
Normal file
@ -0,0 +1,282 @@
|
||||
"""
|
||||
All master data in one place, can be created by 1 function call
|
||||
|
||||
"""
|
||||
|
||||
import webnotes
|
||||
from webnotes.model.doc import Document
|
||||
|
||||
|
||||
master_groups = {
|
||||
# Company
|
||||
#----------------------------------
|
||||
'company': Document(
|
||||
fielddata={
|
||||
'doctype':'Company',
|
||||
'abbr': 'co',
|
||||
'company_name' : 'comp',
|
||||
'name': 'comp'
|
||||
}
|
||||
),
|
||||
|
||||
# Customer Group
|
||||
#----------------------------------
|
||||
'customer_group': Document(
|
||||
fielddata={
|
||||
'doctype':'Customer Group',
|
||||
'customer_group_name' : 'cg',
|
||||
'name': 'cg',
|
||||
'is_group': 'No',
|
||||
'parent_customer_group':'',
|
||||
'lft' : 1,
|
||||
'rgt': 2
|
||||
}
|
||||
),
|
||||
|
||||
# Item Group
|
||||
#----------------------------------
|
||||
'item_group': Document(
|
||||
fielddata = {
|
||||
'doctype': 'Item Group',
|
||||
'item_group_name': 'ig',
|
||||
'lft': 1,
|
||||
'rgt': 2,
|
||||
'parent_item_group' : '',
|
||||
'is_group': 'No',
|
||||
'name': 'ig'
|
||||
}
|
||||
),
|
||||
|
||||
# Warehouse Type
|
||||
#-----------------------------
|
||||
'warehouse_type' : Document(
|
||||
fielddata = {
|
||||
'doctype' : 'Warehouse Type',
|
||||
'name': 'normal',
|
||||
'warehouse_type' : 'normal'
|
||||
}
|
||||
),
|
||||
|
||||
# Supplier Type
|
||||
#-----------------------------
|
||||
'supplier_type' : Document(
|
||||
fielddata = {
|
||||
'doctype': 'Supplier Type',
|
||||
'supplier_type': 'stype'
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
||||
main_masters = {
|
||||
# Customer
|
||||
#----------------------------------
|
||||
'customer': Document(
|
||||
fielddata={
|
||||
'doctype':'Customer',
|
||||
'docstatus':0,
|
||||
'customer_name' : 'cust',
|
||||
'company' : 'comp',
|
||||
'customer_group' : '',
|
||||
'name': 'cust'
|
||||
}
|
||||
),
|
||||
|
||||
|
||||
# Supplier
|
||||
#----------------------------------
|
||||
'supplier': Document(
|
||||
fielddata = {
|
||||
'doctype': 'Supplier',
|
||||
'supplier_name': 'supp',
|
||||
'name': 'supp',
|
||||
'supplier_type' : 'stype'
|
||||
}
|
||||
),
|
||||
|
||||
# Customer Account
|
||||
#----------------------------------
|
||||
'customer_acc': Document(
|
||||
fielddata={
|
||||
'doctype':'Account',
|
||||
'docstatus':0,
|
||||
'account_name' : 'cust',
|
||||
'debit_or_credit': 'Debit',
|
||||
'company' : 'comp',
|
||||
'lft': 1,
|
||||
'rgt': 2,
|
||||
'group_or_ledger' : 'Ledger',
|
||||
'is_pl_account': 'No',
|
||||
'name' : 'cust - co'
|
||||
}
|
||||
),
|
||||
|
||||
# Customer Account
|
||||
#----------------------------------
|
||||
'supplier_acc': Document(
|
||||
fielddata={
|
||||
'doctype':'Account',
|
||||
'docstatus':0,
|
||||
'account_name' : 'supp',
|
||||
'debit_or_credit': 'Credit',
|
||||
'company' : 'comp',
|
||||
'lft': 5,
|
||||
'rgt': 6,
|
||||
'group_or_ledger' : 'Ledger',
|
||||
'is_pl_account': 'No',
|
||||
'name' : 'supp - co'
|
||||
}
|
||||
),
|
||||
|
||||
# Bank Account
|
||||
#----------------------------------
|
||||
'bank_acc': Document(
|
||||
fielddata={
|
||||
'doctype':'Account',
|
||||
'docstatus':0,
|
||||
'account_name' : 'icici',
|
||||
'parent_account': '',
|
||||
'debit_or_credit': 'Debit',
|
||||
'company' : 'comp',
|
||||
'lft': 3,
|
||||
'rgt': 4,
|
||||
'group_or_ledger' : 'Ledger',
|
||||
'is_pl_account': 'No',
|
||||
'name' : 'icici - co'
|
||||
}
|
||||
),
|
||||
|
||||
# Income Account
|
||||
#----------------------------------
|
||||
'income_acc': Document(
|
||||
fielddata={
|
||||
'doctype':'Account',
|
||||
'docstatus':0,
|
||||
'account_name' : 'income',
|
||||
'debit_or_credit': 'Credit',
|
||||
'company' : 'comp',
|
||||
'lft': 7,
|
||||
'rgt': 8,
|
||||
'group_or_ledger' : 'Ledger',
|
||||
'is_pl_account': 'Yes',
|
||||
'name' : 'income - co'
|
||||
}
|
||||
),
|
||||
|
||||
# Expense Account
|
||||
#----------------------------------
|
||||
'expense_acc': Document(
|
||||
fielddata={
|
||||
'doctype':'Account',
|
||||
'docstatus':0,
|
||||
'account_name' : 'expense',
|
||||
'debit_or_credit': 'Debit',
|
||||
'company' : 'comp',
|
||||
'lft': 9,
|
||||
'rgt': 10,
|
||||
'group_or_ledger' : 'Ledger',
|
||||
'is_pl_account': 'Yes',
|
||||
'name' : 'expense - co'
|
||||
}
|
||||
),
|
||||
|
||||
# Cost Center
|
||||
#----------------------------------
|
||||
'cost_center': Document(
|
||||
fielddata={
|
||||
'doctype':'Cost Center',
|
||||
'docstatus':0,
|
||||
'cost_center_name' : 'cc',
|
||||
'lft': 1,
|
||||
'rgt': 2,
|
||||
'group_or_ledger' : 'Ledger',
|
||||
'name' : 'cc'
|
||||
}
|
||||
),
|
||||
|
||||
# Item
|
||||
#----------------------------------
|
||||
# Stock item / non-serialized
|
||||
|
||||
'item': [
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Item',
|
||||
'docstatus': 0,
|
||||
'name': 'it',
|
||||
'item_name': 'it',
|
||||
'item_code': 'it',
|
||||
'item_group': 'ig',
|
||||
'is_stock_item': 'Yes',
|
||||
'has_serial_no': 'Yes',
|
||||
'stock_uom': 'Nos',
|
||||
'is_sales_item': 'Yes',
|
||||
'is_purchase_item': 'Yes',
|
||||
'is_service_item': 'No',
|
||||
'is_sub_contracted_item': 'No',
|
||||
'is_pro_applicable': 'Yes',
|
||||
'is_manufactured_item': 'Yes'
|
||||
}
|
||||
),
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Ref Rate Detail',
|
||||
'parentfield': 'ref_rate_details',
|
||||
'parenttype': 'Item',
|
||||
'parent' : 'it',
|
||||
'price_list_name': 'pl',
|
||||
'ref_currency': 'INR',
|
||||
'ref_rate': 100
|
||||
}
|
||||
),
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Item Tax',
|
||||
'parentfield': 'item_tax',
|
||||
'parenttype': 'Item',
|
||||
'parent' : 'it',
|
||||
'tax_type' : 'Tax1',
|
||||
'tax_rate': 10
|
||||
}
|
||||
)
|
||||
],
|
||||
|
||||
# Warehouse
|
||||
#-----------------------------
|
||||
'warehouse': [
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Warehouse',
|
||||
'name' : 'wh1',
|
||||
'warehouse_name' : 'wh1',
|
||||
'warehouse_type': 'normal',
|
||||
'company': 'comp'
|
||||
}
|
||||
),
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Warehouse',
|
||||
'name' : 'wh2',
|
||||
'warehouse_name' : 'wh2',
|
||||
'warehouse_type': 'normal',
|
||||
'company': 'comp'
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Save all master records
|
||||
#----------------------------------
|
||||
def create_master_records():
|
||||
for m in master_groups.keys():
|
||||
master_groups[m].save(1)
|
||||
|
||||
for m in main_masters.keys():
|
||||
if type(main_masters[m]) == list:
|
||||
for each in main_masters[m]:
|
||||
each.save(1)
|
||||
else:
|
||||
main_masters[m].save(1)
|
32
erpnext/sandbox/testdata/stock_entry.py
vendored
Normal file
32
erpnext/sandbox/testdata/stock_entry.py
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
from webnotes.model.doc import Document
|
||||
|
||||
mr = [
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Stock Entry',
|
||||
'posting_date': '2011-09-01',
|
||||
'transfer_date': '2011-09-01',
|
||||
'posting_time': '12:00',
|
||||
'company': 'comp',
|
||||
'fiscal_year' : '2011-2012',
|
||||
'purpose': 'Material Receipt',
|
||||
'name': 'ste'
|
||||
}
|
||||
),
|
||||
Document(
|
||||
fielddata ={
|
||||
'doctype': 'Stock Entry Detail',
|
||||
'parenttype': 'Stock Entry',
|
||||
'parentfield' : 'mtn_details',
|
||||
'parent' : 'ste',
|
||||
'item_code' : 'it',
|
||||
't_warehouse' : 'wh1',
|
||||
'qty' : 10,
|
||||
'transfer_qty' : 10,
|
||||
'incoming_rate': 100,
|
||||
'stock_uom': 'Nos',
|
||||
'conversion_factor': 1,
|
||||
'serial_no': 'srno1, srno2, srno3, srno4, srno5, srno6, srno7, srno8, srno9, srno10'
|
||||
}
|
||||
)
|
||||
]
|
@ -38,7 +38,7 @@ class DocType(TransactionBase):
|
||||
for d in app_dtl:
|
||||
if(d[0]): appr_users.append(d[0])
|
||||
if(d[1]): appr_roles.append(d[1])
|
||||
|
||||
|
||||
if not has_common(appr_roles, webnotes.user.get_roles()) and not has_common(appr_users, session['user']):
|
||||
msg, add_msg = '',''
|
||||
if max_amount:
|
||||
@ -117,7 +117,7 @@ class DocType(TransactionBase):
|
||||
# Check for authorization set for individual user
|
||||
|
||||
based_on = [x[0] for x in sql("select distinct based_on from `tabAuthorization Rule` where transaction = %s and system_user = %s and (company = %s or ifnull(company,'')='') and docstatus != 2", (doctype_name, session['user'], company))]
|
||||
|
||||
|
||||
for d in based_on:
|
||||
self.bifurcate_based_on_type(doctype_name, total, av_dis, d, doc_obj, 1, company)
|
||||
|
||||
@ -128,7 +128,13 @@ class DocType(TransactionBase):
|
||||
# Specific Role
|
||||
# ===============
|
||||
# Check for authorization set on particular roles
|
||||
based_on = [x[0] for x in sql("select based_on from `tabAuthorization Rule` where transaction = %s and system_role IN (%s) and based_on IN (%s) and (company = %s or ifnull(company,'')='') and docstatus != 2", (doctype_name, "'"+"','".join(webnotes.user.get_roles())+"'", "'"+"','".join(final_based_on)+"'",company))]
|
||||
based_on = [x[0] for x in sql("""select based_on
|
||||
from `tabAuthorization Rule`
|
||||
where transaction = %s and system_role IN (%s) and based_on IN (%s)
|
||||
and (company = %s or ifnull(company,'')='')
|
||||
and docstatus != 2
|
||||
""" % ('%s', "'"+"','".join(webnotes.user.get_roles())+"'", "'"+"','".join(final_based_on)+"'", '%s'), (doctype_name, company))]
|
||||
|
||||
for d in based_on:
|
||||
self.bifurcate_based_on_type(doctype_name, total, av_dis, d, doc_obj, 2, company)
|
||||
|
||||
|
@ -139,7 +139,7 @@ class DocType:
|
||||
elif purpose == 'Sales Return':
|
||||
sql("update `tabSerial No` set status = 'Delivered', purchase_document_type = '', purchase_document_no = '' where name = '%s'" % serial_no)
|
||||
else:
|
||||
sql("update `tabSerial No` set docstatus = 2, status = 'Not in Use', purchase_document_type = '', purchase_document_no = '', purchase_date = '', purchase_rate = '', supplier = null, supplier_name = '', supplier_address = '', warehouse = '' where name = '%s'" % serial_no)
|
||||
sql("update `tabSerial No` set docstatus = 2, status = 'Not in Use', purchase_document_type = '', purchase_document_no = '', purchase_date = null, purchase_rate = 0, supplier = null, supplier_name = '', supplier_address = '', warehouse = '' where name = '%s'" % serial_no)
|
||||
|
||||
|
||||
# -------------------------------
|
||||
|
@ -5,17 +5,18 @@
|
||||
{
|
||||
'creation': '2010-08-08 17:09:30',
|
||||
'docstatus': 0,
|
||||
'modified': '2010-12-16 23:57:04',
|
||||
'modified_by': 'nabin@webnotestech.com',
|
||||
'modified': '2011-09-28 16:19:59',
|
||||
'modified_by': 'Administrator',
|
||||
'owner': 'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': '1300788639',
|
||||
'_last_update': '1311621379',
|
||||
'allow_trash': 1,
|
||||
'autoname': 'field:warehouse_name',
|
||||
'colour': 'White:FFF',
|
||||
'default_print_format': 'Standard',
|
||||
'doctype': 'DocType',
|
||||
'document_type': 'Master',
|
||||
'module': 'Stock',
|
||||
@ -24,7 +25,7 @@
|
||||
'section_style': 'Tabbed',
|
||||
'server_code_error': ' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 55
|
||||
'version': 56
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
@ -58,7 +59,6 @@
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 1,
|
||||
'permlevel': 2,
|
||||
'role': 'Material User',
|
||||
'submit': 0,
|
||||
@ -71,7 +71,6 @@
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 2,
|
||||
'permlevel': 0,
|
||||
'role': 'Material User',
|
||||
'submit': 0,
|
||||
@ -84,7 +83,6 @@
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 3,
|
||||
'permlevel': 1,
|
||||
'role': 'Material User',
|
||||
'submit': 0,
|
||||
@ -97,7 +95,6 @@
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 4,
|
||||
'permlevel': 2,
|
||||
'role': 'Material Manager',
|
||||
'submit': 0,
|
||||
@ -110,7 +107,6 @@
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 5,
|
||||
'permlevel': 0,
|
||||
'role': 'Material Manager',
|
||||
'submit': 0,
|
||||
@ -123,7 +119,6 @@
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 6,
|
||||
'permlevel': 1,
|
||||
'role': 'Material Manager',
|
||||
'submit': 0,
|
||||
@ -133,7 +128,6 @@
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 7,
|
||||
'permlevel': 1,
|
||||
'role': 'All'
|
||||
},
|
||||
@ -144,7 +138,6 @@
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 8,
|
||||
'permlevel': 0,
|
||||
'role': 'Material Master Manager',
|
||||
'submit': 0,
|
||||
@ -154,7 +147,6 @@
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 9,
|
||||
'permlevel': 1,
|
||||
'role': 'Material Master Manager'
|
||||
},
|
||||
@ -164,7 +156,6 @@
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 10,
|
||||
'permlevel': 0,
|
||||
'role': 'System Manager',
|
||||
'write': 1
|
||||
@ -174,7 +165,6 @@
|
||||
{
|
||||
'create': 0,
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 11,
|
||||
'permlevel': 2,
|
||||
'role': 'System Manager',
|
||||
'write': 1
|
||||
@ -185,7 +175,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'trash_reason',
|
||||
'fieldtype': 'Small Text',
|
||||
'idx': 1,
|
||||
'label': 'Trash Reason',
|
||||
'oldfieldname': 'trash_reason',
|
||||
'oldfieldtype': 'Small Text',
|
||||
@ -196,7 +185,6 @@
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Section Break',
|
||||
'idx': 2,
|
||||
'label': 'Warehouse Detail',
|
||||
'oldfieldtype': 'Section Break',
|
||||
'permlevel': 0
|
||||
@ -207,7 +195,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'warehouse_name',
|
||||
'fieldtype': 'Data',
|
||||
'idx': 3,
|
||||
'label': 'Warehouse Name',
|
||||
'oldfieldname': 'warehouse_name',
|
||||
'oldfieldtype': 'Data',
|
||||
@ -221,7 +208,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'warehouse_type',
|
||||
'fieldtype': 'Link',
|
||||
'idx': 4,
|
||||
'label': 'Warehouse Type',
|
||||
'oldfieldname': 'warehouse_type',
|
||||
'oldfieldtype': 'Link',
|
||||
@ -237,14 +223,13 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'company',
|
||||
'fieldtype': 'Link',
|
||||
'idx': 5,
|
||||
'in_filter': 1,
|
||||
'label': 'Company',
|
||||
'oldfieldname': 'company',
|
||||
'oldfieldtype': 'Link',
|
||||
'options': 'Company',
|
||||
'permlevel': 0,
|
||||
'search_index': 0
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
@ -253,7 +238,6 @@
|
||||
'fieldname': 'email_id',
|
||||
'fieldtype': 'Data',
|
||||
'hidden': 1,
|
||||
'idx': 6,
|
||||
'label': 'Email Id',
|
||||
'oldfieldname': 'email_id',
|
||||
'oldfieldtype': 'Data',
|
||||
@ -267,7 +251,6 @@
|
||||
'fieldname': 'auto_indent_mail',
|
||||
'fieldtype': 'Select',
|
||||
'hidden': 1,
|
||||
'idx': 7,
|
||||
'label': 'Send Reorder Alert Mail ',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': 'auto_indent_mail',
|
||||
@ -285,7 +268,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'phone_no',
|
||||
'fieldtype': 'Int',
|
||||
'idx': 8,
|
||||
'label': 'Phone No',
|
||||
'oldfieldname': 'phone_no',
|
||||
'oldfieldtype': 'Int',
|
||||
@ -298,7 +280,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'mobile_no',
|
||||
'fieldtype': 'Int',
|
||||
'idx': 9,
|
||||
'label': 'Mobile No',
|
||||
'oldfieldname': 'mobile_no',
|
||||
'oldfieldtype': 'Int',
|
||||
@ -310,7 +291,6 @@
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Column Break',
|
||||
'idx': 10,
|
||||
'oldfieldtype': 'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
@ -320,7 +300,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'address_line_1',
|
||||
'fieldtype': 'Data',
|
||||
'idx': 11,
|
||||
'label': 'Address Line 1',
|
||||
'oldfieldname': 'address_line_1',
|
||||
'oldfieldtype': 'Data',
|
||||
@ -332,7 +311,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'address_line_2',
|
||||
'fieldtype': 'Data',
|
||||
'idx': 12,
|
||||
'label': 'Address Line 2',
|
||||
'oldfieldname': 'address_line_2',
|
||||
'oldfieldtype': 'Data',
|
||||
@ -346,7 +324,6 @@
|
||||
'fieldname': 'country',
|
||||
'fieldtype': 'Link',
|
||||
'hidden': 0,
|
||||
'idx': 13,
|
||||
'in_filter': 0,
|
||||
'label': 'Country',
|
||||
'no_copy': 0,
|
||||
@ -367,7 +344,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'state',
|
||||
'fieldtype': 'Select',
|
||||
'idx': 14,
|
||||
'label': 'State',
|
||||
'oldfieldname': 'state',
|
||||
'oldfieldtype': 'Select',
|
||||
@ -380,7 +356,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'city',
|
||||
'fieldtype': 'Data',
|
||||
'idx': 15,
|
||||
'label': 'City',
|
||||
'oldfieldname': 'city',
|
||||
'oldfieldtype': 'Data',
|
||||
@ -393,7 +368,6 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'pin',
|
||||
'fieldtype': 'Int',
|
||||
'idx': 16,
|
||||
'label': 'PIN',
|
||||
'oldfieldname': 'pin',
|
||||
'oldfieldtype': 'Int',
|
||||
@ -404,7 +378,6 @@
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Section Break',
|
||||
'idx': 17,
|
||||
'label': 'Repost Stock',
|
||||
'oldfieldtype': 'Section Break',
|
||||
'permlevel': 2
|
||||
@ -415,46 +388,9 @@
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Button',
|
||||
'hidden': 0,
|
||||
'idx': 18,
|
||||
'label': 'Repost Stock Ledger',
|
||||
'oldfieldtype': 'Button',
|
||||
'options': 'repost_stock',
|
||||
'permlevel': 2
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'test_field2',
|
||||
'fieldtype': 'Data',
|
||||
'idx': 19,
|
||||
'label': 'Test Field2',
|
||||
'oldfieldname': 'test_field2',
|
||||
'oldfieldtype': 'Data',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'test_field1',
|
||||
'fieldtype': 'Data',
|
||||
'idx': 20,
|
||||
'label': 'Test Field1',
|
||||
'oldfieldname': 'test_field1',
|
||||
'oldfieldtype': 'Data',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'test_field',
|
||||
'fieldtype': 'Data',
|
||||
'idx': 21,
|
||||
'label': 'Test Field',
|
||||
'oldfieldname': 'test_field',
|
||||
'oldfieldtype': 'Data',
|
||||
'permlevel': 0
|
||||
}
|
||||
]
|
Loading…
x
Reference in New Issue
Block a user