payment reconciliation fixes

This commit is contained in:
Nabin Hait 2013-01-17 18:26:58 +05:30
parent a81010a5b3
commit 1efaf841c4
2 changed files with 55 additions and 56 deletions

View File

@ -17,14 +17,11 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import webnotes import webnotes
from webnotes.utils import cstr, flt, get_defaults, now, sendmail from webnotes.utils import cstr, flt, get_defaults
from webnotes.model import db_exists
from webnotes.model.doc import Document, addchild from webnotes.model.doc import Document, addchild
from webnotes.model.wrapper import getlist, copy_doclist from webnotes.model.wrapper import getlist
from webnotes.model.code import get_obj from webnotes.model.code import get_obj
from webnotes import msgprint from webnotes import msgprint
from webnotes.utils.email_lib import sendmail
from utilities.transaction_base import TransactionBase from utilities.transaction_base import TransactionBase
@ -55,9 +52,6 @@ class DocType:
return flt(bal) return flt(bal)
# Add a new account
# -----------------
def add_ac(self,arg): def add_ac(self,arg):
arg = eval(arg) arg = eval(arg)
ac = Document('Account') ac = Document('Account')
@ -113,14 +107,23 @@ class DocType:
# Make a dictionary(le) for every gl entry and append to a list(self.entries) # 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, merge_entries): def make_single_entry(self,parent,d,le_map,cancel, merge_entries):
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)): if self.get_val(le_map['account'], d, parent) and \
flist = ['account','cost_center','against','debit','credit','remarks','voucher_type','voucher_no','posting_date','fiscal_year','against_voucher','against_voucher_type','company','is_opening', 'aging_date'] (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', 'posting_date', 'fiscal_year', 'against_voucher',
'against_voucher_type', 'company', 'is_opening', 'aging_date']
# Check budget before gl entry # Check budget before gl entry
#check budget only if account is expense account #check budget only if account is expense account
is_expense_acct = webnotes.conn.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)) is_expense_acct = webnotes.conn.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): 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) 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 # Create new GL entry object and map values
le = Document('GL Entry') le = Document('GL Entry')
@ -136,6 +139,7 @@ class DocType:
else: else:
self.entries.append(le) self.entries.append(le)
def manage_debit_credit(self, cancel): def manage_debit_credit(self, cancel):
total_debit, total_credit = 0, 0 total_debit, total_credit = 0, 0
for le in self.entries: for le in self.entries:
@ -158,6 +162,7 @@ class DocType:
# update total debit / credit # update total debit / credit
total_debit += flt(le.debit, 2) total_debit += flt(le.debit, 2)
total_credit += flt(le.credit, 2) total_credit += flt(le.credit, 2)
webnotes.errprint([le.account, le.debit, le.credit])
diff = flt(total_debit - total_credit, 2) diff = flt(total_debit - total_credit, 2)
if abs(diff)==0.01: if abs(diff)==0.01:
@ -191,8 +196,11 @@ class DocType:
for le_map in le_map_list: for le_map in le_map_list:
if le_map['table_field']: if le_map['table_field']:
for d in getlist(doclist,le_map['table_field']): for d in getlist(doclist,le_map['table_field']):
webnotes.errprint([d.fields])
# purchase_tax_details is the table of other charges in purchase cycle # 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') != 'Valuation'): if le_map['table_field'] != 'purchase_tax_details' or \
(le_map['table_field'] == 'purchase_tax_details' and \
d.fields.get('category') != 'Valuation'):
self.make_single_entry(doc,d,le_map,cancel, merge_entries) self.make_single_entry(doc,d,le_map,cancel, merge_entries)
else: else:
self.make_single_entry(None,doc,le_map,cancel, merge_entries) self.make_single_entry(None,doc,le_map,cancel, merge_entries)
@ -309,9 +317,6 @@ class DocType:
return return
######################################################################################################################
#------------------------------------------
def reconcile_against_document(self, args): def reconcile_against_document(self, args):
""" """
Cancel JV, Update aginst document, split if required and resubmit jv Cancel JV, Update aginst document, split if required and resubmit jv
@ -329,6 +334,7 @@ class DocType:
d['against_fld'] = against_fld[d['against_voucher_type']] d['against_fld'] = against_fld[d['against_voucher_type']]
# cancel JV # cancel JV
webnotes.errprint("cancel")
jv_obj = get_obj('Journal Voucher', d['voucher_no'], with_children=1) jv_obj = get_obj('Journal Voucher', d['voucher_no'], with_children=1)
self.make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel =1, adv_adj =1) self.make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel =1, adv_adj =1)
@ -336,10 +342,10 @@ class DocType:
self.update_against_doc(d, jv_obj) self.update_against_doc(d, jv_obj)
# re-submit JV # re-submit JV
webnotes.errprint("resubmit")
jv_obj = get_obj('Journal Voucher', d['voucher_no'], with_children =1) jv_obj = get_obj('Journal Voucher', d['voucher_no'], with_children =1)
self.make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel = 0, adv_adj =1) self.make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel = 0, adv_adj =1)
#------------------------------------------
def update_against_doc(self, d, jv_obj): def update_against_doc(self, d, jv_obj):
""" """
Updates against document, if partial amount splits into rows Updates against document, if partial amount splits into rows
@ -347,7 +353,8 @@ class DocType:
webnotes.conn.sql(""" webnotes.conn.sql("""
update `tabJournal Voucher Detail` t1, `tabJournal Voucher` t2 update `tabJournal Voucher Detail` t1, `tabJournal Voucher` t2
set t1.%(dr_or_cr)s = '%(allocated_amt)s', t1.%(against_fld)s = '%(against_voucher)s', t2.modified = now() set t1.%(dr_or_cr)s = '%(allocated_amt)s',
t1.%(against_fld)s = '%(against_voucher)s', t2.modified = now()
where t1.name = '%(voucher_detail_no)s' and t1.parent = t2.name""" % d) where t1.name = '%(voucher_detail_no)s' and t1.parent = t2.name""" % d)
if d['allocated_amt'] < d['unadjusted_amt']: if d['allocated_amt'] < d['unadjusted_amt']:
@ -364,7 +371,6 @@ class DocType:
ch.docstatus = 1 ch.docstatus = 1
ch.save(1) ch.save(1)
#------------------------------------------
def check_if_jv_modified(self, args): def check_if_jv_modified(self, args):
""" """
check if there is already a voucher reference check if there is already a voucher reference

View File

@ -18,40 +18,37 @@ from __future__ import unicode_literals
import webnotes import webnotes
from webnotes.utils import flt from webnotes.utils import flt
from webnotes.model import db_exists
from webnotes.model.doc import addchild from webnotes.model.doc import addchild
from webnotes.model.wrapper import getlist, copy_doclist from webnotes.model.wrapper import getlist
from webnotes.model.code import get_obj from webnotes.model.code import get_obj
from webnotes import msgprint from webnotes import msgprint
sql = webnotes.conn.sql
class DocType: class DocType:
def __init__(self, doc, doclist): def __init__(self, doc, doclist):
self.doc = doc self.doc = doc
self.doclist = doclist self.doclist = doclist
self.acc_type = self.doc.account and sql("select debit_or_credit from `tabAccount` where name = %s", self.doc.account)[0][0].lower() or '' self.acc_type = self.doc.account and webnotes.conn.sql("""select debit_or_credit
from `tabAccount` where name = %s""", self.doc.account)[0][0].lower() or ''
self.dt = { self.dt = {
'Sales Invoice': 'Sales Invoice', 'Sales Invoice': 'Sales Invoice',
'Purchase Invoice': 'Purchase Invoice', 'Purchase Invoice': 'Purchase Invoice',
'Journal Voucher': 'Journal Voucher' 'Journal Voucher': 'Journal Voucher'
} }
#--------------------------------------------------
def get_voucher_details(self): def get_voucher_details(self):
tot_amt = sql(""" tot_amt = webnotes.conn.sql("""
select sum(%s) from `tabGL Entry` where select sum(%s) from `tabGL Entry` where
voucher_type = %s and voucher_no = %s voucher_type = %s and voucher_no = %s
and account = %s and ifnull(is_cancelled, 'No') = 'No' and account = %s and ifnull(is_cancelled, 'No') = 'No'""" %
"""% (self.acc_type, '%s', '%s', '%s'), (self.dt[self.doc.voucher_type], self.doc.voucher_no, self.doc.account)) (self.acc_type, '%s', '%s', '%s'),
(self.dt[self.doc.voucher_type], self.doc.voucher_no, self.doc.account))
outstanding = sql(""" outstanding = webnotes.conn.sql("""
select sum(%s) - sum(%s) from `tabGL Entry` where select sum(%s) - sum(%s) from `tabGL Entry` where
against_voucher = %s and voucher_no != %s against_voucher = %s and voucher_no != %s
and account = %s and ifnull(is_cancelled, 'No') = 'No' and account = %s and ifnull(is_cancelled, 'No') = 'No'""" %
""" % ((self.acc_type == 'debit' and 'credit' or 'debit'), self.acc_type, '%s', '%s', '%s'), (self.doc.voucher_no, self.doc.voucher_no, self.doc.account)) ((self.acc_type == 'debit' and 'credit' or 'debit'), self.acc_type, '%s', '%s', '%s'),
(self.doc.voucher_no, self.doc.voucher_no, self.doc.account))
ret = { ret = {
'total_amount': flt(tot_amt[0][0]) or 0, 'total_amount': flt(tot_amt[0][0]) or 0,
@ -60,8 +57,6 @@ class DocType:
return ret return ret
#--------------------------------------------------
def get_payment_entries(self): def get_payment_entries(self):
""" """
Get payment entries for the account and period Get payment entries for the account and period
@ -72,7 +67,6 @@ class DocType:
gle = self.get_gl_entries() gle = self.get_gl_entries()
self.create_payment_table(gle) self.create_payment_table(gle)
#--------------------------------------------------
def get_gl_entries(self): def get_gl_entries(self):
self.validate_mandatory() self.validate_mandatory()
dc = self.acc_type == 'debit' and 'credit' or 'debit' dc = self.acc_type == 'debit' and 'credit' or 'debit'
@ -80,41 +74,40 @@ class DocType:
cond = self.doc.from_date and " and t1.posting_date >= '" + self.doc.from_date + "'" or "" cond = self.doc.from_date and " and t1.posting_date >= '" + self.doc.from_date + "'" or ""
cond += self.doc.to_date and " and t1.posting_date <= '" + self.doc.to_date + "'"or "" cond += self.doc.to_date and " and t1.posting_date <= '" + self.doc.to_date + "'"or ""
cond += self.doc.amt_greater_than and ' and t2.' + dc+' >= ' + self.doc.amt_greater_than or '' cond += self.doc.amt_greater_than and \
cond += self.doc.amt_less_than and ' and t2.' + dc+' <= ' + self.doc.amt_less_than or '' ' and t2.' + dc+' >= ' + self.doc.amt_greater_than or ''
cond += self.doc.amt_less_than and \
' and t2.' + dc+' <= ' + self.doc.amt_less_than or ''
gle = sql(""" gle = webnotes.conn.sql("""
select t1.name as voucher_no, t1.posting_date, t1.total_debit as total_amt, sum(ifnull(t2.credit, 0)) - sum(ifnull(t2.debit, 0)) as amt_due, t1.remark, t2.against_account, t2.name as voucher_detail_no select t1.name as voucher_no, t1.posting_date, t1.total_debit as total_amt,
sum(ifnull(t2.credit, 0)) - sum(ifnull(t2.debit, 0)) as amt_due, t1.remark,
t2.against_account, t2.name as voucher_detail_no
from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2
where t1.name = t2.parent where t1.name = t2.parent and t1.docstatus = 1 and t2.account = %s
and t1.docstatus = 1 and ifnull(t2.against_voucher, '')='' and ifnull(t2.against_invoice, '')=''
and t2.account = %s and ifnull(t2.against_jv, '')='' and t2.%s > 0 %s group by t1.name, t2.name """ %
and ifnull(t2.against_voucher, '')='' and ifnull(t2.against_invoice, '')='' and ifnull(t2.against_jv, '')='' ('%s', dc, cond), self.doc.account, as_dict=1)
and t2.%s > 0
%s
group by t1.name, t2.name
"""% ('%s', dc, cond), self.doc.account, as_dict=1)
return gle return gle
#--------------------------------------------------
def create_payment_table(self, gle): def create_payment_table(self, gle):
for d in gle: for d in gle:
ch = addchild(self.doc, 'ir_payment_details', 'Payment to Invoice Matching Tool Detail', self.doclist) ch = addchild(self.doc, 'ir_payment_details',
'Payment to Invoice Matching Tool Detail', self.doclist)
ch.voucher_no = d.get('voucher_no') ch.voucher_no = d.get('voucher_no')
ch.posting_date = d.get('posting_date') ch.posting_date = d.get('posting_date')
ch.amt_due = self.acc_type == 'debit' and flt(d.get('amt_due')) or -1*flt(d.get('amt_due')) ch.amt_due = self.acc_type == 'debit' and flt(d.get('amt_due')) \
or -1*flt(d.get('amt_due'))
ch.total_amt = flt(d.get('total_amt')) ch.total_amt = flt(d.get('total_amt'))
ch.against_account = d.get('against_account') ch.against_account = d.get('against_account')
ch.remarks = d.get('remark') ch.remarks = d.get('remark')
ch.voucher_detail_no = d.get('voucher_detail_no') ch.voucher_detail_no = d.get('voucher_detail_no')
#--------------------------------------------------
def validate_mandatory(self): def validate_mandatory(self):
if not self.doc.account: if not self.doc.account:
msgprint("Please select Account first", raise_exception=1) msgprint("Please select Account first", raise_exception=1)
#--------------------------------------------------
def reconcile(self): def reconcile(self):
""" """
Links booking and payment voucher Links booking and payment voucher
@ -122,7 +115,8 @@ class DocType:
2. split into multiple rows if partially adjusted, assign against voucher 2. split into multiple rows if partially adjusted, assign against voucher
3. submit payment voucher 3. submit payment voucher
""" """
if not self.doc.voucher_no or not sql("select name from `tab%s` where name = %s" %(self.dt[self.doc.voucher_type], '%s'), self.doc.voucher_no): if not self.doc.voucher_no or not webnotes.conn.sql("""select name from `tab%s`
where name = %s""" % (self.dt[self.doc.voucher_type], '%s'), self.doc.voucher_no):
msgprint("Please select valid Voucher No to proceed", raise_exception=1) msgprint("Please select valid Voucher No to proceed", raise_exception=1)
lst = [] lst = []
@ -142,7 +136,6 @@ class DocType:
lst.append(args) lst.append(args)
if lst: if lst:
get_obj('GL Control').reconcile_against_document(lst) get_obj('GL Control').reconcile_against_document(lst)
msgprint("Successfully allocated.") msgprint("Successfully allocated.")