mirror of
https://github.com/frappe/erpnext.git
synced 2026-09-17 18:45:20 +00:00
chore: resolve conflict
This commit is contained in:
@@ -7,13 +7,8 @@ from frappe import _, qb
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.model.meta import get_field_precision
|
from frappe.model.meta import get_field_precision
|
||||||
from frappe.query_builder import Criterion, Order
|
from frappe.query_builder import Criterion, Order
|
||||||
<<<<<<< HEAD
|
|
||||||
from frappe.query_builder.functions import NullIf, Sum
|
from frappe.query_builder.functions import NullIf, Sum
|
||||||
from frappe.utils import flt, get_link_to_form
|
|
||||||
=======
|
|
||||||
from frappe.query_builder.functions import Max, NullIf, Sum
|
|
||||||
from frappe.utils import flt, get_link_to_form, nowdate
|
from frappe.utils import flt, get_link_to_form, nowdate
|
||||||
>>>>>>> a0b14c0607 (refactor: reversal capability on exchange rate revaluation)
|
|
||||||
|
|
||||||
import erpnext
|
import erpnext
|
||||||
from erpnext.accounts.doctype.journal_entry.journal_entry import get_balance_on
|
from erpnext.accounts.doctype.journal_entry.journal_entry import get_balance_on
|
||||||
@@ -619,7 +614,7 @@ class ExchangeRateRevaluation(Document):
|
|||||||
.run(pluck="name")
|
.run(pluck="name")
|
||||||
)
|
)
|
||||||
if journals:
|
if journals:
|
||||||
from erpnext.accounts.doctype.journal_entry.mapper import make_reverse_journal_entry
|
from erpnext.accounts.doctype.journal_entry.journal_entry import make_reverse_journal_entry
|
||||||
|
|
||||||
for x in journals:
|
for x in journals:
|
||||||
reversal = make_reverse_journal_entry(x)
|
reversal = make_reverse_journal_entry(x)
|
||||||
|
|||||||
@@ -300,148 +300,3 @@ class TestExchangeRateRevaluation(ERPNextTestSuite, AccountsTestMixin):
|
|||||||
|
|
||||||
for key, _val in expected_data.items():
|
for key, _val in expected_data.items():
|
||||||
self.assertEqual(expected_data.get(key), account_details.get(key))
|
self.assertEqual(expected_data.get(key), account_details.get(key))
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
|
|
||||||
@ERPNextTestSuite.change_settings(
|
|
||||||
"Accounts Settings",
|
|
||||||
{"allow_multi_currency_invoices_against_single_party_account": 1, "allow_stale": 0},
|
|
||||||
)
|
|
||||||
def test_05_revaluation_journal_reversal(self):
|
|
||||||
"""
|
|
||||||
Test reversing of revaluation journals
|
|
||||||
"""
|
|
||||||
si = create_sales_invoice(
|
|
||||||
item=self.item,
|
|
||||||
company=self.company,
|
|
||||||
customer=self.customer,
|
|
||||||
debit_to=self.debtors_usd,
|
|
||||||
posting_date=today(),
|
|
||||||
parent_cost_center=self.cost_center,
|
|
||||||
cost_center=self.cost_center,
|
|
||||||
rate=100,
|
|
||||||
price_list_rate=100,
|
|
||||||
do_not_submit=1,
|
|
||||||
)
|
|
||||||
si.currency = "USD"
|
|
||||||
si.conversion_rate = 80
|
|
||||||
si.save().submit()
|
|
||||||
|
|
||||||
err = frappe.new_doc("Exchange Rate Revaluation")
|
|
||||||
err.company = self.company
|
|
||||||
err.posting_date = today()
|
|
||||||
err.fetch_and_calculate_accounts_data()
|
|
||||||
self.assertEqual(len(err.accounts), 1)
|
|
||||||
err.save().submit()
|
|
||||||
|
|
||||||
gain_loss_account = err.get_for_unrealized_gain_loss_account()
|
|
||||||
usd_account = err.accounts[0].account
|
|
||||||
old_balance = err.accounts[0].balance_in_base_currency
|
|
||||||
new_balance = err.accounts[0].new_balance_in_base_currency
|
|
||||||
total_gain_loss = err.total_gain_loss
|
|
||||||
|
|
||||||
# Create JV for ERR
|
|
||||||
ret = err.check_journal_and_reversal()
|
|
||||||
self.assertFalse(ret.get("journals_posted"))
|
|
||||||
err_journals = err.make_jv_entries()
|
|
||||||
je = frappe.get_doc("Journal Entry", err_journals.get("revaluation_jv"))
|
|
||||||
je = je.submit()
|
|
||||||
|
|
||||||
je.reload()
|
|
||||||
self.assertEqual(je.voucher_type, "Exchange Rate Revaluation")
|
|
||||||
self.assertEqual(len(je.accounts), 3)
|
|
||||||
expected = [
|
|
||||||
(usd_account, new_balance, 0.0, 100.0, 0.0),
|
|
||||||
(usd_account, 0.0, old_balance, 0.0, 100.0),
|
|
||||||
(gain_loss_account, 0.0, total_gain_loss, 0.0, total_gain_loss),
|
|
||||||
]
|
|
||||||
actual = []
|
|
||||||
for acc in je.accounts:
|
|
||||||
actual.append(
|
|
||||||
(
|
|
||||||
acc.account,
|
|
||||||
acc.debit,
|
|
||||||
acc.credit,
|
|
||||||
acc.debit_in_account_currency,
|
|
||||||
acc.credit_in_account_currency,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self.assertEqual(expected, actual)
|
|
||||||
|
|
||||||
# Assert reversals are not posted
|
|
||||||
ret = err.check_journal_and_reversal()
|
|
||||||
self.assertTrue(ret.get("journals_posted"))
|
|
||||||
self.assertFalse(ret.get("reversals_posted"))
|
|
||||||
|
|
||||||
err.make_reverse_journal()
|
|
||||||
ret = err.check_journal_and_reversal()
|
|
||||||
self.assertTrue(ret.get("journals_posted"))
|
|
||||||
self.assertTrue(ret.get("reversals_posted"))
|
|
||||||
|
|
||||||
reverse_jv = frappe.db.get_all(
|
|
||||||
"Journal Entry", filters={"reversal_of": err_journals.get("revaluation_jv")}, pluck="name"
|
|
||||||
)
|
|
||||||
self.assertIsNotNone(reverse_jv)
|
|
||||||
|
|
||||||
|
|
||||||
class TestExchangeRateRevaluationValidation(ERPNextTestSuite):
|
|
||||||
"""Validation and gain/loss calculation paths, exercised on the document directly
|
|
||||||
so they don't need the multi-currency GL setup the integration tests above build."""
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
frappe.set_user("Administrator")
|
|
||||||
self.company = "_Test Company"
|
|
||||||
|
|
||||||
def _revaluation_with_rows(self, rows, rounding_loss_allowance=0.05):
|
|
||||||
doc = frappe.new_doc("Exchange Rate Revaluation")
|
|
||||||
doc.company = self.company
|
|
||||||
doc.posting_date = today()
|
|
||||||
doc.rounding_loss_allowance = rounding_loss_allowance
|
|
||||||
for row in rows:
|
|
||||||
doc.append("accounts", row)
|
|
||||||
return doc
|
|
||||||
|
|
||||||
def test_rounding_loss_allowance_must_be_between_0_and_1(self):
|
|
||||||
for bad in (-0.1, 1, 1.5):
|
|
||||||
doc = self._revaluation_with_rows([], rounding_loss_allowance=bad)
|
|
||||||
self.assertRaises(frappe.ValidationError, doc.validate)
|
|
||||||
# values inside [0, 1) are accepted, at the lower bound and mid-range
|
|
||||||
for good in (0.0, 0.5):
|
|
||||||
self._revaluation_with_rows([], rounding_loss_allowance=good).validate()
|
|
||||||
|
|
||||||
def test_gain_loss_computed_and_split_by_zero_balance(self):
|
|
||||||
doc = self._revaluation_with_rows(
|
|
||||||
[
|
|
||||||
# open (unbooked) row: base balance moved 1000 -> 1100, a 100 gain
|
|
||||||
{"zero_balance": 0, "balance_in_base_currency": 1000, "new_balance_in_base_currency": 1100},
|
|
||||||
# already-settled (zero_balance) row carries a booked loss of 40
|
|
||||||
{"zero_balance": 1, "gain_loss": -40},
|
|
||||||
]
|
|
||||||
)
|
|
||||||
doc.validate()
|
|
||||||
|
|
||||||
# gain_loss is derived only for open rows; the zero-balance row keeps its value
|
|
||||||
self.assertEqual(doc.accounts[0].gain_loss, 100)
|
|
||||||
self.assertEqual(doc.gain_loss_unbooked, 100)
|
|
||||||
self.assertEqual(doc.gain_loss_booked, -40)
|
|
||||||
self.assertEqual(doc.total_gain_loss, 60)
|
|
||||||
|
|
||||||
def test_before_submit_drops_rows_without_gain_loss(self):
|
|
||||||
doc = self._revaluation_with_rows(
|
|
||||||
[
|
|
||||||
{"zero_balance": 0, "balance_in_base_currency": 1000, "new_balance_in_base_currency": 1100},
|
|
||||||
{"zero_balance": 0, "balance_in_base_currency": 500, "new_balance_in_base_currency": 500},
|
|
||||||
]
|
|
||||||
)
|
|
||||||
doc.validate() # second row nets to a 0 gain_loss
|
|
||||||
doc.remove_accounts_without_gain_loss()
|
|
||||||
self.assertEqual(len(doc.accounts), 1)
|
|
||||||
self.assertEqual(doc.accounts[0].gain_loss, 100)
|
|
||||||
|
|
||||||
def test_before_submit_requires_at_least_one_gain_loss_row(self):
|
|
||||||
doc = self._revaluation_with_rows(
|
|
||||||
[{"zero_balance": 0, "balance_in_base_currency": 500, "new_balance_in_base_currency": 500}]
|
|
||||||
)
|
|
||||||
doc.validate()
|
|
||||||
self.assertRaises(frappe.ValidationError, doc.remove_accounts_without_gain_loss)
|
|
||||||
>>>>>>> 65775e59a1 (refactor(test): for reverse journals as well)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user