Skip to content

Commit

Permalink
Added stricter checks for Belgium and Germany
Browse files Browse the repository at this point in the history
  • Loading branch information
ToX82 committed Jul 31, 2023
1 parent f24eb95 commit 9ef3cf0
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 49 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ Thumbs.db

# IDE folders
/.idea
/.vscode
/.vscode
.phpunit.result.cache
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"php": ">=7.0.0"
},
"require-dev": {
"phpunit/phpunit": "^5.5"
"phpunit/phpunit": "*"
},
"autoload": {
"psr-4": {
Expand Down
26 changes: 12 additions & 14 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>

<phpunit bootstrap="vendor/autoload.php" colors="true">
<testsuites>
<testsuite name="VatNumber Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>

<filter>
<whitelist>
<directory suffix=".php">src</directory>
</whitelist>
</filter>
</phpunit>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/autoload.php" colors="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<coverage>
<include>
<directory suffix=".php">src</directory>
</include>
</coverage>
<testsuites>
<testsuite name="VatNumber Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
</phpunit>
77 changes: 59 additions & 18 deletions src/VatNumber.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ class VatNumber
*
* @param string $country Country code
* @param string $code VAT number
*
* @return bool
*/
public static function check(string $country, string $code): bool
Expand All @@ -39,7 +38,7 @@ public static function check(string $country, string $code): bool
return self::_checkLength($code, 11, 11) && self::_numbersOnly($code);
case "BE":
// 10 digits.
return self::_checkLength($code, 10, 10) && self::_numbersOnly($code);
return self::_checkLength($code, 10, 10) && self::_checkBelgium($code);
case "BG":
// 9 or 10 digits.
return self::_checkLength($code, 9, 10) && self::_numbersOnly($code);
Expand All @@ -49,6 +48,9 @@ public static function check(string $country, string $code): bool
case "CA":
// 9 characters.
return self::_checkLength($code, 9, 9);
case "CO":
// 10 characters.
return self::_checkLength($code, 10, 10);
case "HR":
// 11 digits.
return self::_checkLength($code, 11, 11) && self::_numbersOnly($code);
Expand All @@ -75,7 +77,7 @@ public static function check(string $country, string $code): bool
return self::_checkLength($code, 11, 11) && self::_checkFrance($code);
case "DE":
// 9 or 10 digits.
return self::_checkLength($code, 9, 9) && self::_numbersOnly($code);
return self::_checkLength($code, 9, 9) && self::_checkGermany($code);
case "EL":
// 9 digits.
return self::_checkLength($code, 9, 9) && self::_numbersOnly($code);
Expand Down Expand Up @@ -186,7 +188,6 @@ public static function check(string $country, string $code): bool
* @param string $code VAT number
* @param int $min Min length
* @param int $max Max length
*
* @return bool
*/
private static function _checkLength(string $code, int $min, int $max): bool
Expand All @@ -198,7 +199,6 @@ private static function _checkLength(string $code, int $min, int $max): bool
* Checks that a string is only numbers.
*
* @param string $code VAT number
*
* @return bool
*/
private static function _numbersOnly(string $code): bool
Expand All @@ -211,7 +211,6 @@ private static function _numbersOnly(string $code): bool
* Eg. K99999999L or L99999999G
*
* @param string $code VAT number
*
* @return bool
*/
private static function _checkAlbania(string $code): bool
Expand All @@ -228,7 +227,6 @@ private static function _checkAlbania(string $code): bool
* Eg. U12345678
*
* @param string $code VAT number
*
* @return bool
*/
private static function _checkAustria(string $code): bool
Expand All @@ -241,12 +239,30 @@ private static function _checkAustria(string $code): bool
return true;
}

/**
* Additional validations for Belgium
* Eg. 09999999XX
*
* @param string $code VAT number
* @return bool
*/
private static function _checkBelgium(string $code): bool
{
if (!preg_match('/^\d{8}[0-9][0-9]$/', $code)) {
return false;
}

$checkDigits = substr($code, 0, 8) % 97;
$checkDigits = sprintf('%02d', 97 - $checkDigits);

return substr($code, 8, 2) == $checkDigits;
}

/**
* Additional validations for Switzerland
* Eg. 123.456.789
*
* @param string $code VAT number
*
* @return bool
*/
private static function _checkSwitzerland(string $code): bool
Expand All @@ -264,7 +280,6 @@ private static function _checkSwitzerland(string $code): bool
* Eg. 12345678X
*
* @param string $code VAT number
*
* @return bool
*/
private static function _checkCyprus(string $code): bool
Expand All @@ -282,7 +297,6 @@ private static function _checkCyprus(string $code): bool
* Eg. 12345678901 - X1234567890 - 1X123456789 - XX123456789
*
* @param string $code VAT number
*
* @return bool
*/
private static function _checkFrance(string $code): bool
Expand All @@ -300,11 +314,45 @@ private static function _checkFrance(string $code): bool
return true;
}

/**
* Additional validations for Germany
* Eg. 122265872
*
* @param string $code VAT number
* @return bool
*/
private static function _checkGermany(string $code): bool
{
$count = 1;
$product = 10;
$sum = 0;
$checkDigit = intval(substr($code, -1));
$result = 0;

while ($count < 9) {
$sum = (intval(substr($code, $count - 1, 1)) + $product) % 10;

if ($sum === 0) {
$sum = 10;
}

$product = (2 * $sum) % 11;
$count++;
}

$result = 11 - $product;

if ($result === 10) {
$result = 0;
}

return $result === $checkDigit;
}

/**
* Additional validations for Ireland
*
* @param string $code Regional VAT code
*
* @return bool
*/
private static function _checkIreland(string $code): bool
Expand All @@ -324,7 +372,6 @@ private static function _checkIreland(string $code): bool
* Additional validations for Italy
*
* @param string $code Regional VAT code
*
* @return bool
*/
private static function _checkItaly(string $code): bool
Expand Down Expand Up @@ -356,7 +403,6 @@ private static function _checkItaly(string $code): bool
* Eg. MK4032013544513
*
* @param string $code Regional VAT code
*
* @return bool
*/
private static function _checkNorthMacedonia(string $code): bool
Expand All @@ -373,7 +419,6 @@ private static function _checkNorthMacedonia(string $code): bool
* Eg. 01012345-0001
*
* @param string $code Regional VAT code
*
* @return bool
*/
private static function _checkNigeria(string $code): bool
Expand All @@ -389,7 +434,6 @@ private static function _checkNigeria(string $code): bool
* Additional validations for Netherlands
*
* @param string $code Regional VAT code
*
* @return bool
*/
private static function _checkNetherlands(string $code): bool
Expand All @@ -406,7 +450,6 @@ private static function _checkNetherlands(string $code): bool
* Additional validations for Norway
*
* @param string $code Regional VAT code
*
* @return bool
*/
private static function _checkNorway(string $code): bool
Expand All @@ -427,7 +470,6 @@ private static function _checkNorway(string $code): bool
* Additional validations for Russia
*
* @param string $code Regional VAT code
*
* @return bool
*/
private static function _checkRussia(string $code): bool
Expand All @@ -443,7 +485,6 @@ private static function _checkRussia(string $code): bool
* Additional validations for Spain
*
* @param string $code Regional VAT code
*
* @return bool
*/
private static function _checkSpain(string $code): bool
Expand Down
32 changes: 17 additions & 15 deletions tests/Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

namespace Tox82\Tests\Validator;

use PHPUnit_Framework_TestCase;
use PHPUnit\Framework\TestCase;
use Tox82\VatNumber;

/**
* Tests!
*/
class VatTest extends PHPUnit_Framework_TestCase
class VatTest extends TestCase
{
/**
* Valid VAT numbers should be valid!
Expand All @@ -27,38 +27,41 @@ public function testCheckValids()
$this->assertTrue(VatNumber::check('AL', 'L99999999G'));
$this->assertTrue(VatNumber::check('AT', 'U12345678'));
$this->assertTrue(VatNumber::check('AU', '12345678901'));
$this->assertTrue(VatNumber::check('BE', '1234567890'));
$this->assertTrue(VatNumber::check('BE', '1234567894'));
$this->assertTrue(VatNumber::check('BG', '123456789'));
$this->assertTrue(VatNumber::check('BG', '1234567890'));
$this->assertTrue(VatNumber::check('BY', '190190190'));
$this->assertTrue(VatNumber::check('HR', '12345678901'));
$this->assertTrue(VatNumber::check('CA', '1234567AB'));
$this->assertTrue(VatNumber::check('CH', '123.456.789'));
$this->assertTrue(VatNumber::check('CY', '12345678X'));
$this->assertTrue(VatNumber::check('CZ', '12345678'));
$this->assertTrue(VatNumber::check('CZ', '123456789'));
$this->assertTrue(VatNumber::check('CZ', '1234567890'));
$this->assertTrue(VatNumber::check('DE', '122265872'));
$this->assertTrue(VatNumber::check('DK', '12345678'));
$this->assertTrue(VatNumber::check('EE', '123456789'));
$this->assertTrue(VatNumber::check('EL', '123456789'));
$this->assertTrue(VatNumber::check('ES', '12345678X'));
$this->assertTrue(VatNumber::check('ES', 'X12345678'));
$this->assertTrue(VatNumber::check('ES', 'X1234567X'));
$this->assertTrue(VatNumber::check('FI', '12345678'));
$this->assertTrue(VatNumber::check('FR', '12345678901'));
$this->assertTrue(VatNumber::check('FR', '12345678901'));
$this->assertTrue(VatNumber::check('FR', 'X1234567890'));
$this->assertTrue(VatNumber::check('FR', '1X123456789'));
$this->assertTrue(VatNumber::check('FR', 'X1234567890'));
$this->assertTrue(VatNumber::check('FR', 'XX123456789'));
$this->assertTrue(VatNumber::check('DE', '123456789'));
$this->assertTrue(VatNumber::check('EL', '123456789'));
$this->assertTrue(VatNumber::check('GB', '123456789'));
$this->assertTrue(VatNumber::check('HR', '12345678901'));
$this->assertTrue(VatNumber::check('HU', '12345678'));
$this->assertTrue(VatNumber::check('IE', '1234567X'));
$this->assertTrue(VatNumber::check('IE', '1X23456X'));
$this->assertTrue(VatNumber::check('IE', '1234567XX'));
$this->assertTrue(VatNumber::check('IE', '1X23456X'));
$this->assertTrue(VatNumber::check('IT', '00154189997'));
$this->assertTrue(VatNumber::check('LV', '12345678901'));
$this->assertTrue(VatNumber::check('IT', '01573850516'));
$this->assertTrue(VatNumber::check('LT', '123456789'));
$this->assertTrue(VatNumber::check('LT', '123456789012'));
$this->assertTrue(VatNumber::check('LU', '12345678'));
$this->assertTrue(VatNumber::check('LV', '12345678901'));
$this->assertTrue(VatNumber::check('MK', 'MK4032013544513'));
$this->assertTrue(VatNumber::check('MT', '12345678'));
$this->assertTrue(VatNumber::check('NG', '01012345-0001'));
Expand All @@ -79,12 +82,9 @@ public function testCheckValids()
$this->assertTrue(VatNumber::check('RU', '9999999999'));
$this->assertTrue(VatNumber::check('RU', '999999999999'));
$this->assertTrue(VatNumber::check('RU', '9999999999999'));
$this->assertTrue(VatNumber::check('SK', '1234567890'));
$this->assertTrue(VatNumber::check('SI', '12345678'));
$this->assertTrue(VatNumber::check('ES', 'X12345678'));
$this->assertTrue(VatNumber::check('ES', '12345678X'));
$this->assertTrue(VatNumber::check('ES', 'X1234567X'));
$this->assertTrue(VatNumber::check('SE', '123456789012'));
$this->assertTrue(VatNumber::check('SI', '12345678'));
$this->assertTrue(VatNumber::check('SK', '1234567890'));
}

/**
Expand All @@ -108,6 +108,7 @@ public function testCheckWithInvalidLength()
$this->assertFalse(VatNumber::check('AT', 'U123456780'));
$this->assertFalse(VatNumber::check('AU', '123456789012'));
$this->assertFalse(VatNumber::check('CA', '1234567ABC'));
$this->assertFalse(VatNumber::check('DE', '12226587'));
$this->assertFalse(VatNumber::check('IT', '001541899970'));
$this->assertFalse(VatNumber::check('MK', 'MK40320135445131'));
$this->assertFalse(VatNumber::check('RU', '99999999999999'));
Expand All @@ -124,8 +125,9 @@ public function testCheckWithInvalidCharacters()
$this->assertFalse(VatNumber::check('AL', 'K999999999'));
$this->assertFalse(VatNumber::check('AT', 'A12345678'));
$this->assertFalse(VatNumber::check('AU', 'A2345678901'));
$this->assertFalse(VatNumber::check('DE', '122265873'));
$this->assertFalse(VatNumber::check('IT', '01573850514'));
$this->assertFalse(VatNumber::check('MK', 'AA4032013544513'));
$this->assertFalse(VatNumber::check('NO', '123456789MV'));
}
}
}

0 comments on commit 9ef3cf0

Please sign in to comment.