centro_custo_id); $servicos = self::getFormServicos($centroCusto); return [ 'additionals' => [ 'data_atual' => Carbon::today()->format('d/m/Y'), 'permite_atendimento_enfermagem' => self::permiteAtendimentoEnfermagem($centroCusto), ], 'form' => [ 'classificacoes_risco' => ClassificacaoRisco::orderBy('nome') ->get(['id', 'nome']) ->map(fn ($classificacaoRisco) => [ 'id' => $classificacaoRisco->id, 'nome' => Str::upper($classificacaoRisco->nome), ]), 'opcoes_entrada' => OpcaoEntrada::where('modulo_id', ModuloService::getId(Modulo::AMBULATORIO)) ->whereHas('centroCusto', function($query) use ($centroCusto) { $query->where('infraestrutura_id', $centroCusto->infraestrutura_id); }) ->whereExists(function($query) { $query->select(DB::raw(1)) ->from('ambulatorio_atendimento') ->join('painel_senha_fila', 'painel_senha_fila.id', 'ambulatorio_atendimento.fila_id') ->whereNull('ambulatorio_atendimento.finalizado_em') ->whereColumn('painel_senha_fila.opcao_entrada_id', 'painel_senha_opcao_entrada.id'); }) ->orderBy('nome') ->get(['id', 'nome']), 'prioridades' => Prioridade::orderBy('nome') ->get(['id', 'nome']), 'salas' => Sala::orderBy('nome') ->where('centro_custo_id', request()->centro_custo_id) ->get(['id', 'nome']), 'status' => DB::table('painel_senha_status') ->select([ 'id', 'nome', ]) ->orderBy('nome') ->get(), 'telas' => Tela::orderBy('nome') ->whereHas('opcoesChamada', fn ($q) => $q ->where('centro_custo_id', request()->centro_custo_id) ) ->get(['id', 'nome']), 'tempos_espera' => TempoEspera::orderBy('tempo') ->whereHas('infraestrutura.centrosCusto', fn ($q) => $q ->where('id', request()->centro_custo_id) ) ->get(['id', 'tempo']) ->map(fn ($tempoEspera) => [ 'id' => $tempoEspera->id, 'minutos' => $tempoEspera->minutos, ]), 'ordenacoes' => collect([ ['value' => 'dataHoraAgendamento', 'text' => 'Data/hora de agendamento'], ['value' => 'dataHoraChegada', 'text' => 'Data/hora de chegada'], ]), 'servicos' => $servicos, 'cria_ficha_atencao_basica_atendimento_domiciliar' => self::criaFicha('atendimento-domiciliar'), 'centros_custo_encaminhamento' => self::getCentrosCustoEncaminhamento(), ], 'model' => [ 'data' => Carbon::today()->format('d/m/Y'), 'classificacao_risco_id' => null, 'opcao_entrada_id' => null, 'prioridade_id' => null, 'status_id' => Status::EM_ESPERA, 'tempo_espera_id' => null, 'ordenacao' => 'dataHoraAgendamento', 'servicos' => $servicos->pluck('id'), 'fila' => self::index((object) request()->all()), ], ]; } private static function permiteAtendimentoEnfermagem($centroCusto) { $parametrizacaoOcupacao = DB::table('ambulatorio_parametrizacao_infraestrutura_ocupacao as parametrizacao_infraestrutura_ocupacao') ->join( 'ambulatorio_parametrizacao_infraestrutura as parametrizacao_infraestrutura', 'parametrizacao_infraestrutura.id', 'parametrizacao_infraestrutura_ocupacao.parametrizacao_infraestrutura_id' ) ->where('parametrizacao_infraestrutura.infraestrutura_id', $centroCusto->infraestrutura_id) ->where('parametrizacao_infraestrutura_ocupacao.ocupacao_id', self::getCurrentLotacao()->ocupacao_id) ->select('parametrizacao_infraestrutura_ocupacao.permite_atendimento_enfermagem') ->first(); if ($parametrizacaoOcupacao) { return (bool) $parametrizacaoOcupacao->permite_atendimento_enfermagem; } return false; } private static function getFormServicos($centroCusto) { return DB::table('ambulatorio_servico as servico') ->join( 'ambulatorio_parametrizacao_infraestrutura_servico as parametrizacao_servico', 'parametrizacao_servico.servico_id', 'servico.id' ) ->join( 'ambulatorio_parametrizacao_infraestrutura as parametrizacao_infraestrutura', 'parametrizacao_infraestrutura.id', 'parametrizacao_servico.parametrizacao_infraestrutura_id' ) ->where('parametrizacao_infraestrutura.infraestrutura_id', $centroCusto->infraestrutura_id) ->select( 'servico.id', 'servico.nome' ) ->orderBy('servico.nome') ->get(); } public static function index($params) { $parametrizacao = Parametrizacao::first(); $quantidadeDias = $parametrizacao->cadastro_paciente_desatualizado_quantidade_dias ?? 0; $filas = DB::table('painel_senha_fila as fila') ->join( 'cadastro_centro_custo AS centro_custo', 'centro_custo.id', 'fila.centro_custo_id' ) ->join( 'cadastro_setor AS setor', 'setor.id', 'centro_custo.setor_id' ) ->join( 'painel_senha_opcao_entrada as opcao_entrada', 'opcao_entrada.id', 'fila.opcao_entrada_id' ) ->join( 'painel_senha_status as fila_status', 'fila_status.id', 'fila.status_id' ) ->leftJoin( 'painel_senha_prioridade as prioridade', 'prioridade.id', 'fila.prioridade_id' ) ->leftJoin( 'ambulatorio_atendimento as atendimento', 'atendimento.fila_id', 'fila.id' ) ->leftJoin('ambulatorio_atendimento_soap as soap_rascunho', fn ($j) => $j ->on('soap_rascunho.atendimento_id', 'atendimento.id') ->where('soap_rascunho.is_rascunho', true) ) ->leftJoin( 'cadastro_lotacao as soap_rascunho_lotacao', 'soap_rascunho_lotacao.id', 'soap_rascunho.created_lotacao_id' ) ->leftJoin( 'ambulatorio_agendamento as agendamento', 'agendamento.id', 'atendimento.agendamento_id' ) ->leftJoin( 'ambulatorio_jornada as jornada', 'jornada.id', 'agendamento.jornada_id' ) ->leftJoin( 'cadastro_lotacao as jornada_lotacao', 'jornada_lotacao.id', 'jornada.lotacao_id' ) ->leftJoin( 'ambulatorio_demanda_espontanea as demanda_espontanea', 'demanda_espontanea.id', 'atendimento.demanda_espontanea_id' ) ->leftJoin( 'cadastro_paciente as paciente', 'paciente.id', DB::raw("COALESCE(demanda_espontanea.paciente_id, agendamento.paciente_id)") ) ->leftJoin( 'cadastro_cidadao as paciente_cidadao', 'paciente_cidadao.id', 'paciente.cidadao_id' ) ->leftJoinSub( DB::table('atencao_basica_avaliacao') ->select('paciente_id', DB::raw('MAX(id) as id')) ->groupBy('paciente_id'), 'avaliacao', 'avaliacao.paciente_id', 'paciente.id' ) ->leftJoin( 'cadastro_usuario as usuario', 'usuario.id', DB::raw("COALESCE(atendimento.responsavel_atual_usuario_id, demanda_espontanea.usuario_id, jornada_lotacao.usuario_id)") ) ->leftJoin( 'cadastro_cidadao as usuario_cidadao', 'usuario_cidadao.id', 'usuario.cidadao_id' ) ->leftJoin( 'cadastro_especialidade as especialidade', 'especialidade.id', DB::raw("COALESCE(atendimento.responsavel_atual_especialidade_id, demanda_espontanea.especialidade_id, jornada.especialidade_id)") ) ->leftJoin( 'sigtap.ocupacao as ocupacao', 'ocupacao.id', DB::raw("COALESCE(atendimento.responsavel_atual_ocupacao_id, demanda_espontanea.ocupacao_id, jornada_lotacao.ocupacao_id)") ) ->leftJoin( 'cadastro_lotacao as responsavel_encaminhamento_atual_lotacao', 'responsavel_encaminhamento_atual_lotacao.id', 'atendimento.responsavel_encaminhamento_atual_lotacao_id' ) ->leftJoin( 'cadastro_usuario as responsavel_encaminhamento_atual_usuario', 'responsavel_encaminhamento_atual_usuario.id', 'responsavel_encaminhamento_atual_lotacao.usuario_id' ) ->leftJoin( 'cadastro_cidadao as responsavel_encaminhamento_atual_usuario_cidadao', 'responsavel_encaminhamento_atual_usuario_cidadao.id', 'responsavel_encaminhamento_atual_usuario.cidadao_id' ) ->leftJoin( 'ambulatorio_atendimento_pre_atendimento as pre_atendimento', 'pre_atendimento.atendimento_id', 'atendimento.id' ) ->leftJoin( 'ambulatorio_classificacao_risco as classificacao_risco', 'classificacao_risco.id', 'pre_atendimento.classificacao_risco_id' ) ->whereNull('fila.deleted_at') ->whereRaw("fila.created_at >= DATE_SUB(CURDATE(), INTERVAL 15 DAY)") ->where('fila.evadido', false) ->where('fila.finalizado', false) ->where('opcao_entrada.modulo_id', ModuloService::getId(Modulo::AMBULATORIO)) ->where('setor.tipo_id', $params->setor_tipo_id) ->where('centro_custo.id', $params->centro_custo_id) ->whereNull('atendimento.finalizado_em') ->select(DB::raw(" fila.id, avaliacao.id as avaliacao_id, DATE_FORMAT(fila.emitido_em, '%d/%m/%Y') as emitido_em, atendimento.id as atendimento_id, fila.senha as numero_senha, CONCAT(opcao_entrada.sigla, fila.senha) as senha, paciente_cidadao.nome as paciente_nome, paciente_cidadao.nome_social as paciente_nome_social, paciente_cidadao.preferencia_nome_id as paciente_preferencia_nome_id, DATE_FORMAT(paciente_cidadao.data_nascimento, '%d/%m/%Y') as paciente_data_nascimento, paciente_cidadao.cpf as paciente_cpf, paciente_cidadao.cns as paciente_cns, paciente_cidadao.nome_mae as paciente_nome_mae, LPAD(paciente.prontuario, 6, '0') as paciente_prontuario, paciente.id as paciente_id, usuario.id as usuario_id, usuario_cidadao.nome as usuario_nome, ocupacao.id as ocupacao_id, ocupacao.codigo as ocupacao_descricao, especialidade.nome as especialidade_nome, agendamento.jornada_id, TIMESTAMP(jornada.data, agendamento.horario) as data_hora_agendamento, fila.created_at as data_hora_chegada, DATE_FORMAT(agendamento.horario, '%H:%i') as horario_agendado, DATE_FORMAT(fila.created_at, '%H:%i') as horario_chegada, classificacao_risco.id as classificacao_risco_id, classificacao_risco.nome as classificacao_risco_nome, opcao_entrada.id as opcao_entrada_id, opcao_entrada.nome as opcao_entrada_nome, prioridade.id as prioridade_id, prioridade.nome as prioridade_nome, prioridade.grau as prioridade_grau, fila_status.id as status_id, CASE WHEN paciente.updated_at IS NULL AND paciente_cidadao.updated_at IS NULL THEN 1 WHEN paciente.updated_at IS NOT NULL AND (paciente_cidadao.updated_at IS NULL OR paciente.updated_at > paciente_cidadao.updated_at) THEN CASE WHEN " . ($quantidadeDias > 0 ? "DATE_ADD(paciente.updated_at, INTERVAL " . $quantidadeDias . " DAY) < NOW()" : "false") . " THEN DATEDIFF(NOW(), DATE_ADD(paciente.updated_at, INTERVAL " . $quantidadeDias . " DAY)) ELSE 0 END WHEN paciente_cidadao.updated_at IS NOT NULL AND (paciente.updated_at IS NULL OR paciente_cidadao.updated_at > paciente.updated_at) THEN CASE WHEN " . ($quantidadeDias > 0 ? "DATE_ADD(paciente_cidadao.updated_at, INTERVAL " . $quantidadeDias . " DAY) < NOW()" : "false") . " THEN DATEDIFF(NOW(), DATE_ADD(paciente_cidadao.updated_at, INTERVAL " . $quantidadeDias . " DAY)) ELSE 0 END ELSE 0 END as dias_cadastro_desatualizado, soap_rascunho_lotacao.usuario_id as soap_rascunho_usuario_id, soap_rascunho_lotacao.ocupacao_id as soap_rascunho_ocupacao_id, IF( pre_atendimento.id IS NOT NULL OR EXISTS ( SELECT 1 FROM ambulatorio_atendimento_soap as soap WHERE soap.atendimento_id = atendimento.id ), 0, 1 ) as allow_pre_atendimento, atendimento.pos_consulta, responsavel_encaminhamento_atual_usuario_cidadao.nome as responsavel_encaminhamento_atual_nome ")) ->addSelect([ 'chamadas' => function ($query) { $query->select(DB::raw("COALESCE(COUNT(chamada.id), 0)")) ->from('painel_senha_chamada AS chamada') ->whereColumn('chamada.fila_id', 'fila.id') ->whereColumn('chamada.status_id', 'fila.status_id'); }, ]) ->get(); $filas->each(function ($fila) { $fila->is_encaminhado = !is_null($fila->responsavel_encaminhamento_atual_nome); $fila->paciente_cpf = MaskUtil::getCpfMasked($fila->paciente_cpf); $fila->paciente_cns = MaskUtil::getCnsMasked($fila->paciente_cns); $fila->paciente_idade = isset($fila->paciente_data_nascimento) ? AgeService::getFormattedAge(Carbon::createFromFormat('d/m/Y', $fila->paciente_data_nascimento)) : null; $fila->tempo_espera = self::getTempoEspera($fila->id); $fila->servicos = self::getServicos($fila->atendimento_id); $fila->allow_pre_atendimento = (bool) $fila->allow_pre_atendimento; $fila->pos_consulta = (bool) $fila->pos_consulta; unset($fila->atendimento_id); }); return $filas; } public static function getTempoEspera($filaId) { $tempoEsperaTotal = DB::table('painel_senha_fila_historico AS historico') ->where('historico.fila_id', $filaId) ->select( 'historico.created_at', 'historico.status_id' ) ->distinct() ->get() ->reduce(function ($count, $historico) use ($filaId) { if ($historico->status_id === Status::EM_ESPERA) { $proximo = DB::table('painel_senha_fila_historico') ->where('fila_id', $filaId) ->where('created_at', '>', $historico->created_at) ->select('created_at') ->first(); return $count + Carbon::create($historico->created_at) ->diffInMinutes($proximo->created_at ?? Carbon::now()); } return $count; }, 1); $centroCustoLogado = self::getCurrentCentroCusto(); $tempoEspera = DB::table('painel_senha_tempo_espera') ->whereNull('deleted_at') ->where('tempo', '<=', $tempoEsperaTotal) ->where('infraestrutura_id', $centroCustoLogado->infraestrutura_id) ->select( 'id', 'cor' ) ->orderByDesc('tempo') ->first(); if (is_null($tempoEspera)) { $tempoEspera = DB::table('painel_senha_tempo_espera') ->whereNull('deleted_at') ->where('tempo', '>=', $tempoEsperaTotal) ->where('infraestrutura_id', $centroCustoLogado->infraestrutura_id) ->select( 'id', 'cor' ) ->orderBy('tempo') ->first(); } $tempoEsperaTotal = Carbon::now() ->subMinutes($tempoEsperaTotal) ->diff(Carbon::now()); return [ 'id' => $tempoEspera->id ?? null, 'cor' => $tempoEspera->cor ?? null, 'total' => [ 'dias' => (int) $tempoEsperaTotal->format('%d') > 0 ? (int) $tempoEsperaTotal->format('%d') : null, 'horas' => (int) $tempoEsperaTotal->format('%h') ?? null, 'minutos' => (int) $tempoEsperaTotal->format('%i') ?? null, ], ]; } private static function getServicos($atendimentoId) { return DB::table('ambulatorio_atendimento_servico as atendimento_servico') ->join( 'ambulatorio_servico as servico', 'servico.id', 'atendimento_servico.servico_id' ) ->where('atendimento_servico.atendimento_id', $atendimentoId) ->select( 'servico.id', 'servico.nome' ) ->orderBy('servico.nome') ->get(); } public static function store($params) { $centroCusto = CentroCusto::findOrFail($params->centro_custo_id); $senha = ( Fila::where('opcao_entrada_id', $params->opcao_entrada_id) ->whereRaw('emitido_em = CURRENT_DATE') ->max('senha') ?? 0 ) + 1; $emitidoEm = (isset($params->habilita_integracao_aplicativo_feridas) && $params->habilita_integracao_aplicativo_feridas) ? $params->data_jornada->format('Y-m-d') : now(); return Fila::create([ 'paciente_id' => $params->paciente_id, 'centro_custo_id' => $centroCusto->id, 'status_id' => Status::EM_ESPERA, 'opcao_entrada_id' => $params->opcao_entrada_id, 'prioridade_id' => $params->prioridade_id, 'senha' => $senha, 'emitido_em' => $emitidoEm ]); self::dispatch($centroCusto->id); } public static function answer($id) { $fila = Fila::findOrFail($id); $fila->update(['status_id' => Status::EM_ATENDIMENTO]); self::dispatch($fila->centro_custo_id); } public static function forward($id, $centroCustoIdTo) { $fila = Fila::findOrFail($id); $centroCustoIdFrom = $fila->centro_custo_id; $fila->update([ 'centro_custo_id' => $centroCustoIdTo, 'status_id' => Status::EM_ESPERA, ]); self::dispatch($centroCustoIdFrom); self::dispatch($centroCustoIdTo); } public static function sendBack($id) { $fila = Fila::findOrFail($id); $fila->update(['status_id' => Status::EM_ESPERA]); self::dispatch($fila->centro_custo_id); } public static function evade($id) { $fila = Fila::findOrFail($id); self::validateEvade(); $fila->update([ 'evadido' => true, 'motivo_evasao' => request()->motivo, 'motivo_cancelamento_evasao' => null, 'finalizado' => true, ]); if ($fila->ambulatorioAtendimento) { $atendimento = $fila->ambulatorioAtendimento; if ($atendimento->agendamento_id) { $atendimento->agendamento->update([ 'status_id' => AgendamentoStatus::EVADIDO ]); } $atendimento->update([ 'finalizado_em' => Carbon::now(), 'finalizado_lotacao_id' => self::getCurrentLotacao()->id, ]); } self::dispatch($fila->centro_custo_id); } private static function validateEvade() { request()->validate([ 'motivo' => [ 'required', 'string', 'max:500', ], ]); } public static function undoEvade($id) { $fila = Fila::findOrFail($id); self::validateUndoEvade(); if ($fila->evadido) { $fila->update([ 'evadido' => false, 'motivo_evasao' => null, 'motivo_cancelamento_evasao' => request()->motivo, 'finalizado' => false, ]); if ($fila->ambulatorioAtendimento) { $fila->ambulatorioAtendimento->update([ 'finalizado_em' => null, 'finalizado_lotacao_id' => null, ]); if ($fila->ambulatorioAtendimento->agendamento_id) { $fila->ambulatorioAtendimento->agendamento->update([ 'status_id' => AgendamentoStatus::AGENDADO ]); } } self::dispatch($fila->centro_custo_id); } } private static function validateUndoEvade() { request()->validate([ 'motivo' => [ 'required', 'string', 'max:500', ], ]); } public static function destroy($id) { $fila = Fila::findOrFail($id); $centroCustoId = $fila->centro_custo_id; $fila->delete(); self::dispatch($centroCustoId); } public static function dispatch($centroCustoId) { $centroCusto = CentroCusto::findOrFail($centroCustoId); $fila = self::index((object) [ 'centro_custo_id' => $centroCusto->id, 'setor_tipo_id' => $centroCusto->setor->tipo_id, ]); FilaEvent::dispatch( $centroCusto->setor->tipo_id, $centroCusto->id, Modulo::AMBULATORIO, $fila ); } public static function getAgendamentosRetroativos() { $agendamentos = DB::table('ambulatorio_agendamento as agendamento') ->join( 'cadastro_paciente as paciente', 'paciente.id', 'agendamento.paciente_id' ) ->join( 'cadastro_cidadao as paciente_cidadao', 'paciente_cidadao.id', 'paciente.cidadao_id' ) ->join( 'ambulatorio_jornada as jornada', 'jornada.id', 'agendamento.jornada_id' ) ->join( 'cadastro_lotacao as jornada_lotacao', 'jornada_lotacao.id', 'jornada.lotacao_id' ) ->join( 'cadastro_usuario as usuario', 'usuario.id', 'jornada_lotacao.usuario_id' ) ->join( 'cadastro_cidadao as usuario_cidadao', 'usuario_cidadao.id', 'usuario.cidadao_id' ) ->join( 'cadastro_especialidade as especialidade', 'especialidade.id', 'jornada.especialidade_id' ) ->where('agendamento.status_id', AgendamentoStatus::AGENDADO) ->where(fn ($q) => $q ->whereExists(fn ($q) => $q ->selectRaw(1) ->from('ambulatorio_atendimento as atendimento') ->whereColumn('atendimento.agendamento_id', 'agendamento.id') ->whereNull('atendimento.finalizado_em') ) ->orWhereNotExists(fn ($q) => $q ->selectRaw(1) ->from('ambulatorio_atendimento as atendimento') ->whereColumn('atendimento.agendamento_id', 'agendamento.id') ) ) ->whereDate('jornada.data', Carbon::createFromFormat('d/m/Y', request()->data)) ->where('jornada.lotacao_id', self::getCurrentLotacao()->id) ->selectRaw(" agendamento.id, DATE_FORMAT(agendamento.horario, '%H:%i') as horario, paciente_cidadao.nome as paciente_nome, paciente_cidadao.nome_social as paciente_nome_social, paciente_cidadao.preferencia_nome_id as paciente_preferencia_nome_id, DATE_FORMAT(paciente_cidadao.data_nascimento, '%d/%m/%Y') as paciente_data_nascimento, paciente_cidadao.cpf as paciente_cpf, paciente_cidadao.cns as paciente_cns, paciente_cidadao.nome_mae as paciente_nome_mae, LPAD(paciente.prontuario, 6, '0') as paciente_prontuario, especialidade.nome as especialidade_nome ") ->get(); $agendamentos->each(function ($agendamento) { $agendamento->paciente_cpf = MaskUtil::getCpfMasked($agendamento->paciente_cpf); $agendamento->paciente_cns = MaskUtil::getCnsMasked($agendamento->paciente_cns); $agendamento->paciente_idade = isset($agendamento->paciente_data_nascimento) ? AgeService::getFormattedAge(Carbon::createFromFormat('d/m/Y', $agendamento->paciente_data_nascimento)) : null; }); return $agendamentos; } public static function criaFicha($funcionalidadeIdentificador) { $lotacaoLogada = self::getCurrentLotacao(); return ParametrizacaoInfraestruturaOcupacao::whereHas('parametrizacaoInfraestrutura', fn ($q) => $q ->where('infraestrutura_id', $lotacaoLogada->infraestrutura_id) ) ->where('ocupacao_id', $lotacaoLogada->ocupacao_id) ->whereHas('fichasAtb', fn ($q) => $q ->where('funcionalidade_id', Funcionalidade::whereHas('modulo', fn ($q) => $q ->where('identificador', 'atencao-basica') ) ->where('identificador', $funcionalidadeIdentificador) ->first('id')->id ) ) ->exists(); } 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, ]); } }