Files
Antonio Lopes dos Santos afec302c3e
All checks were successful
build-api-image / build (push) Successful in 51s
init commit
2026-08-04 16:52:02 -03:00

1105 lines
46 KiB
PHP

<?php
namespace App\Services\ProntoAtendimento\Fila;
use App\Enums\Administracao\Modulo;
use App\Enums\Cadastro\Estabelecimento\Servico;
use App\Enums\Cadastro\Estabelecimento\SetorTipo;
use App\Enums\Cadastro\UnidadeMedida as UnidadeMedidaEnum;
use App\Enums\PainelSenha\Status;
use App\Enums\Parametrizacao\Exame\Status as ExameStatus;
use App\Enums\Parametrizacao\Exame\Tipo;
use App\Enums\ProntoAtendimento\Atendimento\Desfecho;
use App\Events\PainelSenha\FilaEvent;
use App\Models\Cadastro\Estabelecimento\CentroCusto;
use App\Models\Cadastro\Estabelecimento\Infraestrutura;
use App\Models\Cadastro\Estabelecimento\Sala;
use App\Models\Cadastro\UnidadeMedida;
use App\Models\PainelSenha\Fila;
use App\Models\PainelSenha\Prioridade;
use App\Models\PainelSenha\Tela;
use App\Models\PainelSenha\TempoEspera;
use App\Models\ProntoAtendimento\Atendimento\Atendimento;
use App\Models\ProntoAtendimento\Atendimento\Enfermagem\Historico as HistoricoEnfermagem;
use App\Models\ProntoAtendimento\Atendimento\Medico\AtendimentoMedico;
use App\Models\ProntoAtendimento\Atendimento\PrescricaoInterna;
use App\Models\ProntoAtendimento\Atendimento\ServicoEnfermagem;
use App\Models\ProntoAtendimento\Atendimento\SinalVital;
use App\Models\ProntoAtendimento\ClassificacaoRisco\ClassificacaoRisco;
use App\Models\ProntoAtendimento\Parametrizacao\Parametrizacao;
use App\Services\Administracao\ModuloService;
use App\Services\ProntoAtendimento\Impressao\ImpressaoService;
use App\Services\Service;
use Carbon\Carbon;
use Exception;
use Illuminate\Support\Facades\DB;
class FilaService extends Service
{
public static function list($request)
{
$centroCustoLogado = CentroCusto::findOrFail(auth()->payload()->get('centro_custo_id'));
$infraestrutura = Infraestrutura::findOrFail($centroCustoLogado->infraestrutura_id);
return [
'form' => [
'classificacoes_risco' => ClassificacaoRisco::orderBy('nome')
->get()
->map(function($query) {
return [
'id' => $query->id,
'nome' => mb_strtoupper($query->nome),
];
}),
'opcoes_entrada' => DB::table('painel_senha_opcao_entrada')
->where('modulo_id', ModuloService::getId(Modulo::PRONTO_ATENDIMENTO))
->whereNull('deleted_at')
->select([
'id',
'nome',
])
->whereExists(function($query) {
$query->select(DB::raw(1))
->from('painel_senha_fila')
->join('pronto_atendimento_atendimento', 'pronto_atendimento_atendimento.fila_id', 'painel_senha_fila.id')
->join('pronto_atendimento_faa', 'pronto_atendimento_faa.id', 'pronto_atendimento_atendimento.faa_id')
->whereNull('pronto_atendimento_faa.desfecho_id')
->whereColumn('painel_senha_fila.opcao_entrada_id', 'painel_senha_opcao_entrada.id');
})
->whereExists(function ($query) use ($infraestrutura) {
$query->select(DB::raw(1))
->from('cadastro_centro_custo')
->join('cadastro_infraestrutura', 'cadastro_infraestrutura.id', 'cadastro_centro_custo.infraestrutura_id')
->whereColumn('cadastro_centro_custo.id', 'painel_senha_opcao_entrada.centro_custo_id')
->where('cadastro_infraestrutura.unidade_id', $infraestrutura->unidade_id);
})
->orderBy('nome')
->get(),
'prioridades' => Prioridade::orderBy('nome')
->get()
->map(function($query) {
return [
'id' => $query->id,
'nome' => $query->nome,
];
}),
'salas' => Sala::orderBy('nome')
->where('centro_custo_id', $request->centro_custo_id)
->get()
->map(function($query) {
return [
'id' => $query->id,
'nome' => $query->nome,
];
}),
'status' => DB::table('painel_senha_status')
->select([
'painel_senha_status.id',
'painel_senha_status.nome',
])
->orderBy('painel_senha_status.nome')
->get(),
'telas' => Tela::orderBy('nome')
->whereHas('opcoesChamada', function($query) use ($request) {
$query->where('centro_custo_id', $request->centro_custo_id);
})
->get()
->map(function($query) {
return [
'id' => $query->id,
'nome' => $query->nome,
];
}),
'tempos_espera' => TempoEspera::orderBy('tempo')
->whereHas('infraestrutura.centrosCusto', function ($query) use ($request) {
$query->where('id', $request->centro_custo_id);
})
->get()
->map(function($query) {
return [
'id' => $query->id,
'minutos' => $query->minutos,
];
}),
],
'model' => [
'status_id' => Status::EM_ESPERA,
'fila' => self::index($request),
],
];
}
public static function index($params)
{
$isObservacao = $params['setor_tipo_id'] == SetorTipo::OBSERVACAO;
$isSetorAtualExameImagem = false;
$infraestruturaId = null;
if ($isObservacao) {
$centroCusto = DB::table('cadastro_centro_custo')
->whereNull('deleted_at')
->where('id', $params['centro_custo_id'])
->select('infraestrutura_id', 'setor_id')
->first();
$isSetorAtualExameImagem = DB::table('cadastro_setor')
->whereNull('deleted_at')
->where('id', $centroCusto->setor_id)
->select('tipo_id')
->first()->tipo_id === SetorTipo::EXAMES;
$infraestruturaId = $centroCusto->infraestrutura_id;
}
return 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(
'cadastro_lotacao AS fila_lotacao',
'fila_lotacao.id',
'fila.updated_lotacao_id'
)
->join(
'cadastro_usuario AS fila_lotacao_usuario',
'fila_lotacao_usuario.id',
'fila_lotacao.usuario_id'
)
->join(
'cadastro_cidadao AS fila_lotacao_usuario_cidadao',
'fila_lotacao_usuario_cidadao.id',
'fila_lotacao_usuario.cidadao_id'
)
->join(
'painel_senha_status AS status',
'status.id',
'fila.status_id'
)
->join(
'painel_senha_opcao_entrada AS opcao_entrada',
'opcao_entrada.id',
'fila.opcao_entrada_id'
)
->leftJoin(
'geral_faixa_etaria AS faixa_etaria',
'faixa_etaria.id',
'opcao_entrada.faixa_etaria_id'
)
->leftJoin(
'painel_senha_prioridade AS prioridade',
'prioridade.id',
'fila.prioridade_id'
)
->leftJoin(
'pronto_atendimento_atendimento AS atendimento',
'atendimento.fila_id',
'fila.id'
)
->leftJoin(
'pronto_atendimento_atendimento_recepcao AS recepcao',
'recepcao.atendimento_id',
'atendimento.id'
)
->leftJoin(
'sigtap.ocupacao AS ocupacao',
'ocupacao.id',
'recepcao.ocupacao_id'
)
->leftJoin(
'pronto_atendimento_faa AS faa',
'faa.id',
'atendimento.faa_id'
)
->leftJoin(
'cadastro_paciente AS paciente',
'paciente.id',
'faa.paciente_id'
)
->leftJoin(
'cadastro_cidadao AS cidadao',
'cidadao.id',
'paciente.cidadao_id'
)
->whereNull('fila.deleted_at')
->whereNotNull('faa.id')
->where('fila.evadido', false)
->where('opcao_entrada.modulo_id', ModuloService::getId(Modulo::PRONTO_ATENDIMENTO))
->where('setor.tipo_id', $params['setor_tipo_id'])
->whereNull('faa.desfecho_id')
->where(fn ($q) => $q->whereNull('faa.finalizado')->orWhere('faa.finalizado', false))
->when($isObservacao,
fn ($q) => $q->where('centro_custo.infraestrutura_id', $infraestruturaId),
fn ($q) => $q->where('centro_custo.id', $params['centro_custo_id'])
)
->when($isSetorAtualExameImagem, fn ($q) => $q
->whereExists(fn ($q) => $q
->select(DB::raw(1))
->from('pronto_atendimento_pedido_exame as pedido')
->join('pronto_atendimento_pedido_exame_item as item', 'item.pedido_exame_id', 'pedido.id')
->join('parametrizacao_exame as exame', 'exame.id', 'item.exame_id')
->whereColumn('pedido.atendimento_id', 'atendimento.id')
->where('exame.tipo_id', Tipo::IMAGEM)
->whereIn('item.status_id', [
ExameStatus::SOLICITADO,
ExameStatus::AGUARDANDO_RESULTADO,
])
)
)
->select(
'fila.id',
'fila.created_at',
'fila.opcao_entrada_id',
'fila.prioridade_id',
'fila.status_id',
'fila.senha',
'fila_lotacao_usuario.id AS profissional_atual_id',
'fila_lotacao_usuario_cidadao.nome AS profissional_atual_nome',
'status.nome AS status_nome',
'prioridade.nome AS prioridade_nome',
'opcao_entrada.faixa_etaria_id AS opcao_entrada_faixa_etaria_id',
'opcao_entrada.nome AS opcao_entrada_nome',
'opcao_entrada.sigla AS opcao_entrada_sigla',
DB::raw("COALESCE(faixa_etaria.nome, 'TODOS') AS opcao_entrada_tipo_atendimento"),
'atendimento.id AS atendimento_id',
'faa.desfecho_id AS faa_desfecho_id',
'faa.id AS faa_id',
'recepcao.atendido_em',
'recepcao.urgente',
'recepcao.urgente_motivo',
'recepcao.motivo_atendimento',
'ocupacao.nome AS recepcao_ocupacao_nome',
'paciente.id AS paciente_id',
'paciente.sequencial_desconhecido_em AS paciente_sequencial_desconhecido_em',
'paciente.prontuario AS cidadao_prontuario',
'cidadao.nome AS cidadao_nome',
'cidadao.nome_social AS cidadao_nome_social',
'cidadao.nome_mae AS cidadao_nome_mae',
'cidadao.data_nascimento AS cidadao_data_nascimento',
'cidadao.preferencia_nome_id AS cidadao_preferencia_nome_id',
'cidadao.caracteristicas_fisicas AS cidadao_caracteristicas_fisicas',
'opcao_entrada.prioridade_obrigatoria AS opcao_entrada_prioridade_obrigatoria',
)
->addSelect([
'last_setor_tipo_id' => function ($query) {
$query->select('historico_centro_custo_setor.tipo_id')
->from('painel_senha_fila_historico AS historico')
->join(
'cadastro_centro_custo AS historico_centro_custo',
'historico_centro_custo.id',
'historico.centro_custo_id'
)
->join(
'cadastro_setor AS historico_centro_custo_setor',
'historico_centro_custo_setor.id',
'historico_centro_custo.setor_id'
)
->whereColumn('historico.fila_id', 'fila.id')
->whereColumn('historico.centro_custo_id', '<>', 'fila.centro_custo_id')
->orderByDesc('historico.created_at')
->limit(1);
},
'chamadas' => function ($query) {
$query->select(DB::raw("COALESCE(COUNT(chamada.id), 0)"))
->from('painel_senha_chamada AS chamada')
->whereColumn('chamada.created_centro_custo_id', 'fila.centro_custo_id')
->whereColumn('chamada.status_id', 'fila.status_id')
->whereColumn('chamada.fila_id', 'fila.id');
},
'classificacao_risco_id' => function ($query) {
$query->select('atendimento_classificacao_risco.classificacao_risco_id')
->from('pronto_atendimento_atendimento_classificacao_risco AS atendimento_classificacao_risco')
->whereColumn('atendimento_classificacao_risco.atendimento_id', 'atendimento.id')
->orderByDesc('atendimento_classificacao_risco.id')
->limit(1);
},
'classificacao_risco_nome' => function ($query) {
$query->select('classificacao_risco.nome')
->from('pronto_atendimento_atendimento_classificacao_risco AS atendimento_classificacao_risco')
->join(
'pronto_atendimento_classificacao_risco AS classificacao_risco',
'classificacao_risco.id',
'atendimento_classificacao_risco.classificacao_risco_id'
)
->whereColumn('atendimento_classificacao_risco.atendimento_id', 'atendimento.id')
->orderByDesc('atendimento_classificacao_risco.id')
->limit(1);
},
'classificacao_risco_tipo_cor' => function ($query) {
$query->select('classificacao_risco_tipo.cor')
->from('pronto_atendimento_atendimento_classificacao_risco AS atendimento_classificacao_risco')
->join(
'pronto_atendimento_classificacao_risco AS classificacao_risco',
'classificacao_risco.id',
'atendimento_classificacao_risco.classificacao_risco_id'
)
->join(
'pronto_atendimento_classificacao_risco_tipo AS classificacao_risco_tipo',
'classificacao_risco_tipo.id',
'classificacao_risco.tipo_id'
)
->whereColumn('atendimento_classificacao_risco.atendimento_id', 'atendimento.id')
->orderByDesc('atendimento_classificacao_risco.id')
->limit(1);
},
'classificacao_risco_tipo_ordem' => function ($query) {
$query->select('classificacao_risco_tipo.ordem')
->from('pronto_atendimento_atendimento_classificacao_risco AS atendimento_classificacao_risco')
->join(
'pronto_atendimento_classificacao_risco AS classificacao_risco',
'classificacao_risco.id',
'atendimento_classificacao_risco.classificacao_risco_id'
)
->join(
'pronto_atendimento_classificacao_risco_tipo AS classificacao_risco_tipo',
'classificacao_risco_tipo.id',
'classificacao_risco.tipo_id'
)
->whereColumn('atendimento_classificacao_risco.atendimento_id', 'atendimento.id')
->orderByDesc('atendimento_classificacao_risco.id')
->limit(1);
},
'atendimento_medico_desfecho_nome' => function ($query) {
$query->select('desfecho.nome')
->from('pronto_atendimento_atendimento_medico AS atendimento_medico')
->join(
'pronto_atendimento_faa_desfecho AS desfecho',
'desfecho.id',
'atendimento_medico.desfecho_id'
)
->whereColumn('atendimento_medico.atendimento_id', 'atendimento.id')
->orderByDesc('atendimento_medico.id')
->limit(1);
},
'atendimento_medico_solicitou_reavaliacao' => function ($query) {
$query->select(DB::raw("COALESCE(IF(atendimento_medico.desfecho_id IS NULL, 1, 0), 0)"))
->from('pronto_atendimento_atendimento_medico AS atendimento_medico')
->whereColumn('atendimento_medico.atendimento_id', 'atendimento.id')
->orderByDesc('atendimento_medico.id')
->limit(1);
},
'atendimento_medico_reavaliacao_profissional_nome' => function ($query) {
$query->select(DB::raw("
IF(atendimento_medico.desfecho_id IS NULL, atendimento_medico_cidadao.nome, NULL)
"))
->from('pronto_atendimento_atendimento_medico AS atendimento_medico')
->join(
'cadastro_lotacao AS atendimento_medico_lotacao',
'atendimento_medico_lotacao.id',
'atendimento_medico.created_lotacao_id'
)
->join(
'cadastro_usuario AS atendimento_medico_usuario',
'atendimento_medico_usuario.id',
'atendimento_medico_lotacao.usuario_id'
)
->join(
'cadastro_cidadao AS atendimento_medico_cidadao',
'atendimento_medico_cidadao.id',
'atendimento_medico_usuario.cidadao_id'
)
->whereColumn('atendimento_medico.atendimento_id', 'atendimento.id')
->orderByDesc('atendimento_medico.id')
->limit(1);
},
'atendimento_medico_data_hora_proxima_reavaliacao' => function ($query) {
$query->select('atendimento_medico.data_hora_proxima_reavaliacao')
->from('pronto_atendimento_atendimento_medico AS atendimento_medico')
->whereColumn('atendimento_medico.atendimento_id', 'atendimento.id')
->orderByDesc('atendimento_medico.id')
->limit(1);
},
'paciente_observacao_created_at' => function ($query) {
$query->select('paciente_observacao.created_at')
->from('pronto_atendimento_paciente_observacao AS paciente_observacao')
->whereColumn('paciente_observacao.atendimento_id', 'atendimento.id')
->orderBy('paciente_observacao.id')
->limit(1);
},
'has_atendimento_medico' => function ($query) {
$query->select(DB::raw("COALESCE(1, 0)"))
->from('pronto_atendimento_atendimento_medico AS atendimento_medico')
->whereColumn('atendimento_medico.atendimento_id', 'atendimento.id')
->limit(1);
},
'has_atendimento_observacao' => function ($query) {
$query->select('painel_senha_fila_historico.id')
->from('painel_senha_fila_historico')
->join('cadastro_centro_custo', 'cadastro_centro_custo.id', 'painel_senha_fila_historico.centro_custo_id')
->join('cadastro_setor', 'cadastro_setor.id', 'cadastro_centro_custo.setor_id')
->where('cadastro_setor.tipo_id', SetorTipo::OBSERVACAO)
->whereColumn('painel_senha_fila_historico.fila_id', 'atendimento.fila_id')
->orderByDesc('painel_senha_fila_historico.id')
->limit(1);
},
])
->orderByDesc('classificacao_risco_tipo_ordem')
->orderByDesc(DB::raw("opcao_entrada_nome = 'ATENDIMENTO PREFERENCIAL'"))
->orderByRaw('ISNULL(fila.prioridade_id), TRUE')
->orderBy('fila.senha')
->orderBy('fila.atualizado_em')
->get()
->map(fn ($fila) => [
'id' => $fila->id,
'last_fila_setor_tipo_id' => $fila->last_setor_tipo_id,
'atendimento' => [
'id' => $fila->atendimento_id,
'faa' => [
'id' => $fila->faa_id,
'desfecho_id' => $fila->faa_desfecho_id,
],
'medico_desfecho_nome' => $fila->atendimento_medico_desfecho_nome,
'classificacao_risco' => [
'id' => $fila->classificacao_risco_id,
'nome' => $fila->classificacao_risco_nome,
'tipo' => [
'cor' => $fila->classificacao_risco_tipo_cor,
'ordem' => $fila->classificacao_risco_tipo_ordem,
],
],
'paciente' => [
'id' => $fila->paciente_id,
'is_desconhecido' => !is_null($fila->paciente_sequencial_desconhecido_em),
'cidadao' => [
'preferencia_nome_id' => $fila->cidadao_preferencia_nome_id,
'nome' => $fila->cidadao_nome,
'nome_social' => $fila->cidadao_nome_social,
'has_idade' => !is_null($fila->cidadao_data_nascimento),
'idade' => self::getIdade($fila->cidadao_data_nascimento),
'prontuario' => $fila->cidadao_prontuario,
'nome_mae' => $fila->cidadao_nome_mae ?? 'Não informado',
'data_nascimento' => is_null($fila->cidadao_data_nascimento)
? 'Não informada'
: (new Carbon($fila->cidadao_data_nascimento))->format('d/m/Y'),
'caracteristicas_fisicas' => $fila->cidadao_caracteristicas_fisicas ?? 'Não informado',
],
],
'recepcao' => [
'atendido_em' => is_null($fila->atendido_em)
? null
: (new Carbon($fila->atendido_em))->format('d/m/Y H:i:s'),
'urgente' => $fila->urgente,
'urgente_motivo' => $fila->urgente_motivo,
'ocupacao' => [
'nome' => $fila->recepcao_ocupacao_nome,
],
'motivo_atendimento' => $fila->motivo_atendimento,
],
'tempo_observacao' => self::getTempoEmObservacao($fila->paciente_observacao_created_at),
'data_hora_proxima_reavaliacao' => is_null($fila->atendimento_medico_data_hora_proxima_reavaliacao)
? null
: (new Carbon($fila->atendimento_medico_data_hora_proxima_reavaliacao))->format('d/m/Y H:i'),
'reavaliacao' => (bool) $fila->atendimento_medico_solicitou_reavaliacao,
'reavaliacao_profissional' => $fila->atendimento_medico_reavaliacao_profissional_nome,
'profissional_atual' => [
'nome' => $fila->profissional_atual_nome
],
'has_atendimento_medico' => (bool) $fila->has_atendimento_medico,
],
'chamadas' => $fila->chamadas,
'created_at' => $fila->created_at,
'destacado' => (new Carbon($fila->created_at))->diffInHours(Carbon::now()) >= 24,
'opcao_entrada' => [
'id' => $fila->opcao_entrada_id,
'nome' => $fila->opcao_entrada_nome,
'tipo_atendimento' => $fila->opcao_entrada_tipo_atendimento,
'faixa_etaria_id' => $fila->opcao_entrada_faixa_etaria_id,
'prioridade_obrigatoria' => $fila->opcao_entrada_prioridade_obrigatoria,
],
'prioridade' => [
'id' => $fila->prioridade_id,
'nome' => $fila->prioridade_nome,
],
'profissional' => [
'id' => $fila->profissional_atual_id,
'nome' => $fila->profissional_atual_nome,
],
'senha' => $fila->opcao_entrada_sigla . $fila->senha,
'status' => [
'id' => $fila->status_id,
'nome' => $fila->status_nome,
],
'tempo_espera' => self::getTempoEspera($fila->id),
'has_atendimento_observacao' => !!$fila->has_atendimento_observacao,
])
->filter(fn ($fila) => count($fila) > 0)
->values();
}
public static function update($request, $id)
{
return Fila::findOrFail($id)->update($request->all());
}
private static function getIdade($dataNascimento)
{
$idade = ['anos' => null, 'meses' => null, 'dias' => null];
if (!is_null($dataNascimento)) {
$diffIdade = Carbon::now()->diff(Carbon::create($dataNascimento));
$idade['anos'] = $diffIdade->format('%Y');
$idade['meses'] = $diffIdade->format('%m');
$idade['dias'] = $diffIdade->format('%d');
}
return $idade;
}
private static function getTempoEmObservacao($pacienteObservacaoCreatedAt)
{
if (is_null($pacienteObservacaoCreatedAt)) {
return '00:00:00';
}
$pacienteObservacaoCreatedAt = new Carbon($pacienteObservacaoCreatedAt);
$diff = $pacienteObservacaoCreatedAt->diff(Carbon::now());
$msg = '';
if ($diff->d >= 1) {
$timeReach24Hours = $pacienteObservacaoCreatedAt->modify('+24 hours');
$msg = "{$timeReach24Hours->format('H:i:s')}";
}
else {
$msg = "{$diff->format('%H:%I:%S')}";
}
return $msg;
}
private 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);
$tempoEspera = DB::table('painel_senha_tempo_espera')
->where('tempo', '<=', $tempoEsperaTotal)
->select(
'id',
'cor'
)
->orderByDesc('tempo')
->first();
if (is_null($tempoEspera)) {
$tempoEspera = DB::table('painel_senha_tempo_espera')
->where('tempo', '>=', $tempoEsperaTotal)
->select(
'id',
'cor'
)
->orderBy('tempo')
->first();
}
$tempoEsperaTotal = Carbon::now()
->subMinutes($tempoEsperaTotal)
->diff(Carbon::now());
return [
'id' => $tempoEspera->id,
'cor' => $tempoEspera->cor,
'total' => [
'dias' => (int) $tempoEsperaTotal->format('%d') > 0
? (int) $tempoEsperaTotal->format('%d') : null,
'horas' => (int) $tempoEsperaTotal->format('%h') ?? null,
'minutos' => (int) $tempoEsperaTotal->format('%i') ?? null,
],
];
}
public static function getAdditionalEnfermagemData($atendimentoId)
{
$atendimento = Atendimento::findOrFail($atendimentoId);
$ultimoAtendimentoMedico = $atendimento->atendimentosMedico()->orderByDesc('created_at')->first();
return [
'servicos_enfermagem' => self::getServicosEnfermagem($atendimentoId),
'observacoes_enfermagem' => self::getObservacoesEnfermagem($atendimentoId),
'prescricoes_internas' => self::getPrescricoesInternas($atendimentoId),
'exames_laboratoriais' => self::getExamesLaboratoriais($atendimentoId),
'exames_imagem' => self::getExamesImagem($atendimentoId),
'solicitou_reavaliacao' => is_null($ultimoAtendimentoMedico)
? null
: ($ultimoAtendimentoMedico->solicitou_reavaliacao ? 'Sim' : 'Não (Alta médica)'),
'triagem' => $atendimento->atendimentosTriagem()->exists()
? [
'sinais_vitais' => self::getSinaisVitaisTriagem($atendimentoId),
'historicos_enfermagem' => self::getHistoricoEnfermagemTriagem($atendimentoId),
]
: null,
];
}
private static function getServicosEnfermagem($atendimentoId)
{
return ServicoEnfermagem::where(
function ($query) use ($atendimentoId) {
$query->whereHas('atendimentoEnfermagem', function ($query) use ($atendimentoId) {
$query->where('atendimento_id', $atendimentoId);
})
->orWhereHas('atendimentoMedico', function ($query) use ($atendimentoId) {
$query->where('atendimento_id', $atendimentoId);
});
})
->get()
->map(function ($servico) {
return [
'id' => $servico->id,
'procedimento' => [
'codigo' => $servico->procedimento->codigo,
'nome' => $servico->procedimento->nome,
],
'status' => [
'nome' => $servico->status->nome,
],
];
});
}
private static function getPrescricoesInternas($atendimentoId)
{
$medicamentos = collect([]);
PrescricaoInterna::whereHas('atendimentoMedico', function ($query) use ($atendimentoId) {
$query->where('atendimento_id', $atendimentoId);
})->get()->each(function ($prescricaoInterna) use ($medicamentos) {
$prescricaoInterna->medicamentos->each(function ($medicamento) use ($medicamentos) {
$medicamentos->push([
'nome' => $medicamento->medicamento->nome,
'quantidade' => $medicamento->quantidade,
'unidade_medida_sigla' => $medicamento->unidadeMedida->sigla ?? null,
'forma_farmaceutica_nome' => $medicamento->medicamento->formaFarmaceutica->nome ?? null,
'administracao' => $medicamento->administracao,
'aplicacoes' => $medicamento->aplicacoes->map(fn ($aplicacao, $i) => [
'numero' => $i + 1,
'status' => [
'nome' => $aplicacao->status->nome
]
])
]);
});
});
return $medicamentos;
}
private static function getExamesLaboratoriais($atendimentoId)
{
$exames = collect([]);
Atendimento::findOrFail($atendimentoId)->pedidosExames
->each(function ($pedido) use ($exames) {
$pedido->exames
->filter(fn ($exame) => $exame->exame->tipo_id === Tipo::LABORATORIAL)
->each(function ($exame) use ($exames) {
$exames->push([
'exame' => [
'nome' => $exame->exame->nome,
],
'procedimento' => [
'codigo' => $exame->exame->procedimento->codigo,
'nome' => $exame->exame->procedimento->nome,
],
'status' => [
'nome' => $exame->status->nome,
],
]);
});
});
return $exames;
}
private static function getExamesImagem($atendimentoId)
{
$exames = collect([]);
Atendimento::findOrFail($atendimentoId)->pedidosExames
->each(function ($pedido) use ($exames) {
$pedido->exames
->filter(fn ($exame) => $exame->exame->tipo_id === Tipo::IMAGEM)
->each(function ($exame) use ($exames) {
$exames->push([
'exame' => [
'nome' => $exame->exame->nome,
],
'procedimento' => [
'codigo' => $exame->exame->procedimento->codigo,
'nome' => $exame->exame->procedimento->nome,
],
'status' => [
'nome' => $exame->status->nome,
],
]);
});
});
return $exames;
}
private static function getObservacoesEnfermagem($atendimentoId)
{
return AtendimentoMedico::where('atendimento_id', $atendimentoId)
->whereNotNull('observacoes_enfermagem')
->get()
->map(function($query) {
return [
'centro_custo' => [
'setor' => [
'nome' => $query->createdCentroCusto->setor->nome ?? null,
],
],
'lotacao' => [
'ocupacao' => [
'nome' => $query->createdLotacao->ocupacao->nome ?? null,
],
'profissional' => [
'nome' => $query->createdLotacao->usuario->cidadao->nome ?? null,
],
],
'classificacao_risco' => [
'nome' => $query->classificacaoRisco->classificacaoRisco->nome ?? null,
],
'data_hora' => $query->created_at->format('d/m/Y H:i:s'),
'descricao' => $query->observacoes_enfermagem,
];
})
->values();
}
private static function getSinaisVitaisTriagem($atendimentoId)
{
return SinalVital::where(
function ($query) use ($atendimentoId) {
$query->whereHas('atendimentoTriagem', function ($query) use ($atendimentoId) {
$query->where('atendimento_id', $atendimentoId);
});
})
->get()
->map(function ($sinalVital) {
return [
'id' => $sinalVital->id,
'pa' => $sinalVital->pa,
'pa_unidade_medida_sigla' => is_null($sinalVital->pa_unidade_medida_id)
? null
: UnidadeMedida::findOrFail($sinalVital->pa_unidade_medida_id)->sigla,
'glicemia' => $sinalVital->glicemia,
'glicemia_unidade_medida_sigla' => UnidadeMedida::findOrFail(UnidadeMedidaEnum::MILIGRAMAS_POR_DECILITRO)->sigla,
'temperatura' => $sinalVital->temperatura,
'temperatura_unidade_medida_sigla' => UnidadeMedida::findOrFail(UnidadeMedidaEnum::CELSIUS)->sigla,
'pulso' => $sinalVital->pulso,
'pulso_unidade_medida_sigla' => UnidadeMedida::findOrFail(UnidadeMedidaEnum::BATIMENTOS_POR_MINUTO)->sigla,
'respiracao' => $sinalVital->respiracao,
'respiracao_unidade_medida_sigla' => UnidadeMedida::findOrFail(UnidadeMedidaEnum::MOVIMENTOS_POR_MINUTO)->sigla,
'saturacao' => $sinalVital->saturacao,
'saturacao_unidade_medida_sigla' => UnidadeMedida::findOrFail(UnidadeMedidaEnum::PORCENTAGEM)->sigla,
'intensidade_dor' => $sinalVital->intensidade_dor,
'intensidade_dor_unidade_medida_sigla' => UnidadeMedida::findOrFail(UnidadeMedidaEnum::NIVEL_DE_DOR)->sigla,
'cintura' => $sinalVital->cintura,
'cintura_unidade_medida_sigla' => UnidadeMedida::findOrFail(UnidadeMedidaEnum::CENTIMETROS)->sigla,
'lotacao' => [
'ocupacao' => [
'id' => $sinalVital->createdLotacao->ocupacao->id ?? null,
'codigo' => $sinalVital->createdLotacao->ocupacao->codigo ?? null,
'nome' => $sinalVital->createdLotacao->ocupacao->nome ?? null,
],
'profissional' => [
'nome' => $sinalVital->createdLotacao->usuario->cidadao->nome ?? null,
],
],
'centro_custo' => [
'setor' => [
'nome' => $sinalVital->createdCentroCusto->setor->nome ?? null,
],
],
'classificacao_risco' => [
'nome' => $sinalVital->atendimentoTriagem->classificacaoRisco->classificacaoRisco->nome ?? null,
],
'data_hora' => $sinalVital->created_at->format('d/m/Y H:i:s'),
];
});
}
private static function getHistoricoEnfermagemTriagem($atendimentoId)
{
return HistoricoEnfermagem::where(
function ($query) use ($atendimentoId) {
$query->whereHas('atendimentoTriagem', function ($query) use ($atendimentoId) {
$query->where('atendimento_id', $atendimentoId);
});
})
->get()
->map(function ($historico) {
return [
'descricao' => $historico->descricao,
'centro_custo' => [
'setor' => [
'nome' => $historico->createdCentroCusto->setor->nome,
],
],
'lotacao' => [
'ocupacao' => [
'codigo' => $historico->createdLotacao->ocupacao->codigo,
'nome' => $historico->createdLotacao->ocupacao->nome,
],
'profissional' => [
'nome' => $historico->createdLotacao->usuario->cidadao->nome,
],
],
'classificacao_risco' => [
'nome' => $historico->classificacaoRisco->classificacaoRisco->nome ?? null,
],
'data_hora' => $historico->created_at->format('d/m/Y H:i:s'),
];
});
}
public static function getImpressoes($atendimentoId, $setorTipoId)
{
return ImpressaoService::getImpressoes(
$atendimentoId,
[
'faturar_enfermagem' => (Parametrizacao::first()->faturamento_automatico_enfermagem ?? false)
&& $setorTipoId == SetorTipo::ENFERMAGEM
]
);
}
public static function store($request)
{
$centroCustoLogado = CentroCusto::findOrFail(auth()->payload()->get('centro_custo_id'));
$infraestrutura = Infraestrutura::findOrFail($centroCustoLogado->infraestrutura_id);
$centroCusto = CentroCusto::where('infraestrutura_id', $infraestrutura->id)
->whereHas('setor', function($query) {
$query->where('tipo_id', SetorTipo::RECEPCAO);
})
->firstOrFail();
$fila = new Fila();
$tempoEspera = TempoEspera::orderBy('tempo')
->where('infraestrutura_id', $centroCustoLogado->infraestrutura_id)
->first();
$senha = (
$fila->where('opcao_entrada_id', $request['opcao_entrada_id'])
->whereRaw('emitido_em = CURRENT_DATE')
->max('senha') ?? 0
) + 1;
$params = [
'opcao_entrada_id' => $request['opcao_entrada_id'],
'centro_custo_id' => $centroCusto->id,
'prioridade_id' => $request['prioridade_id'] ?? null,
'tempo_espera_id' => $tempoEspera->id ?? null,
'status_id' => Status::EM_ESPERA,
'senha' => $senha,
];
$fila = $fila->create($params);
self::dispatch($centroCusto);
return $fila;
}
public static function show($id)
{
return self::get(Fila::class, $id);
}
public static function destroy($id)
{
$fila = self::show($id);
$centroCusto = CentroCusto::findOrFail($fila->centro_custo_id);
$fila->delete();
self::dispatch($centroCusto);
}
public static function answer($id)
{
$fila = self::show($id);
$fila->update(['status_id' => Status::EM_ATENDIMENTO]);
$centroCusto = CentroCusto::findOrFail($fila->centro_custo_id);
self::dispatch($centroCusto);
return $fila;
}
public static function sendBack($id)
{
$fila = self::show($id);
$fila->update(['status_id' => Status::EM_ESPERA]);
$centroCusto = CentroCusto::findOrFail($fila->centro_custo_id);
self::dispatch($centroCusto);
return $fila;
}
public static function forward($request, $id)
{
$fila = self::show($id);
$centroCustoDe = CentroCusto::findOrFail($fila->centro_custo_id);
$camposParaAtualizar = [
'centro_custo_id' => $request['centro_custo_id_para'],
'status_id' => Status::EM_ESPERA,
'prioridade_id' => $request['prioridade_id'] ?? null,
];
$fila->update($camposParaAtualizar);
$centroCustoPara = CentroCusto::findOrFail($fila->centro_custo_id);
self::dispatch($centroCustoDe);
self::dispatch($centroCustoPara);
return $fila;
}
public static function evade($request, $id)
{
$fila = self::show($id);
$currentLotacao = self::getCurrentLotacao();
$fila->update([
'evadido' => true,
'motivo_evasao' => $request['motivo_evasao'],
]);
$centroCusto = CentroCusto::findOrFail($fila->centro_custo_id);
$atendimento = Atendimento::where('fila_id', $fila->id)->first();
if ($atendimento) {
$atendimento->faa->update([
'desfecho_id' => Desfecho::EVASAO,
'lotacao_id' => $currentLotacao->id,
'usuario_id' => $currentLotacao->usuario_id,
'data_hora_desfecho' => Carbon::now(),
'finalizado' => true,
]);
}
self::dispatch($centroCusto);
return $fila;
}
public static function dispatch($centroCusto, $salaId = null)
{
$centroCustoIds = [];
if ($centroCusto->setor->tipo->id === SetorTipo::OBSERVACAO) {
CentroCusto::where('infraestrutura_id', $centroCusto->infraestrutura_id)
->whereHas('setor', function ($query) {
$query->whereIn('servico_id', [
Servico::CONSULTA_MEDICA,
Servico::ENFERMAGEM,
Servico::EXAME_RAIO_X
]);
})
->get()
->each(function ($cc) use (&$centroCustoIds) {
$centroCustoIds[] = $cc->id;
});
} else {
$centroCustoIds[] = $centroCusto->id;
}
foreach ($centroCustoIds as $ccId) {
$fila = self::index([
'centro_custo_id' => $ccId,
'setor_tipo_id' => $centroCusto->setor->tipo->id,
]);
try {
FilaEvent::dispatch(
$centroCusto->setor->tipo->id,
$ccId,
Modulo::PRONTO_ATENDIMENTO,
$fila,
$salaId
);
} catch (Exception $error) {
// TODO: Gravar exception em um arquivo.
}
}
}
}