Solucionado (ver solução)
Solucionado
(ver solução)
14
respostas

Formatação de Moeda

Bom dia. A partir de um campo formatado para moeda (maskmoney) estou tentando fazer a inserção no BD mas não estou conseguindo. Alguém poderia dar uma luz? (abaixo copiei parte dos códigos)

produto-formulario

<div class="form-group">
        <label>Preço:</label>     
            <input type="text" name="preco" id="currency" class="form-control"  
               data-thousands="." data-decimal="," data-prefix="R$ "  
               value="<?=$produto->getPreco() ?>" required>

adiciona-produto

$produto = new Produto();
$produto->setCodigo($_POST["codigo"]) ;
$produto->setReferencia($_POST["referencia"]);
$produto->setNome($_POST["nome"]);
$produto->setPreco($_POST["preco"]);

produtoDAO

function insereProduto($produto) {
$query = "insert into produtos (codigo, referencia, nome, preco, peso, medida, ncm, descricao, marca_id, categoria_id, destaque) values ({$produto->getCodigo()}, '{$produto->getReferencia()}', '{$produto->getNome()}', {$produto->getPreco()}, {$produto->getPeso()}, '{$produto->getMedida()}', {$produto->getNcm()}, '{$produto->getDescricao()}', {$produto->getMarca()}, {$produto->getCategoria()}, {$produto->getDestaque()})";
return mysqli_query($this->conexao, $query);
}
14 respostas

O que acontece quando tenta inserir Sergio? Qual é o tipo da coluna no banco de dados?

Oi Wanderson, muito obrigado pelo seu retorno.

A coluna preco no BD está DECIMAL (10,2)

Quando tento incluir um produto ele retorna "produto não incluido" sem mencionar nenhum erro.

Antes de utilizar esse JS (maskmoney) eu conseguia fazer uma inclusão mas utilizando ponto e duas casas decimais.

Quando implementei esse maskmoney ficou show (automaticamente no campo preco) você só digita numeros e ele faz a máscara.

Mas agora acho que tenho que desfazer isso quando é enviado os dados para o adiciona-produto (se é isso mesmo que tem que ser feito) para poder incluir um produto no BD... e isso não sei como desfazer. Você poderia me ajudar?

Pode ser que seja um simples erro de tipo, tudo que vem do formulário está em string, se o campo é do tipo numérico, pode ser que o banco não insira. Experimenta usar a função number_format do php para converter o valor de string para decimal.

http://php.net/manual/en/function.number-format.php

Você pode usar isso dentro do setPreco().

Muito obrigado Wanderson, você poderia me ajudar mais um pouco, eu não sei onde colocar a função que você sugeriu e nem como substituir pela nova.

Seria no adiciona-produto, no produtoDAO ou na classe produto? Como eu encaixo lá esse formato? Não tenho nenhum exemplo na apostila FP-73 nem próximo disso.

string number_format ( float $number , int $decimals = 0 , string $dec_point = "." , string $thousands_sep = "," )

Opa Sergio, agora me toquei que essa função também retorna uma string. Na classe produto, você deve ter algo como:

public function setPreco($preco){
    $this->preco = $preco;
}

certo? Tenta fazer uma conversão do valor da seguinte forma:

public function setPreco($preco){
    $this->preco = (float) $preco;
}

Muito obrigado Wanderson,

Ele inseriu no BD, mas inseriu valor 0 (zero). Não o valor que eu digitei. Os demais campos foram gravados certinho. O que poderia ser? Onde eu tenho que corrigir?

Se inseriu 0 (zero) é por que o valor que tá chegando no post não é um valor conversível para número. Dá um var_dump($_POST) pra gente ver como esse número está saindo do formulário?

oi Wanderson segue teste:

array(12) { ["id"]=> string(0) "" ["codigo"]=> string(13) "2345345345345" ["nome"]=> string(14) "asdfsdfsadfsdf" ["referencia"]=> string(8) "4n27hnds" ["preco"]=> string(11) "R$ 4.523,45" ["peso"]=> string(4) "3245" ["medida"]=> string(4) "2345" ["ncm"]=> string(4) "2345" ["descricao"]=> string(10) "gtewrtwert" ["marca_id"]=> string(1) "1" ["categoria_id"]=> string(1) "1" ["destaque"]=> string(1) "2" } O Produto asdfsdfsadfsdf, R$ 0 Foi adicionado com sucesso!

Bem o que eu pensei, você tem que remover esse R$ antes de mandar pro baco Sergio, e esse ponto dos milhares também, deve ser usado como separador de casas decimais. O próprio plugin já resolve isso dessa forma: .maskMoney('unmasked')

Você deve usar essa função antes de submeter o formulário, ou, usar o data-affixes-stay="true", que pode resolver isso.

Obrigado Wanderson,

Seria dentro do campo preço que eu coloco o plugin?

Tentei no setPreco e não funcionou

public function setPreco($preco){
    $this->preco = (float) $preco;
.maskMoney('unmasked');
}

Não serio, o plugin é javascript e ele só funciona no navegador. Tenta no HTML usar o atributo que falei antes: data-affixes-stay="false"

Consegui Wanderson, mas ele não está incluindo os centavos. O que pode estar ocorrendo desta vez? Fiz o teste novamente e me parece que o cifrão (R$) não aparece mais no imput mas a virgula não alterou para ponto...

array(12) { ["id"]=> string(0) "" ["codigo"]=> string(17) "09458-04385-24385"
 ["nome"]=> string(24) "TESTE FORMATAÇÃO PRECO" 
["referencia"]=> string(8) "4n27hnds"
 ["preco"]=> string(6) "123,45"
["peso"]=> string(3) "123" 
["medida"]=> string(8) "12x12x12" 
["ncm"]=> string(3) "123"
 ["descricao"]=> string(16) "etyeyertyrtyetry"
 ["marca_id"]=> string(1) "1"
 ["categoria_id"]=> string(1) "1" 
["destaque"]=> string(1) "2" }
O Produto TESTE FORMATAÇÃO PRECO, R$ 123 Foi adicionado com sucesso!
solução!

Não funciona por que os decimais no banco é com ponto, não com vírgula. Vamos resolver isso assim. Remova o data-affixes-stay="false" do HTML e no set preço, use esse código aqui:

public function setPreco($preco){
  if(!is_numeric($preco)){
    $preco_convertido = str_replace("R$ ", "", $preco);
    $preco_convertido = str_replace(".", "", $preco_convertido);
    $preco_convertido = (float) str_replace(",", ".", $preco_convertido);
    $this->preco = $preco_convertido;
  }else {
    $this->preco = $preco;
  }
}

É uma solução básica, incompleta por que não trata todos os casos, mas funciona, já testei aqui. Depois cuide em melhorar esse código conforme avança nos estudos.

Wanderson, na mosca!!!!

Funcionou certinho.

Claro, vou melhorar sim. Todos esses ensinamentos estão me tornando melhor.

Muito obrigado mesmo

abraços