[Report] HSN-wise-summary of outward supplies (#13803)
* hsn wise summary report * renamed * added total amount column * moved total amount column
This commit is contained in:
parent
5e7b2eb338
commit
88aa3ec275
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
frappe.query_reports["HSN-wise-summary of outward supplies"] = {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"fieldname":"company",
|
||||||
|
"label": __("Company"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Company",
|
||||||
|
"reqd": 1,
|
||||||
|
"default": frappe.defaults.get_user_default("Company")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"gst_hsn_code",
|
||||||
|
"label": __("HSN/SAC"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "GST HSN Code",
|
||||||
|
"width": "80"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"add_total_row": 0,
|
||||||
|
"creation": "2018-04-26 10:49:29.159400",
|
||||||
|
"disabled": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Report",
|
||||||
|
"idx": 0,
|
||||||
|
"is_standard": "Yes",
|
||||||
|
"letter_head": "Standard",
|
||||||
|
"modified": "2018-04-26 12:59:38.603649",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Regional",
|
||||||
|
"name": "HSN-wise-summary of outward supplies",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"ref_doctype": "Sales Invoice",
|
||||||
|
"report_name": "HSN-wise-summary of outward supplies",
|
||||||
|
"report_type": "Script Report",
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"role": "Accounts User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Accounts Manager"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Auditor"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,217 @@
|
|||||||
|
# Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe, erpnext
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils import flt
|
||||||
|
from frappe.model.meta import get_field_precision
|
||||||
|
from frappe.utils.xlsxutils import handle_html
|
||||||
|
|
||||||
|
def execute(filters=None):
|
||||||
|
return _execute(filters)
|
||||||
|
|
||||||
|
def _execute(filters=None):
|
||||||
|
if not filters: filters = {}
|
||||||
|
columns = get_columns()
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
data = []
|
||||||
|
for d in item_list:
|
||||||
|
row = [d.gst_hsn_code, d.description, d.stock_uom, d.stock_qty]
|
||||||
|
total_tax = 0
|
||||||
|
for tax in tax_columns:
|
||||||
|
item_tax = itemised_tax.get(d.name, {}).get(tax, {})
|
||||||
|
total_tax += flt(item_tax.get("tax_amount"))
|
||||||
|
|
||||||
|
row += [d.base_net_amount + total_tax]
|
||||||
|
row += [d.base_net_amount]
|
||||||
|
|
||||||
|
for tax in tax_columns:
|
||||||
|
item_tax = itemised_tax.get(d.name, {}).get(tax, {})
|
||||||
|
row += [item_tax.get("tax_amount", 0)]
|
||||||
|
|
||||||
|
data.append(row)
|
||||||
|
if data:
|
||||||
|
data = get_merged_data(columns, data) # merge same hsn code data
|
||||||
|
return columns, data
|
||||||
|
|
||||||
|
def get_columns():
|
||||||
|
columns = [
|
||||||
|
{
|
||||||
|
"fieldname": "gst_hsn_code",
|
||||||
|
"label": _("HSN/SAC"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "GST HSN Code",
|
||||||
|
"width": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "description",
|
||||||
|
"label": _("Description"),
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "stock_uom",
|
||||||
|
"label": _("Stock UOM"),
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "stock_qty",
|
||||||
|
"label": _("Stock Qty"),
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"width": 90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "total_amount",
|
||||||
|
"label": _("Total Amount"),
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "taxable_amount",
|
||||||
|
"label": _("Total Taxable Amount"),
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 170
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
return columns
|
||||||
|
|
||||||
|
def get_conditions(filters):
|
||||||
|
conditions = ""
|
||||||
|
|
||||||
|
for opts in (("company", " and company=%(company)s"),
|
||||||
|
("gst_hsn_code", " and gst_hsn_code=%(gst_hsn_code)s")):
|
||||||
|
if filters.get(opts[0]):
|
||||||
|
conditions += opts[1]
|
||||||
|
|
||||||
|
return conditions
|
||||||
|
|
||||||
|
def get_items(filters):
|
||||||
|
conditions = get_conditions(filters)
|
||||||
|
match_conditions = frappe.build_match_conditions("Sales Invoice")
|
||||||
|
if match_conditions:
|
||||||
|
match_conditions = " and {0} ".format(match_conditions)
|
||||||
|
|
||||||
|
|
||||||
|
return frappe.db.sql("""
|
||||||
|
select
|
||||||
|
`tabSales Invoice Item`.name, `tabSales Invoice Item`.base_price_list_rate,
|
||||||
|
`tabSales Invoice Item`.gst_hsn_code, `tabSales Invoice Item`.stock_qty,
|
||||||
|
`tabSales Invoice Item`.stock_uom, `tabSales Invoice Item`.base_net_amount,
|
||||||
|
`tabSales Invoice Item`.parent, `tabSales Invoice Item`.item_code,
|
||||||
|
`tabGST HSN Code`.description
|
||||||
|
from `tabSales Invoice`, `tabSales Invoice Item`, `tabGST HSN Code`
|
||||||
|
where `tabSales Invoice`.name = `tabSales Invoice Item`.parent
|
||||||
|
and `tabSales Invoice`.docstatus = 1
|
||||||
|
and `tabSales Invoice Item`.gst_hsn_code is not NULL
|
||||||
|
and `tabSales Invoice Item`.gst_hsn_code = `tabGST HSN Code`.name %s %s
|
||||||
|
|
||||||
|
""" % (conditions, match_conditions), filters, as_dict=1)
|
||||||
|
|
||||||
|
|
||||||
|
def get_tax_accounts(item_list, columns, company_currency,
|
||||||
|
doctype="Sales Invoice", tax_doctype="Sales Taxes and Charges"):
|
||||||
|
import json
|
||||||
|
item_row_map = {}
|
||||||
|
tax_columns = []
|
||||||
|
invoice_item_row = {}
|
||||||
|
itemised_tax = {}
|
||||||
|
conditions = ""
|
||||||
|
|
||||||
|
tax_amount_precision = get_field_precision(frappe.get_meta(tax_doctype).get_field("tax_amount"),
|
||||||
|
currency=company_currency) or 2
|
||||||
|
|
||||||
|
for d in item_list:
|
||||||
|
invoice_item_row.setdefault(d.parent, []).append(d)
|
||||||
|
item_row_map.setdefault(d.parent, {}).setdefault(d.item_code or d.item_name, []).append(d)
|
||||||
|
|
||||||
|
tax_details = frappe.db.sql("""
|
||||||
|
select
|
||||||
|
parent, description, item_wise_tax_detail,
|
||||||
|
base_tax_amount_after_discount_amount
|
||||||
|
from `tab%s`
|
||||||
|
where
|
||||||
|
parenttype = %s and docstatus = 1
|
||||||
|
and (description is not null and description != '')
|
||||||
|
and parent in (%s)
|
||||||
|
%s
|
||||||
|
order by description
|
||||||
|
""" % (tax_doctype, '%s', ', '.join(['%s']*len(invoice_item_row)), conditions),
|
||||||
|
tuple([doctype] + list(invoice_item_row)))
|
||||||
|
|
||||||
|
for parent, description, item_wise_tax_detail, tax_amount in tax_details:
|
||||||
|
description = handle_html(description)
|
||||||
|
if description not in tax_columns and tax_amount:
|
||||||
|
# as description is text editor earlier and markup can break the column convention in reports
|
||||||
|
tax_columns.append(description)
|
||||||
|
|
||||||
|
if item_wise_tax_detail:
|
||||||
|
try:
|
||||||
|
item_wise_tax_detail = json.loads(item_wise_tax_detail)
|
||||||
|
|
||||||
|
for item_code, tax_data in item_wise_tax_detail.items():
|
||||||
|
if not frappe.db.get_value("Item", item_code, "gst_hsn_code"):
|
||||||
|
continue
|
||||||
|
itemised_tax.setdefault(item_code, frappe._dict())
|
||||||
|
if isinstance(tax_data, list):
|
||||||
|
tax_amount = tax_data[1]
|
||||||
|
else:
|
||||||
|
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(d.name, {})[description] = frappe._dict({
|
||||||
|
"tax_amount": flt(item_tax_amount, tax_amount_precision)
|
||||||
|
})
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
tax_columns.sort()
|
||||||
|
for desc in tax_columns:
|
||||||
|
columns.append(desc + " Amount:Currency/currency:160")
|
||||||
|
|
||||||
|
# columns += ["Total Amount:Currency/currency:110"]
|
||||||
|
return itemised_tax, tax_columns
|
||||||
|
|
||||||
|
def get_merged_data(columns, data):
|
||||||
|
merged_hsn_dict = {} # to group same hsn under one key and perform row addition
|
||||||
|
add_column_index = [] # store index of columns that needs to be added
|
||||||
|
tax_col = len(get_columns())
|
||||||
|
fields_to_merge = ["stock_qty", "total_amount", "taxable_amount"] # columns for which index needs to be found
|
||||||
|
|
||||||
|
for i,d in enumerate(columns):
|
||||||
|
# check if fieldname in to_merge list and ignore tax-columns
|
||||||
|
if i < tax_col and d["fieldname"] in fields_to_merge:
|
||||||
|
add_column_index.append(i)
|
||||||
|
|
||||||
|
for row in data:
|
||||||
|
if merged_hsn_dict.has_key(row[0]):
|
||||||
|
to_add_row = merged_hsn_dict.get(row[0])
|
||||||
|
|
||||||
|
# add columns from the add_column_index table
|
||||||
|
for k in add_column_index:
|
||||||
|
to_add_row[k] += row[k]
|
||||||
|
|
||||||
|
# add tax columns
|
||||||
|
for k in range(len(columns)):
|
||||||
|
if tax_col <= k < len(columns):
|
||||||
|
to_add_row[k] += row[k]
|
||||||
|
|
||||||
|
# update hsn dict with the newly added data
|
||||||
|
merged_hsn_dict[row[0]] = to_add_row
|
||||||
|
else:
|
||||||
|
merged_hsn_dict[row[0]] = row
|
||||||
|
|
||||||
|
# extract data rows to be displayed in report
|
||||||
|
data = [merged_hsn_dict[d] for d in merged_hsn_dict]
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user