fix: Tax withholding post LDC limit consumed (#36611)
* fix: Tax withholding post LDC limit consumed * fix: LDC condition check
This commit is contained in:
parent
12a6f3b997
commit
985ff9781b
@ -262,14 +262,20 @@ def get_tax_amount(party_type, parties, inv, tax_details, posting_date, pan_no=N
|
||||
if tax_deducted:
|
||||
net_total = inv.tax_withholding_net_total
|
||||
if ldc:
|
||||
tax_amount = get_tds_amount_from_ldc(ldc, parties, tax_details, posting_date, net_total)
|
||||
limit_consumed = get_limit_consumed(ldc, parties)
|
||||
if is_valid_certificate(ldc, posting_date, limit_consumed):
|
||||
tax_amount = get_lower_deduction_amount(
|
||||
net_total, limit_consumed, ldc.certificate_limit, ldc.rate, tax_details
|
||||
)
|
||||
else:
|
||||
tax_amount = net_total * tax_details.rate / 100 if net_total > 0 else 0
|
||||
else:
|
||||
tax_amount = net_total * tax_details.rate / 100 if net_total > 0 else 0
|
||||
|
||||
# once tds is deducted, not need to add vouchers in the invoice
|
||||
voucher_wise_amount = {}
|
||||
else:
|
||||
tax_amount = get_tds_amount(ldc, parties, inv, tax_details, tax_deducted, vouchers)
|
||||
tax_amount = get_tds_amount(ldc, parties, inv, tax_details, vouchers)
|
||||
|
||||
elif party_type == "Customer":
|
||||
if tax_deducted:
|
||||
@ -416,7 +422,7 @@ def get_deducted_tax(taxable_vouchers, tax_details):
|
||||
return sum(entries)
|
||||
|
||||
|
||||
def get_tds_amount(ldc, parties, inv, tax_details, tax_deducted, vouchers):
|
||||
def get_tds_amount(ldc, parties, inv, tax_details, vouchers):
|
||||
tds_amount = 0
|
||||
invoice_filters = {"name": ("in", vouchers), "docstatus": 1, "apply_tds": 1}
|
||||
|
||||
@ -496,15 +502,10 @@ def get_tds_amount(ldc, parties, inv, tax_details, tax_deducted, vouchers):
|
||||
net_total += inv.tax_withholding_net_total
|
||||
supp_credit_amt = net_total - cumulative_threshold
|
||||
|
||||
if ldc and is_valid_certificate(
|
||||
ldc.valid_from,
|
||||
ldc.valid_upto,
|
||||
inv.get("posting_date") or inv.get("transaction_date"),
|
||||
tax_deducted,
|
||||
inv.tax_withholding_net_total,
|
||||
ldc.certificate_limit,
|
||||
):
|
||||
tds_amount = get_ltds_amount(supp_credit_amt, 0, ldc.certificate_limit, ldc.rate, tax_details)
|
||||
if ldc and is_valid_certificate(ldc, inv.get("posting_date") or inv.get("transaction_date"), 0):
|
||||
tds_amount = get_lower_deduction_amount(
|
||||
supp_credit_amt, 0, ldc.certificate_limit, ldc.rate, tax_details
|
||||
)
|
||||
else:
|
||||
tds_amount = supp_credit_amt * tax_details.rate / 100 if supp_credit_amt > 0 else 0
|
||||
|
||||
@ -582,8 +583,7 @@ def get_invoice_total_without_tcs(inv, tax_details):
|
||||
return inv.grand_total - tcs_tax_row_amount
|
||||
|
||||
|
||||
def get_tds_amount_from_ldc(ldc, parties, tax_details, posting_date, net_total):
|
||||
tds_amount = 0
|
||||
def get_limit_consumed(ldc, parties):
|
||||
limit_consumed = frappe.db.get_value(
|
||||
"Purchase Invoice",
|
||||
{
|
||||
@ -597,37 +597,29 @@ def get_tds_amount_from_ldc(ldc, parties, tax_details, posting_date, net_total):
|
||||
"sum(tax_withholding_net_total)",
|
||||
)
|
||||
|
||||
if is_valid_certificate(
|
||||
ldc.valid_from, ldc.valid_upto, posting_date, limit_consumed, net_total, ldc.certificate_limit
|
||||
):
|
||||
tds_amount = get_ltds_amount(
|
||||
net_total, limit_consumed, ldc.certificate_limit, ldc.rate, tax_details
|
||||
)
|
||||
|
||||
return tds_amount
|
||||
return limit_consumed
|
||||
|
||||
|
||||
def get_ltds_amount(current_amount, deducted_amount, certificate_limit, rate, tax_details):
|
||||
if certificate_limit - flt(deducted_amount) - flt(current_amount) >= 0:
|
||||
def get_lower_deduction_amount(
|
||||
current_amount, limit_consumed, certificate_limit, rate, tax_details
|
||||
):
|
||||
if certificate_limit - flt(limit_consumed) - flt(current_amount) >= 0:
|
||||
return current_amount * rate / 100
|
||||
else:
|
||||
ltds_amount = certificate_limit - flt(deducted_amount)
|
||||
ltds_amount = certificate_limit - flt(limit_consumed)
|
||||
tds_amount = current_amount - ltds_amount
|
||||
|
||||
return ltds_amount * rate / 100 + tds_amount * tax_details.rate / 100
|
||||
|
||||
|
||||
def is_valid_certificate(
|
||||
valid_from, valid_upto, posting_date, deducted_amount, current_amount, certificate_limit
|
||||
):
|
||||
valid = False
|
||||
def is_valid_certificate(ldc, posting_date, limit_consumed):
|
||||
available_amount = flt(ldc.certificate_limit) - flt(limit_consumed)
|
||||
if (
|
||||
getdate(ldc.valid_from) <= getdate(posting_date) <= getdate(ldc.valid_upto)
|
||||
) and available_amount > 0:
|
||||
return True
|
||||
|
||||
available_amount = flt(certificate_limit) - flt(deducted_amount)
|
||||
|
||||
if (getdate(valid_from) <= getdate(posting_date) <= getdate(valid_upto)) and available_amount > 0:
|
||||
valid = True
|
||||
|
||||
return valid
|
||||
return False
|
||||
|
||||
|
||||
def normal_round(number):
|
||||
|
@ -4,6 +4,7 @@
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
|
||||
from frappe.utils import today
|
||||
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
@ -17,6 +18,7 @@ class TestTaxWithholdingCategory(unittest.TestCase):
|
||||
# create relevant supplier, etc
|
||||
create_records()
|
||||
create_tax_withholding_category_records()
|
||||
make_pan_no_field()
|
||||
|
||||
def tearDown(self):
|
||||
cancel_invoices()
|
||||
@ -451,6 +453,40 @@ class TestTaxWithholdingCategory(unittest.TestCase):
|
||||
pe2.cancel()
|
||||
pe3.cancel()
|
||||
|
||||
def test_lower_deduction_certificate_application(self):
|
||||
frappe.db.set_value(
|
||||
"Supplier",
|
||||
"Test LDC Supplier",
|
||||
{
|
||||
"tax_withholding_category": "Test Service Category",
|
||||
"pan": "ABCTY1234D",
|
||||
},
|
||||
)
|
||||
|
||||
create_lower_deduction_certificate(
|
||||
supplier="Test LDC Supplier",
|
||||
certificate_no="1AE0423AAJ",
|
||||
tax_withholding_category="Test Service Category",
|
||||
tax_rate=2,
|
||||
limit=50000,
|
||||
)
|
||||
|
||||
pi1 = create_purchase_invoice(supplier="Test LDC Supplier", rate=35000)
|
||||
pi1.submit()
|
||||
self.assertEqual(pi1.taxes[0].tax_amount, 700)
|
||||
|
||||
pi2 = create_purchase_invoice(supplier="Test LDC Supplier", rate=35000)
|
||||
pi2.submit()
|
||||
self.assertEqual(pi2.taxes[0].tax_amount, 2300)
|
||||
|
||||
pi3 = create_purchase_invoice(supplier="Test LDC Supplier", rate=35000)
|
||||
pi3.submit()
|
||||
self.assertEqual(pi3.taxes[0].tax_amount, 3500)
|
||||
|
||||
pi1.cancel()
|
||||
pi2.cancel()
|
||||
pi3.cancel()
|
||||
|
||||
|
||||
def cancel_invoices():
|
||||
purchase_invoices = frappe.get_all(
|
||||
@ -610,6 +646,7 @@ def create_records():
|
||||
"Test TDS Supplier6",
|
||||
"Test TDS Supplier7",
|
||||
"Test TDS Supplier8",
|
||||
"Test LDC Supplier",
|
||||
]:
|
||||
if frappe.db.exists("Supplier", name):
|
||||
continue
|
||||
@ -806,3 +843,39 @@ def create_tax_withholding_category(
|
||||
"accounts": [{"company": "_Test Company", "account": account}],
|
||||
}
|
||||
).insert()
|
||||
|
||||
|
||||
def create_lower_deduction_certificate(
|
||||
supplier, tax_withholding_category, tax_rate, certificate_no, limit
|
||||
):
|
||||
fiscal_year = get_fiscal_year(today(), company="_Test Company")
|
||||
if not frappe.db.exists("Lower Deduction Certificate", certificate_no):
|
||||
frappe.get_doc(
|
||||
{
|
||||
"doctype": "Lower Deduction Certificate",
|
||||
"company": "_Test Company",
|
||||
"supplier": supplier,
|
||||
"certificate_no": certificate_no,
|
||||
"tax_withholding_category": tax_withholding_category,
|
||||
"fiscal_year": fiscal_year[0],
|
||||
"valid_from": fiscal_year[1],
|
||||
"valid_upto": fiscal_year[2],
|
||||
"rate": tax_rate,
|
||||
"certificate_limit": limit,
|
||||
}
|
||||
).insert()
|
||||
|
||||
|
||||
def make_pan_no_field():
|
||||
pan_field = {
|
||||
"Supplier": [
|
||||
{
|
||||
"fieldname": "pan",
|
||||
"label": "PAN",
|
||||
"fieldtype": "Data",
|
||||
"translatable": 0,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
create_custom_fields(pan_field, update=1)
|
||||
|
Loading…
Reference in New Issue
Block a user