koblas / stdnum-js

A JavaScript library to provide functions to handle, parse and validate standard numbers.
MIT License
39 stars 26 forks source link

No validateVat method #50

Open dreinon opened 1 year ago

dreinon commented 1 year ago

Hi! Congrats for the implementation of this python-original module in TS! Really helpful!

I was wondering why there is a validatePerson and validateEntity method, but no validateVat method? Thanks!

koblas commented 1 year ago

Thanks!

I had given the validateVat method some thought. My original thinking was that it should validate it and return a list of countries that it was valid for. e.g.

function validateVat(value: string): string[];

Or something similar. I can see this being useful in the context of you having a VAT that you believe to be a EU VAT but you're uncertain which country or maybe you're attempting to validate that it matches a given country (e.g. company claims to be French but they give a German VAT).

What's the use case that you're thinking about?

dreinon commented 1 year ago

In my case, we do have the country of the company, so we would just need to pass the country and a value to the function and get if it is valid or not. In case it is, get the formatted value.

koblas commented 1 year ago

Thinking about this a bit more I wonder if this would be a solid solution. Which basically would restrict the "business" validators to things that are VAT codes. It would then be easy for you to write a specific function for your needs.

const vatValidators: Record<string, Validator> {
  // ...
  BE: BE.vat,
  BG: BG.vat,
  // ...
}
dreinon commented 1 year ago

Hi @koblas, didn't really understand your proposal, sorry. Could you explain a bit more, please?

koblas commented 1 year ago

Based on the current patterns in the code, it would make sense for the the code to just have a table for VAT validation for the given country. As you mentioned you already know the country so this would allow you to just have an implementation something like.

function vatFormat(country: string, vat: string): string | null {
     const validator = vatValidator[country];
     // VAT validation for country not found
     if (!validator) {
         return null;
     }
     // 
     const { isValid} = validator.validate(vat);
     if (!isValid) {
         return null;
     }
     return validator.format(vat);
}
dreinon commented 1 year ago

Right, that would be a valid implementation! Don't we have euVat object already?

koblas commented 1 year ago

Not presently, but that would be a simple add.

dreinon commented 1 year ago

Isn't it this line?

koblas commented 1 year ago

Good grief! Yes, it is. Though at least while I was writing this, I was thinking it was singular for VAT not an array.

dreinon commented 1 year ago

Good grief! Yes, it is. Though at least while I was writing this, I was thinking it was singular for VAT not an array.

Right! Though the arrays in the values of the VAT object are 1-lenght arrays, therefore we could just add the following function, taking the example you posted:

function vatFormat(country: string, vat: string): string | undefined {
     const [validator] = vatValidator[country];

     // VAT validation for country not found
     if (!validator) return;

     const { isValid} = validator.validate(vat);
     if (!isValid) return;

     return validator.format(vat);
}