$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); } }