Yii Framework Forum: Formulário Master - Detail (Ordem De Compras) - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Formulário Master - Detail (Ordem De Compras) Como criar um formulário com 1 Cabeçalho e vários Itens? Rate Topic: -----

#1 User is offline   Gustavo Gonçalves 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 40
  • Joined: 02-October 12
  • Location:Belo Horizonte, MG - Brasil

Posted 08 October 2012 - 08:34 AM

Pessoal, bom dia à todos.

Estou desenvolvendo um sistema de Gerenciamento Comercial (Contas a pagar, receber, compras, vendas, estoque) para uso próprio. Pesquisei várias opções no mercado, mas todas ficavam acima do meu orçamento. Portanto, resolvi criar coragem e desenvolver eu mesmo.

O problema é que apesar de trabalhar com informática desde 1995, eu nunca fui programador Web. Então estou começando tudo do zero, pesquisando bastante nas documentações e fóruns sobre o assunto.

Agora preciso aprender a criar formulários Master/Detail. Vou começar pela Ordem de Compras, mas vou utilizar isso em diversas situações.

No meu caso, tenho uma tabela MASTER (CABEÇALHO DE COMPRA) e a DETAIL (ITENS DE COMPRA).

Achei algumas informações sobre isso, mas nenhuma tão didática para um leigo como eu.
Não consegui inserir os links (pois é meu primeiro post).. então anexei em um arquivo txt.

O que já construí:
- Fiz um formulário com três abas (Principal, Itens e Pagamento)
- Na aba "Itens" usei um campo Typehead, que ao selecionar o item, preenche outros campos com o código e preço do produto

O que preciso:
- Colocar um botão para inserir/editar vários itens em uma "tabela"
- Deixando para gravar no banco apenas no final, quando o usuário mandar salvar o formulário principal

Gostaria, por favor, da ajuda de vocês para conseguir resolver essa 1a. grande dúvida !

Muito obrigado !

* Coloquei a tela em anexo para vocês visualizarem melhor.

Gustavo Gonçalves

Attached File(s)


0

#2 User is offline   Newerton 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 803
  • Joined: 27-April 10
  • Location:Campo Grande/MS - Cambé/PR, Brasil

Posted 08 October 2012 - 09:57 PM

Gustavo,

Para inserir vários itens ao mesmo tempo, os campos do formulário, precisam está em formato de array().

Você pode fazer de 2 formas.
1. Setar quantos campos somente vai precisar, por exemplo no máximo 20 campos, neste caso você irá usar o for() do PHP.
2. Criar 1 campo, e os demais campos cria usando o jQuery, a função clone, assim você pode usar 2 ou 200 campos.
Exemplo de como usar o clone: http://www.mkyong.co...-clone-example/

Para adicionar vários itens usando o for().
http://www.yiiframew...1/pt/form.table

Neste doc, ensina como fazer no formulário e no controller para coletar os dados.
Newerton Vargas de Araújo
0

#3 User is offline   Gustavo Gonçalves 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 40
  • Joined: 02-October 12
  • Location:Belo Horizonte, MG - Brasil

Posted 10 October 2012 - 08:15 AM

Olá Newerton,

Obrigado pela dica.

Mas em função do layout da página pensei em fazer o seguinte para o cadastro de Itens:
- Colocar uma GridView com um DataProvider vazio (inicialmente)
- Veja que na minha imagem, coloquei um botão "Inserir"... através dele quero chamar uma função (addItem) no Controller para Validar os campos e Inserir os registros no DataProvider.
- No momento de salvar o formulário todo (Ordem de Compras), lá na Action Create, faço um foreach no DataProvider dos Itens, criando um novo Model e aplicando o método Save().

Preciso de duas dicas, se possível com exemplo do código, pois já estou há mais de 8 horas pesquisando essa solução:
- Como passar o DataProvider da view Create para a action addItem do Controller ?
- Como devolver o DataProvider para a View e atualizar a GridView ?

Achei algumas coisas na internet, mas não consegui aplicar nenhuma.

Um abraço e muito obrigado !

Abaixo segue o trecho do código da View Create:
		<?php $this->widget('bootstrap.widgets.TbButton', array(
			'icon' => 'icon-plus',
			'size' =>'medium',
			'type' => 'warning',
			'buttonType' => 'ajaxLink',
			'url' => $this->createUrl('addItem'),
			'ajaxOptions'=>array('type'=>'POST', 'success'=>'allFine'),
			
		)); ?>


<div id='results'>...</div>
<script>
        function allFine(data) {
                // display data returned from action
                $("#results").html(data);
                // refresh your grid
                $.fn.yiiGridView.update('itens-grid');
        }
</script>

<?php
$this->widget('zii.widgets.grid.CGridView', array(
	'id'=>'itens-grid',
    'dataProvider'=>$dp_itens,
    'columns'=>array(
		'id_compra',
		'id_item',
		'id_produto',
		'qtde',
		'desconto',
		'valor',
    ),
));
?>

0

#4 User is offline   Gustavo Gonçalves 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 40
  • Joined: 02-October 12
  • Location:Belo Horizonte, MG - Brasil

Posted 11 October 2012 - 09:21 AM

Bom dia a todos,

Atualizando ...

Despois de muito custo consegui atualizar a GridView com um novo DataProvider. (abaixo vou explicar como fiz)

Agora preciso de ajuda para conseguir enviar o DataProvider ativo da View -> Controller.
Já li algo sobre usar Session, mas estou com dúvidas e não sei se é bom.
Outra opção seria fazer um Foreach na View, "desconstruindo" o Array em vários campos ocultos na página. Assim eu poderia recuperá-los através do $_POST dentro do Controller.

O que é melhor fazer ? Existe outra opção ?


Abaixo segue a explicação de como atualizar uma CGridView a partir de um novo DataProviderArray, quando se clica em algum botão ajax.

Na minha View Principal, tenho um botão Adicionar Itens:

<script>
        function allFine(data) {
                $("#div_itens").html(data);
        }
</script>


		<?php $this->widget('bootstrap.widgets.TbButton', array(
			'icon' => 'icon-plus',
			'size' =>'medium',
			'type' => 'warning',
			'buttonType' => 'ajaxLink',
			'url' => $this->createUrl('addItem'),
			'ajaxOptions'=>array('type'=>'POST',
			'success'=>'allFine', 
						),
			
		)); ?>



No final desta página, tenho o comando abaixo:
<?php echo $this->renderPartial('_griditens', array('dp_itens'=>$dp_itens,)); ?>


Criei uma outra View, "_griditens.php" que contém apenas a GridView dos Itens, pois ela recebe apenas o $dp_itens.
Isso foi importante, para não ter que fazer Render de todos os Models.
Coloquei os botões "Editar" e "Excluir" para manipular os valores do mesmo jeito da Action addItens.
<div class="row-fluid" id="div_itens">
	<div class="span10">		
		<?php 
		$this->widget('bootstrap.widgets.TbGridView',array(
			'id'=>'itens-grid',
			'template'=>"{items}",	
			'dataProvider'=>$dp_itens,
			'type'=>'striped bordered condensed',
			'columns'=>array(
		        array(
			            'name' => 'Produto',
			            'type' => 'raw',
			            'value' => 'CHtml::encode($data["produto"])'
			        ),				
		        array(
			            'name' => 'Qtde',
			            'type' => 'raw',
			            'value' => 'CHtml::encode($data["qtde"])'
			        ),				
		        array(
			            'name' => 'Valor',
			            'type' => 'raw',
			            'value' => 'CHtml::encode($data["valor"])'
			        ),				
		        array(
			            'name' => 'Desconto',
			            'type' => 'raw',
			            'value' => 'CHtml::encode($data["desconto"])'
			        ),				
		        array(
			            'name' => 'SubTotal',
			            'type' => 'raw',
			            'value' => 'CHtml::encode($data["subtotal"])'
			        ),				
				 array(
					'htmlOptions' => array('nowrap'=>'nowrap'),
					'class'=>'bootstrap.widgets.TbButtonColumn',
					'template'=>'{update}{delete}',
					'viewButtonUrl'=>null,
					'updateButtonUrl'=>null,
					'deleteButtonUrl'=>null,				 
                    'buttons'=>array(       
                                'update' => array(
                                  'url'=>'Yii::app()->controller->createUrl("editItem", array("id"=>$data["id"]))',
                                ),
                      			'delete' => array(
                                  //'url'=>'Yii::app()->controller->createUrl("ports/delete", array("id"=>$data[id],"command"=>"delete"))',
                                ),
                         	),				 
				),
			),
		)); 
		?> 
	</div>
</div>	




No meu controller, tenho a Action que é chamada:
	public function actionAddItem()
	{
	    if(!empty($_POST))

               // se precisar fazer um loop em vários campos do $_POST, usar este comando
	       //while(list($key, $val) = each($_POST)) {
	   	  //echo $key."=".$val."<br>";  // so para ver os valores, nao é necessario
	       //}
	   		

               // Cria um novo model limpo, da tabela itens
               $model_itens_add=new Compras02;
	       $model_itens_add->unsetAttributes();

	       $produto = $_POST['searchproduto'];
	       $model_itens_add->id_produto 	= $_POST['add_id'];
	       $model_itens_add->qtde 		= $_POST['add_qtde'];
	       $model_itens_add->desconto 	= $_POST['add_desc'];
	       $model_itens_add->valor 		= $_POST['add_valor'];
				
               ////////////////////////////
               // NESTE PONTO PRECISO TER O DATAPROVIDER ATUAL, PARA JUNTAR COM O NOVO REGISTRO
               ////////////////////////////

		// Dados do GridView
		$rawData=array(
			array('id'=>1, 
				  'produto'=>$produto, 
				  'qtde'=>$model_itens_add->qtde, 
				  'valor'=>$model_itens_add->valor, 
				  'desconto'=>$model_itens_add->desconto, 
				  'subtotal'=>($model_itens_add->qtde * $model_itens_add->valor) - $model_itens_add->desconto,
				  ), 
		);
		
       // Criando o novo Array para a Tabela GridView	 
       // or using: $rawData=User::model()->findAll();
       $dp_itens=new CArrayDataProvider($rawData, array(
           'id'=>'id',
           'sort'=>array(
               'attributes'=>array(
                   'produto',
               ),
           ), 
           'pagination'=>array(
               'pageSize'=>15,
           ),
       ));

		
                // Nao é necessário, deixei aqui pra testar depois o merge de arrays
                // Fazendo um Merge dos Arrays
		//$data = $dp_itens->getData();
		//$data[] = $model_itens_add;
		//$dp_itens->setData($data);		

		// Devolvendo os valores para a página		
		 $this->renderPartial('_griditens',array(
			 'dp_itens'=>$dp_itens,
		 ));		
	}



Espero que seja útil para alguém !!!
Coloquei a tela em anexo para vocês verem como ficou. Lógico que ainda falta formatar os campos valores e etc.

Attached File(s)


0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users