br_documents 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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