itax_code 0.2.0 → 0.4.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.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "itax_code/omocode"
2
4
 
3
5
  module ItaxCode
@@ -25,17 +27,12 @@ module ItaxCode
25
27
  #
26
28
  # @return [Hash]
27
29
  def decode
28
- year = decode_year
29
- month = utils.months.find_index(raw[:birthdate_month]) + 1
30
- day, gender = decode_day_and_gender
31
- birthplace = decode_birthplace
32
-
33
30
  {
34
31
  code: tax_code,
35
32
  gender: gender,
36
- birthdate: Date.parse([year, month, day].join("-")).to_s,
33
+ birthdate: birthdate,
37
34
  birthplace: birthplace,
38
- omocodes: Omocode.new(tax_code).list,
35
+ omocodes: Omocode.new(tax_code).omocodes,
39
36
  raw: raw
40
37
  }
41
38
  end
@@ -45,53 +42,66 @@ module ItaxCode
45
42
  attr_accessor :tax_code, :utils
46
43
 
47
44
  def raw
48
- matches = tax_code.scan(utils.regex).flatten
49
-
50
- {
51
- surname: matches[0],
52
- name: matches[1],
53
- birthdate: matches[2],
54
- birthdate_year: matches[3],
55
- birthdate_month: matches[4],
56
- birthdate_day: matches[5],
57
- birthplace: matches[6],
58
- cin: matches[7]
45
+ @raw ||= {
46
+ surname: raw_matches[0],
47
+ name: raw_matches[1],
48
+ birthdate: raw_matches[2],
49
+ birthdate_year: raw_matches[3],
50
+ birthdate_month: raw_matches[4],
51
+ birthdate_day: raw_matches[5],
52
+ birthplace: raw_matches[6],
53
+ cin: raw_matches[7]
59
54
  }
60
55
  end
61
56
 
62
- def decode_year
63
- year = utils.omocodia_decode raw[:birthdate_year]
64
- year = (Date.today.year.to_s[0..1] + year).to_i
65
- year -= 100 if year > Date.today.year
66
- year
57
+ def raw_matches
58
+ @raw_matches ||= tax_code.scan(utils.regex).flatten
67
59
  end
68
60
 
69
- def decode_day_and_gender
70
- day = utils.omocodia_decode(raw[:birthdate_day]).to_i
61
+ def gender
62
+ val = utils.omocodia_decode(raw[:birthdate_day]).to_i
63
+ val > 40 ? "F" : "M"
64
+ end
71
65
 
72
- if day > 40
73
- day -= 40
74
- [day, "F"]
75
- else
76
- [day, "M"]
77
- end
66
+ # This method tries to calculate the year based on a raw data. This means that the returned
67
+ # value could be wrong. E.g. a person born on 1920 would have birthdate_year = 20 meaning
68
+ # that both 1920 and 2020 could be valid born years.
69
+ def year
70
+ val = (Date.today.year.to_s[0..1] + utils.omocodia_decode(raw[:birthdate_year])).to_i
71
+ val > Date.today.year ? val - 100 : val
78
72
  end
79
73
 
80
- def decode_birthplace(src = utils.cities, exit: false)
81
- place = src.find do |item|
82
- item["code"] == city_code && !item["name"].include?("soppresso")
83
- end
74
+ def month
75
+ utils.months.find_index(raw[:birthdate_month]) + 1
76
+ end
77
+
78
+ def day
79
+ val = utils.omocodia_decode(raw[:birthdate_day]).to_i
80
+ val > 40 ? val - 40 : val
81
+ end
82
+
83
+ def birthdate
84
+ @birthdate ||= Date.parse("#{year}-#{month}-#{day}").to_s
85
+ end
86
+
87
+ def birthplace(src = utils.cities, stop: false)
88
+ place = src.find { |item| item["code"] == birthplace_code && in_dates?(item) }
84
89
 
85
90
  if place.nil?
86
- exit ? return : decode_birthplace(utils.countries, exit: true)
91
+ birthplace(utils.countries, stop: true) unless stop
87
92
  else
88
- place["name"] = place["name"].gsub(" (soppresso)", "")
89
93
  place.to_h.deep_symbolize_keys
90
94
  end
91
95
  end
92
96
 
93
- def city_code
97
+ def birthplace_code
94
98
  raw[:birthplace][0] + utils.omocodia_decode(raw[:birthplace][1..-1])
95
99
  end
100
+
101
+ def in_dates?(item)
102
+ created_on = Date.parse item.fetch("created_on", "0000-01-01")
103
+ deleted_on = Date.parse item.fetch("deleted_on", "9999-12-31")
104
+ Date.parse(birthdate).between? created_on, deleted_on
105
+ end
96
106
  end
97
107
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "csv"
2
4
 
3
5
  module ItaxCode
@@ -10,9 +12,7 @@ module ItaxCode
10
12
  end
11
13
 
12
14
  def slugged(str, separator = "-")
13
- str.gsub!(/\s*@\s*/, " at ")
14
- str.gsub!(/\s*&\s*/, " and ")
15
- str.parameterize(separator: separator)
15
+ str.gsub(/\s*@\s*/, " at ").gsub(/\s*&\s*/, " and ").parameterize(separator: separator)
16
16
  end
17
17
 
18
18
  def months
@@ -29,23 +29,17 @@ module ItaxCode
29
29
 
30
30
  def cin_odds
31
31
  {
32
- "0": 1, "1": 0, "2": 5, "3": 7, "4": 9, "5": 13,
33
- "6": 15, "7": 17, "8": 19, "9": 21, "A": 1, "B": 0,
34
- "C": 5, "D": 7, "E": 9, "F": 13, "G": 15, "H": 17,
35
- "I": 19, "J": 21, "K": 2, "L": 4, "M": 18, "N": 20,
36
- "O": 11, "P": 3, "Q": 6, "R": 8, "S": 12, "T": 14,
37
- "U": 16, "V": 10, "W": 22, "X": 25, "Y": 24, "Z": 23
32
+ "0": 1, "1": 0, "2": 5, "3": 7, "4": 9, "5": 13, "6": 15, "7": 17, "8": 19, "9": 21,
33
+ A: 1, B: 0, C: 5, D: 7, E: 9, F: 13, G: 15, H: 17, I: 19, J: 21, K: 2, L: 4, M: 18,
34
+ N: 20, O: 11, P: 3, Q: 6, R: 8, S: 12, T: 14, U: 16, V: 10, W: 22, X: 25, Y: 24, Z: 23
38
35
  }
39
36
  end
40
37
 
41
38
  def cin_evens
42
39
  {
43
- "0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5,
44
- "6": 6, "7": 7, "8": 8, "9": 9, "A": 0, "B": 1,
45
- "C": 2, "D": 3, "E": 4, "F": 5, "G": 6, "H": 7,
46
- "I": 8, "J": 9, "K": 10, "L": 11, "M": 12, "N": 13,
47
- "O": 14, "P": 15, "Q": 16, "R": 17, "S": 18, "T": 19,
48
- "U": 20, "V": 21, "W": 22, "X": 23, "Y": 24, "Z": 25
40
+ "0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9,
41
+ A: 0, B: 1, C: 2, D: 3, E: 4, F: 5, G: 6, H: 7, I: 8, J: 9, K: 10, L: 11, M: 12, N: 13,
42
+ O: 14, P: 15, Q: 16, R: 17, S: 18, T: 19, U: 20, V: 21, W: 22, X: 23, Y: 24, Z: 25
49
43
  }
50
44
  end
51
45
 
@@ -68,8 +62,14 @@ module ItaxCode
68
62
  omocodia.values.join
69
63
  end
70
64
 
71
- def omocodia_subs_indexes
72
- [6, 7, 9, 10, 12, 13, 14]
65
+ def omocodia_indexes
66
+ [6, 7, 9, 10, 12, 13, 14].reverse
67
+ end
68
+
69
+ def omocodia_indexes_combos
70
+ (1..omocodia_indexes.size).flat_map do |index|
71
+ omocodia_indexes.combination(index).to_a
72
+ end
73
73
  end
74
74
 
75
75
  def omocodia_encode(val)
@@ -92,8 +92,7 @@ module ItaxCode
92
92
  tot = 0
93
93
 
94
94
  code.chars.each_with_index do |char, index|
95
- tot += cin_odds[char.to_sym] if (index + 1).odd?
96
- tot += cin_evens[char.to_sym] if (index + 1).even?
95
+ tot += (index + 1).odd? ? cin_odds[char.to_sym] : cin_evens[char.to_sym]
97
96
  end
98
97
 
99
98
  cin_remainders[tot % 26]
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ItaxCode
2
4
  # Handles the validation logic.
3
5
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ItaxCode
2
- VERSION = "0.2.0".freeze
4
+ VERSION = "0.4.0"
3
5
  end
data/lib/itax_code.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/all"
2
4
 
3
5
  require "itax_code/version"
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "csv"
4
+ require "net/http"
5
+ require "tempfile"
6
+ require "uri"
7
+
8
+ namespace :cities do
9
+ desc "Import cities from Istat remote CSV"
10
+ task :import do
11
+ tempfile = Tempfile.new
12
+ tempfile.write Net::HTTP.get(
13
+ URI("https://raw.githubusercontent.com/italia/anpr/master/src/archivi/ANPR_archivio_comuni.csv")
14
+ )
15
+
16
+ output_string = CSV.generate do |csv|
17
+ csv << %w[code province name created_on deleted_on]
18
+
19
+ CSV.foreach(tempfile.path, headers: true) do |row|
20
+ csv << [
21
+ row["CODCATASTALE"],
22
+ row["SIGLAPROVINCIA"],
23
+ row["DENOMINAZIONE_IT"].upcase,
24
+ row["DATAISTITUZIONE"],
25
+ row["DATACESSAZIONE"]
26
+ ]
27
+ end
28
+ end
29
+
30
+ File.write("lib/itax_code/data/cities.csv", output_string)
31
+ ensure
32
+ tempfile.close
33
+ tempfile.unlink
34
+ end
35
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: itax_code
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matteo Rossi
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-11-26 00:00:00.000000000 Z
11
+ date: 2023-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -24,119 +24,7 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: byebug
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: minitest
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: mocha
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
- - !ruby/object:Gem::Dependency
70
- name: rake
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: rubocop
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: rubocop-minitest
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: rubocop-performance
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: simplecov
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- description:
27
+ description:
140
28
  email:
141
29
  - mttrss5@gmail.com
142
30
  executables: []
@@ -144,15 +32,15 @@ extensions: []
144
32
  extra_rdoc_files: []
145
33
  files:
146
34
  - ".github/CODEOWNERS"
147
- - ".github/workflows/build-and-push.yml"
148
35
  - ".github/workflows/lint.yml"
36
+ - ".github/workflows/release.yml"
149
37
  - ".github/workflows/test.yml"
150
38
  - ".gitignore"
151
39
  - ".rubocop.yml"
152
40
  - ".travis.yml"
41
+ - CHANGELOG.md
153
42
  - CODE_OF_CONDUCT.md
154
43
  - Gemfile
155
- - Gemfile.lock
156
44
  - README.md
157
45
  - Rakefile
158
46
  - bin/console
@@ -168,6 +56,7 @@ files:
168
56
  - lib/itax_code/utils.rb
169
57
  - lib/itax_code/validator.rb
170
58
  - lib/itax_code/version.rb
59
+ - rakelib/cities.rake
171
60
  homepage: https://github.com/matteoredz/itax-code
172
61
  licenses:
173
62
  - MIT
@@ -175,7 +64,8 @@ metadata:
175
64
  homepage_uri: https://github.com/matteoredz/itax-code
176
65
  source_code_uri: https://github.com/matteoredz/itax-code
177
66
  changelog_uri: https://github.com/matteoredz/itax-code/CHANGELOG.md
178
- post_install_message:
67
+ rubygems_mfa_required: 'true'
68
+ post_install_message:
179
69
  rdoc_options: []
180
70
  require_paths:
181
71
  - lib
@@ -190,8 +80,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
190
80
  - !ruby/object:Gem::Version
191
81
  version: '0'
192
82
  requirements: []
193
- rubygems_version: 3.1.2
194
- signing_key:
83
+ rubygems_version: 3.4.10
84
+ signing_key:
195
85
  specification_version: 4
196
86
  summary: Encode and decode Italian tax code (Codice Fiscale)
197
87
  test_files: []
@@ -1,27 +0,0 @@
1
- ---
2
- name: Build and Push
3
-
4
- on:
5
- push:
6
- branches:
7
- - main
8
-
9
- jobs:
10
- build:
11
- runs-on: ubuntu-latest
12
- steps:
13
- - name: Checkout
14
- uses: actions/checkout@v2
15
- - uses: fregante/setup-git-user@v1
16
- - name: Set up Ruby
17
- uses: ruby/setup-ruby@v1
18
- with:
19
- bundler-cache: true
20
- ruby-version: 2.7.0
21
- - run: bundle install
22
- - name: Build and Push to RubyGems
23
- run: ./bin/release
24
- env:
25
- GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
26
- RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_API_KEY}}
27
- ...
data/Gemfile.lock DELETED
@@ -1,74 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- itax_code (0.2.0)
5
- activesupport
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- activesupport (6.1.4.1)
11
- concurrent-ruby (~> 1.0, >= 1.0.2)
12
- i18n (>= 1.6, < 2)
13
- minitest (>= 5.1)
14
- tzinfo (~> 2.0)
15
- zeitwerk (~> 2.3)
16
- ast (2.4.2)
17
- byebug (11.1.3)
18
- concurrent-ruby (1.1.9)
19
- docile (1.4.0)
20
- i18n (1.8.11)
21
- concurrent-ruby (~> 1.0)
22
- minitest (5.14.4)
23
- mocha (1.13.0)
24
- parallel (1.21.0)
25
- parser (3.0.3.0)
26
- ast (~> 2.4.1)
27
- rainbow (3.0.0)
28
- rake (13.0.6)
29
- regexp_parser (2.1.1)
30
- rexml (3.2.5)
31
- rubocop (1.23.0)
32
- parallel (~> 1.10)
33
- parser (>= 3.0.0.0)
34
- rainbow (>= 2.2.2, < 4.0)
35
- regexp_parser (>= 1.8, < 3.0)
36
- rexml
37
- rubocop-ast (>= 1.12.0, < 2.0)
38
- ruby-progressbar (~> 1.7)
39
- unicode-display_width (>= 1.4.0, < 3.0)
40
- rubocop-ast (1.13.0)
41
- parser (>= 3.0.1.1)
42
- rubocop-minitest (0.17.0)
43
- rubocop (>= 0.90, < 2.0)
44
- rubocop-performance (1.12.0)
45
- rubocop (>= 1.7.0, < 2.0)
46
- rubocop-ast (>= 0.4.0)
47
- ruby-progressbar (1.11.0)
48
- simplecov (0.21.2)
49
- docile (~> 1.1)
50
- simplecov-html (~> 0.11)
51
- simplecov_json_formatter (~> 0.1)
52
- simplecov-html (0.12.3)
53
- simplecov_json_formatter (0.1.3)
54
- tzinfo (2.0.4)
55
- concurrent-ruby (~> 1.0)
56
- unicode-display_width (2.1.0)
57
- zeitwerk (2.5.1)
58
-
59
- PLATFORMS
60
- ruby
61
-
62
- DEPENDENCIES
63
- byebug
64
- itax_code!
65
- minitest
66
- mocha
67
- rake
68
- rubocop
69
- rubocop-minitest
70
- rubocop-performance
71
- simplecov
72
-
73
- BUNDLED WITH
74
- 2.2.28