Payment to invoice matching tool

This commit is contained in:
Nabin Hait 2014-04-30 19:30:50 +05:30
parent b54307d58e
commit 576f025c84
8 changed files with 255 additions and 188 deletions

View File

@ -10,7 +10,7 @@
{ {
"fieldname": "properties", "fieldname": "properties",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"in_list_view": 1, "in_list_view": 0,
"label": "Account Details", "label": "Account Details",
"oldfieldtype": "Section Break", "oldfieldtype": "Section Break",
"permlevel": 0 "permlevel": 0
@ -18,7 +18,7 @@
{ {
"fieldname": "column_break0", "fieldname": "column_break0",
"fieldtype": "Column Break", "fieldtype": "Column Break",
"in_list_view": 1, "in_list_view": 0,
"permlevel": 0, "permlevel": 0,
"width": "50%" "width": "50%"
}, },
@ -36,18 +36,6 @@
"reqd": 1, "reqd": 1,
"search_index": 1 "search_index": 1
}, },
{
"fieldname": "level",
"fieldtype": "Int",
"hidden": 1,
"in_list_view": 1,
"label": "Level",
"oldfieldname": "level",
"oldfieldtype": "Int",
"permlevel": 0,
"print_hide": 1,
"read_only": 1
},
{ {
"default": "Ledger", "default": "Ledger",
"fieldname": "group_or_ledger", "fieldname": "group_or_ledger",
@ -211,7 +199,7 @@
"icon": "icon-money", "icon": "icon-money",
"idx": 1, "idx": 1,
"in_create": 1, "in_create": 1,
"modified": "2014-04-28 16:52:32.059072", "modified": "2014-04-30 11:28:52.916199",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Account", "name": "Account",

View File

@ -1,7 +1,7 @@
{ {
"allow_import": 1, "allow_import": 1,
"autoname": "naming_series:", "autoname": "naming_series:",
"creation": "2013-03-25 10:53:52.000000", "creation": "2013-03-25 10:53:52",
"docstatus": 0, "docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"fields": [ "fields": [
@ -34,6 +34,7 @@
"reqd": 1 "reqd": 1
}, },
{ {
"default": "Journal Entry",
"fieldname": "voucher_type", "fieldname": "voucher_type",
"fieldtype": "Select", "fieldtype": "Select",
"in_filter": 1, "in_filter": 1,
@ -41,10 +42,11 @@
"label": "Voucher Type", "label": "Voucher Type",
"oldfieldname": "voucher_type", "oldfieldname": "voucher_type",
"oldfieldtype": "Select", "oldfieldtype": "Select",
"options": "\nJournal Entry\nBank Voucher\nCash Voucher\nCredit Card Voucher\nDebit Note\nCredit Note\nContra Voucher\nExcise Voucher\nWrite Off Voucher\nOpening Entry", "options": "Journal Entry\nBank Voucher\nCash Voucher\nCredit Card Voucher\nDebit Note\nCredit Note\nContra Voucher\nExcise Voucher\nWrite Off Voucher\nOpening Entry",
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"read_only": 0, "read_only": 0,
"reqd": 1,
"search_index": 1 "search_index": 1
}, },
{ {
@ -438,7 +440,7 @@
"icon": "icon-file-text", "icon": "icon-file-text",
"idx": 1, "idx": 1,
"is_submittable": 1, "is_submittable": 1,
"modified": "2014-01-20 17:48:51.000000", "modified": "2014-04-29 14:55:19.872882",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Journal Voucher", "name": "Journal Voucher",

View File

@ -1,36 +1,51 @@
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt // License: GNU General Public License v3. See license.txt
cur_frm.add_fetch("account", "company", "company")
cur_frm.cscript.onload_post_render = function(doc) { cur_frm.cscript.onload_post_render = function(doc) {
$(cur_frm.get_field("reconcile").input).addClass("btn-info"); $(cur_frm.get_field("reconcile").input).addClass("btn-info");
} }
cur_frm.cscript.refresh = function(doc) {
cur_frm.set_intro("");
if(!doc.voucher_no) {
cur_frm.set_intro(__("Select the Invoice against which you want to allocate payments."));
} else {
cur_frm.set_intro(__("Set allocated amount against each Payment Entry and click 'Allocate'."));
}
}
cur_frm.fields_dict.voucher_no.get_query = function(doc) { cur_frm.fields_dict.voucher_no.get_query = function(doc) {
// TO-do: check for pos, it should not come // TO-do: check for pos, it should not come
if (!doc.account) msgprint(__("Please select Account first")); if (!doc.account) msgprint(__("Please select Account first"));
else { else {
return { return {
doctype: doc.voucher_type, doctype: doc.voucher_type,
query: "erpnext.accounts.doctype.payment_to_invoice_matching_tool.payment_to_invoice_matching_tool.gl_entry_details", query: "erpnext.accounts.doctype.payment_to_invoice_matching_tool.payment_to_invoice_matching_tool.get_voucher_nos",
filters: { filters: {
"dt": doc.voucher_type, "voucher_type": doc.voucher_type,
"acc": doc.account "account": doc.account
} }
} }
} }
} }
cur_frm.cscript.voucher_no = function(doc, cdt, cdn) { cur_frm.cscript.voucher_no = function() {
return get_server_fields('get_voucher_details', '', '', doc, cdt, cdn, 1) return cur_frm.call({
doc: cur_frm.doc,
method: "get_voucher_details"
});
}
cur_frm.cscript.get_against_entries = function() {
return cur_frm.call({
doc: cur_frm.doc,
method: "get_against_entries"
});
}
cur_frm.cscript.reconcile = function() {
return cur_frm.call({
doc: cur_frm.doc,
method: "reconcile"
});
}
cur_frm.cscript.amt_to_be_reconciled = function(doc, cdt, cdn) {
var total_allocated_amount = 0
$.each(cur_frm.doc.against_entries, function(i, d) {
if(d.amt_to_be_reconciled > 0) total_allocated_amount += flt(d.amt_to_be_reconciled);
else if (d.amt_to_be_reconciled < 0) frappe.throw(__("Allocated amount can not be negative"));
})
cur_frm.set_value("total_allocated_amount", total_allocated_amount);
} }

View File

@ -1,5 +1,5 @@
{ {
"creation": "2013-01-30 12:49:46.000000", "creation": "2013-01-30 12:49:46",
"docstatus": 0, "docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "Other", "document_type": "Other",
@ -7,31 +7,17 @@
{ {
"fieldname": "account", "fieldname": "account",
"fieldtype": "Link", "fieldtype": "Link",
"in_list_view": 0,
"label": "Account", "label": "Account",
"options": "Account", "options": "Account",
"permlevel": 0, "permlevel": 0,
"reqd": 1 "reqd": 1
}, },
{ {
"fieldname": "account_type", "default": "Journal Voucher",
"fieldtype": "Data",
"hidden": 1,
"label": "Account Type",
"permlevel": 0,
"read_only": 1
},
{
"fieldname": "company",
"fieldtype": "Link",
"hidden": 1,
"label": "Company",
"options": "Company",
"permlevel": 0,
"print_hide": 1
},
{
"fieldname": "voucher_type", "fieldname": "voucher_type",
"fieldtype": "Select", "fieldtype": "Select",
"in_list_view": 0,
"label": "Voucher Type", "label": "Voucher Type",
"options": "Sales Invoice\nPurchase Invoice\nJournal Voucher", "options": "Sales Invoice\nPurchase Invoice\nJournal Voucher",
"permlevel": 0, "permlevel": 0,
@ -40,21 +26,16 @@
{ {
"fieldname": "voucher_no", "fieldname": "voucher_no",
"fieldtype": "Link", "fieldtype": "Link",
"in_list_view": 1,
"label": "Voucher No", "label": "Voucher No",
"options": "[Select]", "options": "[Select]",
"permlevel": 0, "permlevel": 0,
"reqd": 1 "reqd": 1
}, },
{
"fieldname": "pull_payment_entries",
"fieldtype": "Button",
"label": "Pull Payment Entries",
"options": "get_payment_entries",
"permlevel": 0
},
{ {
"fieldname": "column_break1", "fieldname": "column_break1",
"fieldtype": "Column Break", "fieldtype": "Column Break",
"in_list_view": 0,
"permlevel": 0, "permlevel": 0,
"print_width": "50%", "print_width": "50%",
"width": "50%" "width": "50%"
@ -62,54 +43,26 @@
{ {
"fieldname": "total_amount", "fieldname": "total_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"in_list_view": 1,
"label": "Total Amount", "label": "Total Amount",
"options": "Company:company:default_currency", "options": "",
"permlevel": 0, "permlevel": 0,
"read_only": 1 "read_only": 1
}, },
{ {
"fieldname": "pending_amt_to_reconcile", "fieldname": "unmatched_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"label": "Outstanding Amount", "label": "Unmatched Amount",
"options": "Company:company:default_currency", "options": "",
"permlevel": 0, "permlevel": 0,
"read_only": 1 "read_only": 1
}, },
{ {
"fieldname": "payment_entries", "fieldname": "against_entries_section",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Payment Entries", "label": "Against Entries",
"permlevel": 0 "permlevel": 0
}, },
{
"description": "Update allocated amount in the above table and then click \"Allocate\" button",
"fieldname": "ir_payment_details",
"fieldtype": "Table",
"label": "Payment Entries",
"options": "Payment to Invoice Matching Tool Detail",
"permlevel": 0
},
{
"fieldname": "reconcile",
"fieldtype": "Button",
"label": "Allocate",
"options": "reconcile",
"permlevel": 0
},
{
"fieldname": "section_break0",
"fieldtype": "Section Break",
"options": "Simple",
"permlevel": 0
},
{
"fieldname": "column_break2",
"fieldtype": "Column Break",
"label": "Filter By Date",
"permlevel": 0,
"print_width": "50%",
"width": "50%"
},
{ {
"fieldname": "from_date", "fieldname": "from_date",
"fieldtype": "Date", "fieldtype": "Date",
@ -122,39 +75,87 @@
"label": "To Date", "label": "To Date",
"permlevel": 0 "permlevel": 0
}, },
{
"fieldname": "help_html",
"fieldtype": "HTML",
"label": "Help HTML",
"options": "Click \"Pull Payment Entries\" to refresh the table with filters.",
"permlevel": 0
},
{ {
"fieldname": "column_break3", "fieldname": "column_break3",
"fieldtype": "Column Break", "fieldtype": "Column Break",
"label": "Filter By Amount", "label": "",
"permlevel": 0, "permlevel": 0,
"print_width": "50%", "print_width": "50%",
"width": "50%" "width": "50%"
}, },
{ {
"fieldname": "amt_greater_than", "fieldname": "amt_greater_than",
"fieldtype": "Data", "fieldtype": "Currency",
"label": "Amount >=", "label": "Amount >=",
"permlevel": 0 "permlevel": 0
}, },
{ {
"fieldname": "amt_less_than", "fieldname": "amt_less_than",
"fieldtype": "Data", "fieldtype": "Currency",
"label": "Amount <=", "label": "Amount <=",
"permlevel": 0 "permlevel": 0
},
{
"fieldname": "section_break0",
"fieldtype": "Section Break",
"options": "Simple",
"permlevel": 0
},
{
"fieldname": "get_against_entries",
"fieldtype": "Button",
"label": "Get Against Entries",
"options": "",
"permlevel": 0
},
{
"description": "Update allocated amount in the above table and then click \"Allocate\" button",
"fieldname": "against_entries",
"fieldtype": "Table",
"label": "Against Entries",
"options": "Payment to Invoice Matching Tool Detail",
"permlevel": 0
},
{
"fieldname": "sec_break1",
"fieldtype": "Section Break",
"options": "Simple",
"permlevel": 0
},
{
"fieldname": "total_allocated_amount",
"fieldtype": "Currency",
"label": "Total Allocated Amount",
"permlevel": 0,
"read_only": 1
},
{
"fieldname": "col_breal4",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"default": "",
"fieldname": "allocate_amount_automatically",
"fieldtype": "Button",
"hidden": 1,
"label": "Allocate Amount Automatically",
"permlevel": 0,
"reqd": 0
},
{
"fieldname": "reconcile",
"fieldtype": "Button",
"label": "Reconcile",
"options": "",
"permlevel": 0
} }
], ],
"hide_toolbar": 1, "hide_toolbar": 0,
"icon": "icon-magic", "icon": "icon-magic",
"idx": 1, "idx": 1,
"issingle": 1, "issingle": 1,
"modified": "2013-12-20 19:23:24.000000", "modified": "2014-04-30 17:11:05.908619",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Payment to Invoice Matching Tool", "name": "Payment to Invoice Matching Tool",

View File

@ -17,69 +17,99 @@ class PaymenttoInvoiceMatchingTool(Document):
where voucher_type = %s and voucher_no = %s where voucher_type = %s and voucher_no = %s
and account = %s""", (self.voucher_type, self.voucher_no, self.account)) and account = %s""", (self.voucher_type, self.voucher_no, self.account))
total_amount = total_amount and flt(total_amount[0][0]) or 0 self.total_amount = total_amount and flt(total_amount[0][0]) or 0
reconciled_payment = frappe.db.sql(""" reconciled_payment = frappe.db.sql("""
select abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))) from `tabGL Entry` where select abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)))
against_voucher = %s and voucher_no != %s from `tabGL Entry`
and account = %s""", (self.voucher_no, self.voucher_no, self.account)) where against_voucher = %s and account = %s
""", (self.voucher_no, self.account))
reconciled_payment = reconciled_payment and flt(reconciled_payment[0][0]) or 0 reconciled_payment = reconciled_payment and flt(reconciled_payment[0][0]) or 0
ret = { self.unmatched_amount = self.total_amount - reconciled_payment
'total_amount': total_amount,
'pending_amt_to_reconcile': total_amount - reconciled_payment
}
return ret def get_against_entries(self):
def get_payment_entries(self):
""" """
Get payment entries for the account and period Get payment entries for the account and period
Payment entry will be decided based on account type (Dr/Cr) Payment entry will be decided based on account type (Dr/Cr)
""" """
self.set('ir_payment_details', []) self.set('against_entries', [])
gle = self.get_gl_entries() gle = self.get_gl_entries()
self.create_payment_table(gle) self.create_against_entries_table(gle)
def get_gl_entries(self): def get_gl_entries(self):
self.validate_mandatory() self.validate_mandatory()
dr_or_cr = "credit" if self.total_amount > 0 else "debit"
cond = self.from_date and " and t1.posting_date >= '" + self.from_date + "'" or "" cond = self.from_date and " and t1.posting_date >= '" + self.from_date + "'" or ""
cond += self.to_date and " and t1.posting_date <= '" + self.to_date + "'"or "" cond += self.to_date and " and t1.posting_date <= '" + self.to_date + "'" or ""
if self.amt_greater_than: if self.amt_greater_than:
cond += ' and abs(ifnull(t2.debit, 0) - ifnull(t2.credit, 0)) >= ' + \ cond += ' and abs(ifnull(t2.debit, 0) - ifnull(t2.credit, 0)) >= ' + self.amt_greater_than
self.amt_greater_than
if self.amt_less_than: if self.amt_less_than:
cond += ' and abs(ifnull(t2.debit, 0) - ifnull(t2.credit, 0)) >= ' + \ cond += ' and abs(ifnull(t2.debit, 0) - ifnull(t2.credit, 0)) >= ' + self.amt_less_than
self.amt_less_than
gle = frappe.db.sql(""" gle = frappe.db.sql("""
select t1.name as voucher_no, t1.posting_date, t1.total_debit as total_amt, select
abs(sum(ifnull(t2.credit, 0)) - sum(ifnull(t2.debit, 0))) as amt_due, t1.remark, t1.name as voucher_no, t1.posting_date, t1.total_debit as total_amt,
t2.against_account, t2.name as voucher_detail_no abs(ifnull(t2.debit, 0) - ifnull(t2.credit, 0)) as unmatched_amount, t1.remark,
t2.against_account, t2.name as voucher_detail_no, t2.is_advance
from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2
where t1.name = t2.parent and t1.docstatus = 1 and t2.account = %s where t1.name = t2.parent and t1.docstatus = 1 and t2.account = %s
and ifnull(t2.against_voucher, '')='' and ifnull(t2.against_invoice, '')='' and ifnull(t2.against_voucher, '')='' and ifnull(t2.against_invoice, '')=''
and ifnull(t2.against_jv, '')='' and t1.name != %s %s group by t1.name, t2.name """ % and ifnull(t2.against_jv, '')='' and t2.%s > 0 and t1.name != %s
('%s', '%s', cond), (self.account, self.voucher_no), as_dict=1) and not exists (select * from `tabJournal Voucher Detail`
where parent=%s and against_jv = t1.name) %s
group by t1.name, t2.name """ %
('%s', dr_or_cr, '%s', '%s', cond), (self.account, self.voucher_no, self.voucher_no), as_dict=1)
return gle return gle
def create_payment_table(self, gle): def create_against_entries_table(self, gle):
adjusted_jv = {}
for d in gle: for d in gle:
ch = self.append('ir_payment_details', {}) if not adjusted_jv.has_key(d.get("voucher_no")):
matched_amount = frappe.db.sql("""
select
ifnull(abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))), 0)
from
`tabGL Entry`
where
account = %s and against_voucher_type = "Journal Voucher"
and ifnull(against_voucher, '') = %s
""", (self.account, d.get('voucher_no')))
matched_amount = matched_amount[0][0] if matched_amount else 0
else:
matched_amount = adjusted_jv.get(d.get("voucher_no"))
if matched_amount < flt(d.get('unmatched_amount')):
unmatched_amount = flt(d.get('unmatched_amount')) - matched_amount
adjusted_jv.setdefault(d.get("voucher_no"), 0)
else:
unmatched_amount = 0
adjusted_jv.setdefault(d.get("voucher_no"), matched_amount - flt(d.get('unmatched_amount')))
if unmatched_amount:
ch = self.append('against_entries', {})
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 = flt(d.get('amt_due')) ch.unmatched_amount = unmatched_amount
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')
ch.is_advance = d.get("is_advance")
ch.original_amount = flt(d.get('unmatched_amount'))
def validate_mandatory(self): def validate_mandatory(self):
if not self.account: for fieldname in ["account", "voucher_type", "voucher_no"]:
msgprint(_("Please select Account first"), raise_exception=1) if not self.get(fieldname):
frappe.throw(_("Please select {0} first").format(self.meta.get_label("fieldname")))
if not frappe.db.exists(self.voucher_type, self.voucher_no):
frappe.throw(_("Voucher No is not valid"))
def reconcile(self): def reconcile(self):
""" """
@ -88,23 +118,26 @@ class PaymenttoInvoiceMatchingTool(Document):
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.voucher_no or not frappe.db.sql("""select name from `tab%s` self.validate_mandatory()
where name = %s""" % (self.voucher_type, '%s'), self.voucher_no):
frappe.throw(_("Please select valid Voucher No to proceed")) if not self.total_allocated_amount:
frappe.throw(_("You must allocate amount before reconcile"))
dr_or_cr = "credit" if self.total_amount > 0 else "debit"
lst = [] lst = []
for d in self.get('ir_payment_details'): for d in self.get('against_entries'):
if flt(d.amt_to_be_reconciled) > 0: if flt(d.allocated_amount) > 0:
args = { args = {
'voucher_no' : d.voucher_no, 'voucher_no' : d.voucher_no,
'voucher_detail_no' : d.voucher_detail_no, 'voucher_detail_no' : d.voucher_detail_no,
'against_voucher_type' : self.voucher_type, 'against_voucher_type' : self.voucher_type,
'against_voucher' : self.voucher_no, 'against_voucher' : self.voucher_no,
'account' : self.account, 'account' : self.account,
'is_advance' : 'No', 'is_advance' : d.is_advance,
# 'dr_or_cr' : self.account_type=='debit' and 'credit' or 'debit', 'dr_or_cr' : dr_or_cr,
'unadjusted_amt' : flt(d.amt_due), 'unadjusted_amt' : flt(d.original_amount),
'allocated_amt' : flt(d.amt_to_be_reconciled) 'allocated_amt' : flt(d.allocated_amount)
} }
lst.append(args) lst.append(args)
@ -112,35 +145,34 @@ class PaymenttoInvoiceMatchingTool(Document):
if lst: if lst:
from erpnext.accounts.utils import reconcile_against_document from erpnext.accounts.utils import reconcile_against_document
reconcile_against_document(lst) reconcile_against_document(lst)
self.get_against_entries()
msgprint(_("Successfully allocated")) msgprint(_("Successfully allocated"))
else:
msgprint(_("No amount allocated"), raise_exception=1)
def gl_entry_details(doctype, txt, searchfield, start, page_len, filters): def get_voucher_nos(doctype, txt, searchfield, start, page_len, filters):
from erpnext.controllers.queries import get_match_cond non_reconclied_entries = []
return frappe.db.sql("""select gle.voucher_no, gle.posting_date, entries = frappe.db.sql("""
gle.debit, gle.credit from `tabGL Entry` gle select
where gle.account = '%(acc)s' voucher_no, posting_date, ifnull(abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))), 0) as amount
and gle.voucher_type = '%(dt)s' from
and gle.voucher_no like '%(txt)s' `tabGL Entry`
and (ifnull(gle.against_voucher, '') = '' where
or ifnull(gle.against_voucher, '') = gle.voucher_no ) account = %s and voucher_type = %s and voucher_no like %s
and (select ifnull(abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))), 0) and ifnull(against_voucher, '') = ''
from `tabGL Entry` group by voucher_no
where account = '%(acc)s' """, (filters["account"], filters["voucher_type"], "%%%s%%" % txt), as_dict=True)
and against_voucher_type = '%(dt)s'
and against_voucher = gle.voucher_no for d in entries:
and voucher_no != gle.voucher_no) adjusted_amount = frappe.db.sql("""
!= abs(ifnull(gle.debit, 0) - ifnull(gle.credit, 0)) select
and if(gle.voucher_type='Sales Invoice', ifnull((select is_pos from `tabSales Invoice` ifnull(abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))), 0)
where name=gle.voucher_no), 0), 0)=0 from
%(mcond)s `tabGL Entry`
ORDER BY gle.posting_date desc, gle.voucher_no desc where
limit %(start)s, %(page_len)s""" % { account = %s and against_voucher_type = %s and ifnull(against_voucher, '') = %s
"dt":filters["dt"], """, (filters["account"], filters["voucher_type"], d.voucher_no))
"acc":filters["acc"], adjusted_amount = adjusted_amount[0][0] if adjusted_amount else 0
'mcond':get_match_cond(doctype),
'txt': "%%%s%%" % txt, if adjusted_amount != d.amount:
"start": start, non_reconclied_entries.append([d.voucher_no, d.posting_date, d.amount])
"page_len": page_len
}) return non_reconclied_entries

View File

@ -1,5 +1,5 @@
{ {
"creation": "2013-02-22 01:27:39.000000", "creation": "2013-02-22 01:27:39",
"docstatus": 0, "docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"fields": [ "fields": [
@ -16,7 +16,7 @@
"width": "140px" "width": "140px"
}, },
{ {
"fieldname": "amt_due", "fieldname": "unmatched_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"in_list_view": 1, "in_list_view": 1,
"label": "Unmatched Amount", "label": "Unmatched Amount",
@ -25,7 +25,7 @@
"read_only": 1 "read_only": 1
}, },
{ {
"fieldname": "amt_to_be_reconciled", "fieldname": "allocated_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"in_list_view": 1, "in_list_view": 1,
"label": "Allocated Amount", "label": "Allocated Amount",
@ -33,6 +33,11 @@
"permlevel": 0, "permlevel": 0,
"reqd": 1 "reqd": 1
}, },
{
"fieldname": "col_break1",
"fieldtype": "Column Break",
"permlevel": 0
},
{ {
"fieldname": "posting_date", "fieldname": "posting_date",
"fieldtype": "Date", "fieldtype": "Date",
@ -76,13 +81,30 @@
"print_hide": 1, "print_hide": 1,
"read_only": 1, "read_only": 1,
"reqd": 0 "reqd": 0
},
{
"fieldname": "is_advance",
"fieldtype": "Data",
"hidden": 1,
"label": "Is Advance",
"permlevel": 0,
"read_only": 1
},
{
"fieldname": "original_amount",
"fieldtype": "Currency",
"hidden": 1,
"label": "Original Amount",
"permlevel": 0
} }
], ],
"hide_toolbar": 1,
"idx": 1, "idx": 1,
"istable": 1, "istable": 1,
"modified": "2013-12-20 19:23:24.000000", "modified": "2014-04-30 19:27:15.993641",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Payment to Invoice Matching Tool Detail", "name": "Payment to Invoice Matching Tool Detail",
"owner": "Administrator" "owner": "Administrator",
"permissions": []
} }

View File

@ -125,7 +125,7 @@ def reconcile_against_document(args):
""" """
for d in args: for d in args:
check_if_jv_modified(d) check_if_jv_modified(d)
validate_allocated_amount(d)
against_fld = { against_fld = {
'Journal Voucher' : 'against_jv', 'Journal Voucher' : 'against_jv',
'Sales Invoice' : 'against_invoice', 'Sales Invoice' : 'against_invoice',
@ -159,11 +159,17 @@ def check_if_jv_modified(args):
and ifnull(t2.against_voucher, '')='' and ifnull(t2.against_voucher, '')=''
and ifnull(t2.against_invoice, '')='' and ifnull(t2.against_jv, '')='' and ifnull(t2.against_invoice, '')='' and ifnull(t2.against_jv, '')=''
and t1.name = '%(voucher_no)s' and t2.name = '%(voucher_detail_no)s' and t1.name = '%(voucher_no)s' and t2.name = '%(voucher_detail_no)s'
and t1.docstatus=1 and t2.%(dr_or_cr)s = %(unadjusted_amt)s""" % args) and t1.docstatus=1 """ % args)
if not ret: if not ret:
throw(_("""Payment Entry has been modified after you pulled it. Please pull it again.""")) throw(_("""Payment Entry has been modified after you pulled it. Please pull it again."""))
def validate_allocated_amount(args):
if args.get("allocated_amt") < 0:
throw(_("Allocated amount can not be negative"))
elif args.get("allocated_amt") > args.get("unadjusted_amt"):
throw(_("Allocated amount can not greater than unadusted amount"))
def update_against_doc(d, jv_obj): def update_against_doc(d, jv_obj):
""" """
Updates against document, if partial amount splits into rows Updates against document, if partial amount splits into rows

View File

@ -35,3 +35,4 @@ erpnext.patches.4_0.countrywise_coa
execute:frappe.delete_doc("DocType", "MIS Control") execute:frappe.delete_doc("DocType", "MIS Control")
execute:frappe.delete_doc("Page", "Financial Statements") execute:frappe.delete_doc("Page", "Financial Statements")
execute:frappe.delete_doc("DocType", "Stock Ledger") execute:frappe.delete_doc("DocType", "Stock Ledger")
execute:frappe.db.sql("update `tabJournal Voucher` set voucher_type='Journal Entry' where ifnull(voucher_type, '')=''")