savar valor moterário e data no formato DB

117 views
Skip to first unread message

Cálcio

unread,
Jan 14, 2016, 6:29:13 AM1/14/16
to YFB - Yii Framework Brasil
Qual o melhor maneira e a mais simples de salvar um valor de moeda e data no MySQL?
No meu formulário eu tenho 2 entradas (data e moeda). Eu preciso preenchê-lo usando nosso formato e salve-o usando o formato DB.

Ex.:
Data (no form): 21/03/2016, Valor (no form): 1.587,69
Data (no DB): 2016/03/21, Valor (no DB): 1.587,69

Tenho as seguintes configurações

web.php
...
'language' => 'pt-br',
   
'components' => [
       
'formatter' => [
           
'class' => 'yii\i18n\Formatter',
           
'dateFormat' => 'php:d/m/Y',
           
'datetimeFormat' => 'php:d/m/Y H:i:s',
           
'timeFormat' => 'php:H:i:s',
           
'decimalSeparator' => ',',
           
'thousandSeparator' => '.',
           
'currencyCode' => 'R$',
       
],
       
/*
         * Antes de inserir os dados no banco, formatá-los para se tornarem compatíveis com determinados tipos de campos.
         */

       
'formatterDB' => [
           
'class' => 'yii\i18n\Formatter',
           
'dateFormat' => 'php:Y-m-d',
           
'datetimeFormat' => 'php:Y-m-d H:i:s',
           
'timeFormat' => 'php:H:i:s',
           
'decimalSeparator' => '.',
       
],
...

index.php
<?= GridView::widget([
       
'dataProvider' => $dataProvider,
       
'filterModel' => $searchModel,
       
'columns' => [
           
['class' => 'yii\grid\SerialColumn'],

           
'id',
           
'valor:currency',
           
'data:date',
           
// 'created_at:datetime',
           
// 'updated_at:datetime',

           
['class' => 'yii\grid\ActionColumn'],
       
],
   
]); ?>

alguma luz de como gravar isso certo e como no form na hora do update já vir formatado no nosso formato?


Cálcio

unread,
Jan 14, 2016, 6:39:35 AM1/14/16
to YFB - Yii Framework Brasil
Só para complementar, meu problema por enquanto está na validação, pois assim que digito 1.587,69 ele já dispara o erro “Valor” deve ser um número.
Então preciso passar por esse erro tb.

Carlos Alexandre Zucolli

unread,
Jan 14, 2016, 4:31:24 PM1/14/16
to yii-framew...@googlegroups.com
Boa noite Cálcio,

Como sabes, não conheço muito bem, porém encontrei este link sobre a Data que acho ser útil.


Valeu.

Carlos



Em qui, 14 de jan de 2016 às 09:39, Cálcio <calc...@gmail.com> escreveu:
Só para complementar, meu problema por enquanto está na validação, pois assim que digito 1.587,69 ele já dispara o erro “Valor” deve ser um número.
Então preciso passar por esse erro tb.

--
YFB - Yii Framework Brasil
04/2011: Anexos de até 250kb foram autorizados pelos membros da lista. Use com moderação.
---
Você recebeu essa mensagem porque está inscrito no grupo "YFB - Yii Framework Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para yii-framework-br...@googlegroups.com.
Para ver essa discussão na Web, acesse https://groups.google.com/d/msgid/yii-framework-brasil/f5b5225b-f6ac-4594-98be-91e012813fab%40googlegroups.com.
Para mais opções, acesse https://groups.google.com/d/optout.

Fábio Sales

unread,
Jan 14, 2016, 6:36:35 PM1/14/16
to yii-framew...@googlegroups.com
Cálcio,

Boa noite,

Na versão 1.1, utilizo a extensão i18n-datetime-behavior, que faz esse trabalho para mim. Aredito que deva existir algo semelhante na versão 2 do Yii.

Atenciosamente,

Fábio Sales
Analista de tecnologia da informação
www.desenvolvemos.net

Cálcio

unread,
Jan 15, 2016, 5:02:06 AM1/15/16
to YFB - Yii Framework Brasil
Valeu @Carlos e Fábio.
Essas duas formas já tentei. Repare que no web.php que postei tem a utilização do i18n.

Sobre o behavior, nosso camarada @Kilderson me passou uma classe de behavior que já foi implementada no meu projeto, criei tb um model base que extende de ActiveRecord e implementa o método behaviors

BaseModel.php
<?php

namespace app\models;

use Yii;
use yii\db\ActiveRecord;
use app\components\behaviors\DbAttributesFilterBehavior;

class BaseModel extends ActiveRecord
{
   
public function behaviors()
   
{
       
return [
           
'class' => DbAttributesFilterBehavior::className(),
       
];
   
}
}

O Modelo que estou tentando aplicar isso é o TesteModel.php que está exatamente assim:
<?php

namespace app\models;

use Yii;
use app\models\BaseModel;

/**
 * This is the model class for table "teste".
 *
 * @property integer $id
 * @property double $value
 * @property string $data
 */

class Teste extends BaseModel
{
   
/**
     * @inheritdoc
     */

   
public static function tableName()
   
{
       
return 'teste';
   
}

   
/**
     * @inheritdoc
     */

   
public function rules()
   
{
       
return [
           
[['value'], 'number'],
           
[['data'], 'safe'],
           
['data', 'date', 'format' => 'd/M/yyyy'],
       
];
   
}

   
/**
     * @inheritdoc
     */

   
public function attributeLabels()
   
{
       
return [
           
'id' => 'ID',
           
'value' => 'Valor',
           
'data' => 'Data',
       
];
   
}
}

Aparentemente deveria funcionar.
Mas está faltando algo com certeza e ñ identifiquei oq é.

Cálcio

unread,
Jan 15, 2016, 11:02:05 AM1/15/16
to YFB - Yii Framework Brasil
Resolvi parte do problema...

Não estou usando Behaviors. Simplesmente utilizei as rules usando Expressão Regulares. Segue como ficou meu rules() no model.

public function rules()
   
{
       
return [
           
[['value', 'data'], 'required'],
           
[['value', 'data'], 'trim'],
           
[['data'], 'string', 'max' => 10, 'min' => 10],
           
[['value'], 'number', 'numberPattern' => '/^(?:[1-9](?:[\d]{0,2}(?:\.[\d]{3})*|[\d]+)|0)(?:,[\d]{0,2})?$/'], //Aqui defini a expressão regular para aceitar 1.589,69

Cálcio

unread,
Jan 15, 2016, 11:04:47 AM1/15/16
to YFB - Yii Framework Brasil
Esqueci de colocar o resto do código...

No model ainda adicionei


   
public function beforeSave($insert) {
       
if (parent::beforeSave($insert)) {
            $this
->value = str_replace('.', '', $this->value);
            $this
->value = str_replace(',', '.', $this->value);
           
return true;
       
} else {
           
return false;
       
}
   
}


Sidney

unread,
Jan 15, 2016, 11:04:59 AM1/15/16
to yii-framew...@googlegroups.com
Há uma solicitação de 'melhoria' exatamente referente a isso Cálcio. O cebe postou um sugestão, talvez lhe sirva (similar ao que você fez mas parece ser mais global):



Atenciosamente,
Sidney Lins
------

--
YFB - Yii Framework Brasil
04/2011: Anexos de até 250kb foram autorizados pelos membros da lista. Use com moderação.
---
Você recebeu essa mensagem porque está inscrito no grupo "YFB - Yii Framework Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para yii-framework-br...@googlegroups.com.

Cálcio

unread,
Jan 15, 2016, 11:25:17 AM1/15/16
to YFB - Yii Framework Brasil
É eu vi lá.

Agora está faltando conseguir ajustar a data e achar de novo como formatar no fomulário na hora do update.

Sidney

unread,
Jan 15, 2016, 3:44:57 PM1/15/16
to yii-framew...@googlegroups.com
Mas você não disse que está usando um Behavior pra formatar? Pra formatar no update não seria no evento afterFind? O behavior que citou não é pra isso? Me perdi no real problema agora! rsss

Nas minhas horas vagas estou trabalhando em um módulo de reservas, mas por enquanto estou na parte estritamente funcional, então estou usando datas e valores no formato americano pois não é a preocupação no momento. Mas logo vou chegar nesse ponto, então este tópico vai ser útil. Então, "tamo junto" (no que eu puder ajudar, pelo menos).


Atenciosamente,
Sidney Lins
------

Em 15 de janeiro de 2016 14:25, Cálcio <calc...@gmail.com> escreveu:
É eu vi lá.

Agora está faltando conseguir ajustar a data e achar de novo como formatar no fomulário na hora do update.

--
YFB - Yii Framework Brasil
04/2011: Anexos de até 250kb foram autorizados pelos membros da lista. Use com moderação.
---
Você recebeu essa mensagem porque está inscrito no grupo "YFB - Yii Framework Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para yii-framework-br...@googlegroups.com.

Sidney

unread,
Jan 15, 2016, 4:03:48 PM1/15/16
to yii-framew...@googlegroups.com
Independente de qualquer coisa, uma outra possibilidade é usar dois campos, o original e outro apenas para fins de exibição (sugestão que por sinal foi recomendada pelo próprio qiang, tanto no Yii 1 como no 2. 


Atenciosamente,
Sidney Lins
------

Cálcio

unread,
Jan 18, 2016, 8:11:08 AM1/18/16
to YFB - Yii Framework Brasil
E aí Sidney, blz?

Então. Eu tentei usar o behaviors para fazer essas conversões de valores monetários e data, porém ñ consegui fazer rodar. Então a solução que achei para os valores monetários foi mudando as rules e usar o beforeSave().
Porém ñ tentei nada do tipo para data.

Estou muito perdido ainda nesses conceitos de bahaviors e esses métodos de *save() do Yii. A ficha não caiu.


Uma coisa que não entendi pra que realmente serve o formatter e formatterDB dentro de componentes:
'components' => [
        'formatter' => [
            'class' => 'yii\i18n\Formatter',
            'dateFormat' => 'php:d/m/Y',
            'datetimeFormat' => 'php:d/m/Y H:i:s',
            'timeFormat' => 'php:H:i:s',
            'decimalSeparator' => ',',
            'thousandSeparator' => '.',
            'currencyCode' => '',
        ],


Na teoria ele deveria resolver esses problemas de conversão, já que se usa a classe yii\i18n\Formatter. mas não é o que acontece.

Sidney

unread,
Jan 19, 2016, 10:48:03 AM1/19/16
to yii-framew...@googlegroups.com
E aí Cálcio!

Tanto o formatter como o formatterDB são o mesmo componente. Eles não vão funcionar automaticamente nesse caso, até onde eu sei. Nos eventos certos, vc deve chamar "Yii::$app->formatter->asDate('2014-01-01');" ou "Yii::$app->formatterDB->asDate('2014-01-01');".



Atenciosamente,
Sidney Lins
------

--
YFB - Yii Framework Brasil
04/2011: Anexos de até 250kb foram autorizados pelos membros da lista. Use com moderação.
---
Você recebeu essa mensagem porque está inscrito no grupo "YFB - Yii Framework Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para yii-framework-br...@googlegroups.com.

ancker (gmail)

unread,
Jan 19, 2016, 11:12:22 AM1/19/16
to yii-framew...@googlegroups.com
Em componentes de data uso assim:

$form->field($model, 'dataIda')->widget(DateControl::classname(), [
                    'saveFormat' => 'php:U'
                ])->label('Data da Viagem');


E não tenho problemas...

Cálcio

unread,
Jan 19, 2016, 1:24:04 PM1/19/16
to YFB - Yii Framework Brasil
@Sidney pior q já tinha visto essa página q passou mas ela me deixou + confuso do que esclareceu as coisas. rs
Ela parece que é para a view ou algo assim e não faz a conversão do padrão BR para o padrão do banco.

@ancker, precisa declarar algum widget na classe? Se sim. Qual?
Tentei de forma direta como está no seu exemplo e deu erro de class not fount, daí tentei declarar DateControl e Date e tb ñ funcionou.

ancker (gmail)

unread,
Jan 19, 2016, 1:44:55 PM1/19/16
to yii-framew...@googlegroups.com
@calcio,

Eu uso os componentes do kartik e salvo no BD mysql quase tudo relacionado a data como timestamp (php:U)...
O exemplo a seguir mostra um datepicker no formato dd-mm-yyyy mas manda para o controller o timestamp do que foi selecionado.

na view:
(...)
use kartik\datecontrol\DateControl;
(...)
<?=

                $form->field($model, 'dataIda')->widget(DateControl::classname(), [
                    'saveFormat' => 'php:U'
                ])->label('Data da Viagem');
                ?>

no main-local.php:
(...)
use kartik\datecontrol\Module;
(...)
'modules' => [
(...)
        'datecontrol' => [
            'class' => 'kartik\datecontrol\Module',
            // format settings for displaying each date attribute (ICU format example)
            'displaySettings' => [
                Module::FORMAT_DATE => 'php:d-M-Y',
                Module::FORMAT_TIME => 'HH:mm:ss a',
                Module::FORMAT_DATETIME => 'dd-MM-yyyy HH:mm:ss a',
            ],
            // format settings for saving each date attribute (PHP format example)
            'saveSettings' => [
                //Module::FORMAT_DATE => 'php:U', // saves as unix timestamp
                Module::FORMAT_DATE => 'php:d-m-Y',
                Module::FORMAT_TIME => 'php:H:i:s',
                Module::FORMAT_DATETIME => 'php:Y-m-d H:i:s',
            ],
            // set your display timezone
            'displayTimezone' => 'America/Sao_Paulo',
            // set your timezone for date saved to db
            //'saveTimezone' => 'UTC',
            'saveTimezone' => 'America/Sao_Paulo',
            // automatically use kartik\widgets for each of the above formats
            'autoWidget' => true,
            // use ajax conversion for processing dates from display format to save format.
            'ajaxConversion' => true,
            // default settings for each widget from kartik\widgets used when autoWidget is true
            'autoWidgetSettings' => [
                Module::FORMAT_DATE => [
                    'options' => ['placeholder' => 'Selecione a data ...'],
                    'pluginOptions' => [
                        'autoclose' => true,
                        'todayHighlight' => true,
                        'todayBtn' => true
                    ]],
                Module::FORMAT_DATETIME => [], // setup if needed
                Module::FORMAT_TIME => [], // setup if needed
            ],
        // other settings
        ],
(...)
]
--
YFB - Yii Framework Brasil
04/2011: Anexos de até 250kb foram autorizados pelos membros da lista. Use com moderação.
---
Você recebeu essa mensagem porque está inscrito no grupo "YFB - Yii Framework Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para yii-framework-br...@googlegroups.com.

Sidney

unread,
Jan 19, 2016, 4:03:30 PM1/19/16
to yii-framew...@googlegroups.com
Ancker, achei bem legal essa opção 'saveFormat' do widget do kartik (não conheço muito as extensões dele, apesar de serem super famosas). Foi uma ótima ideia. No meu caso, prefiro evitar extensões de terceiros onde é possível, então quando eu for fazer as conversões, vou juntar o que você disse e tentar implementar a mesma funcionalidade usando 'altField' e 'altFormat' do próprio DatePicker JUI. 

Resumindo, ao exibir: formatter, e nos forms: datepicker com o altField. Ao validar, valido sempre no formato do banco e o cliente pode escolher usando as configurações regionalizadas já que por fim os dados devolvidos serão os do altField no formato altFormat.

Cálcio, acho que por enquanto não posso tentar ajudar em mais nada. Vou ficar apenas observando o tópico. ;)


Atenciosamente,
Sidney Lins
------

Reply all
Reply to author
Forward
0 new messages