mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-02 11:49:10 +00:00
feat: Make Tax loss booking optional
- Checkbox in Accounts Settings - Apply checkbox in PE deductions setting logic - Adjust tests
This commit is contained in:
@@ -31,6 +31,7 @@
|
|||||||
"determine_address_tax_category_from",
|
"determine_address_tax_category_from",
|
||||||
"column_break_19",
|
"column_break_19",
|
||||||
"add_taxes_from_item_tax_template",
|
"add_taxes_from_item_tax_template",
|
||||||
|
"book_tax_discount_loss",
|
||||||
"print_settings",
|
"print_settings",
|
||||||
"show_inclusive_tax_in_print",
|
"show_inclusive_tax_in_print",
|
||||||
"column_break_12",
|
"column_break_12",
|
||||||
@@ -360,6 +361,13 @@
|
|||||||
"fieldname": "show_balance_in_coa",
|
"fieldname": "show_balance_in_coa",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Show Balances in Chart Of Accounts"
|
"label": "Show Balances in Chart Of Accounts"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"description": "Split Early Payment Discount Loss into Income and Tax Loss",
|
||||||
|
"fieldname": "book_tax_discount_loss",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Book Tax Loss on Early Payment Discount"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "icon-cog",
|
"icon": "icon-cog",
|
||||||
@@ -367,7 +375,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-01-02 12:07:42.434214",
|
"modified": "2023-03-28 09:50:20.375233",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounts Settings",
|
"name": "Accounts Settings",
|
||||||
|
|||||||
@@ -1824,7 +1824,10 @@ def get_payment_entry(
|
|||||||
pe.set_amounts()
|
pe.set_amounts()
|
||||||
|
|
||||||
if discount_amount:
|
if discount_amount:
|
||||||
base_total_discount_loss = set_early_payment_discount_loss(pe, doc, valid_discounts)
|
base_total_discount_loss = 0
|
||||||
|
if frappe.db.get_single_value("Accounts Settings", "book_tax_discount_loss"):
|
||||||
|
base_total_discount_loss = split_early_payment_discount_loss(pe, doc, valid_discounts)
|
||||||
|
|
||||||
set_pending_discount_loss(
|
set_pending_discount_loss(
|
||||||
pe, doc, discount_amount, base_total_discount_loss, party_account_currency
|
pe, doc, discount_amount, base_total_discount_loss, party_account_currency
|
||||||
)
|
)
|
||||||
@@ -1991,19 +1994,25 @@ def set_pending_discount_loss(
|
|||||||
# Avoid considering miniscule losses
|
# Avoid considering miniscule losses
|
||||||
discount_amount = flt(discount_amount - base_total_discount_loss, doc.precision("grand_total"))
|
discount_amount = flt(discount_amount - base_total_discount_loss, doc.precision("grand_total"))
|
||||||
|
|
||||||
# If pending base discount amount (mostly rounding loss), set it in deductions
|
# Set base discount amount (discount loss/pending rounding loss) in deductions
|
||||||
if discount_amount > 0.0:
|
if discount_amount > 0.0:
|
||||||
positive_negative = -1 if pe.payment_type == "Pay" else 1
|
positive_negative = -1 if pe.payment_type == "Pay" else 1
|
||||||
|
|
||||||
|
# If tax loss booking is enabled, pending loss will be rounding loss.
|
||||||
|
# Otherwise it will be the total discount loss.
|
||||||
|
book_tax_loss = frappe.db.get_single_value("Accounts Settings", "book_tax_discount_loss")
|
||||||
|
account_type = "round_off_account" if book_tax_loss else "default_discount_account"
|
||||||
|
|
||||||
pe.set_gain_or_loss(
|
pe.set_gain_or_loss(
|
||||||
account_details={
|
account_details={
|
||||||
"account": frappe.get_cached_value("Company", pe.company, "round_off_account"),
|
"account": frappe.get_cached_value("Company", pe.company, account_type),
|
||||||
"cost_center": pe.cost_center or frappe.get_cached_value("Company", pe.company, "cost_center"),
|
"cost_center": pe.cost_center or frappe.get_cached_value("Company", pe.company, "cost_center"),
|
||||||
"amount": discount_amount * positive_negative,
|
"amount": discount_amount * positive_negative,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def set_early_payment_discount_loss(pe, doc, valid_discounts) -> float:
|
def split_early_payment_discount_loss(pe, doc, valid_discounts) -> float:
|
||||||
"""Split early payment discount into Income Loss & Tax Loss."""
|
"""Split early payment discount into Income Loss & Tax Loss."""
|
||||||
total_discount_percent = get_total_discount_percent(doc, valid_discounts)
|
total_discount_percent = get_total_discount_percent(doc, valid_discounts)
|
||||||
|
|
||||||
|
|||||||
@@ -256,17 +256,24 @@ class TestPaymentEntry(FrappeTestCase):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
si.save()
|
si.save()
|
||||||
|
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
|
frappe.db.set_single_value("Accounts Settings", "book_tax_discount_loss", 1)
|
||||||
|
pe_with_tax_loss = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC")
|
||||||
|
|
||||||
|
self.assertEqual(pe_with_tax_loss.references[0].payment_term, "30 Credit Days with 10% Discount")
|
||||||
|
self.assertEqual(pe_with_tax_loss.references[0].allocated_amount, 236.0)
|
||||||
|
self.assertEqual(pe_with_tax_loss.paid_amount, 212.4)
|
||||||
|
self.assertEqual(pe_with_tax_loss.deductions[0].amount, 20.0) # Loss on Income
|
||||||
|
self.assertEqual(pe_with_tax_loss.deductions[1].amount, 3.6) # Loss on Tax
|
||||||
|
self.assertEqual(pe_with_tax_loss.deductions[1].account, "_Test Account Service Tax - _TC")
|
||||||
|
|
||||||
|
frappe.db.set_single_value("Accounts Settings", "book_tax_discount_loss", 0)
|
||||||
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC")
|
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC")
|
||||||
|
|
||||||
self.assertEqual(pe.references[0].payment_term, "30 Credit Days with 10% Discount")
|
|
||||||
self.assertEqual(pe.references[0].allocated_amount, 236.0)
|
self.assertEqual(pe.references[0].allocated_amount, 236.0)
|
||||||
self.assertEqual(pe.paid_amount, 212.4)
|
self.assertEqual(pe.paid_amount, 212.4)
|
||||||
self.assertEqual(pe.deductions[0].amount, 20.0) # Loss on Income
|
self.assertEqual(pe.deductions[0].amount, 23.6)
|
||||||
self.assertEqual(pe.deductions[1].amount, 3.6) # Loss on Tax
|
|
||||||
self.assertEqual(pe.deductions[1].account, "_Test Account Service Tax - _TC")
|
|
||||||
|
|
||||||
pe.submit()
|
pe.submit()
|
||||||
si.load_from_db()
|
si.load_from_db()
|
||||||
@@ -311,12 +318,18 @@ class TestPaymentEntry(FrappeTestCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(pe_1.paid_amount, 236.0) # discount not applied
|
self.assertEqual(pe_1.paid_amount, 236.0) # discount not applied
|
||||||
|
|
||||||
|
# Test if tax loss is booked on enabling configuration
|
||||||
|
frappe.db.set_single_value("Accounts Settings", "book_tax_discount_loss", 1)
|
||||||
|
pe_with_tax_loss = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC")
|
||||||
|
self.assertEqual(pe_with_tax_loss.deductions[0].amount, 42.37) # Loss on Income
|
||||||
|
self.assertEqual(pe_with_tax_loss.deductions[1].amount, 7.63) # Loss on Tax
|
||||||
|
self.assertEqual(pe_with_tax_loss.deductions[1].account, "_Test Account Service Tax - _TC")
|
||||||
|
|
||||||
|
frappe.db.set_single_value("Accounts Settings", "book_tax_discount_loss", 0)
|
||||||
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC")
|
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC")
|
||||||
self.assertEqual(pe.references[0].allocated_amount, 236.0)
|
self.assertEqual(pe.references[0].allocated_amount, 236.0)
|
||||||
self.assertEqual(pe.paid_amount, 186)
|
self.assertEqual(pe.paid_amount, 186)
|
||||||
self.assertEqual(pe.deductions[0].amount, 42.37) # Loss on Income
|
self.assertEqual(pe.deductions[0].amount, 50.0)
|
||||||
self.assertEqual(pe.deductions[1].amount, 7.63) # Loss on Tax
|
|
||||||
self.assertEqual(pe.deductions[1].account, "_Test Account Service Tax - _TC")
|
|
||||||
|
|
||||||
pe.submit()
|
pe.submit()
|
||||||
si.load_from_db()
|
si.load_from_db()
|
||||||
@@ -328,7 +341,10 @@ class TestPaymentEntry(FrappeTestCase):
|
|||||||
|
|
||||||
@change_settings(
|
@change_settings(
|
||||||
"Accounts Settings",
|
"Accounts Settings",
|
||||||
{"allow_multi_currency_invoices_against_single_party_account": 1},
|
{
|
||||||
|
"allow_multi_currency_invoices_against_single_party_account": 1,
|
||||||
|
"book_tax_discount_loss": 1,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
def test_payment_entry_multicurrency_si_with_base_currency_accounting_early_payment_discount(
|
def test_payment_entry_multicurrency_si_with_base_currency_accounting_early_payment_discount(
|
||||||
self,
|
self,
|
||||||
|
|||||||
Reference in New Issue
Block a user