bloqueia_paciente_temporario ?? false; $provisorioQuantidadeDias = $cadastroParametrizacao->cadastro_paciente_provisorio_quantidade_dias ?? 0; $pacientes = DB::table('cadastro_paciente as paciente') ->join('cadastro_cidadao as cidadao', 'cidadao.id', 'paciente.cidadao_id') ->leftJoin('cadastro_cidadao_telefone as telefone', function ($join) { $join->on('telefone.cidadao_id', '=', 'cidadao.id') ->where('telefone.principal', true) ->whereRaw('telefone.id = ( SELECT MAX(id) FROM cadastro_cidadao_telefone WHERE cidadao_id = cidadao.id AND principal = true AND deleted_at is null )'); }) ->leftJoin('cadastro_domicilio as domicilio', 'domicilio.id', 'cidadao.domicilio_id') ->leftJoin('cadastro_endereco as endereco', 'endereco.id', 'domicilio.endereco_id') ->leftJoin('cadastro_logradouro as logradouro', 'logradouro.id', 'endereco.logradouro_id') ->leftJoin('cadastro_logradouro_tipo as logradouro_tipo', 'logradouro_tipo.id', 'logradouro.tipo_id') ->leftJoin('cadastro_bairro as bairro', 'bairro.id', 'logradouro.bairro_id') ->leftJoin('intranet.cadastro_municipio as municipio', 'municipio.id', 'logradouro.municipio_id') ->leftJoin('intranet.cadastro_estado as estado', 'estado.id', 'municipio.estado_id') ->leftJoin('cadastro_unidade as unidade_referencia', 'unidade_referencia.id', 'paciente.unidade_id') ->leftJoin('cadastro_paciente_classificacao as classificacao', 'classificacao.id', 'paciente.classificacao_id') ->leftJoin('cadastro_obito', function ($join) { $join->on('cidadao.id', '=', 'cadastro_obito.cidadao_id') ->whereNull('cadastro_obito.deleted_at'); }) ->whereNull('paciente.deleted_at') ->whereNull('cadastro_obito.id') ->select(DB::raw(" paciente.id, cidadao.nome, cidadao.nome_social, DATE_FORMAT(cidadao.data_nascimento, '%d/%m/%Y') as data_nascimento, paciente.prontuario, paciente.subclassificacao_id, cidadao.cpf, cidadao.cns, cidadao.nome_mae, unidade_referencia.nome_fantasia as unidade_referencia, classificacao.descricao as classificacao, DATE_FORMAT(paciente.validade_fim, '%d/%m/%Y') as validade_cadastro, CONCAT( logradouro_tipo.descricao, ' ', logradouro.nome, ', ', COALESCE(endereco.numero, 'S/N'), ' - ', bairro.nome, ', ', municipio.nome, ' - ', estado.uf ) as endereco, telefone.id as telefone_id, telefone.numero as telefone_numero, telefone.autoriza_sms as telefone_autoriza_sms, cidadao.id as cidadao_id, classificacao.id as classificacao_id ")); $pacientes->where(function ($query) { $query->where('paciente.bloqueado', false) ->orWhereNull('paciente.bloqueado'); }); if ($provisorioBloqueado) { $pacientes->where(function ($query) use ($provisorioQuantidadeDias) { $query->where('paciente.subclassificacao_id', '!=', Subclassificacao::TEMPORARIO) ->orWhere(function ($query) use ($provisorioQuantidadeDias) { $query->where('paciente.subclassificacao_id', Subclassificacao::TEMPORARIO) ->where(function ($query) use ($provisorioQuantidadeDias) { $query->where(function ($query) { $query->whereNull('paciente.validade_inicio') ->orWhereDate('paciente.validade_inicio', '<=', Carbon::now()->format('Y-m-d')); }); $query->where(function ($query) use ($provisorioQuantidadeDias) { $query->whereNull('paciente.validade_fim') ->orWhere(function ($query) use ($provisorioQuantidadeDias) { if (!is_null($provisorioQuantidadeDias) && $provisorioQuantidadeDias > 0) { $query->whereDate('paciente.validade_fim', '>=', Carbon::now()->format('Y-m-d')) ->orWhereDate('paciente.validade_fim', '>=', Carbon::now()->subDays($provisorioQuantidadeDias)->format('Y-m-d')); } else { $query->whereDate('paciente.validade_fim', '>=', Carbon::now()->format('Y-m-d')); } }); }); }); }) ->orWhereNull('paciente.subclassificacao_id'); }); } return datatables() ->of($pacientes) ->filterColumn('cidadao.data_nascimento', function ($query, $keyword) { $query->whereRaw("DATE_FORMAT(cidadao.data_nascimento, '%d/%m/%Y') like ?", ["%{$keyword}%"]); }) ->filterColumn('paciente.prontuario', function ($query, $keyword) { $query->whereRaw("LPAD(paciente.prontuario, 6, 0) like ?", ["%{$keyword}%"]); }) ->filterColumn('cidadao.nome', function ($query, $keyword) { $query->where(function ($query) use ($keyword) { $query->where('cidadao.nome', 'like', "%{$keyword}%") ->orWhere('cidadao.nome_social', 'like', "%{$keyword}%"); }); }) ->addColumn('idade', function ($paciente) { return is_null($paciente->data_nascimento) ? null : AgeService::getFormattedAge( Carbon::createFromFormat('d/m/Y', $paciente->data_nascimento)->toDateTime() ); }) ->addColumn('idade_anos', function ($paciente) { if ($paciente->data_nascimento === null) { return null; } $idade = AgeService::getAge(Carbon::createFromFormat('d/m/Y', $paciente->data_nascimento)->toDateTime()); return $idade->years; }) ->editColumn('cpf', fn ($paciente) => MaskUtil::getCpfMasked($paciente->cpf)) ->editColumn('cns', fn ($paciente) => MaskUtil::getCnsMasked($paciente->cns)) ->editColumn('telefone_numero', fn ($paciente) => MaskUtil::getPhoneMasked($paciente->telefone_numero)) ->editColumn('telefone_autoriza_sms', fn ($paciente) => !!$paciente->telefone_autoriza_sms) ->toJson(); } public static function list() { $params = (object) request()->all(); $params->infraestrutura_id = self::getCurrentCentroCusto()->infraestrutura_id; $params->data = Carbon::today(); if (collect(['ocupacoes', 'especialidades', 'usuarios'])->contains(request()->listar)) { $paciente = Paciente::setEagerLoads([])->where('id', $params->paciente_id)->first(); $params->paciente_nao_municipe = $paciente->classificacao_id !== Classificacao::MUNICIPE; } switch (request()->listar) { case 'totalizadores': { return self::getTotalizadores(); } case 'agendamentos': { return [ 'agendamentos' => self::getAgendamentos($params), ]; } case 'usuarios': { return [ 'usuarios' => self::getUsuariosWithJornada($params), 'ocupacoes' => [], 'especialidades' => [], 'jornadas' => [], ]; } case 'ocupacoes': { return [ 'ocupacoes' => self::getOcupacoesWithJornada($params), 'especialidades' => [], 'jornadas' => [], ]; } case 'especialidades': { return [ 'especialidades' => self::getEspecialidadesWithJornada($params), 'jornadas' => [], ]; } case 'jornadas': { return [ 'jornadas' => self::getJornadas($params), ]; } } } public static function create($filaId = null) { $fila = null; if (!is_null($filaId)) { $fila = Fila::findOrFail($filaId); FilaService::answer($fila->id); } return [ 'additionals' => self::getAdditionalsData($fila), 'form' => self::getFormData($fila), 'model' => self::getModelData($fila), ]; } public static function edit($atendimentoId) { $atendimento = Atendimento::findOrFail($atendimentoId); return [ 'additionals' => self::getAdditionalsData($atendimento->fila), 'form' => self::getFormData($atendimento->fila, $atendimento), 'model' => self::getModelData($atendimento->fila, $atendimento), ]; } private static function getAdditionalsData($fila = null) { return [ 'has_atendimento' => is_null($fila) ? false : $fila->ambulatorioAtendimento()->exists(), 'permissoes_atualizacao_cadastro_paciente' => self::getPermissoesAtualizacaoCadastroPaciente(), ]; } private static function getFormData($fila = null, $atendimento = null) { $demandaEspontaneaObservaVagaAtendimento = self::demandaEspontaneaObservaVagaAtendimento(); $agendamentos = []; $usuarios = []; $ocupacoes = []; $especialidades = []; $jornadas = []; if (!is_null($atendimento)) { $params = [ 'paciente_id' => $atendimento->paciente->id, 'paciente_nao_municipe' => $atendimento->paciente->classificacao_id !== Classificacao::MUNICIPE, 'infraestrutura_id' => self::getCurrentCentroCusto()->infraestrutura_id, 'data' => Carbon::today(), ]; if ($atendimento->is_demanda_espontanea) { $usuarios = self::getUsuariosWithJornada((object) $params); if (!is_null($atendimento->usuario)) { $ocupacoes = self::getOcupacoesWithJornada((object) array_merge($params, [ 'usuario_id' => $atendimento->usuario->id, ])); } if (!is_null($atendimento->ocupacao)) { $especialidades = self::getEspecialidadesWithJornada((object) array_merge($params, [ 'usuario_id' => $atendimento->usuario->id, 'ocupacao_id' => $atendimento->ocupacao->id, ])); } if ($demandaEspontaneaObservaVagaAtendimento) { if (!is_null($atendimento->usuario) && !is_null($atendimento->ocupacao)) { $jornadas = self::getJornadas((object) [ 'data' => $atendimento->created_at->format('Y-m-d'), 'usuario_id' => $atendimento->usuario->id, 'ocupacao_id' => $atendimento->ocupacao->id, 'infraestrutura_id' => $params['infraestrutura_id'], ]); } } } else { $agendamentos = self::getAgendamentos((object) $params, $atendimento->agendamento_id); } } $atendimentoTipos = TipoAtendimento::whereIn('id', [ TipoAtendimentoEnum::CONSULTA_AGENDADA_PROGRAMADA, TipoAtendimentoEnum::CONSULTA_AGENDADA, TipoAtendimentoEnum::ESCUTA_INICIAL_ORIENTACAO, TipoAtendimentoEnum::CONSULTA_NO_DIA, TipoAtendimentoEnum::ATENDIMENTO_DE_URGENCIA, ])->orderBy('descricao')->get(['id', 'descricao'])->map(fn ($tipo) => [ 'id' => $tipo->id, 'nome' => $tipo->descricao, 'is_demanda_espontanea' => collect([ TipoAtendimentoEnum::ESCUTA_INICIAL_ORIENTACAO, TipoAtendimentoEnum::CONSULTA_NO_DIA, TipoAtendimentoEnum::ATENDIMENTO_DE_URGENCIA, ])->contains($tipo->id) ]); return [ 'opcoes_entrada' => self::getOpcoesEntrada($fila), 'prioridades' => self::getPrioridades(), 'demanda_tipos' => self::getDemandaTipos(), 'atendimento_tipos' => $atendimentoTipos, 'agendamentos' => $agendamentos, 'usuarios' => $usuarios, 'ocupacoes' => $ocupacoes, 'especialidades' => $especialidades, 'jornadas' => $jornadas, 'servicos' => self::getServicos(), 'centros_custo_encaminhamento' => self::getCentrosCustoEncaminhamento( $atendimento->fila->centro_custo_id ?? null ), ]; } public static function unidadePaciente($pacienteId) { $possuiJornadaUnidadePaciente = false; $parametrizacao = ParametrizacaoAgendamento::first(); $cadastroParametrizacao = Parametrizacao::first(); $infraestruturaId = self::getCurrentCentroCusto()->infraestrutura_id; $paciente = Paciente::findOrFail($pacienteId); $unidadeId = Infraestrutura::findOrFail($infraestruturaId)->unidade_id; if ($parametrizacao->avisa_paciente_outra_unidade) { if ($unidadeId !== $paciente->unidade_id) { $possuiJornadaUnidadePaciente = Unidade::where('id', $paciente->unidade_id)->exists(); } } return [ 'unidade_com_jornada' => $possuiJornadaUnidadePaciente, 'unidade' => $paciente->unidade->nome_fantasia ?? null, 'cns_valido' => Cns::isValid($paciente->cidadao->cns), 'avisa_cns_temporario_invalido' => $cadastroParametrizacao->exibe_alerta_paciente_cns_temporario_invalido ?? false, ]; } private static function getOpcoesEntrada($fila = null) { if (is_null($fila)) { return OpcaoEntrada::where('centro_custo_id', self::getCurrentCentroCusto()->id) ->where('modulo_id', ModuloService::getId(Modulo::AMBULATORIO)) ->orderBy('nome') ->get(['id', 'nome', 'prioridade_obrigatoria']); } return OpcaoEntrada::where('id', $fila->opcao_entrada_id) ->get(['id', 'nome', 'prioridade_obrigatoria']); } private static function getPrioridades() { return Prioridade::orderBy('nome')->get(['id', 'tipo_id', 'nome']); } private static function getDemandaTipos() { return [ ['value' => DemandaTipo::AGENDADA, 'text' => 'Demanda agendada'], ['value' => DemandaTipo::ESPONTANEA, 'text' => 'Demanda espontânea'], ]; } private static function getTotalizadores() { $agendamentos = GerenciamentoDiarioService::getAgendamentos(['data' => Carbon::today()->format('d/m/Y')]); $atendimentos = GerenciamentoDiarioService::getAtendimentos(); $atendidosEvadidos = GerenciamentoDiarioService::getAtendidosEvadidos(); return [ 'total_pacientes_agendados' => $agendamentos->count(), 'total_faltas_no_dia' => $agendamentos->where('status_id', AgendamentoStatus::FALTA_DO_PACIENTE)->count(), 'total_pacientes_atendidos_no_dia' => $atendidosEvadidos->where('evadido', false)->count(), 'total_pacientes_em_atendimento' => $atendimentos->where('fila_status_id', Status::EM_ATENDIMENTO)->count(), 'total_pacientes_aguardando_atendimento' => $atendimentos->where('fila_status_id', Status::EM_ESPERA)->count(), 'total_evasoes' => $atendidosEvadidos->where('evadido', true)->count(), ]; } private static function getAgendamentos($params, $agendamentoId = null) { return DB::table('ambulatorio_agendamento as agendamento') ->join('ambulatorio_jornada as jornada', 'jornada.id', 'agendamento.jornada_id') ->join('cadastro_lotacao as lotacao', 'lotacao.id', 'jornada.lotacao_id') ->join('sigtap.ocupacao as ocupacao', 'ocupacao.id', 'lotacao.ocupacao_id') ->join('cadastro_usuario as usuario', 'usuario.id', 'lotacao.usuario_id') ->join('cadastro_cidadao as cidadao', 'cidadao.id', 'usuario.cidadao_id') ->join('cadastro_especialidade as especialidade', 'especialidade.id', 'jornada.especialidade_id') ->where('agendamento.paciente_id', $params->paciente_id) ->where('agendamento.status_id', AgendamentoStatus::AGENDADO) ->where(fn ($q) => $q ->whereNotExists(fn ($q) => $q ->select(DB::raw(1)) ->from('ambulatorio_atendimento as atendimento') ->whereColumn('atendimento.agendamento_id', 'agendamento.id') ) ->when($agendamentoId, fn ($q) => $q ->orWhere('agendamento.id', $agendamentoId) ) ) ->where('jornada.data', $params->data) ->where('lotacao.infraestrutura_id', $params->infraestrutura_id) ->select(DB::raw(" agendamento.id, DATE_FORMAT(agendamento.horario, '%H:%i') as horario, CONCAT(ocupacao.codigo, ' - ', ocupacao.nome) as ocupacao_descricao, especialidade.nome as especialidade_nome, cidadao.nome as usuario_nome ")) ->unionAll(DB::table('ambulatorio_agendamento as agendamento') ->join('ambulatorio_jornada as jornada', 'jornada.id', 'agendamento.jornada_id') ->join('cadastro_lotacao as lotacao', 'lotacao.id', 'jornada.lotacao_id') ->join('cadastro_infraestrutura as infraestrutura', 'infraestrutura.id', 'lotacao.infraestrutura_id') ->join('sigtap.ocupacao as ocupacao', 'ocupacao.id', 'lotacao.ocupacao_id') ->join('cadastro_usuario as usuario', 'usuario.id', 'lotacao.usuario_id') ->join('cadastro_cidadao as cidadao', 'cidadao.id', 'usuario.cidadao_id') ->join('cadastro_especialidade as especialidade', 'especialidade.id', 'jornada.especialidade_id') ->where('agendamento.paciente_id', $params->paciente_id) ->where('agendamento.status_id', AgendamentoStatus::AGENDADO) ->where(fn ($q) => $q ->whereNotExists(fn ($q) => $q ->select(DB::raw(1)) ->from('ambulatorio_atendimento as atendimento') ->whereColumn('atendimento.agendamento_id', 'agendamento.id') ) ->when($agendamentoId, fn ($q) => $q ->orWhere('agendamento.id', $agendamentoId) ) ) ->where('jornada.data', $params->data) ->where('infraestrutura.infraestrutura_id', $params->infraestrutura_id) ->select(DB::raw(" agendamento.id, DATE_FORMAT(agendamento.horario, '%H:%i') as horario, CONCAT(ocupacao.codigo, ' - ', ocupacao.nome) as ocupacao_descricao, especialidade.nome as especialidade_nome, cidadao.nome as usuario_nome ")) ) ->get(); } private static function getUsuariosWithJornada($params) { return Usuario::setEagerLoads([]) ->whereHas('lotacoes', fn ($q) => $q ->where('infraestrutura_id', $params->infraestrutura_id) ->whereHas('ambulatorioJornadas', fn ($q) => $q ->whereNotNull('quantidade_consulta') ->whereNull('situacao_id') ->whereDate('data', $params->data) ) ) ->get(['id', 'cidadao_id']) ->map(fn ($usuario) => [ 'id' => $usuario->id, 'nome' => $usuario->cidadao()->setEagerLoads([])->first(['nome'])->nome, ]) ->sortBy('nome') ->values(); } private static function getOcupacoesWithJornada($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') ->join( 'cadastro_especialidade as especialidade', 'especialidade.id', 'jornada.especialidade_id' ) ->whereColumn('jornada.lotacao_id', 'lotacao.id') ->whereNotNull('jornada.quantidade_consulta') ->whereNull('jornada.situacao_id') ->whereDate('jornada.data', $params->data) ->where(fn ($query) => self::setCadastroWhereEspecialidadePaciente( $query, $params->paciente_id, 'especialidade' )) ->when($params->paciente_nao_municipe, fn ($q) => $q ->where('especialidade.permite_agendamento_nao_municipe', true) ) ) ) ->orderByRaw("CONCAT(ocupacao.codigo, ' - ', ocupacao.nome)") ->select(DB::raw(" ocupacao.id, CONCAT(ocupacao.codigo, ' - ', ocupacao.nome) as descricao ")) ->get(); } private static function getEspecialidadesWithJornada($params) { return Especialidade::where(fn ($q) => self::setCadastroWhereEspecialidadePaciente($q, $params->paciente_id)) ->whereHas('ambulatorioJornadas', fn ($q) => $q ->whereNotNull('quantidade_consulta') ->whereNull('situacao_id') ->whereDate('data', $params->data) ->whereHas('lotacao', fn ($q) => $q ->where('infraestrutura_id', $params->infraestrutura_id) ->where('usuario_id', $params->usuario_id) ->where('ocupacao_id', $params->ocupacao_id) ) ) ->when($params->paciente_nao_municipe, fn ($q) => $q ->where('permite_agendamento_nao_municipe', true) ) ->orderBy('nome') ->get() ->map(fn ($q) => [ 'id' => $q->id, 'nome' => $q->nome, 'demanda_espontanea_observa_vaga_atendimento' => $q->ambulatorioParametrizacoesInfraestruturaEspecialidade() ->whereHas('parametrizacaoInfraestrutura', fn ($q) => $q->where('infraestrutura_id', $params->infraestrutura_id)) ->first()->demanda_espontanea_observa_vaga_atendimento ?? false, ]); } private static function getJornadas($params) { $jornadas = Jornada::setEagerLoads([]) ->whereHas('lotacao', fn ($q) => $q ->where('usuario_id', $params->usuario_id) ->where('ocupacao_id', $params->ocupacao_id) ->where('infraestrutura_id', $params->infraestrutura_id) ) ->whereNotNull('quantidade_consulta') ->whereNull('situacao_id') ->whereDate('data', $params->data) ->orderBy('inicio') ->get() ->map(function ($jornada) { $quantidadeAgendamentos = $jornada->agendamentos() ->whereNotIn('status_id', self::getStatusLiberamHorario()) ->where('tipo_id', AgendamentoTipo::CONSULTA) ->count(); $quantidadeDemandasEspontaneas = $jornada->demandasEspontaneas()->count(); $quantidadeUtilizada = $quantidadeAgendamentos + $quantidadeDemandasEspontaneas; $quantidadeConsulta = $jornada->quantidade_consulta; return [ 'id' => $jornada->id, 'quantidade_utilizada' => $quantidadeUtilizada, 'quantidade_consulta' => $quantidadeConsulta, 'inicio' => $jornada->inicio->format('H:i'), 'fim' => $jornada->fim->format('H:i'), 'descricao' => $jornada->inicio->format('d/m/Y H:i') . ' - ' . $quantidadeUtilizada . '/' . $quantidadeConsulta, ]; }); $horarioAtual = Carbon::now()->format('H:i'); $jornada = $jornadas ->filter(fn ($jornada) => $jornada['inicio'] <= $horarioAtual && $jornada['fim'] >= $horarioAtual) ->first(); return [ 'jornada_id' => $jornada['id'] ?? null, 'jornadas' => $jornadas, ]; } private static function setCadastroWhereEspecialidadePaciente($query, $pacienteId, $tableAlias = '') { if (!empty($tableAlias)) { $tableAlias .= '.'; } $paciente = Paciente::find($pacienteId); $idade = $paciente->cidadao->idade; return $query->where(fn ($q) => $q ->when($idade, fn ($q) => $q ->where(fn ($q) => $q ->whereNull("{$tableAlias}idade_minima") ->orWhere("{$tableAlias}idade_minima", '<=', $idade['anos']) ) ->where(fn ($q) => $q ->whereNull("{$tableAlias}idade_maxima") ->orWhere("{$tableAlias}idade_maxima", '>=', $idade['anos']) ) ) ->where(fn ($q) => $q ->whereNull("{$tableAlias}sexo_id") ->orWhere("{$tableAlias}sexo_id", $paciente->cidadao->sexo_id) ) ); } private static function getServicos() { return Servico::orderBy('nome') ->whereHas('parametrizacoesInfraestrutura', fn ($q) => $q ->where('infraestrutura_id', self::getCurrentCentroCusto()->infraestrutura_id) ) ->get(['id', 'nome', 'tipo_id']); } private static function getCentrosCustoEncaminhamento($centroCustoId = null) { if (is_null($centroCustoId)) { return Encaminhamento::where('centro_custo_id_de', self::getCurrentCentroCusto()->id) ->whereHas('centroCustoPara', fn ($q) => $q ->whereHas('setor', fn ($q) => $q ->whereIn('tipo_id', [ SetorTIpo::ENFERMAGEM, SetorTipo::CONSULTORIO ]) ) ) ->get() ->map(fn ($encaminhamento) => [ 'id' => $encaminhamento->centroCustoPara->id, 'setor_nome' => $encaminhamento->centroCustoPara->setor->nome, ]); } return CentroCusto::where('id', $centroCustoId) ->get() ->map(fn ($centroCusto) => [ 'id' => $centroCusto->id, 'setor_nome' => $centroCusto->setor->nome, ]); } private static function getModelData($fila = null, $atendimento = null) { $isDemandaEspontanea = $atendimento->is_demanda_espontanea ?? false; return [ 'paciente' => is_null($atendimento) ? null : Paciente::with([ 'cidadao', 'cidadao.etniaIndigena', 'cidadao.nacionalidade', 'cidadao.racaCor', 'cidadao.sexo', 'classificacao', 'unidade', ])->where('id', $atendimento->paciente->id)->first(), 'opcao_entrada_id' => $fila->opcao_entrada_id ?? null, 'prioridade_id' => $fila->prioridade_id ?? null, 'demanda_tipo' => $atendimento->demanda_tipo ?? null, 'agendamento_id' => $atendimento->agendamento_id ?? null, 'usuario_id' => $isDemandaEspontanea ? ($atendimento->usuario->id ?? null) : null, 'ocupacao_id' => $isDemandaEspontanea ? ($atendimento->ocupacao->id ?? null) : null, 'especialidade_id' => $isDemandaEspontanea ? ($atendimento->especialidade->id ?? null) : null, 'jornada_id' => $isDemandaEspontanea ? ($atendimento->jornada->id ?? null) : null, 'servicos' => ($atendimento->servicos ?? collect())->pluck('id'), 'centro_custo_encaminhamento_id' => $atendimento->fila->centro_custo_id ?? null, ]; } public static function store() { self::validateStore(); $atendimento = new Atendimento(); DB::transaction(function () use ($atendimento) { if (!is_null(request()->paciente['telefone_principal']['id'])) { CidadaoTelefone::find(request()->paciente['telefone_principal']['id']) ->update(request()->paciente['telefone_principal']); } $fila = Fila::find(request()->fila_id); $demandaEspontaneaId = null; if (is_null($fila)) { $fila = FilaService::store((object) array_merge( request()->only(['paciente_id', 'opcao_entrada_id', 'prioridade_id']), ['centro_custo_id' => self::getCurrentCentroCusto()->id] )); } else { $fila->update(request()->only('paciente_id')); } if (is_null(request()->agendamento_id)) { $demandaEspontaneaId = DemandaEspontanea::create(array_merge( request()->only(['paciente_id', 'ocupacao_id', 'especialidade_id', 'usuario_id', 'jornada_id']), ['data' => Carbon::today()] ))->id; } $atendimento->fill([ 'atendimento_tipo_id' => request()->atendimento_tipo_id, 'fila_id' => $fila->id, 'paciente_id' => request()->paciente_id, 'agendamento_id' => request()->agendamento_id, 'demanda_espontanea_id' => $demandaEspontaneaId, ]); $atendimento->save(); $atendimento->servicos()->sync(request()->servicos); FilaService::forward($fila->id, request()->centro_custo_encaminhamento_id); }); return $atendimento->fresh(); } private static function validateStore() { $demandaEspontaneaObservaVagaAtendimento = self::demandaEspontaneaObservaVagaAtendimento(); $validations = [ 'paciente.telefone_principal.id' => [ 'nullable', 'integer', Rule::exists(CidadaoTelefone::class, 'id'), ], 'paciente.telefone_principal.numero' => [ 'nullable', 'required_with:paciente.telefone_principal.id', 'digits_between:10,11', ], 'paciente.telefone_principal.autoriza_sms' => [ 'nullable', 'required_with:paciente.telefone_principal.id', 'boolean', ], 'atendimento_tipo_id' => [ 'required', 'integer', Rule::exists(TipoAtendimento::class, 'id'), ], 'fila_id' => [ 'nullable', 'integer', Rule::exists(Fila::class, 'id'), ], 'paciente_id' => [ 'required', 'integer', Rule::exists(Paciente::class, 'id'), ], 'opcao_entrada_id' => [ 'required', 'integer', Rule::exists(OpcaoEntrada::class, 'id'), ], 'prioridade_id' => [ 'nullable', Rule::requiredIf(fn () => OpcaoEntrada::find(request()->opcao_entrada_id) ->prioridade_obrigatoria ?? false ), Rule::exists(Prioridade::class, 'id'), ], 'agendamento_id' => [ 'nullable', 'integer', Rule::exists(Agendamento::class, 'id'), ], 'usuario_id' => [ 'nullable', 'required_with:ocupacao_id', 'integer', Rule::exists(Usuario::class, 'id'), ], 'ocupacao_id' => [ 'nullable', 'required_with:especialidade_id', 'integer', Rule::exists(Ocupacao::class, 'id'), ], 'especialidade_id' => [ 'nullable', 'integer', Rule::exists(Especialidade::class, 'id'), ], 'servicos' => [ 'present', 'array' ], 'servicos.*' => [ 'required', 'integer', Rule::exists(Servico::class, 'id'), ], 'centro_custo_encaminhamento_id' => [ 'required', 'integer', Rule::in(self::getCentrosCustoEncaminhamento()->pluck('id')), ], ]; if ($demandaEspontaneaObservaVagaAtendimento) { $validations['jornada_id'] = [ 'required', 'integer', Rule::exists(Jornada::class, 'id'), ]; } request()->validate($validations); } public static function update($atendimentoId) { $atendimento = Atendimento::findOrFail($atendimentoId); self::validateUpdate($atendimento); DB::transaction(function () use ($atendimento) { $atendimento->fila()->update(request()->only(['prioridade_id'])); if ($atendimento->is_demanda_espontanea) { $atendimento->demandaEspontanea()->update( request()->only(['ocupacao_id', 'especialidade_id', 'usuario_id']) ); } $atendimento->servicos()->sync(request()->servicos); FilaService::dispatch($atendimento->fila->centro_custo_id); }); return $atendimento->fresh(); } private static function validateUpdate($atendimento) { request()->validate([ 'prioridade_id' => [ 'nullable', Rule::requiredIf(fn () => $atendimento->fila->opcaoEntrada->prioridade_obrigatoria), Rule::exists(Prioridade::class, 'id'), ], 'usuario_id' => [ 'nullable', 'required_with:ocupacao_id', 'integer', Rule::exists(Usuario::class, 'id'), ], 'ocupacao_id' => [ 'nullable', 'required_with:especialidade_id', 'integer', Rule::exists(Ocupacao::class, 'id'), ], 'especialidade_id' => [ 'nullable', 'integer', Rule::exists(Especialidade::class, 'id'), ], 'servicos' => [ 'present', 'array' ], 'servicos.*' => [ 'required', 'integer', Rule::exists(Servico::class, 'id'), ], ]); } public static function destroy($atendimentoId) { $atendimento = Atendimento::findOrFail($atendimentoId); DB::transaction(function () use ($atendimento) { $demandaEspontaneaId = $atendimento->demanda_espontanea_id; $centroCustoAtualId = $atendimento->fila->centro_custo_id; $firstItemHistorico = $atendimento->fila->historico() ->orderBy('id') ->first(['centro_custo_id', 'status_id']); $atendimento->fila()->update([ 'centro_custo_id' => $firstItemHistorico->centro_custo_id, 'status_id' => $firstItemHistorico->status_id, 'paciente_id' => null, ]); $atendimento->delete(); if (!is_null($demandaEspontaneaId)) { DemandaEspontanea::destroy($demandaEspontaneaId); } FilaService::dispatch($centroCustoAtualId); FilaService::dispatch($firstItemHistorico->centro_custo_id); }); } private static function getPermissoesAtualizacaoCadastroPaciente() { $parametrizacao = CnsService::getParametrizacao(); if (!is_null($parametrizacao)) { $lotacao = self::getCurrentLotacao(); return DB::table('cadastro_parametrizacao_permissao_usuario') ->select([ 'municipe', 'provisorio', 'outro_municipio', ]) ->where('infraestrutura_id', $lotacao->infraestrutura_id) ->where('usuario_id', $lotacao->usuario_id) ->get() ->first(); } return null; } private static function getStatusLiberamHorario() { return [ AgendamentoStatus::REAGENDADO_PELO_PACIENTE, AgendamentoStatus::REAGENDADO_PELO_MEDICO, AgendamentoStatus::CANCELADO_PELO_PACIENTE, AgendamentoStatus::CANCELADO_PELO_MEDICO, ]; } private static function demandaEspontaneaObservaVagaAtendimento() { $response = false; if (isset(request()->especialidade_id)) { $currentCentroCusto = self::getCurrentCentroCusto(); $response = ParametrizacaoInfraestruturaEspecialidade::where('especialidade_id', request()->especialidade_id) ->whereHas('parametrizacaoInfraestrutura', fn ($q) => $q->where('infraestrutura_id', $currentCentroCusto->infraestrutura_id)) ->first()->demanda_espontanea_observa_vaga_atendimento ?? false; } return $response; } }