Skip to content

Commit

Permalink
feat: Make Tax loss booking optional
Browse files Browse the repository at this point in the history
- Checkbox in Accounts Settings
- Apply checkbox in PE deductions setting logic
- Adjust tests
  • Loading branch information
marination committed Mar 27, 2023
1 parent c5da7f5 commit 216a46b
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"determine_address_tax_category_from",
"column_break_19",
"add_taxes_from_item_tax_template",
"book_tax_discount_loss",
"print_settings",
"show_inclusive_tax_in_print",
"column_break_12",
Expand Down Expand Up @@ -360,14 +361,21 @@
"fieldname": "show_balance_in_coa",
"fieldtype": "Check",
"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",
"idx": 1,
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2023-01-02 12:07:42.434214",
"modified": "2023-03-28 09:50:20.375233",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",
Expand Down
17 changes: 13 additions & 4 deletions erpnext/accounts/doctype/payment_entry/payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -1824,7 +1824,10 @@ def get_payment_entry(
pe.set_amounts()

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(
pe, doc, discount_amount, base_total_discount_loss, party_account_currency
)
Expand Down Expand Up @@ -1991,19 +1994,25 @@ def set_pending_discount_loss(
# Avoid considering miniscule losses
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:
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(
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"),
"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."""
total_discount_percent = get_total_discount_percent(doc, valid_discounts)

Expand Down
34 changes: 25 additions & 9 deletions erpnext/accounts/doctype/payment_entry/test_payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,17 +256,24 @@ def test_payment_entry_against_payment_terms_with_discount(self):
},
)
si.save()

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")

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.paid_amount, 212.4)
self.assertEqual(pe.deductions[0].amount, 20.0) # Loss on Income
self.assertEqual(pe.deductions[1].amount, 3.6) # Loss on Tax
self.assertEqual(pe.deductions[1].account, "_Test Account Service Tax - _TC")
self.assertEqual(pe.deductions[0].amount, 23.6)

pe.submit()
si.load_from_db()
Expand Down Expand Up @@ -311,12 +318,18 @@ def test_payment_entry_against_payment_terms_with_discount_amount(self):
)
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")
self.assertEqual(pe.references[0].allocated_amount, 236.0)
self.assertEqual(pe.paid_amount, 186)
self.assertEqual(pe.deductions[0].amount, 42.37) # Loss on Income
self.assertEqual(pe.deductions[1].amount, 7.63) # Loss on Tax
self.assertEqual(pe.deductions[1].account, "_Test Account Service Tax - _TC")
self.assertEqual(pe.deductions[0].amount, 50.0)

pe.submit()
si.load_from_db()
Expand All @@ -328,7 +341,10 @@ def test_payment_entry_against_payment_terms_with_discount_amount(self):

@change_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(
self,
Expand Down

0 comments on commit 216a46b

Please sign in to comment.