synapses-validators 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ === 0.1.0 :: 2012-05-15
2
+
3
+ * First public release with CPF, CNPJ and Email Validations
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+ gemspec
3
+
data/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ Synapses-Validators is gem created by Tiago Machado and João Lucas for implement additional validations for Synapses Group.
2
+
3
+ Most part of CPF/CNPJ validations is available at https://github.com/tapajos/brazilian-rails
4
+
5
+
6
+ The MIT License
7
+
8
+ Permission is hereby granted, free of charge, to any person
9
+ obtaining a copy of this software and associated documentation
10
+ files (the "Software"), to deal in the Software without
11
+ restriction, including without limitation the rights to use,
12
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the
14
+ Software is furnished to do so, subject to the following
15
+ conditions:
16
+
17
+ The above copyright notice and this permission notice shall be
18
+ included in all copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27
+ OTHER DEALINGS IN THE SOFTWARE.
28
+
@@ -0,0 +1,74 @@
1
+ # Synapses Validators
2
+
3
+ ## Authors
4
+
5
+ * Tiago Machado (tiago@synapses.com.br)
6
+ * João Lucas (joaolucas@synapses.com.br)
7
+
8
+ Based on Brazilian Rails (https://github.com/tapajos/brazilian-rails)
9
+
10
+ ## How to use
11
+
12
+ Include "synapses-validators" in yor gemfile.
13
+
14
+ ```ruby
15
+ gem 'synapses-validators'
16
+ ```
17
+
18
+ Go to your models, and set your validators.
19
+
20
+ ### CPF
21
+
22
+ ```ruby
23
+ validates :cpf, :presence => true, :uniqueness => true, :cpf => true, :if => :is_person_br?
24
+ ```
25
+
26
+ Or
27
+
28
+ ```ruby
29
+ act_as_cpf :cpf
30
+ ```
31
+
32
+ ### CNPJ
33
+
34
+ ```ruby
35
+ validates :cnpj, :presence => true, :uniqueness => true, :cnpj => true, :if => :is_business_br?
36
+ ```
37
+
38
+ Or
39
+
40
+ ```ruby
41
+ act_as_cnpj :cpf
42
+ ```
43
+
44
+ ### Email
45
+
46
+ ```ruby
47
+ validates :email,
48
+ :presence => true,
49
+ :uniqueness => true,
50
+ :length => {:within => 5..50},
51
+ :email_format => true
52
+ ```
53
+
54
+
55
+ ### I18n
56
+
57
+ The error messages is localized. So, you must have this lines in your locale files:
58
+
59
+ ```ruby
60
+ activerecord:
61
+ errors:
62
+ messages:
63
+ invalid: inválido
64
+ not_formatted: não está no formato correto
65
+ ```
66
+
67
+ ### TODO
68
+
69
+ * Implement tests.
70
+
71
+
72
+ ## License
73
+
74
+ Synapses Validators is licensed for use under the terms of the MIT License.
@@ -0,0 +1,2 @@
1
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
2
+ task :default => :spec
@@ -0,0 +1,6 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # Synapses Group
3
+
4
+ class Cnpj
5
+ include CpfCnpj
6
+ end
@@ -0,0 +1,9 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Synapses Group
3
+
4
+ class CnpjValidator < ActiveModel::EachValidator
5
+ def validate_each(record, attribute, value)
6
+ return if value.nil?
7
+ record.errors.add attribute, :invalid unless Cnpj.new(value).valid?
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # Synapses Group
3
+
4
+ class Cpf
5
+ include CpfCnpj
6
+ end
@@ -0,0 +1,89 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # Synapses Group
3
+
4
+ module CpfCnpj
5
+
6
+ attr_reader :number
7
+
8
+ def initialize(number)
9
+ @number = number
10
+ @match = self.instance_of?(Cpf) ? @number =~ CPF_REGEX : @number =~ CNPJ_REGEX
11
+ @plain_number = $1
12
+ @verification_number = $2
13
+ @number = (@match ? format_number! : nil)
14
+ end
15
+
16
+ def to_s
17
+ @number || ""
18
+ end
19
+
20
+ def ==(value)
21
+ self.number == value.number
22
+ end
23
+
24
+ def valid?
25
+ return false unless @match
26
+ verify_number
27
+ end
28
+
29
+ private
30
+ DIVISOR = 11
31
+
32
+ CPF_LENGTH = 11
33
+ CPF_REGEX = /^(\d{3}\.?\d{3}\.?\d{3})-?(\d{2})$/
34
+ CPF_ALGS_1 = [10, 9, 8, 7, 6, 5, 4, 3, 2]
35
+ CPF_ALGS_2 = [11, 10, 9, 8, 7, 6, 5, 4, 3, 2]
36
+
37
+ CNPJ_LENGTH = 14
38
+ CNPJ_REGEX = /^(\d{2}\.?\d{3}\.?\d{3}\/?\d{4})-?(\d{2})$/ # <= 11.222.333/0001-XX
39
+ CNPJ_ALGS_1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
40
+ CNPJ_ALGS_2 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
41
+
42
+
43
+ def verify_number
44
+ unmasked_number = @number.gsub(/[\.\/-]/, "")
45
+ if self.instance_of? Cpf
46
+ return false if unmasked_number.length != 11
47
+ elsif self.instance_of? Cnpj
48
+ return false if unmasked_number.length != 14
49
+ end
50
+ return false if unmasked_number.scan(/\d/).uniq.length == 1
51
+ first_digit = first_verification_digit
52
+ second_digit = second_verification_digit(first_digit)
53
+ verif = first_digit + second_digit
54
+ verif == @verification_number
55
+ end
56
+
57
+ def multiply_and_sum(algs, number_str)
58
+ multiplied = []
59
+ number_str.scan(/\d{1}/).each_with_index { |e, i| multiplied[i] = e.to_i * algs[i] }
60
+ multiplied.inject { |s,e| s + e }
61
+ end
62
+
63
+ def verification_digit(rest)
64
+ rest < 2 ? 0 : DIVISOR - rest
65
+ end
66
+
67
+ def first_verification_digit
68
+ array = self.instance_of?(Cpf) ? CPF_ALGS_1 : CNPJ_ALGS_1
69
+ sum = multiply_and_sum(array, @plain_number)
70
+ verification_digit(sum%DIVISOR).to_s
71
+ end
72
+
73
+ def second_verification_digit(first_digit)
74
+ array = self.instance_of?(Cpf) ? CPF_ALGS_2 : CNPJ_ALGS_2
75
+ sum = multiply_and_sum(array, @plain_number + first_digit)
76
+ verification_digit(sum%DIVISOR).to_s
77
+ end
78
+
79
+ def format_number!
80
+ if self.instance_of? Cpf
81
+ @number =~ /(\d{3})\.?(\d{3})\.?(\d{3})-?(\d{2})/
82
+ @number = "#{$1}.#{$2}.#{$3}-#{$4}"
83
+ else
84
+ @number =~ /(\d{2})\.?(\d{3})\.?(\d{3})\/?(\d{4})-?(\d{2})/
85
+ @number = "#{$1}.#{$2}.#{$3}/#{$4}-#{$5}"
86
+ end
87
+ end
88
+
89
+ end
@@ -0,0 +1,63 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # Synapses Group
3
+
4
+ module CpfCnpjActiveRecord
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+ end
8
+ module ClassMethods
9
+ def act_as_cpf(*args)
10
+ init(args, 'Cpf')
11
+ end
12
+
13
+ def act_as_cnpj(*args)
14
+ init(args, 'Cnpj')
15
+ end
16
+
17
+ def init(args, klass)
18
+ unless args.size.zero?
19
+ args.each do |name|
20
+ add_composed_class(name, klass)
21
+ module_eval create_code(name.to_s, klass)
22
+ end
23
+ end
24
+ end
25
+
26
+ def add_composed_class(name, klass)
27
+ options = {:class_name => klass, :mapping => [name.to_s, "number"], :allow_nil => true}
28
+ constructor = Proc.new { |number| eval(klass).new(number) }
29
+ converter = Proc.new { |value| eval(klass).new(value) }
30
+ begin
31
+ composed_of name, options.merge( { :constructor => constructor, :converter => converter } )
32
+ rescue Exception
33
+ composed_of name, options { eval(klass).new(name[:number]) }
34
+ end
35
+ end
36
+
37
+ def create_code(name, klass)
38
+ str = <<-CODE
39
+ validate :#{name}_valid?
40
+ def #{name}_valid?
41
+ value = read_attribute('#{name}')
42
+ if !value.nil? && value.strip != '' && !#{name}.nil? && !#{name}.valid?
43
+ self.errors.add('#{name}', :invalid)
44
+ end
45
+ end
46
+ def #{name}=(value)
47
+ if value.blank?
48
+ write_attribute('#{name}', nil)
49
+ elsif value.kind_of?(#{eval(klass)})
50
+ write_attribute('#{name}', value.number)
51
+ else
52
+ begin
53
+ c = #{eval(klass)}.new(value)
54
+ c.valid? ? write_attribute('#{name}', c.number) : write_attribute('#{name}', value)
55
+ rescue
56
+ @#{name} = value
57
+ end
58
+ end
59
+ end
60
+ CODE
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,9 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Synapses Group
3
+
4
+ class CpfValidator < ActiveModel::EachValidator
5
+ def validate_each(record, attribute, value)
6
+ return if value.nil?
7
+ record.errors.add attribute, :invalid unless Cpf.new(value).valid?
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Synapses Group
3
+
4
+ class EmailFormatValidator < ActiveModel::EachValidator
5
+ def validate_each(object, attribute, value)
6
+ unless EmailFormatValidator::validate_email(value)
7
+ object.errors.add attribute, :not_formatted
8
+ end
9
+ end
10
+
11
+ def self.validate_email(email)
12
+ email =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
13
+ end
14
+ end
15
+
16
+
@@ -0,0 +1,20 @@
1
+ # -*- encoding : utf-8 -*-
2
+ $:.unshift(File.dirname(__FILE__)) unless
3
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
4
+
5
+ %w(cpf_cnpj cnpj cpf cpf_cnpj_activerecord cnpj_validator cpf_validator).each {
6
+ |req| require File.dirname(__FILE__) + "/cpf_cnpj/#{req}"
7
+ }
8
+
9
+ %w(email_format_validator).each {
10
+ |req| require File.dirname(__FILE__) + "/email/#{req}"
11
+ }
12
+
13
+ %w(rubygems active_record active_support).each {
14
+ |req| require req
15
+ }
16
+
17
+ ActiveRecord::Base.send :include, CpfCnpjActiveRecord
18
+
19
+ module SynapsesValidators
20
+ end
@@ -0,0 +1,15 @@
1
+ $gemspec = Gem::Specification.new do |s|
2
+ s.name = 'synapses-validators'
3
+ s.version = '0.1.0'
4
+ s.summary = "Implements additional validations required to Synapses Group"
5
+ s.description = "Adds CPF, CNPJ and Email validation"
6
+ s.authors = ["Synapses Group"]
7
+ s.email = ["tiago@synapses.com.br"]
8
+
9
+ s.files = [
10
+ "CHANGELOG", "LICENSE", "README.md", "Rakefile",
11
+ "lib/**/*.rb", "Gemfile", "synapses-validators.gemspec"
12
+ ].map{|p| Dir[p]}.flatten
13
+
14
+ s.homepage = 'https://github.com/synapsesgroup/synapses-validators'
15
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: synapses-validators
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Synapses Group
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-15 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Adds CPF, CNPJ and Email validation
15
+ email:
16
+ - tiago@synapses.com.br
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - CHANGELOG
22
+ - LICENSE
23
+ - README.md
24
+ - Rakefile
25
+ - lib/cpf_cnpj/cnpj.rb
26
+ - lib/cpf_cnpj/cnpj_validator.rb
27
+ - lib/cpf_cnpj/cpf.rb
28
+ - lib/cpf_cnpj/cpf_cnpj.rb
29
+ - lib/cpf_cnpj/cpf_cnpj_activerecord.rb
30
+ - lib/cpf_cnpj/cpf_validator.rb
31
+ - lib/email/email_format_validator.rb
32
+ - lib/synapses-validators.rb
33
+ - Gemfile
34
+ - synapses-validators.gemspec
35
+ homepage: https://github.com/synapsesgroup/synapses-validators
36
+ licenses: []
37
+ post_install_message:
38
+ rdoc_options: []
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ requirements: []
54
+ rubyforge_project:
55
+ rubygems_version: 1.8.24
56
+ signing_key:
57
+ specification_version: 3
58
+ summary: Implements additional validations required to Synapses Group
59
+ test_files: []