diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 7980d0b9ffe..1a618d6cf56 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -14,6 +14,13 @@ from erpnext.accounts.general_ledger import make_gl_entries from erpnext.accounts.utils import get_account_currency from frappe.model.utils import get_fetch_values + +GST_INVOICE_NUMBER_FORMAT = re.compile(r"^[a-zA-Z0-9\-/]+$") #alphanumeric and - / +GSTIN_FORMAT = re.compile("^[0-9]{2}[A-Z]{4}[0-9A-Z]{1}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}[1-9A-Z]{1}[0-9A-Z]{1}$") +GSTIN_UIN_FORMAT = re.compile("^[0-9]{4}[A-Z]{3}[0-9]{5}[0-9A-Z]{3}") +PAN_NUMBER_FORMAT = re.compile("[A-Z]{5}[0-9]{4}[A-Z]{1}") + + def validate_gstin_for_india(doc, method): if hasattr(doc, 'gst_state') and doc.gst_state: doc.gst_state_number = state_numbers[doc.gst_state] @@ -37,12 +44,10 @@ def validate_gstin_for_india(doc, method): frappe.throw(_("Invalid GSTIN! A GSTIN must have 15 characters.")) if gst_category and gst_category == 'UIN Holders': - p = re.compile("^[0-9]{4}[A-Z]{3}[0-9]{5}[0-9A-Z]{3}") - if not p.match(doc.gstin): + if not GSTIN_UIN_FORMAT.match(doc.gstin): frappe.throw(_("Invalid GSTIN! The input you've entered doesn't match the GSTIN format for UIN Holders or Non-Resident OIDAR Service Providers")) else: - p = re.compile("^[0-9]{2}[A-Z]{4}[0-9A-Z]{1}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}[1-9A-Z]{1}[0-9A-Z]{1}$") - if not p.match(doc.gstin): + if not GSTIN_FORMAT.match(doc.gstin): frappe.throw(_("Invalid GSTIN! The input you've entered doesn't match the format of GSTIN.")) validate_gstin_check_digit(doc.gstin) @@ -59,8 +64,7 @@ def validate_pan_for_india(doc, method): if doc.get('country') != 'India' or not doc.pan: return - p = re.compile("[A-Z]{5}[0-9]{4}[A-Z]{1}") - if not p.match(doc.pan): + if not PAN_NUMBER_FORMAT.match(doc.pan): frappe.throw(_("Invalid PAN No. The input you've entered doesn't match the format of PAN.")) def validate_tax_category(doc, method): @@ -152,14 +156,14 @@ def validate_document_name(doc, method=None): """Validate GST invoice number requirements.""" country = frappe.get_cached_value("Company", doc.company, "country") + # Date was chosen as start of next FY to avoid irritating current users. if country != "India" or getdate(doc.posting_date) < getdate("2021-04-01"): return if len(doc.name) > 16: frappe.throw(_("Maximum length of document number should be 16 characters as per GST rules. Please change the naming series.")) - gst_doc_name_pattern = re.compile(r"^[a-zA-Z0-9\-/]+$") - if not gst_doc_name_pattern.match(doc.name): + if not GST_INVOICE_NUMBER_FORMAT.match(doc.name): frappe.throw(_("Document name should only contain alphanumeric values, dash(-) and slash(/) characters as per GST rules. Please change the naming series.")) # don't remove this function it is used in tests @@ -814,4 +818,4 @@ def get_regional_round_off_accounts(company, account_list): account_list.extend(gst_account_list) - return account_list \ No newline at end of file + return account_list