352 lines
13 KiB
PHP
352 lines
13 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Almoxarifado;
|
|
|
|
use App\Enums\Almoxarifado\SaidaTipo;
|
|
use App\Exceptions\Almoxarifado\BaixaEstoqueIndisponivelException;
|
|
use App\Exceptions\Almoxarifado\EstoqueIndisponivelException;
|
|
use App\Models\Almoxarifado\EntradaItem;
|
|
use App\Models\Almoxarifado\MotivoBaixa;
|
|
use App\Models\Almoxarifado\Saida;
|
|
use App\Models\Almoxarifado\SaidaItem;
|
|
use App\Models\Cadastro\Material\Material;
|
|
use App\Models\Cadastro\SujeitoAtencao\Usuario;
|
|
use App\Services\Cadastro\Material\MaterialService;
|
|
use App\Services\Service;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Validation\Rule;
|
|
|
|
class BaixaService extends Service
|
|
{
|
|
public static function datatable()
|
|
{
|
|
$materiais = DB::table('cadastro_material')
|
|
->join(
|
|
'cadastro_grupo',
|
|
'cadastro_grupo.id',
|
|
'cadastro_material.grupo_id'
|
|
)
|
|
->join(
|
|
'cadastro_apresentacao',
|
|
'cadastro_apresentacao.id',
|
|
'cadastro_material.apresentacao_id'
|
|
)
|
|
->leftJoin(
|
|
'cadastro_subgrupo',
|
|
'cadastro_subgrupo.id',
|
|
'cadastro_material.subgrupo_id'
|
|
)
|
|
->leftJoin(
|
|
'cadastro_unidade_medida as apresentacao_unidade_medida',
|
|
'apresentacao_unidade_medida.id',
|
|
'cadastro_material.apresentacao_unidade_medida_id'
|
|
)
|
|
->leftJoin('almoxarifado_entrada_item', function ($join) {
|
|
|
|
$join
|
|
->on('almoxarifado_entrada_item.material_id', 'cadastro_material.id')
|
|
->whereExists(function ($query) {
|
|
|
|
$query
|
|
->select(DB::raw('1'))
|
|
->from('almoxarifado_entrada')
|
|
->whereColumn('almoxarifado_entrada.id', 'almoxarifado_entrada_item.entrada_id')
|
|
->where('almoxarifado_entrada.finalizada', true)
|
|
->where('almoxarifado_entrada.centro_custo_id', self::getCurrentCentroCusto()->id);
|
|
});
|
|
})
|
|
->whereNull('cadastro_material.deleted_at')
|
|
->where(function ($query) {
|
|
|
|
$query->where(function ($query) {
|
|
|
|
$query
|
|
->whereNull('cadastro_material.subgrupo_id')
|
|
->whereExists(function ($query) {
|
|
|
|
$query
|
|
->select(DB::raw(1))
|
|
->from('almoxarifado_parametrizacao_controle_estoque_grupo')
|
|
->whereColumn('almoxarifado_parametrizacao_controle_estoque_grupo.grupo_id', 'cadastro_material.grupo_id')
|
|
->where('almoxarifado_parametrizacao_controle_estoque_grupo.centro_custo_id', self::getCurrentCentroCusto()->id);
|
|
});
|
|
})->orWhere(function ($query) {
|
|
|
|
$query
|
|
->whereNotNull('cadastro_material.subgrupo_id')
|
|
->whereExists(function ($query) {
|
|
|
|
$query
|
|
->select(DB::raw(1))
|
|
->from('almoxarifado_parametrizacao_controle_estoque_subgrupo')
|
|
->join(
|
|
'almoxarifado_parametrizacao_controle_estoque_grupo',
|
|
'almoxarifado_parametrizacao_controle_estoque_grupo.id',
|
|
'almoxarifado_parametrizacao_controle_estoque_subgrupo.parametrizacao_controle_estoque_grupo_id'
|
|
)
|
|
->whereColumn('almoxarifado_parametrizacao_controle_estoque_subgrupo.subgrupo_id', 'cadastro_material.subgrupo_id')
|
|
->where('almoxarifado_parametrizacao_controle_estoque_grupo.centro_custo_id', self::getCurrentCentroCusto()->id);
|
|
});
|
|
});
|
|
})
|
|
->select(
|
|
'cadastro_material.id',
|
|
'cadastro_material.codigo_material',
|
|
DB::raw(MaterialService::getDescricaoCompletaRaw(
|
|
'cadastro_material',
|
|
'cadastro_apresentacao',
|
|
'apresentacao_unidade_medida'
|
|
) . " as descricao"),
|
|
'cadastro_material.is_ativo',
|
|
'cadastro_grupo.nome AS grupo',
|
|
'cadastro_subgrupo.nome AS subgrupo',
|
|
)
|
|
->distinct();
|
|
|
|
return datatables()
|
|
->of($materiais)
|
|
->filterColumn('descricao', function ($query, $keyword) {
|
|
|
|
$query->whereRaw(MaterialService::getDescricaoCompletaRaw(
|
|
'cadastro_material',
|
|
'cadastro_apresentacao',
|
|
'apresentacao_unidade_medida'
|
|
) . " like ?", ["%{$keyword}%"]);
|
|
})
|
|
->skipTotalRecords()
|
|
->toJson();
|
|
}
|
|
|
|
public static function history()
|
|
{
|
|
$saidas = DB::table('almoxarifado_saida')
|
|
->join(
|
|
'almoxarifado_saida_item',
|
|
'almoxarifado_saida_item.saida_id',
|
|
'almoxarifado_saida.id'
|
|
)
|
|
->join(
|
|
'almoxarifado_saida_baixa',
|
|
'almoxarifado_saida_baixa.saida_id',
|
|
'almoxarifado_saida.id'
|
|
)
|
|
->join(
|
|
'cadastro_lotacao as baixa_lotacao',
|
|
'baixa_lotacao.id',
|
|
'almoxarifado_saida_baixa.created_lotacao_id'
|
|
)
|
|
->join(
|
|
'cadastro_usuario as baixa_usuario',
|
|
'baixa_usuario.id',
|
|
'baixa_lotacao.usuario_id'
|
|
)
|
|
->join(
|
|
'cadastro_cidadao as baixa_cidadao',
|
|
'baixa_cidadao.id',
|
|
'baixa_usuario.cidadao_id'
|
|
)
|
|
->join(
|
|
'almoxarifado_motivo_baixa',
|
|
'almoxarifado_motivo_baixa.id',
|
|
'almoxarifado_saida_baixa.motivo_id'
|
|
)
|
|
->leftJoin(
|
|
'cadastro_usuario',
|
|
'cadastro_usuario.id',
|
|
'almoxarifado_saida_baixa.usuario_solicitante_id'
|
|
)
|
|
->leftJoin(
|
|
'cadastro_cidadao',
|
|
'cadastro_cidadao.id',
|
|
'cadastro_usuario.cidadao_id'
|
|
)
|
|
->select(
|
|
'almoxarifado_saida_item.id AS saida_item_id',
|
|
DB::raw("DATE_FORMAT(almoxarifado_saida.created_at, '%d/%m/%Y') AS data"),
|
|
'almoxarifado_motivo_baixa.descricao AS motivo_descricao',
|
|
'almoxarifado_saida_baixa.justificativa',
|
|
'baixa_cidadao.nome AS usuario_baixa_nome',
|
|
'cadastro_cidadao.nome AS usuario_solicitante_nome',
|
|
DB::raw('(
|
|
SELECT SUM(se.quantidade_saida)
|
|
FROM almoxarifado_saida_item_entrada_item se
|
|
WHERE se.saida_item_id = almoxarifado_saida_item.id
|
|
) as quantidade'),
|
|
DB::raw("DATE_FORMAT(almoxarifado_saida_item.estornado_em, '%d/%m/%Y') as data_estorno"),
|
|
DB::raw('IF (almoxarifado_saida_item.estornado_em IS NULL, 0, 1) AS estornado'),
|
|
)
|
|
->addSelect([
|
|
'usuario_estorno_nome' => function ($query) {
|
|
|
|
$query->select('entrada_item_estorno_cidadao.nome')
|
|
->from('almoxarifado_saida_item_entrada_item as saida_item_entrada_item')
|
|
->leftJoin(
|
|
'almoxarifado_entrada_item as entrada_item_estorno',
|
|
'entrada_item_estorno.id',
|
|
'saida_item_entrada_item.entrada_item_estornado_id'
|
|
)
|
|
->leftJoin(
|
|
'cadastro_lotacao as entrada_item_estorno_lotacao',
|
|
'entrada_item_estorno_lotacao.id',
|
|
'entrada_item_estorno.created_lotacao_id'
|
|
)
|
|
->leftJoin(
|
|
'cadastro_usuario as entrada_item_estorno_usuario',
|
|
'entrada_item_estorno_usuario.id',
|
|
'entrada_item_estorno_lotacao.usuario_id'
|
|
)
|
|
->leftJoin(
|
|
'cadastro_cidadao as entrada_item_estorno_cidadao',
|
|
'entrada_item_estorno_cidadao.id',
|
|
'entrada_item_estorno_usuario.cidadao_id'
|
|
)
|
|
->whereColumn('saida_item_entrada_item.saida_item_id', 'almoxarifado_saida_item.id')
|
|
->limit(1);
|
|
},
|
|
])
|
|
->where('almoxarifado_saida.tipo_id', SaidaTipo::BAIXA)
|
|
->where('almoxarifado_saida_item.material_id', request()->query('material_id'))
|
|
->where('almoxarifado_saida.centro_custo_id', self::getCurrentCentroCusto()->id);
|
|
|
|
return datatables()
|
|
->of($saidas)
|
|
->filterColumn('almoxarifado_saida.created_at', function ($query, $keyword) {
|
|
|
|
$query->whereRaw("DATE_FORMAT(almoxarifado_saida.created_at, '%d/%m/%Y') like ?", ["%{$keyword}%"]);
|
|
})
|
|
->toJson();
|
|
}
|
|
|
|
public static function create($materialId)
|
|
{
|
|
$material = Material::findOrFail($materialId);
|
|
$estoque = AlmoxarifadoService::getEstoque($material->id);
|
|
|
|
$entradaItens = collect($estoque['por_entrada'])->map(function ($entradaItem) {
|
|
|
|
$entradaItem->quantidade_saida = 0;
|
|
|
|
return $entradaItem;
|
|
});
|
|
|
|
return [
|
|
'form' => [
|
|
'motivos' => MotivoBaixa::orderBy('descricao')
|
|
->get(['id', 'tipo_id', 'descricao', 'justificar']),
|
|
'possui_entrada_com_lote' => !is_null($entradaItens->whereNotNull('lote')->first()),
|
|
],
|
|
'model' => [
|
|
'motivo_id' => null,
|
|
'justificativa' => null,
|
|
'usuario_solicitante' => null,
|
|
'estoque' => $estoque['total'],
|
|
'quantidade' => null,
|
|
'escolheu_entrada_item_manualmente' => false,
|
|
'entrada_itens' => $entradaItens,
|
|
],
|
|
];
|
|
}
|
|
|
|
public static function store()
|
|
{
|
|
self::validate();
|
|
|
|
$saida = new Saida();
|
|
|
|
DB::transaction(function () use (&$saida) {
|
|
|
|
try {
|
|
|
|
$saida = AlmoxarifadoService::saveSaidaDeBaixa(self::getParams());
|
|
}
|
|
catch (EstoqueIndisponivelException $e) {
|
|
|
|
throw new BaixaEstoqueIndisponivelException();
|
|
}
|
|
});
|
|
|
|
return $saida->itens()->first();
|
|
}
|
|
|
|
private static function getParams()
|
|
{
|
|
return [
|
|
'material_id' => request()->material_id,
|
|
'motivo_id' => request()->motivo_id,
|
|
'justificativa' => request()->justificativa,
|
|
'usuario_solicitante_id' => request()->usuario_solicitante_id,
|
|
'quantidade' => (int) request()->quantidade,
|
|
'entrada_itens' => collect(request()->entrada_itens)->map(fn ($entradaItem) => [
|
|
'entrada_item_id' => $entradaItem['entrada_item_id'],
|
|
'quantidade_saida' => (int) $entradaItem['quantidade_saida'],
|
|
]),
|
|
'escolheu_entrada_item_manualmente' => request()->escolheu_entrada_item_manualmente,
|
|
];
|
|
}
|
|
|
|
public static function reverse($saidaItemId)
|
|
{
|
|
$saidaItem = SaidaItem::findOrFail($saidaItemId);
|
|
|
|
DB::transaction(function () use ($saidaItem) {
|
|
|
|
AlmoxarifadoService::estornarSaidaItens(collect([
|
|
['id' => $saidaItem->id]
|
|
]));
|
|
});
|
|
}
|
|
|
|
public static function validate()
|
|
{
|
|
$rules = [
|
|
'material_id' => [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(Material::class, 'id'),
|
|
],
|
|
'motivo_id' => [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(MotivoBaixa::class, 'id'),
|
|
],
|
|
'justificativa' => [
|
|
'nullable',
|
|
'string',
|
|
'max:100',
|
|
],
|
|
'usuario_solicitante_id' => [
|
|
'nullable',
|
|
'integer',
|
|
Rule::exists(Usuario::class, 'id'),
|
|
],
|
|
'quantidade' => [
|
|
'required',
|
|
'integer',
|
|
'min:1',
|
|
],
|
|
'escolheu_entrada_item_manualmente' => [
|
|
'required',
|
|
'boolean',
|
|
],
|
|
'entrada_itens' => [
|
|
'present',
|
|
'array',
|
|
],
|
|
'entrada_itens.*.entrada_item_id' => [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(EntradaItem::class, 'id'),
|
|
],
|
|
'entrada_itens.*.quantidade_saida' => [
|
|
'required',
|
|
'integer',
|
|
'min:1',
|
|
],
|
|
];
|
|
|
|
$messages = [];
|
|
|
|
request()->validate($rules, $messages);
|
|
}
|
|
}
|