codice-fiscale 0.0.4 → 0.0.5

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.
data/README.md CHANGED
@@ -11,7 +11,7 @@ gender, birthdate and the birthplace. Read more on [wikipedia](http://en.wikiped
11
11
  ```ruby
12
12
  require 'codice_fiscale'
13
13
 
14
- CodiceFiscale.calculate 'mario', 'rossi', :male, Date.new(1987, 1, 1), 'italia', 'lc', 'Abbadia Lariana'
14
+ CodiceFiscale.calculate :name => 'Mario', :surname => 'Rossi', :gender => :male, :birthdate => Date.new(1987, 1, 1), :province_code => 'LC', :city_name => 'Abbadia Lariana'
15
15
 
16
16
  # RSSMRA87A01A005V
17
17
  ```
@@ -22,8 +22,9 @@ If a person was born outside Italy, only the italian name of the county is requi
22
22
  For example, an italian citizen born in France:
23
23
 
24
24
  ```ruby
25
- CodiceFiscale.calculate 'mario', 'rossi', :male, Date.new(1987, 1, 1), 'francia'
25
+ CodiceFiscale.calculate :name => 'Mario', :surname => 'Rossi', :gender => :male, :birthdate => Date.new(1987, 1, 1), :country_name => 'Francia'
26
26
  ```
27
+
27
28
  If a person was born in Italy you have to specify the *code* of the province and the *name* of the city. These informations are actually contained in an XLS
28
29
  document downloaded from [agenziaterritorio.it](http://www.agenziaterritorio.it/?id=721), converted to CSV and shipped with this gem.
29
30
 
@@ -9,20 +9,31 @@ require 'codice_fiscale/configuration'
9
9
  module CodiceFiscale
10
10
  extend self
11
11
 
12
- def calculate name, surname, gender, birthdate, country_name, province_code = nil, city_name = nil
13
- code = birthplace_part country_name, city_name, province_code
14
- return nil unless code
15
- code = surname_part(surname) + name_part(name) + birthdate_part(birthdate, gender) + code
12
+ def calculate params
13
+ validate_calculate_params params
14
+ code = birthplace_part (params[:country_name] || Codes::ITALY), params[:city_name], params[:province_code]
15
+ raise "Missing city/country code. Mispelled?" unless code
16
+ code = surname_part(params[:surname]) + name_part(params[:name]) + birthdate_part(params[:birthdate], params[:gender]) + code
16
17
  code + check_character(code)
17
18
  end
18
19
 
20
+ def validate_calculate_params params
21
+ [:name, :surname, :gender, :birthdate].each do |param_name|
22
+ raise "Missing #{param_name} parameter" unless params[param_name]
23
+ end
24
+ raise "Invalid birthdate: #{params[:birthdate]}" unless params[:birthdate].respond_to? :year
25
+ unless Codes::GENDERS.include? params[:gender]
26
+ raise "Invalid gender. Possible values are #{Codes::GENDERS}"
27
+ end
28
+ end
29
+
19
30
 
20
31
  # Methods to generate each part of the code
21
32
 
22
33
  def surname_part surname
23
34
  surname.upcase!
24
35
  code = first_three_consonants surname
25
- code << first_three_vocals(surname)
36
+ code << first_three_vowels(surname)
26
37
  truncate_and_right_pad_with_three_x code
27
38
  end
28
39
 
@@ -31,7 +42,7 @@ module CodiceFiscale
31
42
  consonants_of_name = consonants name
32
43
  return consonants_of_name[0]+consonants_of_name[2..3] if consonants_of_name.size >= 4
33
44
  code = first_three_consonants name
34
- code << first_three_vocals(name)
45
+ code << first_three_vowels(name)
35
46
  truncate_and_right_pad_with_three_x code
36
47
  end
37
48
 
@@ -53,7 +64,7 @@ module CodiceFiscale
53
64
  end
54
65
 
55
66
  def birthplace_part country_name, city_name = nil, province_code = nil
56
- if %w[italia italy].include?(country_name.downcase.strip)
67
+ if Codes.italy? country_name
57
68
  city_code city_name, province_code
58
69
  else
59
70
  country_code country_name
@@ -87,8 +98,8 @@ module CodiceFiscale
87
98
  intersects(string, Alphabet.consonants)[0..2]
88
99
  end
89
100
 
90
- def first_three_vocals string
91
- intersects(string, Alphabet.vocals)[0..2]
101
+ def first_three_vowels string
102
+ intersects(string, Alphabet.vowels)[0..2]
92
103
  end
93
104
 
94
105
  def truncate_and_right_pad_with_three_x string
@@ -2,16 +2,16 @@ module CodiceFiscale
2
2
  module Alphabet
3
3
  extend self
4
4
 
5
- def vocals
5
+ def vowels
6
6
  %w[A E I O U]
7
7
  end
8
8
 
9
9
  def consonants
10
- letters - vocals
10
+ letters - vowels
11
11
  end
12
12
 
13
13
  def letters
14
- %w[A B C D E F G H I J K L M N O P Q R S T U V W X Y Z]
14
+ ('A'..'Z').to_a
15
15
  end
16
16
  end
17
17
  end
@@ -2,13 +2,26 @@ module CodiceFiscale
2
2
  module Codes
3
3
  extend self
4
4
 
5
+ ITALY = 'Italia'
6
+
7
+ MONTH_CODES = %w[A B C D E H L M P R S T]
8
+
9
+ ODD_CODES = {'0' => 1, '1' => 0, '2' => 5, '3' => 7, '4' => 9, '5' => 13, '6' => 15, '7' => 17, '8' => 19, '9' => 21, 'A' => 1, 'B' => 0,
10
+ 'C' => 5, 'D' => 7, 'E' => 9, 'F' => 13, 'G' => 15, 'H' => 17, 'I' => 19, 'J' => 21, 'K' => 2, 'L' => 4, 'M' => 18, 'N' => 20,
11
+ 'O' => 11, 'P' => 3, 'Q' => 6, 'R' => 8, 'S' => 12, 'T' => 14, 'U' => 16, 'V' => 10, 'W' => 22, 'X' => 25, 'Y' => 24, 'Z' => 23}
12
+
13
+ EVEN_CODES = {'0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, 'A' => 0, 'B' => 1,
14
+ 'C' => 2, 'D' => 3, 'E' => 4, 'F' => 5, 'G' => 6, 'H' => 7, 'I' => 8, 'J' => 9, 'K' => 10, 'L' => 11, 'M' => 12, 'N' => 13,
15
+ 'O' => 14, 'P' => 15, 'Q' => 16, 'R' => 17, 'S' => 18, 'T' => 19, 'U' => 20, 'V' => 21, 'W' => 22, 'X' => 23, 'Y' => 24, 'Z' => 25}
16
+
17
+ GENDERS = [:male, :female]
18
+
5
19
  def config
6
20
  CodiceFiscale.config
7
21
  end
8
22
 
9
23
  def month_letter month_number
10
- decode = %w[A B C D E H L M P R S T]
11
- month_number <= 0 ? nil : decode[month_number-1]
24
+ month_number <= 0 ? nil : MONTH_CODES[month_number-1]
12
25
  end
13
26
 
14
27
  def city city_name, province_code
@@ -28,22 +41,19 @@ module CodiceFiscale
28
41
  end
29
42
 
30
43
  def odd_character character
31
- decode = {'0' => 1, '1' => 0, '2' => 5, '3' => 7, '4' => 9, '5' => 13, '6' => 15, '7' => 17, '8' => 19, '9' => 21, 'A' => 1, 'B' => 0,
32
- 'C' => 5, 'D' => 7, 'E' => 9, 'F' => 13, 'G' => 15, 'H' => 17, 'I' => 19, 'J' => 21, 'K' => 2, 'L' => 4, 'M' => 18, 'N' => 20,
33
- 'O' => 11, 'P' => 3, 'Q' => 6, 'R' => 8, 'S' => 12, 'T' => 14, 'U' => 16, 'V' => 10, 'W' => 22, 'X' => 25, 'Y' => 24, 'Z' => 23}
34
- decode[character.upcase]
44
+ ODD_CODES[character.upcase]
35
45
  end
36
46
 
37
47
  def even_character character
38
- decode = {'0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, 'A' => 0, 'B' => 1,
39
- 'C' => 2, 'D' => 3, 'E' => 4, 'F' => 5, 'G' => 6, 'H' => 7, 'I' => 8, 'J' => 9, 'K' => 10, 'L' => 11, 'M' => 12, 'N' => 13,
40
- 'O' => 14, 'P' => 15, 'Q' => 16, 'R' => 17, 'S' => 18, 'T' => 19, 'U' => 20, 'V' => 21, 'W' => 22, 'X' => 23, 'Y' => 24, 'Z' => 25}
41
- decode[character.upcase]
48
+ EVEN_CODES[character.upcase]
42
49
  end
43
50
 
44
51
  def check_character number
45
- decode = %w[A B C D E F G H I J K L M N O P Q R S T U V W X Y Z]
46
- decode[number]
52
+ Alphabet.letters[number]
53
+ end
54
+
55
+ def italy? country_name
56
+ ITALY.casecmp(country_name.strip) == 0
47
57
  end
48
58
  end
49
59
  end
@@ -1,3 +1,3 @@
1
1
  module CodiceFiscale
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -168,15 +168,47 @@ describe CodiceFiscale do
168
168
  describe '#calculate' do
169
169
  context 'italian citizen' do
170
170
  it 'return the expected code' do
171
- params = ['mario', 'rossi', :male, Date.new(1987, 1, 1), 'italia', 'lc', 'Abbadia Lariana']
172
- subject.calculate(*params).should == 'RSSMRA87A01A005V'
171
+ params = {:name => 'mario', :surname => 'rossi', :gender => :male, :birthdate => Date.new(1987, 1, 1),
172
+ :province_code => 'lc', :city_name => 'Abbadia Lariana'}
173
+ subject.calculate(params).should == 'RSSMRA87A01A005V'
173
174
  end
174
175
  end
175
176
 
176
177
  context 'return the expected code' do
177
178
  it 'work' do
178
- params = ['mario', 'rossi', :male, Date.new(1987, 1, 1), 'Albania']
179
- subject.calculate(*params).should == 'RSSMRA87A01Z100H'
179
+ params = {:name => 'mario', :surname => 'rossi', :gender => :male, :birthdate => Date.new(1987, 1, 1), :country_name => 'Albania'}
180
+ subject.calculate(params).should == 'RSSMRA87A01Z100H'
181
+ end
182
+ end
183
+ end
184
+
185
+ describe '#validate_calculate_params' do
186
+ let(:mandatory_params) { {:name => 'mario', :surname => 'rossi', :gender => :male, :birthdate => Date.new(1987, 1, 1)} }
187
+
188
+ context 'All mandatory params are correct' do
189
+ it 'do not raise any arror' do
190
+ lambda { subject.validate_calculate_params(mandatory_params) }.should_not raise_error
191
+ end
192
+ end
193
+
194
+ context 'A mandatory parameter is missing' do
195
+ it 'raise an error' do
196
+ without_name = mandatory_params.reject {|p| p == :name }
197
+ lambda { subject.validate_calculate_params(without_name) }.should raise_error
198
+ end
199
+ end
200
+
201
+ context 'Gender is invalid' do
202
+ it 'raise an error' do
203
+ params = mandatory_params.merge :gender => :lol
204
+ lambda { subject.validate_calculate_params(params) }.should raise_error
205
+ end
206
+ end
207
+
208
+ context 'Birthdate is invalid' do
209
+ it 'raise an error' do
210
+ params = mandatory_params.merge :birthdate => '2000/01/01'
211
+ lambda { subject.validate_calculate_params(params) }.should raise_error
180
212
  end
181
213
  end
182
214
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codice-fiscale
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: