Validar campo CNPJ/CPF no model

1,165 views
Skip to first unread message

Douglas

unread,
Apr 9, 2012, 3:21:13 PM4/9/12
to CakePHP Tuga
Olá pessoal, tudo bem?

Sou iniciante no Cake e estou criando uma tela para cadastro de
clientes. O cliente pode ser pessoa física (PF) ou jurídica (PJ).
Os campos exibidos no formulário, bem como a validação, dependem se o
cliente é PF ou PJ.
Porém, alguns campos servem para os dois, mas com validação diferente.
Como exemplo, tenho um campo CNPJ / CPF onde pode ser digitado tanto
um CPF quanto um CNPJ


A dúvida é a seguinte: como fazer para que as validações sejam feitas
de acordo com o tipo de cliente? (faço a distinção pelo números de
caracteres no campo CNPJ / CPF)

De tudo que tentei, o que chegou mais próximo de um resultado
satisfatório foi isso:
Usar o BeforeValidate para verificar se é uma PF ou uma PJ e chamar um
método (função) que atribui na variável $validate todas as regras de
validação pertinentes ao tipo de pessoa que está sendo cadastrada. Com
isso, ele até verifica se o CPF (ou CNPJ) é válido, se todos os campos
estão com o mínimo exigido de caracteres. Enfim, ele executa as
verificações que eu solicito.
Porém, quando está tudo certo e clico no botão OK para enviar os dados
ao BD, ele apenas recarrega a página já com os campos preenchidos com
os valores que acabei de inserir mas não salva no BD.

Acredito que o problema esteja no fato de eu estar atribuindo valores
ao $validate (como está dentro do método, $this->validate) no método.
Quando deixei a atribuição do $validate FORA do método, apenas com uma
validação do tamanho mínimo do campo nome, ele salvou no BD
normalmente.

Agradeço a quem puder ajudar
Até mais!

Douglas Henrique

Márcio Fornari

unread,
Apr 9, 2012, 3:32:45 PM4/9/12
to cakep...@googlegroups.com
Não seria mais facil colocar um radio button para selecionar o tipo de pessoa?
tente usar o ajax para fazer a mágica aparecer após o usuário selecionar o tipo de pessoa.


--
CakePHP Tuga (cakephp-pt)

Utilize http://bin.cakephp.org para códigos
Cookbook: http://book.cakephp.org

Website do CakePHP: http://cakephp.org/
Website do grupo: http://groups.google.com/group/cakephp-pt?hl=pt-PT



--
Green day Forever and Ever!!!

.Márcio Fornari 
.Bacharel em  Sistemas de Informação
.Contatos pelo Telefone: (49)8814 - 3378
.ou pelo e-mail: marcio...@gmail.com
.Msn: marci...@hotmail.com
..........................................................................
Message has been deleted

Douglas

unread,
Apr 9, 2012, 3:46:26 PM4/9/12
to CakePHP Tuga
Márcio Fornari, obrigado pela sugestão.

Na verdade, estou utilizando JavaScript para exibir/ocultar os campos
assim que perde o foco no campo CPF / CNPJ.
Poderia até colocar o radiobutton mas a questão é que eu preciso
armazenar tudo na mesma tabela, PF e PJ (CPF/CNPJ, RG/IE ficam no
mesmo campo). E aqui está o problema, quando é PJ por exemplo, tem
campo que se torna obrigatório. Portanto, no $validate tenho que usar
o notEmpty. Caso contrário o campo é opcional.

Sobre diferenciar isso eu consegui, mas tive que atribuir dentro de um
metódo chamado pelo beforeSave. Só que acho que por esse motivo, ele
apenas VALIDA mas não SALVA


Até+

On 9 abr, 16:32, Márcio Fornari <marcioforn...@gmail.com> wrote:
> Não seria mais facil colocar um radio button para selecionar o tipo de
> pessoa?
> tente usar o ajax para fazer a mágica aparecer após o usuário selecionar o
> tipo de pessoa.
>
> > Utilizehttp://bin.cakephp.orgpara códigos
> > Cookbook:http://book.cakephp.org
>
> > Website do CakePHP:http://cakephp.org/
> > Website do grupo:http://groups.google.com/group/cakephp-pt?hl=pt-PT
>
> --
> Green day Forever and Ever!!!
>
> .Márcio Fornari
> .Bacharel em  Sistemas de Informação
> .Contatos pelo Telefone: (49)8814 - 3378
> .ou pelo e-mail: marcioforn...@gmail.com
> .Msn: marciof...@hotmail.com
> ..........................................................................

Paulo Diovani

unread,
Apr 9, 2012, 3:56:29 PM4/9/12
to cakep...@googlegroups.com
Se o campo é o mesmo tu ainda pode validar no model, fácil, só criar um método no Model para a validação.

Acho que a forma mais prática é usar uma expressão regular (veja preg_match) para identificar se é CPF ou CNPJ, e então usar a validação de acordo.

Fiz algo parecido esses tempos, se lembrar mando um exemplo à noite.

--
Paulo Diovani,

Cauan Cabral

unread,
Apr 9, 2012, 4:08:50 PM4/9/12
to cakep...@googlegroups.com
Tem um plugin oficial do CakePHP que faz essa validação: https://github.com/cakephp/localized/tree/2.0/

As instruções em português: https://github.com/cakephp/localized/blob/2.0/README.pt_br.mdown

2012/4/9 Paulo Diovani <pa...@diovani.com>

--
CakePHP Tuga (cakephp-pt)
 
Utilize http://bin.cakephp.org para códigos



--
Cauan Cabral
----------------
Como falar comigo: Google Talk: cau...@gmail.com Skype: CauanCabral MSN: cau...@gmail.com
Onde me encontrar: LinkedinFacebookWordpressTwitterOrkut


Message has been deleted

Douglas

unread,
Apr 10, 2012, 12:21:25 PM4/10/12
to CakePHP Tuga
Talvez eu não tenha explicado o real problema lá em cima:


Estou conseguindo fazer a verificação se o CPF, se o CNPJ, etc são
válidos.


A questão é que eu preciso armazenar tudo na mesma tabela, PF e PJ
(CPF/CNPJ, RG/IE ficam no mesmo campo). E aqui está o problema, quando
é PJ por exemplo, tem campo que se torna obrigatório. Portanto, no
$validate tenho que usar o notEmpty. Caso contrário o campo é
opcional. Nessa diferença que encontro dificuldades, às vezes o MESMO
campo pode ser notEmpty e às vezes não. Como atribuir valores NÃO
CONSTANTES ao $validate?


Só lembrando, que a forma que eu encontrei para fazer isso, foi
inserir o $validate dentro de um método. De acordo com o tipo de
pessoa, o $validate faz a validação correta.


Resumindo um trecho desse método, utilizando apenas os campos cnpj_cpf
e ie_rg, está assim:


(...)
$cpf_cnpj = $this->data['Cliente']['cnpj_cpf'];
$uf = $this->data['Cliente']['uf'];

if($cpf_cnpj > 11){
    $messageCpfCnpj = "CNPJ inválido";
    $validaIE = "validarIE"; //se for PJ precisa validar a Inscrição
Estadual
}


else if($cpf_cnpj == 11){
    $messageCpfCnpj = "CPF inválido";
    $validaIE = "naoValida"; //função que sempre retorna true, pois
para PF, esse campo é composto pelo RG, que não necessita de validação
}


$this->validate = array('cnpj_cpf'=>array(
                                      'validaCpfCnpj'=>array(
'rule'=>array('validaCnpjCpf','cnpj_cpf'),
'message'=>"$messageCpfCnpj"
),
'minimo'=>array(
'rule'=>array('minLength','11'),
'message'=>'CNPJ/CPF inválido.'
)
),
'ie_rg'=>array(
'minimo'=>array(
'rule'=>array('minLength','9'),
'message'=>'IE/RG inválido. Deve conter no mínimo 9
caracteres.'
),
'validaIE'=>array(
'rule'=>array("$validaIE",'ie_rg',"$uf"),//$uf contém o estado
do endereço de cadastro
'message'=>"$messageIE"
                                                        )
                                       )
                           );


Eu acho que por o $validate estar dentro do método, ele apenas VALIDA
mas não SALVA



On 9 Abr, 17:08, Cauan Cabral <cau...@gmail.com> wrote:
> Tem um plugin oficial do CakePHP que faz essa validação:https://github.com/cakephp/localized/tree/2.0/
>
> As instruções em português:https://github.com/cakephp/localized/blob/2.0/README.pt_br.mdown
>
> 2012/4/9 Paulo Diovani <pa...@diovani.com>
>
>
>
>
>
>
>
>
>
> > Se o campo é o mesmo tu ainda pode validar no model, fácil, só criar um
> > método no Model para a validação.
>
> > Acho que a forma mais prática é usar uma expressão regular (veja
> > preg_match <http://br2.php.net/manual/en/function.preg-match.php>) para
> > identificar se é CPF ou CNPJ, e então usar a validação de acordo.
>
> > Fiz algo parecido esses tempos, se lembrar mando um exemplo à noite.
>
> > --
> > Paulo Diovani,
> > diovani.com / @paulodiovani <http://twitter.com/paulodiovani> / ♣<http://entbonsai.com>
>
> >  --
> > CakePHP Tuga (cakephp-pt)
>
> > Utilizehttp://bin.cakephp.orgpara códigos
> > Cookbook:http://book.cakephp.org
>
> > Website do CakePHP:http://cakephp.org/
> > Website do grupo:http://groups.google.com/group/cakephp-pt?hl=pt-PT
>
> --
> Cauan Cabral
> ----------------
> Como falar comigo: Google Talk: cau...@gmail.com Skype: CauanCabral MSN:
> cau...@gmail.com
> Onde me encontrar: [image:
> Linkedin]<http://www.linkedin.com/in/cauancabral>[image:
> Facebook] <http://www.facebook.com/cauancabral>[image:
> Wordpress]<http://cauancabral.net>[image:
> Twitter] <http://twitter.com/cauancabral>[image:
> Orkut]<http://www.orkut.com.br/Main#Profile?uid=7512190439488689375>

Cauan Cabral

unread,
Apr 10, 2012, 12:26:35 PM4/10/12
to cakep...@googlegroups.com
Como atribuir valores NÃO CONSTANTES ao $validate?

Da mesma forma que você atribui qualquer valor não constante à um atributo de classe:
em um método ou construtor.

No caso da validação, você pode fazer isso no callback beforeValidate, porque nele você
já terá os dados que vão ser salvos (é só olhar no atributo $data do model).

Da mesma forma, se você quer setar algum valor para um determinado campo, é só
definir ele no mesmo atributo $data do model.
 
2012/4/10 Douglas <e.tis...@icos.com.br>
--
CakePHP Tuga (cakephp-pt)

Utilize http://bin.cakephp.org para códigos



--
Cauan Cabral
----------------

Douglas

unread,
Apr 10, 2012, 12:37:27 PM4/10/12
to CakePHP Tuga
Exatamente o que eu fiz e, até por isso, se eu deixar um campo em
branco, ou inserir um dado incorreto/inválido, ele gera a mensagem de
erro. Está executando as validações do jeito que eu preciso, quando é
CPF valida CPF, quando é CNPJ valida CNPJ, etc.

Como você confirmou que estou no caminho certo, a dúvida agora passa a
ser porque quando está TUDO CORRETO, ele não salva no BD?
Se eu deixar o $validate com valores constantes, atribuindo esses
valores fora do beforeSave, ele valida e salva normalmente.
Ele só não está salvando quando eu uso o $validate dentro do método.
Ele valida, mas não salva no BD.
E eu preciso desse dinamismo no $validate. Não posso usar constante.


On 10 Abr, 13:26, Cauan Cabral <cau...@gmail.com> wrote:
> > Como atribuir valores NÃO CONSTANTES ao $validate?
>
> Da mesma forma que você atribui qualquer valor não constante à um atributo
> de classe:
> em um método ou construtor.
>
> No caso da validação, você pode fazer isso no callback beforeValidate,
> porque nele você
> já terá os dados que vão ser salvos (é só olhar no atributo $data do model).
>
> Da mesma forma, se você quer setar algum valor para um determinado campo, é
> só
> definir ele no mesmo atributo $data do model.
>
> 2012/4/10 Douglas <e.tisupo...@icos.com.br>

Cauan Cabral

unread,
Apr 10, 2012, 1:14:09 PM4/10/12
to cakep...@googlegroups.com
Você esta usando o beforeValidate ou o beforeSave?
Ele precisa retornar true pra prosseguir

2012/4/10 Douglas <e.tis...@icos.com.br>
--
CakePHP Tuga (cakephp-pt)

Utilize http://bin.cakephp.org para códigos



--
Cauan Cabral
----------------

Douglas

unread,
Apr 10, 2012, 4:10:09 PM4/10/12
to CakePHP Tuga
Desculpa, escrevi errado ali em cima... estou usando o
beforeValidate() para setar o $validate

On 10 Abr, 14:14, Cauan Cabral <cau...@gmail.com> wrote:
> Você esta usando o beforeValidate ou o beforeSave?
> Ele precisa retornar true pra prosseguir
>
> 2012/4/10 Douglas <e.tisupo...@icos.com.br>

Cauan Cabral

unread,
Apr 10, 2012, 6:00:02 PM4/10/12
to cakep...@googlegroups.com
Esta retornando true em caso de sucesso na validação?

2012/4/10 Douglas <e.tis...@icos.com.br>
--
CakePHP Tuga (cakephp-pt)

Utilize http://bin.cakephp.org para códigos



--
Cauan Cabral
----------------

Douglas

unread,
Apr 11, 2012, 12:07:31 PM4/11/12
to CakePHP Tuga
Eu acredito que não, pois no controller, acabei de implementar isso:

if (!empty($this->data)) {
pr('nao vazio');
if ($this->Cliente->save($this->data)) {
pr('salva');
$this->Session->setFlash('SALVO COM SUCESSO.');
$this->redirect(array('action' => 'aplicacao'));
}
else{
pr('erro ao salvar');
}

E só está exibindo o 'nao vazio' e o 'erro ao salvar'. Tem alguma
forma melhor de verificar essa sua questão?

On 10 Abr, 19:00, Cauan Cabral <cau...@gmail.com> wrote:
> Esta retornando true em caso de sucesso na validação?
>
> 2012/4/10 Douglas <e.tisupo...@icos.com.br>

Marcelo F Andrade

unread,
Apr 11, 2012, 12:35:20 PM4/11/12
to cakep...@googlegroups.com
2012/4/11 Douglas <e.tis...@icos.com.br>:

> Eu acredito que não, pois no controller, acabei de implementar isso:
>
> if (!empty($this->data)) {
>        pr('nao vazio');
>        if ($this->Cliente->save($this->data)) {
>                pr('salva');
>                $this->Session->setFlash('SALVO COM SUCESSO.');
>                $this->redirect(array('action' => 'aplicacao'));
>        }
>        else{
>                pr('erro ao salvar');
>        }
>
> E só está exibindo o 'nao vazio' e o 'erro ao salvar'. Tem alguma
> forma melhor de verificar essa sua questão?

Faz um tempinho que não mexo, mas muito provavelmente
alguma validação está barrando. No lugar do 'erro ao salvar'
experimenta verificar que informação ele retorna dando um

pr($this->Cliente->validationErrors); // acho que é isso

Atts.

--
MARCELO F ANDRADE
Belem, Amazonia, Brazil

"I took the red pill"

Douglas

unread,
Apr 11, 2012, 1:28:45 PM4/11/12
to CakePHP Tuga
Aeee...consegui!!!

Muito obrigado Cauan Cabral e Marcelo F Andrade por me ajudarem!

O Cauan me ajudou a caminhar para a linha de chegada e o Marcelo deu o
empurrão para eu ultrapassá-la rsrsrs

Essa última dica aí para inserir o
pr($this->Cliente->validationErrors);

foi essencial. Não conhecia essa função. Graças a ela encontrei onde
estava o problema:
- o campo "data" é preenchido automaticamente pelo servidor. E estava
dando erro na hora de validá-la, pois havia esquecido que já
padronizamos a validação para o formato de data nacional. Bastou
inverter os parâmetros no date();
- tinha um outro campo não obrigatório, onde eu tinha utilizado de
maneira incorreta o "allowEmpty" também.

Sem o "validationErrors" eu não enxergava onde estava o problema.
Depois disso, ficou simples hehehe

Obrigado!


On 11 Abr, 13:35, Marcelo F Andrade <mfandr...@gmail.com> wrote:
> 2012/4/11 Douglas <e.tisupo...@icos.com.br>:
Reply all
Reply to author
Forward
0 new messages