mirror of
https://github.com/frappe/erpnext.git
synced 2026-02-17 08:35:00 +00:00
fix: (india) HSN wise report
Problem: The previous approach for calculating tax_rate was incorrect. ``` ['tax_rate'] * ['number of unique rows'] ``` Joining `tabSales Taxes and Charges` was adding unnecessary rows & complexity. Solution: Instead of trying to get tax_rate from the main query itself, I used the get_tax_accounts's data to calculate the correct tax_rate. Todo: Union Territory
This commit is contained in:
@@ -23,22 +23,29 @@ def _execute(filters=None):
|
||||
if not filters:
|
||||
filters = {}
|
||||
columns = get_columns()
|
||||
output_gst_accounts = get_output_gst_accounts(filters.company)
|
||||
|
||||
company_currency = erpnext.get_company_currency(filters.company)
|
||||
item_list = get_items(filters)
|
||||
if item_list:
|
||||
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency)
|
||||
itemised_tax, tax_columns = get_tax_accounts(
|
||||
item_list, columns, company_currency, output_gst_accounts
|
||||
)
|
||||
|
||||
data = []
|
||||
added_item = []
|
||||
for d in item_list:
|
||||
if (d.parent, d.item_code) not in added_item:
|
||||
row = [d.gst_hsn_code, d.description, d.stock_uom, d.stock_qty, d.tax_rate or 0]
|
||||
row = [d.gst_hsn_code, d.description, d.stock_uom, d.stock_qty]
|
||||
total_tax = 0
|
||||
tax_rate = 0
|
||||
for tax in tax_columns:
|
||||
item_tax = itemised_tax.get((d.parent, d.item_code), {}).get(tax, {})
|
||||
if item_tax.get("is_gst_tax"):
|
||||
tax_rate += flt(item_tax.get("tax_rate", 0))
|
||||
total_tax += flt(item_tax.get("tax_amount", 0))
|
||||
|
||||
row += [tax_rate]
|
||||
row += [d.base_net_amount + total_tax]
|
||||
row += [d.base_net_amount]
|
||||
for tax in tax_columns:
|
||||
@@ -51,6 +58,40 @@ def _execute(filters=None):
|
||||
return columns, data
|
||||
|
||||
|
||||
def get_output_gst_accounts(company):
|
||||
|
||||
accounts = frappe.qb.DocType("Account")
|
||||
gst_accounts = frappe.qb.DocType("GST Account")
|
||||
|
||||
accounts_query = (
|
||||
frappe.qb.from_(accounts)
|
||||
.select(accounts.name)
|
||||
.where((accounts.account_type == "Tax") & (accounts.root_type == "Liability"))
|
||||
)
|
||||
|
||||
gst_accounts_query = (
|
||||
frappe.qb.from_(gst_accounts)
|
||||
.select(
|
||||
gst_accounts.cgst_account,
|
||||
gst_accounts.sgst_account,
|
||||
gst_accounts.igst_account,
|
||||
gst_accounts.utgst_account,
|
||||
gst_accounts.cess_account,
|
||||
)
|
||||
.where((gst_accounts.is_reverse_charge_account == 0) & (gst_accounts.company == company))
|
||||
)
|
||||
|
||||
gst_accounts_list = [
|
||||
account for sublist in gst_accounts_query.run() for account in sublist if account
|
||||
]
|
||||
|
||||
tax_accounts_list = [account[0] for account in accounts_query.run() if account]
|
||||
|
||||
output_tax_list = [account for account in gst_accounts_list if account in tax_accounts_list]
|
||||
|
||||
return output_tax_list
|
||||
|
||||
|
||||
def get_columns():
|
||||
columns = [
|
||||
{
|
||||
@@ -103,40 +144,19 @@ def get_items(filters):
|
||||
SELECT
|
||||
`tabSales Invoice Item`.gst_hsn_code,
|
||||
`tabSales Invoice Item`.stock_uom,
|
||||
sum(
|
||||
`tabSales Invoice Item`.stock_qty
|
||||
) as stock_qty,
|
||||
sum(
|
||||
`tabSales Invoice Item`.base_net_amount
|
||||
) as base_net_amount,
|
||||
sum(
|
||||
`tabSales Invoice Item`.base_price_list_rate
|
||||
) as base_price_list_rate,
|
||||
|
||||
sum(`tabSales Invoice Item`.stock_qty) AS stock_qty,
|
||||
sum(`tabSales Invoice Item`.base_net_amount) AS base_net_amount,
|
||||
sum(`tabSales Invoice Item`.base_price_list_rate) AS base_price_list_rate,
|
||||
`tabSales Invoice Item`.parent,
|
||||
`tabSales Invoice Item`.item_code,
|
||||
`tabGST HSN Code`.description,
|
||||
json_extract(
|
||||
`tabSales Taxes and Charges`.item_wise_tax_detail,
|
||||
concat(
|
||||
'$."', `tabSales Invoice Item`.item_code,
|
||||
'"[0]'
|
||||
)
|
||||
) * count(
|
||||
distinct `tabSales Taxes and Charges`.name
|
||||
) as tax_rate
|
||||
`tabGST HSN Code`.description
|
||||
FROM
|
||||
`tabSales Invoice`
|
||||
INNER JOIN
|
||||
`tabSales Invoice Item` ON `tabSales Invoice`.name = `tabSales Invoice Item`.parent
|
||||
INNER JOIN
|
||||
`tabGST HSN Code` ON `tabSales Invoice Item`.gst_hsn_code = `tabGST HSN Code`.name % s % s
|
||||
LEFT JOIN
|
||||
`tabSales Taxes and Charges` ON `tabSales Taxes and Charges`.parent = `tabSales Invoice`.name
|
||||
INNER JOIN `tabSales Invoice Item` ON `tabSales Invoice`.name = `tabSales Invoice Item`.parent
|
||||
INNER JOIN `tabGST HSN Code` ON `tabSales Invoice Item`.gst_hsn_code = `tabGST HSN Code`.name % s % s
|
||||
WHERE
|
||||
`tabSales Invoice`.docstatus = 1
|
||||
AND
|
||||
`tabSales Invoice Item`.gst_hsn_code is not NULL
|
||||
AND `tabSales Invoice Item`.gst_hsn_code IS NOT NULL
|
||||
GROUP BY
|
||||
`tabSales Invoice Item`.parent,
|
||||
`tabSales Invoice Item`.item_code,
|
||||
@@ -158,6 +178,7 @@ def get_tax_accounts(
|
||||
item_list,
|
||||
columns,
|
||||
company_currency,
|
||||
output_gst_accounts,
|
||||
doctype="Sales Invoice",
|
||||
tax_doctype="Sales Taxes and Charges",
|
||||
):
|
||||
@@ -210,15 +231,25 @@ def get_tax_accounts(
|
||||
continue
|
||||
itemised_tax.setdefault(item_code, frappe._dict())
|
||||
if isinstance(tax_data, list):
|
||||
tax_rate = 0
|
||||
is_gst_tax = 0
|
||||
if account_head in output_gst_accounts:
|
||||
is_gst_tax = 1
|
||||
tax_rate = tax_data[0]
|
||||
tax_amount = tax_data[1]
|
||||
else:
|
||||
tax_rate = 0
|
||||
tax_amount = 0
|
||||
|
||||
for d in item_row_map.get(parent, {}).get(item_code, []):
|
||||
item_tax_amount = tax_amount
|
||||
if item_tax_amount:
|
||||
itemised_tax.setdefault((parent, item_code), {})[account_head] = frappe._dict(
|
||||
{"tax_amount": flt(item_tax_amount, tax_amount_precision)}
|
||||
{
|
||||
"tax_rate": flt(tax_rate, 2),
|
||||
"is_gst_tax": is_gst_tax,
|
||||
"tax_amount": flt(item_tax_amount, tax_amount_precision),
|
||||
}
|
||||
)
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user