br-utils 0.1.0 → 0.2.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 +4 -4
- data/.github/workflows/ci.yml +27 -0
- data/README.md +446 -22
- data/lib/brazilian-utils/area-code-utils.rb +60 -0
- data/lib/brazilian-utils/bank-account-utils.rb +82 -0
- data/lib/brazilian-utils/bank-utils.rb +61 -0
- data/lib/brazilian-utils/boleto-utils.rb +139 -0
- data/lib/brazilian-utils/caepf-utils.rb +91 -0
- data/lib/brazilian-utils/cbo-utils.rb +74 -0
- data/lib/brazilian-utils/cei-utils.rb +79 -0
- data/lib/brazilian-utils/cep-utils.rb +34 -1
- data/lib/brazilian-utils/certidao-utils.rb +171 -0
- data/lib/brazilian-utils/cfop-utils.rb +74 -0
- data/lib/brazilian-utils/cnae-utils.rb +104 -0
- data/lib/brazilian-utils/cnh-utils.rb +68 -15
- data/lib/brazilian-utils/cno-utils.rb +76 -0
- data/lib/brazilian-utils/cnpj-utils.rb +126 -13
- data/lib/brazilian-utils/cns-utils.rb +110 -0
- data/lib/brazilian-utils/cpf-utils.rb +14 -1
- data/lib/brazilian-utils/credit-card-utils.rb +47 -0
- data/lib/brazilian-utils/csosn-utils.rb +55 -0
- data/lib/brazilian-utils/cst-utils.rb +103 -0
- data/lib/brazilian-utils/currency-utils.rb +347 -226
- data/lib/brazilian-utils/data/area_codes.json +676 -0
- data/lib/brazilian-utils/data/banks.json +357 -0
- data/lib/brazilian-utils/data/cbo.json +1 -0
- data/lib/brazilian-utils/data/cfop.json +1 -0
- data/lib/brazilian-utils/data/cnae.json +1 -0
- data/lib/brazilian-utils/data/csosn.json +42 -0
- data/lib/brazilian-utils/data/cst.json +294 -0
- data/lib/brazilian-utils/data/legal_nature.json +900 -0
- data/lib/brazilian-utils/data/municipalities.json +1 -0
- data/lib/brazilian-utils/data/ncm.json +1 -0
- data/lib/brazilian-utils/data/states.json +218 -0
- data/lib/brazilian-utils/date-utils.rb +504 -244
- data/lib/brazilian-utils/email-utils.rb +20 -9
- data/lib/brazilian-utils/iban-utils.rb +120 -0
- data/lib/brazilian-utils/ie-utils.rb +84 -0
- data/lib/brazilian-utils/legal-nature-utils.rb +238 -235
- data/lib/brazilian-utils/legal-process-utils.rb +35 -5
- data/lib/brazilian-utils/license-plate-utils.rb +24 -4
- data/lib/brazilian-utils/municipality-utils.rb +58 -0
- data/lib/brazilian-utils/ncm-utils.rb +91 -0
- data/lib/brazilian-utils/nfe-key-utils.rb +158 -0
- data/lib/brazilian-utils/number-utils.rb +123 -0
- data/lib/brazilian-utils/passport-utils.rb +65 -0
- data/lib/brazilian-utils/phone-utils.rb +491 -272
- data/lib/brazilian-utils/pis-utils.rb +16 -1
- data/lib/brazilian-utils/pix-key-utils.rb +70 -0
- data/lib/brazilian-utils/pix-payload-utils.rb +253 -0
- data/lib/brazilian-utils/registro-profissional-utils.rb +112 -0
- data/lib/brazilian-utils/renavam-utils.rb +14 -0
- data/lib/brazilian-utils/state-utils.rb +105 -0
- data/lib/brazilian-utils/text-utils.rb +105 -0
- data/lib/brazilian-utils/vin-utils.rb +46 -0
- data/lib/brazilian-utils/voter-id-utils.rb +70 -19
- metadata +54 -2
- data/.travis.yml +0 -5
|
@@ -1,235 +1,238 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
'
|
|
26
|
-
|
|
27
|
-
'
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
#
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
#
|
|
113
|
-
#
|
|
114
|
-
#
|
|
115
|
-
#
|
|
116
|
-
#
|
|
117
|
-
#
|
|
118
|
-
#
|
|
119
|
-
#
|
|
120
|
-
#
|
|
121
|
-
#
|
|
122
|
-
#
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
#
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
#
|
|
142
|
-
#
|
|
143
|
-
#
|
|
144
|
-
#
|
|
145
|
-
#
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
#
|
|
155
|
-
#
|
|
156
|
-
#
|
|
157
|
-
# @
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
#
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
#
|
|
171
|
-
#
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
# Returns
|
|
186
|
-
#
|
|
187
|
-
#
|
|
188
|
-
#
|
|
189
|
-
#
|
|
190
|
-
#
|
|
191
|
-
#
|
|
192
|
-
#
|
|
193
|
-
#
|
|
194
|
-
#
|
|
195
|
-
#
|
|
196
|
-
#
|
|
197
|
-
#
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
#
|
|
214
|
-
#
|
|
215
|
-
# @
|
|
216
|
-
#
|
|
217
|
-
# @
|
|
218
|
-
#
|
|
219
|
-
#
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
#
|
|
226
|
-
#
|
|
227
|
-
#
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
module BrazilianUtils
|
|
4
|
+
# Utilities for consulting and validating the official *Natureza Jurídica* (Legal Nature)
|
|
5
|
+
# codes defined by IBGE/CONCLA and the Receita Federal do Brasil (RFB).
|
|
6
|
+
#
|
|
7
|
+
# The table backing this module is CONCLA's Natureza Jurídica 2021 table:
|
|
8
|
+
# 92 codes currently in force, plus a best-effort list of codes retired by
|
|
9
|
+
# past revisions (see `data/legal_nature.json`).
|
|
10
|
+
#
|
|
11
|
+
# This module offers simple lookups and validation helpers based on the
|
|
12
|
+
# official table. It does not infer the current legal/registration status
|
|
13
|
+
# of any entity.
|
|
14
|
+
#
|
|
15
|
+
# Source: https://concla.ibge.gov.br/images/concla/documentacao/CONCLA-TNJ2021-NotasExplicativas.pdf
|
|
16
|
+
module LegalNatureUtils
|
|
17
|
+
DATA_FILE = File.join(File.dirname(__FILE__), 'data', 'legal_nature.json')
|
|
18
|
+
|
|
19
|
+
# @private
|
|
20
|
+
def self.load_data
|
|
21
|
+
return @data if @data
|
|
22
|
+
|
|
23
|
+
raw = JSON.parse(File.read(DATA_FILE))
|
|
24
|
+
in_force = {}
|
|
25
|
+
raw['inForce'].each { |row| in_force[row['code']] = row }
|
|
26
|
+
retired = {}
|
|
27
|
+
raw['retired'].each { |row| retired[row['code']] = row }
|
|
28
|
+
@data = { in_force: in_force, retired: retired }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private_class_method :load_data
|
|
32
|
+
|
|
33
|
+
# Normalizes a legal nature code: strips hyphens, dots and whitespace,
|
|
34
|
+
# and requires exactly 4 digits.
|
|
35
|
+
#
|
|
36
|
+
# @param code [String, Integer] The code to normalize
|
|
37
|
+
# @return [String, nil] The normalized 4-digit code, or nil if invalid
|
|
38
|
+
#
|
|
39
|
+
# @private
|
|
40
|
+
def self.normalize(code)
|
|
41
|
+
return nil unless code.is_a?(String) || code.is_a?(Integer)
|
|
42
|
+
|
|
43
|
+
digits = code.to_s.gsub(/[-.\s]/, '')
|
|
44
|
+
digits.match?(/\A\d{4}\z/) ? digits : nil
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private_class_method :normalize
|
|
48
|
+
|
|
49
|
+
# @private
|
|
50
|
+
def self.entry_to_hash(row)
|
|
51
|
+
entry = {
|
|
52
|
+
code: row['code'],
|
|
53
|
+
description: row['description'],
|
|
54
|
+
category: { code: row['category']['code'], description: row['category']['description'] },
|
|
55
|
+
legacy: row['legacy']
|
|
56
|
+
}
|
|
57
|
+
entry[:currentCode] = row['currentCode'] if row['legacy']
|
|
58
|
+
entry
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private_class_method :entry_to_hash
|
|
62
|
+
|
|
63
|
+
# Checks if a string corresponds to a valid *Natureza Jurídica* code.
|
|
64
|
+
#
|
|
65
|
+
# Accepts both the 92 codes currently in force and the (best-effort)
|
|
66
|
+
# list of codes retired by a past revision.
|
|
67
|
+
#
|
|
68
|
+
# @param code [String] The code to be validated. Accepts "NNNN" or
|
|
69
|
+
# "NNN-N", with hyphens/dots/whitespace tolerated around the digits.
|
|
70
|
+
#
|
|
71
|
+
# @return [Boolean] Returns true if the normalized code exists in the
|
|
72
|
+
# official table (in force or retired), false otherwise.
|
|
73
|
+
#
|
|
74
|
+
# @example Valid codes
|
|
75
|
+
# is_valid("2062") #=> true (Sociedade Empresária Limitada)
|
|
76
|
+
# is_valid("206-2") #=> true (same, with hyphen)
|
|
77
|
+
#
|
|
78
|
+
# @example Invalid codes
|
|
79
|
+
# is_valid("9999") #=> false (not in official table)
|
|
80
|
+
# is_valid("abcd") #=> false (not digits)
|
|
81
|
+
# is_valid(nil) #=> false (not a string)
|
|
82
|
+
def self.is_valid(code)
|
|
83
|
+
normalized = normalize(code)
|
|
84
|
+
return false unless normalized
|
|
85
|
+
|
|
86
|
+
data = load_data
|
|
87
|
+
data[:in_force].key?(normalized) || data[:retired].key?(normalized)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
class << self
|
|
91
|
+
alias valid? is_valid
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Retrieves the description of a *Natureza Jurídica* code.
|
|
95
|
+
#
|
|
96
|
+
# @param code [String] The code to look up. Accepts "NNNN" or "NNN-N".
|
|
97
|
+
#
|
|
98
|
+
# @return [String, nil] The full description if the code is valid, otherwise nil.
|
|
99
|
+
#
|
|
100
|
+
# @example
|
|
101
|
+
# get_description("2062") #=> "Sociedade Empresária Limitada"
|
|
102
|
+
# get_description("101-5") #=> "Órgão Público do Poder Executivo Federal"
|
|
103
|
+
def self.get_description(code)
|
|
104
|
+
normalized = normalize(code)
|
|
105
|
+
return nil unless normalized
|
|
106
|
+
|
|
107
|
+
data = load_data
|
|
108
|
+
row = data[:in_force][normalized] || data[:retired][normalized]
|
|
109
|
+
row && row['description']
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Looks a legal nature code up in the IBGE/CONCLA Natureza Jurídica 2021
|
|
113
|
+
# table.
|
|
114
|
+
#
|
|
115
|
+
# @param value [String, Integer] The code to look up ("NNNN" or "NNN-N").
|
|
116
|
+
# @return [Hash, nil] `{ code:, description:, category: { code:,
|
|
117
|
+
# description: }, legacy:, currentCode: (only when legacy) }`, or nil
|
|
118
|
+
# for an unknown code.
|
|
119
|
+
#
|
|
120
|
+
# @example
|
|
121
|
+
# get("2062") #=> { code: "2062", description: "Sociedade Empresária Limitada", category: { code: "2", description: "Entidades Empresariais" }, legacy: false }
|
|
122
|
+
# get("2208") #=> { code: "2208", description: "Entidade Binacional Itaipu", ..., legacy: true, currentCode: "2275" }
|
|
123
|
+
def self.get(value)
|
|
124
|
+
normalized = normalize(value)
|
|
125
|
+
return nil unless normalized
|
|
126
|
+
|
|
127
|
+
data = load_data
|
|
128
|
+
row = data[:in_force][normalized] || data[:retired][normalized]
|
|
129
|
+
row && entry_to_hash(row)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Formats a legal nature code as `NNN-N`.
|
|
133
|
+
#
|
|
134
|
+
# The mask is applied as far as the digits go (fewer than 4 digits are
|
|
135
|
+
# returned unmasked); use {is_valid} to check the code first.
|
|
136
|
+
#
|
|
137
|
+
# @param value [String, Integer] The value to format.
|
|
138
|
+
# @param options [Hash] `:pad` left-pads the value with zeros to 4
|
|
139
|
+
# digits first.
|
|
140
|
+
# @return [String] The masked code, or as much of the mask as fits.
|
|
141
|
+
#
|
|
142
|
+
# @example
|
|
143
|
+
# format("2062") #=> "206-2"
|
|
144
|
+
# format("206-2") #=> "206-2"
|
|
145
|
+
# format("206") #=> "206"
|
|
146
|
+
def self.format(value, options = {})
|
|
147
|
+
digits = value.to_s.gsub(/\D/, '')
|
|
148
|
+
digits = digits.rjust(4, '0') if options[:pad] || options['pad']
|
|
149
|
+
return digits if digits.length < 4
|
|
150
|
+
|
|
151
|
+
"#{digits[0, 3]}-#{digits[3]}"
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Generates a random valid legal nature code (4 digits), drawn only
|
|
155
|
+
# among the 92 codes currently in force.
|
|
156
|
+
#
|
|
157
|
+
# @return [String] A randomly generated, valid legal nature code.
|
|
158
|
+
def self.generate
|
|
159
|
+
load_data[:in_force].keys.sample
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Returns a copy of the *Natureza Jurídica* table as a map from code to
|
|
163
|
+
# description.
|
|
164
|
+
#
|
|
165
|
+
# @param params [Hash] `:include_retired` also includes the retired
|
|
166
|
+
# codes (default false: only the 92 codes in force).
|
|
167
|
+
# @return [Hash<String, String>] Mapping from 4-digit codes to descriptions
|
|
168
|
+
#
|
|
169
|
+
# @example
|
|
170
|
+
# all_codes = list
|
|
171
|
+
# all_codes["2062"] #=> "Sociedade Empresária Limitada"
|
|
172
|
+
def self.list(params = {})
|
|
173
|
+
include_retired = params[:include_retired] || params['include_retired']
|
|
174
|
+
data = load_data
|
|
175
|
+
result = {}
|
|
176
|
+
data[:in_force].each { |code, row| result[code] = row['description'] }
|
|
177
|
+
data[:retired].each { |code, row| result[code] = row['description'] } if include_retired
|
|
178
|
+
result
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
class << self
|
|
182
|
+
alias list_all list
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Returns every legal nature of a CONCLA category (the first digit of
|
|
186
|
+
# the code), sorted by code.
|
|
187
|
+
#
|
|
188
|
+
# Categories: 1 Administração Pública, 2 Entidades Empresariais,
|
|
189
|
+
# 3 Entidades sem Fins Lucrativos, 4 Pessoas Físicas,
|
|
190
|
+
# 5 Organizações Internacionais e Outras Instituições Extraterritoriais.
|
|
191
|
+
#
|
|
192
|
+
# @param category [Integer, String] The category number (1-5)
|
|
193
|
+
# @param options [Hash] `:include_retired` also includes retired codes.
|
|
194
|
+
#
|
|
195
|
+
# @return [Array<Hash>] The legal natures of the category, in the same
|
|
196
|
+
# shape as {get}, sorted by code; an empty array for an unknown
|
|
197
|
+
# category.
|
|
198
|
+
def self.list_by_category(category, options = {})
|
|
199
|
+
category_str = category.to_s
|
|
200
|
+
return [] unless %w[1 2 3 4 5].include?(category_str)
|
|
201
|
+
|
|
202
|
+
include_retired = options[:include_retired] || options['include_retired']
|
|
203
|
+
data = load_data
|
|
204
|
+
|
|
205
|
+
rows = data[:in_force].values.select { |row| row['category']['code'] == category_str }
|
|
206
|
+
rows += data[:retired].values.select { |row| row['category']['code'] == category_str } if include_retired
|
|
207
|
+
|
|
208
|
+
rows.sort_by { |row| row['code'] }.map { |row| entry_to_hash(row) }
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Returns the category number for a given code.
|
|
212
|
+
#
|
|
213
|
+
# @param code [String] The code to check. Accepts "NNNN" or "NNN-N".
|
|
214
|
+
#
|
|
215
|
+
# @return [Integer, nil] The category number (1-5), or nil if invalid
|
|
216
|
+
#
|
|
217
|
+
# @example
|
|
218
|
+
# get_category("2062") #=> 2 (Entidades Empresariais)
|
|
219
|
+
# get_category("9999") #=> nil (invalid code)
|
|
220
|
+
def self.get_category(code)
|
|
221
|
+
entry = get(code)
|
|
222
|
+
entry && entry[:category][:code].to_i
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Removes legal nature formatting and keeps only digits, capped to 4 digits.
|
|
226
|
+
#
|
|
227
|
+
# @param value [String, Integer] A legal nature code, with or without formatting.
|
|
228
|
+
# @return [String] The parsed digits.
|
|
229
|
+
#
|
|
230
|
+
# @example
|
|
231
|
+
# parse("206-2") #=> "2062"
|
|
232
|
+
def self.parse(value)
|
|
233
|
+
return '' unless value.is_a?(String) || value.is_a?(Integer)
|
|
234
|
+
|
|
235
|
+
value.to_s.gsub(/\D/, '')[0, 4]
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end
|
|
@@ -131,10 +131,12 @@ module BrazilianUtils
|
|
|
131
131
|
|
|
132
132
|
# Generates a random legal process ID.
|
|
133
133
|
#
|
|
134
|
-
# @param year [Integer] The year for the legal process ID (default
|
|
134
|
+
# @param year [Integer, Hash] The year for the legal process ID (default
|
|
135
|
+
# is current year), or a single options Hash (as the contract's
|
|
136
|
+
# `GenerateProcessoJuridicoParams`) with `:year` and `:court`.
|
|
135
137
|
# The year should not be in the past.
|
|
136
138
|
# @param orgao [Integer] The judicial segment code (1-9) for the legal process ID
|
|
137
|
-
# (default is random)
|
|
139
|
+
# (default is random). Ignored when `year` is a Hash.
|
|
138
140
|
#
|
|
139
141
|
# @return [String, nil] A randomly generated legal process ID (20 digits),
|
|
140
142
|
# or nil if arguments are invalid
|
|
@@ -146,9 +148,19 @@ module BrazilianUtils
|
|
|
146
148
|
# generate()
|
|
147
149
|
# #=> "88031888120233030000" (uses current year and random orgao)
|
|
148
150
|
#
|
|
151
|
+
# generate(year: 2023, court: 5)
|
|
152
|
+
# #=> "51659517020235080562" (contract-style options Hash)
|
|
153
|
+
#
|
|
149
154
|
# generate(2022, 10)
|
|
150
155
|
# #=> nil (year in the past, orgao out of range)
|
|
151
|
-
def self.generate(year = Time.now.year, orgao =
|
|
156
|
+
def self.generate(year = Time.now.year, orgao = nil)
|
|
157
|
+
if year.is_a?(Hash)
|
|
158
|
+
options = year
|
|
159
|
+
year = options[:year] || options['year'] || Time.now.year
|
|
160
|
+
orgao = options[:court] || options[:orgao] || options['court'] || options['orgao']
|
|
161
|
+
end
|
|
162
|
+
orgao ||= rand(1..9)
|
|
163
|
+
|
|
152
164
|
return nil if year < Time.now.year
|
|
153
165
|
return nil unless (1..9).include?(orgao)
|
|
154
166
|
|
|
@@ -177,7 +189,9 @@ module BrazilianUtils
|
|
|
177
189
|
|
|
178
190
|
# Calculates the checksum (verification digits) for a legal process ID.
|
|
179
191
|
#
|
|
180
|
-
# The checksum is calculated as:
|
|
192
|
+
# The checksum is calculated as: 98 - ((basenum * 100) % 97), padded to 2 digits.
|
|
193
|
+
# This is the ISO 7064 MOD 97-10 check digit used by CNJ Resolution 65/2008,
|
|
194
|
+
# art. 1º, § 2º.
|
|
181
195
|
#
|
|
182
196
|
# @param basenum [Integer] The base number for checksum calculation
|
|
183
197
|
# (without the verification digits)
|
|
@@ -186,7 +200,7 @@ module BrazilianUtils
|
|
|
186
200
|
#
|
|
187
201
|
# @private
|
|
188
202
|
def self.checksum(basenum)
|
|
189
|
-
result =
|
|
203
|
+
result = 98 - ((basenum * 100) % 97)
|
|
190
204
|
result.to_s.rjust(2, '0')
|
|
191
205
|
end
|
|
192
206
|
|
|
@@ -236,5 +250,21 @@ module BrazilianUtils
|
|
|
236
250
|
end
|
|
237
251
|
|
|
238
252
|
private_class_method :load_legal_process_data
|
|
253
|
+
|
|
254
|
+
# Removes legal process formatting and keeps only digits, capped to 20
|
|
255
|
+
# digits.
|
|
256
|
+
#
|
|
257
|
+
# @param value [String, Integer] A legal process number, with or without
|
|
258
|
+
# the CNJ mask.
|
|
259
|
+
# @return [String] The parsed digits.
|
|
260
|
+
#
|
|
261
|
+
# @example
|
|
262
|
+
# parse("0002080-25.2012.5.15.0049") #=> "00020802520125150049"
|
|
263
|
+
# parse("00020802520125150049123") #=> "00020802520125150049"
|
|
264
|
+
def self.parse(value)
|
|
265
|
+
return '' unless value.is_a?(String) || value.is_a?(Integer)
|
|
266
|
+
|
|
267
|
+
value.to_s.gsub(/\D/, '')[0, 20]
|
|
268
|
+
end
|
|
239
269
|
end
|
|
240
270
|
end
|
|
@@ -34,17 +34,19 @@ module BrazilianUtils
|
|
|
34
34
|
# #=> "ABC1C34"
|
|
35
35
|
#
|
|
36
36
|
# convert_to_mercosul("ABC4*67")
|
|
37
|
-
# #=>
|
|
37
|
+
# #=> ""
|
|
38
38
|
def self.convert_to_mercosul(license_plate)
|
|
39
|
-
return
|
|
39
|
+
return '' unless license_plate.is_a?(String)
|
|
40
40
|
|
|
41
41
|
clean = remove_symbols(license_plate).upcase
|
|
42
|
+
return '' unless valid_old_format?(clean)
|
|
43
|
+
|
|
42
44
|
chars = clean.chars
|
|
43
|
-
|
|
45
|
+
|
|
44
46
|
# Convert the 5th character (index 4) - the first digit after the letters
|
|
45
47
|
# 0→A, 1→B, 2→C, etc.
|
|
46
48
|
chars[4] = ('A'.ord + chars[4].to_i).chr
|
|
47
|
-
|
|
49
|
+
|
|
48
50
|
chars.join
|
|
49
51
|
end
|
|
50
52
|
|
|
@@ -223,6 +225,8 @@ module BrazilianUtils
|
|
|
223
225
|
# generate('invalid')
|
|
224
226
|
# #=> nil
|
|
225
227
|
def self.generate(format = 'LLLNLNN')
|
|
228
|
+
return nil unless format.is_a?(String)
|
|
229
|
+
|
|
226
230
|
format_upper = format.upcase
|
|
227
231
|
|
|
228
232
|
return nil unless ['LLLNLNN', 'LLLNNNN'].include?(format_upper)
|
|
@@ -275,5 +279,21 @@ module BrazilianUtils
|
|
|
275
279
|
end
|
|
276
280
|
|
|
277
281
|
private_class_method :valid_mercosul?
|
|
282
|
+
|
|
283
|
+
# Removes separators from a license plate, upper-cases it and caps it to
|
|
284
|
+
# 7 characters.
|
|
285
|
+
#
|
|
286
|
+
# @param value [String] A license plate string, in any case, with or
|
|
287
|
+
# without separators.
|
|
288
|
+
# @return [String] The parsed value.
|
|
289
|
+
#
|
|
290
|
+
# @example
|
|
291
|
+
# parse("abc-1234") #=> "ABC1234"
|
|
292
|
+
# parse("abc123456") #=> "ABC1234"
|
|
293
|
+
def self.parse(value)
|
|
294
|
+
return '' unless value.is_a?(String)
|
|
295
|
+
|
|
296
|
+
remove_symbols(value).upcase[0, 7]
|
|
297
|
+
end
|
|
278
298
|
end
|
|
279
299
|
end
|