Skip to content
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

Validating Belgium VAT numbers without leading zero #76

Closed
timo002 opened this issue Sep 9, 2019 · 9 comments
Closed

Validating Belgium VAT numbers without leading zero #76

timo002 opened this issue Sep 9, 2019 · 9 comments

Comments

@timo002
Copy link

timo002 commented Sep 9, 2019

When validating a Belgium VAT number, they should start with a zero (after the country code). The ValidatorBE class fixes this nicely when it validates the number. If the number is 9 chararacters long, it will be prefixed with a zero.

The function validateVatSum then returns true and the VAT number is processed to the VIES service through a SOAP call. But the VAT number send to VIES is without the leading zero and thus it is validated false.

So it has no point of adding the leading zero if this is not also send to VIES. I would advise to also send the VAT number with leading zero to VIES. Or otherwise validate a VAT number without the leading zero as invalid directly in de ValidatorBE class.

@cottton
Copy link
Contributor

cottton commented Sep 9, 2019

See https://github.com/DragonBe/vies/blob/master/src/Vies/Validator/ValidatorBE.php#L37

IMO a validator should validate.
If a validator manipulates the value (VAT) f.e. via reference
then this could bring unexpected results.

Perhaps a ValidatorException would work.
In this case the message could be "Missing leading zero on BE VAT number." or something like that.

Or, the keep it easy, return false :)

@timo002
Copy link
Author

timo002 commented Sep 9, 2019

Well, a Belgium VAT number without a leading zero isn't valid. So actually the ValidatorBE should not add the leading zero. But if it does, then that should also be used when the VAT number is send to the VIES service.

So in my opinion, add it, or not. But if it is added, also in the VIES service. Otherwise the Validator says it is ok, and the VIES always will reply false.

@DragonBe
Copy link
Owner

I've looked at our solution and I'm agreeing with both of you. Yes, we're adding a leading 0 if the amount of numbers equals to 9 which should not occur.

I also agree that older VAT ID's in Belgium with only 9 numbers (and not having a leading 0) are valid and should be validated by the backend VIES service provided by the European Commission.

So I searched for some public Belgian VAT ID's with only 9 numbers and validated them against the online VIES service and guess what?!? The service itself returns it as INVALID!

image

My test values are:

But when I add a leading "0" (zero) to the validation service, the validation passes and I get good results.

image

Which allows me to conclude that our action to add a leading 0 in front of the entered VAT ID was a good move, but we should be consistent and pushing that modified number also to VIES so we get a valid result back.

Of course, in the response we should indicate that the validation only occurred when we added the leading 0, just like VIES does in their own response (see screenshot above).

So I ask both of you (@timo002 & @cottton): should we or should we not make the modification for the user so we pass the online validation and remove our modification in the offline validation?

Bear in mind that the regulation for businesses is to add a leading zero in all their publications. This was handed to me on a paper back in the day when I registered our own company (which I no longer poses).

@timo002
Copy link
Author

timo002 commented Sep 16, 2019

I think that you should not add the leading zero in the validator. If someone forgets the leading zero, it is a wrong VAT code. Even if a user forgets it by mistake, it is still a wrong VAT code. I see it this way, if the user can omit the zero and the validator puts it in front of it. Then the user could also omit the last checksum, the validator could also calculate it.

In my case, I will prefix the leading zero if a user forgets it. I do this before I even call the VIES class.

@cottton
Copy link
Contributor

cottton commented Sep 16, 2019

First: how do we get updated vatNumber to the user:

// user input
$countryIso = 'BE';
$vatNumber = '627515170'; // missing leading zero

$vies = new DragonBe\Vies\Vies();
// ::validateVat will prepare the varNumber and adds the missing leading zero internally
$response = $vies->validateVat($countryIso, $vatNumber);

// response contains the updated, valid vatNumber
echo var_export($response->toArray(), true) . PHP_EOL;
// array(
//     'countryCode'      => 'BE',
//     'vatNumber'        => '0627515170', // <----------------------------------
//     'requestDate'      => '2019-09-16',
//     'valid'            => true,
//     'name'             => 'Van Geldorp, Bert',
//     'address'          => 'Kammenstraat 99
// 2910 Essen',
//     'identifier'       => '',
//     'nameMatch'        => '',
//     'companyTypeMatch' => '',
//     'streetMatch'      => '',
//     'postcodeMatch'    => '',
//     'cityMatch'        => '',
// )

// the user input stays untouched
var_dump($vatNumber); // string(10) "627515170"
// I thought about updating the $varNumber by reference
// BUT this could cause weird behavior on existing tools out there.

// So user now SHOULD use the vatNumber in the response.
$vatNumber = $response->getVatNumber();
var_dump($vatNumber); // 0627515170

BTW: vatNumber gets changed anyway at: $vatNumber = self::filterVat($vatNumber);
So use really SHOULD use the vatNumber in the response for further processes.


Changes in short:

  • ValidatorInterface new method ::sanitize

  • ValidatorAbstract new static method ::sanitize

  • Vies::filterVat "moved" to ValidatorAbstract::sanitize (default sanitization(?))
    Note: keeping Vies::filterVat because it was public and some users may rely on it. But it now redirects to ValidatorAbstract::sanitize.

  • ValidatorBE::sanitize calls parent::sanitize FIRST (clean up) and then adds missing leading zero.)

  • Vies::validateVatSum now updating the $vatNumber by reference.

  • Vies::validateVatSum calls $validator ::sanitize and then ::validate.

Note: added notes like #DISABLED - ... and ## todo ... which should be deleted before release.

...
So, this is the only way i found to not change too much code and keep it simple.

Validators now CAN manipulate the value, but caller (in this case Vies it self) must call the ::sanitize method.

Works on my side. I put a PR but this contains notes ect.

Please check on your side and unit tests.

Delete those notes before merge(?).

PR: #77

@DragonBe
Copy link
Owner

@cottton, thank you for your PR and I really appreciate the work you have put into the sanitisation of the VAT number. But after giving this some really good thought and talking to several people who deal with VAT a lot more than I do, I have to lean towards the remark @timo002 made: keep the input as it is, if the user omits the leading 0 the validation of this library should fail.

Even though the VAT number used to be valid, in this day and age the Belgian VAT ID should contain 10 digits and the first digit is a "0" (ref. https://financien.belgium.be/nl/ondernemingen/btw/aangifte/aanvang_wijziging_einde_activiteit#q1 [DUTCH]).

@DragonBe DragonBe self-assigned this Sep 28, 2019
DragonBe added a commit that referenced this issue Sep 28, 2019
Guess my pre-commit hook to run phpcs wasn't working properly, my bad
@cottton
Copy link
Contributor

cottton commented Sep 29, 2019

@cottton, thank you for your PR and I really appreciate the work you have put into the sanitisation of the VAT number.

No problem =)

keep the input as it is

Actually the input gets filtered (::filterVat) but this seems ok:
Does it change the input? (Internally)Yes.
Does it change the VAT? No.

It just changes the format - like a datetime string.
So - I think that is the best solution.

@DragonBe
Copy link
Owner

DragonBe commented Sep 29, 2019

Does it change the input? (Internally)Yes.

The goal of this application is to validate the input so this internal change should not happen IMO.

Like I mentioned in #76 (comment) when I use the VIES service directly, it rejects Belgian VAT ID's without a leading 0 so should this library also reject it, even if it's easy to correct it.

@cottton
Copy link
Contributor

cottton commented Sep 30, 2019

Thats what i mean too. I agree =)
I just wanted to show that the filter method does not change the actual value.

Like a Datetime string.
input: Mon, 30 Sep 2019 17:43:11 +0000
internal usage: (re-format to Y-m-d H:i:s) 2019-09-30 17:43:11

Same value, different format. All fine.
Adding the leading zero would not be the same value.

DragonBe added a commit that referenced this issue Nov 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants