romanianvalidators 0.1.6 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +13 -0
- data/.ruby-version +1 -1
- data/.travis.yml +4 -1
- data/README.md +71 -26
- data/lib/romanianvalidators.rb +6 -31
- data/lib/romanianvalidators/active_model.rb +32 -0
- data/lib/romanianvalidators/active_model/validations/bic_validator.rb +13 -0
- data/lib/romanianvalidators/active_model/validations/cif_validator.rb +13 -0
- data/lib/romanianvalidators/active_model/validations/cnp_validator.rb +13 -0
- data/lib/romanianvalidators/active_model/validations/iban_validator.rb +13 -0
- data/lib/romanianvalidators/bic.rb +25 -0
- data/lib/romanianvalidators/cif.rb +61 -0
- data/lib/romanianvalidators/cnp.rb +34 -0
- data/lib/romanianvalidators/iban.rb +25 -0
- data/romanianvalidators.gemspec +7 -7
- data/test/test_helper.rb +2 -0
- metadata +14 -8
- data/lib/active_model/validations/bic_validator.rb +0 -25
- data/lib/active_model/validations/cif_validator.rb +0 -30
- data/lib/active_model/validations/cnp_validator.rb +0 -51
- data/lib/active_model/validations/iban_validator.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ad45c5638e6e12b9fd6e9914810400220a0de56
|
4
|
+
data.tar.gz: a8ca1b49f450c18bd755980695c27e1d70abe65c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 68dc85bf25ffa47139957327a360fb62f6dab5d39a837c14f2cee4c7243764a1931a91a940cfd89789cfc31899092d134dc01c42ddbfa55e0c3535485041f218
|
7
|
+
data.tar.gz: 9c16e8cf4a240f82fa6b9da7deff1db68526f36dd050848ccf8bba8faf83cb667d4482a06730634a191cc169083238ec3113f1285d3d9424fba3f08e288fb975
|
data/.rubocop.yml
ADDED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-2.
|
1
|
+
ruby-2.3.0
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,55 +1,100 @@
|
|
1
|
-
# Romanian Validators [![Build Status](https://travis-ci.org/mtarnovan/romanianvalidators.
|
1
|
+
# Romanian Validators [![Build Status](https://travis-ci.org/mtarnovan/romanianvalidators.svg?branch=master)](https://travis-ci.org/mtarnovan/romanianvalidators) [![Gem Version](https://badge.fury.io/rb/romanianvalidators.svg)](https://badge.fury.io/rb/romanianvalidators) [![Code Climate](https://codeclimate.com/github/mtarnovan/romanianvalidators/badges/gpa.svg)](https://codeclimate.com/github/mtarnovan/romanianvalidators)
|
2
2
|
|
3
|
-
|
3
|
+
Validators for:
|
4
4
|
|
5
5
|
* Cod Numeric Personal (CNP)
|
6
6
|
* Cod de identificare fiscală (CIF) and
|
7
7
|
* IBAN (only Romanian format as published by Romanian National Bank).
|
8
8
|
* BIC
|
9
9
|
|
10
|
-
Extracted from [
|
10
|
+
Extracted from [openapi.ro](https://openapi.ro), business APIs for Romanian developers.
|
11
|
+
Includes `ActiveModel` validators.
|
11
12
|
|
12
13
|
## Installation
|
13
14
|
|
14
|
-
|
15
|
+
Include it in your `Gemfile`. If you just want the validation, without `ActiveModel`, use:
|
15
16
|
|
16
|
-
|
17
|
+
gem 'romanianvalidators'
|
17
18
|
|
18
|
-
|
19
|
-
...
|
20
|
-
gem 'romanianvalidations'
|
21
|
-
...
|
19
|
+
If you want ActiveModel integration, use instead:
|
22
20
|
|
23
|
-
|
21
|
+
gem 'romanianvalidators', require: 'romanian_validators/active_model'
|
24
22
|
|
25
|
-
|
23
|
+
Has no other dependency (other than `ActiveModel` if you require it).
|
26
24
|
|
27
|
-
|
28
|
-
|
29
|
-
Tested with MRI 1.8.7, 1.9.3, 2.0.0, REE, Rubinius and JRuby (see `.travis.yml`)
|
25
|
+
Tested with MRI 1.9.3, 2.0, 2.1, 2.3, REE, Rubinius and JRuby (see `.travis.yml`)
|
30
26
|
|
31
27
|
## Usage
|
32
28
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
29
|
+
Without `ActiveModel`, just call the `valid?` method on the corresponding module
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
> RomanianValidators::Cif.valid?(13548146)
|
33
|
+
=> true
|
34
|
+
> RomanianValidators::Iban.valid?(123)
|
35
|
+
=> false
|
36
|
+
```
|
38
37
|
|
39
|
-
|
38
|
+
With `ActiveModel`, include it in your model
|
40
39
|
|
40
|
+
```ruby
|
41
|
+
include RomanianValidators::ActiveModel::Validations
|
42
|
+
```
|
43
|
+
|
44
|
+
then use like this:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
validates :my_attribute, cif: true
|
48
|
+
```
|
49
|
+
|
50
|
+
Example:
|
41
51
|
```ruby
|
42
52
|
class User
|
43
|
-
|
44
|
-
|
53
|
+
include ActiveModel::Model
|
54
|
+
include RomanianValidators::ActiveModel::Validations
|
55
|
+
attr_accessor :cnp, :company_cif
|
56
|
+
|
57
|
+
validates :cnp, cnp: { message: 'This is not a valid CNP' }
|
58
|
+
validates :company_cif, cif: true
|
45
59
|
end
|
60
|
+
|
61
|
+
> u = User.new(cnp: 123, company_cif: 123)
|
62
|
+
=> #<User:0x007fbf7f959b38 @cnp=123, @company_cif=123>
|
63
|
+
> u.valid?
|
64
|
+
=> false
|
65
|
+
> u.errors
|
66
|
+
=> #<ActiveModel::Errors:0x007fbf80958548 @base=#<User:0x007fbf7f959b38 @cnp=123, @company_cif=123, @validation_context=nil, @errors=#<ActiveModel::Errors:0x007fbf80958548 ...>>, @messages={:cnp=>["This is not a valid CNP"], :company_cif=>["is invalid"]}, @details={:cnp=>[{:error=>"This is not a valid CNP"}], :company_cif=>[{:error=>:invalid}]}>
|
67
|
+
```
|
68
|
+
|
69
|
+
For CIFs, a (lazy) enumerator is provided. This enumerator is significantly
|
70
|
+
more efficient than iterating over a range of numbers and filtering valid CIFs, because
|
71
|
+
it generates the control digit from `cif % 10` directly.
|
72
|
+
|
73
|
+
Example:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
> RomanianValidators::Cif.enumerator(1).take(10).to_a
|
77
|
+
=> [19, 27, 35, 43, 51, 60, 78, 86, 94, 108]
|
78
|
+
> RomanianValidators::Cif.enumerator(1_000_000, :down).take(10).to_a
|
79
|
+
=> [999993, 999985, 999977, 999969, 999950, 999942, 999934, 999926, 999918, 999900]
|
80
|
+
```
|
81
|
+
|
82
|
+
### Upgrading
|
83
|
+
|
84
|
+
If upgrading from `0.1.x`, note that the `ActiveModel` validations are now in a separate module so you need to add
|
85
|
+
`include RomanianValidators::ActiveModel::Validations` in your models. Additionaly you need to add a `require` in your Gemfile (again, only if using `ActiveModel`):
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
gem 'romanianvalidators', require: 'romanianvalidators/active_model'
|
46
89
|
```
|
47
90
|
|
48
|
-
###
|
91
|
+
### Changelog
|
49
92
|
|
50
|
-
|
51
|
-
|
93
|
+
#### 0.2.0
|
94
|
+
* moved validations from `ActiveModel::Validations` to `RomanianValidators::ActiveModel::Validations`.
|
95
|
+
This module must be manually required in models.
|
96
|
+
* added a lazy enumerator that generates valid CIFs: `RomanianValidators::Cif.enumerator(start, direction = :up)`
|
52
97
|
|
53
98
|
### Copyright
|
54
99
|
|
55
|
-
Copyright (c) 2007-
|
100
|
+
Copyright (c) 2007-2018 Mihai Târnovan. MIT LICENSE. See LICENSE for details.
|
data/lib/romanianvalidators.rb
CHANGED
@@ -1,34 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
def self.romanianvalidators
|
6
|
-
%w(cif cnp iban bic)
|
7
|
-
end
|
8
|
-
|
9
|
-
module EmptyBlankEachValidator
|
10
|
-
def validate_each(record, attribute, value)
|
11
|
-
allow_blank = options.fetch(:allow_blank, false)
|
12
|
-
allow_nil = options.fetch(:allow_nil, false)
|
13
|
-
message = options.fetch(:message, :invalid)
|
14
|
-
record.errors.add_on_empty(attribute) && return if value.nil? && !allow_nil
|
15
|
-
record.errors.add_on_blank(attribute) && return if value.blank? && !allow_blank
|
16
|
-
record.errors.add(attribute, message) && return unless valid?(value)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
romanianvalidators.each do |validator_name|
|
21
|
-
require "active_model/validations/#{validator_name}_validator"
|
22
|
-
end
|
1
|
+
module RomanianValidators
|
2
|
+
def self.available_validators
|
3
|
+
%w(cif cnp iban bic)
|
4
|
+
end
|
23
5
|
|
24
|
-
|
25
|
-
|
26
|
-
define_method('validates_' + validator) do |*fields|
|
27
|
-
options ||= (fields.delete(fields.find { |f| f.is_a? Hash })) || true
|
28
|
-
args = fields.push(validator => options)
|
29
|
-
validates(*args)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
6
|
+
available_validators.each do |validator_name|
|
7
|
+
require "romanianvalidators/#{validator_name}"
|
33
8
|
end
|
34
9
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'romanianvalidators'
|
2
|
+
require 'active_model'
|
3
|
+
module RomanianValidators
|
4
|
+
module ActiveModel
|
5
|
+
module Validations
|
6
|
+
module EmptyBlankEachValidator
|
7
|
+
def validate_each(record, attribute, value)
|
8
|
+
allow_blank = options.fetch(:allow_blank, false)
|
9
|
+
allow_nil = options.fetch(:allow_nil, false)
|
10
|
+
message = options.fetch(:message, :invalid)
|
11
|
+
record.errors.add_on_empty(attribute) && return if value.nil? && !allow_nil
|
12
|
+
record.errors.add_on_blank(attribute) && return if value.blank? && !allow_blank
|
13
|
+
record.errors.add(attribute, message) && return unless valid?(value)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
RomanianValidators.available_validators.each do |validator_name|
|
18
|
+
require "romanianvalidators/active_model/validations/#{validator_name}_validator"
|
19
|
+
end
|
20
|
+
|
21
|
+
module HelperMethods
|
22
|
+
RomanianValidators.available_validators.each do |validator|
|
23
|
+
define_method('validates_' + validator) do |*fields|
|
24
|
+
options ||= fields.delete(fields.find { |f| f.is_a? Hash }) || true
|
25
|
+
args = fields.push(validator => options)
|
26
|
+
validates(*args)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module RomanianValidators
|
2
|
+
module ActiveModel
|
3
|
+
module Validations
|
4
|
+
class BicValidator < ::ActiveModel::EachValidator
|
5
|
+
include ActiveModel::Validations::EmptyBlankEachValidator
|
6
|
+
|
7
|
+
def valid?(bic)
|
8
|
+
RomanianValidators::Bic.valid?(bic)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module RomanianValidators
|
2
|
+
module ActiveModel
|
3
|
+
module Validations
|
4
|
+
class CifValidator < ::ActiveModel::EachValidator
|
5
|
+
include ActiveModel::Validations::EmptyBlankEachValidator
|
6
|
+
|
7
|
+
def valid?(cif)
|
8
|
+
RomanianValidators::Cif.valid?(cif)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module RomanianValidators
|
2
|
+
module ActiveModel
|
3
|
+
module Validations
|
4
|
+
class CnpValidator < ::ActiveModel::EachValidator
|
5
|
+
include ActiveModel::Validations::EmptyBlankEachValidator
|
6
|
+
|
7
|
+
def valid?(cnp)
|
8
|
+
RomanianValidators::Cnp.valid?(cnp)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module RomanianValidators
|
2
|
+
module ActiveModel
|
3
|
+
module Validations
|
4
|
+
class IbanValidator < ::ActiveModel::EachValidator
|
5
|
+
include ActiveModel::Validations::EmptyBlankEachValidator
|
6
|
+
|
7
|
+
def valid?(iban)
|
8
|
+
RomanianValidators::Iban.valid?(iban)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module RomanianValidators
|
2
|
+
module Bic
|
3
|
+
COUNTRY_CODES =
|
4
|
+
%w(AF AL DZ AS AD AO AI AG AR AM AW AU AT AZ BS BH BD BB BY BE BZ BJ BM
|
5
|
+
BT BO BA BW BR BN BG BF BI KH CM CA CV KY CF TD CL CN CO KM CG CD CK CR
|
6
|
+
CI HR CU CY CZ DK DJ DM DO EC EG SV GQ ER EE ET FK FO FJ FI FR GF PF GA
|
7
|
+
GM GE DE GH GI GR GL GD GP GU GT GN GW GY HT VA HN HK HU IS IN ID IR IQ
|
8
|
+
IE IL IT JM JP JO KZ KE KI KP KR KW KG LA LV LB LS LR LY LI LT LU MO MK
|
9
|
+
MG MW MY MV ML MT MH MQ MR MU MX FM MD MC MN MS MA MZ MM NA NR NP NL AN
|
10
|
+
NC NZ NI NE NG NU NF MP NO OM PK PW PA PG PY PE PH PN PL PT PR QA RE RO
|
11
|
+
RU RW SH KN LC PM VC WS SM ST SA SN SC SL SG SK SI SB SO ZA ES LK SD SR
|
12
|
+
SJ SZ SE CH SY TW TJ TZ TH TG TK TO TT TN TR TM TC TV UG UA AE GB US UY
|
13
|
+
UZ VU VE VN VG VI WF EH YE ZM ZW).freeze
|
14
|
+
|
15
|
+
module_function
|
16
|
+
|
17
|
+
# This is only a basic validation of a BIC
|
18
|
+
# http://www.swift.com/biconline/index.cfm?fuseaction=display_aboutbic
|
19
|
+
def valid?(bic)
|
20
|
+
return false unless bic.size == 8 || bic.size == 11 # length 8 or 11
|
21
|
+
return false unless (bic[0..3] =~ /[^A-Z]/).nil? # first 4 must be letters only
|
22
|
+
COUNTRY_CODES.include?(bic[4..5])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module RomanianValidators
|
2
|
+
module Cif
|
3
|
+
TEST_KEY = '753217532'.to_s.chars.map(&:to_i).reverse.freeze
|
4
|
+
FIRST_CIF = 19 # used to break iteration when direction is :down
|
5
|
+
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def valid?(cif)
|
9
|
+
return false unless well_formed?(cif)
|
10
|
+
control, sum = control_sum(cif, TEST_KEY)
|
11
|
+
sum * 10 % 11 % 10 == control
|
12
|
+
end
|
13
|
+
|
14
|
+
def well_formed?(cif)
|
15
|
+
cif.present? && (2..10).cover?(cif.size) && (cif =~ /[^0-9]/).nil?
|
16
|
+
end
|
17
|
+
|
18
|
+
def next_valid_cif(cif)
|
19
|
+
control, sum = control_sum(cif, TEST_KEY)
|
20
|
+
last_digit_of_next_cif = sum * 10 % 11 % 10
|
21
|
+
|
22
|
+
if last_digit_of_next_cif < control
|
23
|
+
next_valid_cif(((cif / 10) + 1) * 10)
|
24
|
+
else
|
25
|
+
replace_last_digit(cif, last_digit_of_next_cif)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def prev_valid_cif(cif)
|
30
|
+
control, sum = control_sum(cif, TEST_KEY)
|
31
|
+
last_digit_of_next_cif = sum * 10 % 11 % 10
|
32
|
+
|
33
|
+
if last_digit_of_next_cif > control
|
34
|
+
next_valid_cif(((cif / 10) - 1) * 10)
|
35
|
+
else
|
36
|
+
replace_last_digit(cif, last_digit_of_next_cif)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def enumerator(start, direction = :up)
|
41
|
+
Enumerator.new do |yielder|
|
42
|
+
memo = direction == :up ? next_valid_cif(start + 1) : prev_valid_cif(start - 1)
|
43
|
+
loop do
|
44
|
+
yielder << memo
|
45
|
+
memo = direction == :up ? next_valid_cif(memo + 1) : prev_valid_cif(memo - 1)
|
46
|
+
break if memo < FIRST_CIF
|
47
|
+
end
|
48
|
+
end.lazy
|
49
|
+
end
|
50
|
+
|
51
|
+
def replace_last_digit(number, digit)
|
52
|
+
((number / 10).to_s + digit.to_s).to_i
|
53
|
+
end
|
54
|
+
|
55
|
+
def control_sum(n, test_key)
|
56
|
+
control, *rest_digits = n.to_s.chars.map(&:to_i).reverse
|
57
|
+
sum = rest_digits.zip(test_key).map { |a, b| a * b }.reduce(0, &:+)
|
58
|
+
[control, sum]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RomanianValidators
|
2
|
+
module Cnp
|
3
|
+
TEST_KEY = '279146358279'.each_char.map(&:to_i)
|
4
|
+
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def valid?(cnp)
|
8
|
+
return false unless well_formed?(cnp) && valid_birthdate?(cnp)
|
9
|
+
control = (0..11).reduce(0) { |acc, elem| acc + TEST_KEY[elem] * cnp[elem].chr.to_i } % 11
|
10
|
+
control = 1 if control == 10
|
11
|
+
control == cnp[12].chr.to_i
|
12
|
+
end
|
13
|
+
|
14
|
+
def well_formed?(cnp)
|
15
|
+
(cnp =~ /[^0-9]/).nil? && cnp.size == 13
|
16
|
+
end
|
17
|
+
|
18
|
+
def valid_birthdate?(cnp)
|
19
|
+
year_code = cnp[0].chr.to_i
|
20
|
+
year =
|
21
|
+
case year_code
|
22
|
+
when 1..2 then '19'
|
23
|
+
when 3..4 then '18'
|
24
|
+
when 5..6 then '20'
|
25
|
+
when 9 then '19' # oare se sare peste un an bisect intre 1800-2099 ?
|
26
|
+
else return false
|
27
|
+
end
|
28
|
+
year = (year + cnp[1..2]).to_i
|
29
|
+
Date.valid_civil?(year, cnp[3..4].to_i, cnp[5..6].to_i) ? true : false
|
30
|
+
rescue ArgumentError
|
31
|
+
return false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module RomanianValidators
|
2
|
+
module Iban
|
3
|
+
# use ord for ruby >= 1.9
|
4
|
+
USE_ORD = ''.respond_to?(:ord)
|
5
|
+
|
6
|
+
module_function
|
7
|
+
|
8
|
+
# Descrierea algoritmului:
|
9
|
+
# http://www.bnr.ro/files/d/Legislatie/EN/Reg_IBAN.pdf
|
10
|
+
def valid?(iban)
|
11
|
+
return false if iban.size < 3
|
12
|
+
transpose((iban.slice(4, iban.size) + iban[0..3])).to_i % 97 == 1
|
13
|
+
rescue
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
# replace letters according to algorithm
|
18
|
+
# algorithm conversion maps chars to ASCII value - 55
|
19
|
+
def transpose(iban)
|
20
|
+
iban.upcase.gsub(/[A-Z]/) do |s|
|
21
|
+
USE_ORD ? (s[0].ord - 55).to_s : (s[0].to_i - 55).to_s
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/romanianvalidators.gemspec
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
Gem::Specification.new do |s|
|
3
3
|
s.name = 'romanianvalidators'
|
4
|
-
s.version = '0.
|
4
|
+
s.version = '0.2.0'
|
5
5
|
s.authors = ['Mihai Târnovan']
|
6
6
|
s.email = ['mihai.tarnovan@cubus.ro']
|
7
7
|
s.homepage = 'http://github.com/mtarnovan/romanianvalidators'
|
8
8
|
s.license = 'MIT'
|
9
|
-
s.summary =
|
10
|
-
s.description =
|
9
|
+
s.summary = 'Collection of validations for Cod Numeric Personal (CNP), Cod de identificare fiscală (CIF) and IBAN (only Romanian format, as published by Romanian National Bank)'
|
10
|
+
s.description = s.summary
|
11
11
|
|
12
12
|
s.add_development_dependency 'bundler'
|
13
13
|
s.add_development_dependency 'minitest'
|
14
|
-
s.add_dependency 'rake'
|
15
|
-
s.add_dependency 'activemodel'
|
14
|
+
s.add_dependency 'rake', '>= 0.8.7'
|
15
|
+
s.add_dependency 'activemodel', '>= 3.0.0'
|
16
16
|
|
17
17
|
s.files = `git ls-files`.split("\n")
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
-
s.rubyforge_project =
|
20
|
-
end
|
19
|
+
s.rubyforge_project = 'romanianvalidators'
|
20
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -11,12 +11,14 @@ require 'minitest/autorun'
|
|
11
11
|
$-w = old_w
|
12
12
|
|
13
13
|
require 'romanianvalidators'
|
14
|
+
require 'romanianvalidators/active_model'
|
14
15
|
require 'active_support/core_ext/array/wrap'
|
15
16
|
|
16
17
|
I18n.enforce_available_locales = true
|
17
18
|
|
18
19
|
class TestRecord
|
19
20
|
include ActiveModel::Validations
|
21
|
+
include RomanianValidators::ActiveModel::Validations
|
20
22
|
attr_accessor :cnp, :bic, :cif, :iban
|
21
23
|
|
22
24
|
def initialize(attrs = {})
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: romanianvalidators
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mihai Târnovan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-04-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -68,7 +68,7 @@ dependencies:
|
|
68
68
|
version: 3.0.0
|
69
69
|
description: Collection of validations for Cod Numeric Personal (CNP), Cod de identificare
|
70
70
|
fiscală (CIF) and IBAN (only Romanian format, as published by Romanian National
|
71
|
-
Bank)
|
71
|
+
Bank)
|
72
72
|
email:
|
73
73
|
- mihai.tarnovan@cubus.ro
|
74
74
|
executables: []
|
@@ -76,6 +76,7 @@ extensions: []
|
|
76
76
|
extra_rdoc_files: []
|
77
77
|
files:
|
78
78
|
- ".gitignore"
|
79
|
+
- ".rubocop.yml"
|
79
80
|
- ".ruby-gemset"
|
80
81
|
- ".ruby-version"
|
81
82
|
- ".travis.yml"
|
@@ -84,11 +85,16 @@ files:
|
|
84
85
|
- LICENSE
|
85
86
|
- README.md
|
86
87
|
- Rakefile
|
87
|
-
- lib/active_model/validations/bic_validator.rb
|
88
|
-
- lib/active_model/validations/cif_validator.rb
|
89
|
-
- lib/active_model/validations/cnp_validator.rb
|
90
|
-
- lib/active_model/validations/iban_validator.rb
|
91
88
|
- lib/romanianvalidators.rb
|
89
|
+
- lib/romanianvalidators/active_model.rb
|
90
|
+
- lib/romanianvalidators/active_model/validations/bic_validator.rb
|
91
|
+
- lib/romanianvalidators/active_model/validations/cif_validator.rb
|
92
|
+
- lib/romanianvalidators/active_model/validations/cnp_validator.rb
|
93
|
+
- lib/romanianvalidators/active_model/validations/iban_validator.rb
|
94
|
+
- lib/romanianvalidators/bic.rb
|
95
|
+
- lib/romanianvalidators/cif.rb
|
96
|
+
- lib/romanianvalidators/cnp.rb
|
97
|
+
- lib/romanianvalidators/iban.rb
|
92
98
|
- romanianvalidators.gemspec
|
93
99
|
- test/data/valid_bics.txt
|
94
100
|
- test/data/valid_cifs.txt
|
@@ -119,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
119
125
|
version: '0'
|
120
126
|
requirements: []
|
121
127
|
rubyforge_project: romanianvalidators
|
122
|
-
rubygems_version: 2.
|
128
|
+
rubygems_version: 2.6.7
|
123
129
|
signing_key:
|
124
130
|
specification_version: 4
|
125
131
|
summary: Collection of validations for Cod Numeric Personal (CNP), Cod de identificare
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module ActiveModel
|
2
|
-
module Validations
|
3
|
-
class BicValidator < EachValidator
|
4
|
-
include ActiveModel::Validations::EmptyBlankEachValidator
|
5
|
-
COUNTRY_CODES =
|
6
|
-
%w(AF AL DZ AS AD AO AI AG AR AM AW AU AT AZ BS BH BD BB BY BE BZ BJ BM
|
7
|
-
BT BO BA BW BR BN BG BF BI KH CM CA CV KY CF TD CL CN CO KM CG CD CK CR
|
8
|
-
CI HR CU CY CZ DK DJ DM DO EC EG SV GQ ER EE ET FK FO FJ FI FR GF PF GA
|
9
|
-
GM GE DE GH GI GR GL GD GP GU GT GN GW GY HT VA HN HK HU IS IN ID IR IQ
|
10
|
-
IE IL IT JM JP JO KZ KE KI KP KR KW KG LA LV LB LS LR LY LI LT LU MO MK
|
11
|
-
MG MW MY MV ML MT MH MQ MR MU MX FM MD MC MN MS MA MZ MM NA NR NP NL AN
|
12
|
-
NC NZ NI NE NG NU NF MP NO OM PK PW PA PG PY PE PH PN PL PT PR QA RE RO
|
13
|
-
RU RW SH KN LC PM VC WS SM ST SA SN SC SL SG SK SI SB SO ZA ES LK SD SR
|
14
|
-
SJ SZ SE CH SY TW TJ TZ TH TG TK TO TT TN TR TM TC TV UG UA AE GB US UY
|
15
|
-
UZ VU VE VN VG VI WF EH YE ZM ZW)
|
16
|
-
# This is only a basic validation of a BIC
|
17
|
-
# http://www.swift.com/biconline/index.cfm?fuseaction=display_aboutbic
|
18
|
-
def valid?(bic)
|
19
|
-
return false unless bic.size == 8 || bic.size == 11 # length 8 or 11
|
20
|
-
return false unless (bic[0..3] =~ (/[^A-Z]/)).nil? # first 4 must be letters only
|
21
|
-
COUNTRY_CODES.include?(bic[4..5])
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module ActiveModel
|
2
|
-
module Validations
|
3
|
-
class CifValidator < EachValidator
|
4
|
-
|
5
|
-
# reversed test key (753217532)
|
6
|
-
TEST_KEY = '235712357'.freeze
|
7
|
-
|
8
|
-
include ActiveModel::Validations::EmptyBlankEachValidator
|
9
|
-
|
10
|
-
# Algoritmul de validare al unui cod CUI
|
11
|
-
# Pas preliminar: Se testeaza daca codul respecta formatul unui cod CUI. Adica lungimea maxima sa fie de 10 cifre si sa contina doar caractere numerice.
|
12
|
-
# Pas 1: Se foloseste cheia de testare "753217532". Se inverseaza ordinea cifrelor codului CUI precum si a cheii de testare.
|
13
|
-
# Pas 2: Se ignora prima cifra din codul CUI inversat (aceasta este cifra de control) si se inmulteste fiecare cifra cu cifra corespunzatoare din cheia de testare inversata.
|
14
|
-
# Pas 3: Se aduna toate produsele obtinute. Suma rezultata se inmulteste cu 10 si apoi se afla restul impartirii la 11.
|
15
|
-
# Pas 4: Pentru un CUI valid cifra obtinuta, in urma operatiei MODULO 11, va trebui sa corespunda cu cifra de control a codului CUI initial .
|
16
|
-
def valid?(cif)
|
17
|
-
return false unless well_formed?(cif)
|
18
|
-
rc = cif.reverse.freeze
|
19
|
-
(1..(cif.size - 1)).inject(0) {|sum, n| sum += TEST_KEY[n-1].chr.to_i * rc[n].chr.to_i} * 10 % 11 % 10 == rc[0].chr.to_i
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def well_formed?(cif)
|
25
|
-
cif.present? && (2..10).include?(cif.size) && (cif=~(/[^0-9]/)).nil?
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
module ActiveModel
|
2
|
-
module Validations
|
3
|
-
class CnpValidator < EachValidator
|
4
|
-
TEST_KEY = '279146358279'.each_char.map(&:to_i)
|
5
|
-
|
6
|
-
include ActiveModel::Validations::EmptyBlankEachValidator
|
7
|
-
|
8
|
-
# Algoritm de validare CNP
|
9
|
-
# Pas preliminar: Se testeaza daca codul respecta formatul unui cod CNP.
|
10
|
-
# Adica prima cifra sa fie cuprinsa in intervalul 1 - 6 sau sa fie 9 pentru straini.
|
11
|
-
# Urmatoarele sase cifre trebuie sa constituie o data calendaristica valida in formatul AALLZZ.
|
12
|
-
#
|
13
|
-
# Pas 1:
|
14
|
-
# Se foloseste cheia de testare "279146358279". Primele douasprezece cifre se inmultesc pe rand de la
|
15
|
-
# stanga spre dreapta cu cifra corespunzatoare din cheia de testare.
|
16
|
-
#
|
17
|
-
# Pas 2: Cele douasprezece produse obtinute se aduna si suma obtinuta se imparte la 11.
|
18
|
-
# * Daca restul impartirii la 11 este mai mic ca 10, atunci acesta va reprezenta cifra de control.
|
19
|
-
# * Daca restul impartirii este 10 atunci cifra de control este 1.
|
20
|
-
# Restul impartirii reprezinta cifra de control. Pentru un CNP valid acest rest va trebui
|
21
|
-
# sa coincida cu cifra de pe pozitia treisprezece din CNP-ul initial.
|
22
|
-
def valid?(cnp)
|
23
|
-
return false unless well_formed?(cnp) && valid_birthdate?(cnp)
|
24
|
-
control = (0..11).reduce(0) { |a, e| a + TEST_KEY[e] * cnp[e].chr.to_i } % 11
|
25
|
-
control = 1 if control == 10
|
26
|
-
control == cnp[12].chr.to_i
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def well_formed?(cnp)
|
32
|
-
(cnp =~ (/[^0-9]/)).nil? && cnp.size == 13
|
33
|
-
end
|
34
|
-
|
35
|
-
def valid_birthdate?(cnp)
|
36
|
-
year_code = cnp[0].chr.to_i
|
37
|
-
year = case year_code
|
38
|
-
when 1..2 then '19'
|
39
|
-
when 3..4 then '18'
|
40
|
-
when 5..6 then '20'
|
41
|
-
when 9 then '19' # oare se sare peste un an bisect intre 1800-2099 ?
|
42
|
-
else return false
|
43
|
-
end
|
44
|
-
year = (year + cnp[1..2]).to_i
|
45
|
-
Date.valid_civil?(year, cnp[3..4].to_i, cnp[5..6].to_i) ? true : false
|
46
|
-
rescue ArgumentError
|
47
|
-
return false
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module ActiveModel
|
2
|
-
module Validations
|
3
|
-
class IbanValidator < EachValidator
|
4
|
-
|
5
|
-
# use ord for ruby >= 1.9
|
6
|
-
USE_ORD = ''.respond_to?(:ord)
|
7
|
-
|
8
|
-
include ActiveModel::Validations::EmptyBlankEachValidator
|
9
|
-
|
10
|
-
# Descrierea algoritmului:
|
11
|
-
# http://www.bnr.ro/files/d/Legislatie/EN/Reg_IBAN.pdf
|
12
|
-
def valid?(iban)
|
13
|
-
return false if iban.size < 3
|
14
|
-
transpose((iban.slice(4, iban.size) + iban[0..3])).to_i % 97 == 1
|
15
|
-
rescue
|
16
|
-
false
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
# replace letters according to algorithm
|
22
|
-
# algorithm conversion maps chars to ASCII value - 55
|
23
|
-
def transpose(iban)
|
24
|
-
iban.upcase.gsub(/[A-Z]/) do |s|
|
25
|
-
USE_ORD ? (s[0].ord - 55).to_s : (s[0].to_i - 55).to_s
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|