mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-01 12:38:27 +00:00
Bank reconciliation WIP
This commit is contained in:
@@ -2,7 +2,13 @@
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Bank Transaction', {
|
||||
refresh: function(frm) {
|
||||
|
||||
onload: function(frm) {
|
||||
frm.set_query('payment_document', 'payment_entries', function(doc, cdt, cdn) {
|
||||
return {
|
||||
"filters": {
|
||||
"name": ["in", ["Payment Entry", "Journal Entry", "Sales Invoice", "Purchase Invoice"]]
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -78,7 +78,6 @@ erpnext.accounts.bankReconciliation = class BankReconciliation {
|
||||
|
||||
make_reconciliation_tool() {
|
||||
const me = this;
|
||||
console.log(me)
|
||||
frappe.model.with_doctype("Bank Transaction", () => {
|
||||
new erpnext.accounts.ReconciliationTool({
|
||||
parent: me.parent,
|
||||
@@ -116,7 +115,6 @@ erpnext.accounts.bankTransactionUpload = class bankTransactionUpload {
|
||||
no_socketio: true,
|
||||
sample_url: "e.g. http://example.com/somefile.csv",
|
||||
callback: function(attachment, r) {
|
||||
console.log(r)
|
||||
if (!r.exc && r.message) {
|
||||
me.data = r.message;
|
||||
me.setup_transactions_dom();
|
||||
@@ -432,16 +430,23 @@ erpnext.accounts.ReconciliationRow = class ReconciliationRow {
|
||||
|
||||
show_dialog(data) {
|
||||
const me = this;
|
||||
|
||||
frappe.db.get_value("Bank Account", me.data.bank_account, "account", (r) => {
|
||||
me.gl_account = r.account;
|
||||
})
|
||||
|
||||
frappe.xcall('erpnext.accounts.page.bank_reconciliation.bank_reconciliation.get_linked_payments',
|
||||
{bank_transaction: data}
|
||||
)
|
||||
.then((result) => {
|
||||
{bank_transaction: data, freeze:true, freeze_message:__("Finding linked payments")}
|
||||
).then((result) => {
|
||||
console.log(result)
|
||||
me.make_dialog(result)
|
||||
})
|
||||
}
|
||||
|
||||
make_dialog(data) {
|
||||
const me = this;
|
||||
me.selected_payment = null;
|
||||
|
||||
const fields = [
|
||||
{
|
||||
fieldtype: 'Section Break',
|
||||
@@ -459,18 +464,59 @@ erpnext.accounts.ReconciliationRow = class ReconciliationRow {
|
||||
},
|
||||
{
|
||||
fieldtype: 'Link',
|
||||
fieldname: 'payment_entry',
|
||||
options: 'Payment Entry',
|
||||
label: 'Payment Entry',
|
||||
fieldname: 'payment_doctype',
|
||||
options: 'DocType',
|
||||
label: 'Payment DocType',
|
||||
get_query: () => {
|
||||
return {
|
||||
filters : [
|
||||
["Payment Entry", "ifnull(clearance_date, '')", "=", ""],
|
||||
["Payment Entry", "docstatus", "=", 1]
|
||||
]
|
||||
filters : {
|
||||
"name": ["in", ["Payment Entry", "Journal Entry", "Sales Invoice"]]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
fieldtype: 'Column Break',
|
||||
fieldname: 'column_break_1',
|
||||
},
|
||||
{
|
||||
fieldtype: 'Dynamic Link',
|
||||
fieldname: 'payment_entry',
|
||||
options: 'payment_doctype',
|
||||
label: 'Payment Document',
|
||||
get_query: () => {
|
||||
let dt = this.dialog.fields_dict.payment_doctype.value;
|
||||
if (dt === "Payment Entry") {
|
||||
return {
|
||||
filters : [
|
||||
["Payment Entry", "ifnull(clearance_date, '')", "=", ""],
|
||||
["Payment Entry", "docstatus", "=", 1]
|
||||
]
|
||||
}
|
||||
} else if (dt === "Journal Entry") {
|
||||
return {
|
||||
query: "erpnext.accounts.page.bank_reconciliation.bank_reconciliation.journal_entry_query",
|
||||
filters : {
|
||||
"bank_account": this.data.bank_account
|
||||
}
|
||||
}
|
||||
} else if (dt === "Sales Invoice") {
|
||||
return {
|
||||
query: "erpnext.accounts.page.bank_reconciliation.bank_reconciliation.sales_invoices_query"
|
||||
}
|
||||
}
|
||||
},
|
||||
onchange: function() {
|
||||
if (me.selected_payment !== this.value) {
|
||||
me.selected_payment = this.value;
|
||||
me.display_payment_details(this);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
fieldtype: 'Section Break',
|
||||
fieldname: 'section_break_3'
|
||||
},
|
||||
{
|
||||
fieldtype: 'HTML',
|
||||
fieldname: 'payment_details'
|
||||
@@ -479,11 +525,12 @@ erpnext.accounts.ReconciliationRow = class ReconciliationRow {
|
||||
|
||||
me.dialog = new frappe.ui.Dialog({
|
||||
title: __("Choose a corresponding payment"),
|
||||
fields: fields
|
||||
fields: fields,
|
||||
size: "large"
|
||||
});
|
||||
|
||||
const proposals_wrapper = me.dialog.fields_dict.payment_proposals.$wrapper;
|
||||
if (data.length > 0) {
|
||||
if (data && data.length > 0) {
|
||||
data.map(value => {
|
||||
proposals_wrapper.append(frappe.render_template("linked_payment_row", value))
|
||||
})
|
||||
@@ -494,26 +541,62 @@ erpnext.accounts.ReconciliationRow = class ReconciliationRow {
|
||||
|
||||
$(me.dialog.body).on('click', '.reconciliation-btn', (e) => {
|
||||
const payment_entry = $(e.target).attr('data-name');
|
||||
const payment_doctype = $(e.target).attr('data-doctype');
|
||||
frappe.xcall('erpnext.accounts.page.bank_reconciliation.bank_reconciliation.reconcile',
|
||||
{bank_transaction: me.bank_entry, payment_entry: payment_entry})
|
||||
{bank_transaction: me.bank_entry, payment_doctype: payment_doctype, payment_entry: payment_entry})
|
||||
.then((result) => {
|
||||
erpnext.accounts.ReconciliationTool.trigger_list_update();
|
||||
me.dialog.hide();
|
||||
})
|
||||
})
|
||||
|
||||
$(me.dialog.body).on('blur', '.input-with-feedback', (e) => {
|
||||
if (e.target.value) {
|
||||
e.preventDefault();
|
||||
me.dialog.fields_dict['payment_details'].$wrapper.empty();
|
||||
frappe.db.get_doc("Payment Entry", e.target.value)
|
||||
.then(doc => {
|
||||
const details_wrapper = me.dialog.fields_dict.payment_details.$wrapper;
|
||||
details_wrapper.append(frappe.render_template("linked_payment_row", doc));
|
||||
})
|
||||
}
|
||||
|
||||
});
|
||||
me.dialog.show();
|
||||
}
|
||||
|
||||
display_payment_details(event) {
|
||||
const me = this;
|
||||
if (event.value) {
|
||||
let dt = me.dialog.fields_dict.payment_doctype.value;
|
||||
me.dialog.fields_dict['payment_details'].$wrapper.empty();
|
||||
frappe.db.get_doc(dt, event.value)
|
||||
.then(doc => {
|
||||
let displayed_docs = []
|
||||
if (dt === "Payment Entry") {
|
||||
doc.currency = doc.payment_type == "Receive" ? doc.paid_to_account_currency : doc.paid_from_account_currency;
|
||||
displayed_docs.push(doc);
|
||||
} else if (dt === "Journal Entry") {
|
||||
doc.accounts.forEach(payment => {
|
||||
if (payment.account === me.gl_account) {
|
||||
payment.posting_date = doc.posting_date;
|
||||
payment.party = doc.pay_to_recd_from;
|
||||
payment.reference_no = doc.cheque_no;
|
||||
payment.reference_date = doc.cheque_date;
|
||||
payment.currency = payment.account_currency;
|
||||
payment.paid_amount = payment.credit > 0 ? payment.credit : payment.debit;
|
||||
payment.name = doc.name;
|
||||
displayed_docs.push(payment);
|
||||
}
|
||||
})
|
||||
} else if (dt === "Sales Invoice") {
|
||||
doc.payments.forEach(payment => {
|
||||
if (payment.clearance_date === null || payment.clearance_date === "") {
|
||||
payment.posting_date = doc.posting_date;
|
||||
payment.party = doc.customer;
|
||||
payment.reference_no = doc.remarks;
|
||||
payment.currency = doc.currency;
|
||||
payment.paid_amount = payment.amount;
|
||||
payment.name = doc.name;
|
||||
displayed_docs.push(payment);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const details_wrapper = me.dialog.fields_dict.payment_details.$wrapper;
|
||||
displayed_docs.forEach(values => {
|
||||
details_wrapper.append(frappe.render_template("linked_payment_row", values));
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -8,76 +8,125 @@ from frappe import _
|
||||
import difflib
|
||||
from operator import itemgetter
|
||||
from frappe.utils import flt
|
||||
from six import iteritems
|
||||
|
||||
@frappe.whitelist()
|
||||
def reconcile(bank_transaction, payment_entry):
|
||||
def reconcile(bank_transaction, payment_doctype, payment_entry):
|
||||
transaction = frappe.get_doc("Bank Transaction", bank_transaction)
|
||||
payment_entry = frappe.get_doc("Payment Entry", payment_entry)
|
||||
payment_entry = frappe.get_doc(payment_doctype, payment_entry)
|
||||
|
||||
if transaction.payment_entry:
|
||||
frappe.throw(_("This bank transaction is already linked to a payment entry"))
|
||||
if transaction.unallocated_amount == 0:
|
||||
frappe.throw(_("This bank transaction is already fully reconciled"))
|
||||
|
||||
"""
|
||||
if transaction.credit > 0 and payment_entry.payment_type == "Pay":
|
||||
frappe.throw(_("The selected payment entry should be linked with a debitor bank transaction"))
|
||||
|
||||
if transaction.debit > 0 and payment_entry.payment_type == "Receive":
|
||||
frappe.throw(_("The selected payment entry should be linked with a creditor bank transaction"))
|
||||
"""
|
||||
|
||||
add_payment_to_transaction(transaction, payment_entry)
|
||||
clear_payment_entry(transaction, payment_entry)
|
||||
add_payment_to_transaction(transaction, payment_doctype, payment_entry)
|
||||
#clear_payment_entry(transaction, payment_doctype, payment_entry)
|
||||
|
||||
return 'reconciled'
|
||||
|
||||
def add_payment_to_transaction(transaction, payment_entry):
|
||||
transaction.append("payment_entries", {"payment_entry": payment_entry.name})
|
||||
def add_payment_to_transaction(transaction, payment_doctype, payment_entry):
|
||||
transaction.append("payment_entries", {"payment_document": payment_doctype, "payment_entry": payment_entry.name})
|
||||
transaction.save()
|
||||
|
||||
def clear_payment_entry(transaction, payment_entry):
|
||||
linked_bank_transactions = frappe.get_all("Bank Transaction", filters={"payment_entry": payment_entry, "docstatus": 1},
|
||||
def clear_payment_entry(transaction, payment_doctype, payment_entry):
|
||||
pass
|
||||
"""
|
||||
linked_bank_transactions = frappe.get_all("Bank Transaction Payments", filters={"payment_entry": payment_entry, "docstatus": 1},
|
||||
fields=["sum(debit) as debit", "sum(credit) as credit"])
|
||||
|
||||
cleared_amount = (flt(linked_bank_transactions[0].credit) - flt(linked_bank_transactions[0].debit))
|
||||
|
||||
if cleared_amount == payment_entry.paid_amount:
|
||||
frappe.db.set_value("Payment Entry", payment_entry.name, "clearance_date", transaction.date)
|
||||
frappe.db.set_value(payment_doctype, payment_entry.name, "clearance_date", transaction.date)
|
||||
"""
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_linked_payments(bank_transaction):
|
||||
|
||||
transaction = frappe.get_doc("Bank Transaction", bank_transaction)
|
||||
bank_account = frappe.db.get_value("Bank Account", transaction.bank_account, "account")
|
||||
|
||||
# Get all payment entries with a matching amount
|
||||
amount_matching = check_matching_amount(transaction)
|
||||
amount_matching = check_matching_amount(bank_account, transaction)
|
||||
print(amount_matching)
|
||||
|
||||
# Get some data from payment entries linked to a corresponding bank transaction
|
||||
description_matching = check_matching_descriptions(transaction)
|
||||
description_matching = get_matching_descriptions_data(bank_account, transaction)
|
||||
print(description_matching)
|
||||
|
||||
"""
|
||||
if amount_matching:
|
||||
match = check_amount_vs_description(amount_matching, description_matching)
|
||||
if match:
|
||||
return match
|
||||
else:
|
||||
return merge_matching_lists(amount_matching, description_matching)
|
||||
return check_amount_vs_description(amount_matching, description_matching)
|
||||
|
||||
else:
|
||||
linked_payments = get_matching_transactions_payments(description_matching)
|
||||
return linked_payments
|
||||
"""
|
||||
print("else")
|
||||
#linked_payments = get_matching_transactions_payments(description_matching)
|
||||
#return linked_payments
|
||||
|
||||
def check_matching_amount(transaction):
|
||||
def check_matching_amount(bank_account, transaction):
|
||||
payments = []
|
||||
amount = transaction.credit if transaction.credit > 0 else transaction.debit
|
||||
payment_type = "Receive" if transaction.credit > 0 else "Pay"
|
||||
|
||||
payments = frappe.get_all("Payment Entry", fields=["name", "paid_amount", "payment_type", "reference_no", "reference_date",
|
||||
"party", "party_type", "posting_date", "paid_to_account_currency"], filters=[["paid_amount", "like", "{0}%".format(amount)],
|
||||
["docstatus", "=", "1"], ["payment_type", "=", payment_type], ["ifnull(clearance_date, '')", "=", ""]])
|
||||
payment_type = "Receive" if transaction.credit > 0 else "Pay"
|
||||
account_from_to = "paid_to" if transaction.credit > 0 else "paid_from"
|
||||
currency_field = "paid_to_account_currency as currency" if transaction.credit > 0 else "paid_from_account_currency as currency"
|
||||
payment_entries = frappe.get_all("Payment Entry", fields=["'Payment Entry' as doctype", "name", "paid_amount", "payment_type", "reference_no", "reference_date",
|
||||
"party", "party_type", "posting_date", "{0}".format(currency_field)], filters=[["paid_amount", "like", "{0}%".format(amount)],
|
||||
["docstatus", "=", "1"], ["payment_type", "=", payment_type], ["ifnull(clearance_date, '')", "=", ""], ["{0}".format(account_from_to), "=", "{0}".format(bank_account)]])
|
||||
|
||||
payment_field = "jea.debit_in_account_currency" if transaction.credit > 0 else "jea.credit_in_account_currency"
|
||||
journal_entries = frappe.db.sql("""
|
||||
SELECT
|
||||
'Journal Entry' as doctype, je.name, je.posting_date, je.cheque_no as reference_no,
|
||||
je.pay_to_recd_from as party, je.cheque_date as reference_date, %s as paid_amount
|
||||
FROM
|
||||
`tabJournal Entry Account` as jea
|
||||
JOIN
|
||||
`tabJournal Entry` as je
|
||||
ON
|
||||
jea.parent = je.name
|
||||
WHERE
|
||||
(je.clearance_date is null or je.clearance_date='0000-00-00')
|
||||
AND
|
||||
jea.account = '%s'
|
||||
AND
|
||||
%s like '%s'
|
||||
AND
|
||||
je.docstatus = 1
|
||||
""" % (payment_field, bank_account, payment_field, amount), as_dict=True)
|
||||
|
||||
sales_invoices = frappe.db.sql("""
|
||||
SELECT
|
||||
'Sales Invoice' as doctype, si.name, si.customer as party,
|
||||
si.posting_date, sip.amount as paid_amount
|
||||
FROM
|
||||
`tabSales Invoice Payment` as sip
|
||||
JOIN
|
||||
`tabSales Invoice` as si
|
||||
ON
|
||||
sip.parent = si.name
|
||||
WHERE
|
||||
(sip.clearance_date is null or sip.clearance_date='0000-00-00')
|
||||
AND
|
||||
sip.account = '%s'
|
||||
AND
|
||||
sip.amount like '%s'
|
||||
AND
|
||||
si.docstatus = 1
|
||||
""" % (bank_account, amount), as_dict=True)
|
||||
|
||||
for data in [payment_entries, journal_entries, sales_invoices]:
|
||||
if data:
|
||||
payments.extend(data)
|
||||
|
||||
return payments
|
||||
|
||||
def check_matching_descriptions(transaction):
|
||||
def get_matching_descriptions_data(bank_account, transaction):
|
||||
bank_transactions = frappe.db.sql("""
|
||||
SELECT
|
||||
bt.name, bt.description, bt.date, btp.payment_document, btp.payment_entry
|
||||
@@ -104,33 +153,42 @@ def check_matching_descriptions(transaction):
|
||||
|
||||
document_types = set([x["payment_document"] for x in selection])
|
||||
|
||||
links = {}
|
||||
for document_type in document_types:
|
||||
print(document_type)
|
||||
links[document_type] = [x["payment_entry"] for x in selection if x["payment_document"]==document_type]
|
||||
|
||||
|
||||
return selection
|
||||
data = []
|
||||
for key, value in iteritems(links):
|
||||
if key == "Payment Entry":
|
||||
data.extend(frappe.get_all("Payment Entry", filters=[["name", "in", value]], fields=["'Payment Entry' as doctype", "posting_date", "party", "reference_no", "reference_date", "paid_amount"]))
|
||||
if key == "Journal Entry":
|
||||
data.extend(frappe.get_all("Journal Entry", filters=[["name", "in", value]], fields=["'Journal Entry' as doctype", "posting_date", "paid_to_recd_from as party", "cheque_no as reference_no", "cheque_date as reference_date"]))
|
||||
if key == "Sales Invoice":
|
||||
data.extend(frappe.get_all("Sales Invoice", filters=[["name", "in", value]], fields=["'Sales Invoice' as doctype", "posting_date", "customer as party"]))
|
||||
#if key == "Purchase Invoice":
|
||||
# data.append(frappe.get_all("Purchase Invoice", filters=[["name", "in", value]], fields=["posting_date", "customer as party"]))
|
||||
|
||||
return data
|
||||
|
||||
def check_amount_vs_description(amount_matching, description_matching):
|
||||
result = []
|
||||
print(description_matching)
|
||||
print(amount_matching)
|
||||
for match in amount_matching:
|
||||
m = [match for x in description_matching.payment_entries if match["name"]==x["payment_entry"]]
|
||||
result.append(m)
|
||||
print(result)
|
||||
return result
|
||||
|
||||
def merge_matching_lists(amount_matching, description_matching):
|
||||
|
||||
for match in amount_matching:
|
||||
if match["name"] in map(itemgetter('payment_entry'), description_matching):
|
||||
index = map(itemgetter('payment_entry'), description_matching).index(match["name"])
|
||||
del description_matching[index]
|
||||
if description_matching:
|
||||
for am_match in amount_matching:
|
||||
for des_match in description_matching:
|
||||
if am_match["party"] == des_match["party"]:
|
||||
result.append(am_match)
|
||||
continue
|
||||
|
||||
linked_payments = get_matching_transactions_payments(description_matching)
|
||||
if hasattr(am_match, "reference_no") and hasattr(des_match, "reference_no"):
|
||||
if difflib.SequenceMatcher(lambda x: x == " ", am_match["reference_no"], des_match["reference_no"]) > 70:
|
||||
result.append(am_match)
|
||||
|
||||
result = amount_matching.append(linked_payments)
|
||||
return sorted(result, key = lambda x: x["posting_date"], reverse=True)
|
||||
return sorted(result, key = lambda x: x["posting_date"], reverse=True)
|
||||
|
||||
else:
|
||||
return sorted(amount_matching, key = lambda x: x["posting_date"], reverse=True)
|
||||
|
||||
def get_matching_transactions_payments(description_matching):
|
||||
payments = [x["payment_entry"] for x in description_matching]
|
||||
@@ -144,4 +202,68 @@ def get_matching_transactions_payments(description_matching):
|
||||
return sorted(reference_payment_list, key=lambda x: payment_by_ratio[x["name"]])
|
||||
|
||||
else:
|
||||
return []
|
||||
return []
|
||||
|
||||
def journal_entry_query(doctype, txt, searchfield, start, page_len, filters):
|
||||
account = frappe.db.get_value("Bank Account", filters.get("bank_account"), "account")
|
||||
|
||||
return frappe.db.sql("""
|
||||
SELECT
|
||||
jea.parent, je.pay_to_recd_from,
|
||||
if(jea.debit_in_account_currency > 0, jea.debit_in_account_currency, jea.credit_in_account_currency)
|
||||
FROM
|
||||
`tabJournal Entry Account` as jea
|
||||
LEFT JOIN
|
||||
`tabJournal Entry` as je
|
||||
ON
|
||||
jea.parent = je.name
|
||||
WHERE
|
||||
(je.clearance_date is null or je.clearance_date='0000-00-00')
|
||||
AND
|
||||
jea.account = %(account)s
|
||||
AND
|
||||
jea.parent like %(txt)s
|
||||
AND
|
||||
je.docstatus = 1
|
||||
ORDER BY
|
||||
if(locate(%(_txt)s, jea.parent), locate(%(_txt)s, jea.parent), 99999),
|
||||
jea.parent
|
||||
LIMIT
|
||||
%(start)s, %(page_len)s""".format(**{
|
||||
'key': searchfield,
|
||||
}), {
|
||||
'txt': "%%%s%%" % txt,
|
||||
'_txt': txt.replace("%", ""),
|
||||
'start': start,
|
||||
'page_len': page_len,
|
||||
'account': account
|
||||
}
|
||||
)
|
||||
|
||||
def sales_invoices_query(doctype, txt, searchfield, start, page_len, filters):
|
||||
return frappe.db.sql("""
|
||||
SELECT
|
||||
sip.parent, si.customer, sip.amount, sip.mode_of_payment
|
||||
FROM
|
||||
`tabSales Invoice Payment` as sip
|
||||
LEFT JOIN
|
||||
`tabSales Invoice` as si
|
||||
ON
|
||||
sip.parent = si.name
|
||||
WHERE
|
||||
(sip.clearance_date is null or sip.clearance_date='0000-00-00')
|
||||
AND
|
||||
sip.parent like %(txt)s
|
||||
ORDER BY
|
||||
if(locate(%(_txt)s, sip.parent), locate(%(_txt)s, sip.parent), 99999),
|
||||
sip.parent
|
||||
LIMIT
|
||||
%(start)s, %(page_len)s""".format(**{
|
||||
'key': searchfield,
|
||||
}), {
|
||||
'txt': "%%%s%%" % txt,
|
||||
'_txt': txt.replace("%", ""),
|
||||
'start': start,
|
||||
'page_len': page_len
|
||||
}
|
||||
)
|
||||
@@ -23,6 +23,8 @@
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu reports-dropdown" style="max-height: 300px; overflow-y: auto; right: 0px; left: auto;">
|
||||
<li><a class="new-reconciliation" data-name={{ name }}>{{ __("Reconcile") }}</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a class="new-payment" data-name={{ name }}>{{ __("New Payment") }}</a></li>
|
||||
<li><a class="new-invoice" data-name={{ name }}>{{ __("New Invoice") }}</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -4,16 +4,22 @@
|
||||
<label class="control-label">{{ name }}</label>
|
||||
</div>
|
||||
<div class="col-xs-5 ellipsis hidden-xs">
|
||||
<h4>{{ __("Date:") }}</h4><h6> {{ posting_date }}</h6>
|
||||
<h4>{{ __("Reference Date:") }}</h4><h6>{{ reference_date }}</h6>
|
||||
<h4>{{ __("Date") }}</h4><h6> {%= frappe.datetime.str_to_user(posting_date) %}</h6>
|
||||
{% if (typeof reference_date !== "undefined") %}
|
||||
<h4>{{ __("Reference Date") }}</h4><h6>{%= frappe.datetime.str_to_user(reference_date) %}</h6>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-xs-7 ellipsis list-subject">
|
||||
<h4>{{ __("Amount:") }}</h4><h6>{{ format_currency(paid_amount, paid_to_account_currency) }}</h6>
|
||||
<h4>{{ __("Party:") }}</h4><h6>{{ party }}</h6>
|
||||
<h4>{{ __("Reference:") }}</h4><h6>{{ reference_no }}</h6>
|
||||
<h4>{{ __("Amount") }}</h4><h6>{{ format_currency(paid_amount, currency) }}</h6>
|
||||
{% if (typeof party !== "undefined") %}
|
||||
<h4>{{ __("Party") }}</h4><h6>{{ party }}</h6>
|
||||
{% endif %}
|
||||
{% if (typeof reference_no !== "undefined") %}
|
||||
<h4>{{ __("Reference") }}</h4><h6>{{ reference_no }}</h6>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="text-right margin-bottom">
|
||||
<button class="btn btn-primary btn-xs reconciliation-btn" data-name={{ name }}>{{ __("Reconcile") }}</button>
|
||||
<button class="btn btn-primary btn-xs reconciliation-btn" data-doctype={{ doctype }} data-name={{ name }}>{{ __("Reconcile") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user