init commit
All checks were successful
build-api-image / build (push) Successful in 51s

This commit is contained in:
Antonio Lopes dos Santos
2026-08-04 16:52:02 -03:00
commit afec302c3e
11594 changed files with 1636728 additions and 0 deletions

View File

@@ -0,0 +1,702 @@
<?php
namespace App\Services\Almoxarifado;
use App\Enums\Cadastro\Grupo\GrupoTipo;
use App\Models\Almoxarifado\ParametrizacaoControleEstoqueGrupo;
use App\Models\Almoxarifado\ParametrizacaoDispensacaoMateriais;
use App\Models\Almoxarifado\ParametrizacaoDispensacaoUnidade;
use App\Models\Almoxarifado\ParametrizacaoEstoque;
use App\Models\Almoxarifado\ParametrizacaoRequisicao;
use App\Models\Almoxarifado\RequisicaoPermissao;
use App\Models\Almoxarifado\ParametrizacaoPortalDivulgacaoGrupo;
use App\Models\Cadastro\Estabelecimento\CentroCusto;
use App\Models\Cadastro\Estabelecimento\Infraestrutura;
use App\Models\Cadastro\Estabelecimento\Unidade;
use App\Models\Cadastro\Grupo\Grupo;
use App\Models\Cadastro\Material\Material;
use App\Models\Cadastro\Subgrupo\Subgrupo;
use App\Services\Service;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
class ParametrizacaoService extends Service
{
public static function getParametrizacaoRequisicao()
{
$parametrizacaoRequisicao = ParametrizacaoRequisicao::first();
return [
'numero_requisicao_automatico' => $parametrizacaoRequisicao
->numero_requisicao_automatico ?? false,
'permite_requisitar_materiais_sem_estoque' => $parametrizacaoRequisicao
->permite_requisitar_materiais_sem_estoque ?? false,
'prazo_validade' => $parametrizacaoRequisicao->prazo_validade
];
}
public static function getNovoNumeroRequisicao()
{
return Carbon::now()->format('ymdHis');
}
public static function controlaEstoque($materialId, $centroCustoId = null)
{
$material = Material::findOrFail($materialId);
if (is_null($centroCustoId)) {
$centroCustoId = self::getCurrentCentroCusto()->id;
}
return ParametrizacaoControleEstoqueGrupo::where('centro_custo_id', $centroCustoId)
->where('grupo_id', $material->grupo_id)
->when($material->subgrupo_id, function ($query, $subgrupoId) {
$query->whereHas('subgrupos', fn ($query) => $query->where('subgrupo_id', $subgrupoId));
})
->exists();
}
public static function list()
{
switch (request()->origem) {
case 'portal-divulgacao': {
switch (request()->listar) {
case 'infraestruturas': {
return Infraestrutura::setEagerLoads([])
->where('unidade_id', request()->unidade_id)
->whereHas('centrosCusto')
->get(['id', 'nome', 'principal', 'unidade_id'])
->map(fn ($infraestrutura) => [
'id' => $infraestrutura->id,
'nome' => $infraestrutura->nome
])
->sortBy('nome')
->values();
}
case 'centros-custo': {
return CentroCusto::where('infraestrutura_id', request()->infraestrutura_id)
->get(['id', 'setor_id'])
->map(fn ($centroCusto) => [
'id' => $centroCusto->id,
'setor_nome' => $centroCusto->setor->nome
])
->sortBy('setor_nome')
->values();
}
case 'grupos': {
return Grupo::whereIn('grupo_tipo_id', [GrupoTipo::MEDICAMENTO, GrupoTipo::MATERIAL])->get(['id', 'nome'])->map(function ($grupo) {
$parametrizacao = $grupo->almoxarifadoParametrizacoesPortalDivulgacaoGrupo()
->where('centro_custo_id', request()->centro_custo_id)
->first();
$permiteControlar = false;
if (!is_null($parametrizacao)) {
$permiteControlar = true;
}
return [
'id' => $grupo->id,
'centro_custo_id' => request()->centro_custo_id,
'nome' => $grupo->nome,
'permite_controlar' => $permiteControlar,
'subgrupos' => $grupo->subgrupos()
->whereHas('materiais', fn ($q) => $q->where('is_ativo', true))
->get(['id', 'nome'])->map(function ($subgrupo) {
$parametrizacao = $subgrupo->almoxarifadoParametrizacoesPortalDivulgacaoSubgrupo()
->whereHas('parametrizacaoPortalDivulgacaoGrupo', fn ($q) => $q
->where('centro_custo_id', request()->centro_custo_id)
)
->first();
$permiteControlar = false;
if (!is_null($parametrizacao)) {
$permiteControlar = true;
}
return [
'id' => $subgrupo->id,
'nome' => $subgrupo->nome,
'permite_controlar' => $permiteControlar,
];
}),
];
});
}
case 'item-grupos': {
$grupo = Grupo::where('id', request()->grupo_id)
->first(['id', 'nome']);
$parametrizacao = $grupo->almoxarifadoParametrizacoesPortalDivulgacaoGrupo()
->where('centro_custo_id', request()->centro_custo_id)
->first();
return [
'id' => $grupo->id,
'nome' => $grupo->nome,
'permite_controlar' => !is_null($parametrizacao),
'materiais' => $grupo->materiais()
->where('is_ativo', true)
->when(
request()->filled('subgrupo_ids'),
fn ($query) => $query->whereIn('subgrupo_id', request()->subgrupo_ids)
)
->get(['id', 'descricao as nome'])
->map(function ($material) use ($parametrizacao){
if (!is_null($parametrizacao)) {
$permiteControlar = $material->parametrizacaoPortalDivulgacaoMaterialgrupo()
->where('parametrizacao_portal_divulgacao_grupo_id', $parametrizacao->id)
->exists();
}
else {
$permiteControlar = !request()->filled('subgrupo_ids');
}
return [
'id' => $material->id,
'nome' => $material->nome,
'permite_controlar' => $permiteControlar
];
})
->values()
->toArray(),
];
}
}
}
case 'controle-estoque': {
switch (request()->listar) {
case 'infraestruturas': {
return Infraestrutura::setEagerLoads([])
->where('unidade_id', request()->unidade_id)
->whereHas('centrosCusto')
->get(['id', 'nome', 'principal', 'unidade_id'])
->map(fn ($infraestrutura) => [
'id' => $infraestrutura->id,
'nome' => $infraestrutura->nome
])
->sortBy('nome')
->values();
}
case 'centros-custo': {
return CentroCusto::where('infraestrutura_id', request()->infraestrutura_id)
->get(['id', 'setor_id'])
->map(fn ($centroCusto) => [
'id' => $centroCusto->id,
'setor_nome' => $centroCusto->setor->nome
])
->sortBy('setor_nome')
->values();
}
case 'grupos': {
return Grupo::get(['id', 'nome'])->map(function ($grupo) {
$parametrizacao = $grupo->almoxarifadoParametrizacoesControleEstoqueGrupo()
->where('centro_custo_id', request()->centro_custo_id)
->first();
$permiteControlar = false;
$hasPermissaoRequisicao = false;
if (!is_null($parametrizacao)) {
$permiteControlar = true;
$hasPermissaoRequisicao = RequisicaoPermissao::where(
'created_centro_custo_id',
request()->centro_custo_id
)
->whereHas('material', fn ($q) => $q->where('grupo_id', $grupo->id))
->exists();
}
return [
'id' => $grupo->id,
'nome' => $grupo->nome,
'permite_controlar' => $permiteControlar,
'has_permissao_requisicao' => $hasPermissaoRequisicao,
'subgrupos' => $grupo->subgrupos()->get(['id', 'nome'])->map(function ($subgrupo) {
$parametrizacao = $subgrupo->almoxarifadoParametrizacoesControleEstoqueSubgrupo()
->whereHas('parametrizacaoControleEstoqueGrupo', fn ($q) => $q
->where('centro_custo_id', request()->centro_custo_id)
)
->first();
$permiteControlar = false;
$hasPermissaoRequisicao = false;
if (!is_null($parametrizacao)) {
$permiteControlar = true;
$hasPermissaoRequisicao = RequisicaoPermissao::where(
'created_centro_custo_id',
request()->centro_custo_id
)
->whereHas('material', fn ($q) => $q->where('subgrupo_id', $subgrupo->id))
->exists();
}
return [
'id' => $subgrupo->id,
'nome' => $subgrupo->nome,
'permite_controlar' => $permiteControlar,
'has_permissao_requisicao' => $hasPermissaoRequisicao,
];
}),
];
});
}
}
}
case 'estoque-minimo-maximo': {
switch (request()->listar) {
case 'infraestruturas': {
return Infraestrutura::setEagerLoads([])
->where('unidade_id', request()->unidade_id)
->whereHas('centrosCusto', fn ($q) => $q
->whereHas('almoxarifadoParametrizacoesControleEstoqueGrupo')
)
->get(['id', 'nome', 'principal', 'unidade_id'])
->map(fn ($infraestrutura) => [
'id' => $infraestrutura->id,
'nome' => $infraestrutura->nome
])
->sortBy('nome')
->values();
}
case 'centros-custo': {
return CentroCusto::whereHas('almoxarifadoParametrizacoesControleEstoqueGrupo')
->where('infraestrutura_id', request()->infraestrutura_id)
->get(['id', 'setor_id'])
->map(fn ($centroCusto) => [
'id' => $centroCusto->id,
'setor_nome' => $centroCusto->setor->nome
])
->sortBy('setor_nome')
->values();
}
case 'grupos': {
return Grupo::whereHas(
'almoxarifadoParametrizacoesControleEstoqueGrupo',
fn ($query) => $query->where('centro_custo_id', request()->centro_custo_id)
)
->get()
->map(fn ($grupo) => [
'id' => $grupo->id,
'nome' => $grupo->nome,
'materiais' => $grupo->materiais()
->where('is_ativo', true)
->where(fn ($query) => $query
->whereNull('subgrupo_id')
->orWhereHas('subgrupo', fn ($query) => $query
->whereHas(
'almoxarifadoParametrizacoesControleEstoqueSubgrupo',
fn ($query) => $query->whereHas(
'parametrizacaoControleEstoqueGrupo',
fn ($query) => $query
->where('centro_custo_id', request()->centro_custo_id)
)
)
)
)
->get()
->map(function ($material) {
$parametrizacao = ParametrizacaoEstoque::where(
'centro_custo_id',
request()->centro_custo_id
)
->where('material_id', $material->id)
->first();
return [
'id' => $material->id,
'codigo' => $material->codigo_material,
'descricao' => $material->descricao_completa,
'subgrupo_id' => $material->subgrupo_id,
'subgrupo_nome' => $material->subgrupo->nome ?? null,
'estoque_minimo' => $parametrizacao->estoque_minimo ?? null,
'estoque_maximo' => $parametrizacao->estoque_maximo ?? null,
];
}),
]);
}
}
}
}
}
public static function create()
{
$parametrizacaoRequisicao = ParametrizacaoRequisicao::first();
return [
'requisicao' => [
'model' => [
'numero_requisicao_automatico' => $parametrizacaoRequisicao
->numero_requisicao_automatico ?? false,
'permite_requisitar_materiais_sem_estoque' => $parametrizacaoRequisicao
->permite_requisitar_materiais_sem_estoque ?? false,
'prazo_validade' => $parametrizacaoRequisicao->prazo_validade ?? null,
'motivo_obrigatorio' => $parametrizacaoRequisicao->motivo_obrigatorio ?? false,
],
],
'controle_estoque' => [
'form' => [
'unidades' => Unidade::whereHas('infraestruturas', fn ($q) => $q->whereHas('centrosCusto'))
->orderBy('nome_fantasia')
->get(['id', 'nome_fantasia']),
'infraestruturas' => [],
'centrosCusto' => [],
],
'model' => [
'centros_custo' => CentroCusto::whereHas('almoxarifadoParametrizacoesControleEstoqueGrupo')
->get()
->map(fn ($centroCusto) => [
'id' => $centroCusto->id,
'setor_nome' => $centroCusto->setor->nome,
'local_atendimento_nome' => $centroCusto->infraestrutura->nome,
'unidade_nome_fantasia' => $centroCusto->infraestrutura->unidade->nome_fantasia,
'grupos' => [],
'is_saved' => true,
])
]
],
'portal_divulgacao' => [
'form' => [
'unidades' => Unidade::whereHas('infraestruturas', fn ($q) => $q->whereHas('centrosCusto'))
->orderBy('nome_fantasia')
->get(['id', 'nome_fantasia']),
'infraestruturas' => [],
'centrosCusto' => [],
],
'model' => [
'portal_centros_custo' => CentroCusto::whereHas('almoxarifadoParametrizacoesPortalDivulgacaoGrupo')
->get()
->map(fn ($centroCusto) => [
'id' => $centroCusto->id,
'setor_nome' => $centroCusto->setor->nome,
'local_atendimento_nome' => $centroCusto->infraestrutura->nome,
'unidade_nome_fantasia' => $centroCusto->infraestrutura->unidade->nome_fantasia,
'grupos' => [],
'is_saved' => true,
])
]
],
'dispensacao_materiais' => [
'form' => [
'unidades' => Unidade::whereHas('infraestruturas', fn ($q) => $q->whereHas('centrosCusto'))
->orderBy('nome_fantasia')
->get(['id', 'nome_fantasia']),
'infraestruturas' => [],
'centrosCusto' => [],
],
'model' => [
'centros_custo' => CentroCusto::has('almoxarifadoParametrizacaoDispensacaoUnidades')
->get()->map(fn($centroCusto) => [
'id' => $centroCusto->id,
'setor_nome' => $centroCusto->setor->nome,
'local_atendimento_nome' => $centroCusto->infraestrutura->nome,
'unidade_nome_fantasia' => $centroCusto->infraestrutura->unidade->nome_fantasia,
]
),
'grupos' => Grupo::with('materiais')->where('grupo_tipo_id', GrupoTipo::MATERIAL)->get()->map(fn($grupo) => [
'id' => $grupo->id,
'dispensar' => $grupo->almoxarifadoParametrizacoesDispensarMateriais->isNotEmpty(),
'nome' => $grupo->nome,
'materiais' => $grupo->materiais->map(fn($material) => [
'id' => $material->id,
'descricao' => $material->descricao,
'grupo_id' => $material->grupo_id,
'dispensar' => $material->almoxarifadoParametrizacaoDispensacao->isNotEmpty() || $material->grupo->almoxarifadoParametrizacoesDispensarMateriais->isNotEmpty()
])
]),
]
],
'estoque' => [
'form' => [
'unidades' => Unidade::whereHas('infraestruturas', fn ($q) => $q->whereHas(
'centrosCusto',
fn ($q) => $q->whereHas('almoxarifadoParametrizacoesControleEstoqueGrupo')
))
->orderBy('nome_fantasia')
->get(['id', 'nome_fantasia']),
'infraestruturas' => [],
'centrosCusto' => [],
],
'model' => [
'centros_custo' => CentroCusto::whereHas('almoxarifadoParametrizacoesEstoque')
->get()
->map(fn ($centroCusto) => [
'id' => $centroCusto->id,
'setor_nome' => $centroCusto->setor->nome,
'local_atendimento_nome' => $centroCusto->infraestrutura->nome,
'unidade_nome_fantasia' => $centroCusto->infraestrutura->unidade->nome_fantasia,
'grupos' => [],
'is_saved' => true,
])
],
],
];
}
public static function store()
{
self::validate();
DB::transaction(function () {
self::saveParametrizacaoRequisicao(request()->requisicao);
self::saveParametrizacaoControleEstoque(request()->controle_estoque);
self::saveParametrizacaoDispensacaoMateriais(request()->dispensacao_materiais);
self::saveParametrizacaoEstoque(request()->estoque);
self::saveParametrizacaoPortalDivulgacao(request()->portal_divulgacao);
});
}
private static function saveParametrizacaoRequisicao($data)
{
ParametrizacaoRequisicao::updateOrCreate(
['id' => ParametrizacaoRequisicao::first()->id ?? null],
$data
);
}
private static function saveParametrizacaoControleEstoque($data)
{
collect($data['centros_custo'])->each(function ($centroCustoData) {
$centroCusto = CentroCusto::findOrFail($centroCustoData['id']);
$centroCusto->almoxarifadoParametrizacoesControleEstoqueGrupo()
->whereNotIn('grupo_id', collect($centroCustoData['grupos'])->pluck('id'))
->delete();
foreach ($centroCustoData['grupos'] as $grupo) {
$parametrizacaoGrupo = $centroCusto->almoxarifadoParametrizacoesControleEstoqueGrupo()
->updateOrCreate([
'centro_custo_id' => $centroCusto->id,
'grupo_id' => $grupo['id'],
]);
$parametrizacaoGrupo->subgrupos()
->whereNotIn('subgrupo_id', $grupo['subgrupos'])
->delete();
$parametrizacaoGrupo->subgrupos()
->createMany(collect($grupo['subgrupos'])->map(fn ($sg) => ['subgrupo_id' => $sg]));
}
});
}
private static function saveParametrizacaoPortalDivulgacao($data)
{
collect($data['portal_centros_custo'])->each(function ($centroCustoData) {
$centroCusto = CentroCusto::findOrFail($centroCustoData['id']);
$centroCusto->almoxarifadoParametrizacoesPortalDivulgacaoGrupo()
->whereNotIn('grupo_id', collect($centroCustoData['grupos'])->pluck('id'))
->delete();
foreach ($centroCustoData['grupos'] as $grupo) {
$parametrizacaoGrupo = $centroCusto->almoxarifadoParametrizacoesPortalDivulgacaoGrupo()
->updateOrCreate([
'centro_custo_id' => $centroCusto->id,
'grupo_id' => $grupo['id'],
]);
$materiaisIds = collect($grupo['materiais'])
->map(fn($sg) => is_array($sg) ? $sg['id'] ?? null : $sg)
->filter()
->unique()
->toArray();
if (!empty($materiaisIds)) {
$parametrizacaoGrupo->material()
->whereNotIn('material_id', $materiaisIds)
->delete();
}
foreach ($materiaisIds as $materialId) {
$parametrizacaoGrupo->material()->firstOrCreate([
'material_id' => $materialId
]);
}
$subgrupoIds = collect($grupo['subgrupos'])
->map(fn($sg) => is_array($sg) ? $sg['id'] ?? null : $sg)
->filter()
->unique()
->toArray();
$parametrizacaoGrupo->subgrupos()
->whereNotIn('subgrupo_id', $subgrupoIds)
->delete();
foreach ($subgrupoIds as $subgrupoId) {
$parametrizacaoGrupo->subgrupos()->firstOrCreate([
'subgrupo_id' => $subgrupoId
]);
}
}
});
}
private static function saveParametrizacaoDispensacaoMateriais($data)
{
ParametrizacaoDispensacaoUnidade::truncate();
collect($data['centros_custo'])->each(function($centroCusto) {
ParametrizacaoDispensacaoUnidade::create(
['centro_custo_id' => $centroCusto['id']]
);
});
ParametrizacaoDispensacaoMateriais::truncate();
collect($data['grupos'])->each(function($grupo) {
if($grupo['dispensar']) {
ParametrizacaoDispensacaoMateriais::create([
'grupo_id' => $grupo['id']
]);
} else {
collect($grupo['materiais'])->each(function($material) {
if($material['dispensar']) {
ParametrizacaoDispensacaoMateriais::create([
'material_id' => $material['id']
]);
}
});
}
});
}
private static function saveParametrizacaoEstoque($data)
{
$centrosCusto = collect($data['centros_custo']);
$centrosCusto->each(function ($centroCustoData) {
foreach ($centroCustoData['materiais'] as $material) {
if (!is_null($material['estoque_minimo']) || !is_null($material['estoque_maximo'])) {
ParametrizacaoEstoque::updateOrCreate(
[
'centro_custo_id' => $centroCustoData['id'],
'material_id' => $material['id'],
],
[
'estoque_minimo' => $material['estoque_minimo'],
'estoque_maximo' => $material['estoque_maximo'],
]
);
}
else {
ParametrizacaoEstoque::where('centro_custo_id', $centroCustoData['id'])
->where('material_id', $material['id'])
->delete();
}
}
});
}
public static function validate()
{
$rules = [
'requisicao.numero_requisicao_automatico' => [
'required',
'boolean'
],
'requisicao.permite_requisitar_materiais_sem_estoque' => [
'required',
'boolean'
],
'controle_estoque.centros_custo' => [
'present',
'array',
],
'controle_estoque.centros_custo.*.id' => [
'required',
'integer',
Rule::exists(CentroCusto::class, 'id'),
],
'controle_estoque.centros_custo.*.grupos' => [
'array',
],
'controle_estoque.centros_custo.*.grupos.*.id' => [
'integer',
Rule::exists(Grupo::class, 'id'),
],
'controle_estoque.centros_custo.*.grupos.*.subgrupos' => [
'array',
],
'controle_estoque.centros_custo.*.grupos.*.subgrupos.*' => [
'integer',
Rule::exists(Subgrupo::class, 'id'),
],
'estoque.centros_custo' => [
'present',
'array',
],
'estoque.centros_custo.*.id' => [
'required',
'integer',
Rule::exists(CentroCusto::class, 'id'),
],
'estoque.centros_custo.*.materiais' => [
'array',
],
'estoque.centros_custo.*.materiais.*.id' => [
'integer',
Rule::exists(Material::class, 'id'),
],
'estoque.centros_custo.*.materiais.*.estoque_minimo' => [
'nullable',
'integer',
],
'estoque.centros_custo.*.materiais.*.estoque_maximo' => [
'nullable',
'integer',
],
];
$messages = [];
request()->validate($rules, $messages);
}
}