czech_bank_account 0.1.1 → 1.1.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: 170b31ca98d2c005dd70b7b848684a538ac42e68eaf042c3627818b702b52490
4
+ data.tar.gz: 41fcc889142a3ff8fc5f5028b5d0889b4bfa256bd48760c226f55314cb16fec2
5
5
  SHA512:
6
- metadata.gz: c9792b21bd4efc892dbdedf15902cedb9f11d4b6ad14ee8124741c54dc0913901d7a14f26dac1d2d2a15f1fed3ca2bef90be830d630850941bd649350939255c
7
- data.tar.gz: 60583111a448444cb5b4d6126cffb90dea039bbc4131e42a9495e829922ee0a243126b430271232d05b379192c77818216322a104d7aa52b6551e72dcfe242aa
6
+ metadata.gz: 4cdf29bd08dc75db570205cc5a4f6c1f911be66fc7d4b24f3deb7515407ee0b579804c6801c51134ce7e65f0ab980dc83ecd5c1281b96e4d4ccf8a2d71741cb5
7
+ data.tar.gz: f4b54116c1568d8246117ce2b72cd1c35866a3945b335555c825bc372276359d4d53397d168ff664889d033248cc5a60b0d1028dbc8b792f6457c6912f92b44b
data/.travis.yml ADDED
@@ -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.1.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
@@ -0,0 +1,101 @@
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
+ attr_accessor :prefix
7
+
8
+ def self.parse(account)
9
+ if account.include?('-')
10
+ prefix, base = account.split('-')
11
+ number, bank_code = base.split('/')
12
+ else
13
+ prefix = nil
14
+ number, bank_code = account.split('/')
15
+ end
16
+
17
+ instance = self.new(number, bank_code)
18
+ instance.prefix = prefix if prefix
19
+
20
+ instance
21
+ end
22
+
23
+ def initialize(number = nil, bank_code = nil)
24
+ @number, @bank_code = number.to_s, bank_code.to_s
25
+ end
26
+
27
+ def validate
28
+ errors = []
29
+
30
+ if number.empty?
31
+ errors << :number_is_empty
32
+ end
33
+
34
+ if bank_code.empty?
35
+ errors << :bank_code_is_empty
36
+ end
37
+
38
+ validate_allowed_chars(errors)
39
+ validate_number(errors)
40
+ validate_bank_code(errors)
41
+
42
+ errors
43
+ end
44
+
45
+ def valid?
46
+ errors = validate
47
+ errors.none?
48
+ end
49
+
50
+ private
51
+
52
+ def validate_allowed_chars(errors)
53
+ unless number.match?(/\A[0-9-]*\z/)
54
+ errors << :number_includes_not_allowed_characters
55
+ end
56
+ end
57
+
58
+ def validate_number(errors)
59
+ return if number.empty?
60
+ return if number.count('-') > 1
61
+
62
+ if number.include? '-'
63
+ prefix, base = number.split '-'
64
+ else
65
+ prefix = nil
66
+ base = number
67
+ end
68
+
69
+ if prefix && prefix.length > 6
70
+ errors << :number_prefix_is_over_length_limit
71
+ return
72
+ end
73
+
74
+ if base && (base.length < 2 || base.length > 10)
75
+ errors << :number_is_over_or_under_length_limit
76
+ return
77
+ end
78
+
79
+ if prefix && weighted_sum(prefix) % 11 != 0
80
+ errors << :prefix_doesnt_pass_checksum
81
+ end
82
+
83
+ if number && weighted_sum(base) % 11 != 0
84
+ errors << :number_doesnt_pass_checksum
85
+ end
86
+ end
87
+
88
+ def validate_bank_code(errors)
89
+ unless CzechBankAccount::KNOWN_BANK_CODES.include? bank_code
90
+ errors << :unknown_bank_code
91
+ end
92
+ end
93
+
94
+ def weighted_sum(number)
95
+ normalized = number.rjust(10, '0')
96
+ chars = normalized.chars.map(&:to_i)
97
+ zipped = chars.zip WEIGHTS
98
+ zipped.inject(0) { |acc, pair| acc + pair.first * pair.last }
99
+ end
100
+ end
101
+ 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
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.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Premysl Donat
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-28 00:00:00.000000000 Z
11
+ date: 2023-07-25 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,16 +60,18 @@ 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
57
73
  metadata: {}
58
- post_install_message:
74
+ post_install_message:
59
75
  rdoc_options: []
60
76
  require_paths:
61
77
  - lib
@@ -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
75
- signing_key:
89
+ rubygems_version: 3.3.25
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: []