Merge pull request #36196 from GursheenK/customer-details-in-tax-withholding-category-report

fix: show tax withholding category details for customers
This commit is contained in:
Deepesh Garg 2023-07-25 14:48:15 +05:30 committed by GitHub
commit 6830a8737a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 136 additions and 82 deletions

View File

@ -0,0 +1,55 @@
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.query_reports["Tax Withholding Details"] = {
"filters": [
{
"fieldname":"company",
"label": __("Company"),
"fieldtype": "Link",
"options": "Company",
"default": frappe.defaults.get_default('company')
},
{
"fieldname":"party_type",
"label": __("Party Type"),
"fieldtype": "Select",
"options": ["Supplier", "Customer"],
"reqd": 1,
"default": "Supplier",
"on_change": function(){
frappe.query_report.set_filter_value("party", "");
}
},
{
"fieldname":"party",
"label": __("Party"),
"fieldtype": "Dynamic Link",
"get_options": function() {
var party_type = frappe.query_report.get_filter_value('party_type');
var party = frappe.query_report.get_filter_value('party');
if(party && !party_type) {
frappe.throw(__("Please select Party Type first"));
}
return party_type;
}
},
{
"fieldname":"from_date",
"label": __("From Date"),
"fieldtype": "Date",
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
"reqd": 1,
"width": "60px"
},
{
"fieldname":"to_date",
"label": __("To Date"),
"fieldtype": "Date",
"default": frappe.datetime.get_today(),
"reqd": 1,
"width": "60px"
}
]
}

View File

@ -12,11 +12,11 @@
"modified": "2021-09-20 12:05:50.387572", "modified": "2021-09-20 12:05:50.387572",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "TDS Payable Monthly", "name": "Tax Withholding Details",
"owner": "Administrator", "owner": "Administrator",
"prepared_report": 0, "prepared_report": 0,
"ref_doctype": "Purchase Invoice", "ref_doctype": "Purchase Invoice",
"report_name": "TDS Payable Monthly", "report_name": "Tax Withholding Details",
"report_type": "Script Report", "report_type": "Script Report",
"roles": [ "roles": [
{ {

View File

@ -33,77 +33,94 @@ def validate_filters(filters):
def get_result( def get_result(
filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map, invoice_net_total_map filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map, invoice_net_total_map
): ):
supplier_map = get_supplier_pan_map() party_map = get_party_pan_map(filters.get("party_type"))
tax_rate_map = get_tax_rate_map(filters) tax_rate_map = get_tax_rate_map(filters)
gle_map = get_gle_map(tds_docs) gle_map = get_gle_map(tds_docs)
out = [] out = []
for name, details in gle_map.items(): for name, details in gle_map.items():
tds_deducted, total_amount_credited = 0, 0 tax_amount, total_amount = 0, 0
tax_withholding_category = tax_category_map.get(name) tax_withholding_category = tax_category_map.get(name)
rate = tax_rate_map.get(tax_withholding_category) rate = tax_rate_map.get(tax_withholding_category)
for entry in details: for entry in details:
supplier = entry.party or entry.against party = entry.party or entry.against
posting_date = entry.posting_date posting_date = entry.posting_date
voucher_type = entry.voucher_type voucher_type = entry.voucher_type
if voucher_type == "Journal Entry": if voucher_type == "Journal Entry":
suppliers = journal_entry_party_map.get(name) party_list = journal_entry_party_map.get(name)
if suppliers: if party_list:
supplier = suppliers[0] party = party_list[0]
if not tax_withholding_category: if not tax_withholding_category:
tax_withholding_category = supplier_map.get(supplier, {}).get("tax_withholding_category") tax_withholding_category = party_map.get(party, {}).get("tax_withholding_category")
rate = tax_rate_map.get(tax_withholding_category) rate = tax_rate_map.get(tax_withholding_category)
if entry.account in tds_accounts: if entry.account in tds_accounts:
tds_deducted += entry.credit - entry.debit tax_amount += entry.credit - entry.debit
if invoice_net_total_map.get(name): if invoice_net_total_map.get(name):
total_amount_credited = invoice_net_total_map.get(name) total_amount = invoice_net_total_map.get(name)
else: else:
total_amount_credited += entry.credit total_amount += entry.credit
if tax_amount:
if party_map.get(party, {}).get("party_type") == "Supplier":
party_name = "supplier_name"
party_type = "supplier_type"
table_name = "Supplier"
else:
party_name = "customer_name"
party_type = "customer_type"
table_name = "Customer"
if tds_deducted:
row = { row = {
"pan" "pan"
if frappe.db.has_column("Supplier", "pan") if frappe.db.has_column(table_name, "pan")
else "tax_id": supplier_map.get(supplier, {}).get("pan"), else "tax_id": party_map.get(party, {}).get("pan"),
"supplier": supplier_map.get(supplier, {}).get("name"), "party": party_map.get(party, {}).get("name"),
} }
if filters.naming_series == "Naming Series": if filters.naming_series == "Naming Series":
row.update({"supplier_name": supplier_map.get(supplier, {}).get("supplier_name")}) row.update({"party_name": party_map.get(party, {}).get(party_name)})
row.update( row.update(
{ {
"section_code": tax_withholding_category, "section_code": tax_withholding_category,
"entity_type": supplier_map.get(supplier, {}).get("supplier_type"), "entity_type": party_map.get(party, {}).get(party_type),
"tds_rate": rate, "rate": rate,
"total_amount_credited": total_amount_credited, "total_amount": total_amount,
"tds_deducted": tds_deducted, "tax_amount": tax_amount,
"transaction_date": posting_date, "transaction_date": posting_date,
"transaction_type": voucher_type, "transaction_type": voucher_type,
"ref_no": name, "ref_no": name,
} }
) )
out.append(row) out.append(row)
return out return out
def get_supplier_pan_map(): def get_party_pan_map(party_type):
supplier_map = frappe._dict() party_map = frappe._dict()
suppliers = frappe.db.get_all(
"Supplier", fields=["name", "pan", "supplier_type", "supplier_name", "tax_withholding_category"]
)
for d in suppliers: fields = ["name", "tax_withholding_category"]
supplier_map[d.name] = d if party_type == "Supplier":
fields += ["supplier_type", "supplier_name"]
else:
fields += ["customer_type", "customer_name"]
return supplier_map if frappe.db.has_column(party_type, "pan"):
fields.append("pan")
party_details = frappe.db.get_all(party_type, fields=fields)
for party in party_details:
party.party_type = party_type
party_map[party.name] = party
return party_map
def get_gle_map(documents): def get_gle_map(documents):
@ -131,17 +148,17 @@ def get_columns(filters):
columns = [ columns = [
{"label": _(frappe.unscrub(pan)), "fieldname": pan, "fieldtype": "Data", "width": 90}, {"label": _(frappe.unscrub(pan)), "fieldname": pan, "fieldtype": "Data", "width": 90},
{ {
"label": _("Supplier"), "label": _(filters.get("party_type")),
"options": "Supplier", "fieldname": "party",
"fieldname": "supplier", "fieldtype": "Dynamic Link",
"fieldtype": "Link", "options": "party_type",
"width": 180, "width": 180,
}, },
] ]
if filters.naming_series == "Naming Series": if filters.naming_series == "Naming Series":
columns.append( columns.append(
{"label": _("Supplier Name"), "fieldname": "supplier_name", "fieldtype": "Data", "width": 180} {"label": _("Party Name"), "fieldname": "party_name", "fieldtype": "Data", "width": 180}
) )
columns.extend( columns.extend(
@ -153,17 +170,22 @@ def get_columns(filters):
"fieldtype": "Link", "fieldtype": "Link",
"width": 180, "width": 180,
}, },
{"label": _("Entity Type"), "fieldname": "entity_type", "fieldtype": "Data", "width": 180}, {"label": _("Entity Type"), "fieldname": "entity_type", "fieldtype": "Data", "width": 120},
{"label": _("TDS Rate %"), "fieldname": "tds_rate", "fieldtype": "Percent", "width": 90},
{ {
"label": _("Total Amount Credited"), "label": _("TDS Rate %") if filters.get("party_type") == "Supplier" else _("TCS Rate %"),
"fieldname": "total_amount_credited", "fieldname": "rate",
"fieldtype": "Percent",
"width": 90,
},
{
"label": _("Total Amount"),
"fieldname": "total_amount",
"fieldtype": "Float", "fieldtype": "Float",
"width": 90, "width": 90,
}, },
{ {
"label": _("Amount of TDS Deducted"), "label": _("TDS Amount") if filters.get("party_type") == "Supplier" else _("TCS Amount"),
"fieldname": "tds_deducted", "fieldname": "tax_amount",
"fieldtype": "Float", "fieldtype": "Float",
"width": 90, "width": 90,
}, },
@ -173,13 +195,13 @@ def get_columns(filters):
"fieldtype": "Date", "fieldtype": "Date",
"width": 90, "width": 90,
}, },
{"label": _("Transaction Type"), "fieldname": "transaction_type", "width": 90}, {"label": _("Transaction Type"), "fieldname": "transaction_type", "width": 100},
{ {
"label": _("Reference No."), "label": _("Reference No."),
"fieldname": "ref_no", "fieldname": "ref_no",
"fieldtype": "Dynamic Link", "fieldtype": "Dynamic Link",
"options": "transaction_type", "options": "transaction_type",
"width": 90, "width": 180,
}, },
] ]
) )
@ -190,6 +212,7 @@ def get_columns(filters):
def get_tds_docs(filters): def get_tds_docs(filters):
tds_documents = [] tds_documents = []
purchase_invoices = [] purchase_invoices = []
sales_invoices = []
payment_entries = [] payment_entries = []
journal_entries = [] journal_entries = []
tax_category_map = frappe._dict() tax_category_map = frappe._dict()
@ -209,10 +232,13 @@ def get_tds_docs(filters):
"against": ("not in", bank_accounts), "against": ("not in", bank_accounts),
} }
if filters.get("supplier"): party = frappe.get_all(filters.get("party_type"), pluck="name")
query_filters.update({"against": ("in", party)})
if filters.get("party"):
del query_filters["account"] del query_filters["account"]
del query_filters["against"] del query_filters["against"]
or_filters = {"against": filters.get("supplier"), "party": filters.get("supplier")} or_filters = {"against": filters.get("party"), "party": filters.get("party")}
tds_docs = frappe.get_all( tds_docs = frappe.get_all(
"GL Entry", "GL Entry",
@ -224,6 +250,8 @@ def get_tds_docs(filters):
for d in tds_docs: for d in tds_docs:
if d.voucher_type == "Purchase Invoice": if d.voucher_type == "Purchase Invoice":
purchase_invoices.append(d.voucher_no) purchase_invoices.append(d.voucher_no)
if d.voucher_type == "Sales Invoice":
sales_invoices.append(d.voucher_no)
elif d.voucher_type == "Payment Entry": elif d.voucher_type == "Payment Entry":
payment_entries.append(d.voucher_no) payment_entries.append(d.voucher_no)
elif d.voucher_type == "Journal Entry": elif d.voucher_type == "Journal Entry":
@ -234,6 +262,9 @@ def get_tds_docs(filters):
if purchase_invoices: if purchase_invoices:
get_doc_info(purchase_invoices, "Purchase Invoice", tax_category_map, invoice_net_total_map) get_doc_info(purchase_invoices, "Purchase Invoice", tax_category_map, invoice_net_total_map)
if sales_invoices:
get_doc_info(sales_invoices, "Sales Invoice", tax_category_map, invoice_net_total_map)
if payment_entries: if payment_entries:
get_doc_info(payment_entries, "Payment Entry", tax_category_map) get_doc_info(payment_entries, "Payment Entry", tax_category_map)
@ -267,6 +298,8 @@ def get_journal_entry_party_map(journal_entries):
def get_doc_info(vouchers, doctype, tax_category_map, invoice_net_total_map=None): def get_doc_info(vouchers, doctype, tax_category_map, invoice_net_total_map=None):
if doctype == "Purchase Invoice": if doctype == "Purchase Invoice":
fields = ["name", "tax_withholding_category", "base_tax_withholding_net_total"] fields = ["name", "tax_withholding_category", "base_tax_withholding_net_total"]
if doctype == "Sales Invoice":
fields = ["name", "base_net_total"]
else: else:
fields = ["name", "tax_withholding_category"] fields = ["name", "tax_withholding_category"]
@ -276,6 +309,8 @@ def get_doc_info(vouchers, doctype, tax_category_map, invoice_net_total_map=None
tax_category_map.update({entry.name: entry.tax_withholding_category}) tax_category_map.update({entry.name: entry.tax_withholding_category})
if doctype == "Purchase Invoice": if doctype == "Purchase Invoice":
invoice_net_total_map.update({entry.name: entry.base_tax_withholding_net_total}) invoice_net_total_map.update({entry.name: entry.base_tax_withholding_net_total})
if doctype == "Sales Invoice":
invoice_net_total_map.update({entry.name: entry.base_net_total})
def get_tax_rate_map(filters): def get_tax_rate_map(filters):

View File

@ -1,37 +0,0 @@
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.query_reports["TDS Payable Monthly"] = {
"filters": [
{
"fieldname":"company",
"label": __("Company"),
"fieldtype": "Link",
"options": "Company",
"default": frappe.defaults.get_default('company')
},
{
"fieldname":"supplier",
"label": __("Supplier"),
"fieldtype": "Link",
"options": "Supplier",
},
{
"fieldname":"from_date",
"label": __("From Date"),
"fieldtype": "Date",
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
"reqd": 1,
"width": "60px"
},
{
"fieldname":"to_date",
"label": __("To Date"),
"fieldtype": "Date",
"default": frappe.datetime.get_today(),
"reqd": 1,
"width": "60px"
}
]
}

View File

@ -262,6 +262,7 @@ erpnext.patches.v14_0.update_reference_due_date_in_journal_entry
erpnext.patches.v15_0.saudi_depreciation_warning erpnext.patches.v15_0.saudi_depreciation_warning
erpnext.patches.v15_0.delete_saudi_doctypes erpnext.patches.v15_0.delete_saudi_doctypes
erpnext.patches.v14_0.show_loan_management_deprecation_warning erpnext.patches.v14_0.show_loan_management_deprecation_warning
execute:frappe.rename_doc("Report", "TDS Payable Monthly", "Tax Withholding Details", force=True)
[post_model_sync] [post_model_sync]
execute:frappe.delete_doc_if_exists('Workspace', 'ERPNext Integrations Settings') execute:frappe.delete_doc_if_exists('Workspace', 'ERPNext Integrations Settings')