activepesel 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -18
- data/.rspec +1 -0
- data/.rubocop.yml +176 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +8 -2
- data/MIT-LICENSE +1 -1
- data/README.md +30 -18
- data/Rakefile +1 -38
- data/activepesel.gemspec +15 -15
- data/lib/active_model/validations/pesel_validator.rb +5 -3
- data/lib/activepesel/personal_data.rb +23 -18
- data/lib/activepesel/pesel.rb +22 -19
- data/lib/activepesel/pesel_attr.rb +5 -8
- data/lib/activepesel/pesel_generator.rb +47 -28
- data/lib/activepesel/version.rb +3 -1
- data/lib/activepesel.rb +8 -1
- data/media/id.jpg +0 -0
- data/spec/activepesel/pesel_attr_spec.rb +28 -0
- data/spec/activepesel/pesel_generator_spec.rb +70 -0
- data/spec/activepesel/pesel_spec.rb +98 -0
- data/spec/spec_helper.rb +23 -0
- metadata +27 -135
- data/.rvmrc +0 -1
- data/Gemfile.lock +0 -94
- data/lib/tasks/activepesel_tasks.rake +0 -4
- data/test/activepesel_test.rb +0 -7
- data/test/dummy/README.rdoc +0 -261
- data/test/dummy/Rakefile +0 -7
- data/test/dummy/app/assets/javascripts/application.js +0 -13
- data/test/dummy/app/assets/stylesheets/application.css +0 -13
- data/test/dummy/app/controllers/application_controller.rb +0 -3
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/mailers/.gitkeep +0 -0
- data/test/dummy/app/models/#user.rb# +0 -9
- data/test/dummy/app/models/.gitkeep +0 -0
- data/test/dummy/app/models/user.rb +0 -9
- data/test/dummy/app/views/layouts/application.html.erb +0 -14
- data/test/dummy/config/application.rb +0 -65
- data/test/dummy/config/boot.rb +0 -10
- data/test/dummy/config/database.yml +0 -25
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -37
- data/test/dummy/config/environments/production.rb +0 -67
- data/test/dummy/config/environments/test.rb +0 -37
- data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy/config/initializers/inflections.rb +0 -15
- data/test/dummy/config/initializers/mime_types.rb +0 -5
- data/test/dummy/config/initializers/secret_token.rb +0 -7
- data/test/dummy/config/initializers/session_store.rb +0 -8
- data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/test/dummy/config/locales/en.yml +0 -5
- data/test/dummy/config/routes.rb +0 -58
- data/test/dummy/config.ru +0 -4
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20121114223156_create_users.rb +0 -10
- data/test/dummy/db/schema.rb +0 -23
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/lib/assets/.gitkeep +0 -0
- data/test/dummy/log/.gitkeep +0 -0
- data/test/dummy/log/development.log +0 -96
- data/test/dummy/log/test.log +0 -12541
- data/test/dummy/public/404.html +0 -26
- data/test/dummy/public/422.html +0 -26
- data/test/dummy/public/500.html +0 -25
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +0 -6
- data/test/dummy/test/fixtures/users.yml +0 -37
- data/test/dummy/test/unit/user_test.rb +0 -7
- data/test/pesel_attr_test.rb +0 -62
- data/test/pesel_generator_test.rb +0 -46
- data/test/pesel_test.rb +0 -66
- data/test/pesel_validator_test.rb +0 -29
- data/test/test_helper.rb +0 -15
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: '02738e059a1bbedb639b461ea980a2b1b6d4501e84589ef51725f8b7e0625945'
|
4
|
+
data.tar.gz: f8d7d1639e109ffb5c41014ae7aeca384cc0b80b0e0c8abc1f3e78b73987ee1e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d26e1884df6aec08ca3ab40d8d9e6a1da0029704a75e432368ac4986c527977be243a46835185f3a7f5aea0a65813ad584ed32f1d52c12aaa01b16c28c540c42
|
7
|
+
data.tar.gz: 2edd6225b3310920707b3bcba8a43443bed39081e3ab83dbbfdad0abba2e745e5397f6967eb17d1298cca111fe9934463d23d88d150dee5e5b18e64490a23b80
|
data/.gitignore
CHANGED
@@ -1,21 +1,15 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# bundler
|
2
|
+
.bundle
|
3
|
+
Gemfile.lock
|
4
|
+
Gemfile.local
|
5
|
+
vendor/
|
3
6
|
pkg/
|
4
|
-
test/dummy/db/*.sqlite3
|
5
|
-
test/dummy/log/*.log
|
6
|
-
test/dummy/tmp/
|
7
|
-
test/dummy/.sass-cache
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
.#*
|
17
|
-
\#*\#
|
18
|
-
*.log
|
8
|
+
# rbenv
|
9
|
+
.ruby-version
|
10
|
+
|
11
|
+
# byebug
|
12
|
+
.byebug_history
|
13
|
+
|
14
|
+
# For MacOS:
|
19
15
|
.DS_Store
|
20
|
-
org-clock-save.el
|
21
|
-
emacs-config.el
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.7.5
|
3
|
+
NewCops: enable
|
4
|
+
Exclude:
|
5
|
+
- 'vendor/**/*'
|
6
|
+
- 'test/fixtures/**/*'
|
7
|
+
- 'db/**/*'
|
8
|
+
- 'bin/**/*'
|
9
|
+
- 'log/**/*'
|
10
|
+
- 'tmp/**/*'
|
11
|
+
- 'app/views/**/*'
|
12
|
+
- 'config/environments/*'
|
13
|
+
- 'node_modules/**/*'
|
14
|
+
|
15
|
+
# Metrics Cops
|
16
|
+
|
17
|
+
Metrics/ClassLength:
|
18
|
+
Description: 'Avoid classes longer than 100 lines of code.'
|
19
|
+
Max: 100
|
20
|
+
Enabled: true
|
21
|
+
|
22
|
+
Metrics/ModuleLength:
|
23
|
+
Description: 'Avoid modules longer than 100 lines of code.'
|
24
|
+
Max: 100
|
25
|
+
Enabled: true
|
26
|
+
|
27
|
+
Metrics/ParameterLists:
|
28
|
+
Description: 'Pass no more than four parameters into a method.'
|
29
|
+
Max: 4
|
30
|
+
Enabled: true
|
31
|
+
|
32
|
+
Metrics/MethodLength:
|
33
|
+
Description: 'Avoid methods longer than 10 lines of code.'
|
34
|
+
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#short-methods'
|
35
|
+
Max: 10
|
36
|
+
Enabled: true
|
37
|
+
|
38
|
+
Metrics/BlockLength:
|
39
|
+
CountComments: false
|
40
|
+
Max: 10
|
41
|
+
Exclude:
|
42
|
+
- 'spec/**/*'
|
43
|
+
- '*.gemspec'
|
44
|
+
AllowedMethods:
|
45
|
+
- context
|
46
|
+
- describe
|
47
|
+
- it
|
48
|
+
- shared_examples
|
49
|
+
- shared_examples_for
|
50
|
+
- namespace
|
51
|
+
- draw
|
52
|
+
- configure
|
53
|
+
- group
|
54
|
+
|
55
|
+
# Style Cops
|
56
|
+
|
57
|
+
Style/BlockDelimiters:
|
58
|
+
Exclude:
|
59
|
+
- 'spec/**/*'
|
60
|
+
|
61
|
+
Style/SymbolArray:
|
62
|
+
Enabled: false
|
63
|
+
|
64
|
+
Style/ClassAndModuleChildren:
|
65
|
+
Description: 'Checks style of children classes and modules.'
|
66
|
+
Enabled: false
|
67
|
+
EnforcedStyle: nested
|
68
|
+
|
69
|
+
Style/CollectionMethods:
|
70
|
+
Enabled: true
|
71
|
+
PreferredMethods:
|
72
|
+
find: detect
|
73
|
+
inject: reduce
|
74
|
+
collect: map
|
75
|
+
find_all: select
|
76
|
+
|
77
|
+
Style/Documentation:
|
78
|
+
Description: 'Document classes and non-namespace modules.'
|
79
|
+
Enabled: false
|
80
|
+
|
81
|
+
Style/FrozenStringLiteralComment:
|
82
|
+
Description: >-
|
83
|
+
Add the frozen_string_literal comment to the top of files
|
84
|
+
to help transition from Ruby 2.3.0 to Ruby 3.0.
|
85
|
+
Enabled: false
|
86
|
+
|
87
|
+
Style/IfUnlessModifier:
|
88
|
+
Description: >-
|
89
|
+
Favor modifier if/unless usage when you have a
|
90
|
+
single-line body.
|
91
|
+
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier'
|
92
|
+
Enabled: false
|
93
|
+
|
94
|
+
Style/InlineComment:
|
95
|
+
Description: 'Avoid inline comments.'
|
96
|
+
Enabled: false
|
97
|
+
|
98
|
+
Style/LineEndConcatenation:
|
99
|
+
Description: >-
|
100
|
+
Use \ instead of + or << to concatenate two string literals at
|
101
|
+
line end.
|
102
|
+
Enabled: true
|
103
|
+
|
104
|
+
Style/StringLiterals:
|
105
|
+
Description: 'Checks if uses of quotes match the configured preference.'
|
106
|
+
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#consistent-string-literals'
|
107
|
+
EnforcedStyle: single_quotes
|
108
|
+
Enabled: true
|
109
|
+
|
110
|
+
Style/TrailingCommaInArguments:
|
111
|
+
Description: 'Checks for trailing comma in argument lists.'
|
112
|
+
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas'
|
113
|
+
EnforcedStyleForMultiline: comma
|
114
|
+
SupportedStylesForMultiline:
|
115
|
+
- comma
|
116
|
+
- consistent_comma
|
117
|
+
- no_comma
|
118
|
+
Enabled: true
|
119
|
+
|
120
|
+
Style/TrailingCommaInArrayLiteral:
|
121
|
+
Description: 'Checks for trailing comma in array literals.'
|
122
|
+
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas'
|
123
|
+
EnforcedStyleForMultiline: comma
|
124
|
+
SupportedStylesForMultiline:
|
125
|
+
- comma
|
126
|
+
- consistent_comma
|
127
|
+
- no_comma
|
128
|
+
Enabled: true
|
129
|
+
|
130
|
+
Style/TrailingCommaInHashLiteral:
|
131
|
+
Description: 'Checks for trailing comma in hash literals.'
|
132
|
+
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas'
|
133
|
+
EnforcedStyleForMultiline: comma
|
134
|
+
SupportedStylesForMultiline:
|
135
|
+
- comma
|
136
|
+
- consistent_comma
|
137
|
+
- no_comma
|
138
|
+
Enabled: true
|
139
|
+
|
140
|
+
# Layout Cops
|
141
|
+
|
142
|
+
Layout/ArgumentAlignment:
|
143
|
+
Exclude:
|
144
|
+
- 'config/initializers/*'
|
145
|
+
|
146
|
+
Layout/FirstArgumentIndentation:
|
147
|
+
Enabled: false
|
148
|
+
|
149
|
+
Layout/DotPosition:
|
150
|
+
Description: 'Checks the position of the dot in multi-line method calls.'
|
151
|
+
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains'
|
152
|
+
Enabled: false
|
153
|
+
|
154
|
+
Layout/LineLength:
|
155
|
+
Description: 'Limit lines to 120 characters.'
|
156
|
+
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#80-character-limits'
|
157
|
+
Max: 120
|
158
|
+
|
159
|
+
Layout/MultilineOperationIndentation:
|
160
|
+
Description: >-
|
161
|
+
Checks indentation of binary operations that span more than
|
162
|
+
one line.
|
163
|
+
Enabled: true
|
164
|
+
EnforcedStyle: indented
|
165
|
+
|
166
|
+
Layout/MultilineMethodCallIndentation:
|
167
|
+
Description: >-
|
168
|
+
Checks indentation of method calls with the dot operator
|
169
|
+
that span more than one line.
|
170
|
+
Enabled: true
|
171
|
+
EnforcedStyle: indented
|
172
|
+
|
173
|
+
# Bundler Cops
|
174
|
+
|
175
|
+
Bundler/OrderedGems:
|
176
|
+
Enabled: false
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
## 0.2.0 (Jan, 25th 2023)
|
2
|
+
- Replace tests with specs
|
3
|
+
- Stop including `Activepesel::PeselAttr` `to ActiveRecord::Base`, it should be included explicitly to a model instead
|
4
|
+
- Replace `Activepesel::Pesel#generate` with `Activepesel::Pesel#generate_one` and `Activepesel::Pesel#generate_all`
|
5
|
+
- Add Ruby 3.X support
|
6
|
+
- Fix styling and add rubocop
|
7
|
+
- Reduce dependencies
|
data/Gemfile
CHANGED
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
# Activepesel
|
2
2
|
|
3
|
-
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/activepesel.svg)](https://badge.fury.io/rb/activepesel)
|
4
|
+
[![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop)
|
4
5
|
|
5
|
-
|
6
|
+
A simple PESEL (polish personal ID number) validator (ActiveModel based), generator and personal data extractor.
|
7
|
+
|
8
|
+
![](./media/id.jpg)
|
9
|
+
|
10
|
+
----------
|
6
11
|
|
7
12
|
Activepesel library is available as a gem. In your Gemfile add:
|
8
13
|
|
@@ -10,24 +15,24 @@ Activepesel library is available as a gem. In your Gemfile add:
|
|
10
15
|
gem 'activepesel'
|
11
16
|
```
|
12
17
|
|
13
|
-
#In your model:
|
18
|
+
# In your model:
|
14
19
|
|
15
20
|
```ruby
|
16
21
|
class User < ActiveRecord::Base
|
22
|
+
# you have to explicitly include it since version 0.2.0
|
23
|
+
include Activepesel::PeselAttr
|
17
24
|
|
18
|
-
|
19
|
-
|
25
|
+
# let's say we have dads_pesel and mums_pesel columns in the database
|
20
26
|
# this will give the access to methods:
|
21
27
|
# dads_pesel_personal_data, mums_pesel_personal_data
|
22
28
|
pesel_attr :dads_pesel, :mums_pesel
|
23
29
|
|
24
30
|
# keep in mind that pesel validator is not performing a presence test
|
25
31
|
# so you need another (standard) validation for this one
|
26
|
-
validates :dads_pesel, :
|
27
|
-
validates :dads_pesel, :
|
28
|
-
validates :mums_pesel, :
|
32
|
+
validates :dads_pesel, presence: true
|
33
|
+
validates :dads_pesel, pesel: true
|
34
|
+
validates :mums_pesel, pesel: true
|
29
35
|
# pesel validator returns standard rails :invalid key error message
|
30
|
-
|
31
36
|
end
|
32
37
|
```
|
33
38
|
|
@@ -38,8 +43,8 @@ When using ```attr_pesel :name_of_attr``` in your model you will get new instanc
|
|
38
43
|
The method returns ```Activepesel::PersonalData``` object which has the following attributes:
|
39
44
|
|
40
45
|
```ruby
|
41
|
-
date_of_birth:Date
|
42
|
-
sex:Integer
|
46
|
+
date_of_birth: Date
|
47
|
+
sex: Integer
|
43
48
|
```
|
44
49
|
See the example:
|
45
50
|
|
@@ -54,23 +59,24 @@ For the invalid PESEL numbers the ```date_of_birth``` attribute is set to ```nil
|
|
54
59
|
|
55
60
|
# Saving personal data into database
|
56
61
|
|
57
|
-
It is a common practice that you want to save the personal data extracted from the PESEL number to be able for example to query your records against all female persons. To do this you can
|
62
|
+
It is a common practice that you'd want to save the personal data extracted from the PESEL number to be able for example to query your records against all female persons. To do this you can do something like this:
|
58
63
|
|
59
64
|
```ruby
|
60
65
|
class User < ActiveRecord::Base
|
66
|
+
include Activepesel::PeselAttr
|
61
67
|
|
62
|
-
attr_accessible :pesel
|
63
68
|
pesel_attr :pesel
|
64
69
|
|
65
|
-
validates :pesel, :
|
70
|
+
validates :pesel, pesel: true
|
66
71
|
|
72
|
+
# we all don't like callbacks but for the sake of this simple example we can live with it
|
67
73
|
before_save :set_personal_data
|
68
74
|
|
69
75
|
private
|
70
76
|
|
71
77
|
def set_personal_data
|
72
78
|
self.date_of_birth = pesel_personal_data.date_of_birth
|
73
|
-
self.sex
|
79
|
+
self.sex = pesel_personal_data.sex
|
74
80
|
end
|
75
81
|
|
76
82
|
end
|
@@ -82,7 +88,7 @@ end
|
|
82
88
|
You can use it like in the given example
|
83
89
|
|
84
90
|
```ruby
|
85
|
-
pesel = Activepesel::Pesel.new(
|
91
|
+
pesel = Activepesel::Pesel.new('82060202039')
|
86
92
|
pesel.valid? => true
|
87
93
|
pesel.personal_data => Activepesel::PersonalData(...)
|
88
94
|
# or even quicker
|
@@ -97,16 +103,22 @@ To generate one randomly picked PESEL number for let's say a male born on Novemb
|
|
97
103
|
|
98
104
|
```ruby
|
99
105
|
# picks one random number for the given personal data
|
100
|
-
Pesel.
|
106
|
+
Activepesel::Pesel.generate_one(sex: 1, date_of_birth: Date.new(1975,11,3))
|
101
107
|
````
|
102
108
|
|
103
109
|
To generate all (5000) PESEL numbers valid for a person of a given sex and date of birth for example a female born on May 20th 2010:
|
104
110
|
|
105
111
|
```ruby
|
106
112
|
# returns all possible numbers for the given personal data in a lexicographic order
|
107
|
-
|
113
|
+
# notice that you can pass a stringified date.
|
114
|
+
Activepesel::Pesel.generate_all, sex: 2, date_of_birth: '2010-05-20')
|
108
115
|
```
|
109
116
|
|
117
|
+
# Copyright
|
118
|
+
|
119
|
+
Copyright (c) 2012 - 2023 Wojciech Pasternak released under the MIT license
|
120
|
+
|
121
|
+
|
110
122
|
|
111
123
|
|
112
124
|
|
data/Rakefile
CHANGED
@@ -1,38 +1 @@
|
|
1
|
-
|
2
|
-
begin
|
3
|
-
require 'bundler/setup'
|
4
|
-
rescue LoadError
|
5
|
-
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
-
end
|
7
|
-
begin
|
8
|
-
require 'rdoc/task'
|
9
|
-
rescue LoadError
|
10
|
-
require 'rdoc/rdoc'
|
11
|
-
require 'rake/rdoctask'
|
12
|
-
RDoc::Task = Rake::RDocTask
|
13
|
-
end
|
14
|
-
|
15
|
-
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
-
rdoc.rdoc_dir = 'rdoc'
|
17
|
-
rdoc.title = 'Activepesel'
|
18
|
-
rdoc.options << '--line-numbers'
|
19
|
-
rdoc.rdoc_files.include('README.rdoc')
|
20
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
-
end
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
Bundler::GemHelper.install_tasks
|
27
|
-
|
28
|
-
require 'rake/testtask'
|
29
|
-
|
30
|
-
Rake::TestTask.new(:test) do |t|
|
31
|
-
t.libs << 'lib'
|
32
|
-
t.libs << 'test'
|
33
|
-
t.pattern = 'test/**/*_test.rb'
|
34
|
-
t.verbose = false
|
35
|
-
end
|
36
|
-
|
37
|
-
|
38
|
-
task :default => :test
|
1
|
+
require 'bundler/gem_tasks'
|
data/activepesel.gemspec
CHANGED
@@ -1,23 +1,23 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
2
4
|
|
3
5
|
# Maintain your gem's version:
|
4
|
-
require
|
6
|
+
require 'activepesel/version'
|
5
7
|
|
6
8
|
# Describe your gem and declare its dependencies:
|
7
9
|
Gem::Specification.new do |s|
|
8
|
-
s.
|
10
|
+
s.required_ruby_version = '>= 2.7.5'
|
11
|
+
s.name = 'activepesel'
|
9
12
|
s.version = Activepesel::VERSION
|
10
|
-
s.platform = Gem::Platform::RUBY
|
11
|
-
s.authors = [
|
12
|
-
s.email = [
|
13
|
-
s.homepage =
|
14
|
-
s.summary =
|
15
|
-
s.description =
|
16
|
-
|
13
|
+
s.platform = Gem::Platform::RUBY
|
14
|
+
s.authors = ['voytee']
|
15
|
+
s.email = ['wpasternak@gmail.com']
|
16
|
+
s.homepage = 'http://github.com/voytee/activepesel'
|
17
|
+
s.summary = 'A simple, ORM agnostic, PESEL validator and personal data extractor'
|
18
|
+
s.description = 'A simple, ORM agnostic, PESEL (polish personal id number) validator and personal data extractor'
|
17
19
|
s.files = `git ls-files`.split("\n")
|
18
|
-
s.
|
19
|
-
s.
|
20
|
-
|
21
|
-
s.add_dependency "rails", ">= 3.0.0"
|
22
|
-
s.add_development_dependency "sqlite3"
|
20
|
+
s.require_paths = ['lib']
|
21
|
+
s.add_dependency 'activesupport', '>= 3.0'
|
22
|
+
s.metadata['rubygems_mfa_required'] = 'true'
|
23
23
|
end
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveModel
|
2
4
|
module Validations
|
3
5
|
class PeselValidator < ActiveModel::EachValidator
|
4
6
|
def validate_each(record, attr_name, value)
|
5
|
-
|
6
|
-
|
7
|
-
|
7
|
+
return if value.blank?
|
8
|
+
|
9
|
+
record.errors.add(attr_name, :invalid) unless Activepesel::Pesel.new(value).valid?
|
8
10
|
end
|
9
11
|
end
|
10
12
|
end
|
@@ -1,24 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Activepesel
|
2
4
|
class PersonalData
|
3
|
-
|
4
5
|
DELTA = {
|
5
6
|
18 => 80,
|
6
|
-
19 =>
|
7
|
+
19 => 0,
|
7
8
|
20 => 20,
|
8
9
|
21 => 40,
|
9
|
-
22 => 60
|
10
|
+
22 => 60,
|
10
11
|
}.freeze
|
11
12
|
|
12
|
-
attr_reader :date_of_birth,
|
13
|
+
attr_reader :date_of_birth,
|
13
14
|
:sex
|
14
15
|
|
15
16
|
def initialize(pesel)
|
16
|
-
@date_of_birth
|
17
|
+
@date_of_birth = get_date_of_birth(pesel)
|
18
|
+
@sex = get_sex(pesel)
|
17
19
|
end
|
18
20
|
|
19
21
|
private
|
20
|
-
|
21
|
-
def get_century(pesel)
|
22
|
+
|
23
|
+
def get_century(pesel) # rubocop:disable Metrics/MethodLength
|
22
24
|
case pesel.number[2..3].to_i
|
23
25
|
when (81..92)
|
24
26
|
18
|
@@ -34,31 +36,34 @@ module Activepesel
|
|
34
36
|
end
|
35
37
|
|
36
38
|
def year(pesel)
|
37
|
-
pesel.number[0..1].to_i + 100 * get_century(pesel)
|
39
|
+
pesel.number[0..1].to_i + (100 * get_century(pesel))
|
38
40
|
end
|
39
41
|
|
40
42
|
def month(pesel)
|
41
43
|
pesel.number[2..3].to_i - DELTA[get_century(pesel)]
|
42
44
|
end
|
43
|
-
|
45
|
+
|
44
46
|
def day(pesel)
|
45
47
|
pesel.number[4..5].to_i
|
46
48
|
end
|
47
49
|
|
48
50
|
def get_date_of_birth(pesel)
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
return unless pesel.valid?
|
52
|
+
|
53
|
+
begin
|
54
|
+
Date.new(year(pesel), month(pesel), day(pesel))
|
55
|
+
rescue ArgumentError
|
56
|
+
nil
|
55
57
|
end
|
56
58
|
end
|
57
|
-
|
59
|
+
|
58
60
|
# ISO/IEC 5218
|
59
61
|
def get_sex(pesel)
|
60
|
-
pesel.valid?
|
62
|
+
if pesel.valid?
|
63
|
+
pesel.digits[9].even? ? 2 : 1
|
64
|
+
else
|
65
|
+
9
|
66
|
+
end
|
61
67
|
end
|
62
|
-
|
63
68
|
end
|
64
69
|
end
|
data/lib/activepesel/pesel.rb
CHANGED
@@ -1,37 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support'
|
4
|
+
require 'active_support/core_ext'
|
5
|
+
|
1
6
|
module Activepesel
|
2
7
|
class Pesel
|
3
|
-
|
4
8
|
class << self
|
5
|
-
delegate :
|
9
|
+
delegate :generate_all, :generate_one, to: :'Activepesel::PeselGenerator'
|
6
10
|
end
|
7
|
-
|
8
|
-
DIGIT_WEIGHTS = [1, 3, 7, 9, 1, 3
|
9
|
-
|
11
|
+
|
12
|
+
DIGIT_WEIGHTS = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3, 1].freeze
|
13
|
+
|
10
14
|
attr_reader :number
|
11
|
-
|
12
|
-
delegate :date_of_birth, :sex,
|
15
|
+
|
16
|
+
delegate :date_of_birth, :sex, to: :personal_data
|
13
17
|
|
14
18
|
def initialize(number)
|
15
|
-
@number = number
|
19
|
+
@number = number
|
16
20
|
end
|
17
|
-
|
21
|
+
|
18
22
|
def valid?
|
19
|
-
digits.size == 11 && control_value % 10
|
23
|
+
digits.size == 11 && (control_value % 10).zero?
|
20
24
|
end
|
21
|
-
|
22
|
-
def digits
|
23
|
-
@number.split("").select{|digit| digit.to_i.to_s == digit}.map(&:to_i)
|
24
|
-
end
|
25
|
-
|
25
|
+
|
26
26
|
def personal_data
|
27
|
-
PersonalData.new(self) if @number
|
27
|
+
@personal_data ||= PersonalData.new(self) if @number
|
28
|
+
end
|
29
|
+
|
30
|
+
def digits
|
31
|
+
@number.chars.select { |digit| digit.to_i.to_s == digit }.map(&:to_i)
|
28
32
|
end
|
29
33
|
|
30
34
|
private
|
31
|
-
|
35
|
+
|
32
36
|
def control_value
|
33
|
-
DIGIT_WEIGHTS.each_with_index.
|
37
|
+
DIGIT_WEIGHTS.each_with_index.reduce(0) { |sum, (factor, idx)| sum + (factor * digits[idx]) }
|
34
38
|
end
|
35
|
-
|
36
39
|
end
|
37
40
|
end
|
@@ -1,20 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Activepesel
|
2
4
|
module PeselAttr
|
3
5
|
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
included do
|
6
|
-
end
|
7
|
-
|
6
|
+
|
8
7
|
module ClassMethods
|
9
8
|
def pesel_attr(*attr_names)
|
10
9
|
attr_names.each do |attr_name|
|
11
|
-
define_method("#{attr_name}_personal_data") do
|
12
|
-
Pesel.new(
|
10
|
+
define_method("#{attr_name}_personal_data") do
|
11
|
+
Pesel.new(__send__(attr_name)).personal_data
|
13
12
|
end
|
14
13
|
end
|
15
14
|
end
|
16
15
|
end
|
17
16
|
end
|
18
17
|
end
|
19
|
-
|
20
|
-
ActiveRecord::Base.send :include, Activepesel::PeselAttr
|