br-utils 0.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.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +120 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +348 -0
  8. data/Rakefile +6 -0
  9. data/examples/boleto_usage_example.rb +79 -0
  10. data/examples/cep_usage_example.rb +148 -0
  11. data/examples/cnh_usage_example.rb +120 -0
  12. data/examples/cnpj_usage_example.rb +227 -0
  13. data/examples/cpf_usage_example.rb +237 -0
  14. data/examples/currency_usage_example.rb +266 -0
  15. data/examples/date_usage_example.rb +259 -0
  16. data/examples/email_usage_example.rb +321 -0
  17. data/examples/legal_nature_usage_example.rb +437 -0
  18. data/examples/legal_process_usage_example.rb +444 -0
  19. data/examples/license_plate_usage_example.rb +440 -0
  20. data/examples/phone_usage_example.rb +595 -0
  21. data/examples/pis_usage_example.rb +588 -0
  22. data/examples/renavam_usage_example.rb +499 -0
  23. data/examples/voter_id_usage_example.rb +573 -0
  24. data/lib/brazilian-utils/boleto-utils.rb +176 -0
  25. data/lib/brazilian-utils/cep-utils.rb +330 -0
  26. data/lib/brazilian-utils/cnh-utils.rb +88 -0
  27. data/lib/brazilian-utils/cnpj-utils.rb +202 -0
  28. data/lib/brazilian-utils/cpf-utils.rb +192 -0
  29. data/lib/brazilian-utils/currency-utils.rb +226 -0
  30. data/lib/brazilian-utils/data/legal_process_ids.json +38 -0
  31. data/lib/brazilian-utils/date-utils.rb +244 -0
  32. data/lib/brazilian-utils/email-utils.rb +54 -0
  33. data/lib/brazilian-utils/legal-nature-utils.rb +235 -0
  34. data/lib/brazilian-utils/legal-process-utils.rb +240 -0
  35. data/lib/brazilian-utils/license-plate-utils.rb +279 -0
  36. data/lib/brazilian-utils/phone-utils.rb +272 -0
  37. data/lib/brazilian-utils/pis-utils.rb +151 -0
  38. data/lib/brazilian-utils/renavam-utils.rb +113 -0
  39. data/lib/brazilian-utils/voter-id-utils.rb +165 -0
  40. metadata +123 -0
@@ -0,0 +1,437 @@
1
+ require_relative '../lib/brazilian-utils/legal-nature-utils'
2
+
3
+ puts "=" * 80
4
+ puts "Brazilian Legal Nature Utils - Usage Examples"
5
+ puts "=" * 80
6
+ puts
7
+
8
+ # ============================================================================
9
+ # Code Validation
10
+ # ============================================================================
11
+ puts "1. CODE VALIDATION"
12
+ puts "-" * 80
13
+
14
+ valid_codes = [
15
+ '2062', # Sociedade Empresária Limitada
16
+ '1015', # Órgão Público Federal
17
+ '2305', # EIRELI
18
+ '3123', # Partido Político
19
+ '2046', # S.A. Aberta
20
+ '2054', # S.A. Fechada
21
+ '4014', # Empresa Individual Imobiliária
22
+ '5002' # Organização Internacional
23
+ ]
24
+
25
+ puts "Valid Legal Nature Codes:"
26
+ valid_codes.each do |code|
27
+ result = BrazilianUtils::LegalNatureUtils.is_valid(code)
28
+ status = result ? "✓" : "✗"
29
+ puts " #{status} #{code} - #{BrazilianUtils::LegalNatureUtils.get_description(code)}"
30
+ end
31
+ puts
32
+
33
+ # ============================================================================
34
+ # Code Validation with Hyphen Format
35
+ # ============================================================================
36
+ puts "2. CODE VALIDATION WITH HYPHEN FORMAT"
37
+ puts "-" * 80
38
+
39
+ codes_with_hyphen = [
40
+ ['2062', '206-2'],
41
+ ['1015', '101-5'],
42
+ ['2305', '230-5'],
43
+ ['3123', '312-3']
44
+ ]
45
+
46
+ puts "Comparing formats (without and with hyphen):"
47
+ codes_with_hyphen.each do |without, with_hyphen|
48
+ result1 = BrazilianUtils::LegalNatureUtils.is_valid(without)
49
+ result2 = BrazilianUtils::LegalNatureUtils.is_valid(with_hyphen)
50
+ status = (result1 && result2) ? "✓" : "✗"
51
+ puts " #{status} #{without} and #{with_hyphen}: Both valid = #{result1 && result2}"
52
+ end
53
+ puts
54
+
55
+ # ============================================================================
56
+ # Invalid Codes
57
+ # ============================================================================
58
+ puts "3. INVALID CODES"
59
+ puts "-" * 80
60
+
61
+ invalid_codes = [
62
+ '9999', # Not in table
63
+ '0000', # Not in table
64
+ '1234', # Not in table
65
+ '123', # Wrong length
66
+ 'abcd', # Not digits
67
+ '', # Empty
68
+ 'invalid' # Invalid format
69
+ ]
70
+
71
+ puts "Invalid codes:"
72
+ invalid_codes.each do |code|
73
+ result = BrazilianUtils::LegalNatureUtils.is_valid(code)
74
+ status = result ? "✓" : "✗"
75
+ display = code.empty? ? '(empty)' : code
76
+ puts " #{status} #{display.ljust(10)} - Valid: #{result}"
77
+ end
78
+ puts
79
+
80
+ # ============================================================================
81
+ # Description Lookup
82
+ # ============================================================================
83
+ puts "4. DESCRIPTION LOOKUP"
84
+ puts "-" * 80
85
+
86
+ lookup_codes = {
87
+ '2062' => 'Limited Liability Company',
88
+ '1015' => 'Federal Public Agency',
89
+ '2305' => 'Individual Limited Liability Company',
90
+ '3123' => 'Political Party',
91
+ '2046' => 'Open Corporation',
92
+ '2143' => 'Cooperative',
93
+ '3050' => 'OSCIP'
94
+ }
95
+
96
+ puts "Code descriptions:"
97
+ lookup_codes.each do |code, english_name|
98
+ description = BrazilianUtils::LegalNatureUtils.get_description(code)
99
+ puts " #{code}: #{description}"
100
+ puts " (#{english_name})"
101
+ end
102
+ puts
103
+
104
+ # ============================================================================
105
+ # List All Codes
106
+ # ============================================================================
107
+ puts "5. LIST ALL CODES"
108
+ puts "-" * 80
109
+
110
+ all_codes = BrazilianUtils::LegalNatureUtils.list_all
111
+ puts "Total legal nature codes in official table: #{all_codes.size}"
112
+ puts
113
+ puts "Sample of all codes (first 10):"
114
+ all_codes.first(10).each do |code, description|
115
+ puts " #{code}: #{description}"
116
+ end
117
+ puts " ... (#{all_codes.size - 10} more codes)"
118
+ puts
119
+
120
+ # ============================================================================
121
+ # List by Category
122
+ # ============================================================================
123
+ puts "6. LIST BY CATEGORY"
124
+ puts "-" * 80
125
+
126
+ categories = {
127
+ 1 => 'Administração Pública (Public Administration)',
128
+ 2 => 'Entidades Empresariais (Business Entities)',
129
+ 3 => 'Entidades Sem Fins Lucrativos (Non-Profit Entities)',
130
+ 4 => 'Pessoas Físicas (Individuals)',
131
+ 5 => 'Organizações Internacionais (International Organizations)'
132
+ }
133
+
134
+ categories.each do |category_num, category_name|
135
+ codes = BrazilianUtils::LegalNatureUtils.list_by_category(category_num)
136
+ puts "Category #{category_num}: #{category_name}"
137
+ puts " Total codes: #{codes.size}"
138
+ puts " Sample codes:"
139
+ codes.first(3).each do |code, description|
140
+ puts " #{code}: #{description}"
141
+ end
142
+ puts
143
+ end
144
+
145
+ # ============================================================================
146
+ # Get Category
147
+ # ============================================================================
148
+ puts "7. GET CATEGORY"
149
+ puts "-" * 80
150
+
151
+ test_codes = ['2062', '1015', '3123', '4014', '5002', '206-2', '9999']
152
+
153
+ puts "Code categories:"
154
+ test_codes.each do |code|
155
+ category = BrazilianUtils::LegalNatureUtils.get_category(code)
156
+ if category
157
+ category_name = categories[category]
158
+ puts " #{code}: Category #{category} - #{category_name}"
159
+ else
160
+ puts " #{code}: Invalid code (no category)"
161
+ end
162
+ end
163
+ puts
164
+
165
+ # ============================================================================
166
+ # Category 2: Business Entities (Most Common)
167
+ # ============================================================================
168
+ puts "8. CATEGORY 2: BUSINESS ENTITIES (MOST COMMON)"
169
+ puts "-" * 80
170
+
171
+ business_entities = BrazilianUtils::LegalNatureUtils.list_by_category(2)
172
+ puts "All Business Entity Types (#{business_entities.size} codes):"
173
+ business_entities.each do |code, description|
174
+ puts " #{code}: #{description}"
175
+ end
176
+ puts
177
+
178
+ # ============================================================================
179
+ # Searching for Specific Types
180
+ # ============================================================================
181
+ puts "9. SEARCHING FOR SPECIFIC TYPES"
182
+ puts "-" * 80
183
+
184
+ # Search for cooperatives
185
+ puts "Searching for 'Cooperativa':"
186
+ all_codes.select { |_, desc| desc.downcase.include?('cooperativa') }.each do |code, description|
187
+ puts " #{code}: #{description}"
188
+ end
189
+ puts
190
+
191
+ # Search for political parties
192
+ puts "Searching for 'Partido':"
193
+ all_codes.select { |_, desc| desc.downcase.include?('partido') }.each do |code, description|
194
+ puts " #{code}: #{description}"
195
+ end
196
+ puts
197
+
198
+ # Search for foundations
199
+ puts "Searching for 'Fundação':"
200
+ all_codes.select { |_, desc| desc.downcase.include?('fundação') }.each do |code, description|
201
+ puts " #{code}: #{description}"
202
+ end
203
+ puts
204
+
205
+ # ============================================================================
206
+ # Practical Use Case: Company Registration
207
+ # ============================================================================
208
+ puts "10. PRACTICAL USE CASE: COMPANY REGISTRATION"
209
+ puts "-" * 80
210
+
211
+ def validate_company_registration(name, cnpj, legal_nature_code)
212
+ errors = []
213
+
214
+ errors << "Company name is required" if name.nil? || name.empty?
215
+ errors << "CNPJ is required" if cnpj.nil? || cnpj.empty?
216
+ errors << "Legal nature code is required" if legal_nature_code.nil? || legal_nature_code.empty?
217
+
218
+ if legal_nature_code && !legal_nature_code.empty?
219
+ unless BrazilianUtils::LegalNatureUtils.valid?(legal_nature_code)
220
+ errors << "Invalid legal nature code: #{legal_nature_code}"
221
+ end
222
+ end
223
+
224
+ if errors.empty?
225
+ description = BrazilianUtils::LegalNatureUtils.get_description(legal_nature_code)
226
+ category = BrazilianUtils::LegalNatureUtils.get_category(legal_nature_code)
227
+ {
228
+ valid: true,
229
+ message: "Registration is valid",
230
+ legal_nature: description,
231
+ category: category
232
+ }
233
+ else
234
+ { valid: false, errors: errors }
235
+ end
236
+ end
237
+
238
+ test_registrations = [
239
+ { name: 'Tech Company LTDA', cnpj: '12.345.678/0001-90', code: '2062' },
240
+ { name: 'Open Corporation SA', cnpj: '98.765.432/0001-10', code: '2046' },
241
+ { name: 'Invalid Corp', cnpj: '11.111.111/0001-11', code: '9999' },
242
+ { name: '', cnpj: '12.345.678/0001-90', code: '2062' }
243
+ ]
244
+
245
+ test_registrations.each_with_index do |reg, index|
246
+ puts "\nTest Registration #{index + 1}:"
247
+ puts " Name: #{reg[:name].inspect}"
248
+ puts " CNPJ: #{reg[:cnpj]}"
249
+ puts " Legal Nature Code: #{reg[:code]}"
250
+
251
+ result = validate_company_registration(reg[:name], reg[:cnpj], reg[:code])
252
+
253
+ if result[:valid]
254
+ puts " Status: ✓ #{result[:message]}"
255
+ puts " Legal Nature: #{result[:legal_nature]}"
256
+ puts " Category: #{result[:category]}"
257
+ else
258
+ puts " Status: ✗ Validation failed"
259
+ result[:errors].each do |error|
260
+ puts " - #{error}"
261
+ end
262
+ end
263
+ end
264
+ puts
265
+
266
+ # ============================================================================
267
+ # Statistics by Category
268
+ # ============================================================================
269
+ puts "11. STATISTICS BY CATEGORY"
270
+ puts "-" * 80
271
+
272
+ puts "Legal Nature Codes Distribution:"
273
+ (1..5).each do |cat|
274
+ codes = BrazilianUtils::LegalNatureUtils.list_by_category(cat)
275
+ category_name = categories[cat].split(' (').first
276
+ percentage = (codes.size * 100.0 / all_codes.size).round(1)
277
+ puts " Category #{cat}: #{codes.size.to_s.rjust(2)} codes (#{percentage.to_s.rjust(4)}%) - #{category_name}"
278
+ end
279
+ puts " Total: #{all_codes.size} codes"
280
+ puts
281
+
282
+ # ============================================================================
283
+ # Common Company Types
284
+ # ============================================================================
285
+ puts "12. COMMON COMPANY TYPES IN BRAZIL"
286
+ puts "-" * 80
287
+
288
+ common_types = [
289
+ '2062', # LTDA
290
+ '2305', # EIRELI
291
+ '2135', # Empresário Individual
292
+ '2046', # S.A. Aberta
293
+ '2054', # S.A. Fechada
294
+ '2143' # Cooperativa
295
+ ]
296
+
297
+ puts "Most common legal nature codes for companies:"
298
+ common_types.each do |code|
299
+ description = BrazilianUtils::LegalNatureUtils.get_description(code)
300
+ puts " #{code}: #{description}"
301
+
302
+ # Show English equivalent
303
+ case code
304
+ when '2062'
305
+ puts " (Similar to: LLC - Limited Liability Company)"
306
+ when '2305'
307
+ puts " (Similar to: Single-member LLC)"
308
+ when '2135'
309
+ puts " (Similar to: Sole Proprietorship)"
310
+ when '2046'
311
+ puts " (Similar to: Public Corporation)"
312
+ when '2054'
313
+ puts " (Similar to: Private Corporation)"
314
+ when '2143'
315
+ puts " (Similar to: Cooperative)"
316
+ end
317
+ end
318
+ puts
319
+
320
+ # ============================================================================
321
+ # Validation with Feedback
322
+ # ============================================================================
323
+ puts "13. VALIDATION WITH DETAILED FEEDBACK"
324
+ puts "-" * 80
325
+
326
+ def validate_with_feedback(code)
327
+ unless BrazilianUtils::LegalNatureUtils.valid?(code)
328
+ if code.nil? || code.empty?
329
+ return { valid: false, message: "Code cannot be empty" }
330
+ elsif code.gsub(/\D/, '').length != 4
331
+ return { valid: false, message: "Code must have exactly 4 digits" }
332
+ else
333
+ return { valid: false, message: "Code not found in official RFB table" }
334
+ end
335
+ end
336
+
337
+ description = BrazilianUtils::LegalNatureUtils.get_description(code)
338
+ category = BrazilianUtils::LegalNatureUtils.get_category(code)
339
+ category_name = categories[category]
340
+
341
+ {
342
+ valid: true,
343
+ message: "Code is valid",
344
+ code: code.gsub(/\D/, ''),
345
+ description: description,
346
+ category: category,
347
+ category_name: category_name
348
+ }
349
+ end
350
+
351
+ test_codes_feedback = ['2062', '206-2', '9999', '123', '', 'invalid', '1015']
352
+
353
+ test_codes_feedback.each do |code|
354
+ result = validate_with_feedback(code)
355
+ display = code.empty? ? '(empty)' : code
356
+
357
+ if result[:valid]
358
+ puts "✓ #{display.ljust(10)} - #{result[:description]}"
359
+ puts " #{' ' * 10} Category #{result[:category]}: #{result[:category_name]}"
360
+ else
361
+ puts "✗ #{display.ljust(10)} - #{result[:message]}"
362
+ end
363
+ end
364
+ puts
365
+
366
+ # ============================================================================
367
+ # Batch Validation
368
+ # ============================================================================
369
+ puts "14. BATCH VALIDATION"
370
+ puts "-" * 80
371
+
372
+ batch_codes = ['2062', '1015', '9999', '2305', '0000', '3123', 'invalid', '2046']
373
+
374
+ valid_count = 0
375
+ invalid_count = 0
376
+
377
+ puts "Validating #{batch_codes.size} codes:"
378
+ batch_codes.each do |code|
379
+ result = BrazilianUtils::LegalNatureUtils.valid?(code)
380
+ status = result ? "✓" : "✗"
381
+
382
+ if result
383
+ valid_count += 1
384
+ desc = BrazilianUtils::LegalNatureUtils.get_description(code)
385
+ puts " #{status} #{code.ljust(10)} - #{desc}"
386
+ else
387
+ invalid_count += 1
388
+ puts " #{status} #{code.ljust(10)} - Invalid"
389
+ end
390
+ end
391
+
392
+ puts
393
+ puts "Summary:"
394
+ puts " Valid: #{valid_count} (#{(valid_count * 100.0 / batch_codes.size).round(1)}%)"
395
+ puts " Invalid: #{invalid_count} (#{(invalid_count * 100.0 / batch_codes.size).round(1)}%)"
396
+ puts
397
+
398
+ # ============================================================================
399
+ # Complete Workflow Example
400
+ # ============================================================================
401
+ puts "15. COMPLETE WORKFLOW EXAMPLE"
402
+ puts "-" * 80
403
+
404
+ company_code = '2062'
405
+
406
+ puts "Analyzing legal nature code: #{company_code}"
407
+ puts
408
+
409
+ # Step 1: Validate
410
+ if BrazilianUtils::LegalNatureUtils.valid?(company_code)
411
+ puts "✓ Code is valid"
412
+
413
+ # Step 2: Get description
414
+ description = BrazilianUtils::LegalNatureUtils.get_description(company_code)
415
+ puts " Description: #{description}"
416
+
417
+ # Step 3: Get category
418
+ category = BrazilianUtils::LegalNatureUtils.get_category(company_code)
419
+ category_name = categories[category]
420
+ puts " Category: #{category} - #{category_name}"
421
+
422
+ # Step 4: List similar codes in the same category
423
+ similar_codes = BrazilianUtils::LegalNatureUtils.list_by_category(category)
424
+ puts " Similar legal natures in this category: #{similar_codes.size} codes"
425
+ puts " Examples:"
426
+ similar_codes.first(5).each do |code, desc|
427
+ marker = code == company_code ? " ← (current)" : ""
428
+ puts " - #{code}: #{desc}#{marker}"
429
+ end
430
+ else
431
+ puts "✗ Code is invalid"
432
+ end
433
+
434
+ puts
435
+ puts "=" * 80
436
+ puts "Examples completed!"
437
+ puts "=" * 80