czech_bank_account 0.1.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c38c48865d97356e32dc0a64570781b4b00025d63107cfa6ac596ef6df012c7
4
- data.tar.gz: 70aba6374a3ed569a7877eab247747b1b40653f8378bda374f145580c191ba5e
3
+ metadata.gz: afa1b5d1a560d14d6796cd23d4dfce263ab899454d361924392961f14b5eb617
4
+ data.tar.gz: 93a1ccf26074b734f8ac125be099e966f01847c41dbc0ed4aa879554e1f23889
5
5
  SHA512:
6
- metadata.gz: c9792b21bd4efc892dbdedf15902cedb9f11d4b6ad14ee8124741c54dc0913901d7a14f26dac1d2d2a15f1fed3ca2bef90be830d630850941bd649350939255c
7
- data.tar.gz: 60583111a448444cb5b4d6126cffb90dea039bbc4131e42a9495e829922ee0a243126b430271232d05b379192c77818216322a104d7aa52b6551e72dcfe242aa
6
+ metadata.gz: b0e473c20496399627495b20cab1e2173581f6b4512e9615786aa0108a7190cf6e6f8f3b834477a381fe8ea3deb5ba1d7b5eeedf6744777acef91cb6df9d7638
7
+ data.tar.gz: e9c4710e01dfdb0e6cc7cd4319262a2657ffbe94d7e4e127ca2ecf47e074a9cce6bdd07bc52e4f1a7b5ee6fb68338ec025a47a1bdeaf5b89a2d821141b6fda6a
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ script: bundle exec rspec
3
+ rvm:
4
+ - 2.6
5
+ - 2.5
6
+ - 2.4
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
- # CzechBankAccount
1
+ # CzechBankAccount [![Build Status](https://www.travis-ci.org/Masa331/czech_bank_account.svg?branch=master)](https://www.travis-ci.org/Masa331/czech_bank_account)
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/czech_bank_account`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Czech bank accounts validations with official Czech National Bank algorithm.
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
6
5
 
7
6
  ## Installation
8
7
 
@@ -20,20 +19,77 @@ Or install it yourself as:
20
19
 
21
20
  $ gem install czech_bank_account
22
21
 
22
+
23
23
  ## Usage
24
24
 
25
- TODO: Write usage instructions here
25
+ Initialize `CzechBankAccount::Account` and call `validate` on it:
26
+ ```
27
+ number = '36-6420840257' # bank account number with optional prefix but without bank code
28
+ bank_code = '0301' # separate bank code
29
+ account = CzechBankAccount::Account.new(number, bank_code)
30
+
31
+ account.validate # returns array with error symbols
32
+ #=> [:prefix_doesnt_pass_checksum, :unknown_bank_code]
33
+ ```
34
+
35
+ Or use a shortcut which returns errors directly:
36
+ ```
37
+ CzechBankAccount.validate('35-6420840257', '9999') # returns array with error symbols
38
+ #=> [:unknown_bank_code]
39
+ ```
40
+
41
+
42
+ ### Possible error symbols
43
+
44
+ 1. `:number_is_empty`
45
+ 2. `:bank_code_is_empty`
46
+ 3. `:number_includes_not_allowed_characters`
47
+ 4. `:number_prefix_is_over_length_limit`
48
+ 5. `:number_is_over_or_under_length_limit`
49
+ 6. `:prefix_doesnt_pass_checksum`
50
+ 7. `:number_doesnt_pass_checksum`
51
+ 8. `:unknown_bank_code`
52
+
53
+
54
+ ### Usage in Rails
26
55
 
27
- ## Development
56
+ Prepare your own custom validation as per [Rails guide](https://guides.rubyonrails.org/active_record_validations.html#performing-custom-validations)
28
57
 
29
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
58
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
59
+ For example ActiveModel::Validator could look like following:
60
+ ```
61
+ # app/validators/czech_bank_account_validator.rb
62
+ class CzechBankAccountValidator < ActiveModel::Validator
63
+ def validate(record)
64
+ errors = CzechBankAccount.validate(record.account_number, record.bank_code)
65
+ errors.each { |e| record.errors.add(:base, e) }
66
+ end
67
+ end
68
+ ```
69
+
70
+ Then in model:
71
+ ```
72
+ class Invoice < ApplicationRecord
73
+ validates_with CzechBankAccountValidator
74
+ end
75
+ ```
76
+
32
77
 
33
78
  ## Contributing
34
79
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/czech_bank_account.
80
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Masa331/czech_bank_account.
81
+
36
82
 
37
83
  ## License
38
84
 
39
85
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
86
+
87
+
88
+ ## Links
89
+
90
+
91
+ ### Official docs for account validation algorithm
92
+
93
+ * http://www.cnb.cz/miranda2/export/sites/www.cnb.cz/cs/platebni_styk/pravni_predpisy/download/vyhl_169_2011.pdf
94
+ * http://www.cnb.cz/miranda2/export/sites/www.cnb.cz/cs/platebni_styk/ucty_kody_bank/download/kody_bank_CR.pdf
95
+ * http://www.cnb.cz/cs/platebni_styk/ucty_kody_bank/index.html
@@ -3,11 +3,11 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
 
4
4
  Gem::Specification.new do |spec|
5
5
  spec.name = 'czech_bank_account'
6
- spec.version = '0.1.1'
6
+ spec.version = '1.0.0'
7
7
  spec.authors = ['Premysl Donat']
8
8
  spec.email = ['pdonat@seznam.cz']
9
9
 
10
- spec.summary = 'Library for working with czech bank account numbers'
10
+ spec.summary = 'Library for validation of czech bank account numbers'
11
11
  spec.description = spec.description
12
12
  spec.homepage = 'https://github.com/Masa331/czech_bank_account'
13
13
  spec.license = 'MIT'
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
19
19
  end
20
20
  spec.require_paths = ['lib']
21
21
 
22
- spec.add_dependency 'activemodel'
23
22
  spec.add_development_dependency 'bundler'
23
+ spec.add_development_dependency 'rspec'
24
+ spec.add_development_dependency 'pry'
24
25
  end
@@ -1,79 +1,10 @@
1
- require 'active_model/validator'
1
+ require 'czech_bank_account/account'
2
2
 
3
3
  module CzechBankAccount
4
- class BankAccountValidator < ActiveModel::Validator
5
- # http://www.cnb.cz/miranda2/export/sites/www.cnb.cz/cs/platebni_styk/pravni_predpisy/download/vyhl_169_2011.pdf
6
- # http://www.cnb.cz/miranda2/export/sites/www.cnb.cz/cs/platebni_styk/ucty_kody_bank/download/kody_bank_CR.pdf
7
- # http://www.cnb.cz/cs/platebni_styk/ucty_kody_bank/index.html
4
+ KNOWN_BANK_CODES = ['0100', '0300', '0600', '0710', '0800', '2010', '2020', '2030', '2060', '2070', '2100', '2200', '2220', '2240', '2250', '2260', '2275', '2600', '2700', '3030', '3050', '3060', '3500', '4000', '4300', '5500', '5800', '6000', '6100', '6200', '6210', '6300', '6700', '6800', '7910', '7940', '7950', '7960', '7970', '7980', '7990', '8030', '8040', '8060', '8090', '8150', '8200', '8215', '8220', '8225', '8230', '8240', '8250', '8260', '8265', '8270', '8280', '8290', '8291', '8292', '8293', '8294']
8
5
 
9
- WEIGHTS = [6, 3, 7, 9, 10, 5, 8, 4, 2, 1]
10
- KNOWN_CODES = ["0100", "0300", "0600", "0710", "0800", "2010", "2020", "2030", "2060", "2070", "2100", "2200", "2220", "2240", "2250", "2260", "2275", "2600", "2700", "3030", "3050", "3060", "3500", "4000", "4300", "5500", "5800", "6000", "6100", "6200", "6210", "6300", "6700", "6800", "7910", "7940", "7950", "7960", "7970", "7980", "7990", "8030", "8040", "8060", "8090", "8150", "8200", "8215", "8220", "8225", "8230", "8240", "8250", "8260", "8265", "8270", "8280", "8290", "8291", "8292", "8293", "8294"]
11
-
12
- def validate(record)
13
- if record.number.blank?
14
- record.errors.add(:base, :number_is_blank)
15
- end
16
-
17
- if record.bank_code.blank?
18
- record.errors.add(:base, :bank_code_is_blank)
19
- end
20
-
21
- validate_allowed_chars(record)
22
- validate_number(record)
23
- validate_bank_code(record)
24
- end
25
-
26
- private
27
-
28
- def validate_allowed_chars(record)
29
- return if record.number.blank?
30
-
31
- unless record.number.match?(/\A[0-9-]*\z/)
32
- record.errors.add :base, :number_includes_not_allowed_characters
33
- end
34
- end
35
-
36
- def validate_number(record)
37
- return if record.number.blank?
38
- return if record.number.count('-') > 1
39
-
40
- if record.number.include? '-'
41
- prefix, number = record.number.split '-'
42
- else
43
- prefix = nil
44
- number = record.number
45
- end
46
-
47
- if prefix && prefix.length > 6
48
- record.errors.add :base, :number_prefix_is_over_length_limit
49
- return
50
- end
51
-
52
- if number && (number.length < 2 || number.length > 10)
53
- record.errors.add :base, :number_is_over_or_under_length_limit
54
- return
55
- end
56
-
57
- if prefix && weighted_sum(prefix) % 11 != 0
58
- record.errors.add :base, :prefix_doesnt_pass_checksum
59
- end
60
-
61
- if number && weighted_sum(number) % 11 != 0
62
- record.errors.add :base, :number_doesnt_pass_checksum
63
- end
64
- end
65
-
66
- def validate_bank_code(record)
67
- unless KNOWN_CODES.include? record.bank_code
68
- record.errors.add :base, :unknown_bank_code
69
- end
70
- end
71
-
72
- def weighted_sum(number)
73
- normalized = number.rjust(10, '0')
74
- chars = normalized.chars.map(&:to_i)
75
- zipped = chars.zip WEIGHTS
76
- zipped.inject(0) { |acc, pair| acc + pair.first * pair.last }
77
- end
6
+ def self.validate(number, bank_code)
7
+ account = Account.new(number, bank_code)
8
+ account.validate
78
9
  end
79
10
  end
@@ -0,0 +1,80 @@
1
+ module CzechBankAccount
2
+ class Account
3
+ WEIGHTS = [6, 3, 7, 9, 10, 5, 8, 4, 2, 1]
4
+
5
+ attr_reader :number, :bank_code
6
+
7
+ def initialize(number = nil, bank_code = nil)
8
+ @number, @bank_code = number.to_s, bank_code.to_s
9
+ end
10
+
11
+ def validate
12
+ errors = []
13
+
14
+ if number.empty?
15
+ errors << :number_is_empty
16
+ end
17
+
18
+ if bank_code.empty?
19
+ errors << :bank_code_is_empty
20
+ end
21
+
22
+ validate_allowed_chars(errors)
23
+ validate_number(errors)
24
+ validate_bank_code(errors)
25
+
26
+ errors
27
+ end
28
+
29
+ private
30
+
31
+ def validate_allowed_chars(errors)
32
+ unless number.match?(/\A[0-9-]*\z/)
33
+ errors << :number_includes_not_allowed_characters
34
+ end
35
+ end
36
+
37
+ def validate_number(errors)
38
+ return if number.empty?
39
+ return if number.count('-') > 1
40
+
41
+ if number.include? '-'
42
+ prefix, base = number.split '-'
43
+ else
44
+ prefix = nil
45
+ base = number
46
+ end
47
+
48
+ if prefix && prefix.length > 6
49
+ errors << :number_prefix_is_over_length_limit
50
+ return
51
+ end
52
+
53
+ if base && (base.length < 2 || base.length > 10)
54
+ errors << :number_is_over_or_under_length_limit
55
+ return
56
+ end
57
+
58
+ if prefix && weighted_sum(prefix) % 11 != 0
59
+ errors << :prefix_doesnt_pass_checksum
60
+ end
61
+
62
+ if number && weighted_sum(base) % 11 != 0
63
+ errors << :number_doesnt_pass_checksum
64
+ end
65
+ end
66
+
67
+ def validate_bank_code(errors)
68
+ unless CzechBankAccount::KNOWN_BANK_CODES.include? bank_code
69
+ errors << :unknown_bank_code
70
+ end
71
+ end
72
+
73
+ def weighted_sum(number)
74
+ normalized = number.rjust(10, '0')
75
+ chars = normalized.chars.map(&:to_i)
76
+ zipped = chars.zip WEIGHTS
77
+ zipped.inject(0) { |acc, pair| acc + pair.first * pair.last }
78
+ end
79
+ end
80
+ end
metadata CHANGED
@@ -1,23 +1,23 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: czech_bank_account
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Premysl Donat
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-28 00:00:00.000000000 Z
11
+ date: 2019-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: activemodel
14
+ name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
- type: :runtime
20
+ type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
@@ -25,7 +25,21 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: bundler
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - ">="
@@ -46,11 +60,13 @@ extensions: []
46
60
  extra_rdoc_files: []
47
61
  files:
48
62
  - ".gitignore"
63
+ - ".travis.yml"
49
64
  - Gemfile
50
65
  - LICENSE.txt
51
66
  - README.md
52
67
  - czech_bank_account.gemspec
53
68
  - lib/czech_bank_account.rb
69
+ - lib/czech_bank_account/account.rb
54
70
  homepage: https://github.com/Masa331/czech_bank_account
55
71
  licenses:
56
72
  - MIT
@@ -70,9 +86,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
86
  - !ruby/object:Gem::Version
71
87
  version: '0'
72
88
  requirements: []
73
- rubyforge_project:
74
- rubygems_version: 2.7.7
89
+ rubygems_version: 3.0.2
75
90
  signing_key:
76
91
  specification_version: 4
77
- summary: Library for working with czech bank account numbers
92
+ summary: Library for validation of czech bank account numbers
78
93
  test_files: []