Lançado Adianti Framework 7.6!
Clique aqui para saber mais
Formulário mestre detalhe, com dois detalhes Boa noite... Estou precisando fazer um formulário de cadastro de clientes, que tenha dois "detalhes", ou seja, um onde possa cadastrar os contatos e outro as filiais. Na parte visual até consegui colocar o formulário mestre detalhe, com os dois detalhes, mas não grava a área de baixo, segue o código: ...
WF
Formulário mestre detalhe, com dois detalhes  
Boa noite...
Estou precisando fazer um formulário de cadastro de clientes, que tenha dois "detalhes", ou seja, um onde possa cadastrar os contatos e outro as filiais.
Na parte visual até consegui colocar o formulário mestre detalhe, com os dois detalhes, mas não grava a área de baixo,

segue o código:
  1. <?php
  2. /**
  3.  * cadastro_de_clientes Master/Detail
  4.  * @author  <your name here>
  5.  */
  6. class cadastro_de_clientes extends TPage
  7. {
  8.     protected $form// form
  9.     protected $detail_list;
  10.     
  11.     /**
  12.      * Page constructor
  13.      */
  14.     public function __construct()
  15.     {
  16.         parent::__construct();
  17.         
  18.         // creates the form
  19.         $this->form = new BootstrapFormBuilder('form_cliente');
  20.         $this->form->setFormTitle('cliente');
  21.         
  22.         // master fields
  23.         $id = new TEntry('id');
  24.         $status = new TEntry('status');
  25.         $cnpj = new TEntry('cnpj');
  26.         $ie = new TEntry('ie');
  27.         $im = new TEntry('im');
  28.         $nome_fantasia = new TEntry('nome_fantasia');
  29.         $rz_social = new TEntry('rz_social');
  30.         $cep = new TEntry('cep');
  31.         $endereco = new TEntry('endereco');
  32.         $numero = new TEntry('numero');
  33.         $complemento = new TEntry('complemento');
  34.         $bairro = new TEntry('bairro');
  35.         $uf = new TEntry('uf');
  36.         $cidade_id = new TCombo('cidade_id''banco''cidade''id''nome');
  37.         // detail fields
  38.         $detail_id = new THidden('detail_id');
  39.         $detail_nome = new TEntry('detail_nome');
  40.         $detail_area_de_contato = new TEntry('detail_area_de_contato');
  41.         $detail_email = new TEntry('detail_email');
  42.         $detail_telefone = new TEntry('detail_telefone');
  43.         $detail_radio = new TEntry('detail_radio');
  44.         
  45.         
  46.         
  47.          // filial fields
  48.         $filial_id = new THidden('filial_id');
  49.         $filial_cnpj = new TEntry('filial_cnpj');
  50.         $filial_rz_social = new TEntry('filial_rz_social');
  51.         $filial_nome_fantasia = new TEntry('filial_nome_fantasia');
  52.         
  53.         
  54.         
  55.         if (!empty($id))
  56.         {
  57.             $id->setEditable(FALSE);
  58.         }
  59.         
  60.         // master fields
  61.         $this->form->addFields( [new TLabel('Código')], [$id] );
  62.         $this->form->addFields( [new TLabel('Status')], [$status] );
  63.         $this->form->addFields( [new TLabel('CNPJ')], [$cnpj] );
  64.         $this->form->addFields( [new TLabel('I.E')], [$ie] );
  65.         $this->form->addFields( [new TLabel('I.M')], [$im] );
  66.         $this->form->addFields( [new TLabel('Nome Fantasia')], [$nome_fantasia] );
  67.         $this->form->addFields( [new TLabel('Razão Social')], [$rz_social] );
  68.         $this->form->addFields( [new TLabel('CEP')], [$cep] );
  69.         $this->form->addFields( [new TLabel('Endereço')], [$endereco] );
  70.         $this->form->addFields( [new TLabel('Número')], [$numero] );
  71.         $this->form->addFields( [new TLabel('Complemento')], [$complemento] );
  72.         $this->form->addFields( [new TLabel('Bairro')], [$bairro] );
  73.         $this->form->addFields( [new TLabel('U.F')], [$uf] );
  74.         $this->form->addFields( [new TLabel('Cidade')], [$cidade_id] );
  75.         
  76.         // detail fields
  77.         $this->form->addContent( ['<h4>Contatos</h4><hr>'] );
  78.         $this->form->addFields( [$detail_id] );
  79.         
  80.         $this->form->addFields( [new TLabel('Nome')], [$detail_nome] );
  81.         $this->form->addFields( [new TLabel('Área')], [$detail_area_de_contato] );
  82.         $this->form->addFields( [new TLabel('Email')], [$detail_email] );
  83.         $this->form->addFields( [new TLabel('Telefone')], [$detail_telefone] );
  84.         $this->form->addFields( [new TLabel('Rádio')], [$detail_radio] );
  85.         $add TButton::create('add', [$this'onSaveDetail'], 'Register''fa:save');
  86.         $this->form->addFields( [], [$add] )->style 'background: whitesmoke; padding: 5px; margin: 1px;';
  87.         
  88.         $this->detail_list = new BootstrapDatagridWrapper(new TQuickGrid);
  89.         $this->detail_list->style "min-width: 700px; width:100%;margin-bottom: 10px";
  90.         $this->detail_list->setId('cliente_list');
  91.         
  92.         // items
  93.         $this->detail_list->addQuickColumn('Nome''nome''left'100);
  94.         $this->detail_list->addQuickColumn('Área''area_de_contato''left'100);
  95.         $this->detail_list->addQuickColumn('Email''email''left'100);
  96.         $this->detail_list->addQuickColumn('Telefone''telefone''left'100);
  97.         $this->detail_list->addQuickColumn('Rádio''radio''left'100);
  98.         // detail actions
  99.         $this->detail_list->addQuickAction'Edit',   new TDataGridAction([$this'onEditDetail']),   'id''fa:edit blue');
  100.         $this->detail_list->addQuickAction'Delete', new TDataGridAction([$this'onDeleteDetail']), 'id''fa:trash red');
  101.         $this->detail_list->createModel();
  102.         
  103.         $panel = new TPanelGroup;
  104.         $panel->add($this->detail_list);
  105.         $panel->getBody()->style 'overflow-x:auto';
  106.         $this->form->addContent( [$panel] );
  107.         
  108.         
  109.         
  110.         // filial fields
  111.         $this->form->addContent( ['<h4>filiais</h4><hr>'] );
  112.         $this->form->addFields( [$filial_id] );
  113.         
  114.         $this->form->addFields( [new TLabel('Cnpj')], [$filial_cnpj] );
  115.         $this->form->addFields( [new TLabel('Rz Social')], [$filial_rz_social] );
  116.         $this->form->addFields( [new TLabel('Nome Fantasia')], [$filial_nome_fantasia] );
  117.         $addd TButton::create('addd', [$this'onSavefilial'], 'Register''fa:save');
  118.         $this->form->addFields( [], [$addd] )->style 'background: whitesmoke; padding: 5px; margin: 1px;';
  119.         
  120.         $this->filial_list = new BootstrapDatagridWrapper(new TQuickGrid);
  121.         $this->filial_list->style "min-width: 700px; width:100%;margin-bottom: 10px";
  122.         $this->filial_list->setId('cliente_list');
  123.         
  124.         // items
  125.         $this->filial_list->addQuickColumn('Cnpj''cnpj''left'100);
  126.         $this->filial_list->addQuickColumn('Rz Social''rz_social''left'100);
  127.         $this->filial_list->addQuickColumn('Nome Fantasia''nome_fantasia''left'100);
  128.         // filial actions
  129.         $this->filial_list->addQuickAction'Edit',   new TDataGridAction([$this'onEditfilial']),   'id''fa:edit blue');
  130.         $this->filial_list->addQuickAction'Delete', new TDataGridAction([$this'onDeletefilial']), 'id''fa:trash red');
  131.         $this->filial_list->createModel();
  132.         
  133.         $painel = new TPanelGroup;
  134.         $painel->add($this->filial_list);
  135.         $painel->getBody()->style 'overflow-x:auto';
  136.         $this->form->addContent( [$painel] );
  137.         
  138.         
  139.         
  140.         $btn $this->form->addAction_t('Save'),  new TAction([$this'onSave']), 'fa:save');
  141.         $btn->class 'btn btn-sm btn-primary';
  142.         $this->form->addAction_t('Clear'), new TAction([$this'onClear']), 'fa:eraser red');
  143.         
  144.         
  145.         
  146.         
  147.         
  148.         
  149.         // create the page container
  150.         $container = new TVBox;
  151.         $container->style 'width: 90%';
  152.         $container->add(new TXMLBreadCrumb('menu.xml'__CLASS__));
  153.         $container->add($this->form);
  154.         parent::add($container);
  155.     }
  156.     
  157.     
  158.     
  159.     /**
  160.      * Clear form
  161.      * @param $param URL parameters
  162.      */
  163.     public function onClear($param)
  164.     {
  165.         $this->form->clear(TRUE);
  166.         TSession::setValue(__CLASS__.'_items', array());
  167.         $this->onReload$param );
  168.     }
  169.     
  170.     
  171.     
  172.     
  173.     
  174.      public function onSavefilial$param )
  175.     {
  176.         try
  177.         {
  178.             TTransaction::open('banco');
  179.             $data $this->form->getData();
  180.             
  181.             /** validation sample
  182.             if (empty($data->fieldX))
  183.             {
  184.                 throw new Exception('The field fieldX is required');
  185.             }
  186.             **/
  187.             
  188.             $item TSession::getValue(__CLASS__.'_item');
  189.             $key = empty($data->filial_id) ? 'X'.mt_rand(10000000001999999999) : $data->filial_id;
  190.             
  191.             $item$key ] = array();
  192.             $item$key ]['id'] = $key;
  193.             $item$key ]['cnpj'] = $data->filial_cnpj;
  194.             $item$key ]['rz_social'] = $data->filial_rz_social;
  195.             $item$key ]['nome_fantasia'] = $data->filial_nome_fantasia;
  196.             
  197.             TSession::setValue(__CLASS__.'_items'$items);
  198.             
  199.             // clear filial form fields
  200.             $data->filial_id '';
  201.             $data->filial_cnpj '';
  202.             $data->filial_rz_social '';
  203.             $data->filial_nome_fantasia '';
  204.             
  205.             TTransaction::close();
  206.             $this->form->setData($data);
  207.             
  208.             $this->onReload$param ); // reload the items
  209.         }
  210.         catch (Exception $e)
  211.         {
  212.             $this->form->setData$this->form->getData());
  213.             new TMessage('error'$e->getMessage());
  214.         }
  215.     }
  216.     
  217.     /**
  218.      * Load an item from session list to filial form
  219.      * @param $param URL parameters
  220.      */
  221.     public static function onEditfilial$param )
  222.     {
  223.         // read session items
  224.         $items TSession::getValue(__CLASS__.'_items');
  225.         
  226.         // get the session item
  227.         $item $items$param['key'] ];
  228.         
  229.         $data = new stdClass;
  230.         $data->filial_id $item['id'];
  231.         $data->filial_cnpj $item['cnpj'];
  232.         $data->filial_rz_social $item['rz_social'];
  233.         $data->filial_nome_fantasia $item['nome_fantasia'];
  234.         
  235.         // fill filial fields
  236.         TForm::sendData'form_cliente'$data );
  237.     }
  238.     
  239.     /**
  240.      * Delete an item from session list
  241.      * @param $param URL parameters
  242.      */
  243.     public static function onDeletefilial$param )
  244.     {
  245.         // reset items
  246.         $data = new stdClass;
  247.             $data->filial_cnpj '';
  248.             $data->filial_rz_social '';
  249.             $data->filial_nome_fantasia '';
  250.         
  251.         // clear form data
  252.         TForm::sendData('form_cliente'$data );
  253.         
  254.         // read session items
  255.         $items TSession::getValue(__CLASS__.'_items');
  256.         
  257.         // get filial id
  258.         $filial_id $param['key'];
  259.         
  260.         // delete the item from session
  261.         unset($items$filial_id ] );
  262.         
  263.         // rewrite session items
  264.         TSession::setValue(__CLASS__.'_items'$items);
  265.         
  266.         // delete item from screen
  267.         TScript::create("ttable_remove_row_by_id('cliente_list', '{$filial_id}')");
  268.     }
  269.     
  270.     
  271.     
  272.     
  273.     
  274.     
  275.     /**
  276.      * Save an item from form to session list
  277.      * @param $param URL parameters
  278.      */
  279.     public function onSaveDetail$param )
  280.     {
  281.         try
  282.         {
  283.             TTransaction::open('banco');
  284.             $data $this->form->getData();
  285.             
  286.             /** validation sample
  287.             if (empty($data->fieldX))
  288.             {
  289.                 throw new Exception('The field fieldX is required');
  290.             }
  291.             **/
  292.             
  293.             $items TSession::getValue(__CLASS__.'_items');
  294.             $key = empty($data->detail_id) ? 'X'.mt_rand(10000000001999999999) : $data->detail_id;
  295.             
  296.             $items$key ] = array();
  297.             $items$key ]['id'] = $key;
  298.             $items$key ]['nome'] = $data->detail_nome;
  299.             $items$key ]['area_de_contato'] = $data->detail_area_de_contato;
  300.             $items$key ]['email'] = $data->detail_email;
  301.             $items$key ]['telefone'] = $data->detail_telefone;
  302.             $items$key ]['radio'] = $data->detail_radio;
  303.             
  304.             TSession::setValue(__CLASS__.'_items'$items);
  305.             
  306.             // clear detail form fields
  307.             $data->detail_id '';
  308.             $data->detail_nome '';
  309.             $data->detail_area_de_contato '';
  310.             $data->detail_email '';
  311.             $data->detail_telefone '';
  312.             $data->detail_radio '';
  313.             
  314.             TTransaction::close();
  315.             $this->form->setData($data);
  316.             
  317.             $this->onReload$param ); // reload the items
  318.         }
  319.         catch (Exception $e)
  320.         {
  321.             $this->form->setData$this->form->getData());
  322.             new TMessage('error'$e->getMessage());
  323.         }
  324.     }
  325.     
  326.     /**
  327.      * Load an item from session list to detail form
  328.      * @param $param URL parameters
  329.      */
  330.     public static function onEditDetail$param )
  331.     {
  332.         // read session items
  333.         $items TSession::getValue(__CLASS__.'_items');
  334.         
  335.         // get the session item
  336.         $item $items$param['key'] ];
  337.         
  338.         $data = new stdClass;
  339.         $data->detail_id $item['id'];
  340.         $data->detail_nome $item['nome'];
  341.         $data->detail_area_de_contato $item['area_de_contato'];
  342.         $data->detail_email $item['email'];
  343.         $data->detail_telefone $item['telefone'];
  344.         $data->detail_radio $item['radio'];
  345.         
  346.         // fill detail fields
  347.         TForm::sendData'form_cliente'$data );
  348.     }
  349.     
  350.     /**
  351.      * Delete an item from session list
  352.      * @param $param URL parameters
  353.      */
  354.     public static function onDeleteDetail$param )
  355.     {
  356.         // reset items
  357.         $data = new stdClass;
  358.             $data->detail_nome '';
  359.             $data->detail_area_de_contato '';
  360.             $data->detail_email '';
  361.             $data->detail_telefone '';
  362.             $data->detail_radio '';
  363.         
  364.         // clear form data
  365.         TForm::sendData('form_cliente'$data );
  366.         
  367.         // read session items
  368.         $items TSession::getValue(__CLASS__.'_items');
  369.         
  370.         // get detail id
  371.         $detail_id $param['key'];
  372.         
  373.         // delete the item from session
  374.         unset($items$detail_id ] );
  375.         
  376.         // rewrite session items
  377.         TSession::setValue(__CLASS__.'_items'$items);
  378.         
  379.         // delete item from screen
  380.         TScript::create("ttable_remove_row_by_id('cliente_list', '{$detail_id}')");
  381.     }
  382.     
  383.     /**
  384.      * Load the items list from session
  385.      * @param $param URL parameters
  386.      */
  387.     public function onReload($param)
  388.     {
  389.         // read session items
  390.         $items TSession::getValue(__CLASS__.'_items');
  391.         
  392.         $this->detail_list->clear(); // clear detail list
  393.         
  394.         if ($items)
  395.         {
  396.             foreach ($items as $list_item)
  397.             {
  398.                 $item = (object) $list_item;
  399.                 
  400.                 $row $this->detail_list->addItem$item );
  401.                 $row->id $list_item['id'];
  402.             }
  403.         }
  404.         
  405.         $this->loaded TRUE;
  406.     }
  407.     
  408.     /**
  409.      * Load Master/Detail data from database to form/session
  410.      */
  411.     public function onEdit($param)
  412.     {
  413.         try
  414.         {
  415.             TTransaction::open('banco');
  416.             
  417.             if (isset($param['key']))
  418.             {
  419.                 $key $param['key'];
  420.                 
  421.                 $object = new cliente($key);
  422.                 $items  contato_clientes::where('cliente_id''='$key)->load();
  423.                 
  424.                 $session_items = array();
  425.                 foreach( $items as $item )
  426.                 {
  427.                     $item_key $item->id;
  428.                     $session_items[$item_key] = $item->toArray();
  429.                     $session_items[$item_key]['id'] = $item->id;
  430.                     $session_items[$item_key]['nome'] = $item->nome;
  431.                     $session_items[$item_key]['area_de_contato'] = $item->area_de_contato;
  432.                     $session_items[$item_key]['email'] = $item->email;
  433.                     $session_items[$item_key]['telefone'] = $item->telefone;
  434.                     $session_items[$item_key]['radio'] = $item->radio;
  435.                 }
  436.                 TSession::setValue(__CLASS__.'_items'$session_items);
  437.                 
  438.                 $this->form->setData($object); // fill the form with the active record data
  439.                 $this->onReload$param ); // reload items list
  440.                 TTransaction::close(); // close transaction
  441.             }
  442.             else
  443.             {
  444.                 $this->form->clear(TRUE);
  445.                 TSession::setValue(__CLASS__.'_items'null);
  446.                 $this->onReload$param );
  447.             }
  448.         }
  449.         catch (Exception $e// in case of exception
  450.         {
  451.             new TMessage('error'$e->getMessage());
  452.             TTransaction::rollback();
  453.         }
  454.     }
  455.     
  456.     /**
  457.      * Save the Master/Detail data from form/session to database
  458.      */
  459.     public function onSave()
  460.     {
  461.         try
  462.         {
  463.             // open a transaction with database
  464.             TTransaction::open('banco');
  465.             
  466.             $data $this->form->getData();
  467.             $master = new cliente;
  468.             $master->fromArray( (array) $data);
  469.             $this->form->validate(); // form validation
  470.             
  471.             $master->store(); // save master object
  472.             // delete details
  473.             $old_items contato_clientes::where('cliente_id''='$master->id)->load();
  474.             
  475.             $keep_items = array();
  476.             
  477.             // get session items
  478.             $items TSession::getValue(__CLASS__.'_items');
  479.             
  480.             if( $items )
  481.             {
  482.                 foreach( $items as $item )
  483.                 {
  484.                     if (substr($item['id'],0,1) == 'X' // new record
  485.                     {
  486.                         $detail = new contato_clientes;
  487.                     }
  488.                     else
  489.                     {
  490.                         $detail contato_clientes::find($item['id']);
  491.                     }
  492.                     $detail->nome  $item['nome'];
  493.                     $detail->area_de_contato  $item['area_de_contato'];
  494.                     $detail->email  $item['email'];
  495.                     $detail->telefone  $item['telefone'];
  496.                     $detail->radio  $item['radio'];
  497.                     $detail->cliente_id $master->id;
  498.                     $detail->store();
  499.                     
  500.                     $keep_items[] = $detail->id;
  501.                 }
  502.             }
  503.             
  504.             if ($old_items)
  505.             {
  506.                 foreach ($old_items as $old_item)
  507.                 {
  508.                     if (!in_array$old_item->id$keep_items))
  509.                     {
  510.                         $old_item->delete();
  511.                     }
  512.                 }
  513.             }
  514.             TTransaction::close(); // close the transaction
  515.             
  516.             // reload form and session items
  517.             $this->onEdit(array('key'=>$master->id));
  518.             
  519.             new TMessage('info'TAdiantiCoreTranslator::translate('Record saved'));
  520.         }
  521.         catch (Exception $e// in case of exception
  522.         {
  523.             new TMessage('error'$e->getMessage());
  524.             $this->form->setData$this->form->getData() ); // keep form data
  525.             TTransaction::rollback();
  526.         }
  527.     }
  528.     
  529.     /**
  530.      * Show the page
  531.      */
  532.     public function show()
  533.     {
  534.         // check if the datagrid is already loaded
  535.         if (!$this->loaded AND (!isset($_GET['method']) OR $_GET['method'] !== 'onReload') )
  536.         {
  537.             $this->onReloadfunc_get_arg(0) );
  538.         }
  539.         parent::show();
  540.     }
  541. }

Pacotão Dominando o Adianti Framework 7
O material mais completo de treinamento do Framework.
Curso em vídeo aulas + Livro completo + Códigos fontes do projeto ERPHouse.
Conteúdo Atualizado! Versão 7.4


Dominando o Adianti 7 Quero me inscrever agora!

Comentários (8)


NR

Os dados dos detalhes são salvos temporiamente na sessão. Cada detalhe precisa de uma chave específica para essa gravação. Aparentemente está usando a mesma para os dois:
  1. <?php
  2. $items TSession::getValue(__CLASS__.'_items');
  3. ?>

Além disso você vai ter que duplicar os tratamentos em alguns funções. Na onReload por exemplo, que é quem exibe os detalhes nas grids, você precisa adicionar mais um foreach para os itens do segundo detalhe. Mesma coisa na onSave, onEdit, etc.
CC

Olá Wempar.
Passei pelo mesmo processo que voce. Estão faltando alguns detalhes no seu form. começando lá em cima com a falta de uma variével para as filiais

  1. <?php
  2.     protected $form// form
  3.     protected $detail_list;
  4. ?>


ficaria assim:
  1. <?php
  2.     protected $form// form
  3.     protected $detail_list;
  4.     protected $detail_filial;
  5. ?>


e mais alguns outros detalhes.

Vou passar aqui meu código na integra pra voce dar uma olhada e adequar para sua necessidade.

  1. <?php
  2. /**
  3.  * VendaForm Master/Detail
  4.  * @author  <your name here>
  5.  */
  6. class VendaForm extends TPage
  7. {
  8.     protected $form// form
  9.     protected $detail_list;
  10.     protected $detail_receber;
  11.    // private $datagrid; // listing
  12.     
  13.     /**
  14.      * Page constructor
  15.      */
  16.     public function __construct()
  17.     {
  18.         parent::__construct();
  19.         
  20.         // creates the form
  21.         $this->form = new BootstrapFormBuilder('form_Venda');
  22.         $this->form->setFormTitle('Venda - '.TSession::getValue('unit_name'));
  23.         
  24.         // create criteria filtro licenciada
  25.         $criteria = new TCriteria;
  26.         $criteria->add(new TFilter('id_licenciada ','=',  TSession::getValue('userunitid')));
  27.         
  28.         // master fields
  29.         $id_venda = new THidden('id_venda');
  30.         $codigo = new TEntry('codigo');
  31.         $data_hora = new TDate('data_hora');
  32.         $data_hora->setMask('dd/mm/yyyy'); 
  33.         $venda_status = new TDBCombo('id_venda_status','sgd','VendaStatus','id_venda_status','descricao','descricao');
  34.         $data_vencimento = new TDate('data_vencimento');
  35.         $data_vencimento->setMask('dd/mm/yyyy'); 
  36.         $id_cliente = new TDBUniqueSearch('id_cliente''sgd''Cliente''id_cliente''nome''nome'$criteria);
  37.         $id_transportadora = new TDBUniqueSearch('id_transportadora''sgd''Transportadora''id_transportadora''nome_fantasia''nome_fantasia'$criteria);
  38.         $taxa_delivery = new TEntry('taxa_delivery');
  39.         $taxa_delivery->setNumericMask('2',',','.',TRUE);
  40.         $taxa_delivery->setSize('100');
  41.         $codigo->setEditable(FALSE);
  42.         $codigo->setSize('60');
  43.         $venda_status->setSize('300');
  44.         $observacao = new TText('observacao');
  45.         $ativo = new TRadioGroup('ativo');
  46.         $ativo->addItems( ['S'=>'Ativo''N'=>'Inativo'] );
  47.         $ativo->setLayout('horizontal');
  48.         $ativo->setUseButton();
  49.         // detail fields
  50.         
  51.         $detail_id_movimento_item = new THidden('detail_id_movimento_item');
  52.         $detail_id_produto = new TDBUniqueSearch('detail_id_produto''sgd''Produto''id_produto''descricao''descricao'$criteria );
  53.         $detail_id_produto->setMinLength(1);
  54.         $detail_id_produto->setChangeAction(new TAction([$this,'onProductChange']));        
  55.         $detail_nome_produto = new TEntry('detail_nome_produto');
  56.         $detail_quantidade = new TEntry('detail_quantidade');
  57.         $detail_unidade = new TEntry('detail_unidade');
  58.         $detail_valor = new TEntry('detail_valor');
  59.         $detail_valor->setNumericMask(2,',''.'TRUE);
  60.         $detail_id_produto->setSize('100%');
  61.         $detail_nome_produto->setSize('300');
  62.         $detail_nome_produto->setEditable(false);
  63.         $detail_quantidade->setSize('40');
  64.         $detail_valor->setSize('100');
  65.         if (!empty($id_venda))
  66.         {
  67.             $id_venda->setEditable(FALSE);
  68.         }
  69.         
  70.         // master fields
  71.         $this->form->addFields( [''], [$id_venda] );
  72.         $this->form->addFields( [new TLabel('Codigo')], [$codigo] );
  73.         $this->form->addFields( [new TLabel('Status Venda')], [$venda_status] );
  74.         $this->form->addFields( [new TLabel('Data Pedido')], [$data_hora] );
  75.         $this->form->addFields( [new TLabel('Data Vencimento')], [$data_vencimento] );
  76.         $this->form->addFields( [new TLabel('Cliente')], [$id_cliente] );
  77.         $this->form->addFields( [new TLabel('Transportadora')], [$id_transportadora] );
  78.         $this->form->addFields( [new TLabel('Valor Frete')], [$taxa_delivery] );
  79.         $this->form->addFields( [new TLabel('Observação')], [$observacao] );
  80.         $this->form->addFields( [new TLabel('Ativo')], [$ativo] );
  81.         
  82.         // detail fields
  83.         $this->form->addContent( ['<h4>Produtos</h4><hr>'] );
  84.         $this->form->addFields( [$detail_id_movimento_item] );
  85.         $this->form->addFields( [new TLabel('Produto')], [$detail_id_produto] );
  86.         $this->form->addFields( [new TLabel('Valor')], [$detail_valor] );
  87.         $this->form->addFields( [new TLabel('Quantidade')], [$detail_quantidade] );
  88.         $add TButton::create('add', [$this'onSaveDetail'], 'Registrar''fa:save');
  89.         $this->form->addFields( [], [$add] )->style 'background: whitesmoke; padding: 5px; margin: 1px;';
  90.         
  91.         $this->detail_list = new BootstrapDatagridWrapper(new TQuickGrid);
  92.         $this->detail_list->style "min-width: 700px; width:100%;margin-bottom: 10px";
  93.         $this->detail_list->setId('Venda_list');
  94.         
  95.         // items
  96.         $cd $this->detail_list->addQuickColumn('Cod''id_produto''right'100);
  97.         $pr $this->detail_list->addQuickColumn('Produto''id_produto''left'100);
  98.         $this->detail_list->addQuickColumn('Quantidade''quantidade''right'100);
  99.         $this->detail_list->addQuickColumn('UN''unidade''right'100);
  100.         $vl $this->detail_list->addQuickColumn('Valor''valor''right'100);
  101.         $st $this->detail_list->addQuickColumn('Subtotal''={valor} * {quantidade}''right'100);
  102.         
  103.         // função para formatar numero
  104.         $format_value = function($value) { 
  105.             if (is_numeric($value))
  106.             {
  107.                 return 'R$ ' number_format($value2',''.');
  108.             }
  109.             return $value;
  110.         };
  111.         
  112.         //colunas com formatação numerica
  113.         $vl->setTransformer($format_value);
  114.         $st->setTransformer($format_value);
  115.         
  116.         // função de total
  117.         $st->setTotalFunction( function($values) {
  118.             return array_sum( (array) $values );
  119.         });
  120.         
  121.         // função retorna descrição produto
  122.         $pr->setTransformer( function($value) {
  123.             return Produto::findInTransaction'sgd'$value )-> descricao;
  124.         });
  125.         
  126.         $cd->setTransformer( function($value) {
  127.             return Produto::findInTransaction'sgd'$value )-> codigo;
  128.         });
  129.         // detail actions
  130.         $this->detail_list->addQuickAction'Edit',   new TDataGridAction([$this'onEditDetail']),   'id_movimento_item''fa:edit blue');
  131.         $this->detail_list->addQuickAction'Delete', new TDataGridAction([$this'onDeleteDetail']), 'id_movimento_item''fa:trash red');
  132.         $this->detail_list->createModel();
  133.         
  134.         $panel = new TPanelGroup;
  135.         $panel->add($this->detail_list);
  136.         $panel->getBody()->style 'overflow-x:auto';
  137.         $this->form->addContent( [$panel] );
  138.         //fields contas a receber
  139.         $receber_id_contas_receber = new THidden('receber_id_contas_receber');
  140.         $receber_id_cliente = new THidden('receber_id_cliente');
  141.         $receber_historico = new TEntry('receber_historico');
  142.         $receber_historico->forceUpperCase();
  143.         $receber_data_vencimento = new TDate('receber_data_vencimento');
  144.         $receber_data_vencimento->setMask('dd/mm/yyyy');
  145.         $receber_valor_receber = new TEntry('receber_valor_receber');        
  146.         $receber_valor_receber->setNumericMask(2,',''.'TRUE);
  147.         $receber_data_recebimento = new TDate('receber_data_recebimento');
  148.         $receber_data_recebimento->setMask('dd/mm/yyyy');
  149.         $receber_valor_recebido = new TEntry('receber_valor_recebido');
  150.         $receber_valor_recebido->setNumericMask(2,',''.'TRUE);
  151.         $receber_valor_receber->setSize('100');
  152.         $receber_valor_recebido->setSize('100');
  153.         //detail contas receber
  154.         $this->form->addContent( ['<h4>Contas Receber</h4><hr>'] );
  155.         $this->form->addFields( [''], [$receber_id_contas_receber] );
  156.         $this->form->addFields( [''], [$receber_id_cliente] );
  157.         $this->form->addFields( [new TLabel('Histórico')], [$receber_historico] );
  158.         $this->form->addFields( [new TLabel('Data Vencimento')], [$receber_data_vencimento] );
  159.         $this->form->addFields( [new TLabel('Valor Receber')], [$receber_valor_receber] );
  160.         $this->form->addFields( [new TLabel('Data Recebimento')], [$receber_data_recebimento] );
  161.         $this->form->addFields( [new TLabel('Valor Recebido')], [$receber_valor_recebido] );
  162.         $add_receber TButton::create('add_receber', [$this'onSaveReceber'], 'Registrar''fa:save');
  163.         $this->form->addFields( [], [$add_receber] )->style 'background: whitesmoke; padding: 5px; margin: 1px;';
  164.         $this->detail_receber = new BootstrapDatagridWrapper(new TQuickGrid);
  165.         $this->detail_receber->style "min-width: 700px; width:100%;margin-bottom: 10px";
  166.         $this->detail_receber->setId('Venda_receber');
  167.         
  168.         // items
  169.         $this->detail_receber->addQuickColumn('Histórico''historico''left'100);
  170.         $this->detail_receber->addQuickColumn('Data Vencimento''data_vencimento''right'100);
  171.         $va $this->detail_receber->addQuickColumn('Valor Receber''valor_receber''right'100);
  172.         $this->detail_receber->addQuickColumn('Data Recebimento''data_recebimento''right'100);
  173.         $vr $this->detail_receber->addQuickColumn('Valor Recebido''valor_recebido''right'100);
  174.         
  175.         $va->setTransformer($format_value);
  176.         $vr->setTransformer($format_value);
  177.         // detail actions
  178.         $this->detail_receber->addQuickAction'Edit',   new TDataGridAction([$this'onEditReceber']),   'id_contas_receber''fa:edit blue');
  179.         $this->detail_receber->addQuickAction'Delete', new TDataGridAction([$this'onDeleteReceber']), 'id_contas_receber''fa:trash red');
  180.         $this->detail_receber->createModel();
  181.         
  182.         $panel_receber = new TPanelGroup;
  183.         $panel_receber->add($this->detail_receber);
  184.         $panel_receber->getBody()->style 'overflow-x:auto';
  185.         $this->form->addContent( [$panel_receber] );
  186.         $btn $this->form->addAction_t('Save'),  new TAction([$this'onSave']), 'fa:save');
  187.         $btn->class 'btn btn-sm btn-primary';
  188.         $this->form->addAction(_t('Clear'), new TAction([$this'onClear']), 'fa:eraser red');
  189.         $this->form->addAction(_t('Print'),new TAction(array('VendaReportDesign','onGenerate')),'fa:file green');
  190.         $this->form->addAction(_t('Back'),new TAction(array('VendaList','onReload')),'fa:arrow-circle-o-left blue');
  191.         
  192.         // create the page container
  193.         $container = new TVBox;
  194.         $container->style 'width: 90%';
  195.         // $container->add(new TXMLBreadCrumb('menu.xml', __CLASS__));
  196.         $container->add($this->form);
  197.         parent::add($container);
  198.     }
  199.  
  200.     static function onProductChange$params )
  201.     {
  202.         if( isset($params['detail_id_produto']) && $params['detail_id_produto'] )
  203.         {
  204.             try
  205.             {
  206.                 TTransaction::open('sgd');
  207.                 $product = new Produto($params['detail_id_produto']);
  208.                 $fill_data = new StdClass;
  209.                 $fill_data->detail_valor number_format($product->valor2',''.');
  210.                 TForm::sendData('form_Venda'$fill_data);
  211.                 TTransaction::close();
  212.             }
  213.             catch (Exception $e// in case of exception
  214.             {
  215.                 new TMessage('error'$e->getMessage());
  216.                 TTransaction::rollback();
  217.             }
  218.         }
  219.     } 
  220.  
  221.     /**
  222.      * Clear form
  223.      * @param $param URL parameters
  224.      */
  225.     public function onClear($param)
  226.     {
  227.         $this->form->clear(TRUE);
  228.         TSession::setValue(__CLASS__.'_items', array());
  229.         $this->onReload$param );
  230.     }
  231.     /**
  232.      * Save an item from form to session list
  233.      * @param $param URL parameters
  234.      */
  235.     public function onSaveReceber$param )
  236.     {
  237.         try
  238.         {
  239.             TTransaction::open('sgd');
  240.             $data $this->form->getData();
  241.             
  242.             $items TSession::getValue(__CLASS__.'_receber');
  243.             $key = empty($data->receber_id_contas_receber) ? 'X'.mt_rand(10000000001999999999) : $data->receber_id_contas_receber;
  244.             $items$key ] = array();
  245.             $items$key ]['id_contas_receber'] = $key;
  246.             $items$key ]['id_cliente'] =  $data->id_cliente;
  247.             $items$key ]['historico'] =  $data->receber_historico;
  248.             $items$key ]['data_vencimento'] = $data->receber_data_vencimento;
  249.             $items$key ]['valor_receber'] = $data->receber_valor_receber;
  250.             $items$key ]['data_recebimento'] = $data->receber_data_recebimento;
  251.             $items$key ]['valor_recebido'] = $data->receber_valor_recebido;
  252.             
  253.             TSession::setValue(__CLASS__.'_receber'$items);
  254.             
  255.             // clear detail form fields
  256.             $data->receber_id_contas_receber '';
  257.             $data->receber_id_cliente '';
  258.             $data->receber_historico '';
  259.             $data->receber_data_vencimento '';
  260.             $data->receber_valor_receber '';
  261.             $data->receber_data_recebimento '';
  262.             $data->receber_valor_recebido '';
  263.             
  264.             TTransaction::close();
  265.             $this->form->setData($data);
  266.             
  267.             $this->onReload$param ); // reload the items
  268.         }
  269.         catch (Exception $e)
  270.         {
  271.             $this->form->setData$this->form->getData());
  272.             new TMessage('error'$e->getMessage());
  273.         }
  274.     }
  275.     
  276.     /**
  277.      * Save an item from form to session list
  278.      * @param $param URL parameters
  279.      */
  280.     public function onSaveDetail$param )
  281.     {
  282.         try
  283.         {
  284.             TTransaction::open('sgd');
  285.             $data $this->form->getData();
  286.             
  287.             /** validation sample
  288.             if (empty($data->fieldX))
  289.             {
  290.                 throw new Exception('The field fieldX is required');
  291.             }
  292.             **/
  293.             
  294.             $items TSession::getValue(__CLASS__.'_items');
  295.             $key = empty($data->detail_id_movimento_item) ? 'X'.mt_rand(10000000001999999999) : $data->detail_id_movimento_item;
  296.             
  297.             $items$key ] = array();
  298.             $items$key ]['id_movimento_item'] = $key;
  299.             $items$key ]['id_produto'] = $data->detail_id_produto;
  300.             $items$key ]['quantidade'] = $data->detail_quantidade;
  301.             $items$key ]['unidade'] = Produto::findInTransaction'sgd'$data->detail_id_produto)->unidade;
  302.             $items$key ]['valor'] = $data->detail_valor;
  303.             
  304.             
  305.             TSession::setValue(__CLASS__.'_items'$items);
  306.             
  307.             // clear detail form fields
  308.             $data->detail_id_movimento_item '';
  309.             $data->detail_id_produto '';
  310.             $data->detail_quantidade '';
  311.             $data->detail_unidade '';
  312.             $data->detail_valor '';
  313.             
  314.             TTransaction::close();
  315.             $this->form->setData($data);
  316.             
  317.             $this->onReload$param ); // reload the items
  318.         }
  319.         catch (Exception $e)
  320.         {
  321.             $this->form->setData$this->form->getData());
  322.             new TMessage('error'$e->getMessage());
  323.         }
  324.     }
  325.     
  326.     /**
  327.      * Load an item from session list to detail form
  328.      * @param $param URL parameters
  329.      */
  330.     public static function onEditDetail$param )
  331.     {
  332.         // read session items
  333.         $items TSession::getValue(__CLASS__.'_items');
  334.         
  335.         // get the session item
  336.         $item $items$param['key'] ];
  337.         
  338.         $data = new stdClass;
  339.         $data->detail_id_movimento_item $item['id_movimento_item'];
  340.         $data->detail_id_produto $item['id_produto'];
  341.         $data->detail_nome_produto 'teste';
  342.         $data->detail_quantidade $item['quantidade'];
  343.         $data->detail_unidade $item['unidade'];
  344.         $data->detail_valor number_format($item['valor'], 2',''.'); 
  345.         
  346.         // fill detail fields
  347.         TForm::sendData'form_Venda'$data );
  348.     }
  349.     public static function onEditReceber$param )
  350.     {
  351.         // read session items
  352.         $items TSession::getValue(__CLASS__.'_receber');
  353.         
  354.         // get the session item
  355.         $item $items$param['key'] ];
  356.         $data = new stdClass;
  357.         $data->receber_id_contas_receber $item['id_contas_receber'];
  358.         $data->receber_historico $item['historico'];
  359.         $data->receber_data_vencimento $item['data_vencimento'];
  360.         $data->receber_valor_receber number_format($item['valor_receber'], 2',''.');
  361.         $data->receber_data_recebimento $item['data_recebimento'];
  362.         $data->receber_valor_recebido number_format$item['valor_recebido'], 2',''.');
  363.         
  364.         // fill detail fields
  365.         TForm::sendData'form_Venda'$data );
  366.     }
  367.     /**
  368.      * Delete an item from session list
  369.      * @param $param URL parameters
  370.      */
  371.     public static function onDeleteDetail$param )
  372.     {
  373.         // reset items
  374. //        $item = $items[ $param['key'] ];
  375.         $data = new stdClass;
  376.         $data->detail_id_produto '';
  377.         $data->detail_quantidade '';
  378.         $data->detail_unidade '';
  379.         $data->detail_valor '';
  380.         
  381.         // clear form data
  382.         TForm::sendData('form_Venda'$data );
  383.         
  384.         // read session items
  385.         $items TSession::getValue(__CLASS__.'_items');
  386.         
  387.         // get detail id
  388.         $detail_id $param['key'];
  389.         
  390.         // delete the item from session
  391.         unset($items$detail_id ] );
  392.         
  393.         // rewrite session items
  394.         TSession::setValue(__CLASS__.'_items'$items);
  395.         
  396.         // delete item from screen
  397.         TScript::create("ttable_remove_row_by_id('Venda_list', '{$detail_id}')");
  398.     }
  399.     public static function onDeleteReceber$param )
  400.     {
  401.         // reset items
  402.         $data = new stdClass;
  403.         $data->receber_id_contas_receber '';
  404.         $data->receber_historico '';
  405.         $data->receber_data_vencimento '';
  406.         $data->receber_valor_receber '';
  407.         $data->receber_data_recebimento '';
  408.         $data->receber_valor_recebido '';
  409.         
  410.         // clear form data
  411.         TForm::sendData('form_Venda'$data );
  412.         
  413.         // read session items
  414.         $items TSession::getValue(__CLASS__.'_receber');
  415.         
  416.         //var_dump($items);
  417.         
  418.         // get detail id
  419.         $receber_detail_id $param['key'];
  420.         //var_dump($items[ $receber_detail_id ]);
  421.         
  422.         // delete the item from session
  423.         unset($items$receber_detail_id ] );
  424.         //var_dump($items);
  425.         
  426.         // rewrite session items
  427.         TSession::setValue(__CLASS__.'_receber'$items);
  428.         
  429.         // delete item from screen
  430.         TScript::create("ttable_remove_row_by_id('Venda_receber', '{$receber_detail_id}')");
  431.     }
  432.     /**
  433.      * Load the items list from session
  434.      * @param $param URL parameters
  435.      */
  436.     public function onReload($param)
  437.     {
  438.         // read session items
  439.         $items TSession::getValue(__CLASS__.'_items');
  440.         $receber TSession::getValue(__CLASS__.'_receber');
  441.  
  442.         $this->detail_list->clear(); // clear detail list
  443.         $this->detail_receber->clear(); // clear detail receber
  444.        
  445.         if ($items)
  446.         {
  447.             foreach ($items as $list_item)
  448.             {
  449.                 $item = (object) $list_item;
  450.                 
  451.                 $row $this->detail_list->addItem$item );
  452.                 $row->id $list_item['id_movimento_item'];
  453.             }
  454.         }
  455.         if ($receber)
  456.         {
  457.             foreach ($receber as $list_receber)
  458.             {
  459.                 $item_receber = (object) $list_receber;
  460.                 
  461.                 $row $this->detail_receber->addItem$item_receber );
  462.                 $row->id $list_receber['id_contas_receber'];
  463.             }
  464.         }
  465.         
  466.         $this->loaded TRUE;
  467.     }
  468.     
  469.     /**
  470.      * Load Master/Detail data from database to form/session
  471.      */
  472.     public function onEdit($param)
  473.     {
  474.         try
  475.         {
  476.             TSession::setValue(__CLASS__.'_items''');
  477.             TSession::setValue(__CLASS__.'_receber''');
  478.             TTransaction::open('sgd');
  479.             
  480.             if (isset($param['key']))
  481.             {
  482.                 $key $param['key'];
  483.                 
  484.                 $object = new Venda($key);
  485.                 if ($object->id_licenciada<>TSession::getValue('userunitid')){
  486.                   new TMessage('info''Registro não encontrado');
  487.                   exit;
  488.                 }
  489.                 $object->data_hora TDate::date2br($object->data_hora ); 
  490.                 $object->data_vencimento TDate::date2br($object->data_vencimento );
  491.                 $object->receber_data_vencimento TDate::date2br($object->receber_data_vencimento ); 
  492.                 $object->receber_data_recebimento TDate::date2br($object->receber_data_recebimento );                
  493.                 
  494.                 $repository = new TRepository('MovimentoItem');
  495.                 $criteria = new TCriteria;
  496.                 $criteria->add(new TFilter('id_licenciada ','=',  TSession::getValue('userunitid')));
  497.                 $criteria->add(new TFilter('id_venda','=',  $key));
  498.                 $items $repository->load($criteriaFALSE);
  499.                 $session_items = array();
  500.                 foreach( $items as $item )
  501.                 {
  502.                     $item_key $item->id_movimento_item;
  503.                     $session_items[$item_key] = $item->toArray();
  504.                     $session_items[$item_key]['id_movimento_item'] = $item->id_movimento_item;
  505.                     $session_items[$item_key]['id_produto'] = $item->id_produto;
  506.                     $session_items[$item_key]['quantidade'] = $item->quantidade;
  507.                     $session_items[$item_key]['unidade'] = Produto::findInTransaction'sgd'$item->id_produto)->unidade;
  508.                     $session_items[$item_key]['valor'] = $item->valor;
  509.                 }
  510.                 TSession::setValue(__CLASS__.'_items'$session_items);
  511.                 
  512.                 $repository = new TRepository('ContasReceber');
  513.                 $criteria = new TCriteria;
  514.                 $criteria->add(new TFilter('id_licenciada ','=',  TSession::getValue('userunitid')));
  515.                 $criteria->add(new TFilter('id_venda','=',  $key));
  516.                 $items $repository->load($criteriaFALSE);
  517.                 $session_items = array();
  518.                 foreach( $items as $item )
  519.                 {
  520.                     $item_key $item->id_contas_receber;
  521.                     $session_items[$item_key] = $item->toArray();
  522.                     $session_items[$item_key]['id_contas_receber'] = $item->id_contas_receber;
  523.                     $session_items[$item_key]['historico'] = $item->historico;
  524.                     $session_items[$item_key]['data_vencimento'] = TDate::date2br($item->data_vencimento);
  525.                     $session_items[$item_key]['valor_receber'] = $item->valor_receber;
  526.                     $session_items[$item_key]['data_recebimento'] = TDate::date2br($item->data_recebimento);
  527.                     $session_items[$item_key]['valor_recebido'] = $item->valor_recebido;
  528.                 }
  529.                 TSession::setValue(__CLASS__.'_receber'$session_items);
  530.                 
  531.                 $this->form->setData($object); // fill the form with the active record data
  532.                 $this->onReload$param ); // reload items list
  533.                 TTransaction::close(); // close transaction
  534.             }
  535.             else
  536.             {
  537.                 $this->form->clear(TRUE);
  538.                 TSession::setValue(__CLASS__.'_items'null);
  539.                 $this->onReload$param );
  540.             }
  541.         }
  542.         catch (Exception $e// in case of exception
  543.         {
  544.             new TMessage('error'$e->getMessage());
  545.             TTransaction::rollback();
  546.         }
  547.     }
  548.     
  549.     /**
  550.      * Save the Master/Detail data from form/session to database
  551.      */
  552.     public function onSave()
  553.     {
  554.         try
  555.         {
  556.             // open a transaction with database
  557.             TTransaction::open('sgd');
  558.             
  559.             $data $this->form->getData();
  560.             $master = new Venda;
  561.             $master->fromArray( (array) $data);
  562.             $this->form->validate(); // form validation
  563.             $novo_id Venda::where('id_licenciada','=',TSession::getValue('userunitid'))->orderBy('codigo','desc')->first();
  564.             if ($novo_id == NULL) {
  565.                 $master->codigo 1;
  566.             } else {
  567.                 if ($master->codigo == NULL) {
  568.                     $master->codigo $novo_id->codigo 1;
  569.                 }; 
  570.             };
  571.             $master->id_licenciada TSession::getValue('userunitid');
  572.             $master->id_funcionario TSession::getValue('userid');
  573.             $master->data_hora TDate::date2us($master->data_hora ); 
  574.             $master->data_vencimento TDate::date2us($master->data_vencimento ); 
  575.             $master->store(); // save master object
  576.             // delete details
  577.             $old_items MovimentoItem::where('id_venda''='$master->id_venda)->load();
  578.             // delete receber
  579.             $old_receber ContasReceber::where('id_venda''='$master->id_venda)->load();
  580.             
  581.             $keep_items = array();
  582.             $keep_receber = array();
  583.             
  584.             // get session items
  585.             $items TSession::getValue(__CLASS__.'_items');
  586.             
  587.             if( $items )
  588.             {
  589.                 foreach( $items as $item )
  590.                 {
  591.                     if (substr($item['id_movimento_item'],0,1) == 'X' // new record
  592.                     {
  593.                         $detail = new MovimentoItem;
  594.                     }
  595.                     else
  596.                     {
  597.                         $detail MovimentoItem::find($item['id_movimento_item']);
  598.                     }
  599.                     $detail->id_licenciada TSession::getValue('userunitid');
  600.                     $detail->id_venda $master->id_venda;
  601.                     $detail->id_produto  $item['id_produto'];
  602.                     $detail->quantidade  $item['quantidade'];
  603.                     $detail->valor  $item['valor'];
  604.                     $detail->id_usuario TSession::getValue('userid');
  605.                     $detail->custo Produto::findInTransaction'sgd'$detail->id_produto )->valor_compra ;
  606.                     $detail->quantidade_movimento = ($item['quantidade'] * (-1));
  607.                     $detail->id_movimento_estoque_tipo 1
  608.                     $detail->data_referencia $master->data_hora
  609.                     $detail->store();
  610.                     
  611.                     $keep_items[] = $detail->id_movimento_item;
  612.                 }
  613.             }
  614.             
  615.             if ($old_items)
  616.             {
  617.                 foreach ($old_items as $old_item)
  618.                 {
  619.                     if (!in_array$old_item->id_movimento_item$keep_items))
  620.                     {
  621.                         $old_item->delete();
  622.                     }
  623.                 }
  624.             }
  625.             // get session receber
  626.             $items TSession::getValue(__CLASS__.'_receber');
  627.             
  628.             if( $items )
  629.             {
  630.                 foreach( $items as $item )
  631.                 {
  632.                     if (substr($item['id_contas_receber'],0,1) == 'X' // new record
  633.                     {
  634.                         $detail = new ContasReceber;
  635.                     }
  636.                     else
  637.                     {
  638.                         $detail ContasReceber::find($item['id_contas_receber']);
  639.                     }
  640.                     $detail->id_licenciada TSession::getValue('userunitid');
  641.                     $detail->id_venda $master->id_venda;
  642.                     $detail->historico  $item['historico'];
  643.                     $detail->data_vencimento  TDate::date2us($item['data_vencimento']);
  644.                     $detail->valor_receber  $item['valor_receber'];
  645.                     $detail->data_recebimento  TDate::date2us($item['data_recebimento']);
  646.                     $detail->valor_recebido  $item['valor_recebido'];
  647.                     $detail->id_usuario TSession::getValue('userid');
  648.                     $detail->id_cliente $master->id_cliente;
  649.                     $detail->store();
  650.                     
  651.                     $keep_receber[] = $detail->id_contas_receber;
  652.                 }
  653.             }
  654.             
  655.             if ($old_receber)
  656.             {
  657.                 foreach ($old_receber as $old_item)
  658.                 {
  659.                     if (!in_array$old_item->id_contas_receber$keep_receber))
  660.                     {
  661.                         $old_item->delete();
  662.                     }
  663.                 }
  664.             }
  665.             TTransaction::close(); // close the transaction
  666.             
  667.             // reload form and session items
  668.             $this->onEdit(array('key'=>$master->id_venda));
  669.             
  670. //            new TMessage('info', TAdiantiCoreTranslator::translate('Record saved'));
  671.         }
  672.         catch (Exception $e// in case of exception
  673.         {
  674.             new TMessage('error'$e->getMessage());
  675.             $this->form->setData$this->form->getData() ); // keep form data
  676.             TTransaction::rollback();
  677.         }
  678.     }
  679.     
  680.     /**
  681.      * Show the page
  682.      */
  683.     public function show()
  684.     {
  685.         // check if the datagrid is already loaded
  686.         if (!$this->loaded AND (!isset($_GET['method']) OR $_GET['method'] !== 'onReload') )
  687.         {
  688.             $this->onReloadfunc_get_arg(0) );
  689.         }
  690.         parent::show();
  691.     }
  692.     
  693. }
  694. ?>





</your>
CC

Esse meu sistema é multiempresa, então voce vai ver alguns códigos aí que fazem parte do tratamento dos dados, para não aparecer dados de uma empresa em outra.
RF

Boa noite...
Eu entendi que precisam ser dados os devidos nomes para cada um dos grupos que quero trabalhar.
Não consegui ler direito o seu código. Mas obrigado por tentar ajudar.
Mas não sei direito o que ajustar no código, vou tentar praticar em um exemplo mais simples, com apenas dois campos.
RF

Boa noite...
Agora que piorou tudo,
Sem sucesso. Vou colocar o código de novo.
  1. <?php
  2. /**
  3.  * cadastro_de_clientes Master/Detail
  4.  * @author  <your name here>
  5.  */
  6. class cadastro_de_clientes extends TPage
  7. {
  8.     protected $form// form
  9.     //protected $detail_list;
  10.     protected $detail_list;
  11.     protected $filial_list;
  12.     
  13.     /**
  14.      * Page constructor
  15.      */
  16.     public function __construct()
  17.     {
  18.         parent::__construct();
  19.         
  20.         // creates the form
  21.         $this->form = new BootstrapFormBuilder('form_cliente');
  22.         $this->form->setFormTitle('cliente');
  23.         
  24.         // master fields
  25.         $id = new TEntry('id');
  26.         $status = new TEntry('status');
  27.         $cnpj = new TEntry('cnpj');
  28.         $ie = new TEntry('ie');
  29.         $im = new TEntry('im');
  30.         $nome_fantasia = new TEntry('nome_fantasia');
  31.         $rz_social = new TEntry('rz_social');
  32.         $cep = new TEntry('cep');
  33.         $endereco = new TEntry('endereco');
  34.         $numero = new TEntry('numero');
  35.         $complemento = new TEntry('complemento');
  36.         $bairro = new TEntry('bairro');
  37.         $uf = new TEntry('uf');
  38.         $cidade_id = new TCombo('cidade_id''banco''cidade''id''nome');
  39.         // detail fields
  40.         $detail_id = new THidden('detail_id');
  41.         $detail_nome = new TEntry('detail_nome');
  42.         $detail_area_de_contato = new TEntry('detail_area_de_contato');
  43.         $detail_email = new TEntry('detail_email');
  44.         $detail_telefone = new TEntry('detail_telefone');
  45.         $detail_radio = new TEntry('detail_radio');
  46.         
  47.         
  48.         
  49.          // filial fields
  50.         $filial_id = new THidden('filial_id');
  51.         $filial_cnpj = new TEntry('filial_cnpj');
  52.         $filial_rz_social = new TEntry('filial_rz_social');
  53.         $filial_nome_fantasia = new TEntry('filial_nome_fantasia');
  54.         
  55.         
  56.         
  57.         if (!empty($id))
  58.         {
  59.             $id->setEditable(FALSE);
  60.         }
  61.         
  62.         // master fields
  63.         $this->form->addFields( [new TLabel('Código')], [$id] );
  64.         $this->form->addFields( [new TLabel('Status')], [$status] );
  65.         $this->form->addFields( [new TLabel('CNPJ')], [$cnpj] );
  66.         $this->form->addFields( [new TLabel('I.E')], [$ie] );
  67.         $this->form->addFields( [new TLabel('I.M')], [$im] );
  68.         $this->form->addFields( [new TLabel('Nome Fantasia')], [$nome_fantasia] );
  69.         $this->form->addFields( [new TLabel('Razão Social')], [$rz_social] );
  70.         $this->form->addFields( [new TLabel('CEP')], [$cep] );
  71.         $this->form->addFields( [new TLabel('Endereço')], [$endereco] );
  72.         $this->form->addFields( [new TLabel('Número')], [$numero] );
  73.         $this->form->addFields( [new TLabel('Complemento')], [$complemento] );
  74.         $this->form->addFields( [new TLabel('Bairro')], [$bairro] );
  75.         $this->form->addFields( [new TLabel('U.F')], [$uf] );
  76.         $this->form->addFields( [new TLabel('Cidade')], [$cidade_id] );
  77.         
  78.         // detail fields
  79.         $this->form->addContent( ['<h4>Contatos</h4><hr>'] );
  80.         $this->form->addFields( [$detail_id] );
  81.         
  82.         $this->form->addFields( [new TLabel('Nome')], [$detail_nome] );
  83.         $this->form->addFields( [new TLabel('Área')], [$detail_area_de_contato] );
  84.         $this->form->addFields( [new TLabel('Email')], [$detail_email] );
  85.         $this->form->addFields( [new TLabel('Telefone')], [$detail_telefone] );
  86.         $this->form->addFields( [new TLabel('Rádio')], [$detail_radio] );
  87.         $add TButton::create('add', [$this'onSaveDetail'], 'Register''fa:save');
  88.         $this->form->addFields( [], [$add] )->style 'background: whitesmoke; padding: 5px; margin: 1px;';
  89.         
  90.         $this->detail_list = new BootstrapDatagridWrapper(new TQuickGrid);
  91.         $this->detail_list->style "min-width: 700px; width:100%;margin-bottom: 10px";
  92.         $this->detail_list->setId('cliente_list');
  93.         
  94.         // items
  95.         $this->detail_list->addQuickColumn('Nome''nome''left'100);
  96.         $this->detail_list->addQuickColumn('Área''area_de_contato''left'100);
  97.         $this->detail_list->addQuickColumn('Email''email''left'100);
  98.         $this->detail_list->addQuickColumn('Telefone''telefone''left'100);
  99.         $this->detail_list->addQuickColumn('Rádio''radio''left'100);
  100.         // detail actions
  101.         $this->detail_list->addQuickAction'Edit',   new TDataGridAction([$this'onEditDetail']),   'id''fa:edit blue');
  102.         $this->detail_list->addQuickAction'Delete', new TDataGridAction([$this'onDeleteDetail']), 'id''fa:trash red');
  103.         $this->detail_list->createModel();
  104.         
  105.         $panel = new TPanelGroup;
  106.         $panel->add($this->detail_list);
  107.         $panel->getBody()->style 'overflow-x:auto';
  108.         $this->form->addContent( [$panel] );
  109.         
  110.         
  111.         
  112.         // filial fields
  113.         $this->form->addContent( ['<h4>filiais</h4><hr>'] );
  114.         $this->form->addFields( [$filial_id] );
  115.         
  116.         $this->form->addFields( [new TLabel('Cnpj')], [$filial_cnpj] );
  117.         $this->form->addFields( [new TLabel('Rz Social')], [$filial_rz_social] );
  118.         $this->form->addFields( [new TLabel('Nome Fantasia')], [$filial_nome_fantasia] );
  119.         $addd TButton::create('addd', [$this'onSavefilial'], 'Register''fa:save');
  120.         $this->form->addFields( [], [$addd] )->style 'background: whitesmoke; padding: 5px; margin: 1px;';
  121.         
  122.         $this->filial_list = new BootstrapDatagridWrapper(new TQuickGrid);
  123.         $this->filial_list->style "min-width: 700px; width:100%;margin-bottom: 10px";
  124.         $this->filial_list->setId('cliente_list');
  125.         
  126.         // items
  127.         $this->filial_list->addQuickColumn('Cnpj''cnpj''left'100);
  128.         $this->filial_list->addQuickColumn('Rz Social''rz_social''left'100);
  129.         $this->filial_list->addQuickColumn('Nome Fantasia''nome_fantasia''left'100);
  130.         // filial actions
  131.         $this->filial_list->addQuickAction'Edit',   new TDataGridAction([$this'onEditfilial']),   'id''fa:edit blue');
  132.         $this->filial_list->addQuickAction'Delete', new TDataGridAction([$this'onDeletefilial']), 'id''fa:trash red');
  133.         $this->filial_list->createModel();
  134.         
  135.         $painel = new TPanelGroup;
  136.         $painel->add($this->filial_list);
  137.         $painel->getBody()->style 'overflow-x:auto';
  138.         $this->form->addContent( [$painel] );
  139.         
  140.         
  141.         
  142.         $btn $this->form->addAction_t('Save'),  new TAction([$this'onSave']), 'fa:save');
  143.         $btn->class 'btn btn-sm btn-primary';
  144.         $this->form->addAction_t('Clear'), new TAction([$this'onClear']), 'fa:eraser red');
  145.         
  146.         
  147.         
  148.         
  149.         
  150.         
  151.         // create the page container
  152.         $container = new TVBox;
  153.         $container->style 'width: 90%';
  154.         $container->add(new TXMLBreadCrumb('menu.xml'__CLASS__));
  155.         $container->add($this->form);
  156.         parent::add($container);
  157.     }
  158.     
  159.     
  160.     
  161.     /**
  162.      * Clear form
  163.      * @param $param URL parameters
  164.      */
  165.     public function onClear($param)
  166.     {
  167.         $this->form->clear(TRUE);
  168.         TSession::setValue(__CLASS__.'_items', array());
  169.         $this->onReload$param );
  170.     }
  171.     
  172.     
  173.     
  174.      public function onSavefilial$param )
  175.     {
  176.         try
  177.         {
  178.             TTransaction::open('banco');
  179.             $data $this->form->getData();
  180.             
  181.             /** validation sample
  182.             if (empty($data->fieldX))
  183.             {
  184.                 throw new Exception('The field fieldX is required');
  185.             }
  186.             **/
  187.             
  188.             $items TSession::getValue(__CLASS__.'_items_filial');
  189.             $key = empty($data->filial_id) ? 'X'.mt_rand(10000000001999999999) : $data->filial_id;
  190.             
  191.             $items$key ] = array();
  192.             $items$key ]['id'] = $key;
  193.             $items$key ]['cnpj'] = $data->filial_cnpj;
  194.             $items$key ]['rz_social'] = $data->filial_rz_social;
  195.             $items$key ]['nome_fantasia'] = $data->filial_nome_fantasia;
  196.             
  197.             TSession::setValue(__CLASS__.'_items_filial'$items);
  198.             
  199.             // clear filial form fields
  200.             $data->filial_id '';
  201.             $data->filial_cnpj '';
  202.             $data->filial_rz_social '';
  203.             $data->filial_nome_fantasia '';
  204.             
  205.             TTransaction::close();
  206.             $this->form->setData($data);
  207.             
  208.             $this->onReload$param ); // reload the items
  209.         }
  210.         catch (Exception $e)
  211.         {
  212.             $this->form->setData$this->form->getData());
  213.             new TMessage('error'$e->getMessage());
  214.         }
  215.     }
  216.     
  217.     /**
  218.      * Load an item from session list to filial form
  219.      * @param $param URL parameters
  220.      */
  221.     public static function onEditfilial$param )
  222.     {
  223.         // read session items
  224.         $items TSession::getValue(__CLASS__.'_items_filial');
  225.         
  226.         // get the session item
  227.         $item $items$param['key'] ];
  228.         
  229.         $data = new stdClass;
  230.         $data->filial_id $item['id'];
  231.         $data->filial_cnpj $item['cnpj'];
  232.         $data->filial_rz_social $item['rz_social'];
  233.         $data->filial_nome_fantasia $item['nome_fantasia'];
  234.         
  235.         // fill filial fields
  236.         TForm::sendData'form_cliente'$data );
  237.     }
  238.     
  239.     /**
  240.      * Delete an item from session list
  241.      * @param $param URL parameters
  242.      */
  243.     public static function onDeletefilial$param )
  244.     {
  245.         // reset items
  246.         $data = new stdClass;
  247.             $data->filial_cnpj '';
  248.             $data->filial_rz_social '';
  249.             $data->filial_nome_fantasia '';
  250.         
  251.         // clear form data
  252.         TForm::sendData('form_cliente'$data );
  253.         
  254.         // read session items
  255.         $items TSession::getValue(__CLASS__.'_items_filial');
  256.         
  257.         // get filial id
  258.         $filial_id $param['key'];
  259.         
  260.         // delete the item from session
  261.         unset($items$filial_id ] );
  262.         
  263.         // rewrite session items
  264.         TSession::setValue(__CLASS__.'_items_filial'$items);
  265.         
  266.         // delete item from screen
  267.         TScript::create("ttable_remove_row_by_id('cliente_list', '{$filial_id}')");
  268.     }
  269.     
  270.     
  271.     
  272.     
  273.     
  274.     
  275.     /**
  276.      * Save an item from form to session list
  277.      * @param $param URL parameters
  278.      */
  279.     public function onSaveDetail$param )
  280.     {
  281.         try
  282.         {
  283.             TTransaction::open('banco');
  284.             $data $this->form->getData();
  285.             
  286.             /** validation sample
  287.             if (empty($data->fieldX))
  288.             {
  289.                 throw new Exception('The field fieldX is required');
  290.             }
  291.             **/
  292.             
  293.             $items TSession::getValue(__CLASS__.'_items');
  294.             $key = empty($data->detail_id) ? 'X'.mt_rand(10000000001999999999) : $data->detail_id;
  295.             
  296.             $items$key ] = array();
  297.             $items$key ]['id'] = $key;
  298.             $items$key ]['nome'] = $data->detail_nome;
  299.             $items$key ]['area_de_contato'] = $data->detail_area_de_contato;
  300.             $items$key ]['email'] = $data->detail_email;
  301.             $items$key ]['telefone'] = $data->detail_telefone;
  302.             $items$key ]['radio'] = $data->detail_radio;
  303.             
  304.             TSession::setValue(__CLASS__.'_items'$items);
  305.             
  306.             // clear detail form fields
  307.             $data->detail_id '';
  308.             $data->detail_nome '';
  309.             $data->detail_area_de_contato '';
  310.             $data->detail_email '';
  311.             $data->detail_telefone '';
  312.             $data->detail_radio '';
  313.             
  314.             TTransaction::close();
  315.             $this->form->setData($data);
  316.             
  317.             $this->onReload$param ); // reload the items
  318.         }
  319.         catch (Exception $e)
  320.         {
  321.             $this->form->setData$this->form->getData());
  322.             new TMessage('error'$e->getMessage());
  323.         }
  324.     }
  325.     
  326.     /**
  327.      * Load an item from session list to detail form
  328.      * @param $param URL parameters
  329.      */
  330.     public static function onEditDetail$param )
  331.     {
  332.         // read session items
  333.         $items TSession::getValue(__CLASS__.'_items');
  334.         
  335.         // get the session item
  336.         $item $items$param['key'] ];
  337.         
  338.         $data = new stdClass;
  339.         $data->detail_id $item['id'];
  340.         $data->detail_nome $item['nome'];
  341.         $data->detail_area_de_contato $item['area_de_contato'];
  342.         $data->detail_email $item['email'];
  343.         $data->detail_telefone $item['telefone'];
  344.         $data->detail_radio $item['radio'];
  345.         
  346.         // fill detail fields
  347.         TForm::sendData'form_cliente'$data );
  348.     }
  349.     
  350.     /**
  351.      * Delete an item from session list
  352.      * @param $param URL parameters
  353.      */
  354.     public static function onDeleteDetail$param )
  355.     {
  356.         // reset items
  357.         $data = new stdClass;
  358.             $data->detail_nome '';
  359.             $data->detail_area_de_contato '';
  360.             $data->detail_email '';
  361.             $data->detail_telefone '';
  362.             $data->detail_radio '';
  363.         
  364.         // clear form data
  365.         TForm::sendData('form_cliente'$data );
  366.         
  367.         // read session items
  368.         $items TSession::getValue(__CLASS__.'_items');
  369.         
  370.         // get detail id
  371.         $detail_id $param['key'];
  372.         
  373.         // delete the item from session
  374.         unset($items$detail_id ] );
  375.         
  376.         // rewrite session items
  377.         TSession::setValue(__CLASS__.'_items'$items);
  378.         
  379.         // delete item from screen
  380.         TScript::create("ttable_remove_row_by_id('cliente_list', '{$detail_id}')");
  381.     }
  382.     
  383.     /**
  384.      * Load the items list from session
  385.      * @param $param URL parameters
  386.      */
  387.     public function onReload($param)
  388.     {
  389.      
  390.         
  391.         // read session items
  392.         $items  TSession::getValue(__CLASS__.'_items');
  393.         $itemsf TSession::getValue(__CLASS__.'_items_filial');
  394.         
  395.         $this->detail_list->clear(); // clear detail list
  396.         $this->filial_list->clear(); // clear detail list
  397.         
  398.         if ($itemsf)
  399.         {
  400.             foreach ($items as $list_item)
  401.             {
  402.                 $item = (object) $list_item;
  403.                 
  404.                 $row $this->filial_list->addItem$item );
  405.                 $row->id $list_item['id'];
  406.             }
  407.         }
  408.         
  409.         
  410.         if ($items)
  411.         {
  412.             foreach ($items as $list_item)
  413.             {
  414.                 $item = (object) $list_item;
  415.                 
  416.                 $row $this->detail_list->addItem$item );
  417.                 $row->id $list_item['id'];
  418.             }
  419.         }
  420.         
  421.         $this->loaded TRUE;
  422.     }
  423.     
  424.     /**
  425.      * Load Master/Detail data from database to form/session
  426.      */
  427.     public function onEdit($param)
  428.     {
  429.         try
  430.         {
  431.             TTransaction::open('banco');
  432.             
  433.             if (isset($param['key']))
  434.             {
  435.                 $key $param['key'];
  436.                 
  437.                 $object = new cliente($key);
  438.                 $items  contato_clientes::where('cliente_id''='$key)->load();
  439.                 
  440.                 $session_items = array();
  441.                 foreach( $items as $item )
  442.                 {
  443.                     $item_key $item->id;
  444.                     $session_items[$item_key] = $item->toArray();
  445.                     $session_items[$item_key]['id'] = $item->id;
  446.                     $session_items[$item_key]['nome'] = $item->nome;
  447.                     $session_items[$item_key]['area_de_contato'] = $item->area_de_contato;
  448.                     $session_items[$item_key]['email'] = $item->email;
  449.                     $session_items[$item_key]['telefone'] = $item->telefone;
  450.                     $session_items[$item_key]['radio'] = $item->radio;
  451.                 }
  452.                 TSession::setValue(__CLASS__.'_items'$session_items);
  453.                 
  454.                 $this->form->setData($object); // fill the form with the active record data
  455.                 $this->onReload$param ); // reload items list
  456.                 TTransaction::close(); // close transaction
  457.             }
  458.             else
  459.             {
  460.                 $this->form->clear(TRUE);
  461.                 TSession::setValue(__CLASS__.'_items'null);
  462.                 $this->onReload$param );
  463.             }
  464.         }
  465.         catch (Exception $e// in case of exception
  466.         {
  467.             new TMessage('error'$e->getMessage());
  468.             TTransaction::rollback();
  469.         }
  470.     }
  471.     
  472.     /**
  473.      * Save the Master/Detail data from form/session to database
  474.      */
  475.     public function onSave()
  476.     {
  477.         try
  478.         {
  479.             // open a transaction with database
  480.             TTransaction::open('banco');
  481.             
  482.             $data $this->form->getData();
  483.             $master = new cliente;
  484.             $master->fromArray( (array) $data);
  485.             $this->form->validate(); // form validation
  486.             
  487.             $master->store(); // save master object
  488.             // delete details
  489.             $old_items contato_clientes::where('cliente_id''='$master->id)->load();
  490.             
  491.             $keep_items = array();
  492.             
  493.             // get session items
  494.             $items TSession::getValue(__CLASS__.'_items');
  495.             
  496.             if( $items )
  497.             {
  498.                 foreach( $items as $item )
  499.                 {
  500.                     if (substr($item['id'],0,1) == 'X' // new record
  501.                     {
  502.                         $detail = new contato_clientes;
  503.                     }
  504.                     else
  505.                     {
  506.                         $detail contato_clientes::find($item['id']);
  507.                     }
  508.                     $detail->nome  $item['nome'];
  509.                     $detail->area_de_contato  $item['area_de_contato'];
  510.                     $detail->email  $item['email'];
  511.                     $detail->telefone  $item['telefone'];
  512.                     $detail->radio  $item['radio'];
  513.                     $detail->cliente_id $master->id;
  514.                     $detail->store();
  515.                     
  516.                     $keep_items[] = $detail->id;
  517.                 }
  518.             }
  519.             
  520.             if ($old_items)
  521.             {
  522.                 foreach ($old_items as $old_item)
  523.                 {
  524.                     if (!in_array$old_item->id$keep_items))
  525.                     {
  526.                         $old_item->delete();
  527.                     }
  528.                 }
  529.             }
  530.             TTransaction::close(); // close the transaction
  531.             
  532.             // reload form and session items
  533.             $this->onEdit(array('key'=>$master->id));
  534.             
  535.             new TMessage('info'TAdiantiCoreTranslator::translate('Record saved'));
  536.         }
  537.         catch (Exception $e// in case of exception
  538.         {
  539.             new TMessage('error'$e->getMessage());
  540.             $this->form->setData$this->form->getData() ); // keep form data
  541.             TTransaction::rollback();
  542.         }
  543.     }
  544.     
  545.     /**
  546.      * Show the page
  547.      */
  548.     public function show()
  549.     {
  550.         // check if the datagrid is already loaded
  551.         if (!$this->loaded AND (!isset($_GET['method']) OR $_GET['method'] !== 'onReload') )
  552.         {
  553.             $this->onReloadfunc_get_arg(0) );
  554.         }
  555.         parent::show();
  556.     }
  557. }
  558. </your>
NR

É por aí mesmo. Faltou fazer a mesma coisa na função onEdit e onSave. E também, na função onReload tem um foreach errado:
  1. <?php
  2. if ($itemsf)
  3. {
  4.     //foreach ($items as $list_item) a variavel deveria ser itemsf
  5.       foreach ($itemsf as $list_item)
  6. ?>
RA

Passei por isso, olha nesse link.

www.adianti.com.br/forum/pt/view_4734
WF

Bom dia...
Pessoal obrigado pelas ajudas, não tive tempo para responder, mas a primeira parte está funcionando sim, já não há tantos erros.
Muito agradecido a todos.