-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
[feat]GSTIN Number Validation and PAN Validation (Multiple TIN functionality) and also refactored is taxID for options object #2153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
7445cd1
b49d810
5d9de31
1558141
4268200
5d38efa
5e4a1f0
b4fd442
1982605
862ff13
3a04feb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1136,6 +1136,10 @@ const taxIdFormat = { | |
| 'en-CA': /^\d{9}$/, | ||
| 'en-GB': /^\d{10}$|^(?!GB|NK|TN|ZZ)(?![DFIQUV])[A-Z](?![DFIQUVO])[A-Z]\d{6}[ABCD ]$/i, | ||
| 'en-IE': /^\d{7}[A-W][A-IW]{0,1}$/i, | ||
| 'en-IN': { | ||
| GSTIN: /^((?!39)(?!00)[0-3][0-9]|97)([A-Z]{3}[ABCFGHLJPT][A-Z](?!0000)[0-9]{4}[A-Z])[1-9A-Z]Z[0-9 A-Z]$/, | ||
| PAN: /^[A-Z]{3}[ABCFGHLJPT][A-Z](?!0000)[0-9]{4}[A-Z]$/, | ||
| }, | ||
| 'en-US': /^\d{2}[- ]{0,1}\d{7}$/, | ||
| 'es-ES': /^(\d{0,8}|[XYZKLM]\d{7})[A-HJ-NP-TV-Z]$/i, | ||
| 'et-EE': /^[1-6]\d{6}(00[1-9]|0[1-9][0-9]|[1-6][0-9]{2}|70[0-9]|710)\d$/, | ||
|
|
@@ -1211,30 +1215,62 @@ const sanitizeRegexes = { | |
| // sanitizeRegexes locale aliases | ||
| sanitizeRegexes['nl-BE'] = sanitizeRegexes['fr-BE']; | ||
|
|
||
| const multipleTinLocale = { | ||
Santhosh-Kumar-99 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 'en-IN': { | ||
| GSTIN: true, | ||
| PAN: true, | ||
| }, | ||
| }; | ||
|
|
||
| const availableOptions = { | ||
| localeOption: true, | ||
| }; | ||
|
|
||
| // Validates args of isTaxID function | ||
| function validateArgs(str, locale, options) { | ||
| const localeOption = options?.localeOption; | ||
|
|
||
| try { assertString(str); } catch (err) { throw new Error(`${err.message} for str`); } | ||
| try { assertString(locale); } catch (err) { throw new Error(`${err.message} for locale`); } | ||
|
|
||
| for (const option in options) { | ||
| if (!(option in availableOptions)) throw new Error(`'${option}' is not available`); | ||
| } | ||
|
|
||
| if (!(locale in taxIdFormat)) throw new Error(`Invalid locale '${locale}'`); | ||
|
|
||
|
|
||
| if (locale in multipleTinLocale) { | ||
| try { assertString(localeOption); } catch (err) { throw new Error(`${err.message} for localeOption`); } | ||
| if (!(localeOption in multipleTinLocale[locale])) throw new Error(`Invalid localeOption '${localeOption}'`); | ||
| } else if (localeOption || localeOption === '') { | ||
| throw new Error(`Invalid localeOption for locale '${locale}'`); | ||
| } | ||
| } | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you get inspiration for this from some other validator using an #2086 is somewhat similar to this PR in that it uses a local option in the options object. Maybe cut things down a bit, taking inspiration from there?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hey @braaar thanks for your feedback, Yeah #2086 is a bit similar but according to #1874 but For now, Example : US TIN
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This complexity is starting to make me feel like maintaining a validator for multiple tax ids for multiple countries is an enourmous undertaking. I suppose it's the only natural way forward, unless we decide to scrap the validator altogether, of course. How many app developers are making international systems that care about tax ids and are using open source validation code? In my eyes the use case for such an all-encompassing validator is quite rare. When I work with things like social security numbers and business IDs I use a country-specific package that contains what I need and is much easier to maintain on its own, should I spot an error or want something added. What are your thoughts on this, @WikiRik? I suppose this enters into a territory where the maintainers should chime in. They are in control of the main direction of the project and also feel the burden of maintaining code the most.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, input from the maintainers is indeed something we'll need. But the fact is that we already have
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @profnandaa can you please help us here.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps I should open a separate issue about scrapping this validator.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah and can we just add PAN regex alone for en-IN locale ,for now ? |
||
| /* | ||
| * Validator function | ||
| * Return true if the passed string is a valid tax identification number | ||
| * for the specified locale. | ||
| * Throw an error exception if the locale is not supported. | ||
| */ | ||
| export default function isTaxID(str, locale = 'en-US') { | ||
| assertString(str); | ||
| export default function isTaxID(str, locale = 'en-US', options) { | ||
| validateArgs(str, locale, options); | ||
| const localeOption = options?.localeOption; | ||
|
|
||
| // Copy TIN to avoid replacement if sanitized | ||
| let strcopy = str.slice(0); | ||
| if (locale in sanitizeRegexes) { | ||
| strcopy = strcopy.replace(sanitizeRegexes[locale], ''); | ||
| } | ||
|
|
||
| if (locale in taxIdFormat) { | ||
| if (locale in sanitizeRegexes) { | ||
| strcopy = strcopy.replace(sanitizeRegexes[locale], ''); | ||
| } | ||
| if (!taxIdFormat[locale].test(strcopy)) { | ||
| return false; | ||
| } | ||
|
|
||
| if (locale in taxIdCheck) { | ||
| return taxIdCheck[locale](strcopy); | ||
| } | ||
| // Fallthrough; not all locales have algorithmic checks | ||
| if (locale in multipleTinLocale) { | ||
| if (!taxIdFormat[locale][localeOption].test(strcopy)) return false; | ||
| return true; | ||
| } | ||
| throw new Error(`Invalid locale '${locale}'`); | ||
| if (!taxIdFormat[locale].test(strcopy)) return false; | ||
| if (locale in taxIdCheck) return taxIdCheck[locale](strcopy); | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.