From dd37f6cbd631a1e2e74bc6f81f6dadc9a794fcad Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Wed, 19 Jul 2023 11:51:45 +0530 Subject: [PATCH] fix: show tax withholding category details for customers --- .../tds_payable_monthly.js | 21 +++- .../tds_payable_monthly.py | 101 ++++++++++++------ 2 files changed, 84 insertions(+), 38 deletions(-) diff --git a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.js b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.js index ff2aa30601..d7f396d298 100644 --- a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.js +++ b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.js @@ -12,10 +12,23 @@ frappe.query_reports["TDS Payable Monthly"] = { "default": frappe.defaults.get_default('company') }, { - "fieldname":"supplier", - "label": __("Supplier"), - "fieldtype": "Link", - "options": "Supplier", + "fieldname":"party_type", + "label": __("Party Type"), + "fieldtype": "Select", + "options": ["Supplier", "Customer"] + }, + { + "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", diff --git a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py index 98838907be..7304448f83 100644 --- a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py +++ b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py @@ -33,77 +33,95 @@ def validate_filters(filters): def get_result( 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() tax_rate_map = get_tax_rate_map(filters) gle_map = get_gle_map(tds_docs) out = [] for name, details in gle_map.items(): - tds_deducted, total_amount_credited = 0, 0 + tax_deducted, total_amount_credited = 0, 0 tax_withholding_category = tax_category_map.get(name) rate = tax_rate_map.get(tax_withholding_category) for entry in details: - supplier = entry.party or entry.against + party = entry.party or entry.against posting_date = entry.posting_date voucher_type = entry.voucher_type if voucher_type == "Journal Entry": - suppliers = journal_entry_party_map.get(name) - if suppliers: - supplier = suppliers[0] + party_list = journal_entry_party_map.get(name) + if party_list: + party = party_list[0] 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) if entry.account in tds_accounts: - tds_deducted += entry.credit - entry.debit + tax_deducted += entry.credit - entry.debit if invoice_net_total_map.get(name): total_amount_credited = invoice_net_total_map.get(name) else: total_amount_credited += entry.credit - if tds_deducted: + if tax_deducted: + 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" + row = { "pan" - if frappe.db.has_column("Supplier", "pan") - else "tax_id": supplier_map.get(supplier, {}).get("pan"), - "supplier": supplier_map.get(supplier, {}).get("name"), + if frappe.db.has_column(table_name, "pan") + else "tax_id": party_map.get(party, {}).get("pan"), + "party": party_map.get(party, {}).get("name"), } 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( { "section_code": tax_withholding_category, - "entity_type": supplier_map.get(supplier, {}).get("supplier_type"), - "tds_rate": rate, + "entity_type": party_map.get(party, {}).get(party_type), + "rate": rate, "total_amount_credited": total_amount_credited, - "tds_deducted": tds_deducted, + "tax_deducted": tax_deducted, "transaction_date": posting_date, "transaction_type": voucher_type, "ref_no": name, + "party_type": party_map.get(party, {}).get("party_type"), } ) - out.append(row) return out -def get_supplier_pan_map(): - supplier_map = frappe._dict() - suppliers = frappe.db.get_all( - "Supplier", fields=["name", "pan", "supplier_type", "supplier_name", "tax_withholding_category"] - ) +def get_party_pan_map(): + party_map = frappe._dict() + fields = ["name", "supplier_type", "supplier_name", "tax_withholding_category"] + if frappe.db.has_column("Supplier", "pan"): + fields.append("pan") + suppliers = frappe.db.get_all("Supplier", fields=fields) + fields = ["name", "customer_type", "customer_name", "tax_withholding_category"] + if frappe.db.has_column("Customer", "pan"): + fields.append("pan") + customers = frappe.db.get_all("Customer", fields=fields) for d in suppliers: - supplier_map[d.name] = d + d.party_type = "Supplier" + party_map[d.name] = d + for d in customers: + d.party_type = "Customer" + party_map[d.name] = d - return supplier_map + return party_map def get_gle_map(documents): @@ -131,17 +149,22 @@ def get_columns(filters): columns = [ {"label": _(frappe.unscrub(pan)), "fieldname": pan, "fieldtype": "Data", "width": 90}, { - "label": _("Supplier"), - "options": "Supplier", - "fieldname": "supplier", - "fieldtype": "Link", + "label": _("Party Type"), + "fieldname": "party_type", + "width": 180, + }, + { + "label": _("Party"), + "fieldname": "party", + "fieldtype": "Dynamic Link", + "options": "party_type", "width": 180, }, ] if filters.naming_series == "Naming Series": columns.append( - {"label": _("Supplier Name"), "fieldname": "supplier_name", "fieldtype": "Data", "width": 180} + {"label": _("Party Name"), "fieldname": "party_name", "fieldtype": "Data", "width": 180} ) columns.extend( @@ -154,7 +177,7 @@ def get_columns(filters): "width": 180, }, {"label": _("Entity Type"), "fieldname": "entity_type", "fieldtype": "Data", "width": 180}, - {"label": _("TDS Rate %"), "fieldname": "tds_rate", "fieldtype": "Percent", "width": 90}, + {"label": _("Rate %"), "fieldname": "rate", "fieldtype": "Percent", "width": 90}, { "label": _("Total Amount Credited"), "fieldname": "total_amount_credited", @@ -162,8 +185,8 @@ def get_columns(filters): "width": 90, }, { - "label": _("Amount of TDS Deducted"), - "fieldname": "tds_deducted", + "label": _("Amount of Tax Deducted"), + "fieldname": "tax_deducted", "fieldtype": "Float", "width": 90, }, @@ -190,6 +213,7 @@ def get_columns(filters): def get_tds_docs(filters): tds_documents = [] purchase_invoices = [] + sales_invoices = [] payment_entries = [] journal_entries = [] tax_category_map = frappe._dict() @@ -209,10 +233,10 @@ def get_tds_docs(filters): "against": ("not in", bank_accounts), } - if filters.get("supplier"): + if filters.get("party"): del query_filters["account"] 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( "GL Entry", @@ -224,6 +248,8 @@ def get_tds_docs(filters): for d in tds_docs: if d.voucher_type == "Purchase Invoice": purchase_invoices.append(d.voucher_no) + if d.voucher_type == "Sales Invoice": + sales_invoices.append(d.voucher_no) elif d.voucher_type == "Payment Entry": payment_entries.append(d.voucher_no) elif d.voucher_type == "Journal Entry": @@ -234,6 +260,9 @@ def get_tds_docs(filters): if purchase_invoices: 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: get_doc_info(payment_entries, "Payment Entry", tax_category_map) @@ -267,6 +296,8 @@ def get_journal_entry_party_map(journal_entries): def get_doc_info(vouchers, doctype, tax_category_map, invoice_net_total_map=None): if doctype == "Purchase Invoice": fields = ["name", "tax_withholding_category", "base_tax_withholding_net_total"] + if doctype == "Sales Invoice": + fields = ["name", "base_net_total"] else: fields = ["name", "tax_withholding_category"] @@ -276,6 +307,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}) if doctype == "Purchase Invoice": 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):