Crie o model Saida
para criar o model Saida use o comando: php artisan make:model Saida -m
configure os campos:
- produto_id (relacionado com a tabela produto)
- qtde_saida decimal
- valor_saida decimal
- subtotal_saida decimal
- data_saida data
- observacao text (opcional)
Schema::create('saidas', function (Blueprint $table) {
$table->id();
$table->BigInteger("produto_id")->unsigned();
$table->foreign("produto_id")->references("id")->on("produtos");
$table->decimal("qtde_saida",10,2)->default(1);
$table->decimal("valor_saida")->default(0);
$table->decimal("subtotal_saida",5,2);
$table->date("data_saida");
$table->string("observacao")->nullable();
$table->timestamps();
});
Crie um controller chamado Saida, para que o projeto fique mais organizado salve o controller numa pasta chamada Estoque
No controller SaidaController crie o método index, o qual deverá:
- pegar a lista de entradas e colocar um array
- chamar a view Saida/Index com o array criado com a lista de entradas
public function index(){
$dados["lista"] = Saida::get();
$dados["entradaJs"] = true;
return view("Estoque.Saida.Create", $dados);
}
Crie a view para a listagem de saida
Dentro da pasta resources/view crie uma pasta chamada de Estoque e dentro de Estoque crie uma outra chamada de Saida e dentro da pasta Saida crie um arquivo chamado Create.blade.php
Copie o conteúdo do arquivo lst_saida para o arquivo Estoque/Saida/Create.blade.php, não esqueça envolvê-lo pelos comandos:
@extends('template')
@section('conteudo')
//aqui fica o conteúdo do arquivo
@endsection
Na view Create, faça os seguintes procedimentos:
- Faça o loop para receber os dados do banco e listar na tabela
@foreach ($lista as $l)
<tr>
<td align="center">{{ $l->id }}</td>
<td align="center">{{ databr($l->data_saida) }}</td>
<td align="left">{{ $l->produto->nome }}</td>
<td align="center">{{ $l->qtde_saida }}</td>
<td align="center">{{ $l->valor_saida }}</td>
<td align="center">{{ $l->subtotal_saida }}</td>
</tr>
@endforeach
Configure os elementos inputs da view Index para inserção das saida, com as seguintes ações:
- Para o input valor sete o id para preco e insira a classe mascara-float
- Para o input qtde sete o id para qtde e insira a classe mascara-float
- crie um input hidden com o id ="produto_id"
- no link chame o método inserirSaidaEstoque para o evento onclick
<div class="border p-3 radius-4 pb-4 caixafield">
<div class="rows center-middle">
<div class="col-6 position-relative">
<label class="text-label">Produto</label>
<div class="grupo-form-btn">
<input type="text" name="produtosaida" id="produtosaida" class="form-campo">
<a href="{{ route('produto.create') }}" class="border radius-50 p-1 fas fa-plus"
title="Inserir novo Produto"></a>
</div>
</div>
<div class="col-2">
<label class="text-label">Valor</label>
<input type="text" id="preco" name="preco" value=""
class="form-campo mascara-float">
</div>
<div class="col-2">
<label class="text-label">Qtde</label>
<input type="text" name="qtde" id="qtde" value=""
class="form-campo mascara-float">
</div>
<div class="col-2 mt-4">
<input type="hidden" id="produto_id" name="produto_id">
<a href="javascript:;" onclick="inserirSaidaEstoque()" class="btn btn-roxo width-100">
Inserir</a>
</div>
</div>
</div>
Vamos criar uma função para buscar os produtos via jquery
Crie um arquivo javascript chamado js_saida.js dentro da public/assets/js
Crie um método chamado produtosaida, o que deverá ser disparado no evento keyup, este método deverá fazer uma consulta no banco via jquery, passando como parâmetro o texto a ser pesquisado e deverá a lista de produtos que contenha o respectivo texto, em seguida deverá mostrar essa lista em uma div abaixo do componente no qual foi digitado o texto.
Ao clicar em um dos itens da lista deverá popular os componentes qtde, preco e produto_id com os respectivos valor e fechar a lista, levando o foco para a qtde.
$(function(){
$("#produtosaida").on("keyup", function(){
var q = $(this).val();
if(q==""){
$(".listaProdutos").hide();
return false;
}
$.ajax({
url:base_url+"produto/pesquisa",
type:"GET",
dataType:"JSON",
data:{q:q},
success:function(data){
console.log(data);
$("#produtosaida").after('<div class="listaProdutos"></div>');
html="";
for(var i in data){
html +='<div class="si"><a href="javascript:;" onclick="selecionarProdutoSaida(this)" ' +
'data-id="'+data[i].id +
'" data-preco = "' + data[i].preco_venda +
'" data-nome = "' + data[i].nome +
'" data-estoque = "' + data[i].estoque_atual + '">' +
data[i].id + " - " + data[i].nome + " - RS " + data[i].preco_venda + '</a></div>';
}
$(".listaProdutos").html(html);
$(".listaProdutos").show();
},
error:function(data){
}
});
});
})
function selecionarProdutoSaida(obj){
var id = $(obj).attr('data-id');
var nome = $(obj).attr('data-nome');
var preco = $(obj).attr('data-preco');
var estoque = $(obj).attr('data-estoque');
$(".listaProdutos").hide();
$("#produto_id").val(id);
$("#produtosaida").val(nome);
$("#preco").val(preco);
$("#subtotal").val(preco);
$("#qtde").val(1);
$("#qtde").focus();
}
No controller ProdutoController crie um método chamado pesquisa, o qual deverá receber via get uma variável chamada q, e em seguida pesquisar a lista de produtos que contenha o valor da variável e retorne o resultado no formato json
public function pesquisa(){
$q = $_GET["q"];
$produtos = Produto::where("nome", "like","%$q%")->get();
return response()->json($produtos);
}
Vamos criar os métodos para fazer inserção da saida de produto
No arquivo js_saida.js crie um método chamado inserirSaidaEstoque, o que deverá invocar a rota entrada/salvarjs e enviar como parâmetros o produto_id, qtde, valor e caso não retorne nenhum erro dar um refresh na tela. Além disso, antes de invocar o método faça a validação se:
- O produto_id é diferente de vazio
- A qtde é diferente de vazio.
function inserirSaidaEstoque(){
var produto_id = $("#produto_id").val();
var qtde = $("#qtde").val();
var valor = $("#preco").val();
if(produto_id==""){
alert("Selecione um produto primeiramente");
$("#produtosaida").focus();
return false;
}
if(qtde==""){
alert("Digite a quantidade");
$("#qtde").focus();
return false;
}
$.ajax({
url:base_url+"saida/salvarJs",
type:"POST",
dataType:"JSON",
data:{
produto_id:produto_id,
qtde :qtde,
valor :valor
},
success:function(data){
fecharModal();
if(data.tem_erro==true){
$("#mostrarUmErro").html(MostrarUmaMsgErro("Erro: " + data.erro));
}else{
$("#mostrarSucesso").html(MostrarUmaMsgSucesso("inserido com sucesso"));
location.reload();
}
},
error:function(data){
}
});
}
Crie um método chamado salvarJs no controller SaidaController, este método deverá:
- Validar os campos qtde e valor para que fiquem no formato correto para inserçao de dados (decimal), use o método getFloat para isso
- fazer a multiplicação da qtde x valor e atribuir o resultado ao campo subtotal_saida.
- inserir os dados no banco de dados e retornar se a operação foi ou não realizada com sucesso, retornando um json
public function salvarJs(Request $request) {
$retorno = new \stdClass();
try {
$obj = new \stdClass();
$obj->produto_id = $request->produto_id ;
$obj->qtde_saida = getFloat($request->qtde) ;
$obj->valor_saida = getFloat($request->valor);
$obj->subtotal_saida = $obj->qtde_saida * $obj->valor_saida;
$obj->data_saida = date("Y-m-d");
$saida = Saida::create(objToArray($obj));
$retorno->tem_erro = false;
return response()->json($retorno);
} catch (\Exception $e) {
$retorno->tem_erro = true;
$retorno->erro = $e->getMessage();
return response()->json($retorno);
}
}
Tente fazer uma entrada de produto, a essa altura já é pra dar tudo certo.
Prepare seu sistema para que permita que sejam feitos filtros por produto e intervalo de datas
No método index faça as seguintes implementações:
- Coloque um Request como parâmetro de recebimento do método
- Crie um objeto chamado filtro com os campos data1, data2 e produto_id
- No array $dados["lista"] chame o método filtro do model entrda e passe como parâmetro o objeto filtro criado
- No array $dados["produtos"] chame a lista de produtos para ser mostrado no combo de filtro
- para o array $dados liste as saidas
public function index(Request $request){
$filtro = new \stdClass();
$filtro->data1 = $request->data1 ?? hoje();
$filtro->data2 = $request->data2 ?? hoje();
$filtro->produto_id = $request->produto_id ?? null;
$dados["lista"] = Saida::filtro($filtro);
$dados["produtos"] = Produto::get();
$dados["filtro"] = $filtro;
$dados["saidaJs"] = true;
return view("Estoque.Saida.Create", $dados);
}
No model Saida, crie um método chamado filtro que receba como parâmetro um objeto $filtro e um variável chamada $paginas inicializada com zero e implemente o método de forma que:
- Se houver o campo $filtro->produto_id, faça o filtro pelo produto_id
- se houver o campo $filtro->data1, faça o filtro pela data1
- se o parametro data2 for enviado faça uma busca no intervalo de data1 e data2
- se a variável páginas for maior que zero que o seja do tipo paginate(), senão que seja get()
public static function filtro($filtro, $paginas=0){
$retorno = self::query();
if($filtro->produto_id){
$retorno->where("produto_id", $filtro->produto_id);
}
if($filtro->data1){
if($filtro->data2){
$retorno->where("data_saida",">=", $filtro->data1)->where("data_saida","<=", $filtro->data2);
}else{
$retorno->where("data_saida", $filtro->data1);
}
}
if($paginas>0){
$retorno = $retorno->paginate($paginas);
}else{
$retorno = $retorno->get();
}
return $retorno;
}
Na view index, no formulário do filtro implemente o seguinte:
- Preencha o elemento select do filtro com a lista de Produto e sete a propriedade name para produto_id
- Para o input de data1 atribua a propriedade name para data1 e no value faça a verificação se existe o objetivo $filtro->data1 se sim mostre.
- Para o input de data2 atribua a propriedade name para data1 e no value faça a verificação se existe o objetivo $filtro->data2 se sim mostre.
<div class="mostraFiltro bg-padrao mt-2 p-2 radius-4 border">
<div class="rows center-middle">
<div class="col-3">
<label class="text-label d-block text-branco">Data 1</label>
<input type="date" name="data1" value="{{ $filtro->data1 ?? null }}"
class="form-campo">
</div>
<div class="col-3">
<label class="text-label d-block text-branco">Data 2</label>
<input type="date" name="categoria" value="{{ $filtro->data1 ?? null }}"
class="form-campo">
</div>
<div class="col-4">
<label class="text-label d-block text-branco">Selecionar Produto </label>
<select name="produto_id" class="form-campo">
<option value="">Selecione uma Produto</option>
@foreach ($produtos as $prod)
<option value="{{ $prod->id }}"
{{ ($filtro->produto_id ?? null) == $prod->id ? 'selected' : '' }}>
{{ $prod->nome }}</option>
@endforeach
</select>
</div>
<div class="col-2 mt-4">
<input type="submit" value="Pesquisar" class="w-100 btn btn-roxo text-uppercase">
</div>
</div>
</div>
Faça o teste com os filtros