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

Curso Dominando o Adianti Framework

O material mais completo de treinamento do Framework.
Curso em vídeo aulas + Livro completo + Códigos fontes do projeto ERPHouse.
Conteúdo Atualizado!


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





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