Merge pull request #39694 from ruthra-kumar/enforce_separate_account_for_each_bank_account
refactor: enforce unique GL Account for each 'Bank Account'
This commit is contained in:
commit
2e509f69d4
@ -9,6 +9,7 @@ from frappe.contacts.address_and_contact import (
|
|||||||
load_address_and_contact,
|
load_address_and_contact,
|
||||||
)
|
)
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
from frappe.utils import comma_and, get_link_to_form
|
||||||
|
|
||||||
|
|
||||||
class BankAccount(Document):
|
class BankAccount(Document):
|
||||||
@ -52,6 +53,17 @@ class BankAccount(Document):
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_company()
|
self.validate_company()
|
||||||
self.validate_iban()
|
self.validate_iban()
|
||||||
|
self.validate_account()
|
||||||
|
|
||||||
|
def validate_account(self):
|
||||||
|
if self.account:
|
||||||
|
if accounts := frappe.db.get_all("Bank Account", filters={"account": self.account}, as_list=1):
|
||||||
|
frappe.throw(
|
||||||
|
_("'{0}' account is already used by {1}. Use another account.").format(
|
||||||
|
frappe.bold(self.account),
|
||||||
|
frappe.bold(comma_and([get_link_to_form(self.doctype, x[0]) for x in accounts])),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def validate_company(self):
|
def validate_company(self):
|
||||||
if self.is_company_account and not self.company:
|
if self.is_company_account and not self.company:
|
||||||
|
@ -32,8 +32,16 @@ class TestBankTransaction(FrappeTestCase):
|
|||||||
frappe.db.delete(dt)
|
frappe.db.delete(dt)
|
||||||
clear_loan_transactions()
|
clear_loan_transactions()
|
||||||
make_pos_profile()
|
make_pos_profile()
|
||||||
add_transactions()
|
|
||||||
add_vouchers()
|
# generate and use a uniq hash identifier for 'Bank Account' and it's linked GL 'Account' to avoid validation error
|
||||||
|
uniq_identifier = frappe.generate_hash(length=10)
|
||||||
|
gl_account = create_gl_account("_Test Bank " + uniq_identifier)
|
||||||
|
bank_account = create_bank_account(
|
||||||
|
gl_account=gl_account, bank_account_name="Checking Account " + uniq_identifier
|
||||||
|
)
|
||||||
|
|
||||||
|
add_transactions(bank_account=bank_account)
|
||||||
|
add_vouchers(gl_account=gl_account)
|
||||||
|
|
||||||
# This test checks if ERPNext is able to provide a linked payment for a bank transaction based on the amount of the bank transaction.
|
# This test checks if ERPNext is able to provide a linked payment for a bank transaction based on the amount of the bank transaction.
|
||||||
def test_linked_payments(self):
|
def test_linked_payments(self):
|
||||||
@ -219,7 +227,9 @@ def clear_loan_transactions():
|
|||||||
frappe.db.delete("Loan Repayment")
|
frappe.db.delete("Loan Repayment")
|
||||||
|
|
||||||
|
|
||||||
def create_bank_account(bank_name="Citi Bank", account_name="_Test Bank - _TC"):
|
def create_bank_account(
|
||||||
|
bank_name="Citi Bank", gl_account="_Test Bank - _TC", bank_account_name="Checking Account"
|
||||||
|
):
|
||||||
try:
|
try:
|
||||||
frappe.get_doc(
|
frappe.get_doc(
|
||||||
{
|
{
|
||||||
@ -231,21 +241,35 @@ def create_bank_account(bank_name="Citi Bank", account_name="_Test Bank - _TC"):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
frappe.get_doc(
|
bank_account = frappe.get_doc(
|
||||||
{
|
{
|
||||||
"doctype": "Bank Account",
|
"doctype": "Bank Account",
|
||||||
"account_name": "Checking Account",
|
"account_name": bank_account_name,
|
||||||
"bank": bank_name,
|
"bank": bank_name,
|
||||||
"account": account_name,
|
"account": gl_account,
|
||||||
}
|
}
|
||||||
).insert(ignore_if_duplicate=True)
|
).insert(ignore_if_duplicate=True)
|
||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
return bank_account.name
|
||||||
|
|
||||||
def add_transactions():
|
|
||||||
create_bank_account()
|
|
||||||
|
|
||||||
|
def create_gl_account(gl_account_name="_Test Bank - _TC"):
|
||||||
|
gl_account = frappe.get_doc(
|
||||||
|
{
|
||||||
|
"doctype": "Account",
|
||||||
|
"company": "_Test Company",
|
||||||
|
"parent_account": "Current Assets - _TC",
|
||||||
|
"account_type": "Bank",
|
||||||
|
"is_group": 0,
|
||||||
|
"account_name": gl_account_name,
|
||||||
|
}
|
||||||
|
).insert()
|
||||||
|
return gl_account.name
|
||||||
|
|
||||||
|
|
||||||
|
def add_transactions(bank_account="_Test Bank - _TC"):
|
||||||
doc = frappe.get_doc(
|
doc = frappe.get_doc(
|
||||||
{
|
{
|
||||||
"doctype": "Bank Transaction",
|
"doctype": "Bank Transaction",
|
||||||
@ -253,7 +277,7 @@ def add_transactions():
|
|||||||
"date": "2018-10-23",
|
"date": "2018-10-23",
|
||||||
"deposit": 1200,
|
"deposit": 1200,
|
||||||
"currency": "INR",
|
"currency": "INR",
|
||||||
"bank_account": "Checking Account - Citi Bank",
|
"bank_account": bank_account,
|
||||||
}
|
}
|
||||||
).insert()
|
).insert()
|
||||||
doc.submit()
|
doc.submit()
|
||||||
@ -265,7 +289,7 @@ def add_transactions():
|
|||||||
"date": "2018-10-23",
|
"date": "2018-10-23",
|
||||||
"deposit": 1700,
|
"deposit": 1700,
|
||||||
"currency": "INR",
|
"currency": "INR",
|
||||||
"bank_account": "Checking Account - Citi Bank",
|
"bank_account": bank_account,
|
||||||
}
|
}
|
||||||
).insert()
|
).insert()
|
||||||
doc.submit()
|
doc.submit()
|
||||||
@ -277,7 +301,7 @@ def add_transactions():
|
|||||||
"date": "2018-10-26",
|
"date": "2018-10-26",
|
||||||
"withdrawal": 690,
|
"withdrawal": 690,
|
||||||
"currency": "INR",
|
"currency": "INR",
|
||||||
"bank_account": "Checking Account - Citi Bank",
|
"bank_account": bank_account,
|
||||||
}
|
}
|
||||||
).insert()
|
).insert()
|
||||||
doc.submit()
|
doc.submit()
|
||||||
@ -289,7 +313,7 @@ def add_transactions():
|
|||||||
"date": "2018-10-27",
|
"date": "2018-10-27",
|
||||||
"deposit": 3900,
|
"deposit": 3900,
|
||||||
"currency": "INR",
|
"currency": "INR",
|
||||||
"bank_account": "Checking Account - Citi Bank",
|
"bank_account": bank_account,
|
||||||
}
|
}
|
||||||
).insert()
|
).insert()
|
||||||
doc.submit()
|
doc.submit()
|
||||||
@ -301,13 +325,13 @@ def add_transactions():
|
|||||||
"date": "2018-10-27",
|
"date": "2018-10-27",
|
||||||
"withdrawal": 109080,
|
"withdrawal": 109080,
|
||||||
"currency": "INR",
|
"currency": "INR",
|
||||||
"bank_account": "Checking Account - Citi Bank",
|
"bank_account": bank_account,
|
||||||
}
|
}
|
||||||
).insert()
|
).insert()
|
||||||
doc.submit()
|
doc.submit()
|
||||||
|
|
||||||
|
|
||||||
def add_vouchers():
|
def add_vouchers(gl_account="_Test Bank - _TC"):
|
||||||
try:
|
try:
|
||||||
frappe.get_doc(
|
frappe.get_doc(
|
||||||
{
|
{
|
||||||
@ -323,7 +347,7 @@ def add_vouchers():
|
|||||||
|
|
||||||
pi = make_purchase_invoice(supplier="Conrad Electronic", qty=1, rate=690)
|
pi = make_purchase_invoice(supplier="Conrad Electronic", qty=1, rate=690)
|
||||||
|
|
||||||
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
|
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account=gl_account)
|
||||||
pe.reference_no = "Conrad Oct 18"
|
pe.reference_no = "Conrad Oct 18"
|
||||||
pe.reference_date = "2018-10-24"
|
pe.reference_date = "2018-10-24"
|
||||||
pe.insert()
|
pe.insert()
|
||||||
@ -342,14 +366,14 @@ def add_vouchers():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
pi = make_purchase_invoice(supplier="Mr G", qty=1, rate=1200)
|
pi = make_purchase_invoice(supplier="Mr G", qty=1, rate=1200)
|
||||||
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
|
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account=gl_account)
|
||||||
pe.reference_no = "Herr G Oct 18"
|
pe.reference_no = "Herr G Oct 18"
|
||||||
pe.reference_date = "2018-10-24"
|
pe.reference_date = "2018-10-24"
|
||||||
pe.insert()
|
pe.insert()
|
||||||
pe.submit()
|
pe.submit()
|
||||||
|
|
||||||
pi = make_purchase_invoice(supplier="Mr G", qty=1, rate=1700)
|
pi = make_purchase_invoice(supplier="Mr G", qty=1, rate=1700)
|
||||||
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
|
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account=gl_account)
|
||||||
pe.reference_no = "Herr G Nov 18"
|
pe.reference_no = "Herr G Nov 18"
|
||||||
pe.reference_date = "2018-11-01"
|
pe.reference_date = "2018-11-01"
|
||||||
pe.insert()
|
pe.insert()
|
||||||
@ -380,10 +404,10 @@ def add_vouchers():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
pi = make_purchase_invoice(supplier="Poore Simon's", qty=1, rate=3900, is_paid=1, do_not_save=1)
|
pi = make_purchase_invoice(supplier="Poore Simon's", qty=1, rate=3900, is_paid=1, do_not_save=1)
|
||||||
pi.cash_bank_account = "_Test Bank - _TC"
|
pi.cash_bank_account = gl_account
|
||||||
pi.insert()
|
pi.insert()
|
||||||
pi.submit()
|
pi.submit()
|
||||||
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
|
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account=gl_account)
|
||||||
pe.reference_no = "Poore Simon's Oct 18"
|
pe.reference_no = "Poore Simon's Oct 18"
|
||||||
pe.reference_date = "2018-10-28"
|
pe.reference_date = "2018-10-28"
|
||||||
pe.paid_amount = 690
|
pe.paid_amount = 690
|
||||||
@ -392,7 +416,7 @@ def add_vouchers():
|
|||||||
pe.submit()
|
pe.submit()
|
||||||
|
|
||||||
si = create_sales_invoice(customer="Poore Simon's", qty=1, rate=3900)
|
si = create_sales_invoice(customer="Poore Simon's", qty=1, rate=3900)
|
||||||
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC")
|
pe = get_payment_entry("Sales Invoice", si.name, bank_account=gl_account)
|
||||||
pe.reference_no = "Poore Simon's Oct 18"
|
pe.reference_no = "Poore Simon's Oct 18"
|
||||||
pe.reference_date = "2018-10-28"
|
pe.reference_date = "2018-10-28"
|
||||||
pe.insert()
|
pe.insert()
|
||||||
@ -415,16 +439,12 @@ def add_vouchers():
|
|||||||
if not frappe.db.get_value(
|
if not frappe.db.get_value(
|
||||||
"Mode of Payment Account", {"company": "_Test Company", "parent": "Cash"}
|
"Mode of Payment Account", {"company": "_Test Company", "parent": "Cash"}
|
||||||
):
|
):
|
||||||
mode_of_payment.append(
|
mode_of_payment.append("accounts", {"company": "_Test Company", "default_account": gl_account})
|
||||||
"accounts", {"company": "_Test Company", "default_account": "_Test Bank - _TC"}
|
|
||||||
)
|
|
||||||
mode_of_payment.save()
|
mode_of_payment.save()
|
||||||
|
|
||||||
si = create_sales_invoice(customer="Fayva", qty=1, rate=109080, do_not_save=1)
|
si = create_sales_invoice(customer="Fayva", qty=1, rate=109080, do_not_save=1)
|
||||||
si.is_pos = 1
|
si.is_pos = 1
|
||||||
si.append(
|
si.append("payments", {"mode_of_payment": "Cash", "account": gl_account, "amount": 109080})
|
||||||
"payments", {"mode_of_payment": "Cash", "account": "_Test Bank - _TC", "amount": 109080}
|
|
||||||
)
|
|
||||||
si.insert()
|
si.insert()
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
|
@ -4,9 +4,13 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
from frappe.utils import getdate
|
from frappe.utils import getdate
|
||||||
|
|
||||||
from erpnext.accounts.doctype.bank_transaction.test_bank_transaction import create_bank_account
|
from erpnext.accounts.doctype.bank_transaction.test_bank_transaction import (
|
||||||
|
create_bank_account,
|
||||||
|
create_gl_account,
|
||||||
|
)
|
||||||
from erpnext.accounts.doctype.payment_entry.payment_entry import (
|
from erpnext.accounts.doctype.payment_entry.payment_entry import (
|
||||||
get_payment_entry,
|
get_payment_entry,
|
||||||
make_payment_order,
|
make_payment_order,
|
||||||
@ -14,28 +18,32 @@ from erpnext.accounts.doctype.payment_entry.payment_entry import (
|
|||||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
||||||
|
|
||||||
|
|
||||||
class TestPaymentOrder(unittest.TestCase):
|
class TestPaymentOrder(FrappeTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
create_bank_account()
|
# generate and use a uniq hash identifier for 'Bank Account' and it's linked GL 'Account' to avoid validation error
|
||||||
|
uniq_identifier = frappe.generate_hash(length=10)
|
||||||
|
self.gl_account = create_gl_account("_Test Bank " + uniq_identifier)
|
||||||
|
self.bank_account = create_bank_account(
|
||||||
|
gl_account=self.gl_account, bank_account_name="Checking Account " + uniq_identifier
|
||||||
|
)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
for bt in frappe.get_all("Payment Order"):
|
frappe.db.rollback()
|
||||||
doc = frappe.get_doc("Payment Order", bt.name)
|
|
||||||
doc.cancel()
|
|
||||||
doc.delete()
|
|
||||||
|
|
||||||
def test_payment_order_creation_against_payment_entry(self):
|
def test_payment_order_creation_against_payment_entry(self):
|
||||||
purchase_invoice = make_purchase_invoice()
|
purchase_invoice = make_purchase_invoice()
|
||||||
payment_entry = get_payment_entry(
|
payment_entry = get_payment_entry(
|
||||||
"Purchase Invoice", purchase_invoice.name, bank_account="_Test Bank - _TC"
|
"Purchase Invoice", purchase_invoice.name, bank_account=self.gl_account
|
||||||
)
|
)
|
||||||
payment_entry.reference_no = "_Test_Payment_Order"
|
payment_entry.reference_no = "_Test_Payment_Order"
|
||||||
payment_entry.reference_date = getdate()
|
payment_entry.reference_date = getdate()
|
||||||
payment_entry.party_bank_account = "Checking Account - Citi Bank"
|
payment_entry.party_bank_account = self.bank_account
|
||||||
payment_entry.insert()
|
payment_entry.insert()
|
||||||
payment_entry.submit()
|
payment_entry.submit()
|
||||||
|
|
||||||
doc = create_payment_order_against_payment_entry(payment_entry, "Payment Entry")
|
doc = create_payment_order_against_payment_entry(
|
||||||
|
payment_entry, "Payment Entry", self.bank_account
|
||||||
|
)
|
||||||
reference_doc = doc.get("references")[0]
|
reference_doc = doc.get("references")[0]
|
||||||
self.assertEqual(reference_doc.reference_name, payment_entry.name)
|
self.assertEqual(reference_doc.reference_name, payment_entry.name)
|
||||||
self.assertEqual(reference_doc.reference_doctype, "Payment Entry")
|
self.assertEqual(reference_doc.reference_doctype, "Payment Entry")
|
||||||
@ -43,13 +51,13 @@ class TestPaymentOrder(unittest.TestCase):
|
|||||||
self.assertEqual(reference_doc.amount, 250)
|
self.assertEqual(reference_doc.amount, 250)
|
||||||
|
|
||||||
|
|
||||||
def create_payment_order_against_payment_entry(ref_doc, order_type):
|
def create_payment_order_against_payment_entry(ref_doc, order_type, bank_account):
|
||||||
payment_order = frappe.get_doc(
|
payment_order = frappe.get_doc(
|
||||||
dict(
|
dict(
|
||||||
doctype="Payment Order",
|
doctype="Payment Order",
|
||||||
company="_Test Company",
|
company="_Test Company",
|
||||||
payment_order_type=order_type,
|
payment_order_type=order_type,
|
||||||
company_bank_account="Checking Account - Citi Bank",
|
company_bank_account=bank_account,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
doc = make_payment_order(ref_doc.name, payment_order)
|
doc = make_payment_order(ref_doc.name, payment_order)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user