fix: Multiple fixes in GSTR-1 report

(cherry picked from commit f2cbb703252564149620a26d6f52800b18c53632)

# Conflicts:
#	erpnext/regional/report/gstr_1/gstr_1.py
This commit is contained in:
Deepesh Garg 2022-05-11 23:48:28 +05:30 committed by Mergify
parent 1ff8b06da3
commit c6b98d8de9
8 changed files with 187862 additions and 14 deletions

View File

@ -1,4 +1,5 @@
{
"actions": [],
"autoname": "field:hsn_code",
"creation": "2017-06-21 10:48:56.422086",
"doctype": "DocType",
@ -7,6 +8,7 @@
"field_order": [
"hsn_code",
"description",
"gst_rates",
"taxes"
],
"fields": [
@ -16,22 +18,37 @@
"in_list_view": 1,
"label": "HSN Code",
"reqd": 1,
"show_days": 1,
"show_seconds": 1,
"unique": 1
},
{
"fieldname": "description",
"fieldtype": "Small Text",
"in_list_view": 1,
"label": "Description"
"label": "Description",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "taxes",
"fieldtype": "Table",
"label": "Taxes",
"options": "Item Tax"
"options": "Item Tax",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "gst_rates",
"fieldtype": "Table",
"label": "GST Rates",
"options": "HSN Tax Rate",
"show_days": 1,
"show_seconds": 1
}
],
"modified": "2019-11-01 11:18:59.556931",
"links": [],
"modified": "2022-05-11 13:42:27.286643",
"modified_by": "Administrator",
"module": "Regional",
"name": "GST HSN Code",

View File

@ -11,6 +11,12 @@ frappe.ui.form.on('GST Settings', {
});
});
frm.add_custom_button('Sync HSN Codes', () => {
frappe.call({
"method": "erpnext.regional.doctype.gst_settings.gst_settings.update_hsn_codes"
})
});
$(frm.fields_dict.gst_summary.wrapper).empty().html(
`<table class="table table-bordered">
<tbody>

View File

@ -2,13 +2,14 @@
# For license information, please see license.txt
import json
import os
import frappe
from frappe import _
from frappe.contacts.doctype.contact.contact import get_default_contact
from frappe.model.document import Document
from frappe.utils import date_diff, get_url, nowdate
from frappe.utils import date_diff, flt, get_url, nowdate
class EmailMissing(frappe.ValidationError):
@ -129,3 +130,34 @@ def _send_gstin_reminder(party_type, party, default_email_id=None, sent_to=None)
)
return email_id
@frappe.whitelist()
def update_hsn_codes():
frappe.enqueue(enqueue_update)
frappe.msgprint(_("HSN/SAC Code sync started, this may take a few minutes..."))
def enqueue_update():
with open(os.path.join(os.path.dirname(__file__), "hsn_code_data.json"), "r") as f:
hsn_codes = json.loads(f.read())
for hsn_code in hsn_codes:
try:
hsn_code_doc = frappe.get_doc("GST HSN Code", hsn_code.get("hsn_code"))
hsn_code_doc.set("gst_rates", [])
for rate in hsn_code.get("gst_rates"):
hsn_code_doc.append(
"gst_rates",
{
"minimum_taxable_value": flt(hsn_code.get("minimum_taxable_value")),
"cgst_rate": flt(rate.get("cgst_rate")),
"sgst_rate": flt(rate.get("sgst_rate")),
"igst_rate": flt(rate.get("igst_rate")),
"cess_rate": flt(rate.get("cess_rate")),
},
)
hsn_code_doc.save()
except Exception as e:
pass

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,73 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2022-05-11 13:32:42.534779",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"minimum_taxable_value",
"cgst_rate",
"sgst_rate",
"igst_rate",
"cess_rate"
],
"fields": [
{
"columns": 2,
"fieldname": "minimum_taxable_value",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Minimum Taxable Value",
"show_days": 1,
"show_seconds": 1
},
{
"columns": 2,
"fieldname": "cgst_rate",
"fieldtype": "Float",
"in_list_view": 1,
"label": "CGST Rate",
"show_days": 1,
"show_seconds": 1
},
{
"columns": 2,
"fieldname": "sgst_rate",
"fieldtype": "Float",
"in_list_view": 1,
"label": "SGST Rate",
"show_days": 1,
"show_seconds": 1
},
{
"columns": 2,
"fieldname": "igst_rate",
"fieldtype": "Float",
"in_list_view": 1,
"label": "IGST Rate",
"show_days": 1,
"show_seconds": 1
},
{
"columns": 2,
"fieldname": "cess_rate",
"fieldtype": "Float",
"in_list_view": 1,
"label": "Cess Rate",
"show_days": 1,
"show_seconds": 1
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2022-05-11 13:32:42.534779",
"modified_by": "Administrator",
"module": "Regional",
"name": "HSN Tax Rate",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC"
}

View File

@ -0,0 +1,9 @@
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class HSNTaxRate(Document):
pass

View File

@ -226,7 +226,10 @@ class Gstr1Report(object):
taxable_value += abs(net_amount)
elif (
not tax_rate
and self.filters.get("type_of_business") == "EXPORT"
and (
self.filters.get("type_of_business") == "EXPORT"
or invoice_details.get("gst_category") == "SEZ"
)
and invoice_details.get("export_type") == "Without Payment of Tax"
):
taxable_value += abs(net_amount)
@ -328,12 +331,13 @@ class Gstr1Report(object):
def get_invoice_items(self):
self.invoice_items = frappe._dict()
self.item_tax_rate = frappe._dict()
self.item_hsn_map = frappe._dict()
self.nil_exempt_non_gst = {}
items = frappe.db.sql(
"""
select item_code, parent, taxable_value, base_net_amount, item_tax_rate, is_nil_exempt,
is_non_gst from `tab%s Item`
gst_hsn_code, is_non_gst from `tab%s Item`
where parent in (%s)
"""
% (self.doctype, ", ".join(["%s"] * len(self.invoices))),
@ -343,6 +347,7 @@ class Gstr1Report(object):
for d in items:
self.invoice_items.setdefault(d.parent, {}).setdefault(d.item_code, 0.0)
self.item_hsn_map.setdefault(d.item_code, d.gst_hsn_code)
self.invoice_items[d.parent][d.item_code] += d.get("taxable_value", 0) or d.get(
"base_net_amount", 0
)
@ -367,6 +372,8 @@ class Gstr1Report(object):
self.nil_exempt_non_gst[d.parent][2] += d.get("taxable_value", 0)
def get_items_based_on_tax_rate(self):
hsn_wise_tax_rate = get_hsn_wise_tax_rates()
self.tax_details = frappe.db.sql(
"""
select
@ -427,15 +434,30 @@ class Gstr1Report(object):
alert=True,
)
<<<<<<< HEAD
# Build itemised tax for export invoices where tax table is blank
for invoice, items in self.invoice_items.items():
=======
# Build itemised tax for export invoices where tax table is blank (Export and SEZ Invoices)
for invoice, items in iteritems(self.invoice_items):
>>>>>>> f2cbb70325 (fix: Multiple fixes in GSTR-1 report)
if (
invoice not in self.items_based_on_tax_rate
and invoice not in unidentified_gst_accounts_invoice
and self.invoices.get(invoice, {}).get("export_type") == "Without Payment of Tax"
and self.invoices.get(invoice, {}).get("gst_category") in ("Overseas", "SEZ")
):
self.items_based_on_tax_rate.setdefault(invoice, {}).setdefault(0, items.keys())
self.items_based_on_tax_rate.setdefault(invoice, {})
for item_code in items.keys():
hsn_code = self.item_hsn_map.get(item_code)
tax_rate = 0
taxable_value = items.get(item_code)
for rates in hsn_wise_tax_rate.get(hsn_code):
if taxable_value > rates.get("minimum_taxable_value"):
tax_rate = rates.get("tax_rate")
self.items_based_on_tax_rate[invoice].setdefault(tax_rate, [])
self.items_based_on_tax_rate[invoice][tax_rate].append(item_code)
def get_columns(self):
self.other_columns = []
@ -728,7 +750,7 @@ def get_json(filters, report_name, data):
elif filters["type_of_business"] == "EXPORT":
for item in report_data[:-1]:
res.setdefault(item["export_type"], []).append(item)
res.setdefault(item["export_type"], {}).setdefault(item["invoice_number"], []).append(item)
out = get_export_json(res)
gst_json["exp"] = out
@ -918,11 +940,21 @@ def get_export_json(res):
for exp_type in res:
exp_item, inv = {"exp_typ": exp_type, "inv": []}, []
for row in res[exp_type]:
inv_item = get_basic_invoice_detail(row)
inv_item["itms"] = [
{"txval": flt(row["taxable_value"], 2), "rt": row["rate"] or 0, "iamt": 0, "csamt": 0}
]
for number, invoice in iteritems(res[exp_type]):
inv_item = get_basic_invoice_detail(invoice[0])
inv_item["itms"] = []
for item in invoice:
inv_item["itms"].append(
{
"txval": flt(item["taxable_value"], 2),
"rt": flt(item["rate"]),
"iamt": flt((item["taxable_value"] * flt(item["rate"])) / 100.0, 2)
if exp_type != "WOPAY"
else 0,
"csamt": (flt(item.get("cess_amount"), 2) or 0),
}
)
inv.append(inv_item)
@ -1060,7 +1092,6 @@ def get_rate_and_tax_details(row, gstin):
# calculate tax amount added
tax = flt((row["taxable_value"] * rate) / 100.0, 2)
frappe.errprint([tax, tax / 2])
if row.get("billing_address_gstin") and gstin[0:2] == row["billing_address_gstin"][0:2]:
itm_det.update({"camt": flt(tax / 2.0, 2), "samt": flt(tax / 2.0, 2)})
else:
@ -1136,3 +1167,26 @@ def get_company_gstins(company):
address_list = [""] + [d.gstin for d in addresses]
return address_list
def get_hsn_wise_tax_rates():
hsn_wise_tax_rate = {}
gst_hsn_code = frappe.qb.DocType("GST HSN Code")
hsn_tax_rates = frappe.qb.DocType("HSN Tax Rate")
hsn_code_data = (
frappe.qb.from_(gst_hsn_code)
.inner_join(hsn_tax_rates)
.on(gst_hsn_code.name == hsn_tax_rates.parent)
.select(gst_hsn_code.hsn_code, hsn_tax_rates.igst_rate, hsn_tax_rates.minimum_taxable_value)
.orderby(hsn_tax_rates.minimum_taxable_value)
.run(as_dict=1)
)
for d in hsn_code_data:
hsn_wise_tax_rate.setdefault(d.hsn_code, [])
hsn_wise_tax_rate[d.hsn_code].append(
{"minimum_taxable_value": d.minimum_taxable_value, "tax_rate": d.igst_rate}
)
return hsn_wise_tax_rate