This commit is contained in:
367
api/app/Services/Almoxarifado/SaidaService.php
Normal file
367
api/app/Services/Almoxarifado/SaidaService.php
Normal file
@@ -0,0 +1,367 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Almoxarifado;
|
||||
|
||||
use App\Enums\Almoxarifado\SaidaTipo;
|
||||
use App\Models\Almoxarifado\EntradaItem;
|
||||
use App\Models\Almoxarifado\Saida;
|
||||
use App\Models\Almoxarifado\SaidaItem;
|
||||
use App\Models\Almoxarifado\SaidaRequisicao;
|
||||
use App\Models\Cadastro\Estabelecimento\CentroCusto;
|
||||
use App\Models\Cadastro\Estabelecimento\Unidade;
|
||||
use App\Models\Cadastro\Material\Material;
|
||||
use App\Models\Cadastro\SujeitoAtencao\Usuario;
|
||||
use App\Models\Almoxarifado\BalanceteFechamento;
|
||||
use App\Services\Service;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class SaidaService extends Service
|
||||
{
|
||||
public static function datatable()
|
||||
{
|
||||
$saidas = DB::table('almoxarifado_saida')
|
||||
->join(
|
||||
'almoxarifado_saida_requisicao',
|
||||
'almoxarifado_saida_requisicao.saida_id',
|
||||
'almoxarifado_saida.id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_centro_custo',
|
||||
'cadastro_centro_custo.id',
|
||||
'almoxarifado_saida_requisicao.centro_custo_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_setor',
|
||||
'cadastro_setor.id',
|
||||
'cadastro_centro_custo.setor_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_infraestrutura',
|
||||
'cadastro_infraestrutura.id',
|
||||
'cadastro_centro_custo.infraestrutura_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_unidade',
|
||||
'cadastro_unidade.id',
|
||||
'cadastro_infraestrutura.unidade_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_usuario',
|
||||
'cadastro_usuario.id',
|
||||
'almoxarifado_saida_requisicao.usuario_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_cidadao',
|
||||
'cadastro_cidadao.id',
|
||||
'cadastro_usuario.cidadao_id'
|
||||
)
|
||||
->select(
|
||||
'almoxarifado_saida.id',
|
||||
DB::raw("DATE_FORMAT(almoxarifado_saida_requisicao.data, '%d/%m/%Y') as data_requisicao"),
|
||||
DB::raw("cadastro_unidade.nome_fantasia AS unidade_nome_fantasia"),
|
||||
DB::raw("COALESCE(cadastro_infraestrutura.nome, cadastro_unidade.nome_fantasia) AS infraestrutura_nome"),
|
||||
'cadastro_setor.nome as setor_nome',
|
||||
'cadastro_cidadao.nome AS usuario_nome',
|
||||
'almoxarifado_saida_requisicao.numero',
|
||||
DB::raw("DATE_FORMAT(almoxarifado_saida.created_at, '%d/%m/%Y') as data_saida"),
|
||||
'almoxarifado_saida.finalizada',
|
||||
)
|
||||
->where('almoxarifado_saida.tipo_id', SaidaTipo::MANUAL)
|
||||
->where('almoxarifado_saida.centro_custo_id', self::getCurrentCentroCusto()->id);
|
||||
|
||||
return datatables()
|
||||
->of($saidas)
|
||||
->filterColumn('almoxarifado_saida_requisicao.data', function ($query, $keyword) {
|
||||
|
||||
$query->whereRaw("DATE_FORMAT(almoxarifado_saida_requisicao.data, '%d/%m/%Y') like ?", ["%{$keyword}%"])
|
||||
->orWhereRaw(
|
||||
"CONCAT(
|
||||
SUBSTR(almoxarifado_saida_requisicao.data,9,2),
|
||||
SUBSTR(almoxarifado_saida_requisicao.data,6,2),
|
||||
SUBSTR(almoxarifado_saida_requisicao.data,1,4)
|
||||
) like ?",
|
||||
["%{$keyword}%"]
|
||||
);
|
||||
})
|
||||
->filterColumn('almoxarifado_saida.created_at', function ($query, $keyword) {
|
||||
|
||||
$query->whereRaw("DATE_FORMAT(almoxarifado_saida.created_at, '%d/%m/%Y') like ?", ["%{$keyword}%"])
|
||||
->orWhereRaw(
|
||||
"CONCAT(
|
||||
SUBSTR(almoxarifado_saida.created_at,9,2),
|
||||
SUBSTR(almoxarifado_saida.created_at,6,2),
|
||||
SUBSTR(almoxarifado_saida.created_at,1,4)
|
||||
) like ?",
|
||||
["%{$keyword}%"]
|
||||
);
|
||||
})
|
||||
->filterColumn('cadastro_infraestrutura.nome', function ($query, $keyword) {
|
||||
|
||||
$query->whereRaw("COALESCE(cadastro_infraestrutura.nome, cadastro_unidade.nome_fantasia) like ?", ["%{$keyword}%"]);
|
||||
})
|
||||
->skipTotalRecords()
|
||||
->toJson();
|
||||
}
|
||||
|
||||
public static function create()
|
||||
{
|
||||
return [
|
||||
'additionals' => self::getAdditionalsData(),
|
||||
'form' => self::getFormData(),
|
||||
'model' => [
|
||||
'finalizada' => false,
|
||||
'requisicao' => [
|
||||
'centro_custo_id' => null,
|
||||
'usuario' => null,
|
||||
'numero' => ParametrizacaoService::getParametrizacaoRequisicao()['numero_requisicao_automatico']
|
||||
? ParametrizacaoService::getNovoNumeroRequisicao() : null,
|
||||
'data' => null,
|
||||
],
|
||||
'itens' => [],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function store()
|
||||
{
|
||||
self::validate();
|
||||
|
||||
$saida = null;
|
||||
|
||||
DB::transaction(function () use (&$saida) {
|
||||
|
||||
$saida = AlmoxarifadoService::saveSaidaManual(self::getParams());
|
||||
});
|
||||
|
||||
return $saida;
|
||||
}
|
||||
|
||||
public static function edit($id)
|
||||
{
|
||||
$saida = Saida::findOrFail($id);
|
||||
|
||||
return [
|
||||
'additionals' => self::getAdditionalsData(),
|
||||
'form' => self::getFormData($saida),
|
||||
'model' => [
|
||||
'finalizada' => $saida->finalizada,
|
||||
'requisicao' => [
|
||||
'centro_custo_id' => $saida->requisicao->centroCusto->id,
|
||||
'usuario' => [
|
||||
'id' => $saida->requisicao->usuario->id,
|
||||
'cidadao_nome' => $saida->requisicao->usuario->cidadao->nome,
|
||||
],
|
||||
'numero' => $saida->requisicao->numero,
|
||||
'data' => $saida->requisicao->data->format('d/m/Y'),
|
||||
],
|
||||
'itens' => $saida->itens->map(fn ($item) => [
|
||||
'id' => $item->id,
|
||||
'material' => [
|
||||
'id' => $item->material->id,
|
||||
'codigo_material' => $item->material->codigo_material,
|
||||
'descricao_completa' => $item->material->descricao_completa,
|
||||
],
|
||||
'quantidade' => $item->quantidade,
|
||||
'estorno_salvo' => $item->estornado,
|
||||
'estornado' => $item->estornado,
|
||||
'entrada_itens' => $item->entradaItens->map(fn ($entradaItem) => [
|
||||
'entrada_item_id' => $entradaItem->id,
|
||||
'quantidade_saida' => $entradaItem->pivotSaidaItemEntradaItem->quantidade_saida,
|
||||
'lote' => $entradaItem->lote,
|
||||
'validade_lote' => $entradaItem->validade_lote,
|
||||
]),
|
||||
'escolheu_entrada_item_manualmente' => $item->escolheu_entrada_item_manualmente,
|
||||
])
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
private static function getFormData($saida = null)
|
||||
{
|
||||
$centroCustoLogadoId = self::getCurrentCentroCusto()->id;
|
||||
|
||||
return [
|
||||
'requisicao' => [
|
||||
'unidades' => Unidade::orderBy('nome_fantasia')
|
||||
->whereHas('infraestruturas', function ($query) use ($centroCustoLogadoId) {
|
||||
|
||||
$query->whereHas('centrosCusto', function ($query) use ($centroCustoLogadoId) {
|
||||
|
||||
$query->where('id', '<>', $centroCustoLogadoId)
|
||||
->whereDoesntHave('almoxarifadoParametrizacoesControleEstoqueGrupo');
|
||||
});
|
||||
})
|
||||
->get()
|
||||
->map(fn ($unidade) => [
|
||||
'id' => $unidade->id,
|
||||
'nome_fantasia' => $unidade->nome_fantasia,
|
||||
'infraestruturas' => $unidade->infraestruturas()
|
||||
->whereHas('centrosCusto', function ($query) use ($centroCustoLogadoId) {
|
||||
|
||||
$query->where('id', '<>', $centroCustoLogadoId)
|
||||
->whereDoesntHave('almoxarifadoParametrizacoesControleEstoqueGrupo');
|
||||
})
|
||||
->get()
|
||||
->sortBy('nome')
|
||||
->map(fn ($infraestrutura) => [
|
||||
'id' => $infraestrutura->id,
|
||||
'nome' => $infraestrutura->nome,
|
||||
'centros_custo' => $infraestrutura->centrosCusto()
|
||||
->where('id', '<>', $centroCustoLogadoId)
|
||||
->whereDoesntHave('almoxarifadoParametrizacoesControleEstoqueGrupo')
|
||||
->get()
|
||||
->map(fn ($centroCusto) => [
|
||||
'id' => $centroCusto->id,
|
||||
'setor_nome' => $centroCusto->setor->nome,
|
||||
])
|
||||
->sortBy('setor_nome')
|
||||
->values()
|
||||
])
|
||||
->values()
|
||||
]),
|
||||
'unidade_id' => $saida ? $saida->requisicao->centroCusto->infraestrutura->unidade_id : null,
|
||||
'infraestrutura_id' => $saida ? $saida->requisicao->centroCusto->infraestrutura->id : null,
|
||||
'balancete_lastest' => BalanceteFechamento::select('id','mes','ano')->orderBy('id','desc')->first() ?? null,
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
private static function getAdditionalsData()
|
||||
{
|
||||
return [
|
||||
'data_atual' => Carbon::now()->format('d/m/Y'),
|
||||
'is_numero_requisicao_automatico' => ParametrizacaoService::getParametrizacaoRequisicao()
|
||||
['numero_requisicao_automatico'],
|
||||
];
|
||||
}
|
||||
|
||||
public static function update($id)
|
||||
{
|
||||
self::validate();
|
||||
|
||||
$saida = Saida::findOrFail($id);
|
||||
|
||||
DB::transaction(function () use (&$saida) {
|
||||
|
||||
$saida = AlmoxarifadoService::saveSaidaManual(self::getParams(), $saida->id);
|
||||
});
|
||||
|
||||
return $saida;
|
||||
}
|
||||
|
||||
private static function getParams()
|
||||
{
|
||||
return [
|
||||
'finalizada' => request()->finalizada,
|
||||
'requisicao' => [
|
||||
'centro_custo_id' => request()->requisicao['centro_custo_id'],
|
||||
'usuario_id' => request()->requisicao['usuario_id'],
|
||||
'numero' => request()->requisicao['numero'],
|
||||
'data' => Carbon::createFromFormat('d/m/Y', request()->requisicao['data']),
|
||||
],
|
||||
'itens' => collect(request()->itens)->map(fn ($item) => [
|
||||
'id' => $item['id'],
|
||||
'material_id' => $item['material_id'],
|
||||
'quantidade' => (int) $item['quantidade'],
|
||||
'estornado' => $item['estornado'],
|
||||
'entrada_itens' => collect($item['entrada_itens'])->map(fn ($entradaItem) => [
|
||||
'entrada_item_id' => $entradaItem['entrada_item_id'],
|
||||
'quantidade_saida' => (int) $entradaItem['quantidade_saida'],
|
||||
]),
|
||||
'escolheu_entrada_item_manualmente' => $item['escolheu_entrada_item_manualmente'],
|
||||
])
|
||||
];
|
||||
}
|
||||
|
||||
public static function validate()
|
||||
{
|
||||
$rules = [
|
||||
'finalizada' => [
|
||||
'required',
|
||||
'boolean',
|
||||
],
|
||||
'requisicao.centro_custo_id' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::exists(CentroCusto::class, 'id'),
|
||||
],
|
||||
'requisicao.usuario_id' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::exists(Usuario::class, 'id'),
|
||||
],
|
||||
'requisicao.numero' => [
|
||||
'required',
|
||||
'digits_between:1,20',
|
||||
Rule::unique(SaidaRequisicao::class, 'numero')->ignore(request()->route('saida'), 'saida_id'),
|
||||
],
|
||||
'requisicao.data' => [
|
||||
'required',
|
||||
'date_format:d/m/Y',
|
||||
'before_or_equal:now',
|
||||
],
|
||||
'itens' => [
|
||||
'required',
|
||||
'array',
|
||||
],
|
||||
'itens.*.id' => [
|
||||
'nullable',
|
||||
'integer',
|
||||
Rule::exists(SaidaItem::class, 'id'),
|
||||
],
|
||||
'itens.*.material_id' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::exists(Material::class, 'id'),
|
||||
],
|
||||
'itens.*.quantidade' => [
|
||||
'required',
|
||||
'integer',
|
||||
'min:1',
|
||||
],
|
||||
'itens.*.escolheu_entrada_item_manualmente' => [
|
||||
'required',
|
||||
'boolean',
|
||||
],
|
||||
'itens.*.estornado' => [
|
||||
'required',
|
||||
'boolean',
|
||||
],
|
||||
'itens.*.entrada_itens' => [
|
||||
'present',
|
||||
'array',
|
||||
],
|
||||
'itens.*.entrada_itens.*.entrada_item_id' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::exists(EntradaItem::class, 'id'),
|
||||
],
|
||||
'itens.*.entrada_itens.*.quantidade_saida' => [
|
||||
'required',
|
||||
'integer',
|
||||
'min:1',
|
||||
],
|
||||
];
|
||||
|
||||
$messages = [
|
||||
'requisicao.numero.unique' => 'O número da requisição já foi inserido anteriormente.',
|
||||
];
|
||||
|
||||
request()->validate($rules, $messages);
|
||||
}
|
||||
|
||||
public static function destroy($id)
|
||||
{
|
||||
$saida = Saida::findOrFail($id);
|
||||
|
||||
DB::transaction(function () use ($saida) {
|
||||
|
||||
$saida->itens->each(fn ($i) => $i->entradaItens()->detach());
|
||||
$saida->delete();
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user