Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions india_compliance/gst_india/overrides/test_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@
create_sales_invoice,
create_transaction,
)
from india_compliance.income_tax_india.overrides.company import (
TDS_ACCOUNT_NAME,
create_tds_account,
)
from india_compliance.income_tax_india.overrides.test_tax_withholding_category import (
create_tax_withholding_category,
)


@parameterized_class(
Expand Down Expand Up @@ -1844,6 +1851,36 @@ def test_is_multicurrency_doc(self):
self.assertFalse(_is_multicurrency_doc({}))
self.assertFalse(_is_multicurrency_doc('{"conversion_rate": 1}'))

def test_taxable_value_excludes_tcs_without_gst_rows(self):
"""
Zero-rated Sales Invoice with no GST rows and TCS via Tax Withholding Category.
TCS row is identified by `is_tax_withholding_account` and must not be
apportioned into the item's taxable value.
"""
company = "_Test Indian Registered Company"
category = "_Test TCS Category"

create_tds_account(company)
create_tax_withholding_category(category, f"{TDS_ACCOUNT_NAME} - _TIRC")

doc = create_transaction(
doctype="Sales Invoice",
item_code="_Test Nil Rated Item",
apply_tds=1,
do_not_save=True,
)
doc.items[0].tax_withholding_category = category
doc.save()

self.assertFalse([row for row in doc.taxes if row.gst_tax_type])

tcs_rows = [row for row in doc.taxes if row.is_tax_withholding_account]
self.assertTrue(tcs_rows)
self.assertTrue(tcs_rows[0].base_tax_amount_after_discount_amount)

item = doc.items[0]
self.assertEqual(item.taxable_value, item.base_net_amount)

def test_copy_e_waybill_fields_from_dn_to_si(self):
"Make sure e-Waybill fields are copied from Delivery Note to Sales Invoice"
dn = create_transaction(doctype="Delivery Note", vehicle_no="GJ01AA1111")
Expand Down
7 changes: 5 additions & 2 deletions india_compliance/gst_india/overrides/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,14 @@
validate_gst_category,
validate_gstin,
)
<<<<<<< HEAD
from india_compliance.gst_india.utils.gstr_1 import SUPECOM
from india_compliance.income_tax_india.overrides.tax_withholding_category import (
get_tax_withholding_accounts,
)
=======
from india_compliance.gst_returns.fields.gstr1 import SubCategory
>>>>>>> 326fe3d (fix: use tds row check instead of account)

DOCTYPES_WITH_GST_DETAIL = {
"Supplier Quotation",
Expand Down Expand Up @@ -168,10 +172,9 @@ def validate_item_wise_tax_detail(doc):


def get_tds_amount(doc):
tds_accounts = get_tax_withholding_accounts(doc.company)
tds_amount = 0
for row in doc.taxes:
if row.account_head not in tds_accounts:
if not row.get("is_tax_withholding_account"):
continue

multiplier = -1 if row.get("add_deduct_tax") == "Deduct" else 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
from frappe.query_builder.functions import IfNull, Sum

from india_compliance.gst_india.constants import GST_TAX_TYPES, TAX_TYPES
from india_compliance.income_tax_india.overrides.tax_withholding_category import (
get_tax_withholding_accounts,
)


def execute(filters: dict | None = None):
Expand All @@ -30,7 +27,6 @@ def execute(filters: dict | None = None):
class AccountWiseSummary:
def __init__(self, filters):
self.filters = filters
self.tds_accounts = get_tax_withholding_accounts(filters.company)

@staticmethod
def get_columns():
Expand Down Expand Up @@ -118,7 +114,7 @@ def allocate_additional_charges(self, invoice, additional_tax, total_proportion,
is_after_gst = True
continue

elif tax.account_head in self.tds_accounts or not tax.base_tax_amount_after_discount_amount:
elif tax.is_tax_withholding_account or not tax.base_tax_amount_after_discount_amount:
continue

if not is_after_gst:
Expand Down Expand Up @@ -240,6 +236,7 @@ def get_taxes_for_docs(self):
taxes_doc.parent,
taxes_doc.account_head,
taxes_doc.charge_type,
taxes_doc.is_tax_withholding_account,
)
.orderby(taxes_doc.idx)
)
Expand Down
3 changes: 0 additions & 3 deletions india_compliance/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,9 +296,6 @@
"after_insert": ("india_compliance.gst_india.overrides.party.create_primary_address"),
},
"Tax Category": {"validate": "india_compliance.gst_india.overrides.tax_category.validate"},
"Tax Withholding Category": {
"on_change": "india_compliance.income_tax_india.overrides.tax_withholding_category.on_change",
},
"Unreconcile Payment": {
"before_submit": "india_compliance.gst_india.overrides.unreconcile_payment.before_submit",
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
import frappe


def on_change(doc, method=None):
frappe.cache.delete_value("tax_withholding_accounts")


def get_tax_withholding_accounts(company):
def _get_tax_withholding_accounts():
return set(frappe.get_all("Tax Withholding Account", pluck="account", filters={"company": company}))

return frappe.cache.hget("tax_withholding_accounts", company, generator=_get_tax_withholding_accounts)


def get_tax_id_for_party(party_type, party):
# PAN field is only available for Customer and Supplier.
if party_type in ("Customer", "Supplier"):
Expand Down
Loading