ERRO AO SALVAR SOMA DETALHES NO MESTRE Boa tarde, Tenho um formulário mestre detalhes, onde estou tentando implementar para que some os ítens do detalhe no campo do mestre. Após salvar a som dos detalhes, ele exclui todos os ítens do detalhe. Tentei seguir o exemplo do tutor más não está dando certo. Onde estou errando? Segue código do Form abaixo. Desde já agradeço. ...
AR
ERRO AO SALVAR SOMA DETALHES NO MESTRE  
Boa tarde,
Tenho um formulário mestre detalhes, onde estou tentando implementar para que some os ítens do detalhe no campo do mestre.
Após salvar a som dos detalhes, ele exclui todos os ítens do detalhe.

Tentei seguir o exemplo do tutor más não está dando certo.

Onde estou errando?

Segue código do Form abaixo. Desde já agradeço.

 
  1. <?php
  2. /**
  3. * ReceitaForm Master/Detail
  4. * @author Alexandre M. Roberto
  5. */
  6. class ReceitaForm extends TPage
  7. {
  8. protected $form; // form
  9. protected $detail_list;
  10. // trait with saveFile, saveFiles, ...
  11. use Adianti\Base\AdiantiFileSaveTrait;
  12. /**
  13. * Page constructor
  14. */
  15. public function __construct()
  16. {
  17. parent::__construct();
  18. // creates the form
  19. $this->form = new BootstrapFormBuilder('form_Receita');
  20. $this->form->setFormTitle('Receita');
  21. // master fields
  22. $id = new TEntry('id');
  23. $dt_receita = new TDate('dt_receita');
  24. $mes = new TCombo('mes');
  25. $ano = new TCombo('ano');
  26. $contribuicoes = new TEntry('contribuicoes');
  27. $ofertas = new TEntry('ofertas');
  28. $promocoes = new TEntry('promocoes');
  29. $patrimonial = new TEntry('patrimonial');
  30. $outros = new TEntry('outros');
  31. $total = new TEntry('total');
  32. $dizimo = new TEntry('dizimo');
  33. $ofertas_a_repassar = new TEntry('ofertas_a_repassar');
  34. $comprovantes = new TMultiFile('comprovantes');
  35. $dep_receitas = new TDate('dep_receitas');
  36. $dep_ofertas_a_repassar = new TDate('dep_ofertas_a_repassar');
  37. $observacoes = new TText('observacoes');
  38. $dt_receita->setMask('dd/mm/yyyy');
  39. $dt_receita->setDatabaseMask('yyyy-mm-dd');
  40. $dt_receita->setValue( date('Y-m-d') );
  41. $total->setEditable(FALSE);
  42. $dizimo->setEditable(FALSE);
  43. $ofertas_a_repassar->setEditable(FALSE);
  44. $current = (int) date('Y');
  45. $mes->addItems( ['01' => 'Janeiro',
  46. '02' => 'Fevereiro',
  47. '03' => 'Março',
  48. '04' => 'Abril',
  49. '05' => 'Maio',
  50. '06' => 'Junho',
  51. '07' => 'Julho',
  52. '08' => 'Agosto',
  53. '09' => 'Setembro',
  54. '10' => 'Outubro',
  55. '11' => 'Novembro',
  56. '12' => 'Dezembro'] );
  57. $ano->addItems( [ ($current -5) => ($current -5), ($current -4) => ($current -4), ($current -3) => ($current -3), ($current -2) => ($current -2), ($current -1) => ($current -1), $current => $current ] );
  58. $comprovantes->setAllowedExtensions( ['png', 'jpg', 'pdf'] );
  59. $comprovantes->enableFileHandling();
  60. $comprovantes->enableImageGallery();
  61. $comprovantes->enablePopover('Preview', '<img style="max-width:300px" src="download.php?file={file_name}">');
  62. $id->setSize('100%');
  63. $dt_receita->setSize('100%');
  64. $mes->setSize('100%');
  65. $ano->setSize('100%');
  66. $contribuicoes->setSize('100%');
  67. $ofertas->setSize('100%');
  68. $promocoes->setSize('100%');
  69. $patrimonial->setSize('100%');
  70. $outros->setSize('100%');
  71. $total->setSize('100%');
  72. $dizimo->setSize('100%');
  73. $ofertas_a_repassar->setSize('100%');
  74. $comprovantes->setSize('100%');
  75. $dep_receitas->setSize('100%');
  76. $dep_ofertas_a_repassar->setSize('100%');
  77. $observacoes->setSize('100%');
  78. // detail fields
  79. $detail_uniqid = new THidden('detail_uniqid');
  80. $detail_id = new THidden('detail_id');
  81. $detail_dt_oferta = new TDate('detail_dt_oferta');
  82. $detail_dt_oferta->setMask('dd/mm/yyyy');
  83. $detail_dt_oferta->setDatabaseMask('yyyy-mm-dd');
  84. $detail_plano_id = new TDBCombo('detail_plano_id', 'sudeste', 'Plano', 'id', 'favorecido');
  85. $detail_plano_id->setEditable(FALSE);
  86. $detail_plano_id->setSize('100%');
  87. $detail_valor = new TEntry('detail_valor');
  88. $detail_valor->setNumericMask(2, ',', '.', true);
  89. // exit action
  90. $detail_dt_oferta->setExitAction(new TAction([$this,'onExitDate']));
  91. if (!empty($id))
  92. {
  93. $id->setEditable(FALSE);
  94. }
  95. // master fields
  96. $row = $this->form->addFields( [ new TLabel('Id'), $id ],
  97. [ new TLabel('Dt Receita'), $dt_receita ],
  98. [ new TLabel('Mês'), $mes ],
  99. [ new TLabel('Ano'), $ano ] );
  100. $row->layout = ['col-sm-3', 'col-sm-3', 'col-sm-3', 'col-sm-3' ];
  101. $row = $this->form->addFields( [ new TLabel('Contribuições'), $contribuicoes ],
  102. [ new TLabel('Ofertas'), $ofertas ],
  103. [ new TLabel('Promoções'), $promocoes ],
  104. [ new TLabel('R. Patrimonial'), $patrimonial ] );
  105. $row->layout = ['col-sm-3', 'col-sm-3', 'col-sm-3', 'col-sm-3' ];
  106. $row = $this->form->addFields( [ new TLabel('Outros'), $outros ],
  107. [ new TLabel('Total Receitas'), $total ],
  108. [ new TLabel('Dízimo (10%)'), $dizimo ],
  109. [ new TLabel('Total Ofertas'), $ofertas_a_repassar ] );
  110. $row->layout = ['col-sm-3', 'col-sm-3', 'col-sm-3', 'col-sm-3' ];
  111. $label2 = new TLabel('Depósitos e Comprovantes', '#5A73DB', 12, '');
  112. $label2->style='text-align:left;border-bottom:1px solid #c0c0c0;width:100%; padding-top: 25px;';
  113. $this->form->addContent( [$label2] );
  114. $row = $this->form->addFields( [ new TLabel('Dep. Dízimo (10%)'), $dep_receitas ],
  115. [ new TLabel('Dep. Ofertas a Repassar'), $dep_ofertas_a_repassar ] );
  116. $row->layout = ['col-sm-6', 'col-sm-6' ];
  117. $row = $this->form->addFields( [ new TLabel('Comprovantes'), $comprovantes ] );
  118. $row->layout = ['col-sm-12' ];
  119. // detail fields
  120. $label3 = new TLabel('Ofertas a Repassar', '#5A73DB', 12, '');
  121. $label3->style='text-align:left;border-bottom:1px solid #c0c0c0;width:100%; padding-top: 25px;';
  122. $this->form->addContent( [$label3] );
  123. $this->form->addFields( [$detail_uniqid] );
  124. $this->form->addFields( [$detail_id] );
  125. $row = $this->form->addFields( [ new TLabel('Dt. Oferta'), $detail_dt_oferta ],
  126. [ new TLabel('Favorecido'), $detail_plano_id ],
  127. [ new TLabel('Valor'), $detail_valor ] );
  128. $row->layout = ['col-sm-2', 'col-sm-8', 'col-sm-2' ];
  129. $add = TButton::create('add', [$this, 'onDetailAdd'], _t('Register'), 'fa:plus-circle green');
  130. $add->getAction()->setParameter('static','1');
  131. $this->form->addFields( [], [$add] );
  132. $this->detail_list = new BootstrapDatagridWrapper(new TDataGrid);
  133. $this->detail_list->setId('Oferta_list');
  134. $this->detail_list->generateHiddenFields();
  135. $this->detail_list->style = "min-width: 700px; width:100%;margin-bottom: 10px";
  136. // items
  137. $this->detail_list->addColumn( new TDataGridColumn('uniqid', 'Uniqid', 'center') )->setVisibility(false);
  138. $this->detail_list->addColumn( new TDataGridColumn('id', 'Id', 'center') )->setVisibility(false);
  139. $dt = $this->detail_list->addColumn( new TDataGridColumn('dt_oferta', 'Dt Oferta', 'left', 50) );
  140. $pl = $this->detail_list->addColumn( new TDataGridColumn('plano_id', 'Plano Id', 'left', 100) );
  141. $vl = $this->detail_list->addColumn( new TDataGridColumn('valor', 'Valor', 'left', 100) );
  142. $dt->setTransformer( function($value, $object) {
  143. if ($value)
  144. $value = TDate::convertToMask($value, 'yyyy-mm-dd', 'dd/mm/yyyy', true);
  145. });
  146. $pl->setTransformer(function($value) {
  147. return Plano::findInTransaction('sudeste', $value)->favorecido;
  148. });
  149. $format_value = function($value) {
  150. if (is_numeric($value)) {
  151. return 'R$ '.number_format($value, 2, ',', '.');
  152. }
  153. return $value;
  154. };
  155. $vl->setTransformer( $format_value );
  156. // detail actions
  157. $action1 = new TDataGridAction([$this, 'onDetailEdit'] );
  158. $action1->setFields( ['uniqid', '*'] );
  159. $action2 = new TDataGridAction([$this, 'onDetailDelete']);
  160. $action2->setField('uniqid');
  161. // add the actions to the datagrid
  162. $this->detail_list->addAction($action1, _t('Edit'), 'fa:edit blue');
  163. $this->detail_list->addAction($action2, _t('Delete'), 'far:trash-alt red');
  164. $this->detail_list->createModel();
  165. $panel = new TPanelGroup;
  166. $panel->add($this->detail_list);
  167. $panel->getBody()->style = 'overflow-x:auto';
  168. $this->form->addContent( [$panel] );
  169. $label4 = new TLabel('Obervações', '#5A73DB', 12, '');
  170. $label4->style='text-align:left;border-bottom:1px solid #c0c0c0;width:100%; padding-top: 25px;';
  171. $this->form->addContent( [$label4] );
  172. $row = $this->form->addFields( [ new TLabel('Observações'), $observacoes ] );
  173. $row->layout = ['col-sm-12' ];
  174. $this->form->addAction( 'Save', new TAction([$this, 'onSave'], ['static'=>'1']), 'fa:save green');
  175. $this->form->addAction( 'Clear', new TAction([$this, 'onClear']), 'fa:eraser red');
  176. // create the page container
  177. $container = new TVBox;
  178. $container->style = 'width: 100%';
  179. // $container->add(new TXMLBreadCrumb('menu.xml', __CLASS__));
  180. $container->add($this->form);
  181. parent::add($container);
  182. }
  183. public static function onExitDate($params)
  184. {
  185. if( !empty($params['detail_dt_oferta']) )
  186. {
  187. try
  188. {
  189. TTransaction::open('sudeste');
  190. $criteria = new TCriteria;
  191. $date = TDate::date2us( $params['detail_dt_oferta']);
  192. $criteria->add( new TFilter( 'dt_oferta', '=', $date) );
  193. $repository = new TRepository('Plano');
  194. $planos = $repository->load( $criteria );
  195. if ($planos)
  196. {
  197. foreach ($planos as $plano)
  198. {
  199. TForm::sendData('form_Receita', (object) ['detail_plano_id' => $plano->id ]);
  200. }
  201. }
  202. else
  203. {
  204. new TMessage('info', 'Verifique se existe oferta a repassar nesta data e tente novamente!');
  205. }
  206. }
  207. catch (Exception $e)
  208. {
  209. new TMessage('error', $e->getMessage());
  210. TTransaction::rollback();
  211. }
  212. }
  213. }
  214. /**
  215. * Clear form
  216. * @param $param URL parameters
  217. */
  218. public function onClear($param)
  219. {
  220. $this->form->clear(TRUE);
  221. }
  222. /**
  223. * Add detail item
  224. * @param $param URL parameters
  225. */
  226. public function onDetailAdd( $param )
  227. {
  228. try
  229. {
  230. $this->form->validate();
  231. $data = $this->form->getData();
  232. /** validation sample
  233. if (empty($data->fieldX))
  234. {
  235. throw new Exception('The field fieldX is required');
  236. }
  237. **/
  238. $uniqid = !empty($data->detail_uniqid) ? $data->detail_uniqid : uniqid();
  239. $grid_data = [];
  240. $grid_data['uniqid'] = $uniqid;
  241. $grid_data['id'] = $data->detail_id;
  242. $grid_data['dt_oferta'] = $data->detail_dt_oferta;
  243. $grid_data['plano_id'] = $data->detail_plano_id;
  244. $grid_data['valor'] = $data->detail_valor;
  245. // insert row dynamically
  246. $row = $this->detail_list->addItem( (object) $grid_data );
  247. $row->id = $uniqid;
  248. TDataGrid::replaceRowById('Oferta_list', $uniqid, $row);
  249. // clear detail form fields
  250. $data->detail_uniqid = '';
  251. $data->detail_id = '';
  252. $data->detail_dt_oferta = '';
  253. $data->detail_plano_id = '';
  254. $data->detail_valor = '';
  255. // send data, do not fire change/exit events
  256. TForm::sendData( 'form_Receita', $data, false, false );
  257. }
  258. catch (Exception $e)
  259. {
  260. $this->form->setData( $this->form->getData());
  261. new TMessage('error', $e->getMessage());
  262. }
  263. }
  264. /**
  265. * Edit detail item
  266. * @param $param URL parameters
  267. */
  268. public static function onDetailEdit( $param )
  269. {
  270. $data = new stdClass;
  271. $data->detail_uniqid = $param['uniqid'];
  272. $data->detail_id = $param['id'];
  273. $data->detail_dt_oferta = $param['dt_oferta'];
  274. $data->detail_plano_id = $param['plano_id'];
  275. $data->detail_valor = $param['valor'];
  276. // send data, do not fire change/exit events
  277. TForm::sendData( 'form_Receita', $data, false, false );
  278. }
  279. /**
  280. * Delete detail item
  281. * @param $param URL parameters
  282. */
  283. public static function onDetailDelete( $param )
  284. {
  285. // clear detail form fields
  286. $data = new stdClass;
  287. $data->detail_uniqid = '';
  288. $data->detail_id = '';
  289. $data->detail_dt_oferta = '';
  290. $data->detail_plano_id = '';
  291. $data->detail_valor = '';
  292. // send data, do not fire change/exit events
  293. TForm::sendData( 'form_Receita', $data, false, false );
  294. // remove row
  295. TDataGrid::removeRowById('Oferta_list', $param['uniqid']);
  296. }
  297. /**
  298. * Load Master/Detail data from database to form
  299. */
  300. public function onEdit($param)
  301. {
  302. try
  303. {
  304. TTransaction::open('sudeste');
  305. if (isset($param['key']))
  306. {
  307. $key = $param['key'];
  308. $object = new Receita($key);
  309. $items = Oferta::where('receita_id', '=', $key)->load();
  310. foreach( $items as $item )
  311. {
  312. $item->uniqid = uniqid();
  313. $row = $this->detail_list->addItem( $item );
  314. $row->id = $item->uniqid;
  315. }
  316. $this->form->setData($object);
  317. TTransaction::close();
  318. }
  319. else
  320. {
  321. $this->form->clear(TRUE);
  322. }
  323. }
  324. catch (Exception $e) // in case of exception
  325. {
  326. new TMessage('error', $e->getMessage());
  327. TTransaction::rollback();
  328. }
  329. }
  330. /**
  331. * Save the Master/Detail data from form to database
  332. */
  333. public function onSave($param)
  334. {
  335. try
  336. {
  337. // open a transaction with database
  338. TTransaction::open('sudeste');
  339. $data = $this->form->getData();
  340. $this->form->validate();
  341. $master = new Receita;
  342. $master->fromArray( (array) $data);
  343. $master->total = $master->contribuicoes + $master->ofertas + $master->patrimonial + $master->promocoes + $master->outros;
  344. $master->dizimo = $master->total * (10 / 100);
  345. $master->system_user_id = TSession::getValue('userid');
  346. $master->system_unit_id = TSession::getValue('userunitid');
  347. $master->store();
  348. Oferta::where('receita_id', '=', $master->id)->delete();
  349. $total = 0;
  350. if( $param['Oferta_list_dt_oferta'] )
  351. {
  352. foreach( $param['Oferta_list_dt_oferta'] as $key => $item_id )
  353. {
  354. $detail = new Oferta;
  355. $detail->dt_oferta = $param['Oferta_list_dt_oferta'][$key];
  356. $detail->plano_id = $param['Oferta_list_plano_id'][$key];
  357. $detail->valor = $param['Oferta_list_valor'][$key];
  358. $detail->receita_id = $master->id;
  359. $total += $detail->valor;
  360. $detail->store();
  361. }
  362. }
  363. $master->ofertas_a_repassar = $total;
  364. $master->store(); // stores the object
  365. TForm::sendData('form_Receita', (object) ['id' => $master->id]);
  366. TTransaction::close(); // close the transaction
  367. new TMessage('info', AdiantiCoreTranslator::translate('Record saved'));
  368. }
  369. catch (Exception $e) // in case of exception
  370. {
  371. new TMessage('error', $e->getMessage());
  372. $this->form->setData( $this->form->getData() ); // keep form data
  373. TTransaction::rollback();
  374. }
  375. }
  376. }

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 (5)


NR

Provavelmente a função store do model Receita está chamando saveAggregate ou saveComposite. Essas funções fazem o delete dos itens antes de salvar os novos. No seu caso, como está controlando isso diretamente no onSave, pode apagar a função store do model
AR

Era isso mesmo.
Muito obrigado Nataniel.
Grande abraço!
AR

Boa tarde Natanael,

Neste mesmo formulário, coloquei as máscaras para os valores numéricos em todos os campos (->setNumericMask(2,',','.', true))

Ao salvar está multiplicando e salvando os valores informados por 100.

Se informo 100 ele salva 10.000.

Tem idéia do que pode ser isso?
AL

Boa tarde a todos, estou com o mesmo problema, quando salvo um registro no datails ele coloca o valor de 95.000,00 como 95000.00 e quando salva o registro ele coloca mais dois zeros, estou tentando tirar dois zeros antes de salvar o campo.
AL

Boa tarde a todos!

Estou com o mesmo problema, quando salvo um registro no datalhe ele coloca o valor de 95.000,00 como 95000.00 no formulário e quando salva o registro ele coloca mais dois zeros, estou tentando tirar dois zeros antes de salvar o campo.