diff --git a/india_compliance/gst_india/report/india_compliance_api_usage/__init__.py b/india_compliance/gst_india/report/india_compliance_api_usage/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/india_compliance/gst_india/report/india_compliance_api_usage/india_compliance_api_usage.js b/india_compliance/gst_india/report/india_compliance_api_usage/india_compliance_api_usage.js new file mode 100644 index 0000000000..873ded23ce --- /dev/null +++ b/india_compliance/gst_india/report/india_compliance_api_usage/india_compliance_api_usage.js @@ -0,0 +1,42 @@ +// Copyright (c) 2025, Resilient Tech and contributors +// For license information, please see license.txt + +frappe.query_reports["India Compliance API Usage"] = { + filters: [ + { + "fieldname": "from_date", + "label": __("From"), + "fieldtype": "Date", + "reqd": 1, + "default": frappe.datetime.add_months(frappe.datetime.now_date(), -6) + }, + { + "fieldname": "to_date", + "label": __("To"), + "fieldtype": "Date", + "reqd": 1, + "default": frappe.datetime.now_date() + }, + { + "fieldname": "report_by", + "label": __("Report by"), + "fieldtype": "Select", + "options": [ + "Endpoint", + "Linked Document", + "Date" + ], + "default": "Endpoint" + }, + ], + + onload(query_report) { + query_report.filters.forEach(filter => { + if (filter.fieldtype === "Date") { + filter.datepicker.update( + { maxDate: new Date() } + ) + } + }); + } +}; diff --git a/india_compliance/gst_india/report/india_compliance_api_usage/india_compliance_api_usage.json b/india_compliance/gst_india/report/india_compliance_api_usage/india_compliance_api_usage.json new file mode 100644 index 0000000000..f57d3f8e49 --- /dev/null +++ b/india_compliance/gst_india/report/india_compliance_api_usage/india_compliance_api_usage.json @@ -0,0 +1,27 @@ +{ + "add_total_row": 0, + "columns": [], + "creation": "2025-02-11 12:15:09.380757", + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "filters": [], + "idx": 0, + "is_standard": "Yes", + "letterhead": null, + "modified": "2025-02-11 12:17:30.611180", + "modified_by": "Administrator", + "module": "GST India", + "name": "India Compliance API Usage", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Integration Request", + "report_name": "India Compliance API Usage", + "report_type": "Script Report", + "roles": [ + { + "role": "System Manager" + } + ], + "timeout": 0 +} \ No newline at end of file diff --git a/india_compliance/gst_india/report/india_compliance_api_usage/india_compliance_api_usage.py b/india_compliance/gst_india/report/india_compliance_api_usage/india_compliance_api_usage.py new file mode 100644 index 0000000000..e0854ac037 --- /dev/null +++ b/india_compliance/gst_india/report/india_compliance_api_usage/india_compliance_api_usage.py @@ -0,0 +1,156 @@ +# Copyright (c) 2025, Resilient Tech and contributors +# For license information, please see license.txt + +import frappe +from frappe import _ +from frappe.query_builder.functions import Count, Date, Replace + +from india_compliance.gst_india.api_classes.base import BASE_URL + + +def execute(filters: dict | None = None): + report = IndiaComplianceAPIUsageReport(filters=filters) + columns = report.get_columns() + data = report.get_data() + + return columns, data + + +class IndiaComplianceAPIUsageReport: + def __init__(self, filters: dict | None = None): + self.from_data = filters.from_date + self.to_date = filters.to_date + self.report_by = filters.report_by + + def get_columns(self) -> list[dict]: + if self.report_by == "Endpoint": + return self._get_columns_by_endpoint() + + if self.report_by == "Date": + return self._get_columns_by_date() + + return self._get_columns_by_linked_doctype() + + def _get_columns_by_endpoint(self): + columns = [ + { + "label": _("Endpoint"), + "fieldname": "endpoint", + "fieldtype": "Data", + "width": 400, + }, + { + "label": _("API Requests Count"), + "fieldname": "api_requests_count", + "fieldtype": "Int", + "width": 200, + }, + ] + + return columns + + def _get_columns_by_date(self): + columns = [ + { + "label": _("Date"), + "fieldname": "date", + "fieldtype": "Date", + "width": 250, + }, + { + "label": _("API Requests Count"), + "fieldname": "api_requests_count", + "fieldtype": "Int", + "width": 200, + }, + ] + + return columns + + def _get_columns_by_linked_doctype(self): + columns = [ + { + "label": _("Reference DocType"), + "fieldname": "reference_doctype", + "fieldtype": "Link", + "options": "DocType", + "width": 200, + }, + { + "label": _("Reference Document"), + "fieldname": "reference_docname", + "fieldtype": "Dynamic Link", + "options": "reference_doctype", + "width": 200, + }, + { + "label": _("API Requests Count"), + "fieldname": "api_requests_count", + "fieldtype": "Int", + "width": 200, + }, + ] + + return columns + + def get_data(self) -> list[dict]: + if self.report_by == "Endpoint": + return self._get_data_by_endpoint() + + if self.report_by == "Date": + return self._get_data_by_date() + + return self._get_data_by_linked_doctype() + + def _get_data_by_endpoint(self): + integration_requests = frappe.qb.DocType("Integration Request") + + query = ( + frappe.qb.from_(integration_requests) + .select( + # Replace base url for all API endpoints + Replace(integration_requests.url, BASE_URL, "").as_("endpoint"), + Count("*").as_("api_requests_count"), + ) + .where(integration_requests.creation >= self.from_data) + .where(integration_requests.creation <= self.to_date) + .groupby(integration_requests.url) + ) + + return query.run(as_dict=True) + + def _get_data_by_date(self): + integration_requests = frappe.qb.DocType("Integration Request") + + query = ( + frappe.qb.from_(integration_requests) + .select( + Date(integration_requests.creation).as_("date"), + Count("*").as_("api_requests_count"), + ) + .where(integration_requests.creation >= self.from_data) + .where(integration_requests.creation <= self.to_date) + .groupby("date") + ) + + return query.run(as_dict=True) + + def _get_data_by_linked_doctype(self): + integration_requests = frappe.qb.DocType("Integration Request") + + query = ( + frappe.qb.from_(integration_requests) + .select( + integration_requests.reference_doctype.as_("reference_doctype"), + integration_requests.reference_docname.as_("reference_docname"), + Count("*").as_("api_requests_count"), + ) + .where(integration_requests.creation >= self.from_data) + .where(integration_requests.creation <= self.to_date) + .groupby( + integration_requests.reference_doctype, + integration_requests.reference_docname, + ) + ) + + return query.run(as_dict=True) diff --git a/india_compliance/gst_india/workspace/gst_india/gst_india.json b/india_compliance/gst_india/workspace/gst_india/gst_india.json index 1f5a10f95d..ccf0fb6e1b 100644 --- a/india_compliance/gst_india/workspace/gst_india/gst_india.json +++ b/india_compliance/gst_india/workspace/gst_india/gst_india.json @@ -1,6 +1,6 @@ { "charts": [], - "content": "[{\"id\":\"Xz6h3FH8sZ\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Pending e-Waybills\",\"col\":4}},{\"id\":\"5wHVnb2VB-\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Pending e-Invoices\",\"col\":4}},{\"id\":\"FT76_s4_M1\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Invoice Cancelled, e-Invoice Active\",\"col\":4}},{\"id\":\"ROouz1137a\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"pSkSY7vg5b\",\"type\":\"header\",\"data\":{\"text\":\"Shortcuts\",\"col\":12}},{\"id\":\"kJscjOHSLN\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"GST Settings\",\"col\":3}},{\"id\":\"BT3ZIyt2_1\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"GSTR-1 Beta\",\"col\":3}},{\"id\":\"fVgN1kK1r6\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"GSTR-3B\",\"col\":3}},{\"id\":\"kxE1gBYYUW\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Reconciliation Tool\",\"col\":3}},{\"id\":\"-G2gVutaOP\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"HSN Code\",\"col\":3}},{\"id\":\"sEPHpNM3bl\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"India Compliance Account\",\"col\":3}},{\"id\":\"bVd6Hbw3Yp\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"oN0FbtHAdc\",\"type\":\"header\",\"data\":{\"text\":\"Reports and Masters\",\"col\":12}},{\"id\":\"doCaNmtmY8\",\"type\":\"card\",\"data\":{\"card_name\":\"Sales and Purchase Reports\",\"col\":4}},{\"id\":\"Emy7VbsSYq\",\"type\":\"card\",\"data\":{\"card_name\":\"Logs\",\"col\":4}},{\"id\":\"2FUZmTJKVp\",\"type\":\"card\",\"data\":{\"card_name\":\"Other GST Reports\",\"col\":4}},{\"id\":\"PhR9LKvBdc\",\"type\":\"card\",\"data\":{\"card_name\":\"New Reports\",\"col\":3}}]", + "content": "[{\"id\":\"Xz6h3FH8sZ\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Pending e-Waybills\",\"col\":4}},{\"id\":\"5wHVnb2VB-\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Pending e-Invoices\",\"col\":4}},{\"id\":\"FT76_s4_M1\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Invoice Cancelled, e-Invoice Active\",\"col\":4}},{\"id\":\"ROouz1137a\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"pSkSY7vg5b\",\"type\":\"header\",\"data\":{\"text\":\"Shortcuts\",\"col\":12}},{\"id\":\"kJscjOHSLN\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"GST Settings\",\"col\":3}},{\"id\":\"BT3ZIyt2_1\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"GSTR-1 Beta\",\"col\":3}},{\"id\":\"fVgN1kK1r6\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"GSTR-3B\",\"col\":3}},{\"id\":\"kxE1gBYYUW\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Reconciliation Tool\",\"col\":3}},{\"id\":\"-G2gVutaOP\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"HSN Code\",\"col\":3}},{\"id\":\"sEPHpNM3bl\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"India Compliance Account\",\"col\":3}},{\"id\":\"bVd6Hbw3Yp\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"oN0FbtHAdc\",\"type\":\"header\",\"data\":{\"text\":\"Reports and Masters\",\"col\":12}},{\"id\":\"doCaNmtmY8\",\"type\":\"card\",\"data\":{\"card_name\":\"Sales and Purchase Reports\",\"col\":4}},{\"id\":\"Emy7VbsSYq\",\"type\":\"card\",\"data\":{\"card_name\":\"Logs\",\"col\":4}},{\"id\":\"2FUZmTJKVp\",\"type\":\"card\",\"data\":{\"card_name\":\"Other GST Reports\",\"col\":4}},{\"id\":\"PhR9LKvBdc\",\"type\":\"card\",\"data\":{\"card_name\":\"New Reports\",\"col\":4}}]", "creation": "2022-02-28 19:04:58.655348", "custom_blocks": [], "docstatus": 0, @@ -163,7 +163,11 @@ "hidden": 0, "is_query_report": 0, "label": "Other GST Reports", +<<<<<<< HEAD "link_count": 6, +======= + "link_count": 7, +>>>>>>> 67c2ee6f (Merge pull request #3046 from karm1000/api_requests_report) "link_type": "DocType", "onboard": 0, "type": "Card Break" @@ -186,6 +190,10 @@ "link_to": "GSTR-3B Details", "link_type": "Report", "onboard": 0, +<<<<<<< HEAD +======= + "report_ref_doctype": "Purchase Invoice", +>>>>>>> 67c2ee6f (Merge pull request #3046 from karm1000/api_requests_report) "type": "Link" }, { @@ -196,6 +204,10 @@ "link_to": "GST Balance", "link_type": "Report", "onboard": 0, +<<<<<<< HEAD +======= + "report_ref_doctype": "GL Entry", +>>>>>>> 67c2ee6f (Merge pull request #3046 from karm1000/api_requests_report) "type": "Link" }, { @@ -216,6 +228,10 @@ "link_to": "Audit Trail", "link_type": "Report", "onboard": 0, +<<<<<<< HEAD +======= + "report_ref_doctype": "Version", +>>>>>>> 67c2ee6f (Merge pull request #3046 from karm1000/api_requests_report) "type": "Link" }, { @@ -231,9 +247,25 @@ }, { "hidden": 0, +<<<<<<< HEAD "is_query_report": 0, "label": "New Reports", "link_count": 2, +======= + "is_query_report": 1, + "label": "GSTIN Status", + "link_count": 0, + "link_to": "GSTIN Status", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "New Reports", + "link_count": 3, +>>>>>>> 67c2ee6f (Merge pull request #3046 from karm1000/api_requests_report) "link_type": "DocType", "onboard": 0, "type": "Card Break" @@ -256,11 +288,29 @@ "link_to": "GST Job Work Stock Movement", "link_type": "Report", "onboard": 0, +<<<<<<< HEAD "report_ref_doctype": "Subcontracting Order", "type": "Link" } ], "modified": "2024-10-05 10:28:10.623892", +======= + "type": "Link" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "India Compliance API Usage", + "link_count": 0, + "link_to": "India Compliance API Usage", + "link_type": "Report", + "onboard": 0, + "report_ref_doctype": "Integration Request", + "type": "Link" + } + ], + "modified": "2025-02-12 10:48:31.054573", +>>>>>>> 67c2ee6f (Merge pull request #3046 from karm1000/api_requests_report) "modified_by": "Administrator", "module": "GST India", "name": "GST India",