bank_account_tools 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,47 @@
1
+ require 'forwardable'
2
+ require 'bank_account_tools/bban'
3
+ require 'bank_account_tools/validators/iban_validator' if defined? ActiveModel
4
+
5
+ module BankAccountTools
6
+ class IBAN # International Bank Account Number
7
+ extend Forwardable
8
+ def_delegators :bban,
9
+ :account_number, :bank_identifier, :branch_identifier, :country_applies_iban?
10
+
11
+ def self.valid?(code)
12
+ new(code).valid?
13
+ end
14
+
15
+ def initialize(code)
16
+ @code = code.to_s.gsub(/\s+/, '').upcase
17
+ end
18
+
19
+ def country_code
20
+ @code[0..1]
21
+ end
22
+
23
+ def check_digits
24
+ @code[2..3]
25
+ end
26
+
27
+ def bban
28
+ @bban ||= BBAN.new(country_code, @code[4..-1])
29
+ end
30
+
31
+ def valid?
32
+ valid_check_digits? && bban.valid?
33
+ end
34
+
35
+ def valid_check_digits?
36
+ to_i % 97 == 1
37
+ end
38
+
39
+ def to_i
40
+ "#{bban}#{country_code}#{check_digits}".each_char.map { |chr| chr.to_i(36) }.join.to_i
41
+ end
42
+
43
+ def to_s(formatted=false)
44
+ formatted ? @code.gsub(/(.{4})/, '\1 ').strip : @code
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,9 @@
1
+ RSpec::Matchers.define :have_valid_bic do |attribute|
2
+ match do
3
+ actual_class_name = subject.is_a?(Class) ? subject : subject.class
4
+ actual = actual_class_name.new
5
+
6
+ expect(actual).to be_invalid
7
+ expect(actual.errors[attribute.to_sym]).to include('is of invalid format')
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ RSpec::Matchers.define :have_valid_iban do |attribute|
2
+ match do
3
+ actual_class_name = subject.is_a?(Class) ? subject : subject.class
4
+ actual = actual_class_name.new
5
+
6
+ expect(actual).to be_invalid
7
+ expect(actual.errors[attribute.to_sym]).to include('is of invalid format')
8
+ end
9
+ end
@@ -0,0 +1,2 @@
1
+ require_relative 'active_model/have_valid_iban'
2
+ require_relative 'active_model/have_valid_bic'
@@ -0,0 +1,7 @@
1
+ require 'active_model/validator'
2
+
3
+ class BicValidator < ActiveModel::EachValidator
4
+ def validate_each(record, attribute, value)
5
+ record.errors.add(attribute, :invalid) unless BankAccountTools::BIC.valid?(value)
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'active_model/validator'
2
+
3
+ class IbanValidator < ActiveModel::EachValidator
4
+ def validate_each(record, attribute, value)
5
+ record.errors.add(attribute, :invalid) unless BankAccountTools::IBAN.valid?(value)
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module BankAccountTools
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,19 @@
1
+ require 'bank_account_tools/version'
2
+ require 'bank_account_tools/iban'
3
+ require 'bank_account_tools/bic'
4
+ require 'bank_account_tools/bban'
5
+ require 'bank_account_tools/contact'
6
+
7
+ require 'pathname'
8
+ require 'yaml'
9
+
10
+ if defined?(::ActiveModel)
11
+ require 'bank_account_tools/validators/bic_validator'
12
+ require 'bank_account_tools/validators/iban_validator'
13
+ end
14
+
15
+ module BankAccountTools
16
+ def self.load_specifications(name)
17
+ YAML.load_file Pathname.new(__FILE__).dirname.parent + 'data' + "#{name}.yml"
18
+ end
19
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ class BankAccount
4
+ include ActiveModel::Model
5
+
6
+ attr_accessor :iban_required, :iban_optional
7
+
8
+ validates :iban_required, iban: true
9
+ validates :iban_optional, iban: true, allow_nil: true
10
+ end
11
+
12
+ describe IbanValidator do
13
+ let(:model) { BankAccount.new }
14
+
15
+ it 'is valid' do
16
+ model.iban_required = 'FR1420041010050500013M02606'
17
+
18
+ expect(model).to be_valid
19
+ end
20
+
21
+ it 'is not valid' do
22
+ model.iban_required = 'FR1420041010050500013'
23
+
24
+ expect(model).to be_invalid
25
+ expect(model.errors[:iban_required]).to include('is invalid')
26
+ end
27
+
28
+ it 'does not validate with nil value' do
29
+ model.iban_required = 'FR1420041010050500013M02606'
30
+ model.iban_optional = nil
31
+
32
+ expect(model).to be_valid
33
+ end
34
+ end
data/spec/bic_spec.rb ADDED
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe BankAccountTools::BIC do
4
+ let(:bic) { described_class.new('ABNACHZ8XXX')}
5
+
6
+ it 'returns the right bank code' do
7
+ expect(bic.bank_code).to eq('ABNA')
8
+ end
9
+
10
+ it 'returns the right country code' do
11
+ expect(bic.country_code).to eq('CH')
12
+ end
13
+
14
+ it 'returns the right location code' do
15
+ expect(bic.location_code).to eq('Z8')
16
+ end
17
+
18
+ it 'returns the right branch code' do
19
+ expect(bic.branch_code).to eq('XXX')
20
+ end
21
+
22
+ [
23
+ 'UCJAES2MXXX',
24
+ 'ABAGATWWXXX',
25
+ 'UCJAES2MXXX'
26
+ ].each do |code|
27
+ describe code do
28
+ it 'has a valid format' do
29
+ expect(BankAccountTools::BIC.new(code)).to be_valid
30
+ end
31
+ end
32
+ end
33
+
34
+ [
35
+ '12341234', # only digits
36
+ 'UCJAES2MXAA', # branch code starts with 'X'
37
+ 'UCJAES2MAA', # too short
38
+ 'UCJAES2M0001' # too long
39
+ ].each do |code|
40
+ describe code do
41
+ it 'has an invalid format' do
42
+ expect(BankAccountTools::BIC.new(code)).not_to be_valid
43
+ end
44
+ end
45
+ end
46
+
47
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe BankAccountTools::Contact do
4
+ let(:iban) { BankAccountTools::IBAN.new('FR14 2004 1010 0505 0001 3M026 06') }
5
+ let(:bic) { BankAccountTools::BIC.new('BYLADEM1203') }
6
+ let(:contact) { BankAccountTools::Contact.new(iban, bic) }
7
+
8
+ it 'is validate' do
9
+ expect(contact).to be_valid
10
+ end
11
+
12
+ it 'has the right types' do
13
+ expect(contact.iban).to be_kind_of(BankAccountTools::IBAN)
14
+ expect(contact.bic).to be_kind_of(BankAccountTools::BIC)
15
+ end
16
+
17
+ it 'exports to_h' do
18
+ expect(contact.to_h).to eq(
19
+ iban: 'FR1420041010050500013M02606',
20
+ bic: 'BYLADEM1203'
21
+ )
22
+ end
23
+
24
+ it 'exports to_a' do
25
+ expect(contact.to_a).to eq(['FR1420041010050500013M02606', 'BYLADEM1203'])
26
+ end
27
+ end
data/spec/iban_spec.rb ADDED
@@ -0,0 +1,160 @@
1
+ require 'spec_helper'
2
+
3
+ describe BankAccountTools::IBAN do
4
+ let(:iban) { BankAccountTools::IBAN.new('FR14 2004 1010 0505 0001 3M026 06') }
5
+
6
+ it 'is valid from class method' do
7
+ expect(BankAccountTools::IBAN.valid?('FR14 2004 1010 0505 0001 3M026 06')).to be_truthy
8
+ end
9
+
10
+ it 'loads the validation rules' do
11
+ expect(BankAccountTools.load_specifications(:iban)).to be_present
12
+ expect(BankAccountTools.load_specifications(:iban)).to be_kind_of(Hash)
13
+ end
14
+
15
+ it 'should return the county code' do
16
+ expect(iban.country_code).to eq('FR')
17
+ end
18
+
19
+ it 'should return the check digits' do
20
+ expect(iban.check_digits).to eq('14')
21
+ end
22
+
23
+ it 'should return the BBAN' do
24
+ expect(iban.bban).to be_a(BankAccountTools::BBAN)
25
+ expect(iban.bban.to_s).to eq('20041010050500013M02606')
26
+ end
27
+
28
+ it 'should convert to integer value' do
29
+ expect(iban.to_i).to eq(200410100505000132202606152714)
30
+ end
31
+
32
+ it 'should convert to string' do
33
+ expect(iban.to_s).to eq('FR1420041010050500013M02606')
34
+ end
35
+
36
+ it 'should convert to formatted string' do
37
+ expect(iban.to_s(true)).to eq('FR14 2004 1010 0505 0001 3M02 606')
38
+ end
39
+
40
+ it 'respond_to? account_number' do
41
+ expect(iban.respond_to?(:account_number)).to be_truthy
42
+ end
43
+
44
+ it 'returns account_number' do
45
+ expect(iban.account_number).to eq('0500013M026')
46
+ end
47
+
48
+ it 'returns bank_identifier' do
49
+ expect(iban.bank_identifier).to eq('20041')
50
+ end
51
+
52
+ it 'returns branch_identifier' do
53
+ expect(iban.branch_identifier).to eq('01005')
54
+ end
55
+
56
+ it 'knows which countries use IBAN' do
57
+ expect(iban.country_applies_iban?).to be_truthy
58
+
59
+ expect(BankAccountTools::IBAN.new('ZZ99 123456790').country_applies_iban?).to be_falsey
60
+ end
61
+
62
+ [
63
+ 'AL47212110090000000235698741',
64
+ 'AD12 00012030200359100100',
65
+ 'AT611904300234573201',
66
+ 'BE68539007547034',
67
+ 'BA391290079401028494',
68
+ 'BG80BNBG96611020345678',
69
+ 'HR1210010051863000160',
70
+ 'CY17002001280000001200527600',
71
+ 'CZ6508000000192000145399',
72
+ 'DK5000400440116243',
73
+ 'EE382200221020145685',
74
+ 'FO1464600009692713',
75
+ 'FI2112345600000785',
76
+ 'FR1420041010050500013M02606',
77
+ 'GE29NB0000000101904917',
78
+ 'DE89370400440532013000',
79
+ 'GI75NWBK000000007099453',
80
+ 'GR1601101250000000012300695',
81
+ 'GL8964710001000206',
82
+ 'HU42117730161111101800000000',
83
+ 'IS140159260076545510730339',
84
+ 'IE29AIBK93115212345678',
85
+ 'IT60X0542811101000000123456',
86
+ 'LV80BANK0000435195001',
87
+ 'LI21088100002324013AA',
88
+ 'LT121000011101001000',
89
+ 'LU280019400644750000',
90
+ 'MK07300000000042425',
91
+ 'MT84MALT011000012345MTLCAST001S',
92
+ 'MD24AG000225100013104168',
93
+ 'MC5813488000010051108001292',
94
+ 'ME25505000012345678951',
95
+ 'NL91ABNA0417164300',
96
+ 'NO9386011117947',
97
+ 'PL27114020040000300201355387',
98
+ 'PT50000201231234567890154',
99
+ 'RO49AAAA1B31007593840000',
100
+ 'SM86U0322509800000000270100',
101
+ 'RS35260005601001611379',
102
+ 'SK3112000000198742637541',
103
+ 'SI56191000000123438',
104
+ 'ES9121000418450200051332',
105
+ 'SE3550000000054910000003',
106
+ 'CH9300762011623852957',
107
+ 'UA573543470006762462054925026',
108
+ 'GB29NWBK60161331926819',
109
+ 'DZ4000400174401001050486',
110
+ 'AO06000600000100037131174',
111
+ 'AZ21NABZ00000000137010001944',
112
+ 'BH29BMAG1299123456BH00',
113
+ 'BJ11B00610100400271101192591',
114
+ 'BR9700360305000010009795493P1',
115
+ 'VG96VPVG0000012345678901',
116
+ 'BF1030134020015400945000643',
117
+ 'BI43201011067444',
118
+ 'CM2110003001000500000605306',
119
+ 'CV64000300004547069110176',
120
+ 'FR7630007000110009970004942',
121
+ 'CG5230011000202151234567890',
122
+ 'CR0515202001026284066',
123
+ 'DO28BAGR00000001212453611324',
124
+ 'EG1100006001880800100014553',
125
+ 'GA2140002000055602673300064',
126
+ 'GT82TRAJ01020000001210029690',
127
+ 'IR580540105180021273113007',
128
+ 'IL620108000000099999999',
129
+ 'CI05A00060174100178530011852',
130
+ 'KZ176010251000042993',
131
+ 'KW74NBOK0000000000001000372151',
132
+ 'LB30099900000001001925579115',
133
+ 'MG4600005030010101914016056',
134
+ 'ML03D00890170001002120000447',
135
+ 'MR1300012000010000002037372',
136
+ 'MU17BOMM0101101030300200000MUR',
137
+ 'MZ59000100000011834194157',
138
+ 'PK24SCBL0000001171495101',
139
+ 'PS92PALS000000000400123456702',
140
+ 'PT50000200000163099310355',
141
+ 'SA0380000000608010167519',
142
+ 'SN12K00100152000025690007542',
143
+ 'TN5914207207100707129648',
144
+ 'TR330006100519786457841326',
145
+ 'AE260211000000230064016',
146
+ 'XK051212012345678906',
147
+ 'JO94CBJO0010000000000131000302',
148
+ 'QA58DOHB00001234567890ABCDEFG',
149
+ 'TL380030000000025923744',
150
+ 'SC18SSCB11010000000000001497USD',
151
+ 'ST23000200000289355710148',
152
+ 'LC55HEMM000100010012001200023015',
153
+ ].each do |code|
154
+ describe code do
155
+ it 'is valid' do
156
+ expect(BankAccountTools::IBAN.new(code)).to be_valid
157
+ end
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,4 @@
1
+ require 'active_model'
2
+ require 'bank_account_tools/iban'
3
+ require 'bank_account_tools/bic'
4
+ require 'bank_account_tools/contact'
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bank_account_tools
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Dimitar Kostov
8
+ - Kevin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2017-08-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.13'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.13'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '12.0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '12.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '3.5'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '3.5'
56
+ - !ruby/object:Gem::Dependency
57
+ name: activemodel
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '4.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '4.0'
70
+ description: 'Bank account tools for dealing with IBANs/BICs: information, validation
71
+ and formatting.'
72
+ email:
73
+ - mitko.kostov@gmail.com
74
+ - kevin.melchert@gmail.com
75
+ executables: []
76
+ extensions: []
77
+ extra_rdoc_files: []
78
+ files:
79
+ - ".gitignore"
80
+ - ".rspec"
81
+ - ".travis.yml"
82
+ - Gemfile
83
+ - LICENSE
84
+ - README.md
85
+ - Rakefile
86
+ - bank_account_tools.gemspec
87
+ - data/iban.yml
88
+ - lib/bank_account_tools.rb
89
+ - lib/bank_account_tools/bban.rb
90
+ - lib/bank_account_tools/bic.rb
91
+ - lib/bank_account_tools/contact.rb
92
+ - lib/bank_account_tools/iban.rb
93
+ - lib/bank_account_tools/matchers/active_model/have_valid_bic.rb
94
+ - lib/bank_account_tools/matchers/active_model/have_valid_iban.rb
95
+ - lib/bank_account_tools/matchers/rspec.rb
96
+ - lib/bank_account_tools/validators/bic_validator.rb
97
+ - lib/bank_account_tools/validators/iban_validator.rb
98
+ - lib/bank_account_tools/version.rb
99
+ - spec/activemodel_spec.rb
100
+ - spec/bic_spec.rb
101
+ - spec/contact_spec.rb
102
+ - spec/iban_spec.rb
103
+ - spec/spec_helper.rb
104
+ homepage: https://github.com/mytrile/bank_account_tools
105
+ licenses:
106
+ - MIT
107
+ metadata: {}
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubyforge_project:
124
+ rubygems_version: 2.6.8
125
+ signing_key:
126
+ specification_version: 4
127
+ summary: Bank account tools for dealing with IBANs/BICs
128
+ test_files:
129
+ - spec/activemodel_spec.rb
130
+ - spec/bic_spec.rb
131
+ - spec/contact_spec.rb
132
+ - spec/iban_spec.rb
133
+ - spec/spec_helper.rb