snils 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6a2f1950c8b25a7604324cbb84d179fb53251f10
4
+ data.tar.gz: dfdc5be3335785ece5d5bf3964e509acc7424be9
5
+ SHA512:
6
+ metadata.gz: 070f9179663627b3d3fb152037f63fdb5790da26429dc7d9db3beb2ec5950597e43d28d1c1a7ef80ab25f96d07d4514bef8d260e0196b808126e37a7d13edd14
7
+ data.tar.gz: a1032ea644a7f785855ca70b45301ecae1e6d95770f6bb0fbf3394f35e2d609bc8602d2b3c3cdfba2192f5c98f265c1c8bd4fe3743cb50b9925bbca114a52b3c
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ html/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ *.bundle
20
+ *.so
21
+ *.o
22
+ *.a
23
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --warnings
3
+ --format documentation
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 1.8.7
5
+ - ree
6
+ - 1.9.3
7
+ - 2.0.0
8
+ - 2.1
9
+ - jruby
10
+ - rbx
11
+ - ruby-head
12
+
13
+ matrix:
14
+ allow_failures:
15
+ - rvm: ruby-head
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in snils.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Andrey Novikov
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,82 @@
1
+ SNILS
2
+ =====
3
+
4
+ [![Gem Version](https://badge.fury.io/rb/snils.svg)](http://badge.fury.io/rb/snils)
5
+ [![Continuous Integration status](https://api.travis-ci.org/Envek/snils.svg)](http://travis-ci.org/Envek/snils)
6
+
7
+ Generating, validating and formatting [SNILS] number (Russian pension insurance individual account number).
8
+
9
+ Генерация, валидация и форматирование СНИЛС (Страхового номера индивидуального лицевого счёта).
10
+
11
+ [Read this README in Russian (Читать это README на русском)](README.ru.md)
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ gem 'snils'
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install snils
26
+
27
+ ## Usage
28
+
29
+ Generate new SNILS:
30
+
31
+ ```ruby
32
+ Snils.new.formatted
33
+ #=> "216-471-647 63"
34
+ ```
35
+
36
+ Validate SNILS:
37
+
38
+ ```ruby
39
+ Snils.new("21647164763").valid?
40
+ #=> true
41
+
42
+ Snils.new("21647164760").valid?
43
+ #=> false
44
+
45
+ Snils.new("21647164760").errors
46
+ #=> [:invalid]
47
+
48
+ Snils.new("216471647").errors
49
+ #=> [[:wrong_length, {:count=>11}], :invalid]
50
+ ```
51
+
52
+ Validating Rails model attributes:
53
+
54
+ ```ruby
55
+ require 'snils'
56
+
57
+ class User < ActiveRecord::Base
58
+ validates :snils, presence: true, uniqueness: true
59
+ validate :snils_validation
60
+
61
+ protected
62
+
63
+ def snils_validation
64
+ validated_snils = Snils.new(snils)
65
+ unless validated_snils.valid?
66
+ validated_snils.errors.each do |error|
67
+ errors.add(:snils, *error)
68
+ end
69
+ end
70
+ end
71
+ end
72
+ ```
73
+
74
+ ## Contributing
75
+
76
+ 1. Fork it ( https://github.com/Envek/snils/fork )
77
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
78
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
79
+ 4. Push to the branch (`git push origin my-new-feature`)
80
+ 5. Create a new Pull Request
81
+
82
+ [SNILS]: http://en.wikipedia.org/wiki/SNILS_(Russia) "Insurance individual account number"
data/README.ru.md ADDED
@@ -0,0 +1,77 @@
1
+ СНИЛС
2
+ =====
3
+
4
+ Генерация, валидация и форматирование [СНИЛС] (Страхового номера индивидуального лицевого счёта).
5
+
6
+ [Read this README in English (Читать это README на английском)](README.ru.md)
7
+
8
+ ## Установка
9
+
10
+ Добавьте следующую строчку в Gemfile в вашем приложении:
11
+
12
+ gem 'snils'
13
+
14
+ И затем выполните:
15
+
16
+ $ bundle
17
+
18
+ Или установите вручную:
19
+
20
+ $ gem install snils
21
+
22
+ ## Использование
23
+
24
+ Генерирование новых СНИЛСов:
25
+
26
+ ```ruby
27
+ Snils.new.formatted
28
+ #=> "216-471-647 63"
29
+ ```
30
+
31
+ Проверка корректности СНИЛСов:
32
+
33
+ ```ruby
34
+ Snils.new("21647164763").valid?
35
+ #=> true
36
+
37
+ Snils.new("21647164760").valid?
38
+ #=> false
39
+
40
+ Snils.new("21647164760").errors
41
+ #=> [:invalid]
42
+
43
+ Snils.new("216471647").errors
44
+ #=> [[:wrong_length, {:count=>11}], :invalid]
45
+ ```
46
+
47
+ Валидация в Ruby on Rails для атрибутов моделей:
48
+
49
+ ```ruby
50
+ require 'snils'
51
+
52
+ class User < ActiveRecord::Base
53
+ validates :snils, presence: true, uniqueness: true
54
+ validate :snils_validation
55
+
56
+ protected
57
+
58
+ def snils_validation
59
+ validated_snils = Snils.new(snils)
60
+ unless validated_snils.valid?
61
+ validated_snils.errors.each do |error|
62
+ errors.add(:snils, *error)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ ```
68
+
69
+ ## Помощь в разработке
70
+
71
+ 1. Сделайте форк проекта в своём github-аккаунте. ( https://github.com/Envek/snils/fork )
72
+ 2. Создайте отдельную ветвь разработки. (`git checkout -b my-new-feature`)
73
+ 3. Внесите в неё желаемые изменения (не забудьте про тесты!) и сделайте коммит(ы). (`git commit -am 'Add some feature'`)
74
+ 4. Запушьте изменения (`git push origin my-new-feature`)
75
+ 5. Создайте новый Pull Request
76
+
77
+ [СНИЛС]: http://ru.wikipedia.org/wiki/%D0%A1%D1%82%D1%80%D0%B0%D1%85%D0%BE%D0%B2%D0%BE%D0%B9_%D0%BD%D0%BE%D0%BC%D0%B5%D1%80_%D0%B8%D0%BD%D0%B4%D0%B8%D0%B2%D0%B8%D0%B4%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BB%D0%B8%D1%86%D0%B5%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D1%87%D1%91%D1%82%D0%B0
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
8
+
9
+ require 'rdoc/task'
10
+
11
+ RDoc::Task.new do |rdoc|
12
+ rdoc.main = 'README.md'
13
+ rdoc.rdoc_files.include('README.md', 'README.ru.md', 'LICENSE.txt', 'lib/**/*.rb')
14
+ end
data/lib/snils.rb ADDED
@@ -0,0 +1,80 @@
1
+ require 'snils/version'
2
+
3
+ # Generating, validating and formatting SNILS number Russian pension insurance individual account number)
4
+ class Snils
5
+
6
+ # New object with SNILS +number+ if provided. Otherwise, it generated randomly
7
+ def initialize(number = nil)
8
+ @snils = if number.kind_of? Numeric
9
+ '%011d' % number
10
+ elsif number
11
+ number.to_s.gsub(/[^\d]/, '')
12
+ else
13
+ self.class.generate
14
+ end
15
+ @errors = []
16
+ @validated = false
17
+ end
18
+
19
+ # Calculates checksum (last 2 digits) of a number
20
+ def checksum
21
+ digits = @snils.split('').take(9).map(&:to_i)
22
+ checksum = digits.each.with_index.inject(0) do |sum, (digit, index)|
23
+ sum + digit * (9 - index)
24
+ end
25
+ checksum = case
26
+ when (100..101).cover?(checksum)
27
+ 0
28
+ when checksum > 101
29
+ checksum % 101
30
+ else
31
+ checksum
32
+ end
33
+ '%02d' % checksum
34
+ end
35
+
36
+ # Validates SNILS. Valid SNILS is a 11 digits long and have correct checksum
37
+ def valid?
38
+ validate unless @validated
39
+ @errors.none?
40
+ end
41
+
42
+ # Validates string with a SNILS. Valid SNILS is a 11 digits long and have correct checksum.
43
+ def self.valid?(snils)
44
+ self.new(snils).valid?
45
+ end
46
+
47
+ # Returns SNILS in format 000-000-000 00
48
+ def formatted
49
+ "#{@snils[0..2]}-#{@snils[3..5]}-#{@snils[6..8]} #{@snils[9..10]}"
50
+ end
51
+
52
+ # Returns unformatted SNILS (only 11 digits)
53
+ def raw
54
+ @snils
55
+ end
56
+ alias_method :to_s, :raw
57
+
58
+ # Returns array with errors if SNILS invalid
59
+ def errors
60
+ validate unless @validated
61
+ @errors
62
+ end
63
+
64
+ # Generates new random valid SNILS
65
+ def self.generate
66
+ digits = Array.new(9).map{ rand (0..9) }.join
67
+ sum = self.new(digits).checksum
68
+ "#{digits}#{sum}"
69
+ end
70
+
71
+ protected
72
+
73
+ def validate
74
+ @errors << [:wrong_length, :count => 11] unless @snils.length == 11
75
+ @errors << :invalid unless @snils[-2..-1] == self.checksum
76
+ @validated = true
77
+ end
78
+
79
+ end
80
+
@@ -0,0 +1,3 @@
1
+ class Snils
2
+ VERSION = '0.1.0'
3
+ end
data/snils.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'snils/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'snils'
8
+ spec.version = Snils::VERSION
9
+ spec.authors = ['Andrey Novikov']
10
+ spec.email = ['envek@envek.name']
11
+ spec.summary = %q{Generating, validating and formatting SNILS number (Russian pension insurance number)}
12
+ spec.homepage = 'https://github.com/Envek/snils'
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_development_dependency 'bundler', '~> 1.6'
21
+ spec.add_development_dependency 'rake'
22
+ spec.add_development_dependency 'rspec', '~> 3.0'
23
+ spec.add_development_dependency 'rdoc'
24
+
25
+ spec.extra_rdoc_files = ['README.md', 'README.ru.md', 'LICENSE.txt']
26
+ spec.rdoc_options << '--main' << 'README.md'
27
+ end
@@ -0,0 +1,123 @@
1
+ require 'rspec'
2
+ require 'snils'
3
+
4
+ describe Snils do
5
+
6
+ # DISCLAIMER: All SNILS used there ARE GENERATED AND RANDOM. Any coincidences are accidental.
7
+
8
+ describe '#initialize' do
9
+
10
+ it 'should initialize with formatted snils' do
11
+ snils = described_class.new('963-117-158 08')
12
+ expect(snils.raw).to eq('96311715808')
13
+ end
14
+
15
+ it 'should initialize with unformatted snils' do
16
+ snils = described_class.new('96311715808')
17
+ expect(snils.raw).to eq('96311715808')
18
+ end
19
+
20
+ it 'should initialize with numeric snils' do
21
+ snils = described_class.new(96311715808)
22
+ expect(snils.raw).to eq('96311715808')
23
+ end
24
+
25
+ it 'should generate new snils if nothing provided' do
26
+ snils = described_class.new
27
+ expect(snils.raw.length).to eq(11)
28
+ expect(snils.valid?).to be true
29
+ end
30
+
31
+ end
32
+
33
+ describe '#valid?' do
34
+
35
+ it 'should validate valid snils' do
36
+ snils = described_class.new('963-117-158 08')
37
+ expect(snils.valid?).to be true
38
+ end
39
+
40
+ it 'should not validate invalid snils (with wrong checksum)' do
41
+ snils = described_class.new('963-117-158 00')
42
+ expect(snils.valid?).to be false
43
+ end
44
+
45
+ it 'should not validate invalid snils (with wrong length)' do
46
+ snils = described_class.new('963-117-158 000')
47
+ expect(snils.valid?).to be false
48
+ end
49
+
50
+ it 'should not validate invalid snils (with wrong length)' do
51
+ snils = described_class.new('963-117-158')
52
+ expect(snils.valid?).to be false
53
+ end
54
+
55
+ end
56
+
57
+ describe '#errors' do
58
+
59
+ it 'should return empty array for valid snils' do
60
+ snils = described_class.new('963-117-158 08')
61
+ expect(snils.errors).to eq []
62
+ end
63
+
64
+ it 'should not validate invalid snils (with wrong checksum)' do
65
+ snils = described_class.new('963-117-158 00')
66
+ expect(snils.errors).to include :invalid
67
+ end
68
+
69
+ it 'should not validate invalid snils (with wrong length)' do
70
+ snils = described_class.new('963-117-158 080')
71
+ expect(snils.errors).to include [:wrong_length, :count => 11]
72
+ end
73
+
74
+ it 'should not validate invalid snils (with wrong length)' do
75
+ snils = described_class.new('963-117-158')
76
+ expect(snils.errors).to include [:wrong_length, :count => 11]
77
+ end
78
+
79
+ end
80
+
81
+ describe '#checksum' do
82
+
83
+ it 'calculates valid checksum' do
84
+ snils = described_class.new('96311715808')
85
+ expect(snils.checksum).to eq('08')
86
+ snils = described_class.new('83568300320')
87
+ expect(snils.checksum).to eq('20')
88
+ snils = described_class.new('61310200300')
89
+ expect(snils.checksum).to eq('00')
90
+ end
91
+
92
+ it 'calculates valid checksum even for invalid snils' do
93
+ snils = described_class.new('96311715800')
94
+ expect(snils.checksum).to eq('08')
95
+ end
96
+
97
+ it 'calculates valid checksum even for incomplete snils' do
98
+ snils = described_class.new('188299822')
99
+ expect(snils.checksum).to eq('50')
100
+ end
101
+
102
+ end
103
+
104
+ describe '#formatted' do
105
+ it 'outputs formatted snils' do
106
+ snils = described_class.new('96311715808')
107
+ expect(snils.formatted).to eq('963-117-158 08')
108
+ end
109
+ end
110
+
111
+ describe '.generate' do
112
+ it 'generates valid snils' do
113
+ expect(described_class.valid?(described_class.generate)).to be true
114
+ end
115
+ end
116
+
117
+ describe '.validate' do
118
+ it 'validates valid snils' do
119
+ expect(described_class.valid?(described_class.generate)).to be true
120
+ end
121
+ end
122
+
123
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: snils
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Andrey Novikov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
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: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rdoc
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email:
71
+ - envek@envek.name
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files:
75
+ - README.md
76
+ - README.ru.md
77
+ - LICENSE.txt
78
+ files:
79
+ - ".gitignore"
80
+ - ".rspec"
81
+ - ".travis.yml"
82
+ - Gemfile
83
+ - LICENSE.txt
84
+ - README.md
85
+ - README.ru.md
86
+ - Rakefile
87
+ - lib/snils.rb
88
+ - lib/snils/version.rb
89
+ - snils.gemspec
90
+ - spec/snils_spec.rb
91
+ homepage: https://github.com/Envek/snils
92
+ licenses:
93
+ - MIT
94
+ metadata: {}
95
+ post_install_message:
96
+ rdoc_options:
97
+ - "--main"
98
+ - README.md
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project:
113
+ rubygems_version: 2.2.2
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Generating, validating and formatting SNILS number (Russian pension insurance
117
+ number)
118
+ test_files:
119
+ - spec/snils_spec.rb