diff --git a/india_compliance/gst_india/api_classes/taxpayer_base.py b/india_compliance/gst_india/api_classes/taxpayer_base.py index da77b0058..1a7efdcd4 100644 --- a/india_compliance/gst_india/api_classes/taxpayer_base.py +++ b/india_compliance/gst_india/api_classes/taxpayer_base.py @@ -367,9 +367,11 @@ def get(self, *args, **kwargs): return self._request("get", *args, **kwargs, params=params) def post(self, *args, **kwargs): + self.default_log_values.update(update_gstr_action=True) return self._request("post", *args, **kwargs) def put(self, *args, **kwargs): + self.default_log_values.update(update_gstr_action=True) return self._request("put", *args, **kwargs) def before_request(self, request_args): diff --git a/india_compliance/gst_india/doctype/gst_invoice_management_system/__init__.py b/india_compliance/gst_india/doctype/gst_invoice_management_system/__init__.py index dde5bb557..8ff9ec221 100644 --- a/india_compliance/gst_india/doctype/gst_invoice_management_system/__init__.py +++ b/india_compliance/gst_india/doctype/gst_invoice_management_system/__init__.py @@ -149,7 +149,7 @@ def __init__(self): self.PI_ITEM = frappe.qb.DocType("Purchase Invoice Item") def get_all(self, names=None, filters=None): - query = self.get_query(filters=filters) + query = self.get_query(filters=filters, additional_fields=["posting_date"]) if names: query = query.where(self.PI.name.isin(names)) diff --git a/india_compliance/gst_india/doctype/gst_invoice_management_system/gst_invoice_management_system.css b/india_compliance/gst_india/doctype/gst_invoice_management_system/gst_invoice_management_system.css index 003527b27..4f36260a1 100644 --- a/india_compliance/gst_india/doctype/gst_invoice_management_system/gst_invoice_management_system.css +++ b/india_compliance/gst_india/doctype/gst_invoice_management_system/gst_invoice_management_system.css @@ -12,6 +12,10 @@ div[data-page-route="GST Invoice Management System"] margin-top: 0; } +div[data-page-route="GST Invoice Management System"] [data-fieldname="data_section"] { + padding-top: 0; +} + div[data-page-route="GST Invoice Management System"] [data-fieldname="invoice_html"] .form-tabs-list { diff --git a/india_compliance/gst_india/doctype/gst_invoice_management_system/gst_invoice_management_system.js b/india_compliance/gst_india/doctype/gst_invoice_management_system/gst_invoice_management_system.js index d693e4348..0e8a95fb5 100644 --- a/india_compliance/gst_india/doctype/gst_invoice_management_system/gst_invoice_management_system.js +++ b/india_compliance/gst_india/doctype/gst_invoice_management_system/gst_invoice_management_system.js @@ -343,7 +343,7 @@ class IMS extends reconciliation.reconciliation_tabs { }, { label: "Bill No.", - fieldname: "bill_no", + fieldname: "bill_no_date", align: "center", width: 120, }, @@ -414,7 +414,7 @@ class IMS extends reconciliation.reconciliation_tabs { data.push({ supplier_name_gstin: this.get_supplier_name_gstin(row), - bill_no: row.bill_no, + bill_no_date: this.get_bill_no_bill_date(row), classification: row._inward_supply.classification, ims_action: row.ims_action || "", match_status: row.match_status, @@ -424,6 +424,7 @@ class IMS extends reconciliation.reconciliation_tabs { inward_supply_name: row.inward_supply_name, pending_upload: row.pending_upload, is_supplier_return_filed: row.is_supplier_return_filed, + linked_voucher_type: row._purchase_invoice.doctype, }); }); @@ -530,7 +531,7 @@ class IMS extends reconciliation.reconciliation_tabs { .join(""); const action_performed_html = ` -
+
${action_performed_cards}
`; @@ -553,6 +554,14 @@ class IMS extends reconciliation.reconciliation_tabs { me.update_filter(e, "ims_action", action, me); }); } + + get_bill_no_bill_date(row) { + return ` + ${row.bill_no} +
+ ${frappe.datetime.str_to_user(row.bill_date) || ""} + `; + } } class IMSAction { @@ -580,10 +589,14 @@ class IMSAction { ); } + // Download Button this.frm.add_custom_button(__("Download Invoices"), () => { render_empty_state(this.frm); this.download_ims_data(); }); + + // Export button + this.frm.add_custom_button(__("Export"), () => this.export_data()); } setup_row_actions() { @@ -767,6 +780,21 @@ class IMSAction { indicator: "green", }); } + + async export_data() { + if (!this.frm.reconciliation_tabs.filtered_data) { + await this.frm.ims_actions.get_ims_data(); + } + + const url = `${DOC_PATH}.download_excel_report`; + open_url_post(`/api/method/${url}`, { + data: JSON.stringify(this.frm.reconciliation_tabs.filtered_data), + doc: JSON.stringify({ + company: this.frm.doc.company, + company_gstin: this.frm.doc.company_gstin, + }), + }); + } } class DetailViewDialog extends reconciliation.detail_view_dialog { diff --git a/india_compliance/gst_india/doctype/gst_invoice_management_system/gst_invoice_management_system.py b/india_compliance/gst_india/doctype/gst_invoice_management_system/gst_invoice_management_system.py index ed8bc1ad9..59817300c 100644 --- a/india_compliance/gst_india/doctype/gst_invoice_management_system/gst_invoice_management_system.py +++ b/india_compliance/gst_india/doctype/gst_invoice_management_system/gst_invoice_management_system.py @@ -4,6 +4,7 @@ import frappe from frappe import _ from frappe.model.document import Document +from frappe.utils import format_date from india_compliance.gst_india.api_classes.taxpayer_base import ( TaxpayerBaseAPI, @@ -23,6 +24,9 @@ from india_compliance.gst_india.doctype.purchase_reconciliation_tool import ( ReconciledData, ) +from india_compliance.gst_india.doctype.purchase_reconciliation_tool.purchase_reconciliation_tool import ( + BuildExcel, +) from india_compliance.gst_india.doctype.purchase_reconciliation_tool.purchase_reconciliation_utils import ( get_formatted_options, ) @@ -32,6 +36,7 @@ from india_compliance.gst_india.doctype.purchase_reconciliation_tool.purchase_reconciliation_utils import ( unlink_documents as _unlink_documents, ) +from india_compliance.gst_india.utils.exporter import ExcelExporter from india_compliance.gst_india.utils.gstr_2 import ( GSTRCategory, ReturnType, @@ -92,6 +97,8 @@ def get_invoice_data(self, inward_supply=None, purchase=None, filters=None): invoice_data = [] for doc in inward_supplies: + _purchase_invoice = purchases.pop(doc.link_name, frappe._dict()) + invoice_data.append( frappe._dict( { @@ -101,10 +108,11 @@ def get_invoice_data(self, inward_supply=None, purchase=None, filters=None): "is_pending_action_allowed": doc.is_pending_action_allowed, "is_supplier_return_filed": doc.is_supplier_return_filed, "doc_type": doc.doc_type, - "_inward_supply": doc, - "_purchase_invoice": purchases.pop( - doc.link_name, frappe._dict() + "posting_date": format_date( + _purchase_invoice.pop("posting_date", None) ), + "_inward_supply": doc, + "_purchase_invoice": _purchase_invoice, } ) ) @@ -259,6 +267,14 @@ def check_action_status(company_gstin, action): return process_save_or_reset_ims(ims_log, action) +@frappe.whitelist() +def download_excel_report(data, doc): + frappe.has_permission("GST Invoice Management System", "export", throw=True) + + build_data = BuildExcelIMS(doc, data) + build_data.export_data() + + def download_and_upload_ims_invoices(company_gstin): """ 1. This function will download invoices from GST Portal, @@ -384,37 +400,140 @@ def process_save_or_reset_ims(return_log, action): if status_cd in ["P", "PE"]: # Exclude erroneous invoices from previous IMS action update - # This is enqueued because linking of integration request is enqueued + # This is enqueued because creation of integration request is enqueued # TODO: flag for re-upload? frappe.enqueue( update_previous_ims_action, queue="long", - integration_request=doc.integration_request, + request_id=doc.request_id, error_report=response.get("error_report") or dict(), ) return response -def update_previous_ims_action(integration_request, error_report=None): - uploaded_invoices = get_uploaded_invoices(integration_request) +def update_previous_ims_action(request_id, error_report=None): + uploaded_invoices = get_uploaded_invoices(request_id) for category, invoices in uploaded_invoices.items(): _class = get_data_handler(ReturnType.IMS.value, category.upper()) _class().update_previous_ims_action(invoices, error_report.get(category, [])) -def get_uploaded_invoices(integration_request): +def get_uploaded_invoices(request_id): request_data = frappe.parse_json( - frappe.db.get_value( - "Integration Request", {"name": integration_request}, "data" - ) + frappe.db.get_value("Integration Request", {"request_id": request_id}, "data") ) if not request_data: - return {} + frappe.throw( + _( + "Integration Request linked with data upload not found for request id {0}" + ).format(request_id) + ) if isinstance(request_data, str): request_data = frappe.parse_json(request_data) return request_data["body"]["data"]["invdata"] + + +class BuildExcelIMS(BuildExcel): + def export_data(self): + """Exports data to an excel file""" + excel = ExcelExporter() + excel.create_sheet( + sheet_name="Invoice Data", + filters=self.filters, + headers=self.invoice_header, + data=self.data, + default_data_format={"horizontal": "center"}, + default_header_format={"bg_color": self.COLOR_PALLATE.dark_gray}, + ) + + excel.remove_sheet("Sheet") + file_name = self.get_file_name() + excel.export(file_name) + + def set_headers(self): + """Sets headers for the excel file""" + self.invoice_header = self.get_invoice_columns() + + def set_filters(self): + """Add filters to the sheet""" + self.filters = frappe._dict( + { + "Company Name": self.doc.company, + "GSTIN": self.doc.company_gstin, + } + ) + + def get_file_name(self): + """Returns file name for the excel file""" + return f"{self.doc.company}_{self.doc.company_gstin}_report" + + def get_invoice_columns(self): + return [ + { + "label": "Supplier Name", + "fieldname": "supplier_name", + "header_format": {"width": 35}, + }, + { + "label": "Supplier GSTIN", + "fieldname": "supplier_gstin", + }, + { + "label": "Bill No", + "fieldname": "bill_no", + }, + { + "label": "Bill Date", + "fieldname": "bill_date", + }, + { + "label": "Match Status", + "fieldname": "match_status", + }, + { + "label": "IMS Action", + "fieldname": "ims_action", + }, + { + "label": "Inward Supply Name", + "fieldname": "inward_supply_name", + }, + { + "label": "Linked Voucher", + "fieldname": "purchase_invoice_name", + }, + { + "label": "Posting Date", + "fieldname": "posting_date", + }, + { + "label": "Taxable Amount Diff \n 2A/2B - Purchase", + "fieldname": "taxable_value_difference", + "fieldtype": "Float", + "data_format": { + "bg_color": self.COLOR_PALLATE.light_pink, + "number_format": "0.00", + "horizontal": "right", + }, + }, + { + "label": "Tax Difference \n 2A/2B - Purchase", + "fieldname": "tax_difference", + "fieldtype": "Float", + "data_format": { + "bg_color": self.COLOR_PALLATE.light_pink, + "number_format": "0.00", + "horizontal": "right", + }, + }, + { + "label": "Classification", + "fieldname": "classification", + "header_format": {"width": 11}, + }, + ] diff --git a/india_compliance/gst_india/doctype/gstr_action/gstr_action.json b/india_compliance/gst_india/doctype/gstr_action/gstr_action.json index 39dc83d30..1517cdc02 100644 --- a/india_compliance/gst_india/doctype/gstr_action/gstr_action.json +++ b/india_compliance/gst_india/doctype/gstr_action/gstr_action.json @@ -7,6 +7,7 @@ "engine": "InnoDB", "field_order": [ "request_type", + "request_id", "token", "status", "creation_time", @@ -44,12 +45,18 @@ "label": "Integration Request", "options": "Integration Request", "read_only": 1 + }, + { + "fieldname": "request_id", + "fieldtype": "Data", + "hidden": 1, + "label": "Request id" } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2024-09-12 12:36:05.679413", + "modified": "2025-01-22 16:33:57.014368", "modified_by": "Administrator", "module": "GST India", "name": "GSTR Action", diff --git a/india_compliance/gst_india/doctype/gstr_action/gstr_action.py b/india_compliance/gst_india/doctype/gstr_action/gstr_action.py index 5f99f6a0a..5d4263f5c 100644 --- a/india_compliance/gst_india/doctype/gstr_action/gstr_action.py +++ b/india_compliance/gst_india/doctype/gstr_action/gstr_action.py @@ -15,6 +15,7 @@ def set_gstr_actions(doc, request_type, token, request_id, status=None): row = { "request_type": request_type, + "request_id": request_id, "token": token, "creation_time": frappe.utils.now_datetime(), } @@ -24,22 +25,3 @@ def set_gstr_actions(doc, request_type, token, request_id, status=None): doc.append("actions", row) doc.save() - enqueue_link_integration_request(token, request_id) - - -def enqueue_link_integration_request(token, request_id): - """ - Integration request is enqueued. Hence, it's name is not available immediately. - Hence, link it after the request is processed. - """ - frappe.enqueue( - link_integration_request, queue="long", token=token, request_id=request_id - ) - - -def link_integration_request(token, request_id): - doc_name = frappe.db.get_value("Integration Request", {"request_id": request_id}) - if doc_name: - frappe.db.set_value( - "GSTR Action", {"token": token}, {"integration_request": doc_name} - ) diff --git a/india_compliance/gst_india/doctype/purchase_reconciliation_tool/__init__.py b/india_compliance/gst_india/doctype/purchase_reconciliation_tool/__init__.py index fd8bd3a64..4137c0558 100644 --- a/india_compliance/gst_india/doctype/purchase_reconciliation_tool/__init__.py +++ b/india_compliance/gst_india/doctype/purchase_reconciliation_tool/__init__.py @@ -1137,6 +1137,7 @@ def process_data(self, reconciliation_data: list, retain_doc: bool = False): "differences": "", "action": "", "classification": "", + "is_reverse_charge": "", } for data in reconciliation_data: @@ -1154,7 +1155,13 @@ def process_data(self, reconciliation_data: list, retain_doc: bool = False): BaseUtil.update_cess_amount(purchase) def update_fields(self, data, purchase, inward_supply): - for field in ("supplier_name", "supplier_gstin", "bill_no", "bill_date"): + for field in ( + "supplier_name", + "supplier_gstin", + "bill_no", + "bill_date", + "is_reverse_charge", + ): data[field] = purchase.get(field) or inward_supply.get(field) data.update( diff --git a/india_compliance/gst_india/utils/api.py b/india_compliance/gst_india/utils/api.py index efcb63df3..81cb46222 100644 --- a/india_compliance/gst_india/utils/api.py +++ b/india_compliance/gst_india/utils/api.py @@ -17,8 +17,9 @@ def create_integration_request( error=None, reference_doctype=None, reference_name=None, + update_gstr_action=False, ): - return frappe.get_doc( + doc = frappe.get_doc( { "doctype": "Integration Request", "integration_request_service": "India Compliance API", @@ -32,7 +33,17 @@ def create_integration_request( "reference_doctype": reference_doctype, "reference_docname": reference_name, } - ).insert(ignore_permissions=True) + ) + doc.insert(ignore_permissions=True) + + if update_gstr_action: + link_integration_request(request_id, doc.name) + + +def link_integration_request(request_id, doc_name): + frappe.db.set_value( + "GSTR Action", {"request_id": request_id}, {"integration_request": doc_name} + ) def pretty_json(obj): diff --git a/india_compliance/gst_india/utils/gstr_2/__init__.py b/india_compliance/gst_india/utils/gstr_2/__init__.py index 8d373ad58..ad31984e6 100644 --- a/india_compliance/gst_india/utils/gstr_2/__init__.py +++ b/india_compliance/gst_india/utils/gstr_2/__init__.py @@ -306,6 +306,7 @@ def save_gstr_2b(gstin, return_period, json_data): return_type, return_period, json_data.get("docdata"), + json_data.get("docRejdata"), json_data.get("gendt"), ) update_import_history(return_period) @@ -316,7 +317,12 @@ def save_ims_invoices(gstin, return_period, json_data): def save_gstr( - gstin, return_type: ReturnType, return_period, json_data, gen_date_2b=None + gstin, + return_type: ReturnType, + return_period, + json_data, + rejected_data=None, + gen_date_2b=None, ): """Save GSTR data to Inward Supply @@ -324,6 +330,8 @@ def save_gstr( :param json_data: dict of list (GSTR category: suppliers) :param gen_date_2b: str (Date when GSTR 2B was generated) """ + if not rejected_data: + rejected_data = {} company = get_party_for_gstin(gstin, "Company") for category in GSTRCategory: @@ -331,9 +339,9 @@ def save_gstr( if not gstr: continue - gstr(company, gstin, return_period, json_data, gen_date_2b).create_transactions( - category, + gstr(company, gstin, return_period, gen_date_2b).create_transactions( json_data.get(category.value.lower()), + rejected_data.get(category.value.lower()), ) diff --git a/india_compliance/gst_india/utils/gstr_2/gstr.py b/india_compliance/gst_india/utils/gstr_2/gstr.py index e77ff2bb9..3db1aa1cd 100644 --- a/india_compliance/gst_india/utils/gstr_2/gstr.py +++ b/india_compliance/gst_india/utils/gstr_2/gstr.py @@ -32,22 +32,25 @@ class GSTR: } ) - def __init__(self, company, gstin, return_period, data, gen_date_2b): + def __init__(self, company, gstin, return_period, gen_date_2b): self.company = company self.gstin = gstin self.return_period = return_period - self._data = data self.gen_date_2b = gen_date_2b + self.category = type(self).__name__[6:] self.setup() def setup(self): self.existing_transaction = self.get_existing_transaction() - def create_transactions(self, category, suppliers): + def create_transactions(self, suppliers, rejected_data): + self.rejected_data = rejected_data or [] + if not suppliers: + self.handle_missing_transactions() return - transactions = self.get_all_transactions(category, suppliers) + transactions = self.get_all_transactions(suppliers) total_transactions = len(transactions) current_transaction = 0 @@ -75,28 +78,26 @@ def handle_missing_transactions(self): def get_existing_transaction(self): return {} - def get_all_transactions(self, category, suppliers): + def get_all_transactions(self, suppliers): transactions = [] for supplier in suppliers: - transactions.extend(self.get_supplier_transactions(category, supplier)) + transactions.extend(self.get_supplier_transactions(supplier)) self.update_gstins() return transactions - def get_supplier_transactions(self, category, supplier): + def get_supplier_transactions(self, supplier): return [ - self.get_transaction( - category, frappe._dict(supplier), frappe._dict(invoice) - ) + self.get_transaction(frappe._dict(supplier), frappe._dict(invoice)) for invoice in supplier.get(self.get_key("invoice_key")) ] - def get_transaction(self, category, supplier, invoice): + def get_transaction(self, supplier, invoice): transaction = frappe._dict( company=self.company, company_gstin=self.gstin, - classification=category.value, + classification=self.category, **self.get_supplier_details(supplier), **self.get_invoice_details(invoice), **self.get_download_details(), diff --git a/india_compliance/gst_india/utils/gstr_2/gstr_2a.py b/india_compliance/gst_india/utils/gstr_2/gstr_2a.py index e76fd8990..3c01ed706 100644 --- a/india_compliance/gst_india/utils/gstr_2/gstr_2a.py +++ b/india_compliance/gst_india/utils/gstr_2/gstr_2a.py @@ -19,14 +19,12 @@ def setup(self): self.cancelled_gstins = {} def get_existing_transaction(self): - category = type(self).__name__[6:] - gst_is = frappe.qb.DocType("GST Inward Supply") existing_transactions = ( frappe.qb.from_(gst_is) .select(gst_is.name, gst_is.supplier_gstin, gst_is.bill_no) .where(gst_is.sup_return_period == self.return_period) - .where(gst_is.classification == category) + .where(gst_is.classification == self.category) .where(gst_is.gstr_1_filled == 0) ).run(as_dict=True) @@ -262,12 +260,8 @@ def get_invoice_details(self, invoice): } # invoice details are included in supplier details - def get_supplier_transactions(self, category, supplier): - return [ - self.get_transaction( - category, frappe._dict(supplier), frappe._dict(supplier) - ) - ] + def get_supplier_transactions(self, supplier): + return [self.get_transaction(frappe._dict(supplier), frappe._dict(supplier))] # item details are not available def get_transaction_items(self, invoice): diff --git a/india_compliance/gst_india/utils/gstr_2/gstr_2b.py b/india_compliance/gst_india/utils/gstr_2/gstr_2b.py index 9d898aa8a..e9ac3f591 100644 --- a/india_compliance/gst_india/utils/gstr_2/gstr_2b.py +++ b/india_compliance/gst_india/utils/gstr_2/gstr_2b.py @@ -1,5 +1,4 @@ import frappe -from frappe.query_builder.functions import IfNull from india_compliance.gst_india.utils import parse_datetime from india_compliance.gst_india.utils.gstr_2.gstr import GSTR, get_mapped_value @@ -7,14 +6,12 @@ class GSTR2b(GSTR): def get_existing_transaction(self): - category = type(self).__name__[6:] - gst_is = frappe.qb.DocType("GST Inward Supply") existing_transactions = ( frappe.qb.from_(gst_is) .select(gst_is.name, gst_is.supplier_gstin, gst_is.bill_no) .where(gst_is.return_period_2b == self.return_period) - .where(gst_is.classification == category) + .where(gst_is.classification == self.category) ).run(as_dict=True) return { @@ -31,12 +28,13 @@ def handle_missing_transactions(self): In such cases, 1) we need to clear the return_period_2b as this could change in future. - 2) safer to clear delete them as well if no matching transactions are found (possibly rejected). + 2) and delete the rejected transactions. """ if not self.existing_transaction: return missing_transactions = list(self.existing_transaction.values()) + rejected_transactions = self.get_all_transactions(self.rejected_data) # clear return_period_2b inward_supply = frappe.qb.DocType("GST Inward Supply") @@ -48,22 +46,19 @@ def handle_missing_transactions(self): .run() ) - # delete unmatched transactions - unmatched_transactions = ( - frappe.qb.from_(inward_supply) - .select(inward_supply.name) - .where(inward_supply.name.isin(missing_transactions)) - .where(IfNull(inward_supply.link_name, "") == "") - .run(pluck=True) - ) + # delete rejected transactions + for transaction in rejected_transactions: + filters = { + "bill_no": transaction.bill_no, + "bill_date": transaction.bill_date, + "classification": transaction.classification, + "supplier_gstin": transaction.supplier_gstin, + } - for transaction_name in unmatched_transactions: - frappe.delete_doc( - "GST Inward Supply", transaction_name, ignore_permissions=True - ) + frappe.delete_doc("GST Inward Supply", filters, ignore_permissions=True) - def get_transaction(self, category, supplier, invoice): - transaction = super().get_transaction(category, supplier, invoice) + def get_transaction(self, supplier, invoice): + transaction = super().get_transaction(supplier, invoice) transaction.return_period_2b = self.return_period transaction.gen_date_2b = parse_datetime(self.gen_date_2b, day_first=True) return transaction @@ -242,9 +237,5 @@ def get_supplier_details(self, supplier): return {} # invoice details are included in supplier details - def get_supplier_transactions(self, category, supplier): - return [ - self.get_transaction( - category, frappe._dict(supplier), frappe._dict(supplier) - ) - ] + def get_supplier_transactions(self, supplier): + return [self.get_transaction(frappe._dict(supplier), frappe._dict(supplier))] diff --git a/india_compliance/gst_india/utils/gstr_2/ims.py b/india_compliance/gst_india/utils/gstr_2/ims.py index 13c0bed85..2f692e782 100644 --- a/india_compliance/gst_india/utils/gstr_2/ims.py +++ b/india_compliance/gst_india/utils/gstr_2/ims.py @@ -43,10 +43,11 @@ def __init__(self, company=None, gstin=None, *args): self.company = company self.existing_transactions = self.get_existing_transactions() - def create_transactions(self, category, invoices): + def create_transactions(self, invoices, rejected_data): self.reset_previous_ims_action() if not invoices: + self.handle_missing_transactions() return transactions = self.get_all_transactions(invoices) diff --git a/india_compliance/public/js/components/data_table_manager.js b/india_compliance/public/js/components/data_table_manager.js index fe88a1eb3..02fab052a 100644 --- a/india_compliance/public/js/components/data_table_manager.js +++ b/india_compliance/public/js/components/data_table_manager.js @@ -82,7 +82,7 @@ india_compliance.DataTableManager = class DataTableManager { value = frappe.format(value, column, { always_show_decimals: true }, data); - if (column.post_format) { + if (column._after_format) { value = column._after_format(value, column, data); } diff --git a/india_compliance/public/js/components/filter_group.js b/india_compliance/public/js/components/filter_group.js index 7cee19271..d7b3da392 100644 --- a/india_compliance/public/js/components/filter_group.js +++ b/india_compliance/public/js/components/filter_group.js @@ -105,10 +105,13 @@ india_compliance.FilterGroup = class FilterGroup extends frappe.ui.FilterGroup { if (filter_value.length === 2) f_value = f_value.slice(0, 2); - return !frappe.utils.arrays_equal( + const remove = frappe.utils.arrays_equal( f_value.slice(0, 4), filter_value.slice(0, 4) ); + if (remove) f.remove(); + + return !remove; }); }