first(); $controleJornada = ControleJornada::select('tipo_controle')->first(); $exameAmbulatorioAtendimento = ExameAmbulatorioAtendimento::select('exibir')->first(); $integracaoAplicativo = IntegracaoAplicativo::first(); return [ 'form' => [ 'unidades' => [], 'tipos' => TipoCotaPrestador::orderBy('id')->get()->map(fn ($tipo) => [ 'id' => $tipo->id, 'descricao' => $tipo->descricao ]), 'prestadores' => Unidade::whereHas('parametrizacaoExameImagem', function ($query) { $query->where('prestador', true); }) ->orderBy('nome_fantasia') ->get() ->map(fn ($unidade) => [ 'unidade_id' => $unidade->id, 'nome_fantasia' => $unidade->nome_fantasia, 'prestador' => $unidade->parametrizacaoExameImagem->prestador, 'infraestruturas' => Infraestrutura::whereHas('parametrizacaoExameImagem', function ($query) { $query->where('prestador', true); }) ->where('unidade_id', $unidade->id) ->orderBy('nome') ->get() ->map(fn ($p) => [ 'infraestrutura_id' => $p->id, 'infraestrutura_nome' => $p->nome, 'unidade_id' => $p->parametrizacaoExameImagem->unidade_id, 'nome_fantasia' => $p->parametrizacaoExameImagem->unidade->nome_fantasia, 'prestador' => $p->parametrizacaoExameImagem->prestador, ]), ]) ->unique('unidade_id') ->values(), 'meses' => MesCotaPrestador::orderBy('id')->get()->map(fn ($mes) => [ 'id' => $mes->id, 'descricao' => $mes->descricao ]), 'anos' => self::getAno(), 'grupos' => DB::table('cadastro_grupo') ->select( 'cadastro_grupo.id', DB::raw('UPPER(cadastro_grupo.nome) as nome'), ) ->where('grupo_tipo_id', GrupoTipo::EXAME) ->whereExists(fn ($q) => $q ->selectRaw(1) ->from('parametrizacao_exame') ->where('parametrizacao_exame.tipo_id', ExameTipo::IMAGEM) ->whereColumn( 'cadastro_grupo.id', 'parametrizacao_exame.grupo_tipo_id' ) ) ->orderBy('nome') ->get() ->map(fn ($kit) => [ 'id' => $kit->id, 'nome' => $kit->nome, 'checked' => false, 'exames' => DB::table('parametrizacao_exame') ->select( 'parametrizacao_exame.id', DB::raw('UPPER(parametrizacao_exame.nome) as nome'), 'parametrizacao_exame.codigo', ) ->where('parametrizacao_exame.grupo_tipo_id', $kit->id) ->orderBy('parametrizacao_exame.nome') ->get() ->values(), ]) ->values(), ], 'model' => [ 'unidades' => Infraestrutura::whereHas('parametrizacaoExameImagem') ->orderBy('nome') ->get() ->map(fn ($infra) => [ 'id' => $infra->parametrizacaoExameImagem->id, 'checked' => false, 'infraestrutura_id' => $infra->id, 'infraestrutura_nome' => $infra->nome, 'infraestrutura_principal' => $infra->principal, 'unidade_id' => $infra->parametrizacaoExameImagem->unidade_id, 'nome_fantasia' => $infra->parametrizacaoExameImagem->unidade->nome_fantasia, 'executante' => $infra->parametrizacaoExameImagem->executante, 'prestador' => $infra->parametrizacaoExameImagem->prestador, 'envia_sms' => $infra->parametrizacaoExameImagem->envia_sms, 'sms' => [ 'dia_antecedencia' => $infra->parametrizacaoExameImagem->sms->dia_antecedencia ?? null, 'periodo_envio' => [ 'start' => is_null($infra->parametrizacaoExameImagem->sms->envio_de ?? null) ? null : (new Carbon($infra->parametrizacaoExameImagem->sms->envio_de))->format('d/m/Y'), 'end' => is_null($infra->parametrizacaoExameImagem->sms->envio_ate ?? null) ? null : (new Carbon($infra->parametrizacaoExameImagem->sms->envio_ate))->format('d/m/Y'), ], 'exames' => ($infra->parametrizacaoExameImagem->sms->exames ?? collect()) ->map(fn ($exame) => [ 'id' => $exame->id, 'nome' => $exame->nome, 'codigo' => $exame->codigo, ]), ], ]), 'cotas' => DB::table('exame_imagem_parametrizacao_cota_prestador') ->join('cadastro_infraestrutura', 'exame_imagem_parametrizacao_cota_prestador.infraestrutura_id', 'cadastro_infraestrutura.id') ->join('cadastro_unidade', 'cadastro_infraestrutura.unidade_id', 'cadastro_unidade.id') ->whereNull('exame_imagem_parametrizacao_cota_prestador.deleted_at') ->whereYear('exame_imagem_parametrizacao_cota_prestador.inicio', Carbon::now()->year) ->groupBy('cadastro_infraestrutura.id') ->select([ 'cadastro_unidade.id as unidade_id', 'cadastro_unidade.nome_fantasia AS nome_fantasia', 'cadastro_infraestrutura.id as infraestrutura_id', DB::raw('COALESCE(cadastro_infraestrutura.nome, cadastro_unidade.nome_fantasia) AS infraestrutura_nome'), DB::raw('YEAR(inicio) AS ano'), ]) ->get() ->map(function ($query) { return [ 'unidade_id' => $query->unidade_id ?? null, 'nome_fantasia' => $query->nome_fantasia ?? null, 'infraestrutura_id' => $query->infraestrutura_id ?? null, 'infraestrutura_nome' => $query->infraestrutura_nome ?? null, 'cota_solicitante' => CotaPrestador::where('unidade_id', $query->unidade_id) ->where('infraestrutura_id', $query->infraestrutura_id) ->orderBy('inicio') ->get() ->map(fn ($cotas) => [ 'id' => $cotas->id ?? null, 'cota_tipo_id' => $cotas->cota_tipo_id ?? null, 'cota_tipo_nome' => $cotas->cota_tipo_id == Tipo::VALOR ? 'Valor' : 'Quantidade', "periodo" => [ 'start' => (new Carbon($cotas->inicio))->format('d/m/Y') ?? null, 'end' => (new Carbon($cotas->fim))->format('d/m/Y') ?? null, ], 'cota' => $cotas->cota_tipo_id == Tipo::VALOR ? number_format($cotas->cota_valor, 2, ',', '.') : $cotas->cota_unidade, 'saldo' => $cotas->cota_tipo_id == Tipo::VALOR ? number_format($cotas->cota_valor, 2, ',', '.') : $cotas->cota_unidade, 'utilizada' => "0", 'cota_unidade' => $cotas->cota_unidade ?? null, 'cota_valor' => number_format($cotas->cota_valor, 2, ',', '.') ?? null, 'observacao' => $cotas->observacao ?? null, 'prestador' => "true", 'agendamentos' => DB::table('exame_imagem_agendamento') ->where('unidade_id', $query->unidade_id) ->whereBetween('data', [$cotas->inicio, $cotas->fim]) ->exists(), ])->values(), 'valor_utilizado' => self::handleTotalValorUtilizado($query), 'jornadas' => DB::table('exame_imagem_jornada') ->where('unidade_id', $query->unidade_id) ->select([ 'exame_imagem_jornada.controle_jornada_id as controle_jornada_id', 'exame_imagem_jornada.id AS id', 'exame_imagem_jornada.unidade_id AS unidade_id', 'exame_imagem_jornada.prestador_id AS prestador_id', ]) ->groupBy('unidade_id') ->get() ->map(fn ($jornada) => [ 'controle_jornada_id' => $jornada->controle_jornada_id, 'jornada_id' => $jornada->id, 'agendamentos' => Agendamento::where('jornada_id', $jornada->id) ->first() ? true : false, 'agendamento' => DB::table('exame_imagem_agendamento') ->join('exame_imagem_jornada', 'exame_imagem_jornada.id', 'exame_imagem_agendamento.jornada_id') ->where('exame_imagem_agendamento.unidade_id', $jornada->unidade_id) ->select([ 'exame_imagem_agendamento.id as id', 'exame_imagem_jornada.prestador_id AS prestador_id', 'exame_imagem_agendamento.data AS data', ]) ->get() ->map(fn ($agendamento) => [ 'agendamento_id' => $agendamento->id, 'prestador' => $agendamento->prestador_id, 'data' => (new Carbon($agendamento->data))->format('d/m/Y') ?? null, ]) ]), ]; }), 'mensagem_protocolo' => $mensagemProtocolo->mensagem, 'ocupacoes' => Ocupacao::all() ->map(fn ($ocupacao) => [ 'id' => $ocupacao->id, 'ocupacao_id' => $ocupacao->ocupacao_id, 'nome' => $ocupacao->ocupacao->nome, ]), 'supervisores' => Supervisor::all() ->map(fn ($supervisor) => [ 'id' => $supervisor->id, 'usuario_id' => $supervisor->usuario_id, 'nome' => $supervisor->usuario->cidadao->nome, 'cpf' => $supervisor->usuario->cidadao->cpf, ]), 'controle_jornada' => $controleJornada->tipo_controle ?? null, 'exibir_exame_ambulatorio_atendimento' => $exameAmbulatorioAtendimento ? $exameAmbulatorioAtendimento->exibir : false, 'integracao_aplicativo' => [ 'habilita_agendamento_conectasus_cidadao' => $integracaoAplicativo->habilita_agendamento_conectasus_cidadao ?? false, 'habilita_consulta_imagem_conectasus_cidadao' => $integracaoAplicativo->habilita_consulta_imagem_conectasus_cidadao ?? false, ], 'app_conectasus_cidadao_prestadores' => AppConectasusCidadaoPrestador::with('infraestrutura.unidade') ->get() ->map(fn ($item) => [ 'id' => $item->id, 'infraestrutura_id' => $item->infraestrutura_id, 'infraestrutura_nome' => $item->infraestrutura->nome, 'unidade_id' => $item->infraestrutura->unidade_id, 'nome_fantasia' => $item->infraestrutura->unidade->nome_fantasia, 'percentual_financeiro' => $item->percentual_financeiro !== null ? (float) $item->percentual_financeiro : null, 'percentual_quantitativo' => $item->percentual_quantitativo !== null ? (float) $item->percentual_quantitativo : null, ]) ->values(), ], ]; } public static function getCotaPrestador($request) { return DB::table('exame_imagem_parametrizacao_cota_prestador') ->join('cadastro_infraestrutura', 'exame_imagem_parametrizacao_cota_prestador.infraestrutura_id', 'cadastro_infraestrutura.id') ->join('cadastro_unidade', 'cadastro_infraestrutura.unidade_id', 'cadastro_unidade.id') ->whereNull('exame_imagem_parametrizacao_cota_prestador.deleted_at') ->when($request->mes, function ($agendada) use ($request) { $agendada->whereMonth('exame_imagem_parametrizacao_cota_prestador.inicio', $request->mes); }) ->whereYear('exame_imagem_parametrizacao_cota_prestador.inicio', $request->ano) ->groupBy('cadastro_infraestrutura.id') ->select([ 'cadastro_unidade.id as unidade_id', 'cadastro_unidade.nome_fantasia AS nome_fantasia', 'cadastro_infraestrutura.id as infraestrutura_id', DB::raw('COALESCE(cadastro_infraestrutura.nome, cadastro_unidade.nome_fantasia) AS infraestrutura_nome'), DB::raw('YEAR(inicio) AS ano'), ]) ->get() ->map(function ($query) { return [ 'unidade_id' => $query->unidade_id ?? null, 'nome_fantasia' => $query->nome_fantasia ?? null, 'infraestrutura_id' => $query->infraestrutura_id ?? null, 'infraestrutura_nome' => $query->infraestrutura_nome ?? null, 'cota_solicitante' => CotaPrestador::where('unidade_id', $query->unidade_id) ->where('infraestrutura_id', $query->infraestrutura_id) ->orderBy('inicio') ->get() ->map(fn ($cotas) => [ 'id' => $cotas->id ?? null, 'cota_tipo_id' => $cotas->cota_tipo_id ?? null, 'cota_tipo_nome' => $cotas->cota_tipo_id == Tipo::VALOR ? 'Valor' : 'Quantidade', "periodo" => [ 'start' => (new Carbon($cotas->inicio))->format('d/m/Y') ?? null, 'end' => (new Carbon($cotas->fim))->format('d/m/Y') ?? null, ], 'cota' => $cotas->cota_tipo_id == Tipo::VALOR ? number_format($cotas->cota_valor, 2, ',', '.') : $cotas->cota_unidade, 'saldo' => $cotas->cota_tipo_id == Tipo::VALOR ? number_format($cotas->cota_valor, 2, ',', '.') : $cotas->cota_unidade, 'utilizada' => "0", 'cota_unidade' => $cotas->cota_unidade ?? null, 'cota_valor' => number_format($cotas->cota_valor, 2, ',', '.') ?? null, 'observacao' => $cotas->observacao ?? null, 'prestador' => "true", ])->values(), 'valor_utilizado' => self::handleTotalValorUtilizado($query), 'jornadas' => DB::table('exame_imagem_jornada') ->where('unidade_id', $query->unidade_id) ->select([ 'exame_imagem_jornada.controle_jornada_id as controle_jornada_id', 'exame_imagem_jornada.id AS id', 'exame_imagem_jornada.unidade_id AS unidade_id', 'exame_imagem_jornada.prestador_id AS prestador_id', ]) ->groupBy('unidade_id') ->get() ->map(fn ($jornada) => [ 'controle_jornada_id' => $jornada->controle_jornada_id, 'jornada_id' => $jornada->id, 'agendamentos' => Agendamento::where('jornada_id', $jornada->id) ->first() ? true : false, 'agendamento' => Agendamento::where('unidade_id', $jornada->unidade_id) ->get() ->map(fn ($agendamento) => [ 'agendamento_id' => $agendamento->id, 'prestador' => $agendamento->jornada->prestador_id, 'data' => (new Carbon($agendamento->data))->format('d/m/Y') ?? null, ]) ]), ]; }); } private static function handleTotalValorUtilizado($query) { $exameImagem = DB::table('exame_imagem_agendamento_exame') ->join('exame_imagem_agendamento', 'exame_imagem_agendamento.id', '=', 'exame_imagem_agendamento_exame.agendamento_id') ->join('parametrizacao_exame', 'parametrizacao_exame.id', '=', 'exame_imagem_agendamento_exame.exame_id') ->whereYear('exame_imagem_agendamento.data', $query->ano) ->when(request()->mes, function ($agendada) { $agendada->whereMonth('exame_imagem_agendamento.data', request()->mes); }) ->when($query->infraestrutura_id, function ($agendada) use ($query) { $agendada->where('exame_imagem_agendamento.infraestrutura_id', $query->infraestrutura_id); }) ->whereIn('exame_imagem_agendamento_exame.status_id', [AgendamentoStatus::REALIZADO, AgendamentoStatus::AGENDADO]) ->selectRaw('SUM(parametrizacao_exame.valor) AS valor') ->value('valor'); $total = floatval($exameImagem ?? 0); return number_format($total, 2, ',', '.'); } public static function store(Request $request) { DB::transaction(function () use ($request) { self::validate($request); self::saveUnidade($request); self::saveCotaPrestador($request); self::saveMensagemProtocolo($request); self::saveOcupacao($request); self::saveSupervisores($request); self::saveControleJornadas($request); self::saveExameAmbulatorioAtendimento($request); self::saveIntegracaoAplicativo($request); self::saveAppConectasusCidadaoPrestador($request); }); } public static function getUnidades() { return Unidade::orderBy('nome_fantasia') ->get() ->map(function ($query) { return [ 'id' => $query->id, 'nome_fantasia' => $query->nome_fantasia, 'infraestruturas' => $query->infraestruturas->sortBy('nome')->map(fn ($infraestrutura) => [ 'id' => $infraestrutura->id, 'nome' => $infraestrutura->nome, 'principal' => $infraestrutura->principal, ])->values() ]; }); } private static function saveUnidade($request) { $ids = []; foreach ($request->unidades as $params) { $tipo = Parametrizacao::where('unidade_id', $params['unidade_id']) ->where('infraestrutura_id', $params['infraestrutura_id']) ->first() ?? new Parametrizacao(); $tipo->fill($params); $tipo->save(); $ids[] = $tipo->id; self::saveUnidadeSms($tipo, $params); } Parametrizacao::destroy(Parametrizacao::whereNotIn('id', $ids)->pluck('id')); } private static function saveUnidadeSms($parametrizacao, $parametrizacaoData) { if (is_null($parametrizacaoData['sms']['dia_antecedencia'])) { if (!is_null($parametrizacao->sms)) { $parametrizacao->sms->delete(); } } else { $smsData = [ 'dia_antecedencia' => $parametrizacaoData['sms']['dia_antecedencia'], 'envio_de' => is_null($parametrizacaoData['sms']['envio_de']) ? null : Carbon::createFromFormat('d/m/Y', $parametrizacaoData['sms']['envio_de']) ->format('Y-m-d'), 'envio_ate' => is_null($parametrizacaoData['sms']['envio_ate']) ? null : Carbon::createFromFormat('d/m/Y', $parametrizacaoData['sms']['envio_ate']) ->format('Y-m-d'), ]; $sms = $parametrizacao->sms; if (is_null($sms)) { $sms = $parametrizacao->sms()->create($smsData); } else { $sms->update($smsData); } $sms->exames()->sync($parametrizacaoData['sms']['exames']); } } private static function saveCotaPrestador($request) { $ids = collect([]); foreach ($request->cota_solicitante as $params) { $cotas = collect($params['cota_solicitante']); $novosIds = $cotas->filter(fn ($item) => isset($item['id']) && $item['id'] !== null)->pluck('id'); $ids = $ids->merge($novosIds)->unique(); foreach ($params['cota_solicitante'] as $param_unidade) { $id = $param_unidade['id']; $inicio = $param_unidade['periodo']['start']; $fim = $param_unidade['periodo']['end']; $tipo = $id && is_numeric($id) ? CotaPrestador::where('id', $id)->first() : new CotaPrestador(); $tipo->fill($param_unidade); $tipo->inicio = Carbon::createFromFormat('d/m/Y', $inicio); $tipo->fim = Carbon::createFromFormat('d/m/Y', $fim); $tipo->cota_valor = $param_unidade['cota_valor']; if (!is_null($param_unidade['cota_valor'])) { $tipo->cota_valor = str_replace('.', '', $tipo->cota_valor); $tipo->cota_valor = str_replace(',', '.', $tipo->cota_valor); } $tipo->save(); $ids->add($tipo->id); } } CotaPrestador::destroy(CotaPrestador::whereNotIn('id', $ids)->pluck('id')); } private static function saveMensagemProtocolo($request) { $msg = MensagemProtocolo::first() ?? new MensagemProtocolo(); $msg->mensagem = $request->mensagem_protocolo; $msg->save(); } private static function saveOcupacao($request) { $ids = []; foreach ($request->ocupacoes as $params) { $ocupacao = Ocupacao::where('ocupacao_id', $params['ocupacao_id']) ->first() ?? new Ocupacao(); $ocupacao->fill($params); $ocupacao->save(); $ids[] = $ocupacao->id; } Ocupacao::destroy(Ocupacao::whereNotIn('id', $ids)->pluck('id')); } private static function saveSupervisores($request) { $ids = []; foreach($request->supervisores as $params) { $supervisor = Supervisor::where('usuario_id', $params['usuario_id']) -> first() ?? new Supervisor(); $supervisor->fill($params); $supervisor->save(); $ids[] = $supervisor->id; } Supervisor::destroy(Supervisor::whereNotIn('id', $ids)->pluck('id')); } private static function saveControleJornadas($request) { $controle = ControleJornada::first() ?? new ControleJornada(); $controle->tipo_controle = $request->controle_jornada; $controle->save(); } private static function saveExameAmbulatorioAtendimento($request) { $impressao = ExameAmbulatorioAtendimento::first() ?? new ExameAmbulatorioAtendimento(); $impressao->exibir = $request->exibir_exame_ambulatorio_atendimento ?? false; $impressao->save(); } private static function saveIntegracaoAplicativo($request) { $integracao = IntegracaoAplicativo::first() ?? new IntegracaoAplicativo(); $integracao->habilita_agendamento_conectasus_cidadao = $request->input('integracao_aplicativo.habilita_agendamento_conectasus_cidadao') ?? false; $integracao->habilita_consulta_imagem_conectasus_cidadao = $request->input('integracao_aplicativo.habilita_consulta_imagem_conectasus_cidadao') ?? false; $integracao->save(); } private static function saveAppConectasusCidadaoPrestador($request) { $ids = []; foreach ($request->input('app_conectasus_cidadao_prestadores', []) as $params) { $item = AppConectasusCidadaoPrestador::where('infraestrutura_id', $params['infraestrutura_id'])->first() ?? new AppConectasusCidadaoPrestador(); $item->infraestrutura_id = $params['infraestrutura_id']; $item->percentual_financeiro = $params['percentual_financeiro'] ?? null; $item->percentual_quantitativo = $params['percentual_quantitativo'] ?? null; $item->save(); $ids[] = $item->id; } AppConectasusCidadaoPrestador::whereNotIn('id', $ids)->delete(); } private static function getAno() { $data = Carbon::now(); $anos = []; for ($i = -5; $i <= 5; $i++) { $anos[] = $data->copy()->addYears($i)->format('Y'); } return $anos; } private static function validate($request) { $validations = [ 'unidade_id' => [ 'integer', 'exists:cadastro_unidade,id', ], 'cotas.*.unidade_id' => [ 'integer', 'exists:cadastro_unidade,id', ], 'cota_tipo' => [ 'integer', ], 'cotas.*.cota_valor' => [ 'nullable', ], 'cota_unidade' => [ 'nullable', ], 'observacao' => [ 'max:500', ], 'mensagem_protocolo' => [ 'required', 'string', 'max:500', 'between:3,500', ], 'controle_jornada' => [ 'required', ], 'integracao_aplicativo.habilita_agendamento_conectasus_cidadao' => [ 'nullable', 'boolean', ], 'integracao_aplicativo.habilita_consulta_imagem_conectasus_cidadao' => [ 'nullable', 'boolean', ], 'app_conectasus_cidadao_prestadores.*.infraestrutura_id' => [ 'required', 'integer', 'exists:cadastro_infraestrutura,id', ], 'app_conectasus_cidadao_prestadores.*.percentual_financeiro' => [ 'nullable', 'numeric', 'min:0', 'max:100', ], 'app_conectasus_cidadao_prestadores.*.percentual_quantitativo' => [ 'nullable', 'numeric', 'min:0', 'max:100', ], ]; $messages = [ 'unidade_id.unique' => 'Unidade já parametrizada.', 'cotas.*.unidade_id.unique' => 'Unidade, mês, ano e/ou tipo já parametrizado.', 'mensagem_protocolo' => 'Mensagem é obrigatória.', 'controle_jornada' => 'Controle de jornada é obrigatória.', ]; return $request->validate($validations, $messages); } }