diff --git a/README.md b/README.md index c0e8748..84a1b69 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,9 @@ Validation of IBAN and BBAN numbers and other country specific bank account formats. Extendable with custom validations # Rules -## Swedish Bban rules is implemented based on this document: -https://www.bankgirot.se/globalassets/dokument/anvandarmanualer/bankernaskontonummeruppbyggnad_anvandarmanual_sv.pdf -EG25001000540 -EG250010005400000100026173878 \ No newline at end of file +## Swedish Bban rules +Implementation is based on this document: +* https://www.bankgirot.se/globalassets/dokument/anvandarmanualer/bankernaskontonummeruppbyggnad_anvandarmanual_sv.pdf + +And ading supporting for 5 digit clearing number as well: +* https://www.swedbank.se/privat/betala-och-overfora/konton/clearingnummer/5-siffriga-clearingnummer-som-borjar-pa-siffran-8.html diff --git a/src/validators/SwedishBbanValidation.ts b/src/validators/SwedishBbanValidation.ts index 2c697ef..cde7653 100644 --- a/src/validators/SwedishBbanValidation.ts +++ b/src/validators/SwedishBbanValidation.ts @@ -15,11 +15,11 @@ interface Account{ } function extractClearingNumber(_clearing: string | null, bban: string) { - return _clearing ? parseInt(_clearing) : parseInt(bban.substr(0, 4)) + return _clearing ? parseInt(_clearing) : parseInt(bban.slice(0, 4)) } function extractAccountNumberOnly(_clearing: string | null, bban: string) { - return _clearing ? bban : bban.substr(4) + return _clearing ? bban : bban.slice(4) } function getType(clearingNumber:number):string { @@ -64,11 +64,14 @@ function parseClearingAndAccountNumber(_clearing:string|null, bban:string):Accou export class SwedishBbanValidation implements IStrictValidation { _config: types.BankAccountValidationConfig private _syntaxTester: RegExp + private _syntaxTesterSwedbank: RegExp constructor(config: Partial) { this._config = defaultsDeep({}, config, defaultConfig) /* syntax: optional clearing (4 digit) + account number (7, 9 or 10 digit)*/ this._syntaxTester = /^(\d{4}(:?\d{7}|\d{9}|\d{10})|(:?\d{7}|\d{9}|\d{10}))$/ + /* syntax: 5 digit clearing starting with 8 + nolla + account number 9 digit */ + this._syntaxTesterSwedbank = /^8\d{4}0\d{9}$/ } canValidate(input: ValidationInput): Boolean { @@ -94,7 +97,7 @@ export class SwedishBbanValidation implements IStrictValidation { const account = parseClearingAndAccountNumber(input.clearingNumber || null, input.accountNumber) - const validSyntax = this._syntaxTester.test(account.bban) + const validSyntax = this._syntaxTester.test(account.bban) || this._syntaxTesterSwedbank.test(account.bban) if (!validSyntax){ return { @@ -104,11 +107,13 @@ export class SwedishBbanValidation implements IStrictValidation { } if ( - account.type === '1.1' && account.length === 7 && sweMod11(account.bban.substr(1)) || + account.type === '1.1' && account.length === 7 && sweMod11(account.bban.slice(1)) || account.type === '1.2' && account.length === 7 && sweMod11(account.bban) || account.type === '2.1' && account.length === 10 && sweMod10(account.accountNumber) || account.type === '2.2' && account.length === 9 && sweMod11(account.accountNumber) || - account.type === '2.3' && account.length === 10 && sweMod10(account.accountNumber) + account.type === '2.3' && account.length === 10 && sweMod10(account.accountNumber) || + // supporting 5 digit clearing number - Swedbank + account.type === '2.3' && account.length === 11 && sweMod10(account.accountNumber.slice(-10)) ){ return { valid: true, diff --git a/test/SE/testBbanValidation.ts b/test/SE/testBbanValidation.ts index 6fe4b50..2bb6212 100644 --- a/test/SE/testBbanValidation.ts +++ b/test/SE/testBbanValidation.ts @@ -59,12 +59,6 @@ describe('SwedishBbanValidation', ()=> { reason: null }) }) - it('should validate a valid type 2.3 Swedish BBAN account (Swedbank)', ()=>{ - chai.expect(validation.validate({accountNumber: '83881122211004'})).to.deep.equal({ - 'valid': true, - reason: null - }) - }) it('should invalidate an invalid Swedish BBAN account', ()=>{ chai.expect(validation.validate({accountNumber: '54401122004'})).to.deep.equal({ @@ -135,12 +129,6 @@ describe('SwedishBbanValidation', ()=> { reason: null }) }) - it('should validate a valid type 2.3 Swedish BBAN account (Swedbank)', ()=>{ - chai.expect(validation.validate({clearingNumber:'8388', accountNumber: '1122211004'})).to.deep.equal({ - 'valid': true, - reason: null - }) - }) xit('should invalidate an invalid Swedish BBAN account', ()=>{ chai.expect(validation.validate({clearingNumber:'5440', accountNumber: '1122004'})).to.deep.equal({ @@ -171,6 +159,54 @@ describe('SwedishBbanValidation', ()=> { }) }) + describe('4 char clearing number type 2.3 (that starts with 8) Swedish Swedbank BBAN account ', ()=> { + // CCCC0KKKKKKKKK + // (4 siffror i clearingnumret, en extra nolla, 9 siffror i kontonumret - totalt 14 siffror). + it('should validate a valid type 2.3 Swedish BBAN account (Swedbank)', ()=>{ // TODO: here + chai.expect(validation.validate({accountNumber: '83880122211006'})).to.deep.equal({ + 'valid': true, + reason: null + }) + }) + it('should validate account number with starting 0', ()=>{ + chai.expect(validation.validate({clearingNumber:'8388', accountNumber: '0122211006'})).to.deep.equal({ + 'valid': true, + reason: null + }) + }) + + it('should validate account number without starting 0', ()=>{ + chai.expect(validation.validate({clearingNumber:'8388', accountNumber: '122211006'})).to.deep.equal({ + 'valid': true, + reason: null + }) + }) + }) + + describe('5 char clearing number type 2.3 (that starts with 8) Swedish Swedbank BBAN account ', ()=> { + // CCCCC0KKKKKKKKK + // (5 siffror i clearingnumret, en extra nolla, 9 siffror i kontonumret - totalt 15 siffror). + it('should validate a valid type 2.3 Swedish BBAN account (Swedbank)', ()=>{ + chai.expect(validation.validate({accountNumber: '838890122211006'})).to.deep.equal({ + 'valid': true, + reason: null + }) + }) + it('should validate account number with starting 0', ()=>{ + chai.expect(validation.validate({clearingNumber:'83889', accountNumber: '0122211006'})).to.deep.equal({ + 'valid': true, + reason: null + }) + }) + + it('should validate account number without starting 0', ()=>{ + chai.expect(validation.validate({clearingNumber:'83889', accountNumber: '122211006'})).to.deep.equal({ + 'valid': true, + reason: null + }) + }) + }) + describe('when determining suitability', ()=> { it('should accept a Swedish country', ()=>{ chai.expect(validation.canValidate({accountNumber: 'invalid', countryCode: 'SE', type: 'bban'})).to.equal(true)