join( 'cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id' ) ->whereNull('cadastro_usuario.deleted_at') ->select(DB::raw(" cadastro_usuario.id, cadastro_cidadao.nome, DATE_FORMAT(cadastro_cidadao.data_nascimento, '%d/%m/%Y') as data_nascimento, CONCAT( SUBSTR(cadastro_cidadao.cpf,1,3), '.', SUBSTR(cadastro_cidadao.cpf,4,3), '.', SUBSTR(cadastro_cidadao.cpf,7,3), '-', SUBSTR(cadastro_cidadao.cpf,10,2) ) AS cpf, cadastro_cidadao.cns ")); return datatables() ->of($usuarios) ->filterColumn('cadastro_cidadao.data_nascimento', function ($query, $keyword) { $query->whereRaw("DATE_FORMAT(cadastro_cidadao.data_nascimento, '%d/%m/%Y') LIKE ?", ["%{$keyword}%"]) ->orWhereRaw( "CONCAT( SUBSTR(cadastro_cidadao.data_nascimento,9,2), SUBSTR(cadastro_cidadao.data_nascimento,6,2), SUBSTR(cadastro_cidadao.data_nascimento,1,4) ) like ?", ["%{$keyword}%"] ); }) ->filterColumn('cadastro_cidadao.cpf', function ($query, $keyword) { $query->whereRaw("cadastro_cidadao.cpf LIKE ?", ["%{$keyword}%"]) ->orWhereRaw( "CONCAT( SUBSTR(cadastro_cidadao.cpf,1,3), '.', SUBSTR(cadastro_cidadao.cpf,4,3), '.', SUBSTR(cadastro_cidadao.cpf,7,3), '-', SUBSTR(cadastro_cidadao.cpf,10,2) ) LIKE ?", ["%{$keyword}%"] ); }) ->skipTotalRecords() ->toJson(); } public static function edit($usuarioId) { $usuario = Usuario::findOrFail($usuarioId); return [ 'form' => self::getFormData($usuario), 'model' => self::getModelData(), ]; } private static function getFormData($usuario) { return [ 'usuario' => self::getUsuarioData($usuario), 'origem' => [ 'feriados' => self::getFeriados(), 'unidades' => self::getOrigemUnidades((object) ['usuario_id' => $usuario->id]), 'infraestruturas' => [], 'ocupacoes' => [], 'especialidades' => [], 'datas' => [], 'agendamentos' => [], ], 'destino' => [ 'unidades' => [], 'infraestruturas' => [], 'ocupacoes' => [], 'especialidades' => [], 'usuarios' => [], 'jornadas' => [], ] ]; } private static function getUsuarioData($usuario) { $cidadao = $usuario->cidadao()->setEagerLoads([])->first(['nome', 'data_nascimento', 'cns', 'cpf']); return [ 'nome' => $cidadao->nome, 'data_nascimento' => is_null($cidadao->data_nascimento) ? null : (new Carbon($cidadao->data_nascimento))->format('d/m/Y'), 'cns' => MaskUtil::getCnsMasked($cidadao->cns), 'cpf' => MaskUtil::getCpfMasked($cidadao->cpf), ]; } private static function getModelData() { return [ 'origem' => [ 'unidade_id' => null, 'infraestrutura_id' => null, 'ocupacao_id' => null, 'especialidade_id' => null, 'data' => null, ], 'destino' => [ 'unidade_id' => null, 'infraestrutura_id' => null, 'ocupacao_id' => null, 'especialidade_id' => null, 'usuario_id' => null, 'agendamentos' => [], 'jornada_id' => null, 'motivo_agendamento_excedente' => null, ], 'cancelamento' => [ 'agendamentos' => [], 'motivo' => null, ] ]; } public static function list() { $params = (object) request()->all(); switch (request()->origem) { case 'origem': { return self::getListOrigemData($params); } case 'destino': { return self::getListDestinoData($params); } } } private static function getListOrigemData($params) { switch (request()->listar) { case 'infraestruturas': { return [ 'infraestruturas' => self::getOrigemInfraestruturas($params), 'ocupacoes' => [], 'especialidades' => [], 'datas' => [], 'agendamentos' => [], ]; } case 'ocupacoes': { return [ 'ocupacoes' => self::getOrigemOcupacoes($params), 'especialidades' => [], 'datas' => [], 'agendamentos' => [], ]; } case 'especialidades': { return [ 'especialidades' => self::getOrigemEspecialidades($params), 'datas' => [], 'agendamentos' => [], ]; } case 'datas': { return [ 'datas' => self::getOrigemDatas($params), 'agendamentos' => [], ]; } case 'agendamentos': { return [ 'agendamentos' => self::getOrigemAgendamentos($params), ]; } } } private static function getOrigemUnidades($params) { return Unidade::whereHas('infraestruturas', fn ($q) => $q ->whereHas('lotacoes', fn ($q) => $q ->where('usuario_id', $params->usuario_id) ->whereHas('ambulatorioJornadas', fn ($q) => $q ->whereDate('data', '>=', Carbon::today()) ->whereHas('agendamentos', fn ($q) => $q ->where('status_id', AgendamentoStatus::AGENDADO) ) ) ) ) ->orderBy('nome_fantasia') ->get(['id', 'nome_fantasia']); } private static function getOrigemInfraestruturas($params) { return Infraestrutura::setEagerLoads([]) ->where('unidade_id', $params->unidade_id) ->whereHas('lotacoes', fn ($q) => $q ->where('usuario_id', $params->usuario_id) ->whereHas('ambulatorioJornadas', fn ($q) => $q ->whereDate('data', '>=', Carbon::today()) ->whereHas('agendamentos', fn ($q) => $q ->where('status_id', AgendamentoStatus::AGENDADO) ) ) ) ->get(['id', 'nome', 'principal', 'unidade_id']) ->map(fn ($infraestrutura) => [ 'id' => $infraestrutura->id, 'nome' => $infraestrutura->nome, ]) ->sortBy('nome') ->values(); } private static function getOrigemOcupacoes($params) { return DB::table('sigtap.ocupacao as ocupacao') ->whereExists(fn ($q) => $q ->select(DB::raw(1)) ->from('cadastro_lotacao as lotacao') ->whereColumn('lotacao.ocupacao_id', 'ocupacao.id') ->where('lotacao.usuario_id', $params->usuario_id) ->where('lotacao.infraestrutura_id', $params->infraestrutura_id) ->whereExists(fn ($q) => $q ->select(DB::raw(1)) ->from('ambulatorio_jornada as jornada') ->whereColumn('jornada.lotacao_id', 'lotacao.id') ->whereDate('jornada.data', '>=', Carbon::today()) ->whereExists(fn ($q) => $q ->select(DB::raw(1)) ->from('ambulatorio_agendamento as agendamento') ->whereColumn('agendamento.jornada_id', 'jornada.id') ->where('status_id', AgendamentoStatus::AGENDADO) ) ) ) ->orderByRaw("CONCAT(ocupacao.codigo, ' - ', ocupacao.nome)") ->select( 'ocupacao.id', DB::raw("CONCAT(ocupacao.codigo, ' - ', ocupacao.nome) as descricao") ) ->get(); } private static function getOrigemEspecialidades($params) { return Especialidade::where('ocupacao_id', $params->ocupacao_id) ->whereHas('ambulatorioJornadas', fn ($q) => $q ->whereDate('data', '>=', Carbon::today()) ->whereHas('lotacao', fn ($q) => $q ->where('usuario_id', $params->usuario_id) ->where('infraestrutura_id', $params->infraestrutura_id) ) ->whereHas('agendamentos', fn ($q) => $q ->where('status_id', AgendamentoStatus::AGENDADO) ) ) ->orderBy('nome') ->get(['id', 'nome']); } private static function getOrigemDatas($params) { $feriados = self::getFeriados()->map(fn ($f) => Carbon::createFromFormat('d/m/Y', $f->data)->setTime(0, 0)); $datas = Jornada::whereDate('data', '>=', Carbon::today()) ->where('especialidade_id', $params->especialidade_id) ->whereHas('lotacao', fn ($q) => $q ->where('usuario_id', $params->usuario_id) ->where('infraestrutura_id', $params->infraestrutura_id) ) ->whereHas('agendamentos', fn ($q) => $q ->where('status_id', AgendamentoStatus::AGENDADO) ) ->groupBy('data') ->select( 'data', DB::raw("( SUM(COALESCE(quantidade_consulta, 0)) + SUM(COALESCE(quantidade_retorno, 0)) ) as quantidade_total") ) ->get() ->reject(fn ($d) => $feriados->contains($d->data)) ->values(); $datas->each(function ($data) use ($params) { $data->quantidade_total = (int) $data->quantidade_total; $data->quantidade_agendada = Agendamento::whereNotIn('status_id', self::getStatusLiberamHorario()) ->whereHas('jornada', fn ($q) => $q ->whereDate('data', $data->data) ->whereHas('lotacao', fn ($q) => $q ->where('usuario_id', $params->usuario_id) ->where('infraestrutura_id', $params->infraestrutura_id) ) ) ->count(); }); return $datas; } private static function getFeriados() { return Feriado::whereHas('modulos', fn ($q) => $q ->where('identificador', Modulo::AMBULATORIO) ) ->orderBy('data') ->get() ->map(fn ($feriado) => (object) [ 'data' => (new Carbon($feriado->data))->format('d/m/Y'), 'tipo_descricao' => $feriado->tipo->descricao, 'observacao' => $feriado->observacao, ]); } private static function getOrigemAgendamentos($params) { return Agendamento::where('status_id', AgendamentoStatus::AGENDADO) ->whereHas('jornada', fn ($q) => $q ->whereDate('data', Carbon::createFromFormat('d/m/Y', $params->data)) ->where('especialidade_id', $params->especialidade_id) ->whereHas('lotacao', fn ($q) => $q ->where('usuario_id', $params->usuario_id) ->where('infraestrutura_id', $params->infraestrutura_id) ) ) ->get(['id', 'jornada_id', 'horario', 'tipo_id', 'paciente_id', 'regulacao_solicitacao_id', 'created_lotacao_id']) ->map(function ($agendamento) { $paciente = $agendamento->paciente()->setEagerLoads([])->first(['cidadao_id', 'prontuario']); $cidadao = $paciente->cidadao()->setEagerLoads([])->first(['id', 'nome', 'data_nascimento']); $tipo = $agendamento->tipo()->first(['id', 'nome']); return (object) [ 'id' => $agendamento->id, 'is_from_regulacao' => !is_null($agendamento->regulacao_solicitacao_id), 'horario' => $agendamento->horario->format('H:i'), 'tipo_id' => $tipo->id, 'tipo_nome' => $tipo->nome, 'paciente_nome' => $cidadao->nome, 'paciente_data_nascimento' => is_null($cidadao->data_nascimento) ? null : (new Carbon($cidadao->data_nascimento))->format('d/m/Y'), 'paciente_prontuario' => $paciente->prontuario, 'paciente_telefone' => MaskUtil::getPhoneMasked($paciente->cidadao->telefone_principal->numero ?? null), 'usuario_agendador_nome' => $agendamento->createdLotacao() ->first('usuario_id') ->usuario() ->setEagerLoads([]) ->first('cidadao_id') ->cidadao() ->setEagerLoads([]) ->first('nome') ->nome ]; }) ->sortBy([ ['horario', 'asc'], ['paciente_nome', 'asc'], ]) ->values(); } private static function getListDestinoData($params) { switch (request()->listar) { case 'unidades': { return [ 'unidades' => self::getDestinoUnidades(), 'infraestruturas' => [], 'ocupacoes' => [], 'especialidades' => [], 'usuarios' => [], 'jornadas' => [], ]; } case 'infraestruturas': { return [ 'infraestruturas' => self::getDestinoInfraestruturas($params), 'ocupacoes' => [], 'especialidades' => [], 'usuarios' => [], 'jornadas' => [], ]; } case 'ocupacoes': { return [ 'ocupacoes' => self::getDestinoOcupacoes($params), 'especialidades' => [], 'usuarios' => [], 'jornadas' => [], ]; } case 'especialidades': { return [ 'especialidades' => self::getDestinoEspecialidades($params), 'usuarios' => [], 'jornadas' => [], ]; } case 'usuarios': { return [ 'usuarios' => self::getDestinoUsuarios($params), 'jornadas' => [], ]; } case 'jornadas': { return [ 'jornadas' => self::getDestinoJornadas($params), ]; } } } private static function getDestinoUnidades() { return Unidade::whereHas('infraestruturas', fn ($q) => $q ->whereHas('lotacoes', fn ($q) => $q ->whereHas('ambulatorioJornadas', fn ($q) => $q ->whereNull('situacao_id') ->whereDate('data', '>=', Carbon::today()) ) ) ) ->orderBy('nome_fantasia') ->get(['id', 'nome_fantasia']); } private static function getDestinoInfraestruturas($params) { return Infraestrutura::setEagerLoads([]) ->where('unidade_id', $params->unidade_id) ->whereHas('lotacoes', fn ($q) => $q ->whereHas('ambulatorioJornadas', fn ($q) => $q ->whereNull('situacao_id') ->whereDate('data', '>=', Carbon::today()) ) ) ->get(['id', 'nome', 'principal', 'unidade_id']) ->map(fn ($infraestrutura) => [ 'id' => $infraestrutura->id, 'nome' => $infraestrutura->nome ]) ->sortBy('nome') ->values(); } private static function getDestinoOcupacoes($params) { return DB::table('sigtap.ocupacao as ocupacao') ->whereExists(fn ($q) => $q ->select(DB::raw(1)) ->from('cadastro_lotacao as lotacao') ->whereColumn('lotacao.ocupacao_id', 'ocupacao.id') ->where('lotacao.infraestrutura_id', $params->infraestrutura_id) ->whereExists(fn ($q) => $q ->select(DB::raw(1)) ->from('ambulatorio_jornada as jornada') ->whereColumn('jornada.lotacao_id', 'lotacao.id') ->whereNull('jornada.situacao_id') ->whereDate('jornada.data', '>=', Carbon::today()) ) ) ->orderByRaw("CONCAT(ocupacao.codigo, ' - ', ocupacao.nome)") ->select(DB::raw(" ocupacao.id, CONCAT(ocupacao.codigo, ' - ', ocupacao.nome) as descricao ")) ->get(); } private static function getDestinoEspecialidades($params) { return Especialidade::where('ocupacao_id', $params->ocupacao_id) ->whereHas('ambulatorioJornadas', fn ($q) => $q ->whereNull('situacao_id') ->whereDate('data', '>=', Carbon::today()) ->whereHas('lotacao', fn ($q) => $q ->where('infraestrutura_id', $params->infraestrutura_id) ) ) ->orderBy('nome') ->get(['id', 'nome']); } private static function getDestinoUsuarios($params) { return Usuario::setEagerLoads([]) ->whereHas('lotacoes', fn ($q) => $q ->where('infraestrutura_id', $params->infraestrutura_id) ->whereHas('ambulatorioJornadas', fn ($q) => $q ->whereNull('situacao_id') ->whereDate('data', '>=', Carbon::today()) ->where('especialidade_id', $params->especialidade_id) ) ) ->get(['id', 'cidadao_id']) ->map(fn ($usuario) => [ 'id' => $usuario->id, 'nome' => $usuario->cidadao()->setEagerLoads([])->first(['nome'])->nome, ]) ->sortBy('nome') ->values(); } private static function getDestinoJornadas($params) { return Jornada::whereNull('situacao_id') ->whereDate('data', '>=', Carbon::today()) ->where('especialidade_id', $params->especialidade_id) ->whereHas('lotacao', fn ($q) => $q ->where('infraestrutura_id', $params->infraestrutura_id) ->where('usuario_id', $params->usuario_id) ) ->select( 'id', 'data', 'inicio', 'fim', DB::raw("COALESCE(quantidade_consulta, 0) as quantidade_consulta_total"), DB::raw("COALESCE(quantidade_retorno, 0) as quantidade_retorno_total") ) ->get() ->map(function ($jornada) { return [ 'id' => $jornada->id, 'data' => $jornada->data->format('d/m/Y'), 'dia_semana' => DiaSemana::findOrFail($jornada->dia_semana)->descricao, 'inicio' => $jornada->inicio->format('H:i'), 'fim' => $jornada->fim->format('H:i'), 'quantidade_consulta_agendada' => Agendamento::where('jornada_id', $jornada->id) ->where('tipo_id', AgendamentoTipo::CONSULTA) ->whereNotIn('status_id', self::getStatusLiberamHorario()) ->count(), 'quantidade_consulta_total' => (int) $jornada->quantidade_consulta_total, 'quantidade_retorno_agendado' => Agendamento::where('jornada_id', $jornada->id) ->where('tipo_id', AgendamentoTipo::RETORNO) ->whereNotIn('status_id', self::getStatusLiberamHorario()) ->count(), 'quantidade_retorno_total' => (int) $jornada->quantidade_retorno_total, ]; }); } public static function reschedule() { self::validateReschedule(); $agendamentosNaoReagendados = (object) [ 'status_nao_permite_alteracao' => collect(), 'incompativel_com_especialidade' => collect(), ]; DB::transaction(function () use ($agendamentosNaoReagendados) { collect(request()->agendamentos)->each(function ($id) use ($agendamentosNaoReagendados) { $agendamentoAnterior = Agendamento::findOrFail($id); if ($agendamentoAnterior->status_id === AgendamentoStatus::AGENDADO) { $jornada = Jornada::findOrFail(request()->jornada_id); if (self::isPacienteValidForEspecialidade($agendamentoAnterior->paciente, $jornada->especialidade)) { $agendamentoAnterior->update(['status_id' => AgendamentoStatus::REAGENDADO_PELO_MEDICO]); $nextHorario = self::getNextHorario($jornada, $agendamentoAnterior->tipo_id); $agendamentoNovo = Agendamento::create([ 'agendamento_anterior_id' => $agendamentoAnterior->id, 'jornada_id' => $jornada->id, 'tipo_id' => $agendamentoAnterior->tipo_id, 'horario' => $nextHorario->horario, 'paciente_id' => $agendamentoAnterior->paciente_id, 'motivo_agendamento_excedente' => $nextHorario->is_excedente ? request()->motivo_agendamento_excedente : null, 'observacao' => $agendamentoAnterior->observacao, 'status_id' => AgendamentoStatus::AGENDADO, ]); (new SmsService($agendamentoAnterior->id))->cancel(); (new SmsService($agendamentoNovo->id))->send(); } else { $agendamentosNaoReagendados->incompativel_com_especialidade->push($agendamentoAnterior->id); } } else { $agendamentosNaoReagendados->status_nao_permite_alteracao->push($agendamentoAnterior->id); } }); }); return (object) ['agendamentos_nao_reagendados' => $agendamentosNaoReagendados]; } private static function validateReschedule() { request()->validate([ 'agendamentos' => [ 'required', 'array', ], 'agendamentos.*' => [ 'required', 'integer', Rule::exists(Agendamento::class, 'id'), ], 'jornada_id' => [ 'required', 'integer', Rule::exists(Jornada::class, 'id'), function ($attribute, $value, $fail) { $hasAgendamentoConsulta = false; $hasAgendamentoRetorno = false; collect(request()->agendamentos) ->each(function ($id) use (&$hasAgendamentoConsulta, &$hasAgendamentoRetorno) { $agendamento = Agendamento::findOrFail($id); if ($agendamento->tipo_id === AgendamentoTipo::CONSULTA) { $hasAgendamentoConsulta = true; } else if ($agendamento->tipo_id === AgendamentoTipo::RETORNO) { $hasAgendamentoRetorno = true; } }); $jornada = Jornada::findOrFail($value); if (($hasAgendamentoConsulta && is_null($jornada->quantidade_consulta)) || ($hasAgendamentoRetorno && is_null($jornada->quantidade_retorno)) ) { $fail("A jornada não é compatível com os agendamentos."); } } ], 'motivo_agendamento_excedente' => [ 'nullable', 'string', 'max:500', ] ]); } private static function isPacienteValidForEspecialidade($paciente, $especialidade) { $idade = $paciente->cidadao->idade['anos']; $sexo = $paciente->cidadao->sexo; if (!is_null($especialidade->sexo_id) && $especialidade->sexo_id !== $sexo->id) { return false; } if ((!is_null($especialidade->idade_minima) && $idade < $especialidade->idade_minima) || (!is_null($especialidade->idade_maxima) && $idade > $especialidade->idade_maxima) ) { return false; } if (!is_null($especialidade->procedimento_grupo_codigo)) { $procedimento = Procedimento::where('codigo', $especialidade->procedimento_grupo_codigo) ->orderByDesc('competencia_id') ->first(); $validator = new ProcedimentoValidationService($procedimento); if (!$validator->isSexoValid($sexo) || !$validator->isIdadeValid($idade)) { return false; } } return true; } private static function getNextHorario($jornada, $agendamentoTipoId) { $nextHorario = (object) [ 'horario' => null, 'is_excedente' => false, ]; if ($jornada->tipo_id === JornadaTipo::FIXA) { $quantidadeAgendada = Agendamento::where('jornada_id', $jornada->id) ->where('tipo_id', $agendamentoTipoId) ->whereTime('horario', $jornada->inicio) ->whereNotIn('status_id', self::getStatusLiberamHorario()) ->count(); $nextHorario->horario = $jornada->inicio->format('H:i'); $nextHorario->is_excedente = $quantidadeAgendada >= $jornada->{self::getCampoQuantidade($agendamentoTipoId)}; } else if ($jornada->tipo_id === JornadaTipo::DINAMICA) { $horarios = collect(); $agendamentos = self::getAgendamentos($jornada->id); $agendamentos->each(fn ($a) => $a->horario = $jornada->inicio->copy()->setTimeFromTimeString($a->horario)); $agendamentos->where('tipo_id', $agendamentoTipoId) ->each(fn ($agendamento) => $horarios->push((object) [ 'horario' => $agendamento->horario->format('H:i'), 'quantidade_agendada' => $agendamento->quantidade_agendada, 'quantidade_total' => 1, ])); $quantidade = $agendamentos->where('tipo_id', $agendamentoTipoId)->count(); if ($quantidade < $jornada->{self::getCampoQuantidade($agendamentoTipoId)}) { $data = $jornada->inicio->copy(); self::setHorarioJornadaDinamica( $horarios, $agendamentos, $jornada, $agendamentoTipoId, $quantidade, $data ); } $horarios = $horarios->sortBy('horario')->values(); $horario = $horarios->where('quantidade_agendada', 0)->first(); if (is_null($horario)) { $horario = $horarios->last(); } $nextHorario->horario = $horario->horario; $nextHorario->is_excedente = $horario->quantidade_agendada >= $horario->quantidade_total; } return $nextHorario; } private static function getAgendamentos($jornadaId) { return Agendamento::where('jornada_id', $jornadaId) ->whereNotIn('status_id', self::getStatusLiberamHorario()) ->groupBy([ 'tipo_id', 'horario', ]) ->orderBy('horario') ->select( 'tipo_id', 'horario', DB::raw("COUNT(id) as quantidade_agendada") ) ->get(); } private static function getStatusLiberamHorario() { return [ AgendamentoStatus::REAGENDADO_PELO_PACIENTE, AgendamentoStatus::REAGENDADO_PELO_MEDICO, AgendamentoStatus::CANCELADO_PELO_PACIENTE, AgendamentoStatus::CANCELADO_PELO_MEDICO, ]; } private static function setHorarioJornadaDinamica($horarios, $agendamentos, $jornada, $tipoId, $quantidade, $data) { $agendamento = $agendamentos->where('horario', $data)->first(); if (is_null($agendamento)) { $final = $data->copy()->addMinutes($jornada->{self::getCampoTempo($tipoId)}); $agendamento = $agendamentos ->where('horario', '>', $data) ->where('horario', '<', $final) ->first(); if ($agendamento) { self::setHorarioJornadaDinamica( $horarios, $agendamentos, $jornada, $tipoId, $quantidade, $agendamento->horario ); } else { $horarios->push((object) [ 'horario' => $data->format('H:i'), 'quantidade_agendada' => 0, 'quantidade_total' => 1, ]); if (++$quantidade < $jornada->{self::getCampoQuantidade($tipoId)}) { $data->addMinutes($jornada->{self::getCampoTempo($tipoId)}); self::setHorarioJornadaDinamica($horarios, $agendamentos, $jornada, $tipoId, $quantidade, $data); } } } else { if ($agendamento->tipo_id == $tipoId) { $data->addMinutes($jornada->{self::getCampoTempo($tipoId)}); self::setHorarioJornadaDinamica($horarios, $agendamentos, $jornada, $tipoId, $quantidade, $data); } else { $data = $agendamento->horario->copy()->addMinutes($jornada->{self::getCampoTempo($tipoId, true)}); self::setHorarioJornadaDinamica($horarios, $agendamentos, $jornada, $tipoId, $quantidade, $data); } } } private static function getCampoQuantidade($tipoId) { if ($tipoId === AgendamentoTipo::CONSULTA) { return 'quantidade_consulta'; } else if ($tipoId === AgendamentoTipo::RETORNO) { return 'quantidade_retorno'; } } private static function getCampoTempo($tipoId, $inverso = false) { if ($tipoId === AgendamentoTipo::CONSULTA) { return $inverso ? 'tempo_retorno' : 'tempo_consulta'; } else if ($tipoId === AgendamentoTipo::RETORNO) { return $inverso ? 'tempo_consulta' : 'tempo_retorno'; } } public static function cancel() { self::validateCancel(); $agendamentosNaoCancelados = (object) [ 'status_nao_permite_alteracao' => collect() ]; DB::transaction(function () use ($agendamentosNaoCancelados) { collect(request()->agendamentos)->each(function ($id) use ($agendamentosNaoCancelados) { $agendamento = Agendamento::findOrFail($id); if ($agendamento->status_id === AgendamentoStatus::AGENDADO) { $agendamento->update([ 'status_id' => AgendamentoStatus::CANCELADO_PELO_MEDICO, 'motivo_cancelamento' => request()->motivo, ]); (new SmsService($agendamento->id))->cancel(); if (!is_null($agendamento->regulacao_solicitacao_id)) { RegulacaoSolicitacaoService::voltarParaStatusSolicitado($agendamento->regulacao_solicitacao_id); } } else { $agendamentosNaoCancelados->status_nao_permite_alteracao->push($id); } }); }); return (object) ['agendamentos_nao_cancelados' => $agendamentosNaoCancelados]; } private static function validateCancel() { request()->validate([ 'agendamentos' => [ 'required', 'array', ], 'agendamentos.*' => [ 'required', 'integer', Rule::exists(Agendamento::class, 'id'), ], 'motivo' => [ 'required', 'string', 'max:500', ], ]); } }