itax_code 0.4.1 → 1.0.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 +1 -0
- data/CHANGELOG.md +18 -0
- data/README.md +120 -0
- data/lib/itax_code/encoder.rb +1 -1
- data/lib/itax_code/omocode.rb +6 -4
- data/lib/itax_code/parser.rb +8 -4
- data/lib/itax_code/utils.rb +42 -17
- data/lib/itax_code/validator.rb +54 -13
- data/lib/itax_code/version.rb +1 -1
- data/lib/itax_code.rb +5 -5
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a38d68de9f4fc5be15da055a5166c402adbe71d67b9e73213875e28c83b17db6
|
4
|
+
data.tar.gz: 7e27421ed321f9f6a8b8d0ec2ba38d005a81414401d5fbfbaa434c6a17e8d40d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 724473a7faa374ac886a4a65cf37fe0168e4f1de0e318be0155f42b525d4ee74252c60a474e5db794c2879792f82f9c912ea2d7385b3a5724ac4d042e08d5362
|
7
|
+
data.tar.gz: 7af13a9eb19e9e3558bf83072448d561b86e964a61e3c4444638b6c7ceb938a4c84232b95ec74386f10358c8f205cd4a99b54bc9e6f14152b72d87ace7635bfa
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [1.0.0](https://github.com/matteoredz/itax-code/compare/v0.4.1...v1.0.0) (2023-08-30)
|
4
|
+
|
5
|
+
|
6
|
+
### ⚠ BREAKING CHANGES
|
7
|
+
|
8
|
+
* allow empty or partial data argument in ItaxCode.valid? ([#26](https://github.com/matteoredz/itax-code/issues/26))
|
9
|
+
* raise InvalidControlInternalNumberError on cin mismatch ([#25](https://github.com/matteoredz/itax-code/issues/25))
|
10
|
+
|
11
|
+
### Features
|
12
|
+
|
13
|
+
* allow empty or partial data argument in ItaxCode.valid? ([#26](https://github.com/matteoredz/itax-code/issues/26)) ([d02da6d](https://github.com/matteoredz/itax-code/commit/d02da6d17a4c04e1a5e07d7dd9d9d966479346bd))
|
14
|
+
|
15
|
+
|
16
|
+
### Bug Fixes
|
17
|
+
|
18
|
+
* compute omocodes from the original one ([#22](https://github.com/matteoredz/itax-code/issues/22)) ([b8a963f](https://github.com/matteoredz/itax-code/commit/b8a963faba2c46e1d23c0dc643a257aabd648dd9))
|
19
|
+
* raise InvalidControlInternalNumberError on cin mismatch ([#25](https://github.com/matteoredz/itax-code/issues/25)) ([121cbca](https://github.com/matteoredz/itax-code/commit/121cbcaf75788c99bee4ffd7a997d07783a7fc15))
|
20
|
+
|
3
21
|
## [0.4.1](https://github.com/matteoredz/itax-code/compare/v0.4.0...v0.4.1) (2023-08-08)
|
4
22
|
|
5
23
|
|
data/README.md
CHANGED
@@ -54,11 +54,131 @@ ItaxCode.decode("RSSMRA80A01F205X")
|
|
54
54
|
# omocodes: %w[
|
55
55
|
# RSSMRA80A01F205X
|
56
56
|
# RSSMRA80A01F20RS
|
57
|
+
# RSSMRA80A01F2L5I
|
58
|
+
# RSSMRA80A01FN05M
|
59
|
+
# RSSMRA80A0MF205P
|
60
|
+
# RSSMRA80AL1F205I
|
61
|
+
# RSSMRA8LA01F205I
|
62
|
+
# RSSMRAU0A01F205U
|
57
63
|
# RSSMRA80A01F2LRD
|
64
|
+
# RSSMRA80A01FN0RH
|
65
|
+
# RSSMRA80A0MF20RK
|
66
|
+
# RSSMRA80AL1F20RD
|
67
|
+
# RSSMRA8LA01F20RD
|
68
|
+
# RSSMRAU0A01F20RP
|
69
|
+
# RSSMRA80A01FNL5X
|
70
|
+
# RSSMRA80A0MF2L5A
|
71
|
+
# RSSMRA80AL1F2L5T
|
72
|
+
# RSSMRA8LA01F2L5T
|
73
|
+
# RSSMRAU0A01F2L5F
|
74
|
+
# RSSMRA80A0MFN05E
|
75
|
+
# RSSMRA80AL1FN05X
|
76
|
+
# RSSMRA8LA01FN05X
|
77
|
+
# RSSMRAU0A01FN05J
|
78
|
+
# RSSMRA80ALMF205A
|
79
|
+
# RSSMRA8LA0MF205A
|
80
|
+
# RSSMRAU0A0MF205M
|
81
|
+
# RSSMRA8LAL1F205T
|
82
|
+
# RSSMRAU0AL1F205F
|
83
|
+
# RSSMRAULA01F205F
|
58
84
|
# RSSMRA80A01FNLRS
|
85
|
+
# RSSMRA80A0MF2LRV
|
86
|
+
# RSSMRA80AL1F2LRO
|
87
|
+
# RSSMRA8LA01F2LRO
|
88
|
+
# RSSMRAU0A01F2LRA
|
89
|
+
# RSSMRA80A0MFN0RZ
|
90
|
+
# RSSMRA80AL1FN0RS
|
91
|
+
# RSSMRA8LA01FN0RS
|
92
|
+
# RSSMRAU0A01FN0RE
|
93
|
+
# RSSMRA80ALMF20RV
|
94
|
+
# RSSMRA8LA0MF20RV
|
95
|
+
# RSSMRAU0A0MF20RH
|
96
|
+
# RSSMRA8LAL1F20RO
|
97
|
+
# RSSMRAU0AL1F20RA
|
98
|
+
# RSSMRAULA01F20RA
|
99
|
+
# RSSMRA80A0MFNL5P
|
100
|
+
# RSSMRA80AL1FNL5I
|
101
|
+
# RSSMRA8LA01FNL5I
|
102
|
+
# RSSMRAU0A01FNL5U
|
103
|
+
# RSSMRA80ALMF2L5L
|
104
|
+
# RSSMRA8LA0MF2L5L
|
105
|
+
# RSSMRAU0A0MF2L5X
|
106
|
+
# RSSMRA8LAL1F2L5E
|
107
|
+
# RSSMRAU0AL1F2L5Q
|
108
|
+
# RSSMRAULA01F2L5Q
|
109
|
+
# RSSMRA80ALMFN05P
|
110
|
+
# RSSMRA8LA0MFN05P
|
111
|
+
# RSSMRAU0A0MFN05B
|
112
|
+
# RSSMRA8LAL1FN05I
|
113
|
+
# RSSMRAU0AL1FN05U
|
114
|
+
# RSSMRAULA01FN05U
|
115
|
+
# RSSMRA8LALMF205L
|
116
|
+
# RSSMRAU0ALMF205X
|
117
|
+
# RSSMRAULA0MF205X
|
118
|
+
# RSSMRAULAL1F205Q
|
59
119
|
# RSSMRA80A0MFNLRK
|
120
|
+
# RSSMRA80AL1FNLRD
|
121
|
+
# RSSMRA8LA01FNLRD
|
122
|
+
# RSSMRAU0A01FNLRP
|
123
|
+
# RSSMRA80ALMF2LRG
|
124
|
+
# RSSMRA8LA0MF2LRG
|
125
|
+
# RSSMRAU0A0MF2LRS
|
126
|
+
# RSSMRA8LAL1F2LRZ
|
127
|
+
# RSSMRAU0AL1F2LRL
|
128
|
+
# RSSMRAULA01F2LRL
|
129
|
+
# RSSMRA80ALMFN0RK
|
130
|
+
# RSSMRA8LA0MFN0RK
|
131
|
+
# RSSMRAU0A0MFN0RW
|
132
|
+
# RSSMRA8LAL1FN0RD
|
133
|
+
# RSSMRAU0AL1FN0RP
|
134
|
+
# RSSMRAULA01FN0RP
|
135
|
+
# RSSMRA8LALMF20RG
|
136
|
+
# RSSMRAU0ALMF20RS
|
137
|
+
# RSSMRAULA0MF20RS
|
138
|
+
# RSSMRAULAL1F20RL
|
139
|
+
# RSSMRA80ALMFNL5A
|
140
|
+
# RSSMRA8LA0MFNL5A
|
141
|
+
# RSSMRAU0A0MFNL5M
|
142
|
+
# RSSMRA8LAL1FNL5T
|
143
|
+
# RSSMRAU0AL1FNL5F
|
144
|
+
# RSSMRAULA01FNL5F
|
145
|
+
# RSSMRA8LALMF2L5W
|
146
|
+
# RSSMRAU0ALMF2L5I
|
147
|
+
# RSSMRAULA0MF2L5I
|
148
|
+
# RSSMRAULAL1F2L5B
|
149
|
+
# RSSMRA8LALMFN05A
|
150
|
+
# RSSMRAU0ALMFN05M
|
151
|
+
# RSSMRAULA0MFN05M
|
152
|
+
# RSSMRAULAL1FN05F
|
153
|
+
# RSSMRAULALMF205I
|
60
154
|
# RSSMRA80ALMFNLRV
|
155
|
+
# RSSMRA8LA0MFNLRV
|
156
|
+
# RSSMRAU0A0MFNLRH
|
157
|
+
# RSSMRA8LAL1FNLRO
|
158
|
+
# RSSMRAU0AL1FNLRA
|
159
|
+
# RSSMRAULA01FNLRA
|
160
|
+
# RSSMRA8LALMF2LRR
|
161
|
+
# RSSMRAU0ALMF2LRD
|
162
|
+
# RSSMRAULA0MF2LRD
|
163
|
+
# RSSMRAULAL1F2LRW
|
164
|
+
# RSSMRA8LALMFN0RV
|
165
|
+
# RSSMRAU0ALMFN0RH
|
166
|
+
# RSSMRAULA0MFN0RH
|
167
|
+
# RSSMRAULAL1FN0RA
|
168
|
+
# RSSMRAULALMF20RD
|
169
|
+
# RSSMRA8LALMFNL5L
|
170
|
+
# RSSMRAU0ALMFNL5X
|
171
|
+
# RSSMRAULA0MFNL5X
|
172
|
+
# RSSMRAULAL1FNL5Q
|
173
|
+
# RSSMRAULALMF2L5T
|
174
|
+
# RSSMRAULALMFN05X
|
61
175
|
# RSSMRA8LALMFNLRG
|
176
|
+
# RSSMRAU0ALMFNLRS
|
177
|
+
# RSSMRAULA0MFNLRS
|
178
|
+
# RSSMRAULAL1FNLRL
|
179
|
+
# RSSMRAULALMF2LRO
|
180
|
+
# RSSMRAULALMFN0RS
|
181
|
+
# RSSMRAULALMFNL5I
|
62
182
|
# RSSMRAULALMFNLRD
|
63
183
|
# ],
|
64
184
|
# raw: {
|
data/lib/itax_code/encoder.rb
CHANGED
data/lib/itax_code/omocode.rb
CHANGED
@@ -19,7 +19,7 @@ module ItaxCode
|
|
19
19
|
# @return [Array]
|
20
20
|
def omocodes
|
21
21
|
[original_omocode] + utils.omocodia_indexes_combos.map do |combo|
|
22
|
-
omocode(combo, ->(char) { utils.omocodia_encode(char) })
|
22
|
+
omocode(original_omocode, combo, ->(char) { utils.omocodia_encode(char) })
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -28,13 +28,15 @@ module ItaxCode
|
|
28
28
|
#
|
29
29
|
# @return [String]
|
30
30
|
def original_omocode
|
31
|
-
|
31
|
+
@original_omocode ||= omocode(
|
32
|
+
tax_code, utils.omocodia_indexes, ->(char) { utils.omocodia_decode(char) }
|
33
|
+
)
|
32
34
|
end
|
33
35
|
|
34
36
|
private
|
35
37
|
|
36
|
-
def omocode(indexes, translation)
|
37
|
-
chars =
|
38
|
+
def omocode(code, indexes, translation)
|
39
|
+
chars = code[0..14].chars
|
38
40
|
|
39
41
|
indexes.each do |index|
|
40
42
|
chars[index] = translation.call(chars[index])
|
data/lib/itax_code/parser.rb
CHANGED
@@ -13,14 +13,18 @@ module ItaxCode
|
|
13
13
|
#
|
14
14
|
# @return [Hash]
|
15
15
|
class Parser
|
16
|
-
|
17
|
-
|
16
|
+
Error = Class.new(StandardError)
|
17
|
+
NoTaxCodeError = Class.new(Error)
|
18
|
+
InvalidControlInternalNumberError = Class.new(Error)
|
19
|
+
InvalidTaxCodeError = Class.new(Error)
|
18
20
|
|
19
21
|
def initialize(tax_code, utils = Utils.new)
|
20
|
-
@tax_code = tax_code
|
21
|
-
@utils = utils
|
22
|
+
@tax_code = tax_code.upcase
|
22
23
|
raise NoTaxCodeError if @tax_code.blank?
|
23
24
|
raise InvalidTaxCodeError unless Validator.standard_length?(@tax_code)
|
25
|
+
|
26
|
+
@utils = utils
|
27
|
+
raise InvalidControlInternalNumberError if raw[:cin] != @utils.encode_cin(tax_code)
|
24
28
|
end
|
25
29
|
|
26
30
|
# Decodes the tax code into its components.
|
data/lib/itax_code/utils.rb
CHANGED
@@ -27,24 +27,49 @@ module ItaxCode
|
|
27
27
|
%w[a e i o u]
|
28
28
|
end
|
29
29
|
|
30
|
-
def
|
30
|
+
def cin
|
31
31
|
{
|
32
|
-
"0"
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
"
|
41
|
-
|
42
|
-
|
32
|
+
"0" => [0, 1],
|
33
|
+
"1" => [1, 0],
|
34
|
+
"2" => [2, 5],
|
35
|
+
"3" => [3, 7],
|
36
|
+
"4" => [4, 9],
|
37
|
+
"5" => [5, 13],
|
38
|
+
"6" => [6, 15],
|
39
|
+
"7" => [7, 17],
|
40
|
+
"8" => [8, 19],
|
41
|
+
"9" => [9, 21],
|
42
|
+
"A" => [0, 1],
|
43
|
+
"B" => [1, 0],
|
44
|
+
"C" => [2, 5],
|
45
|
+
"D" => [3, 7],
|
46
|
+
"E" => [4, 9],
|
47
|
+
"F" => [5, 13],
|
48
|
+
"G" => [6, 15],
|
49
|
+
"H" => [7, 17],
|
50
|
+
"I" => [8, 19],
|
51
|
+
"J" => [9, 21],
|
52
|
+
"K" => [10, 2],
|
53
|
+
"L" => [11, 4],
|
54
|
+
"M" => [12, 18],
|
55
|
+
"N" => [13, 20],
|
56
|
+
"O" => [14, 11],
|
57
|
+
"P" => [15, 3],
|
58
|
+
"Q" => [16, 6],
|
59
|
+
"R" => [17, 8],
|
60
|
+
"S" => [18, 12],
|
61
|
+
"T" => [19, 14],
|
62
|
+
"U" => [20, 16],
|
63
|
+
"V" => [21, 10],
|
64
|
+
"W" => [22, 22],
|
65
|
+
"X" => [23, 25],
|
66
|
+
"Y" => [24, 24],
|
67
|
+
"Z" => [25, 23]
|
43
68
|
}
|
44
69
|
end
|
45
70
|
|
46
71
|
def cin_remainders
|
47
|
-
"
|
72
|
+
("A".."Z").to_a
|
48
73
|
end
|
49
74
|
|
50
75
|
def omocodia
|
@@ -89,13 +114,13 @@ module ItaxCode
|
|
89
114
|
end
|
90
115
|
|
91
116
|
def encode_cin(code)
|
92
|
-
|
117
|
+
cin_tot = 0
|
93
118
|
|
94
|
-
code.
|
95
|
-
|
119
|
+
code[0..14].each_char.with_index do |char, i|
|
120
|
+
cin_tot += cin[char][((i + 1) % 2).to_i]
|
96
121
|
end
|
97
122
|
|
98
|
-
cin_remainders[
|
123
|
+
cin_remainders[cin_tot % 26]
|
99
124
|
end
|
100
125
|
|
101
126
|
def cities
|
data/lib/itax_code/validator.rb
CHANGED
@@ -5,35 +5,76 @@ module ItaxCode
|
|
5
5
|
#
|
6
6
|
# @param [Hash] data The user input data
|
7
7
|
class Validator
|
8
|
-
LENGTH
|
8
|
+
LENGTH = 16
|
9
|
+
REQUIRED_KEYS = %i[surname name gender birthdate birthplace].freeze
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
# @param [String] tax_code The pre-computed tax code
|
12
|
+
# @param [Hash] data The optional user attributes
|
13
|
+
#
|
14
|
+
def initialize(tax_code, data = {})
|
15
|
+
@tax_code = tax_code
|
16
|
+
@data = data
|
12
17
|
end
|
13
18
|
|
14
19
|
class << self
|
15
20
|
# Checks the tax code standard length against user
|
16
|
-
# and business
|
21
|
+
# and business fiscal code standards.
|
17
22
|
#
|
18
|
-
# @param [String]
|
23
|
+
# @param [String] tax_code The tax code
|
19
24
|
#
|
20
25
|
# @return [true, false]
|
21
|
-
def standard_length?(
|
22
|
-
|
26
|
+
def standard_length?(tax_code)
|
27
|
+
tax_code.length == LENGTH
|
23
28
|
end
|
24
29
|
end
|
25
30
|
|
26
|
-
# Checks pre
|
27
|
-
#
|
28
|
-
# @param [String] tax_code The pre computed tax code
|
31
|
+
# Checks pre-computed tax code validity against newly encoded tax code.
|
29
32
|
#
|
30
33
|
# @return [true, false]
|
31
|
-
def valid?
|
32
|
-
|
34
|
+
def valid?
|
35
|
+
encoded_tax_code == tax_code
|
33
36
|
end
|
34
37
|
|
35
38
|
private
|
36
39
|
|
37
|
-
|
40
|
+
attr_reader :tax_code, :data
|
41
|
+
|
42
|
+
# Encodes the tax code from the given 'data' hash, also backfilling missing information
|
43
|
+
# by decoding the pre-computed tax code.
|
44
|
+
#
|
45
|
+
# @return [String, nil] The encoded tax code or nil if decoding the tax code fails
|
46
|
+
def encoded_tax_code
|
47
|
+
if partial_data?
|
48
|
+
decoded_tax_code ? backfill_data! : return
|
49
|
+
end
|
50
|
+
|
51
|
+
Encoder.new(data).encode
|
52
|
+
end
|
53
|
+
|
54
|
+
# Decodes the given tax code to backfill possibly missing data in the 'data' hash.
|
55
|
+
# If the decode fails, it means that the provided tax code is not valid.
|
56
|
+
#
|
57
|
+
# @return [Hash, nil] The decoded hash or nil if the tax code is not valid
|
58
|
+
def decoded_tax_code
|
59
|
+
@decoded_tax_code ||= begin
|
60
|
+
Parser.new(tax_code).decode
|
61
|
+
rescue Parser::Error
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def partial_data?
|
67
|
+
REQUIRED_KEYS.any? { |required_key| data[required_key].blank? }
|
68
|
+
end
|
69
|
+
|
70
|
+
def backfill_data!
|
71
|
+
data.tap do |hash|
|
72
|
+
hash[:surname] ||= decoded_tax_code[:raw][:surname]
|
73
|
+
hash[:name] ||= decoded_tax_code[:raw][:name]
|
74
|
+
hash[:gender] ||= decoded_tax_code[:gender]
|
75
|
+
hash[:birthdate] ||= decoded_tax_code[:birthdate]
|
76
|
+
hash[:birthplace] ||= decoded_tax_code[:birthplace][:code]
|
77
|
+
end
|
78
|
+
end
|
38
79
|
end
|
39
80
|
end
|
data/lib/itax_code/version.rb
CHANGED
data/lib/itax_code.rb
CHANGED
@@ -9,6 +9,8 @@ require "itax_code/parser"
|
|
9
9
|
require "itax_code/validator"
|
10
10
|
|
11
11
|
module ItaxCode
|
12
|
+
Error = Class.new(StandardError)
|
13
|
+
|
12
14
|
class << self
|
13
15
|
# Encodes user tax code.
|
14
16
|
#
|
@@ -38,7 +40,7 @@ module ItaxCode
|
|
38
40
|
# encoded from user informations.
|
39
41
|
#
|
40
42
|
# @param [String] tax_code The user tax code
|
41
|
-
# @param [Hash] data The user attributes
|
43
|
+
# @param [Hash] data The optional user attributes
|
42
44
|
#
|
43
45
|
# @option data [String] :surname
|
44
46
|
# @option data [String] :name
|
@@ -47,10 +49,8 @@ module ItaxCode
|
|
47
49
|
# @option data [String] :birthplace
|
48
50
|
#
|
49
51
|
# @return [Boolean]
|
50
|
-
def valid?(tax_code, data)
|
51
|
-
Validator.new(data).valid?
|
52
|
+
def valid?(tax_code, data = {})
|
53
|
+
Validator.new(tax_code, data).valid?
|
52
54
|
end
|
53
55
|
end
|
54
|
-
|
55
|
-
class Error < StandardError; end
|
56
56
|
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.
|
4
|
+
version: 1.0.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: 2023-08-
|
11
|
+
date: 2023-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -24,7 +24,7 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
description:
|
27
|
+
description:
|
28
28
|
email:
|
29
29
|
- mttrss5@gmail.com
|
30
30
|
executables: []
|
@@ -65,7 +65,7 @@ metadata:
|
|
65
65
|
source_code_uri: https://github.com/matteoredz/itax-code
|
66
66
|
changelog_uri: https://github.com/matteoredz/itax-code/CHANGELOG.md
|
67
67
|
rubygems_mfa_required: 'false'
|
68
|
-
post_install_message:
|
68
|
+
post_install_message:
|
69
69
|
rdoc_options: []
|
70
70
|
require_paths:
|
71
71
|
- lib
|
@@ -80,8 +80,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
80
|
- !ruby/object:Gem::Version
|
81
81
|
version: '0'
|
82
82
|
requirements: []
|
83
|
-
rubygems_version: 3.
|
84
|
-
signing_key:
|
83
|
+
rubygems_version: 3.1.2
|
84
|
+
signing_key:
|
85
85
|
specification_version: 4
|
86
86
|
summary: Encode and decode Italian tax code (Codice Fiscale)
|
87
87
|
test_files: []
|