refactor: assert payment ledger outstanding in both currencies
This commit is contained in:
parent
6e18bb6456
commit
73cc1ba654
@ -5,6 +5,7 @@ import unittest
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import qb
|
from frappe import qb
|
||||||
|
from frappe.query_builder.functions import Sum
|
||||||
from frappe.tests.utils import FrappeTestCase, change_settings
|
from frappe.tests.utils import FrappeTestCase, change_settings
|
||||||
from frappe.utils import add_days, flt, nowdate
|
from frappe.utils import add_days, flt, nowdate
|
||||||
|
|
||||||
@ -48,7 +49,15 @@ def make_supplier(supplier_name, currency=None):
|
|||||||
# class TestAccountsController(FrappeTestCase):
|
# class TestAccountsController(FrappeTestCase):
|
||||||
class TestAccountsController(unittest.TestCase):
|
class TestAccountsController(unittest.TestCase):
|
||||||
"""
|
"""
|
||||||
Test Exchange Gain/Loss booking on various scenarios
|
Test Exchange Gain/Loss booking on various scenarios.
|
||||||
|
Test Cases are numbered for better readbility
|
||||||
|
|
||||||
|
10 series - Sales Invoice against Payment Entries
|
||||||
|
20 series - Sales Invoice against Journals
|
||||||
|
30 series - Sales Invoice against Credit Notes
|
||||||
|
40 series - Purchase Invoice against Payment Entries
|
||||||
|
50 series - Purchase Invoice against Journals
|
||||||
|
60 series - Purchase Invoice against Debit Notes
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -130,7 +139,13 @@ class TestAccountsController(unittest.TestCase):
|
|||||||
self.debtors_usd = acc.name
|
self.debtors_usd = acc.name
|
||||||
|
|
||||||
def create_sales_invoice(
|
def create_sales_invoice(
|
||||||
self, qty=1, rate=1, posting_date=nowdate(), do_not_save=False, do_not_submit=False
|
self,
|
||||||
|
qty=1,
|
||||||
|
rate=1,
|
||||||
|
conversion_rate=80,
|
||||||
|
posting_date=nowdate(),
|
||||||
|
do_not_save=False,
|
||||||
|
do_not_submit=False,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Helper function to populate default values in sales invoice
|
Helper function to populate default values in sales invoice
|
||||||
@ -148,7 +163,7 @@ class TestAccountsController(unittest.TestCase):
|
|||||||
parent_cost_center=self.cost_center,
|
parent_cost_center=self.cost_center,
|
||||||
update_stock=0,
|
update_stock=0,
|
||||||
currency="USD",
|
currency="USD",
|
||||||
conversion_rate=80,
|
conversion_rate=conversion_rate,
|
||||||
is_pos=0,
|
is_pos=0,
|
||||||
is_return=0,
|
is_return=0,
|
||||||
return_against=None,
|
return_against=None,
|
||||||
@ -238,24 +253,61 @@ class TestAccountsController(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
return journals
|
return journals
|
||||||
|
|
||||||
def test_01_payment_against_invoice(self):
|
def assert_ledger_outstanding(
|
||||||
|
self,
|
||||||
|
voucher_type: str,
|
||||||
|
voucher_no: str,
|
||||||
|
outstanding: float,
|
||||||
|
outstanding_in_account_currency: float,
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Assert outstanding amount based on ledger on both company/base currency and account currency
|
||||||
|
"""
|
||||||
|
|
||||||
|
ple = qb.DocType("Payment Ledger Entry")
|
||||||
|
current_outstanding = (
|
||||||
|
qb.from_(ple)
|
||||||
|
.select(
|
||||||
|
Sum(ple.amount).as_("outstanding"),
|
||||||
|
Sum(ple.amount_in_account_currency).as_("outstanding_in_account_currency"),
|
||||||
|
)
|
||||||
|
.where(
|
||||||
|
(ple.against_voucher_type == voucher_type)
|
||||||
|
& (ple.against_voucher_no == voucher_no)
|
||||||
|
& (ple.delinked == 0)
|
||||||
|
)
|
||||||
|
.run(as_dict=True)[0]
|
||||||
|
)
|
||||||
|
self.assertEqual(outstanding, current_outstanding.outstanding)
|
||||||
|
self.assertEqual(
|
||||||
|
outstanding_in_account_currency, current_outstanding.outstanding_in_account_currency
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_10_payment_against_sales_invoice(self):
|
||||||
# Sales Invoice in Foreign Currency
|
# Sales Invoice in Foreign Currency
|
||||||
si = self.create_sales_invoice(qty=1, rate=1)
|
rate = 80
|
||||||
# Payment
|
rate_in_account_currency = 1
|
||||||
pe = self.create_payment_entry(amount=1, source_exc_rate=75).save()
|
|
||||||
|
si = self.create_sales_invoice(qty=1, rate=rate_in_account_currency)
|
||||||
|
|
||||||
|
# Test payments with different exchange rates
|
||||||
|
for exc_rate in [75.9, 83.1, 80.01]:
|
||||||
|
with self.subTest(exc_rate=exc_rate):
|
||||||
|
pe = self.create_payment_entry(amount=1, source_exc_rate=exc_rate).save()
|
||||||
pe.append(
|
pe.append(
|
||||||
"references",
|
"references",
|
||||||
{"reference_doctype": si.doctype, "reference_name": si.name, "allocated_amount": 1},
|
{"reference_doctype": si.doctype, "reference_name": si.name, "allocated_amount": 1},
|
||||||
)
|
)
|
||||||
pe = pe.save().submit()
|
pe = pe.save().submit()
|
||||||
|
|
||||||
|
# Outstanding in both currencies should be '0'
|
||||||
si.reload()
|
si.reload()
|
||||||
self.assertEqual(si.outstanding_amount, 0)
|
self.assertEqual(si.outstanding_amount, 0)
|
||||||
|
self.assert_ledger_outstanding(si.doctype, si.name, 0.0, 0.0)
|
||||||
|
|
||||||
# Exchange Gain/Loss Journal should've been created.
|
# Exchange Gain/Loss Journal should've been created.
|
||||||
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
||||||
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
|
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
|
||||||
|
|
||||||
self.assertNotEqual(exc_je_for_si, [])
|
self.assertNotEqual(exc_je_for_si, [])
|
||||||
self.assertEqual(len(exc_je_for_si), 1)
|
self.assertEqual(len(exc_je_for_si), 1)
|
||||||
self.assertEqual(len(exc_je_for_pe), 1)
|
self.assertEqual(len(exc_je_for_pe), 1)
|
||||||
@ -264,23 +316,26 @@ class TestAccountsController(unittest.TestCase):
|
|||||||
# Cancel Payment
|
# Cancel Payment
|
||||||
pe.cancel()
|
pe.cancel()
|
||||||
|
|
||||||
|
# outstanding should be same as grand total
|
||||||
si.reload()
|
si.reload()
|
||||||
self.assertEqual(si.outstanding_amount, 1)
|
self.assertEqual(si.outstanding_amount, rate_in_account_currency)
|
||||||
|
self.assert_ledger_outstanding(si.doctype, si.name, rate, rate_in_account_currency)
|
||||||
|
|
||||||
# Exchange Gain/Loss Journal should've been cancelled
|
# Exchange Gain/Loss Journal should've been cancelled
|
||||||
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
||||||
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
|
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
|
||||||
|
|
||||||
self.assertEqual(exc_je_for_si, [])
|
self.assertEqual(exc_je_for_si, [])
|
||||||
self.assertEqual(exc_je_for_pe, [])
|
self.assertEqual(exc_je_for_pe, [])
|
||||||
|
|
||||||
def test_02_advance_against_invoice(self):
|
def test_11_advance_against_sales_invoice(self):
|
||||||
# Advance Payment
|
# Advance Payment
|
||||||
adv = self.create_payment_entry(amount=1, source_exc_rate=85).save().submit()
|
adv = self.create_payment_entry(amount=1, source_exc_rate=85).save().submit()
|
||||||
adv.reload()
|
adv.reload()
|
||||||
|
|
||||||
# Invoice in Foreign Currency
|
# Sales Invoices in different exchange rates
|
||||||
si = self.create_sales_invoice(qty=1, rate=1, do_not_submit=True)
|
for exc_rate in [75.9, 83.1, 80.01]:
|
||||||
|
with self.subTest(exc_rate=exc_rate):
|
||||||
|
si = self.create_sales_invoice(qty=1, conversion_rate=exc_rate, rate=1, do_not_submit=True)
|
||||||
si.append(
|
si.append(
|
||||||
"advances",
|
"advances",
|
||||||
{
|
{
|
||||||
@ -296,13 +351,14 @@ class TestAccountsController(unittest.TestCase):
|
|||||||
si = si.save()
|
si = si.save()
|
||||||
si = si.submit()
|
si = si.submit()
|
||||||
|
|
||||||
|
# Outstanding in both currencies should be '0'
|
||||||
adv.reload()
|
adv.reload()
|
||||||
self.assertEqual(si.outstanding_amount, 0)
|
self.assertEqual(si.outstanding_amount, 0)
|
||||||
|
self.assert_ledger_outstanding(si.doctype, si.name, 0.0, 0.0)
|
||||||
|
|
||||||
# Exchange Gain/Loss Journal should've been created.
|
# Exchange Gain/Loss Journal should've been created.
|
||||||
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
||||||
exc_je_for_adv = self.get_journals_for(adv.doctype, adv.name)
|
exc_je_for_adv = self.get_journals_for(adv.doctype, adv.name)
|
||||||
|
|
||||||
self.assertNotEqual(exc_je_for_si, [])
|
self.assertNotEqual(exc_je_for_si, [])
|
||||||
self.assertEqual(len(exc_je_for_si), 1)
|
self.assertEqual(len(exc_je_for_si), 1)
|
||||||
self.assertEqual(len(exc_je_for_adv), 1)
|
self.assertEqual(len(exc_je_for_adv), 1)
|
||||||
@ -314,20 +370,23 @@ class TestAccountsController(unittest.TestCase):
|
|||||||
# Exchange Gain/Loss Journal should've been cancelled
|
# Exchange Gain/Loss Journal should've been cancelled
|
||||||
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
||||||
exc_je_for_adv = self.get_journals_for(adv.doctype, adv.name)
|
exc_je_for_adv = self.get_journals_for(adv.doctype, adv.name)
|
||||||
|
|
||||||
self.assertEqual(exc_je_for_si, [])
|
self.assertEqual(exc_je_for_si, [])
|
||||||
self.assertEqual(exc_je_for_adv, [])
|
self.assertEqual(exc_je_for_adv, [])
|
||||||
|
|
||||||
def test_03_partial_advance_and_payment_for_invoice(self):
|
def test_12_partial_advance_and_payment_for_sales_invoice(self):
|
||||||
"""
|
"""
|
||||||
Invoice with partial advance payment, and a normal payment
|
Sales invoice with partial advance payment, and a normal payment reconciled
|
||||||
"""
|
"""
|
||||||
# Partial Advance
|
# Partial Advance
|
||||||
adv = self.create_payment_entry(amount=1, source_exc_rate=85).save().submit()
|
adv = self.create_payment_entry(amount=1, source_exc_rate=85).save().submit()
|
||||||
adv.reload()
|
adv.reload()
|
||||||
|
|
||||||
# Invoice in Foreign Currency linked with advance
|
# sales invoice with advance(partial amount)
|
||||||
si = self.create_sales_invoice(qty=2, rate=1, do_not_submit=True)
|
rate = 80
|
||||||
|
rate_in_account_currency = 1
|
||||||
|
si = self.create_sales_invoice(
|
||||||
|
qty=2, conversion_rate=80, rate=rate_in_account_currency, do_not_submit=True
|
||||||
|
)
|
||||||
si.append(
|
si.append(
|
||||||
"advances",
|
"advances",
|
||||||
{
|
{
|
||||||
@ -343,19 +402,20 @@ class TestAccountsController(unittest.TestCase):
|
|||||||
si = si.save()
|
si = si.save()
|
||||||
si = si.submit()
|
si = si.submit()
|
||||||
|
|
||||||
|
# Outstanding should be there in both currencies
|
||||||
si.reload()
|
si.reload()
|
||||||
self.assertEqual(si.outstanding_amount, 1)
|
self.assertEqual(si.outstanding_amount, 1) # account currency
|
||||||
|
self.assert_ledger_outstanding(si.doctype, si.name, 80.0, 1.0)
|
||||||
|
|
||||||
# Exchange Gain/Loss Journal should've been created for the partial advance
|
# Exchange Gain/Loss Journal should've been created for the partial advance
|
||||||
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
||||||
exc_je_for_adv = self.get_journals_for(adv.doctype, adv.name)
|
exc_je_for_adv = self.get_journals_for(adv.doctype, adv.name)
|
||||||
|
|
||||||
self.assertNotEqual(exc_je_for_si, [])
|
self.assertNotEqual(exc_je_for_si, [])
|
||||||
self.assertEqual(len(exc_je_for_si), 1)
|
self.assertEqual(len(exc_je_for_si), 1)
|
||||||
self.assertEqual(len(exc_je_for_adv), 1)
|
self.assertEqual(len(exc_je_for_adv), 1)
|
||||||
self.assertEqual(exc_je_for_si, exc_je_for_adv)
|
self.assertEqual(exc_je_for_si, exc_je_for_adv)
|
||||||
|
|
||||||
# Payment
|
# Payment for remaining amount
|
||||||
pe = self.create_payment_entry(amount=1, source_exc_rate=75).save()
|
pe = self.create_payment_entry(amount=1, source_exc_rate=75).save()
|
||||||
pe.append(
|
pe.append(
|
||||||
"references",
|
"references",
|
||||||
@ -363,13 +423,14 @@ class TestAccountsController(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
pe = pe.save().submit()
|
pe = pe.save().submit()
|
||||||
|
|
||||||
|
# Outstanding in both currencies should be '0'
|
||||||
si.reload()
|
si.reload()
|
||||||
self.assertEqual(si.outstanding_amount, 0)
|
self.assertEqual(si.outstanding_amount, 0)
|
||||||
|
self.assert_ledger_outstanding(si.doctype, si.name, 0.0, 0.0)
|
||||||
|
|
||||||
# Exchange Gain/Loss Journal should've been created for the payment
|
# Exchange Gain/Loss Journal should've been created for the payment
|
||||||
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
||||||
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
|
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
|
||||||
|
|
||||||
self.assertNotEqual(exc_je_for_si, [])
|
self.assertNotEqual(exc_je_for_si, [])
|
||||||
# There should be 2 JE's now. One for the advance and one for the payment
|
# There should be 2 JE's now. One for the advance and one for the payment
|
||||||
self.assertEqual(len(exc_je_for_si), 2)
|
self.assertEqual(len(exc_je_for_si), 2)
|
||||||
@ -384,21 +445,20 @@ class TestAccountsController(unittest.TestCase):
|
|||||||
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
||||||
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
|
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
|
||||||
exc_je_for_adv = self.get_journals_for(adv.doctype, adv.name)
|
exc_je_for_adv = self.get_journals_for(adv.doctype, adv.name)
|
||||||
|
|
||||||
self.assertEqual(exc_je_for_si, [])
|
self.assertEqual(exc_je_for_si, [])
|
||||||
self.assertEqual(exc_je_for_pe, [])
|
self.assertEqual(exc_je_for_pe, [])
|
||||||
self.assertEqual(exc_je_for_adv, [])
|
self.assertEqual(exc_je_for_adv, [])
|
||||||
|
|
||||||
def test_04_partial_advance_and_payment_for_invoice_with_cancellation(self):
|
def test_13_partial_advance_and_payment_for_invoice_with_cancellation(self):
|
||||||
"""
|
"""
|
||||||
Invoice with partial advance payment, and a normal payment. Cancel advance and payment.
|
Invoice with partial advance payment, and a normal payment. Then cancel advance and payment.
|
||||||
"""
|
"""
|
||||||
# Partial Advance
|
# Partial Advance
|
||||||
adv = self.create_payment_entry(amount=1, source_exc_rate=85).save().submit()
|
adv = self.create_payment_entry(amount=1, source_exc_rate=85).save().submit()
|
||||||
adv.reload()
|
adv.reload()
|
||||||
|
|
||||||
# Invoice in Foreign Currency linked with advance
|
# invoice with advance(partial amount)
|
||||||
si = self.create_sales_invoice(qty=2, rate=1, do_not_submit=True)
|
si = self.create_sales_invoice(qty=2, conversion_rate=80, rate=1, do_not_submit=True)
|
||||||
si.append(
|
si.append(
|
||||||
"advances",
|
"advances",
|
||||||
{
|
{
|
||||||
@ -414,19 +474,20 @@ class TestAccountsController(unittest.TestCase):
|
|||||||
si = si.save()
|
si = si.save()
|
||||||
si = si.submit()
|
si = si.submit()
|
||||||
|
|
||||||
|
# Outstanding should be there in both currencies
|
||||||
si.reload()
|
si.reload()
|
||||||
self.assertEqual(si.outstanding_amount, 1)
|
self.assertEqual(si.outstanding_amount, 1) # account currency
|
||||||
|
self.assert_ledger_outstanding(si.doctype, si.name, 80.0, 1.0)
|
||||||
|
|
||||||
# Exchange Gain/Loss Journal should've been created for the partial advance
|
# Exchange Gain/Loss Journal should've been created for the partial advance
|
||||||
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
||||||
exc_je_for_adv = self.get_journals_for(adv.doctype, adv.name)
|
exc_je_for_adv = self.get_journals_for(adv.doctype, adv.name)
|
||||||
|
|
||||||
self.assertNotEqual(exc_je_for_si, [])
|
self.assertNotEqual(exc_je_for_si, [])
|
||||||
self.assertEqual(len(exc_je_for_si), 1)
|
self.assertEqual(len(exc_je_for_si), 1)
|
||||||
self.assertEqual(len(exc_je_for_adv), 1)
|
self.assertEqual(len(exc_je_for_adv), 1)
|
||||||
self.assertEqual(exc_je_for_si, exc_je_for_adv)
|
self.assertEqual(exc_je_for_si, exc_je_for_adv)
|
||||||
|
|
||||||
# Payment
|
# Payment(remaining amount)
|
||||||
pe = self.create_payment_entry(amount=1, source_exc_rate=75).save()
|
pe = self.create_payment_entry(amount=1, source_exc_rate=75).save()
|
||||||
pe.append(
|
pe.append(
|
||||||
"references",
|
"references",
|
||||||
@ -434,13 +495,14 @@ class TestAccountsController(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
pe = pe.save().submit()
|
pe = pe.save().submit()
|
||||||
|
|
||||||
|
# Outstanding should be '0' in both currencies
|
||||||
si.reload()
|
si.reload()
|
||||||
self.assertEqual(si.outstanding_amount, 0)
|
self.assertEqual(si.outstanding_amount, 0)
|
||||||
|
self.assert_ledger_outstanding(si.doctype, si.name, 0.0, 0.0)
|
||||||
|
|
||||||
# Exchange Gain/Loss Journal should've been created for the payment
|
# Exchange Gain/Loss Journal should've been created for the payment
|
||||||
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
||||||
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
|
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
|
||||||
|
|
||||||
self.assertNotEqual(exc_je_for_si, [])
|
self.assertNotEqual(exc_je_for_si, [])
|
||||||
# There should be 2 JE's now. One for the advance and one for the payment
|
# There should be 2 JE's now. One for the advance and one for the payment
|
||||||
self.assertEqual(len(exc_je_for_si), 2)
|
self.assertEqual(len(exc_je_for_si), 2)
|
||||||
@ -450,21 +512,22 @@ class TestAccountsController(unittest.TestCase):
|
|||||||
adv.reload()
|
adv.reload()
|
||||||
adv.cancel()
|
adv.cancel()
|
||||||
|
|
||||||
|
# Outstanding should be there in both currencies, since advance is cancelled.
|
||||||
si.reload()
|
si.reload()
|
||||||
self.assertEqual(si.outstanding_amount, 1)
|
self.assertEqual(si.outstanding_amount, 1) # account currency
|
||||||
|
self.assert_ledger_outstanding(si.doctype, si.name, 80.0, 1.0)
|
||||||
|
|
||||||
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
||||||
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
|
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
|
||||||
exc_je_for_adv = self.get_journals_for(adv.doctype, adv.name)
|
exc_je_for_adv = self.get_journals_for(adv.doctype, adv.name)
|
||||||
|
|
||||||
# Exchange Gain/Loss Journal for advance should been cancelled
|
# Exchange Gain/Loss Journal for advance should been cancelled
|
||||||
self.assertEqual(len(exc_je_for_si), 1)
|
self.assertEqual(len(exc_je_for_si), 1)
|
||||||
self.assertEqual(len(exc_je_for_pe), 1)
|
self.assertEqual(len(exc_je_for_pe), 1)
|
||||||
self.assertEqual(exc_je_for_adv, [])
|
self.assertEqual(exc_je_for_adv, [])
|
||||||
|
|
||||||
def test_05_same_payment_split_against_invoice(self):
|
def test_14_same_payment_split_against_invoice(self):
|
||||||
# Invoice in Foreign Currency
|
# Invoice in Foreign Currency
|
||||||
si = self.create_sales_invoice(qty=2, rate=1)
|
si = self.create_sales_invoice(qty=2, conversion_rate=80, rate=1)
|
||||||
# Payment
|
# Payment
|
||||||
pe = self.create_payment_entry(amount=2, source_exc_rate=75).save()
|
pe = self.create_payment_entry(amount=2, source_exc_rate=75).save()
|
||||||
pe.append(
|
pe.append(
|
||||||
@ -473,13 +536,14 @@ class TestAccountsController(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
pe = pe.save().submit()
|
pe = pe.save().submit()
|
||||||
|
|
||||||
|
# There should be outstanding in both currencies
|
||||||
si.reload()
|
si.reload()
|
||||||
self.assertEqual(si.outstanding_amount, 1)
|
self.assertEqual(si.outstanding_amount, 1)
|
||||||
|
self.assert_ledger_outstanding(si.doctype, si.name, 80.0, 1.0)
|
||||||
|
|
||||||
# Exchange Gain/Loss Journal should've been created.
|
# Exchange Gain/Loss Journal should've been created.
|
||||||
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
||||||
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
|
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
|
||||||
|
|
||||||
self.assertNotEqual(exc_je_for_si, [])
|
self.assertNotEqual(exc_je_for_si, [])
|
||||||
self.assertEqual(len(exc_je_for_si), 1)
|
self.assertEqual(len(exc_je_for_si), 1)
|
||||||
self.assertEqual(len(exc_je_for_pe), 1)
|
self.assertEqual(len(exc_je_for_pe), 1)
|
||||||
@ -491,32 +555,35 @@ class TestAccountsController(unittest.TestCase):
|
|||||||
pr.party_type = "Customer"
|
pr.party_type = "Customer"
|
||||||
pr.party = self.customer
|
pr.party = self.customer
|
||||||
pr.receivable_payable_account = self.debit_usd
|
pr.receivable_payable_account = self.debit_usd
|
||||||
|
|
||||||
pr.get_unreconciled_entries()
|
pr.get_unreconciled_entries()
|
||||||
self.assertEqual(len(pr.invoices), 1)
|
self.assertEqual(len(pr.invoices), 1)
|
||||||
self.assertEqual(len(pr.payments), 1)
|
self.assertEqual(len(pr.payments), 1)
|
||||||
|
|
||||||
# Test exact payment allocation
|
|
||||||
invoices = [x.as_dict() for x in pr.invoices]
|
invoices = [x.as_dict() for x in pr.invoices]
|
||||||
payments = [x.as_dict() for x in pr.payments]
|
payments = [x.as_dict() for x in pr.payments]
|
||||||
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
|
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
|
||||||
|
|
||||||
pr.reconcile()
|
pr.reconcile()
|
||||||
self.assertEqual(len(pr.invoices), 0)
|
self.assertEqual(len(pr.invoices), 0)
|
||||||
self.assertEqual(len(pr.payments), 0)
|
self.assertEqual(len(pr.payments), 0)
|
||||||
|
|
||||||
|
# Exc gain/loss journal should have been creaetd for the reconciled amount
|
||||||
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
||||||
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
|
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
|
||||||
self.assertEqual(len(exc_je_for_si), 2)
|
self.assertEqual(len(exc_je_for_si), 2)
|
||||||
self.assertEqual(len(exc_je_for_pe), 2)
|
self.assertEqual(len(exc_je_for_pe), 2)
|
||||||
self.assertEqual(exc_je_for_si, exc_je_for_pe)
|
self.assertEqual(exc_je_for_si, exc_je_for_pe)
|
||||||
|
|
||||||
|
# There should be no outstanding
|
||||||
|
si.reload()
|
||||||
|
self.assertEqual(si.outstanding_amount, 0)
|
||||||
|
self.assert_ledger_outstanding(si.doctype, si.name, 0.0, 0.0)
|
||||||
|
|
||||||
# Cancel Payment
|
# Cancel Payment
|
||||||
pe.reload()
|
pe.reload()
|
||||||
pe.cancel()
|
pe.cancel()
|
||||||
|
|
||||||
si.reload()
|
si.reload()
|
||||||
self.assertEqual(si.outstanding_amount, 2)
|
self.assertEqual(si.outstanding_amount, 2)
|
||||||
|
self.assert_ledger_outstanding(si.doctype, si.name, 160.0, 2.0)
|
||||||
|
|
||||||
# Exchange Gain/Loss Journal should've been cancelled
|
# Exchange Gain/Loss Journal should've been cancelled
|
||||||
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user