mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-01 11:19:09 +00:00
fix: Hotfix conflict resolved
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on('Bank Transaction', {
|
frappe.ui.form.on('Bank Transaction', {
|
||||||
onload: function(frm) {
|
onload(frm) {
|
||||||
frm.set_query('payment_document', 'payment_entries', function() {
|
frm.set_query('payment_document', 'payment_entries', function() {
|
||||||
return {
|
return {
|
||||||
"filters": {
|
"filters": {
|
||||||
@@ -12,3 +12,21 @@ frappe.ui.form.on('Bank Transaction', {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frappe.ui.form.on('Bank Transaction Payments', {
|
||||||
|
payment_entries_remove: function(frm, cdt, cdn) {
|
||||||
|
update_clearance_date(frm, cdt, cdn);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const update_clearance_date = (frm, cdt, cdn) => {
|
||||||
|
if (frm.doc.docstatus === 1) {
|
||||||
|
frappe.xcall('erpnext.accounts.doctype.bank_transaction.bank_transaction.unclear_reference_payment',
|
||||||
|
{doctype: cdt, docname: cdn})
|
||||||
|
.then(e => {
|
||||||
|
if (e == "success") {
|
||||||
|
frappe.show_alert({message:__("Document {0} successfully uncleared", [e]), indicator:'green'});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,19 +1,32 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.model.document import Document
|
from erpnext.controllers.status_updater import StatusUpdater
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
from six.moves import reduce
|
from six.moves import reduce
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
class BankTransaction(Document):
|
class BankTransaction(StatusUpdater):
|
||||||
def after_insert(self):
|
def after_insert(self):
|
||||||
self.unallocated_amount = abs(flt(self.credit) - flt(self.debit))
|
self.unallocated_amount = abs(flt(self.credit) - flt(self.debit))
|
||||||
|
|
||||||
|
def on_submit(self):
|
||||||
|
self.clear_linked_payment_entries()
|
||||||
|
self.set_status()
|
||||||
|
|
||||||
def on_update_after_submit(self):
|
def on_update_after_submit(self):
|
||||||
allocated_amount = reduce(lambda x, y: flt(x) + flt(y), [x.allocated_amount for x in self.payment_entries])
|
self.update_allocations()
|
||||||
|
self.clear_linked_payment_entries()
|
||||||
|
self.set_status(update=True)
|
||||||
|
|
||||||
|
def update_allocations(self):
|
||||||
|
if self.payment_entries:
|
||||||
|
allocated_amount = reduce(lambda x, y: flt(x) + flt(y), [x.allocated_amount for x in self.payment_entries])
|
||||||
|
else:
|
||||||
|
allocated_amount = 0
|
||||||
|
|
||||||
if allocated_amount:
|
if allocated_amount:
|
||||||
frappe.db.set_value(self.doctype, self.name, "allocated_amount", flt(allocated_amount))
|
frappe.db.set_value(self.doctype, self.name, "allocated_amount", flt(allocated_amount))
|
||||||
@@ -23,4 +36,69 @@ class BankTransaction(Document):
|
|||||||
frappe.db.set_value(self.doctype, self.name, "allocated_amount", 0)
|
frappe.db.set_value(self.doctype, self.name, "allocated_amount", 0)
|
||||||
frappe.db.set_value(self.doctype, self.name, "unallocated_amount", abs(flt(self.credit) - flt(self.debit)))
|
frappe.db.set_value(self.doctype, self.name, "unallocated_amount", abs(flt(self.credit) - flt(self.debit)))
|
||||||
|
|
||||||
self.reload()
|
self.reload()
|
||||||
|
|
||||||
|
def clear_linked_payment_entries(self):
|
||||||
|
for payment_entry in self.payment_entries:
|
||||||
|
allocated_amount = self.get_total_allocated_amount(payment_entry)
|
||||||
|
print(allocated_amount)
|
||||||
|
paid_amount = self.get_paid_amount(payment_entry)
|
||||||
|
|
||||||
|
if paid_amount and allocated_amount:
|
||||||
|
if flt(allocated_amount[0]["allocated_amount"]) > flt(paid_amount):
|
||||||
|
frappe.throw(_("The total allocated amount ({0}) is greated than the paid amount ({1}).".format(flt(allocated_amount[0]["allocated_amount"]), flt(paid_amount))))
|
||||||
|
|
||||||
|
elif flt(allocated_amount[0]["allocated_amount"]) == flt(paid_amount):
|
||||||
|
if payment_entry.payment_document in ["Payment Entry", "Journal Entry", "Purchase Invoice", "Expense Claim"]:
|
||||||
|
self.clear_simple_entry(payment_entry)
|
||||||
|
|
||||||
|
elif payment_entry.payment_document == "Sales Invoice":
|
||||||
|
self.clear_sales_invoice(payment_entry)
|
||||||
|
|
||||||
|
def get_total_allocated_amount(self, payment_entry):
|
||||||
|
return frappe.db.sql("""
|
||||||
|
SELECT
|
||||||
|
SUM(btp.allocated_amount) as allocated_amount,
|
||||||
|
bt.name
|
||||||
|
FROM
|
||||||
|
`tabBank Transaction Payments` as btp
|
||||||
|
LEFT JOIN
|
||||||
|
`tabBank Transaction` bt ON bt.name=btp.parent
|
||||||
|
WHERE
|
||||||
|
btp.payment_document = %s
|
||||||
|
AND
|
||||||
|
btp.payment_entry = %s
|
||||||
|
AND
|
||||||
|
bt.docstatus = 1""", (payment_entry.payment_document, payment_entry.payment_entry), as_dict=True)
|
||||||
|
|
||||||
|
def get_paid_amount(self, payment_entry):
|
||||||
|
if payment_entry.payment_document in ["Payment Entry", "Sales Invoice", "Purchase Invoice"]:
|
||||||
|
return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "paid_amount")
|
||||||
|
|
||||||
|
elif payment_entry.payment_document == "Journal Entry":
|
||||||
|
return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "total_credit")
|
||||||
|
|
||||||
|
elif payment_entry.payment_document == "Expense Claim":
|
||||||
|
return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "total_amount_reimbursed")
|
||||||
|
|
||||||
|
else:
|
||||||
|
frappe.throw("Please reconcile {0}: {1} manually".format(payment_entry.payment_document, payment_entry.payment_entry))
|
||||||
|
|
||||||
|
def clear_simple_entry(self, payment_entry):
|
||||||
|
frappe.db.set_value(payment_entry.payment_document, payment_entry.payment_entry, "clearance_date", self.date)
|
||||||
|
|
||||||
|
def clear_sales_invoice(self, payment_entry):
|
||||||
|
frappe.db.set_value("Sales Invoice Payment", dict(parenttype=payment_entry.payment_document,
|
||||||
|
parent=payment_entry.payment_entry), "clearance_date", self.date)
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def unclear_reference_payment(doctype, docname):
|
||||||
|
if frappe.db.exists(doctype, docname):
|
||||||
|
doc = frappe.get_doc(doctype, docname)
|
||||||
|
if doctype == "Sales Invoice":
|
||||||
|
frappe.db.set_value("Sales Invoice Payment", dict(parenttype=doc.payment_document,
|
||||||
|
parent=doc.payment_entry), "clearance_date", None)
|
||||||
|
else:
|
||||||
|
frappe.db.set_value(doc.payment_document, doc.payment_entry, "clearance_date", None)
|
||||||
|
|
||||||
|
return doc.payment_entry
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ frappe.listview_settings['Bank Transaction'] = {
|
|||||||
get_indicator: function(doc) {
|
get_indicator: function(doc) {
|
||||||
if(flt(doc.unallocated_amount)>0) {
|
if(flt(doc.unallocated_amount)>0) {
|
||||||
return [__("Unreconciled"), "orange", "unallocated_amount,>,0"];
|
return [__("Unreconciled"), "orange", "unallocated_amount,>,0"];
|
||||||
} else if(flt(doc.unallocated_amount)===0) {
|
} else if(flt(doc.unallocated_amount)<=0) {
|
||||||
return [__("Reconciled"), "green", "unallocated_amount,=,0"];
|
return [__("Reconciled"), "green", "unallocated_amount,=,0"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ def upload_bank_statement():
|
|||||||
def create_bank_entries(columns, data, bank_account):
|
def create_bank_entries(columns, data, bank_account):
|
||||||
header_map = get_header_mapping(columns, bank_account)
|
header_map = get_header_mapping(columns, bank_account)
|
||||||
|
|
||||||
count = 0
|
success = 0
|
||||||
|
errors = 0
|
||||||
for d in json.loads(data):
|
for d in json.loads(data):
|
||||||
if all(item is None for item in d) is True:
|
if all(item is None for item in d) is True:
|
||||||
continue
|
continue
|
||||||
@@ -44,7 +45,6 @@ def create_bank_entries(columns, data, bank_account):
|
|||||||
for key, value in iteritems(header_map):
|
for key, value in iteritems(header_map):
|
||||||
fields.update({key: d[int(value)-1]})
|
fields.update({key: d[int(value)-1]})
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
bank_transaction = frappe.get_doc({
|
bank_transaction = frappe.get_doc({
|
||||||
"doctype": "Bank Transaction"
|
"doctype": "Bank Transaction"
|
||||||
@@ -54,12 +54,12 @@ def create_bank_entries(columns, data, bank_account):
|
|||||||
bank_transaction.bank_account = bank_account
|
bank_transaction.bank_account = bank_account
|
||||||
bank_transaction.insert()
|
bank_transaction.insert()
|
||||||
bank_transaction.submit()
|
bank_transaction.submit()
|
||||||
count = count + 1
|
success += 1
|
||||||
except Exception as e:
|
except Exception:
|
||||||
frappe.throw(e)
|
|
||||||
frappe.log_error(frappe.get_traceback())
|
frappe.log_error(frappe.get_traceback())
|
||||||
|
errors += 1
|
||||||
|
|
||||||
return count
|
return {"success": success, "errors": errors}
|
||||||
|
|
||||||
def get_header_mapping(columns, bank_account):
|
def get_header_mapping(columns, bank_account):
|
||||||
mapping = get_bank_mapping(bank_account)
|
mapping = get_bank_mapping(bank_account)
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ erpnext.accounts.bankTransactionUpload = class bankTransactionUpload {
|
|||||||
frappe.xcall('erpnext.accounts.doctype.bank_transaction.bank_transaction_upload.create_bank_entries',
|
frappe.xcall('erpnext.accounts.doctype.bank_transaction.bank_transaction_upload.create_bank_entries',
|
||||||
{columns: this.datatable.datamanager.columns, data: this.datatable.datamanager.data, bank_account: me.parent.bank_account}
|
{columns: this.datatable.datamanager.columns, data: this.datatable.datamanager.data, bank_account: me.parent.bank_account}
|
||||||
).then((result) => {
|
).then((result) => {
|
||||||
let result_title = __("{0} bank transaction(s) created", [result])
|
let result_title = result.errors == 0 ? __("{0} bank transaction(s) created", [result.success]) : __("{0} bank transaction(s) created and {1} errors", [result.success, result.errors])
|
||||||
let result_msg = `
|
let result_msg = `
|
||||||
<div class="flex justify-center align-center text-muted" style="height: 50vh; display: flex;">
|
<div class="flex justify-center align-center text-muted" style="height: 50vh; display: flex;">
|
||||||
<h5 class="text-muted">${result_title}</h5>
|
<h5 class="text-muted">${result_title}</h5>
|
||||||
@@ -199,7 +199,11 @@ erpnext.accounts.bankTransactionUpload = class bankTransactionUpload {
|
|||||||
me.parent.page.clear_primary_action();
|
me.parent.page.clear_primary_action();
|
||||||
me.parent.$main_section.empty();
|
me.parent.$main_section.empty();
|
||||||
me.parent.$main_section.append(result_msg);
|
me.parent.$main_section.append(result_msg);
|
||||||
frappe.show_alert({message:__("All bank transactions have been created"), indicator:'green'});
|
if (result.errors == 0) {
|
||||||
|
frappe.show_alert({message:__("All bank transactions have been created"), indicator:'green'});
|
||||||
|
} else {
|
||||||
|
frappe.show_alert({message:__("Please check the error log for details about the import errors"), indicator:'red'});
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -530,11 +534,13 @@ erpnext.accounts.ReconciliationRow = class ReconciliationRow {
|
|||||||
.then(doc => {
|
.then(doc => {
|
||||||
let displayed_docs = []
|
let displayed_docs = []
|
||||||
if (dt === "Payment Entry") {
|
if (dt === "Payment Entry") {
|
||||||
doc.currency = doc.payment_type == "Receive" ? doc.paid_to_account_currency : doc.paid_from_account_currency;
|
payment.currency = doc.payment_type == "Receive" ? doc.paid_to_account_currency : doc.paid_from_account_currency;
|
||||||
displayed_docs.push(doc);
|
payment.doctype = dt
|
||||||
|
displayed_docs.push(payment);
|
||||||
} else if (dt === "Journal Entry") {
|
} else if (dt === "Journal Entry") {
|
||||||
doc.accounts.forEach(payment => {
|
doc.accounts.forEach(payment => {
|
||||||
if (payment.account === me.gl_account) {
|
if (payment.account === me.gl_account) {
|
||||||
|
payment.doctype = dt;
|
||||||
payment.posting_date = doc.posting_date;
|
payment.posting_date = doc.posting_date;
|
||||||
payment.party = doc.pay_to_recd_from;
|
payment.party = doc.pay_to_recd_from;
|
||||||
payment.reference_no = doc.cheque_no;
|
payment.reference_no = doc.cheque_no;
|
||||||
@@ -548,6 +554,7 @@ erpnext.accounts.ReconciliationRow = class ReconciliationRow {
|
|||||||
} else if (dt === "Sales Invoice") {
|
} else if (dt === "Sales Invoice") {
|
||||||
doc.payments.forEach(payment => {
|
doc.payments.forEach(payment => {
|
||||||
if (payment.clearance_date === null || payment.clearance_date === "") {
|
if (payment.clearance_date === null || payment.clearance_date === "") {
|
||||||
|
payment.doctype = dt;
|
||||||
payment.posting_date = doc.posting_date;
|
payment.posting_date = doc.posting_date;
|
||||||
payment.party = doc.customer;
|
payment.party = doc.customer;
|
||||||
payment.reference_no = doc.remarks;
|
payment.reference_no = doc.remarks;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ def reconcile(bank_transaction, payment_doctype, payment_name):
|
|||||||
frappe.throw(_("The selected payment entry should be linked with a creditor bank transaction"))
|
frappe.throw(_("The selected payment entry should be linked with a creditor bank transaction"))
|
||||||
|
|
||||||
add_payment_to_transaction(transaction, payment_entry, gl_entry)
|
add_payment_to_transaction(transaction, payment_entry, gl_entry)
|
||||||
clear_payment_entry(transaction, payment_entry, gl_entry)
|
#clear_payment_entry(transaction, payment_entry, gl_entry)
|
||||||
|
|
||||||
return 'reconciled'
|
return 'reconciled'
|
||||||
|
|
||||||
@@ -42,40 +42,6 @@ def add_payment_to_transaction(transaction, payment_entry, gl_entry):
|
|||||||
})
|
})
|
||||||
transaction.save()
|
transaction.save()
|
||||||
|
|
||||||
def clear_payment_entry(transaction, payment_entry, gl_entry):
|
|
||||||
linked_bank_transactions = frappe.db.sql("""
|
|
||||||
SELECT
|
|
||||||
bt.credit, bt.debit
|
|
||||||
FROM
|
|
||||||
`tabBank Transaction Payments` as btp
|
|
||||||
LEFT JOIN
|
|
||||||
`tabBank Transaction` as bt on btp.parent=bt.name
|
|
||||||
WHERE
|
|
||||||
btp.payment_document = %s
|
|
||||||
AND
|
|
||||||
btp.payment_entry = %s
|
|
||||||
AND
|
|
||||||
bt.docstatus = 1
|
|
||||||
""", (payment_entry.doctype, payment_entry.name), as_dict=True)
|
|
||||||
|
|
||||||
amount_cleared = (flt(linked_bank_transactions[0].credit) - flt(linked_bank_transactions[0].debit))
|
|
||||||
amount_to_be_cleared = (flt(gl_entry.debit) - flt(gl_entry.credit))
|
|
||||||
|
|
||||||
if payment_entry.doctype in ("Payment Entry", "Journal Entry", "Purchase Invoice", "Expense Claim"):
|
|
||||||
clear_simple_entry(amount_cleared, amount_to_be_cleared, payment_entry, transaction)
|
|
||||||
|
|
||||||
elif payment_entry.doctype == "Sales Invoice":
|
|
||||||
clear_sales_invoice(amount_cleared, amount_to_be_cleared, payment_entry, transaction)
|
|
||||||
|
|
||||||
def clear_simple_entry(amount_cleared, amount_to_be_cleared, payment_entry, transaction):
|
|
||||||
if amount_cleared >= amount_to_be_cleared:
|
|
||||||
frappe.db.set_value(payment_entry.doctype, payment_entry.name, "clearance_date", transaction.date)
|
|
||||||
|
|
||||||
def clear_sales_invoice(amount_cleared, amount_to_be_cleared, payment_entry, transaction):
|
|
||||||
if amount_cleared >= amount_to_be_cleared:
|
|
||||||
frappe.db.set_value("Sales Invoice Payment", dict(parenttype=payment_entry.doctype,
|
|
||||||
parent=payment_entry.name), "clearance_date", transaction.date)
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_linked_payments(bank_transaction):
|
def get_linked_payments(bank_transaction):
|
||||||
transaction = frappe.get_doc("Bank Transaction", bank_transaction)
|
transaction = frappe.get_doc("Bank Transaction", bank_transaction)
|
||||||
@@ -250,7 +216,7 @@ def get_matching_descriptions_data(company, transaction):
|
|||||||
if key == "Payment Entry":
|
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", "paid_to_account_currency as currency"]))
|
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", "paid_to_account_currency as currency"]))
|
||||||
if key == "Journal Entry":
|
if key == "Journal Entry":
|
||||||
journal_entries = frappe.get_all("Journal Entry", filters=[["name", "in", value]], fields=["name", "'Journal Entry' as doctype", "posting_date", "paid_to_recd_from as party", "cheque_no as reference_no", "cheque_date as reference_date", "total_credit as paid_amount"])
|
journal_entries = frappe.get_all("Journal Entry", filters=[["name", "in", value]], fields=["name", "'Journal Entry' as doctype", "posting_date", "pay_to_recd_from as party", "cheque_no as reference_no", "cheque_date as reference_date", "total_credit as paid_amount"])
|
||||||
for journal_entry in journal_entries:
|
for journal_entry in journal_entries:
|
||||||
journal_entry_accounts = frappe.get_all("Journal Entry Account", filters={"parenttype": journal_entry["doctype"], "parent": journal_entry["name"]}, fields=["account_currency"])
|
journal_entry_accounts = frappe.get_all("Journal Entry Account", filters={"parenttype": journal_entry["doctype"], "parent": journal_entry["name"]}, fields=["account_currency"])
|
||||||
journal_entry["currency"] = journal_entry_accounts[0]["account_currency"] if journal_entry_accounts else company_currency
|
journal_entry["currency"] = journal_entry_accounts[0]["account_currency"] if journal_entry_accounts else company_currency
|
||||||
|
|||||||
@@ -95,6 +95,10 @@ status_map = {
|
|||||||
["Ordered", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"],
|
["Ordered", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"],
|
||||||
["Transferred", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Transfer'"],
|
["Transferred", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Transfer'"],
|
||||||
["Issued", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Issue'"]
|
["Issued", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Issue'"]
|
||||||
|
],
|
||||||
|
"Bank Transaction": [
|
||||||
|
["Unreconciled", "eval:self.docstatus == 1 and self.unallocated_amount>0"],
|
||||||
|
["Reconciled", "eval:self.docstatus == 1 and self.unallocated_amount<=0"]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user