From 61e10af3afb51717a71b5cf5201f14be4bb9df9f Mon Sep 17 00:00:00 2001 From: Sanket Shah <113279972+Sanket322@users.noreply.github.com> Date: Mon, 4 Nov 2024 10:54:52 +0530 Subject: [PATCH] fix: handle `Invalid GSTIN` error (#2645) closes: #2640 Huly®: IC-2769 --- .../gst_india/api_classes/e_invoice.py | 1 + .../gst_india/api_classes/public.py | 11 +++++++ india_compliance/gst_india/utils/e_invoice.py | 2 +- .../gst_india/utils/gstin_info.py | 3 +- .../gst_india/utils/test_gstin_info.py | 30 ++++++++++++++++++- 5 files changed, 44 insertions(+), 3 deletions(-) diff --git a/india_compliance/gst_india/api_classes/e_invoice.py b/india_compliance/gst_india/api_classes/e_invoice.py index 933f741e4..c59b6c754 100644 --- a/india_compliance/gst_india/api_classes/e_invoice.py +++ b/india_compliance/gst_india/api_classes/e_invoice.py @@ -24,6 +24,7 @@ class EInvoiceAPI(BaseAPI): # Invalid GSTIN error "3028": "GSTIN is invalid", "3029": "GSTIN is not active", + "3001": "Requested data is not available", } def setup(self, doc=None, *, company_gstin=None): diff --git a/india_compliance/gst_india/api_classes/public.py b/india_compliance/gst_india/api_classes/public.py index 3653d7ef2..c5fc70824 100644 --- a/india_compliance/gst_india/api_classes/public.py +++ b/india_compliance/gst_india/api_classes/public.py @@ -18,6 +18,7 @@ def setup(self): self.default_headers.update({"requestid": self.generate_request_id()}) def get_gstin_info(self, gstin): + self.gstin = gstin response = self.get("search", params={"action": "TP", "gstin": gstin}) if self.sandbox_mode: response.update( @@ -33,3 +34,13 @@ def get_returns_info(self, gstin, fy): return self.get( "returns", params={"action": "RETTRACK", "gstin": gstin, "fy": fy} ) + + def is_ignored_error(self, response_json): + if response_json.get("errorCode") == "FO8000": + response_json.update( + { + "sts": "Invalid", + "gstin": self.gstin, + } + ) + return True diff --git a/india_compliance/gst_india/utils/e_invoice.py b/india_compliance/gst_india/utils/e_invoice.py index 223cf48d1..b66065103 100644 --- a/india_compliance/gst_india/utils/e_invoice.py +++ b/india_compliance/gst_india/utils/e_invoice.py @@ -147,7 +147,7 @@ def generate_e_invoice(docname, throw=True, force=False): ) # Handle Invalid GSTIN Error - if result.error_code in ("3028", "3029"): + if result.error_code in ("3028", "3029", "3001"): gstin = data.get("BuyerDtls").get("Gstin") response = api.sync_gstin_info(gstin) diff --git a/india_compliance/gst_india/utils/gstin_info.py b/india_compliance/gst_india/utils/gstin_info.py index 01e02611d..59171620b 100644 --- a/india_compliance/gst_india/utils/gstin_info.py +++ b/india_compliance/gst_india/utils/gstin_info.py @@ -58,6 +58,7 @@ def _get_gstin_info(gstin, *, throw_error=True): queue="long", response=get_formatted_response_for_status(response), ) + except Exception as exc: if isinstance(exc, GSPServerError): frappe.cache.set_value("gst_server_error", True, expires_in_sec=60) @@ -75,7 +76,7 @@ def _get_gstin_info(gstin, *, throw_error=True): gstin_info = frappe._dict( gstin=response.gstin, - business_name=titlecase(business_name), + business_name=titlecase(business_name or ""), gst_category=GST_CATEGORIES.get(response.dty, ""), status=response.sts, ) diff --git a/india_compliance/gst_india/utils/test_gstin_info.py b/india_compliance/gst_india/utils/test_gstin_info.py index 715e56767..8db0d259e 100644 --- a/india_compliance/gst_india/utils/test_gstin_info.py +++ b/india_compliance/gst_india/utils/test_gstin_info.py @@ -1,7 +1,10 @@ from unittest.mock import Mock, patch +import responses +from responses import matchers + import frappe -from frappe.tests import IntegrationTestCase +from frappe.tests import IntegrationTestCase, change_settings from india_compliance.gst_india.utils.gstin_info import get_gstin_info @@ -189,3 +192,28 @@ def test_tcs_gstin_info(self): }, }, ) + + +class TestGstinInvalidInfo(IntegrationTestCase): + @responses.activate + @change_settings("GST Settings", {"validate_gstin_status": 1, "sandbox_mode": 0}) + def test_invalid_gstin(self): + gstin = "24AQTPC8950E1ZO" + url = "https://asp.resilient.tech/commonapi/search" + + responses.add( + responses.GET, + url, + json={ + "errorCode": "FO8000", + "gstin": "24AQTPC8950E1ZO", + "message": "No records found", + "sts": "Invalid", + "success": False, + }, + match=[matchers.query_param_matcher({"action": "TP", "gstin": gstin})], + ) + + gstin_info = get_gstin_info(gstin) + self.assertEqual(gstin_info.status, "Invalid") + self.assertEqual(gstin_info.business_name, "")