Skip to content

Commit

Permalink
Merge pull request #4 from snamor/create-iban-from-bban-country-code
Browse files Browse the repository at this point in the history
Optimize code. Allow creation from valid Bban and country code.
  • Loading branch information
xafardero authored Feb 1, 2017
2 parents a616860 + 3f49eb6 commit de9c1a3
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 27 deletions.
28 changes: 18 additions & 10 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false">
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.7/phpunit.xsd"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="vendor/autoload.php">
<testsuites>
<testsuite name="Demo Test Suite">
<directory suffix=".php">./tests/</directory>
</testsuite>
</testsuites>

<filter>
<whitelist>
<directory>./src/</directory>
</whitelist>
</filter>
</phpunit>
6 changes: 3 additions & 3 deletions src/Bban/SpainBban.php
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,12 @@ private static function validateControlDigit(
foreach ([$bankCode . $branchCode, $accountNumber] as $string) {
$suma = 0;
for ($i = 0, $len = strlen($string); $i < $len; $i++) {
$suma += $validations[$i] * substr($string, $len - $i - 1, 1);
$suma += $validations[$i] * $string[$len - $i - 1];
}
$digit = 11 - $suma % 11;
if ($digit == 11) {
if ($digit === 11) {
$digit = 0;
} elseif ($digit == 10) {
} elseif ($digit === 10) {
$digit = 1;
}
$dc .= $digit;
Expand Down
73 changes: 60 additions & 13 deletions src/Iban.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,7 @@ public static function fromString($iban)
$checkDigits = substr($iban, 2, 2);
$bbanString = substr($iban, 4);

if (! array_key_exists($countryCode, self::$countriesSupported)) {
throw new InvalidArgumentException(
sprintf(
'The country code %s is not supported',
$countryCode
)
);
}
self::validateSupportedCountry($countryCode);
$bbanClass = self::$countriesSupported[$countryCode];

/**
Expand All @@ -85,6 +78,27 @@ public static function fromString($iban)
return new static($countryCode, $checkDigits, $bban);
}

/**
* @param BbanInterface $bban
* @param string $countryCode
*
* @throws InvalidArgumentException
*
* @return static
*/
public static function fromBbanAndCountry(BbanInterface $bban, $countryCode)
{
static::validateCountryCodeFormat($countryCode);
static::validateCountryCodeFormat($countryCode);
static::validateSupportedCountry($countryCode);

$checksum = self::validateChecksum($countryCode, '00', $bban);
$checkDigit = 98 - (int) $checksum;
$checkDigit = str_pad($checkDigit, 2, 0, STR_PAD_LEFT);

return new static($countryCode, $checkDigit, $bban);
}

/**
* @return string
*/
Expand Down Expand Up @@ -179,15 +193,48 @@ private static function validateControlDigit(
$checkDigits,
BbanInterface $bban
) {
$rearranged = strval($bban) . $countryCode . $checkDigits;
$checksum = self::validateChecksum($countryCode, $checkDigits, $bban);

if ($checksum !== '01') {
throw new InvalidArgumentException('The IBAN checksum digits are not valid');
}
}

/**
* @param $countryCode
*
* @throws InvalidArgumentException
*/
private static function validateSupportedCountry($countryCode)
{
if (!array_key_exists($countryCode, self::$countriesSupported)) {
throw new InvalidArgumentException(
sprintf(
'The country code %s is not supported',
$countryCode
)
);
}
}

/**
* @param $countryCode
* @param $checkDigits
* @param BbanInterface $bban
*
* @return string
*/
private static function validateChecksum($countryCode, $checkDigits, BbanInterface $bban)
{
$rearranged = (string) $bban . $countryCode . $checkDigits;
$digitsList = str_split($rearranged);

$digitsList = array_map(['self', 'digitToInt'], $digitsList);
$stringToCompute = implode('', $digitsList);

if (bcmod($stringToCompute, '97') !== '1') {
throw new InvalidArgumentException('The IBAN checksum digits are not valid');
}
$checksum = bcmod($stringToCompute, '97');

return str_pad($checksum, 2, 0, STR_PAD_LEFT);
}

/**
Expand All @@ -198,7 +245,7 @@ private static function validateControlDigit(
private static function digitToInt($value)
{
if (is_numeric($value)) {
return intval($value);
return (int) $value;
}

return ord($value) - 55;
Expand Down
31 changes: 30 additions & 1 deletion tests/IbanTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public function testValidIban(
* @param $controlDigits
* @param $bankAccount
*/
public function testValidIbanFromString(
public function testCreateFromValidString(
$countryCode,
$ibanChecksum,
$bankCode,
Expand All @@ -71,6 +71,35 @@ public function testValidIbanFromString(
$this->assertEquals($stringIban, $iban->__toString());
}

/**
* @dataProvider validIbans
*
* @param $countryCode
* @param $ibanChecksum
* @param $bankCode
* @param $branchCode
* @param $controlDigits
* @param $bankAccount
*/
public function testCreateFromValidBban(
$countryCode,
$ibanChecksum,
$bankCode,
$branchCode,
$controlDigits,
$bankAccount
) {
$bban = $this->prophesizeBban(
$bankCode,
$branchCode,
$controlDigits,
$bankAccount
);

$iban = Iban::fromBbanAndCountry($bban, 'ES');
$this->assertEquals($ibanChecksum, $iban->ibanCheckDigits());
}

/**
* @dataProvider notSupportedIbans
*
Expand Down

0 comments on commit de9c1a3

Please sign in to comment.