Skip to content
setembro 24, 2008 / cassiomarques

Brazilian Rails agora com suporte a CPF e CNPJ

Terminei há pouco tempo uma pequena aplicação financeira escrita em Rails e usei o Brazilian Rails para diversas funcionalidades. Uma das coisas que o Brazilian Rails não tinha e que acabei tendo que criar foi um suporte a CPF e CNPJ, com validações do formato das strings e do seu conteúdo numérico (utilizando módulo 11).

Achei que a solução ficou boa e tive a idéia de adicionar esta funcionalidade ao Brazilian Rails. Depois que o plugin foi adaptado para funcionar como um conjunto de gems ficou realmente simples integrar o que eu havia escrito. E assim surgiu a gem brcpfcnpj!

Com o brcpfcnpj, você pode criar campos que funcionem como um CPF ou um CNPJ de forma totalmente automática, de maneira semelhante ao que já é feito com a classe Dinheiro do Brazilian Rails.

As classes Cpf e Cnpj formatam e validam strings no formato xxx.xxx.xxx-xx (para os CPFs) e xx.xxx.xxx/xxxx-xx (para os CNPJs), onde x pode ser qualquer digito de 0 a 9. Os caracteres ‘.’, ‘/’ e ‘-‘ são totalmente opcionais. Caso um atributo do seu model seja declarado para que funcione como Cpf ou Cnpj e você tente salvar um objeto deste model contendo uma string inválida para o cpf ou o cnpj, um novo erro será inserido em errors e o objeto passará a ser inválido.
Além disso, caso associe um valor não formatado a este atributo, seu conteúdo será automaticamente formatado.

A forma de usar é praticamente a mesma tanto para o CPF quanto para o CNPJ.

Como usar o Cpf:

Suponha que temos um model Pessoa, com um atributo ‘cpf’ que voce quer usar como um numero de documento para cpf. Basta usar o metodo usar_como_cpf, assim:

class Pessoa < ActiveRecord::Base
  usar_como_cpf :cpf
end
&#91;/source&#93;

O atributo que sera usado como cpf pode ter qualquer nome e nao apenas 'cpf'. Agora voce pode usar o atributo para cpf da seguinte forma:
&#91;source language="ruby"&#93; 
p = Pessoa.new
p.cpf = "11144477735"
puts p.cpf # ==> 111.444.777-35
p.cpf.valido? # ==> true
p.cpf_valido? # ==> true

p = Pessoa.new(:cpf => "111.444.777-35")
puts p.cpf # ==> 111.444.777-35

p = Pessoa.new
p.cpf = Cpf.new("111444777-35")
puts p.cpf # ==> 111.444.777-35

p = Pessoa.new
p.cpf = "12345" # ==> um cpf invalido
puts p.valid? # ==> false
p.save # ==> false
p.errors.on(:cpf) # ==> 'numero invalido'

c = Cpf.new("11144477735")
p.cpf = "111.444.777-35"
c == p.cpf # ==> true

Como usar o Cnpj

Suponha que temos um model Empresa, com um atributo ‘cnpj’ que voce quer usar como um numero de documento para cnpj. Basta usar o metodo usar_como_cnpj, assim:

class Empresa < ActiveRecord::Base
  usar_como_cnpj :cnpj
end
&#91;/source&#93;

O atributo que sera usado como cnpj pode ter qualquer nome e nao apenas 'cnpj'. Agora voce pode usar o atributo para cnpj da seguinte forma:
&#91;source language="ruby"&#93;
e = Empresa.new
e.cnpj = "69103604000160"
puts e.cnpj # ==> 69.103.604/0001-60
e.cnpj.valido? # ==> true
e.cnpj_valido? # ==> true
  
e = Empresa.new(:cnpj => "69.103.604/0001-60")
puts e.cnpj # ==> 69.103.604/0001-60
  
e = Empresa.new
e.cnpj = Cnpj.new("691036040001-60")
puts e.cnpj # ==> 69.103.604/0001-60

e = Empresa.new
e.cnpj = "12343" # ==> um cnpj invalido
puts e.valid? # ==> false
e.save # ==> false
e.errors.on(:cnpj) # ==> 'numero invalido'
  
c = Cnpj.new("69103604000160")
e.cnpj = "69.103.604/0001-60"
c == e.cnpj # ==> true   

As novas alterações já foram integradas ao projeto principal. Você pode instalar o projeto utilizando o GitHub. Mais informações em http://www.improveit.com.br/software_livre/brazilian_rails
Espero que seja útil!

4 Comentários

Deixe um comentário
  1. Carlos / set 24 2008 3:51 pm

    Olá Cássio.

    Bela iniciativa para adicionar a validação de CPF/CNPJ no brazilian-rails.
    Estivemos trabalhando aqui também numa validação para esses campos, já temos ela funcionando também em um projeto, contudo imagino que logo vamos atualizar para a nova versão do brazilian-rails e vamos utilizar o novo suporte do plugin.

    Com isso fica uma pergunta, é possível utilizar as duas validações em conjunto? Por exemplo, se eu tiver um model Pessoa, que precise analisar se é CPF ou CNPJ de acordo com o tipo (Física, Jurídica).

    Abraços.
    Carlos

  2. cassiomarques / set 24 2008 4:00 pm

    Olá Carlos,

    Eu não testei nada nesse sentido, mas o que acontece é que quando você faz usar_como_cpf ou usar_como_cnpj, nada impede que seu objeto seja salvo com este atributo vazio. Assim, acho que você poderia por exemplo criar duas colunas na sua tabela, uma para cpf e outra para cnpj, com dois atributos independentes. Dessa forma, se for PF, você recebe, valida e grava o cpf; se for PJ, você recebe, valida e grava o cnpj.

  3. Carlos / set 24 2008 4:05 pm

    Acho que seria possível trabalhar dessa maneira sim, sem problemas.

    Vou aproveitar e trabalhar em algo que permita validar os dois em uma mesma coluna, como já temos hoje funcionando aqui, imagino que seria interessante ter também essa funcionalidade.

  4. cassiomarques / set 24 2008 4:16 pm

    Carlos,

    Pensando aqui, acho que poderia ser feito algo com before_validation… Considerando que você tenha alguma coluna que indique se é PF ou PJ e uma única coluna (por exemplo documento), o método associado ao before_validation poderia fazer o seguinte:

    – Verificar se é PF ou PJ
    – se for pj: usar_como_cnpj :documento
    – se for PF: usar_como_cpf :documento

    Acho que deve funcionar sem maiores problemas.

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: