Skip to content

Commit

Permalink
[feat] Added validation rule for austrian insurance numbers (#82)
Browse files Browse the repository at this point in the history
  • Loading branch information
lkrempler authored May 25, 2024
1 parent 3a01758 commit 48e0ad8
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 0 deletions.
75 changes: 75 additions & 0 deletions src/Rules/AustrianInsuranceNumber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

declare(strict_types=1);

namespace Intervention\Validation\Rules;

use Intervention\Validation\AbstractRule;

class AustrianInsuranceNumber extends AbstractRule
{
/**
* Austrian insurance number length
*
* @var int
*/
private int $length = 10;

/**
* Multiplier series to calculate checksum
* https://www.sozialversicherung.at/cdscontent/?contentid=10007.820902&viewmode=content
*
* @var array
*/
private array $multiplierSeries = [
3, 7, 9, 5, 8, 4, 2, 1, 6
];

/**
* Determine if the validation rule passes.
*
* @param mixed $value
* @return bool
*/
public function isValid(mixed $value): bool
{
$value = str_replace(' ', '', $value);

return is_numeric($value)
&& $this->startsNotWithZero($value)
&& $this->hasValidLength($value)
&& $this->checkChecksum($value);
}

private function hasValidLength($svnumber): bool
{
return $this->length === strlen($svnumber);
}

private function startsNotWithZero($svnumber): bool
{
return (int) $svnumber[0] !== 0;
}

private function checkChecksum($svnumber): bool
{
if (strlen($svnumber) !== $this->length) {
return false;
}

$checksumSVNumber = (int) $svnumber[3];
$svnumberWithoutChecksum = substr($svnumber, 0, 3) . substr($svnumber, 4);

$sum = 0;
for ($c = 0, $cMax = strlen($svnumberWithoutChecksum); $c < $cMax; $c++) {
$result = $svnumberWithoutChecksum[$c] * $this->multiplierSeries[$c];
$sum += $result;
}
$checksum = $sum % 11;

if ($checksum === 10) {
return false;
}
return $checksum === $checksumSVNumber;
}
}
1 change: 1 addition & 0 deletions src/lang/de/validation.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@
'gtin' => 'Der Wert :attribute ist keine gültige Global Trade Item Number (GTIN).',
'postalcode' => 'Der Wert :attribute muss eine gültige Postleitzahl sein.',
'mimetype' => 'Der Wert :attribute einhält keinen gültigen Internet Media Type (MIME-Type).',
'austrianinsurancenumber' => 'Der Wert :attribute enthält keine gültige österreichische Versicherungsnummer',
];
1 change: 1 addition & 0 deletions src/lang/en/validation.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@
'gtin' => 'The :attribute is not a valid Global Trade Item Number (GTIN).',
'postalcode' => 'The value :attribute must be a valid postal code.',
'mimetype' => 'The value :attribute does not contain a valid Internet Media Type (MIME-Type).',
'austrianinsurancenumber' => 'The value :attribute does not contain a valid austrian insurance number.',
];
34 changes: 34 additions & 0 deletions tests/Rules/AustrianInsuranceNumberTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Intervention\Validation\Tests\Rules;

use Intervention\Validation\Rules\AustrianInsuranceNumber;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

final class AustrianInsuranceNumberTest extends TestCase
{
#[DataProvider('dataProvider')]
public function testValidation($result, $value): void
{
$valid = (new AustrianInsuranceNumber())->isValid($value);
$this->assertEquals($result, $valid);
}

public static function dataProvider(): array
{
return [
[true, '8757080475'],
[true, '1230011471'],
[false, '1234567890'],
[false, '0123456789'],
[false, '12345'],
[false, '25bc78'],
[false, '8753080475'],
[false, 'foo'],
[true, '1230 011471'],
];
}
}

0 comments on commit 48e0ad8

Please sign in to comment.