br_documents 0.0.2

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 (85) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +4 -0
  5. data/README.md +146 -0
  6. data/Rakefile +1 -0
  7. data/br_documents.gemspec +30 -0
  8. data/config/locales/pt-BR.yml +8 -0
  9. data/lib/br_documents.rb +4 -0
  10. data/lib/br_documents/cnpj_cpf/cnpj.rb +21 -0
  11. data/lib/br_documents/cnpj_cpf/cpf.rb +21 -0
  12. data/lib/br_documents/cnpj_cpf/document.rb +35 -0
  13. data/lib/br_documents/cnpj_validator.rb +8 -0
  14. data/lib/br_documents/commons/mod11.rb +20 -0
  15. data/lib/br_documents/cpf_validator.rb +8 -0
  16. data/lib/br_documents/ie/ac.rb +17 -0
  17. data/lib/br_documents/ie/al.rb +17 -0
  18. data/lib/br_documents/ie/am.rb +17 -0
  19. data/lib/br_documents/ie/ap.rb +52 -0
  20. data/lib/br_documents/ie/ba.rb +75 -0
  21. data/lib/br_documents/ie/base.rb +17 -0
  22. data/lib/br_documents/ie/ce.rb +12 -0
  23. data/lib/br_documents/ie/df.rb +17 -0
  24. data/lib/br_documents/ie/es.rb +12 -0
  25. data/lib/br_documents/ie/factory.rb +12 -0
  26. data/lib/br_documents/ie/go.rb +17 -0
  27. data/lib/br_documents/ie/ma.rb +12 -0
  28. data/lib/br_documents/ie/mg.rb +53 -0
  29. data/lib/br_documents/ie/ms.rb +12 -0
  30. data/lib/br_documents/ie/mt.rb +18 -0
  31. data/lib/br_documents/ie/pa.rb +17 -0
  32. data/lib/br_documents/ie/pattern1.rb +26 -0
  33. data/lib/br_documents/ie/pattern2.rb +30 -0
  34. data/lib/br_documents/ie/pb.rb +12 -0
  35. data/lib/br_documents/ie/pe.rb +51 -0
  36. data/lib/br_documents/ie/pi.rb +12 -0
  37. data/lib/br_documents/ie/pr.rb +19 -0
  38. data/lib/br_documents/ie/rj.rb +18 -0
  39. data/lib/br_documents/ie/rn.rb +47 -0
  40. data/lib/br_documents/ie/ro.rb +49 -0
  41. data/lib/br_documents/ie/rr.rb +23 -0
  42. data/lib/br_documents/ie/rs.rb +18 -0
  43. data/lib/br_documents/ie/sc.rb +17 -0
  44. data/lib/br_documents/ie/se.rb +12 -0
  45. data/lib/br_documents/ie/sp.rb +55 -0
  46. data/lib/br_documents/ie/to.rb +18 -0
  47. data/lib/br_documents/ie_validator.rb +50 -0
  48. data/lib/br_documents/version.rb +3 -0
  49. data/spec/cnpj_cpf/cnpj_spec.rb +45 -0
  50. data/spec/cnpj_cpf/cpf_spec.rb +45 -0
  51. data/spec/cnpj_validator_spec.rb +36 -0
  52. data/spec/cpf_validator_spec.rb +36 -0
  53. data/spec/ie/ac_spec.rb +40 -0
  54. data/spec/ie/al_spec.rb +33 -0
  55. data/spec/ie/am_spec.rb +40 -0
  56. data/spec/ie/ap_spec.rb +33 -0
  57. data/spec/ie/ba_spec.rb +63 -0
  58. data/spec/ie/ce_spec.rb +13 -0
  59. data/spec/ie/df_spec.rb +40 -0
  60. data/spec/ie/es_spec.rb +13 -0
  61. data/spec/ie/factory_spec.rb +203 -0
  62. data/spec/ie/go_spec.rb +40 -0
  63. data/spec/ie/ma_spec.rb +13 -0
  64. data/spec/ie/mg_spec.rb +40 -0
  65. data/spec/ie/ms_spec.rb +13 -0
  66. data/spec/ie/mt_spec.rb +40 -0
  67. data/spec/ie/pa_spec.rb +40 -0
  68. data/spec/ie/pb_spec.rb +13 -0
  69. data/spec/ie/pe_spec.rb +59 -0
  70. data/spec/ie/pi_spec.rb +13 -0
  71. data/spec/ie/pr_spec.rb +33 -0
  72. data/spec/ie/rj_spec.rb +40 -0
  73. data/spec/ie/rn_spec.rb +59 -0
  74. data/spec/ie/ro_spec.rb +59 -0
  75. data/spec/ie/rr_spec.rb +40 -0
  76. data/spec/ie/rs_spec.rb +38 -0
  77. data/spec/ie/sc_spec.rb +40 -0
  78. data/spec/ie/se_spec.rb +13 -0
  79. data/spec/ie/shared_examples_for_pattern1.rb +33 -0
  80. data/spec/ie/sp_spec.rb +42 -0
  81. data/spec/ie/to_spec.rb +40 -0
  82. data/spec/ie_validator_spec.rb +65 -0
  83. data/spec/spec_helper.rb +21 -0
  84. data/spec/support/utilities.rb +3 -0
  85. metadata +248 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2a4b4ddd2caa2c23d58d23a4467094a831490466
4
+ data.tar.gz: afdeb05383f8d7b83f995ff0b45cf6c9765a67c1
5
+ SHA512:
6
+ metadata.gz: 53a62e408338ee84e882cdf0ac5293f9ddd9a6f811f8d91dc547506bbdb8ae50ad6a9743bb7a8e20f5ed613fe03374a747d1c6138e317eb69e68e3ccf118b4da
7
+ data.tar.gz: c999e3b9bbc5e6a9298cb3aa7863d28f2b25985089fb0fc00718021d8d76bb8882c7c5c504cbf484a3c65b1b2d20b4e9a094e7dde57fd28c8f789e6b5ba4e604
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color --format documentation --order rand
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+ ruby "2.0.0"
3
+
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,146 @@
1
+ # BrDocuments
2
+
3
+ This gem validates Brazilian documents for application use. Today it can validate CNPJ, CPF and IE.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem "br_documents"
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```ruby
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+
21
+ ```ruby
22
+ $ gem install br_documents
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ### Active Record
28
+
29
+ #### CNPJ
30
+
31
+ ```ruby
32
+ class Person < ActiveRecord::Base
33
+
34
+ attr_accessor :cnpj
35
+
36
+ validates :cnpj,
37
+ cnpj: true
38
+ end
39
+
40
+
41
+ pj = Person.new
42
+ pj.cnpj = "85961757000102"
43
+ pj.valid? # => true
44
+
45
+ pj.cnpj = "85.961.757/0001-02" # with mask
46
+ pf.valid? # => true
47
+
48
+ pj.cnpj = "11111111111111"
49
+ pj.valid? # => false
50
+ ```
51
+
52
+ #### CPF
53
+
54
+ ```ruby
55
+ class Person < ActiveRecord::Base
56
+
57
+ attr_accessor :cpf
58
+
59
+ validates :cpf,
60
+ cpf: true
61
+ end
62
+
63
+
64
+ pf = Person.new
65
+ pf.cpf = "11144477735"
66
+ pf.valid? # => true
67
+
68
+ pf.cpf = "111.444.777-35" # with mask
69
+ pf.valid? # => true
70
+
71
+ pf.cpf = "111.111.111-11"
72
+ pf.valid? # => false
73
+ ```
74
+
75
+ #### IE
76
+
77
+ ```ruby
78
+ class City < ActiveRecord::Base
79
+ attr_accessor :name, :uf
80
+
81
+ has_many :people
82
+ end
83
+
84
+ class Person < ActiveRecord::Base
85
+
86
+ attr_accessor :ie
87
+
88
+ belongs_to :city
89
+
90
+ validates :ie,
91
+ ie: {uf: "city#uf"} # you need to inform how it can get the "uf" attribute
92
+ end
93
+
94
+
95
+ c = City.new
96
+ c.name = "Tijucas"
97
+ c.uf = "SC"
98
+
99
+ pj = Person.new
100
+ pj.city = c
101
+
102
+ pj.ie = "253667852"
103
+ pj.valid? # => true
104
+
105
+ pj.ie = "253.667.852" # with mask
106
+ pj.valid? # => true
107
+
108
+ c.uf = "SP"
109
+ pj.valid? # => false
110
+
111
+ c.uf = "SC"
112
+ pj.ie = "111.111.111"
113
+ pj.valid? # => false
114
+ ```
115
+
116
+ ### Ruby
117
+
118
+ #### CNPJ
119
+
120
+ ```ruby
121
+ cnpj = BrDocuments::CnpjCpf::Cnpj.new("04.001.155/0001-01")
122
+ cnpj.valid? # => true
123
+ ```
124
+
125
+ #### CPF
126
+
127
+ ```ruby
128
+ cpf = BrDocuments::CnpjCpf::Cpf.new("111.444.777-35")
129
+ cpf.valid? # => true
130
+ ```
131
+
132
+ #### IE
133
+
134
+ ```ruby
135
+ ie = BrDocuments::IE::Factory.create("SC", "254062407")
136
+ ie.formatted # => "254.062.407"
137
+ ie.valid? # => true
138
+ ```
139
+
140
+ ## Contributing
141
+
142
+ 1. Fork it
143
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
144
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
145
+ 4. Push to the branch (`git push origin my-new-feature`)
146
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "br_documents/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "br_documents"
8
+ spec.version = BrDocuments::VERSION
9
+ spec.authors = ["ASSEINFO - Sistemas de Informação"]
10
+ spec.email = ["asseinfo@asseinfo.com.br"]
11
+ spec.description = "Solução para validar documentos brasileiros"
12
+ spec.summary = "Solução para validar documentos brasileiros"
13
+ spec.homepage = "http://github.com/asseinfo/br_documents"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.metadata["allowed_push_host"] = "http://github.com/asseinfo/br_documents"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake", "~> 10.1.0"
25
+ spec.add_development_dependency "rspec", "~> 2.14.1"
26
+ spec.add_development_dependency "codeclimate-test-reporter"
27
+
28
+ spec.add_runtime_dependency "activemodel", "~> 4.0.0"
29
+ spec.add_runtime_dependency "i18n", "~> 0.6.5"
30
+ end
@@ -0,0 +1,8 @@
1
+ pt-BR:
2
+ validator:
3
+ ie:
4
+ uf:
5
+ read_error: "Não foi possível ler o atributo '%{uf}'"
6
+ no_configured: "Não foi configurado o atributo 'uf' em IeValidator"
7
+ invalid: "UF é inválida"
8
+ no_present: "Quando informado a Inscrição Estadual a UF não deve ficar em branco"
@@ -0,0 +1,4 @@
1
+ require "active_model"
2
+ Dir[File.dirname(__FILE__) + "/**/*.rb"].each { |f| require f }
3
+
4
+ I18n.load_path << File.expand_path("../../config/locales/pt-BR.yml", __FILE__)
@@ -0,0 +1,21 @@
1
+ require_relative "document"
2
+
3
+ module BrDocuments
4
+ module CnpjCpf
5
+ class Cnpj
6
+ include Document
7
+
8
+ def initialize(number)
9
+ @number = number
10
+ end
11
+
12
+ def valid?
13
+ regex = /^(\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2})$|^(\d{14})$/
14
+ weight13 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
15
+ weight14 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
16
+
17
+ valid_number?(@number, regex, weight13, weight14)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require_relative "document"
2
+
3
+ module BrDocuments
4
+ module CnpjCpf
5
+ class Cpf
6
+ include Document
7
+
8
+ def initialize(number)
9
+ @number = number
10
+ end
11
+
12
+ def valid?
13
+ regex = /^(\d{3}\.\d{3}\.\d{3}-\d{2})$|^(\d{11})$/
14
+ weight10 = [10, 9, 8, 7, 6, 5, 4, 3, 2]
15
+ weight11 = [11, 10, 9, 8, 7, 6, 5, 4, 3, 2]
16
+
17
+ valid_number?(@number, regex, weight10, weight11)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,35 @@
1
+ require_relative "../commons/mod11"
2
+
3
+ module BrDocuments
4
+ module CnpjCpf
5
+ module Document
6
+ include Commons::Mod11
7
+
8
+ protected
9
+ def valid_number?(number, regex, weight1, weight2)
10
+ valid_format?(number, regex) and
11
+ not sequence_of_equal_numbers?(number) and
12
+ valid_digital_check?(number, weight1, weight2)
13
+ end
14
+
15
+ private
16
+ def valid_format?(number, regex)
17
+ regex.match(number).present?
18
+ end
19
+
20
+ def sequence_of_equal_numbers?(number)
21
+ remove_mask(number).split("").uniq.length == 1
22
+ end
23
+
24
+ def valid_digital_check?(number, weight1, weight2)
25
+ digital_check1 = generate_digital_check(remove_mask(number), weight1)
26
+ digital_check2 = generate_digital_check(remove_mask(number), weight2)
27
+ number[-2, 2].eql? "#{digital_check1}#{digital_check2}"
28
+ end
29
+
30
+ def remove_mask(number)
31
+ number.gsub(/[\.\/-]/, "")
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,8 @@
1
+ class CnpjValidator < ActiveModel::EachValidator
2
+ def validate_each(record, attribute, value)
3
+ if value.present?
4
+ cnpj = BrDocuments::CnpjCpf::Cnpj.new(value)
5
+ record.errors.add(attribute, :invalid) if not cnpj.valid?
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,20 @@
1
+ module BrDocuments
2
+ module Commons
3
+ module Mod11
4
+
5
+ def generate_digital_check(values, weights)
6
+ sum = reduce_weights(values, weights)
7
+ mod = sum % 11
8
+ mod < 2 ? 0 : (11 - mod)
9
+ end
10
+
11
+ def reduce_weights(values, weights)
12
+ sum = 0
13
+ weights.each_index do |i|
14
+ sum += weights[i] * values[i].to_i
15
+ end
16
+ sum
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,8 @@
1
+ class CpfValidator < ActiveModel::EachValidator
2
+ def validate_each(record, attribute, value)
3
+ if value.present?
4
+ cpf = BrDocuments::CnpjCpf::Cpf.new(value)
5
+ record.errors.add(attribute, :invalid) if not cpf.valid?
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,17 @@
1
+ require_relative "pattern2"
2
+
3
+ module BrDocuments
4
+ module IE
5
+ class AC < Pattern2
6
+ def initialize(number)
7
+ super
8
+ @mask = /^(\d{2}\.\d{3}\.\d{3}\/\d{3}\-\d{2})$|^(\d{13})$/
9
+ end
10
+
11
+ private
12
+ def format_ie(number)
13
+ number.sub(/(\d{2})(\d{3})(\d{3})(\d{3})(\d{2})/, "\\1.\\2.\\3/\\4-\\5")
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require_relative "pattern1"
2
+
3
+ module BrDocuments
4
+ module IE
5
+ class AL < Pattern1
6
+ def initialize(number)
7
+ super
8
+ @mask = /(\d{9})$/
9
+ end
10
+
11
+ private
12
+ def format_ie(number)
13
+ number
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require_relative "pattern1"
2
+
3
+ module BrDocuments
4
+ module IE
5
+ class AM < Pattern1
6
+ def initialize(number)
7
+ super
8
+ @mask = /^(\d{2}\.\d{3}\.\d{3}\-\d{1})$|^(\d{9})$/
9
+ end
10
+
11
+ private
12
+ def format_ie(number)
13
+ number.sub(/(\d{2})(\d{3})(\d{3})(\d{1})/, "\\1.\\2.\\3-\\4")
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,52 @@
1
+ require_relative "base"
2
+
3
+ module BrDocuments
4
+ module IE
5
+ class AP < Base
6
+ include Commons::Mod11
7
+
8
+ private
9
+ def format_ie(number)
10
+ number
11
+ end
12
+
13
+ def valid_format?
14
+ regex = /(\d{9})$/
15
+ regex.match(@number).present?
16
+ end
17
+
18
+ def valid_digital_check?
19
+ weight = [9, 8, 7, 6, 5, 4, 3, 2]
20
+ detect_range_digits
21
+ @number.gsub!(/\./, "")
22
+ @number[-1].eql? generate_digital_check(@number, weight).to_s
23
+ end
24
+
25
+ def detect_range_digits
26
+ number = @number[0, 8]
27
+ if number.to_i >= 3000001 and number.to_i <= 3017000
28
+ @p = 5
29
+ @d = 0
30
+ else
31
+ if number.to_i >= 3017001 and number.to_i <= 3019022
32
+ @p = 9
33
+ @d = 1
34
+ else
35
+ @p = 0
36
+ @d = 0
37
+ end
38
+ end
39
+ end
40
+
41
+ def generate_digital_check(values, weights)
42
+ sum = reduce_weights(values, weights)
43
+ sum += @p
44
+ mod = sum % 11
45
+ digital_check = 11 - mod
46
+ digital_check = 0 if digital_check == 10
47
+ digital_check = @d if digital_check == 11
48
+ digital_check
49
+ end
50
+ end
51
+ end
52
+ end