refactor(test): make use of mixin in ar/ap report tests
This commit is contained in:
parent
ab6e600b9e
commit
bb7bed4c1a
@ -8,20 +8,17 @@ from erpnext import get_default_cost_center
|
|||||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
from erpnext.accounts.report.accounts_receivable.accounts_receivable import execute
|
from erpnext.accounts.report.accounts_receivable.accounts_receivable import execute
|
||||||
|
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
|
||||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||||
|
|
||||||
|
|
||||||
class TestAccountsReceivable(FrappeTestCase):
|
class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
frappe.db.sql("delete from `tabSales Invoice` where company='_Test Company 2'")
|
self.create_company()
|
||||||
frappe.db.sql("delete from `tabSales Order` where company='_Test Company 2'")
|
self.create_customer()
|
||||||
frappe.db.sql("delete from `tabPayment Entry` where company='_Test Company 2'")
|
self.create_item()
|
||||||
frappe.db.sql("delete from `tabGL Entry` where company='_Test Company 2'")
|
self.create_usd_receivable_account()
|
||||||
frappe.db.sql("delete from `tabPayment Ledger Entry` where company='_Test Company 2'")
|
self.clear_old_entries()
|
||||||
frappe.db.sql("delete from `tabJournal Entry` where company='_Test Company 2'")
|
|
||||||
frappe.db.sql("delete from `tabExchange Rate Revaluation` where company='_Test Company 2'")
|
|
||||||
|
|
||||||
self.create_usd_account()
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
@ -49,9 +46,61 @@ class TestAccountsReceivable(FrappeTestCase):
|
|||||||
debtors_usd.account_type = debtors.account_type
|
debtors_usd.account_type = debtors.account_type
|
||||||
self.debtors_usd = debtors_usd.save().name
|
self.debtors_usd = debtors_usd.save().name
|
||||||
|
|
||||||
|
def create_sales_invoice(self, no_payment_schedule=False, do_not_submit=False):
|
||||||
|
frappe.set_user("Administrator")
|
||||||
|
si = create_sales_invoice(
|
||||||
|
item=self.item,
|
||||||
|
company=self.company,
|
||||||
|
customer=self.customer,
|
||||||
|
debit_to=self.debit_to,
|
||||||
|
posting_date=today(),
|
||||||
|
parent_cost_center=self.cost_center,
|
||||||
|
cost_center=self.cost_center,
|
||||||
|
rate=100,
|
||||||
|
price_list_rate=100,
|
||||||
|
do_not_save=1,
|
||||||
|
)
|
||||||
|
if not no_payment_schedule:
|
||||||
|
si.append(
|
||||||
|
"payment_schedule",
|
||||||
|
dict(due_date=getdate(add_days(today(), 30)), invoice_portion=30.00, payment_amount=30),
|
||||||
|
)
|
||||||
|
si.append(
|
||||||
|
"payment_schedule",
|
||||||
|
dict(due_date=getdate(add_days(today(), 60)), invoice_portion=50.00, payment_amount=50),
|
||||||
|
)
|
||||||
|
si.append(
|
||||||
|
"payment_schedule",
|
||||||
|
dict(due_date=getdate(add_days(today(), 90)), invoice_portion=20.00, payment_amount=20),
|
||||||
|
)
|
||||||
|
si = si.save()
|
||||||
|
if not do_not_submit:
|
||||||
|
si = si.submit()
|
||||||
|
return si
|
||||||
|
|
||||||
|
def create_payment_entry(self, docname):
|
||||||
|
pe = get_payment_entry("Sales Invoice", docname, bank_account=self.cash, party_amount=40)
|
||||||
|
pe.paid_from = self.debit_to
|
||||||
|
pe.insert()
|
||||||
|
pe.submit()
|
||||||
|
|
||||||
|
def create_credit_note(self, docname):
|
||||||
|
credit_note = create_sales_invoice(
|
||||||
|
company=self.company,
|
||||||
|
customer=self.customer,
|
||||||
|
item=self.item,
|
||||||
|
qty=-1,
|
||||||
|
debit_to=self.debit_to,
|
||||||
|
cost_center=self.cost_center,
|
||||||
|
is_return=1,
|
||||||
|
return_against=docname,
|
||||||
|
)
|
||||||
|
|
||||||
|
return credit_note
|
||||||
|
|
||||||
def test_accounts_receivable(self):
|
def test_accounts_receivable(self):
|
||||||
filters = {
|
filters = {
|
||||||
"company": "_Test Company 2",
|
"company": self.company,
|
||||||
"based_on_payment_terms": 1,
|
"based_on_payment_terms": 1,
|
||||||
"report_date": today(),
|
"report_date": today(),
|
||||||
"range1": 30,
|
"range1": 30,
|
||||||
@ -61,7 +110,9 @@ class TestAccountsReceivable(FrappeTestCase):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# check invoice grand total and invoiced column's value for 3 payment terms
|
# check invoice grand total and invoiced column's value for 3 payment terms
|
||||||
name = make_sales_invoice().name
|
si = self.create_sales_invoice()
|
||||||
|
name = si.name
|
||||||
|
|
||||||
report = execute(filters)
|
report = execute(filters)
|
||||||
|
|
||||||
expected_data = [[100, 30], [100, 50], [100, 20]]
|
expected_data = [[100, 30], [100, 50], [100, 20]]
|
||||||
@ -71,7 +122,7 @@ class TestAccountsReceivable(FrappeTestCase):
|
|||||||
self.assertEqual(expected_data[i - 1], [row.invoice_grand_total, row.invoiced])
|
self.assertEqual(expected_data[i - 1], [row.invoice_grand_total, row.invoiced])
|
||||||
|
|
||||||
# check invoice grand total, invoiced, paid and outstanding column's value after payment
|
# check invoice grand total, invoiced, paid and outstanding column's value after payment
|
||||||
make_payment(name)
|
self.create_payment_entry(si.name)
|
||||||
report = execute(filters)
|
report = execute(filters)
|
||||||
|
|
||||||
expected_data_after_payment = [[100, 50, 10, 40], [100, 20, 0, 20]]
|
expected_data_after_payment = [[100, 50, 10, 40], [100, 20, 0, 20]]
|
||||||
@ -84,10 +135,10 @@ class TestAccountsReceivable(FrappeTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# check invoice grand total, invoiced, paid and outstanding column's value after credit note
|
# check invoice grand total, invoiced, paid and outstanding column's value after credit note
|
||||||
make_credit_note(name)
|
self.create_credit_note(si.name)
|
||||||
report = execute(filters)
|
report = execute(filters)
|
||||||
|
|
||||||
expected_data_after_credit_note = [100, 0, 0, 40, -40, "Debtors - _TC2"]
|
expected_data_after_credit_note = [100, 0, 0, 40, -40, self.debit_to]
|
||||||
|
|
||||||
row = report[1][0]
|
row = report[1][0]
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@ -108,21 +159,20 @@ class TestAccountsReceivable(FrappeTestCase):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
so = make_sales_order(
|
so = make_sales_order(
|
||||||
company="_Test Company 2",
|
company=self.company,
|
||||||
customer="_Test Customer 2",
|
customer=self.customer,
|
||||||
warehouse="Finished Goods - _TC2",
|
warehouse=self.warehouse,
|
||||||
currency="EUR",
|
debit_to=self.debit_to,
|
||||||
debit_to="Debtors - _TC2",
|
income_account=self.income_account,
|
||||||
income_account="Sales - _TC2",
|
expense_account=self.expense_account,
|
||||||
expense_account="Cost of Goods Sold - _TC2",
|
cost_center=self.cost_center,
|
||||||
cost_center="Main - _TC2",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
pe = get_payment_entry(so.doctype, so.name)
|
pe = get_payment_entry(so.doctype, so.name)
|
||||||
pe = pe.save().submit()
|
pe = pe.save().submit()
|
||||||
|
|
||||||
filters = {
|
filters = {
|
||||||
"company": "_Test Company 2",
|
"company": self.company,
|
||||||
"based_on_payment_terms": 0,
|
"based_on_payment_terms": 0,
|
||||||
"report_date": today(),
|
"report_date": today(),
|
||||||
"range1": 30,
|
"range1": 30,
|
||||||
@ -147,34 +197,32 @@ class TestAccountsReceivable(FrappeTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@change_settings(
|
@change_settings(
|
||||||
"Accounts Settings", {"allow_multi_currency_invoices_against_single_party_account": 1}
|
"Accounts Settings",
|
||||||
|
{"allow_multi_currency_invoices_against_single_party_account": 1, "allow_stale": 0},
|
||||||
)
|
)
|
||||||
def test_exchange_revaluation_for_party(self):
|
def test_exchange_revaluation_for_party(self):
|
||||||
"""
|
"""
|
||||||
Exchange Revaluation for party on Receivable/Payable shoule be included
|
Exchange Revaluation for party on Receivable/Payable should be included
|
||||||
"""
|
"""
|
||||||
|
|
||||||
company = "_Test Company 2"
|
|
||||||
customer = "_Test Customer 2"
|
|
||||||
|
|
||||||
# Using Exchange Gain/Loss account for unrealized as well.
|
# Using Exchange Gain/Loss account for unrealized as well.
|
||||||
company_doc = frappe.get_doc("Company", company)
|
company_doc = frappe.get_doc("Company", self.company)
|
||||||
company_doc.unrealized_exchange_gain_loss_account = company_doc.exchange_gain_loss_account
|
company_doc.unrealized_exchange_gain_loss_account = company_doc.exchange_gain_loss_account
|
||||||
company_doc.save()
|
company_doc.save()
|
||||||
|
|
||||||
si = make_sales_invoice(no_payment_schedule=True, do_not_submit=True)
|
si = self.create_sales_invoice(no_payment_schedule=True, do_not_submit=True)
|
||||||
si.currency = "USD"
|
si.currency = "USD"
|
||||||
si.conversion_rate = 0.90
|
si.conversion_rate = 80
|
||||||
si.debit_to = self.debtors_usd
|
si.debit_to = self.debtors_usd
|
||||||
si = si.save().submit()
|
si = si.save().submit()
|
||||||
|
|
||||||
# Exchange Revaluation
|
# Exchange Revaluation
|
||||||
err = frappe.new_doc("Exchange Rate Revaluation")
|
err = frappe.new_doc("Exchange Rate Revaluation")
|
||||||
err.company = company
|
err.company = self.company
|
||||||
err.posting_date = today()
|
err.posting_date = today()
|
||||||
accounts = err.get_accounts_data()
|
accounts = err.get_accounts_data()
|
||||||
err.extend("accounts", accounts)
|
err.extend("accounts", accounts)
|
||||||
err.accounts[0].new_exchange_rate = 0.95
|
err.accounts[0].new_exchange_rate = 85
|
||||||
row = err.accounts[0]
|
row = err.accounts[0]
|
||||||
row.new_balance_in_base_currency = flt(
|
row.new_balance_in_base_currency = flt(
|
||||||
row.new_exchange_rate * flt(row.balance_in_account_currency)
|
row.new_exchange_rate * flt(row.balance_in_account_currency)
|
||||||
@ -189,7 +237,7 @@ class TestAccountsReceivable(FrappeTestCase):
|
|||||||
je = je.submit()
|
je = je.submit()
|
||||||
|
|
||||||
filters = {
|
filters = {
|
||||||
"company": company,
|
"company": self.company,
|
||||||
"report_date": today(),
|
"report_date": today(),
|
||||||
"range1": 30,
|
"range1": 30,
|
||||||
"range2": 60,
|
"range2": 60,
|
||||||
@ -198,7 +246,7 @@ class TestAccountsReceivable(FrappeTestCase):
|
|||||||
}
|
}
|
||||||
report = execute(filters)
|
report = execute(filters)
|
||||||
|
|
||||||
expected_data_for_err = [0, -5, 0, 5]
|
expected_data_for_err = [0, -500, 0, 500]
|
||||||
row = [x for x in report[1] if x.voucher_type == je.doctype and x.voucher_no == je.name][0]
|
row = [x for x in report[1] if x.voucher_type == je.doctype and x.voucher_no == je.name][0]
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
expected_data_for_err,
|
expected_data_for_err,
|
||||||
@ -214,46 +262,43 @@ class TestAccountsReceivable(FrappeTestCase):
|
|||||||
"""
|
"""
|
||||||
Payment against credit/debit note should be considered against the parent invoice
|
Payment against credit/debit note should be considered against the parent invoice
|
||||||
"""
|
"""
|
||||||
company = "_Test Company 2"
|
|
||||||
customer = "_Test Customer 2"
|
|
||||||
|
|
||||||
si1 = make_sales_invoice()
|
si1 = self.create_sales_invoice()
|
||||||
|
|
||||||
pe = get_payment_entry("Sales Invoice", si1.name, bank_account="Cash - _TC2")
|
pe = get_payment_entry(si1.doctype, si1.name, bank_account=self.cash)
|
||||||
pe.paid_from = "Debtors - _TC2"
|
pe.paid_from = self.debit_to
|
||||||
pe.insert()
|
pe.insert()
|
||||||
pe.submit()
|
pe.submit()
|
||||||
|
|
||||||
cr_note = make_credit_note(si1.name)
|
cr_note = self.create_credit_note(si1.name)
|
||||||
|
|
||||||
si2 = make_sales_invoice()
|
si2 = self.create_sales_invoice()
|
||||||
|
|
||||||
# manually link cr_note with si2 using journal entry
|
# manually link cr_note with si2 using journal entry
|
||||||
je = frappe.new_doc("Journal Entry")
|
je = frappe.new_doc("Journal Entry")
|
||||||
je.company = company
|
je.company = self.company
|
||||||
je.voucher_type = "Credit Note"
|
je.voucher_type = "Credit Note"
|
||||||
je.posting_date = today()
|
je.posting_date = today()
|
||||||
|
|
||||||
debit_account = "Debtors - _TC2"
|
|
||||||
debit_entry = {
|
debit_entry = {
|
||||||
"account": debit_account,
|
"account": self.debit_to,
|
||||||
"party_type": "Customer",
|
"party_type": "Customer",
|
||||||
"party": customer,
|
"party": self.customer,
|
||||||
"debit": 100,
|
"debit": 100,
|
||||||
"debit_in_account_currency": 100,
|
"debit_in_account_currency": 100,
|
||||||
"reference_type": cr_note.doctype,
|
"reference_type": cr_note.doctype,
|
||||||
"reference_name": cr_note.name,
|
"reference_name": cr_note.name,
|
||||||
"cost_center": "Main - _TC2",
|
"cost_center": self.cost_center,
|
||||||
}
|
}
|
||||||
credit_entry = {
|
credit_entry = {
|
||||||
"account": debit_account,
|
"account": self.debit_to,
|
||||||
"party_type": "Customer",
|
"party_type": "Customer",
|
||||||
"party": customer,
|
"party": self.customer,
|
||||||
"credit": 100,
|
"credit": 100,
|
||||||
"credit_in_account_currency": 100,
|
"credit_in_account_currency": 100,
|
||||||
"reference_type": si2.doctype,
|
"reference_type": si2.doctype,
|
||||||
"reference_name": si2.name,
|
"reference_name": si2.name,
|
||||||
"cost_center": "Main - _TC2",
|
"cost_center": self.cost_center,
|
||||||
}
|
}
|
||||||
|
|
||||||
je.append("accounts", debit_entry)
|
je.append("accounts", debit_entry)
|
||||||
@ -261,7 +306,7 @@ class TestAccountsReceivable(FrappeTestCase):
|
|||||||
je = je.save().submit()
|
je = je.save().submit()
|
||||||
|
|
||||||
filters = {
|
filters = {
|
||||||
"company": company,
|
"company": self.company,
|
||||||
"report_date": today(),
|
"report_date": today(),
|
||||||
"range1": 30,
|
"range1": 30,
|
||||||
"range2": 60,
|
"range2": 60,
|
||||||
@ -270,65 +315,3 @@ class TestAccountsReceivable(FrappeTestCase):
|
|||||||
}
|
}
|
||||||
report = execute(filters)
|
report = execute(filters)
|
||||||
self.assertEqual(report[1], [])
|
self.assertEqual(report[1], [])
|
||||||
|
|
||||||
|
|
||||||
def make_sales_invoice(no_payment_schedule=False, do_not_submit=False):
|
|
||||||
frappe.set_user("Administrator")
|
|
||||||
|
|
||||||
si = create_sales_invoice(
|
|
||||||
company="_Test Company 2",
|
|
||||||
customer="_Test Customer 2",
|
|
||||||
currency="EUR",
|
|
||||||
warehouse="Finished Goods - _TC2",
|
|
||||||
debit_to="Debtors - _TC2",
|
|
||||||
income_account="Sales - _TC2",
|
|
||||||
expense_account="Cost of Goods Sold - _TC2",
|
|
||||||
cost_center="Main - _TC2",
|
|
||||||
do_not_save=1,
|
|
||||||
)
|
|
||||||
|
|
||||||
if not no_payment_schedule:
|
|
||||||
si.append(
|
|
||||||
"payment_schedule",
|
|
||||||
dict(due_date=getdate(add_days(today(), 30)), invoice_portion=30.00, payment_amount=30),
|
|
||||||
)
|
|
||||||
si.append(
|
|
||||||
"payment_schedule",
|
|
||||||
dict(due_date=getdate(add_days(today(), 60)), invoice_portion=50.00, payment_amount=50),
|
|
||||||
)
|
|
||||||
si.append(
|
|
||||||
"payment_schedule",
|
|
||||||
dict(due_date=getdate(add_days(today(), 90)), invoice_portion=20.00, payment_amount=20),
|
|
||||||
)
|
|
||||||
|
|
||||||
si = si.save()
|
|
||||||
|
|
||||||
if not do_not_submit:
|
|
||||||
si = si.submit()
|
|
||||||
|
|
||||||
return si
|
|
||||||
|
|
||||||
|
|
||||||
def make_payment(docname):
|
|
||||||
pe = get_payment_entry("Sales Invoice", docname, bank_account="Cash - _TC2", party_amount=40)
|
|
||||||
pe.paid_from = "Debtors - _TC2"
|
|
||||||
pe.insert()
|
|
||||||
pe.submit()
|
|
||||||
|
|
||||||
|
|
||||||
def make_credit_note(docname):
|
|
||||||
credit_note = create_sales_invoice(
|
|
||||||
company="_Test Company 2",
|
|
||||||
customer="_Test Customer 2",
|
|
||||||
currency="EUR",
|
|
||||||
qty=-1,
|
|
||||||
warehouse="Finished Goods - _TC2",
|
|
||||||
debit_to="Debtors - _TC2",
|
|
||||||
income_account="Sales - _TC2",
|
|
||||||
expense_account="Cost of Goods Sold - _TC2",
|
|
||||||
cost_center="Main - _TC2",
|
|
||||||
is_return=1,
|
|
||||||
return_against=docname,
|
|
||||||
)
|
|
||||||
|
|
||||||
return credit_note
|
|
||||||
|
@ -60,7 +60,6 @@ class AccountsTestMixin:
|
|||||||
self.income_account = "Sales - " + abbr
|
self.income_account = "Sales - " + abbr
|
||||||
self.expense_account = "Cost of Goods Sold - " + abbr
|
self.expense_account = "Cost of Goods Sold - " + abbr
|
||||||
self.debit_to = "Debtors - " + abbr
|
self.debit_to = "Debtors - " + abbr
|
||||||
self.debit_usd = "Debtors USD - " + abbr
|
|
||||||
self.cash = "Cash - " + abbr
|
self.cash = "Cash - " + abbr
|
||||||
self.creditors = "Creditors - " + abbr
|
self.creditors = "Creditors - " + abbr
|
||||||
self.retained_earnings = "Retained Earnings - " + abbr
|
self.retained_earnings = "Retained Earnings - " + abbr
|
||||||
@ -105,6 +104,28 @@ class AccountsTestMixin:
|
|||||||
new_acc.save()
|
new_acc.save()
|
||||||
setattr(self, acc.attribute_name, new_acc.name)
|
setattr(self, acc.attribute_name, new_acc.name)
|
||||||
|
|
||||||
|
def create_usd_receivable_account(self):
|
||||||
|
account_name = "Debtors USD"
|
||||||
|
if not frappe.db.get_value(
|
||||||
|
"Account", filters={"account_name": account_name, "company": self.company}
|
||||||
|
):
|
||||||
|
acc = frappe.new_doc("Account")
|
||||||
|
acc.account_name = account_name
|
||||||
|
acc.parent_account = "Accounts Receivable - " + self.company_abbr
|
||||||
|
acc.company = self.company
|
||||||
|
acc.account_currency = "USD"
|
||||||
|
acc.account_type = "Receivable"
|
||||||
|
acc.insert()
|
||||||
|
else:
|
||||||
|
name = frappe.db.get_value(
|
||||||
|
"Account",
|
||||||
|
filters={"account_name": account_name, "company": self.company},
|
||||||
|
fieldname="name",
|
||||||
|
pluck=True,
|
||||||
|
)
|
||||||
|
acc = frappe.get_doc("Account", name)
|
||||||
|
self.debtors_usd = acc.name
|
||||||
|
|
||||||
def clear_old_entries(self):
|
def clear_old_entries(self):
|
||||||
doctype_list = [
|
doctype_list = [
|
||||||
"GL Entry",
|
"GL Entry",
|
||||||
@ -113,6 +134,8 @@ class AccountsTestMixin:
|
|||||||
"Purchase Invoice",
|
"Purchase Invoice",
|
||||||
"Payment Entry",
|
"Payment Entry",
|
||||||
"Journal Entry",
|
"Journal Entry",
|
||||||
|
"Sales Order",
|
||||||
|
"Exchange Rate Revaluation",
|
||||||
]
|
]
|
||||||
for doctype in doctype_list:
|
for doctype in doctype_list:
|
||||||
qb.from_(qb.DocType(doctype)).delete().where(qb.DocType(doctype).company == self.company).run()
|
qb.from_(qb.DocType(doctype)).delete().where(qb.DocType(doctype).company == self.company).run()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user