From 772c95efd4a3c920e639fb107768dca22873b62c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sas=CC=8Ca=20Jovanic=CC=81?= Date: Sat, 2 Dec 2023 21:23:58 +0100 Subject: [PATCH] Add Dutch BBAN validation Fixes #415 --- ChangeLog | 6 +++++- dist/ibantools.js | 34 +++++++++++++++++++++++++++++++++- package.json | 2 +- src/ibantools.ts | 28 +++++++++++++++++++++++++++- test/ibantools_test.js | 11 ++++++++++- 5 files changed, 76 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 238e018..7f6ad09 100755 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ -2023-10-14 Saša Jovanić +2023-12-14 Saša Jovanić + * Version 4.3.7 + * Added Dutch (NL) BBAN validation + +2023-11-26 Saša Jovanić * Version 4.3.6 2023-11-13 Davide Bianco diff --git a/dist/ibantools.js b/dist/ibantools.js index 9e06273..adaea80 100644 --- a/dist/ibantools.js +++ b/dist/ibantools.js @@ -9,7 +9,7 @@ define(["require", "exports"], function (require, exports) { * @package Documentation * @author Saša Jovanić * @module ibantools - * @version 4.3.6 + * @version 4.3.7 * @license MPL-2.0 * @preferred */ @@ -777,6 +777,37 @@ define(["require", "exports"], function (require, exports) { return controlDigitAccount === (remainder_2 === 0 ? 0 : 10 - remainder_2); } }; + /** + * Dutch (NL) BBAN check + * + * @ignore + */ + var checkDutchBBAN = function (bban) { + if (bban === '') { + return false; + } + var weights = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]; + var toCheckAccount = bban.substring(4, 14); + if (toCheckAccount.startsWith('000')) { + return true; + } + if (toCheckAccount.startsWith('00')) { + return false; + } + var sum = toCheckAccount + .split('') + .map(function (value, index) { + if (value === '0' && index === 0) { + return 0; + } + var number = parseInt(value, 10); + var weight = weights[index]; + return number * weight; + }) + .reduce(function (a, b) { return a + b; }); + console.log(sum); + return sum % 11 === 0; + }; /** * Set custom BBAN validation function for country. * @@ -1430,6 +1461,7 @@ define(["require", "exports"], function (require, exports) { NL: { chars: 18, bban_regexp: '^[A-Z]{4}[0-9]{10}$', + bban_validation_func: checkDutchBBAN, IBANRegistry: true, SEPA: true, bank_identifier: '0-3', diff --git a/package.json b/package.json index f617cb2..b659f78 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ibantools", - "version": "4.3.6", + "version": "4.3.7", "description": "Validation, extraction and creation of IBAN, BBAN, BIC/SWIFT numbers plus some other helpful stuff like ISO 3136-1 alpha 2 country list", "keywords": [ "IBAN", diff --git a/src/ibantools.ts b/src/ibantools.ts index b5cd191..f895b61 100755 --- a/src/ibantools.ts +++ b/src/ibantools.ts @@ -9,7 +9,7 @@ * @package Documentation * @author Saša Jovanić * @module ibantools - * @version 4.3.6 + * @version 4.3.7 * @license MPL-2.0 * @preferred */ @@ -894,6 +894,31 @@ const checkHungarianBBAN = (bban: string): boolean => { } }; +/** + * Dutch (NL) BBAN check + * + * @ignore + */ +const checkDutchBBAN = (bban: string): boolean => { + if(bban === '') { return false; } + + const weights = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]; + const toCheckAccount = bban.substring(4, 14); + if(toCheckAccount.startsWith('000')) { return true; } + if(toCheckAccount.startsWith('00')) { return false; } + const sum: number = toCheckAccount + .split('') + .map((value: string, index: number) => { + if(value === '0' && index === 0) { return 0; } + const number = parseInt(value, 10); + const weight = weights[index]; + return number * weight; + }) + .reduce((a: number, b: number) => a + b); + console.log(sum); + return sum % 11 === 0; +} + /** * Set custom BBAN validation function for country. * @@ -1548,6 +1573,7 @@ export const countrySpecs: CountryMapInternal = { NL: { chars: 18, bban_regexp: '^[A-Z]{4}[0-9]{10}$', + bban_validation_func: checkDutchBBAN, IBANRegistry: true, SEPA: true, bank_identifier: '0-3', diff --git a/test/ibantools_test.js b/test/ibantools_test.js index 75e4edc..e514a26 100644 --- a/test/ibantools_test.js +++ b/test/ibantools_test.js @@ -299,6 +299,12 @@ describe('IBANTools', function() { it('with valid RU IBAN should return true', function() { expect(iban.isValidIBAN('RU0204452560040702810412345678901')).to.be.true; }); + it('with valid old Postbank Dutch IBAN should return true', function() { + expect(iban.isValidIBAN('NL08INGB0000000555')).to.be.true; + }); + it('with invalid Dutch IBAN should return false', function() { + expect(iban.isValidIBAN('NL08INGB0012345555')).to.be.false; + }); it('with two dots should return false', function() { expect(iban.isValidIBAN('..')).to.be.false; }); @@ -344,6 +350,7 @@ describe('IBANTools', function() { errorCodes: [ iban.ValidationErrorsIBAN.WrongBBANLength, iban.ValidationErrorsIBAN.WrongBBANFormat, + iban.ValidationErrorsIBAN.WrongAccountBankBranchChecksum, iban.ValidationErrorsIBAN.WrongIBANChecksum, ], }); @@ -383,7 +390,8 @@ describe('IBANTools', function() { it('with invalid IBAN checksum should return false with correct code', function() { expect(iban.validateIBAN('NL91ABNA0517164300')).to.deep.equal({ valid: false, - errorCodes: [iban.ValidationErrorsIBAN.WrongIBANChecksum], + errorCodes: [iban.ValidationErrorsIBAN.WrongAccountBankBranchChecksum, + iban.ValidationErrorsIBAN.WrongIBANChecksum], }); }); @@ -400,6 +408,7 @@ describe('IBANTools', function() { errorCodes: [ iban.ValidationErrorsIBAN.WrongBBANLength, iban.ValidationErrorsIBAN.WrongBBANFormat, + iban.ValidationErrorsIBAN.WrongAccountBankBranchChecksum, iban.ValidationErrorsIBAN.ChecksumNotNumber, iban.ValidationErrorsIBAN.WrongIBANChecksum, ],