payment reconciliation fixes
This commit is contained in:
parent
a81010a5b3
commit
1efaf841c4
@ -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
|
||||||
|
@ -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.")
|
||||||
|
Loading…
Reference in New Issue
Block a user