Skip to content

Commit

Permalink
Merge pull request #1459 from resilient-tech/mergify/bp/version-14-ho…
Browse files Browse the repository at this point in the history
…tfix/pr-1451

fix: add zero rated category in transactions for correct reporting (backport #1451)
  • Loading branch information
mergify[bot] authored Dec 22, 2023
2 parents dbdc001 + 6fe41bd commit a344e37
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,9 @@ function is_e_invoice_applicable(frm) {
frm.doc.company_gstin != frm.doc.billing_address_gstin &&
(frm.doc.place_of_supply === "96-Other Countries" ||
frm.doc.billing_address_gstin) &&
frm.doc.items[0].gst_treatment != "Non-GST" &&
frm.doc.items.some(item => item.gst_treatment == "Taxable") &&
frm.doc.items.some(item =>
["Taxable", "Zero-Rated"].includes(item.gst_treatment)
) &&
is_valid_e_invoice_applicability_date(frm)
);
}
Expand Down
3 changes: 2 additions & 1 deletion india_compliance/gst_india/constants/custom_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,9 @@
"fieldname": "gst_treatment",
"label": "GST Treatment",
"fieldtype": "Autocomplete",
"options": "Taxable\nNil-Rated\nExempted\nNon-GST",
"options": "Taxable\nZero-Rated\nNil-Rated\nExempted\nNon-GST",
"fetch_from": "item_tax_template.gst_treatment",
"fetch_if_empty": 1,
"insert_after": "item_tax_template",
"print_hide": 1,
"read_only": 1,
Expand Down
42 changes: 41 additions & 1 deletion india_compliance/gst_india/overrides/test_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
from parameterized import parameterized_class

import frappe
from frappe.tests.utils import FrappeTestCase
from frappe.tests.utils import FrappeTestCase, change_settings
from frappe.utils import today
from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_sales_return
from erpnext.accounts.party import _get_party_details
from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice

from india_compliance.gst_india.constants import SALES_DOCTYPES
Expand Down Expand Up @@ -531,6 +533,44 @@ def test_gst_details_set_correctly(self):
doc.items[0],
)

@change_settings("GST Settings", {"enable_overseas_transactions": 1})
def test_gst_treatment_for_exports(self):
if not self.is_sales_doctype:
return

doc = create_transaction(
**self.transaction_details,
is_in_state=True,
)
self.assertEqual(doc.items[0].gst_treatment, "Taxable")

# Update Customer after it's already set
doc_details = {
**self.transaction_details,
"customer": "_Test Foreign Customer",
"party_name": "_Test Foreign Customer",
}
doc = create_transaction(**doc_details, do_not_submit=True)
self.assertEqual(doc.items[0].gst_treatment, "Zero-Rated")

party_field = "party_name" if self.doctype == "Quotation" else "customer"

customer = "_Test Registered Customer"
doc.update(
{
party_field: customer,
**_get_party_details(
party=customer,
company=doc.company,
posting_date=today(),
doctype=doc.doctype,
),
}
)
doc.selling_price_list = "Standard Selling"
doc.save()
self.assertEqual(doc.items[0].gst_treatment, "Taxable")

def test_purchase_with_different_place_of_supply(self):
if self.is_sales_doctype:
return
Expand Down
49 changes: 47 additions & 2 deletions india_compliance/gst_india/overrides/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -1118,11 +1118,56 @@ def set_tax_amount_precisions(self, doctype):


def set_gst_treatment_for_item(doc):
is_overseas = is_overseas_doc(doc)
is_sales_transaction = doc.doctype in SALES_DOCTYPES

default_gst_treatment = "Taxable"
gst_accounts = get_all_gst_accounts(doc.company)

for row in doc.taxes:
if row.charge_type in ("Actual", "On Item Quantity"):
continue

if row.account_head not in gst_accounts:
continue

Check warning on line 1132 in india_compliance/gst_india/overrides/transaction.py

View check run for this annotation

Codecov / codecov/patch

india_compliance/gst_india/overrides/transaction.py#L1132

Added line #L1132 was not covered by tests

if row.rate == 0:
default_gst_treatment = "Nil-Rated"

Check warning on line 1135 in india_compliance/gst_india/overrides/transaction.py

View check run for this annotation

Codecov / codecov/patch

india_compliance/gst_india/overrides/transaction.py#L1135

Added line #L1135 was not covered by tests

break

item_templates = set()
gst_treatments = set()
gst_treatment_map = {}

for item in doc.items:
item_templates.add(item.item_tax_template)
gst_treatments.add(item.gst_treatment)

if "Zero-Rated" in gst_treatments and not is_overseas:
# doc changed from overseas to local sale post validate
_gst_treatments = frappe.get_all(
"Item Tax Template",
filters={"name": ("in", item_templates)},
fields=["name", "gst_treatment"],
)
gst_treatment_map = {row.name: row.gst_treatment for row in _gst_treatments}

for item in doc.items:
if item.gst_treatment:
if not item.gst_treatment or not item.item_tax_template:
item.gst_treatment = default_gst_treatment

if not is_sales_transaction:
continue

item.gst_treatment = "Taxable"
if is_overseas:
# IGST sec 16(2) - ITC can be claimed for exempt supply
item.gst_treatment = "Zero-Rated"

elif item.gst_treatment == "Zero-Rated":
item.gst_treatment = (

Check warning on line 1168 in india_compliance/gst_india/overrides/transaction.py

View check run for this annotation

Codecov / codecov/patch

india_compliance/gst_india/overrides/transaction.py#L1168

Added line #L1168 was not covered by tests
gst_treatment_map.get(item.item_tax_template) or default_gst_treatment
)


def set_reverse_charge_as_per_gst_settings(doc):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ def validate_sales_invoice_item():
frappe.qb.from_(sales_invoice_item)
.select(sales_invoice_item.parent)
.where(sales_invoice_item.parenttype == "Sales Invoice")
.where(sales_invoice_item.gst_treatment == "Taxable")
.where(sales_invoice_item.gst_treatment.isin(["Taxable", "Zero-Rated"]))
.distinct()
)

Expand Down
12 changes: 3 additions & 9 deletions india_compliance/gst_india/utils/e_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,7 @@
_cancel_e_waybill,
log_and_process_e_waybill_generation,
)
from india_compliance.gst_india.utils.transaction_data import (
GSTTransactionData,
validate_non_gst_items,
)
from india_compliance.gst_india.utils.transaction_data import GSTTransactionData


@frappe.whitelist()
Expand Down Expand Up @@ -356,9 +353,6 @@ def _throw(error):
# e-Invoice not required for invoice wih all nill-rated/exempted items.
return

if not validate_non_gst_items(doc, throw=throw):
return

if not (doc.place_of_supply == "96-Other Countries" or doc.billing_address_gstin):
return _throw(_("e-Invoice is not applicable for B2C invoices"))

Expand Down Expand Up @@ -403,7 +397,7 @@ def validate_taxable_item(doc, throw=True):
"""
# Check if there is at least one taxable item in the document
if any(item.gst_treatment == "Taxable" for item in doc.items):
if any(item.gst_treatment in ("Taxable", "Zero-Rated") for item in doc.items):
return True

if not throw:
Expand Down Expand Up @@ -521,7 +515,7 @@ def set_item_list(self):
self.item_list = []

for item_details in self.get_all_item_details():
if item_details.get("gst_treatment") != "Taxable":
if item_details.get("gst_treatment") not in ("Taxable", "Zero-Rated"):
continue

self.item_list.append(self.get_item_data(item_details))
Expand Down
2 changes: 1 addition & 1 deletion india_compliance/gst_india/utils/transaction_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def set_transaction_details(self):
for row in self.doc.items:
total += row.taxable_value

if row.gst_treatment == "Taxable":
if row.gst_treatment in ("Taxable", "Zero-Rated"):
total_taxable_value += row.taxable_value

self.transaction_details.update(
Expand Down
26 changes: 23 additions & 3 deletions india_compliance/patches/post_install/improve_item_tax_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,12 +240,12 @@ def remove_old_item_variant_settings():
def update_gst_treatment_for_transactions():
"Disclaimer: No specific way to differentate between nil and exempted. Hence all transactions are updated to nil"

for doctype in TRANSACTION_DOCTYPES:
for item_doctype in TRANSACTION_DOCTYPES:
# GST Treatment is not required in Material Request Item
if doctype == "Material Request Item":
if item_doctype == "Material Request Item":
continue

table = frappe.qb.DocType(doctype)
table = frappe.qb.DocType(item_doctype)
query = frappe.qb.update(table)

(
Expand All @@ -260,6 +260,26 @@ def update_gst_treatment_for_transactions():
.run()
)

doctype = item_doctype.replace(" Item", "")
if doctype not in SALES_DOCTYPES:
continue

doc = frappe.qb.DocType(doctype)

(
query.join(doc)
.on(doc.name == table.parent)
.set(table.gst_treatment, "Zero-Rated")
.where(
(doc.gst_category == "SEZ")
| (
(doc.gst_category == "Overseas")
& (doc.place_of_supply == "96-Other Countries")
)
)
.run()
)

click.secho(
"Nil Rated items are differentiated from Exempted for GST (configrable from Item Tax Template).",
color="yellow",
Expand Down

0 comments on commit a344e37

Please sign in to comment.