-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
feat(finance): add vatNumber() #3985
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
Open
rodrigobnogueira
wants to merge
17
commits into
faker-js:next
Choose a base branch
from
rodrigobnogueira:feat/finance-vat-number
base: next
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
042b2b9
feat(finance): add vatNumber()
rodrigobnogueira 477f075
refactor(finance): address review feedback on vatNumber()
rodrigobnogueira 9c0ea3f
refactor(finance): apply second review round on vatNumber()
rodrigobnogueira af4fc99
fix(finance): guard vatNumber() against inherited keys and even out t…
rodrigobnogueira d1a8555
fix(finance): stop vatNumber() emitting numbers that cannot be issued
rodrigobnogueira ff25c85
docs(finance): correct the vatNumber comments to match what it generates
rodrigobnogueira df6f7fe
Merge remote-tracking branch 'upstream/next' into feat/finance-vat-nu…
rodrigobnogueira bf19bac
Merge remote-tracking branch 'upstream/next' into feat/finance-vat-nu…
rodrigobnogueira 619af0a
docs(finance): set vatNumber's @since to the release it will ship in
rodrigobnogueira cfa02b2
test(finance): cover both shapes of the two-pattern countries
rodrigobnogueira 0de4b53
Merge remote-tracking branch 'upstream/next' into feat/finance-vat-nu…
rodrigobnogueira a7ac68b
refactor(finance): apply review feedback on vatNumber()
rodrigobnogueira 737f5d4
docs(finance): describe the keying of vatNumberFormats as it is now
rodrigobnogueira f907215
test(finance): assert VatNumberCountryCode is accepted by isVAT
rodrigobnogueira e1bf4ae
test(finance): snapshot the VAT patterns instead of restating them
rodrigobnogueira e29dc2b
test(finance): snapshot a generated VAT number per country
rodrigobnogueira edfcba1
Merge branch 'next' into feat/finance-vat-number
ST-DDT File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| /** | ||
| * The VAT identification number patterns of the EU member states, keyed by | ||
| * ISO 3166-1 alpha-2 code, plus `EL`: the prefix Greek numbers carry in place | ||
| * of `GR`. | ||
| * | ||
| * Each pattern is written for `faker.helpers.fromRegExp()`. | ||
| * Currently, all values are generated randomly, so parts with intent such as check digits will likely produce invalid values. | ||
| */ | ||
| export const vatNumberFormats = { | ||
| /** UID-Nummer. */ | ||
| AT: 'ATU[0-9]{8}', | ||
| /** | ||
| * BTW-nummer. Begins with 0 or 1: the 2005 ten-digit form zero-padded the | ||
| * older nine-digit numbers, and the 1 series was opened later, once the 0 | ||
| * series neared exhaustion. | ||
| */ | ||
| BE: 'BE[01][0-9]{9}', | ||
| /** DDS nomer. Nine digits for legal entities, ten for individuals. */ | ||
| BG: 'BG[0-9]{9,10}', | ||
| /** | ||
| * FPA. Numbers begin 0, 1, 3, 4, 5 or 9 under the legacy categories, or 6 | ||
| * under the format introduced in March 2023; 2, 7 and 8 are not issued. | ||
| */ | ||
| CY: 'CY[0134569][0-9]{7}[A-Z]', | ||
| /** DIC. */ | ||
| CZ: 'CZ[0-9]{8,10}', | ||
| /** Umsatzsteuer-Identifikationsnummer. */ | ||
| DE: 'DE[0-9]{9}', | ||
| /** CVR-nummer. */ | ||
| DK: 'DK[0-9]{8}', | ||
| /** KMKR number. */ | ||
| EE: 'EE[0-9]{9}', | ||
| /** AFM. */ | ||
| EL: 'EL[0-9]{9}', | ||
| /** | ||
| * NIF/CIF for entities. The leading character encodes the legal form, which | ||
| * constrains the control character: A, B, E and H always take a digit, | ||
| * C, D, F, G, J, U and V may take either, and foreign entities, public | ||
| * bodies, local corporations and religious congregations (N, P, Q, R, S, W) | ||
| * always take a letter. The two branches are separate patterns because one | ||
| * character class would pair the positions freely and emit combinations that | ||
| * are never issued; the may-take-either letters are generated with a digit, | ||
| * which under-generates rather than over-generates. The natural-person forms | ||
| * are out of scope. | ||
| */ | ||
| ES: ['ES[ABCDEFGHJUV][0-9]{7}[0-9]', 'ES[NPQRSW][0-9]{7}[A-J]'], | ||
| /** ALV-numero. */ | ||
| FI: 'FI[0-9]{8}', | ||
| /** | ||
| * Numero de TVA intracommunautaire: a two-character key followed by the | ||
| * nine-digit SIREN. The letters I and O are not used in the key. | ||
| */ | ||
| FR: 'FR[0-9ABCDEFGHJKLMNPQRSTUVWXYZ]{2}[0-9]{9}', | ||
| /** AFM. Same as `EL`. */ | ||
| GR: 'EL[0-9]{9}', | ||
| /** PDV ID. */ | ||
| HR: 'HR[0-9]{11}', | ||
| /** Kozossegi adoszam. */ | ||
| HU: 'HU[0-9]{8}', | ||
| /** | ||
| * VAT number: seven digits and a check letter, optionally followed by a | ||
| * `W` — the legacy marker for a married woman registered on her husband's | ||
| * number. The 2013 form, whose second letter runs A to I rather than being | ||
| * `W`, is not modelled, nor is the older form that carries a symbol. | ||
| */ | ||
| IE: 'IE[0-9]{7}[A-W]W{0,1}', | ||
| /** Partita IVA. */ | ||
| IT: 'IT[0-9]{11}', | ||
| /** | ||
| * PVM kodas. Nine digits for legal entities, where the eighth is always 1 | ||
| * and the ninth is a check digit. The twelve-digit form for temporarily | ||
| * registered taxpayers is rare and not modelled — note it could not simply | ||
| * widen this pattern to `[0-9]{9,12}`, since the lengths in between are | ||
| * never issued. | ||
| */ | ||
| LT: 'LT[0-9]{7}1[0-9]', | ||
| /** Numero de TVA. */ | ||
| LU: 'LU[0-9]{8}', | ||
| /** PVN numurs. */ | ||
| LV: 'LV[0-9]{11}', | ||
| /** VAT number. */ | ||
| MT: 'MT[0-9]{8}', | ||
| /** | ||
| * Btw-identificatienummer. The two digits after the `B` are a company index | ||
| * running from 01 to 99, so `B00` is never issued — which takes two patterns | ||
| * to express, since a plain digit pair would include it. | ||
| */ | ||
| NL: ['NL[0-9]{9}B0[1-9]', 'NL[0-9]{9}B[1-9][0-9]'], | ||
| /** NIP. */ | ||
| PL: 'PL[0-9]{10}', | ||
| /** Numero de identificacao fiscal. No taxpayer range begins with zero. */ | ||
| PT: 'PT[1-9][0-9]{8}', | ||
| /** Cod de identificare fiscala. Between 2 and 10 digits, never leading zero. */ | ||
| RO: 'RO[1-9][0-9]{1,9}', | ||
| /** | ||
| * Momsnummer: the ten-digit organisationsnummer followed by a two-digit | ||
| * establishment number. Only `01` is generated — it is the value for all but | ||
| * a handful of multi-establishment registrations. | ||
| */ | ||
| SE: 'SE[0-9]{10}01', | ||
| /** ID za DDV. Eight digits, never a leading zero. */ | ||
| SI: 'SI[1-9][0-9]{7}', | ||
| /** IC DPH. */ | ||
| SK: 'SK[0-9]{10}', | ||
| } as const satisfies Record<string, string | ReadonlyArray<string>>; | ||
|
|
||
| /** The codes to draw from, minus `GR`, which would give Greece double weight. */ | ||
| export const vatNumberCountryCodes = Object.keys(vatNumberFormats).filter( | ||
| (code) => code !== 'GR' | ||
| ) as VatNumberCountryCode[]; | ||
|
|
||
| /** | ||
| * The country codes for which a VAT identification number can be generated. | ||
| */ | ||
| export type VatNumberCountryCode = keyof typeof vatNumberFormats; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| export * from './module'; | ||
| export type { VatNumberCountryCode } from './_vat-number'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import type { VATCountryCode } from 'validator'; | ||
| import { describe, expectTypeOf, it } from 'vitest'; | ||
| import type { VatNumberCountryCode } from '../../src/modules/finance/_vat-number'; | ||
|
|
||
| describe('finance', () => { | ||
| describe('vatNumber', () => { | ||
| it('VatNumberCountryCode', () => { | ||
| expectTypeOf<VatNumberCountryCode>().toExtend<VATCountryCode | 'GR'>(); | ||
| // Currently the reverse is not true | ||
| }); | ||
| }); | ||
| }); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.