Skip to content

Commit

Permalink
Find invalid chars in the VAT number and throw an exception if there …
Browse files Browse the repository at this point in the history
…are some

Fix #19
  • Loading branch information
spaze committed Sep 20, 2020
1 parent 5573e51 commit be6ea9f
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 0 deletions.
4 changes: 4 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ parameters:
message: '#^Call to an undefined method SoapClient::checkVatApprox\(\)\.$#'
path: src/VatCalculator.php
count: 1
- # https://github.com/phpstan/phpstan-src/pull/324
message: '#^Parameter \#1 \$invalidChars of class Spaze\\VatCalculator\\Exceptions\\InvalidCharsInVatNumberException constructor expects array<int, array\(string, int\)>, array<int, string> given.$#'
path: src/VatCalculator.php
count: 1

includes:
- vendor/phpstan/phpstan/conf/bleedingEdge.neon
39 changes: 39 additions & 0 deletions src/Exceptions/InvalidCharsInVatNumberException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
declare(strict_types = 1);

namespace Spaze\VatCalculator\Exceptions;

use Throwable;

class InvalidCharsInVatNumberException extends VatNumberException
{

/** @var string[] */
private $invalidChars = [];


/**
* @param array<integer, array{0: string, 1:integer}> $invalidChars
* @param string $vatNumber
* @param Throwable|null $previous
*/
public function __construct(array $invalidChars, string $vatNumber, Throwable $previous = null)
{
$chars = [];
foreach ($invalidChars as $invalidChar) {
$chars[] = sprintf('%s (0x%s) at offset %d', $invalidChar[0], bin2hex($invalidChar[0]), $invalidChar[1]);
$this->invalidChars[] = $invalidChar[0];
}
parent::__construct("VAT number {$vatNumber} contains invalid characters: " . implode(', ', $chars), 0, $previous);
}


/**
* @return string[]
*/
public function getInvalidChars(): array
{
return $this->invalidChars;
}

}
9 changes: 9 additions & 0 deletions src/VatCalculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace Spaze\VatCalculator;

use DateTimeInterface;
use Spaze\VatCalculator\Exceptions\InvalidCharsInVatNumberException;
use Spaze\VatCalculator\Exceptions\UnsupportedCountryException;
use Spaze\VatCalculator\Exceptions\VatCheckUnavailableException;
use SoapClient;
Expand Down Expand Up @@ -129,6 +130,7 @@ public function getTaxRateForLocation(string $countryCode, ?string $postalCode,
* @return bool
* @throws VatCheckUnavailableException
* @throws UnsupportedCountryException
* @throws InvalidCharsInVatNumberException
*/
public function isValidVatNumber(string $vatNumber): bool
{
Expand All @@ -142,10 +144,17 @@ public function isValidVatNumber(string $vatNumber): bool
* @return VatDetails
* @throws VatCheckUnavailableException
* @throws UnsupportedCountryException
* @throws InvalidCharsInVatNumberException
*/
public function getVatDetails(string $vatNumber, ?string $requesterVatNumber = null): VatDetails
{
$vatNumber = str_replace([' ', "\xC2\xA0", "\xA0", '-', '.', ','], '', trim($vatNumber));

$invalidChars = preg_split('/[0-9A-Za-z+*.]+/', $vatNumber, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
if ($invalidChars) {
throw new InvalidCharsInVatNumberException($invalidChars, $vatNumber);
}

$countryCode = substr($vatNumber, 0, 2);
$vatNumber = substr($vatNumber, 2);

Expand Down
8 changes: 8 additions & 0 deletions tests/VatCalculatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use ReflectionClass;
use SoapClient;
use SoapFault;
use Spaze\VatCalculator\Exceptions\InvalidCharsInVatNumberException;
use Spaze\VatCalculator\Exceptions\UnsupportedCountryException;
use Spaze\VatCalculator\Exceptions\VatCheckUnavailableException;
use stdClass;
Expand Down Expand Up @@ -151,6 +152,13 @@ public function testValidateVatNumberThrowsExceptionOnInvalidCountry(): void
}


public function testValidateVatNumberThrowsExceptionOnInvalidChars(): void
{
$this->setExpectedException(InvalidCharsInVatNumberException::class, 'VAT number CY123Μ456_789 contains invalid characters: Μ (0xce9c) at offset 5, _ (0x5f) at offset 10');
$this->vatCalculator->isValidVatNumber('CY123Μ456_789');
}


public function testCanValidateValidVatNumberWithRequesterVatNumber()
{
$result = new stdClass();
Expand Down

0 comments on commit be6ea9f

Please sign in to comment.