tin_valid 0.1.1 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b248c0be6699ce56b48b082c320833ff8cb5594a62762d298ea66315d8d7555b
4
- data.tar.gz: a04549a7599fbadd881f1f905e2c13235d83a3e1d4b7bd8d79dc16393cd18465
3
+ metadata.gz: 2a4dc099cefbd5653c35bb0a8d78061e7e9239a917f2f872e7036651c429c014
4
+ data.tar.gz: c540ebe0de3b7f4c69c65c2d05b0d2d67b1beca905e4ee2e99416b361d4991c9
5
5
  SHA512:
6
- metadata.gz: 608e79cfe16d11cd236c02a4b5dffa9062a4b26b0f8816c2e9a9da350471917a5cc7ac6802202223ec6936f82cc0f91f9b820118a9c56868b2c6c4a9eaa8f67f
7
- data.tar.gz: a17c2624d59049524fbeb5b8adec5263dd6c4009d7bb90c594ad01c499c990a6784515a195bbd3a16148278c32f524b71067b6f0095020dccd24ae5a65987da4
6
+ metadata.gz: d34baae639710a1f82adc36eedce1bb6b961e7fbe3f2128d091b5c61f6956276dc047207d62ac46325577028e5db562a955a4603056d0096469ce48e7698adbf
7
+ data.tar.gz: 97e1d3b264372400e0575a30d15087d53bb3220c49e2126a5aa24417407b806e8018e4bf26cef7e7ff8a1d749e74c907801a8b3e2ae52ddae85008394682ba28
data/.rspec CHANGED
@@ -1,3 +1,2 @@
1
- --format documentation
2
1
  --color
3
2
  --require spec_helper
data/.rubocop.yml CHANGED
@@ -8,6 +8,11 @@ AllCops:
8
8
 
9
9
  # Layout
10
10
 
11
+ Layout/LineLength:
12
+ Max: 80
13
+ Exclude:
14
+ - bin/rspec
15
+
11
16
  Layout/MultilineMethodCallIndentation:
12
17
  # On multiline calls, indent starting from the receiver.
13
18
  # E.g.:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.1.0] - 2025-04-18
4
+
5
+ Features:
6
+ - Add Finland 🇫🇮
7
+ - Add France 🇫🇷
8
+
9
+ Fixes:
10
+ - Test against clearly invalid codes 00000… and 123456…
11
+ - Check that all dates are in the past
12
+
13
+ ## [1.0.0] - 2025-04-17
14
+
15
+ Features:
16
+ - Add Italy 🇮🇹
17
+ - Add Latvia 🇱🇻
18
+ - Add Luxembourg 🇱🇺
19
+ - Add Lithuania 🇱🇹
20
+ - Add Malta 🇲🇹
21
+ - Add Netherlands 🇳🇱
22
+ - Add Poland 🇵🇱
23
+ - Add Portugal 🇵🇹
24
+ - Add Romania 🇷🇴
25
+ - Add Slovakia 🇸🇰
26
+ - Add Slovenia 🇸🇮
27
+ - Add Spain 🇪🇸
28
+ - Add United Kingdom 🇬🇧
29
+
3
30
  ## [0.1.1] - 2025-04-15
4
31
 
5
32
  Features:
@@ -7,7 +34,6 @@ Features:
7
34
  - Add Greece 🇬🇷
8
35
  - Add Hungary 🇭🇺
9
36
  - Add Ireland 🇮🇪
10
- - Add #normalized to Austria 🇦🇹
11
37
 
12
38
  ## [0.1.0] - 2025-04-14
13
39
 
data/README.md CHANGED
@@ -10,11 +10,26 @@ Validate Tax Identification Numbers (TINs) for the following European countries:
10
10
  - Czechia 🇨🇿
11
11
  - Denmark 🇩🇰
12
12
  - Estonia 🇪🇪
13
+ - Finland 🇫🇮
14
+ - France 🇫🇷
13
15
  - Germany 🇩🇪
14
16
  - Greece 🇬🇷
15
17
  - Hungary 🇭🇺
16
18
  - Ireland 🇮🇪
19
+ - Italy 🇮🇹
20
+ - Latvia 🇱🇻
21
+ - Lithuania 🇱🇹
22
+ - Luxembourg 🇱🇺
23
+ - Malta 🇲🇹
24
+ - Netherlands 🇳🇱
25
+ - Poland 🇵🇱
26
+ - Portugal 🇵🇹
27
+ - Romania 🇷🇴
28
+ - Slovakia 🇸🇰
29
+ - Slovenia 🇸🇮
30
+ - Spain 🇪🇸
17
31
  - Sweden 🇸🇪
32
+ - United Kingdom 🇬🇧
18
33
 
19
34
  See also the [descriptions of the structure provided by the European
20
35
  Union](https://taxation-customs.ec.europa.eu/online-services/online-services-and-databases-taxation/taxpayer-identification-number-tin_en).
@@ -38,8 +53,7 @@ gem install tin_valid
38
53
 
39
54
  ```rb
40
55
  # Austria
41
- TinValid::AustriaTin.new(tin: "93-173/6581").valid? # => true
42
- TinValid::AustriaTin.new(tin: "93-173/6581").normalized # => "931736581"
56
+ TinValid::AustriaTin.new(tin: "").valid? # => true
43
57
 
44
58
  # Belgium
45
59
  # Optional birth_date
@@ -68,9 +82,74 @@ TinValid::DenmarkTin.new(tin: "…", birth_date: Date.new(…)).valid?
68
82
  # Optional birth_date
69
83
  TinValid::EstoniaTin.new(tin: "…", birth_date: Date.new(…)).valid?
70
84
 
85
+ # Finland
86
+ # Optional birth_date
87
+ TinValid::FinlandTin.new(tin: "…", birth_date: Date.new(…)).valid?
88
+
89
+ # France
90
+ TinValid::FranceTin.new(tin: "…").valid?
91
+
92
+ # Germany
93
+ TinValid::GermanyTin.new(tin: "…").valid?
94
+
95
+ # Greece
96
+ TinValid::GreeceTin.new(tin: "…").valid?
97
+
98
+ # Hungary
99
+ TinValid::HungaryTin.new(tin: "…").valid?
100
+
101
+ # Ireland
102
+ TinValid::IrelandTin.new(tin: "…").valid?
103
+
104
+ # Italy
105
+ # Optional birth_date
106
+ TinValid::ItalyTin.new(tin: "…", birth_date: Date.new(…)).valid?
107
+
108
+ # Latvia
109
+ # Optional birth_date
110
+ TinValid::LatviaTin.new(tin: "…", birth_date: Date.new(…)).valid?
111
+
112
+ # Lithuania
113
+ # Optional birth_date
114
+ TinValid::LithuaniaTin.new(tin: "…", birth_date: Date.new(…)).valid?
115
+
116
+ # Luxembourg
117
+ # Optional birth_date
118
+ TinValid::LuxembourgTin.new(tin: "…", birth_date: Date.new(…)).valid?
119
+
120
+ # Malta
121
+ TinValid::MaltaTin.new(tin: "…").valid?
122
+
123
+ # Netherlands
124
+ TinValid::NetherlandsTin.new(tin: "…").valid?
125
+
126
+ # Poland
127
+ # Optional birth_date
128
+ TinValid::PolandTin.new(tin: "…", birth_date: Date.new(…)).valid?
129
+
130
+ # Portugal
131
+ TinValid::PortugalTin.new(tin: "…").valid?
132
+
133
+ # Romania
134
+ # Optional birth_date
135
+ TinValid::RomaniaTin.new(tin: "…", birth_date: Date.new(…)).valid?
136
+
137
+ # Slovakia
138
+ # Optional birth_date
139
+ TinValid::SlovakiaTin.new(tin: "…", birth_date: Date.new(…)).valid?
140
+
141
+ # Slovenia
142
+ TinValid::SloveniaTin.new(tin: "…").valid?
143
+
144
+ # Spain
145
+ TinValid::SpainTin.new(tin: "…").valid?
146
+
71
147
  # Sweden
72
148
  # Optional birth_date
73
149
  TinValid::SwedenTin.new(tin: "…", birth_date: Date.new(…)).valid?
150
+
151
+ # United Kingdom
152
+ TinValid::UnitedKingdomTin.new(tin: "…").valid?
74
153
  ```
75
154
 
76
155
  ## Development
@@ -10,6 +10,7 @@ module TinValid
10
10
 
11
11
  def valid?
12
12
  return false unless MATCHER.match?(normalized)
13
+ return false if %w[000000000 123456789].include?(normalized)
13
14
 
14
15
  normalized[-1] == check
15
16
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module TinValid
4
4
  class BelgiumTin
5
+ include TinValid::Helpers
6
+
5
7
  def initialize(tin:, birth_date: nil)
6
8
  @tin = tin
7
9
  @birth_date = birth_date
@@ -37,6 +39,15 @@ module TinValid
37
39
  def check = match[:check].to_i
38
40
 
39
41
  def valid_check?(year, month, day, number)
42
+ # A month (in the range 00...12, 00 is acceptable for person not born in
43
+ # Belgium and with an uncertain date of birth).
44
+ month = 1 if month == "00"
45
+
46
+ # A day of month (in the range 00...31 depending on month and year, 00 is
47
+ # acceptable for person not born in Belgium and with an uncertain date of
48
+ # birth).
49
+ day = 1 if day == "00"
50
+
40
51
  tin_date = date(year, month, day)
41
52
  return false if tin_date.nil?
42
53
  return false if birth_date && birth_date != tin_date
@@ -54,20 +65,5 @@ module TinValid
54
65
  #
55
66
  # 2. 97 - remainder of the previous division is the check number
56
67
  def digit_check(number) = 97 - (number.to_i % 97)
57
-
58
- def date(year, month, day)
59
- # A month (in the range 00...12, 00 is acceptable for person not born in
60
- # Belgium and with an uncertain date of birth).
61
- month = 1 if month == "00"
62
-
63
- # A day of month (in the range 00...31 depending on month and year, 00 is
64
- # acceptable for person not born in Belgium and with an uncertain date of
65
- # birth).
66
- day = 1 if day == "00"
67
-
68
- Date.new(year.to_i, month.to_i, day.to_i)
69
- rescue Date::Error
70
- nil
71
- end
72
68
  end
73
69
  end
@@ -1,11 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TinValid
4
- class BulgariaTin < Data.define(:tin, :birth_date)
4
+ class BulgariaTin
5
+ include TinValid::Helpers
6
+
5
7
  def initialize(tin:, birth_date: nil)
6
- super
8
+ @tin = tin
9
+ @birth_date = birth_date
7
10
  end
8
11
 
12
+ attr_reader :tin, :birth_date
13
+
9
14
  def valid?
10
15
  match = MATCHER.match(tin)
11
16
  return false unless match
@@ -37,9 +42,9 @@ module TinValid
37
42
  day = day.to_i
38
43
 
39
44
  if birth_date.nil?
40
- past_date?("18#{year}", month - 20, day) ||
41
- past_date?("19#{year}", month, day) ||
42
- past_date?("20#{year}", month - 40, day)
45
+ date("18#{year}", month - 20, day) ||
46
+ date("19#{year}", month, day) ||
47
+ date("20#{year}", month - 40, day)
43
48
  elsif birth_year < 1900
44
49
  birth_date == date("18#{year}", month - 20, day)
45
50
  elsif birth_year < 2000
@@ -53,17 +58,6 @@ module TinValid
53
58
 
54
59
  def birth_year = birth_date.year
55
60
 
56
- def past_date?(year, month, day)
57
- found_date = date(year, month, day)
58
- found_date && found_date < Date.today
59
- end
60
-
61
- def date(year, month, day)
62
- Date.new(year.to_i, month.to_i, day.to_i)
63
- rescue Date::Error
64
- nil
65
- end
66
-
67
61
  def check
68
62
  weights = [2, 4, 8, 5, 10, 9, 7, 3, 6]
69
63
 
@@ -1,7 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TinValid
4
- class CroatiaTin < Data.define(:tin)
4
+ class CroatiaTin
5
+ def initialize(tin:)
6
+ @tin = tin
7
+ end
8
+
9
+ attr_reader :tin
10
+
5
11
  def valid?
6
12
  return false unless /\A[0-9]{11}\z/.match?(tin)
7
13
 
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TinValid
4
- class CyprusTin < Data.define(:tin, :kind)
4
+ class CyprusTin
5
5
  def initialize(tin:, kind: nil)
6
- super
6
+ @tin = tin
7
+ @kind = kind
7
8
  end
8
9
 
10
+ attr_reader :tin, :kind
11
+
9
12
  def valid?
10
13
  matcher.match?(tin) && check == tin[-1]
11
14
  end
@@ -1,11 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TinValid
4
- class CzechiaTin < Data.define(:tin, :birth_date)
4
+ class CzechiaTin
5
+ include TinValid::Helpers
6
+
5
7
  def initialize(tin:, birth_date: nil)
6
- super
8
+ @tin = tin
9
+ @birth_date = birth_date
7
10
  end
8
11
 
12
+ attr_reader :tin, :birth_date
13
+
9
14
  def valid? = valid_v1? || valid_v2?
10
15
 
11
16
  private
@@ -33,6 +38,7 @@ module TinValid
33
38
  def valid_v1?
34
39
  match = MATCHER_V1.match(tin)
35
40
  return false unless match
41
+ return false if tin == "000000000"
36
42
  return true if birth_date.nil?
37
43
  return false if year_of_birth >= 1954
38
44
 
@@ -46,11 +52,10 @@ module TinValid
46
52
  birth_date == date(year, month, match[:day])
47
53
  end
48
54
 
49
- # rubocop:disable Metrics/AbcSize
50
- # rubocop:disable Metrics/MethodLength
51
55
  def valid_v2?
52
56
  match = MATCHER_V2.match(tin)
53
57
  return false unless match
58
+ return false if tin == "0000000000"
54
59
  return true if birth_date.nil?
55
60
  return false if year_of_birth < 1954
56
61
 
@@ -59,30 +64,26 @@ module TinValid
59
64
  # 54 - 99 for people born between 1954 and 1999.
60
65
  year = "#{birth_century}#{match[:year]}"
61
66
 
62
- # Month (in the range 1...12 only for men) or month + 20 (in the range
63
- # 21…32 only for men) or month + 50 (in the range 51...62 only for women)
64
- # or month + 70 (in the range 71…82 only for women).
65
- month = match[:month].to_i
66
- if month > 70
67
- month -= 70
68
- elsif month > 50
69
- month -= 50
70
- elsif month > 20
71
- month -= 20
72
- end
73
-
74
- birth_date == date(year, month, match[:day])
67
+ birth_date == date(year, month_integer(match[:month]), match[:day])
75
68
  end
76
- # rubocop:enable Metrics/AbcSize
77
- # rubocop:enable Metrics/MethodLength
78
69
 
79
70
  def year_of_birth = birth_date&.year
80
71
  def birth_century = birth_date.strftime("%Y")[..1]
81
72
 
82
- def date(year, month, day)
83
- Date.new(year.to_i, month.to_i, day.to_i)
84
- rescue Date::Error
85
- nil
73
+ # Month (in the range 1...12 only for men) or month + 20 (in the range
74
+ # 21…32 only for men) or month + 50 (in the range 51...62 only for women)
75
+ # or month + 70 (in the range 71…82 only for women).
76
+ def month_integer(number)
77
+ number = number.to_i
78
+ if number > 70
79
+ number - 70
80
+ elsif number > 50
81
+ number - 50
82
+ elsif number > 20
83
+ number - 20
84
+ else
85
+ number
86
+ end
86
87
  end
87
88
  end
88
89
  end
@@ -1,14 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TinValid
4
- class DenmarkTin < Data.define(:tin, :birth_date)
4
+ class DenmarkTin
5
+ include TinValid::Helpers
6
+
5
7
  def initialize(tin:, birth_date: nil)
6
- super
8
+ @tin = tin
9
+ @birth_date = birth_date
7
10
  end
8
11
 
12
+ attr_reader :tin, :birth_date
13
+
14
+ # rubocop:disable Metrics/AbcSize
9
15
  def valid?
10
16
  match = MATCHER.match(tin)
11
17
  return false unless match
18
+ return false if tin == "0000000000"
12
19
 
13
20
  if birth_date
14
21
  year = "#{birth_century}#{match[:year]}"
@@ -19,6 +26,7 @@ module TinValid
19
26
 
20
27
  match[:check].to_i == checksum
21
28
  end
29
+ # rubocop:enable Metrics/AbcSize
22
30
 
23
31
  private
24
32
 
@@ -38,12 +46,6 @@ module TinValid
38
46
  def birth_century = birth_date.strftime("%Y")[..1]
39
47
  def birth_year = birth_date.year
40
48
 
41
- def date(year, month, day)
42
- Date.new(year.to_i, month.to_i, day.to_i)
43
- rescue Date::Error
44
- nil
45
- end
46
-
47
49
  def checksum
48
50
  # 1. Multiply the values of each position by the corresponding weight:
49
51
  weights =
@@ -1,11 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TinValid
4
- class EstoniaTin < Data.define(:tin, :birth_date)
4
+ class EstoniaTin
5
+ include TinValid::Helpers
6
+
5
7
  def initialize(tin:, birth_date: nil)
6
- super
8
+ @tin = tin
9
+ @birth_date = birth_date
7
10
  end
8
11
 
12
+ attr_reader :tin, :birth_date
13
+
9
14
  def valid?
10
15
  match = MATCHER.match(tin)
11
16
  return false unless match
@@ -36,12 +41,6 @@ module TinValid
36
41
  def birth_century = birth_date.strftime("%Y")[..1]
37
42
  def birth_year = birth_date.year
38
43
 
39
- def date(year, month, day)
40
- Date.new(year.to_i, month.to_i, day.to_i)
41
- rescue Date::Error
42
- nil
43
- end
44
-
45
44
  def checksum
46
45
  # 1. Multiply the values of each position by the corresponding weight:
47
46
  # 2. Add up the results of the above multiplications;
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TinValid
4
+ class FinlandTin
5
+ include TinValid::Helpers
6
+
7
+ def initialize(tin:, birth_date: nil)
8
+ @tin = tin
9
+ @birth_date = birth_date
10
+ end
11
+
12
+ attr_reader :tin, :birth_date
13
+
14
+ def valid?
15
+ match = MATCHER.match(tin)
16
+ return false unless match
17
+
18
+ tin_date = date(
19
+ "#{tin_century(match[:century])}#{match[:year]}",
20
+ match[:month],
21
+ match[:day],
22
+ )
23
+ return false unless tin_date
24
+ return false if birth_date && birth_date != tin_date
25
+
26
+ tin[-1] == check
27
+ end
28
+
29
+ private
30
+
31
+ MATCHER = %r{
32
+ \A
33
+ (?<day>[0-3][0-9])
34
+ (?<month>[0-1][0-9])
35
+ (?<year>[0-9][0-9])
36
+ (?<century>[-+A-FU-Y])
37
+ [0-9]{3}
38
+ [0-9A-Z]
39
+ \z
40
+ }x
41
+ private_constant :MATCHER
42
+
43
+ def tin_century(character)
44
+ case character
45
+ when "+" then 18
46
+ when "-", "U", "V", "W", "X", "Y" then 19
47
+ else 20
48
+ end
49
+ end
50
+
51
+ def check
52
+ # 1. Concatenate C1, C2, C3, C4, C5, C6, C8, C9, C10
53
+ # (warning: C7 is not part of the check digit);
54
+ number = "#{tin[0..5]}#{tin[7..9]}".to_i
55
+
56
+ # 2. Calculate the modulo 31 of the abovementioned number;
57
+ remainder = number % 31
58
+
59
+ # 4. The result of calculating modulo 31 will give as a result a number,
60
+ # which will provide the check mark through the following table:
61
+ case remainder
62
+ when ..9 then remainder.to_s
63
+ when ..15 then (remainder + 55).chr
64
+ when 16 then "H"
65
+ when ..21 then (remainder + 57).chr
66
+ when 21 then "P"
67
+ else (remainder + 59).chr
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TinValid
4
+ class FranceTin
5
+ def initialize(tin:)
6
+ @tin = tin
7
+ end
8
+
9
+ attr_reader :tin
10
+
11
+ def valid?
12
+ return false unless /\A[0-3][0-9]{12}\z/.match?(tin)
13
+ return false if tin == "0000000000000"
14
+
15
+ tin[-3..].to_i == check
16
+ end
17
+
18
+ private
19
+
20
+ def check
21
+ # 1. Concatenate C1, C2, C3, C4, C5, C6, C7, C8, C9, C10;
22
+ # 2. Get modulo 511 of the result of the previous result;
23
+ # 3. Check digit = remainder if remainder < 100, C11 = 0
24
+ # (if remainder < 10, C11 = 0 and C12 = 0).
25
+ tin[..-4].to_i % 511
26
+ end
27
+ end
28
+ end
@@ -1,7 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TinValid
4
- class GermanyTin < Data.define(:tin)
4
+ class GermanyTin
5
+ def initialize(tin:)
6
+ @tin = tin
7
+ end
8
+
9
+ attr_reader :tin
10
+
5
11
  def valid?
6
12
  valid_v1? || valid_v2?
7
13
  end
@@ -12,7 +18,9 @@ module TinValid
12
18
  # 1. 13 characters
13
19
  # 2. Only digits
14
20
  # 3. C5 is a 0
15
- /\A[0-9]{4}0[0-9]{8}\z/.match?(tin)
21
+ return false unless /\A[0-9]{4}0[0-9]{8}\z/.match?(tin)
22
+
23
+ tin.to_i != 0
16
24
  end
17
25
 
18
26
  # rubocop:disable Metrics/AbcSize
@@ -48,13 +56,16 @@ module TinValid
48
56
  # 3. Multiply the result by 2;
49
57
  result *= 2
50
58
 
51
- # 4. Take modulo 11 of the result. Update the value of variable X with the result of this operation;
59
+ # 4. Take modulo 11 of the result. Update the value of variable X with
60
+ # the result of this operation;
52
61
  x = result % 11
53
62
 
54
63
  # 5. Take C2 + X modulo 10. If result is 0, result is 10;
55
64
  # 6. Multiply the result by 2;
56
- # 7. Take modulo 11 of the result. Update the value of variable X with the result of this operation;
57
- # 8. Apply steps 5, 6 and 7 in an analogue way for digits C3 to C10. Consider that last value called Y;
65
+ # 7. Take modulo 11 of the result. Update the value of variable X with
66
+ # the result of this operation;
67
+ # 8. Apply steps 5, 6 and 7 in an analogue way for digits C3 to C10.
68
+ # Consider that last value called Y;
58
69
  x
59
70
  end
60
71
 
@@ -1,9 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TinValid
4
- class GreeceTin < Data.define(:tin)
4
+ class GreeceTin
5
+ def initialize(tin:)
6
+ @tin = tin
7
+ end
8
+
9
+ attr_reader :tin
10
+
5
11
  def valid?
6
- /\A[0-9]{9}\z/.match?(tin)
12
+ return false unless /\A[0-9]{9}\z/.match?(tin)
13
+
14
+ tin != "000000000" && tin != "123456789"
7
15
  end
8
16
  end
9
17
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TinValid
4
+ module Helpers
5
+ private
6
+
7
+ def date(year, month, day)
8
+ found_date = Date.new(year.to_i, month.to_i, day.to_i)
9
+ found_date if found_date < Date.today
10
+ rescue Date::Error
11
+ nil
12
+ end
13
+ end
14
+ end
@@ -1,7 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TinValid
4
- class HungaryTin < Data.define(:tin)
4
+ class HungaryTin
5
+ def initialize(tin:)
6
+ @tin = tin
7
+ end
8
+
9
+ attr_reader :tin
10
+
5
11
  def valid?
6
12
  return false unless /\A8[0-9]{9}\z/.match?(tin)
7
13
 
@@ -11,8 +17,6 @@ module TinValid
11
17
  private
12
18
 
13
19
  def check
14
- tin[..-2].chars
15
-
16
20
  # 1. Multiply the values of each position by the corresponding weight:
17
21
  # 2. Add up the results of the above multiplications;
18
22
  result = (1..9).each_with_index.sum { |num, i| num * tin[i].to_i }