Files
rkm-conectasus-ci-sandbox/api/app/Services/ProntoAtendimento/FechamentoFaa/FechamentoFaaService.php
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

1385 lines
53 KiB
PHP

<?php
namespace App\Services\ProntoAtendimento\FechamentoFaa;
use App\Enums\Cadastro\Estabelecimento\Servico;
use App\Enums\Cadastro\Estabelecimento\SetorTipo;
use App\Enums\Cadastro\SujeitoAtencao\FatorRisco as FatorRiscoEnum;
use App\Enums\Cadastro\SujeitoAtencao\Sexo;
use App\Enums\ProntoAtendimento\Atendimento\Desfecho as DesfechoEnum;
use App\Enums\ProntoAtendimento\FaixaEtaria as FaixaEtariaEnum;
use App\Enums\ProntoAtendimento\Plantao\Status;
use App\Models\Cadastro\Estabelecimento\CentroCusto;
use App\Models\Cadastro\Estabelecimento\Unidade;
use App\Models\Cadastro\SujeitoAtencao\Cidadao;
use App\Models\Cadastro\SujeitoAtencao\FatorRisco;
use App\Models\Geral\FaixaEtaria;
use App\Models\ProntoAtendimento\Atendimento\Atendimento;
use App\Models\ProntoAtendimento\Atendimento\ClassificacaoRisco as ProntoAtendimentoAtendimentoClassificacaoRisco;
use App\Models\ProntoAtendimento\Atendimento\Desfecho;
use App\Models\ProntoAtendimento\Atendimento\EncaminhamentoEspecialidade;
use App\Models\ProntoAtendimento\Atendimento\Enfermagem\AtendimentoEnfermagem;
use App\Models\ProntoAtendimento\Atendimento\Faa;
use App\Models\ProntoAtendimento\Atendimento\Medico\AtendimentoMedico;
use App\Models\ProntoAtendimento\Atendimento\Observacao\PacienteObservacao;
use App\Models\ProntoAtendimento\Atendimento\Procedimento;
use App\Models\ProntoAtendimento\Atendimento\Recepcao;
use App\Models\ProntoAtendimento\Atendimento\Triagem\AtendimentoTriagem;
use App\Models\ProntoAtendimento\ClassificacaoRisco\ClassificacaoRisco;
use App\Models\ProntoAtendimento\Parametrizacao\AtendimentoMedico as ParametrizacaoAtendimentoMedico;
use App\Models\ProntoAtendimento\PedidoExame\PedidoExame;
use App\Models\Sigtap\Cid;
use App\Models\Sigtap\Competencia;
use App\Services\Cadastro\SujeitoAtencao\ObitoService;
use App\Services\ProntoAtendimento\DesfechoService;
use App\Services\ProntoAtendimento\PlantaoService;
use App\Services\Service;
use Carbon\Carbon;
use DateTime;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
class FechamentoFaaService extends Service
{
public static function list()
{
return [
'form' => self::getFormData(),
'model' => [
'periodo' => [
'start' => Carbon::now()->format('d/m/Y'),
'end' => Carbon::now()->format('d/m/Y'),
],
'servico_id' => null,
'faixa_etaria_id' => null,
'lotacao_id' => null,
'faa' => null,
],
'additionals' => [
'data_atual' => Carbon::now()->format('d/m/Y')
]
];
}
private static function getProcedimentoPadrao($usuarios)
{
$especialidadesMedica = EncaminhamentoEspecialidade::all()->pluck('ocupacao_id');
$procedimentoParametrizado = null;
foreach ($usuarios->pluck('ocupacao.id') ?? [] as $ocupacaoId) {
if ($especialidadesMedica->contains($ocupacaoId)) {
$procedimentoParametrizado = ParametrizacaoAtendimentoMedico::first() ?? null;
break;
}
}
return [
'id' => $procedimentoParametrizado->procedimentoPadrao->id ?? null,
'codigo' => $procedimentoParametrizado->procedimentoPadrao->codigo ?? null,
'nome' => $procedimentoParametrizado->procedimentoPadrao->nome ?? null,
'has_cid_principal' => $procedimentoParametrizado->procedimentoPadrao->has_cid_principal ?? null,
'idade_maxima' => $procedimentoParametrizado->procedimentoPadrao->idade_maxima ?? null,
'idade_minima' => $procedimentoParametrizado->procedimentoPadrao->idade_minima ?? null,
'quantidade_maxima_execucao' =>
$procedimentoParametrizado->procedimentoPadrao->quantidade_maxima_execucao ?? null,
'sexo' => $procedimentoParametrizado->procedimentoPadrao->sexo ?? null,
'is_parametrizado' => true,
];
}
private static function getPlantoesUsuario($usuarioId)
{
$plantoes = self::getPlantoesBuilder(request())
->select(
'pronto_atendimento_plantao.id',
'pronto_atendimento_plantao.inicio',
DB::raw('
DATE_FORMAT(pronto_atendimento_plantao.inicio, "%d/%m/%Y") as inicio,
DATE_FORMAT(pronto_atendimento_plantao.fim, "%d/%m/%Y") as fim
'),
)
->join('cadastro_usuario', 'cadastro_usuario.id', 'cadastro_lotacao.usuario_id')
->where('cadastro_lotacao.realiza_atendimento', 1)
->where('cadastro_lotacao.usuario_id', $usuarioId);
return $plantoes->get()->map(function ($plantao) {
return [
'id' => $plantao->id,
'inicio' => $plantao->inicio,
'fim' => $plantao->fim,
];
});
}
private static function getPlantoesBuilder($request)
{
$centroCustroLogado = self::getCentroCustoLogado();
$periodo = self::getPeriodoFromRequest($request);
return DB::table('pronto_atendimento_plantao')
->join('cadastro_lotacao', 'cadastro_lotacao.id', 'pronto_atendimento_plantao.lotacao_id')
->where(function ($query) {
$query->where(function ($q) {
$q->whereNull('pronto_atendimento_plantao.deleted_at')
->whereIn('pronto_atendimento_plantao.status_id', [
Status::CONFIRMADO,
Status::COM_ATENDIMENTO_AGENDADO
]);
})
->orWhere(function ($q) {
$q->whereNotNull('pronto_atendimento_plantao.deleted_at')
->whereExists(function ($sub) {
$sub->select(DB::raw(1))
->from('pronto_atendimento_atendimento_procedimento')
->whereColumn(
'pronto_atendimento_atendimento_procedimento.lotacao_id',
'pronto_atendimento_plantao.lotacao_id'
);
});
});
})
->where(function ($query) use ($periodo) {
$query->where('inicio', '<=', $periodo['end'])
->where('fim', '>=', $periodo['start']);
})
->where('cadastro_lotacao.infraestrutura_id', $centroCustroLogado->infraestrutura_id);
}
private static function getStartOfDay($date = null)
{
if (is_null($date)) {
$date = Carbon::now();
}
return $date->hour(0)->minute(0)->second(0);
}
private static function getEndOfDay($date = null)
{
if (is_null($date)) {
$date = Carbon::now();
}
return $date->hour(23)->minute(59)->second(59);
}
public static function index()
{
return [
'form' => self::getFormData(),
'model' => [
'faas' => self::getFaas(),
'servico' => [
'id' => null,
'nome' => null,
],
'usuario' => [
'id' => null,
'nome' => null,
'lotacao_id' => null,
],
'usuario_responsavel' => [
'id' => null,
'nome' => null,
],
'procedimento' => null,
'cid' => null,
'data_realizacao_procedimento' => null,
'quantidade' => 1,
'desfecho_id' => null,
'paciente_liberado' => [
'lotacao_id' => null,
],
'altaMedica' => [
'lotacao_id' => null,
],
'evasao' => [
'motivo' => null,
],
'encaminhamento_hospitalar' => [
'lotacao_id' => null,
'unidade_id' => null,
'unidade_outra' => false,
'medico_hospitalar' => null,
'cid' => null,
'observacoes' => null,
],
'obito' => [
'lotacao_id' => null,
'dataObito' => null,
'horaObito' => null,
'declaracao' => null,
'cid' => null,
'causa' => null,
],
]
];
}
private static function getFormData()
{
$periodo = self::getPeriodoFromRequest(request());
$centroCustroLogado = self::getCentroCustoLogado();
$usuarios = self::getUsuarios(request());
$usuariosMedicosDesfecho = $usuarios->filter(function ($value) {
return $value['is_medico'];
})->values();
$usuariosNaoMedicosDesfecho = $usuarios->filter(function ($value) {
return !$value['is_medico'];
})->values();
return [
'periodo' => [
'start' => $periodo['start']->format('d/m/Y'),
'end' => $periodo['end']->format('d/m/Y'),
],
'data_atual' => Carbon::now()->format('d/m/Y'),
'unidade_logada' => $centroCustroLogado->infraestrutura->unidade->nome_fantasia,
'local_atendimento_logado' => $centroCustroLogado->infraestrutura->nome,
'servicos' => self::getServicos(),
'faixas_etarias' => self::getFaixaEtaria(),
'usuarios' => $usuarios,
'usuarios_desfecho' => $usuariosMedicosDesfecho,
'usuarios_nao_medicos_desfecho' => $usuariosNaoMedicosDesfecho,
'desfechos' => self::getDesfechos(),
'procedimento_padrao' => self::getProcedimentoPadrao($usuarios),
'unidades' => Unidade::all()->map(function ($unidade) {
return [
'id' => $unidade->id,
'nome_fantasia' => $unidade->nome_fantasia,
];
}),
'fatores_risco' => self::getFatoresRisco(),
'fatores_risco_gestante' => self::getFatoresRiscoGestante(),
'sigtap_competencias' => Competencia::orderByDesc('valor')->take(4)->get(),
'classificacoes_risco' => self::getClassificacoesRisco(),
];
}
private static function getClassificacoesRisco()
{
return ClassificacaoRisco::all()->map(function ($query) {
return [
'id' => $query->id,
'nome' => $query->nome,
'cor' => $query->tipo->cor,
'cor_nome' => $query->tipo->cor_nome,
];
});
}
private static function getFaas()
{
$centroCustroLogado = self::getCentroCustoLogado();
$periodo = self::getPeriodoFromRequest(request());
$faas = DB::table('pronto_atendimento_faa')
->select(
DB::raw('
DATE_FORMAT(pronto_atendimento_atendimento_recepcao.atendido_em, "%d/%m/%Y") as data
'),
DB::raw('
DATE_FORMAT(pronto_atendimento_atendimento_recepcao.atendido_em, "%H:%i") as hora
'),
DB::raw('
DATE_FORMAT(cadastro_cidadao.data_nascimento, "%d/%m/%Y") as data_nascimento
'),
DB::raw('TIMESTAMPDIFF(YEAR, cadastro_cidadao.data_nascimento, NOW()) AS idade'),
'pronto_atendimento_faa.reaberto_em',
'cadastro_cidadao.id as cidadao_id',
'cadastro_cidadao.preferencia_nome_id',
'cadastro_cidadao.nome_social',
'cadastro_cidadao.nome',
'cadastro_cidadao.sexo_id',
'cadastro_sexo.descricao AS sexo_nome',
'cadastro_cidadao.fator_risco_outro',
'cadastro_paciente.id as paciente_id',
'cadastro_paciente.sequencial_desconhecido_em',
'pronto_atendimento_faa.id',
'pronto_atendimento_faa.numero',
'pronto_atendimento_faa.lotacao_id',
'pronto_atendimento_faa.usuario_id as usuario_desfecho_id',
'pronto_atendimento_faa.desfecho_id',
'pronto_atendimento_faa_desfecho.nome as desfecho_nome',
'painel_senha_fila.id as fila_id',
DB::raw(
'(
SELECT paap.procedimento_id
FROM pronto_atendimento_atendimento_procedimento paap
WHERE paap.atendimento_id = pronto_atendimento_atendimento.id
AND paap.is_parametrizado = 1
LIMIT 1
) as procedimento_padrao_id'
),
DB::raw(
'(
SELECT sp.codigo
FROM sigtap.procedimento sp
INNER JOIN pronto_atendimento_atendimento_procedimento paap ON paap.procedimento_id = sp.id
WHERE paap.atendimento_id = pronto_atendimento_atendimento.id
AND paap.is_parametrizado = 1
LIMIT 1
) as procedimento_padrao_codigo'
),
DB::raw(
'(
SELECT spc.cid_id
FROM sigtap.procedimento_cid spc
INNER JOIN pronto_atendimento_atendimento_procedimento paap ON paap.procedimento_id = spc.procedimento_id
WHERE paap.atendimento_id = pronto_atendimento_atendimento.id
AND paap.is_parametrizado = 1
LIMIT 1
) as procedimento_padrao_has_cid_principal'
),
DB::raw(
'(
SELECT sp.nome
FROM sigtap.procedimento sp
INNER JOIN pronto_atendimento_atendimento_procedimento paap ON paap.procedimento_id = sp.id
WHERE paap.atendimento_id = pronto_atendimento_atendimento.id
AND paap.is_parametrizado = 1
LIMIT 1
) as procedimento_padrao_nome'
),
DB::raw(
'(
SELECT sc.id
FROM sigtap.cid sc
INNER JOIN pronto_atendimento_atendimento_procedimento paap ON paap.cid_principal_id = sc.id
WHERE paap.atendimento_id = pronto_atendimento_atendimento.id
AND paap.is_parametrizado = 1
LIMIT 1
) as cid_id'
),
DB::raw(
'(
SELECT sc.codigo
FROM sigtap.cid sc
INNER JOIN pronto_atendimento_atendimento_procedimento paap ON paap.cid_principal_id = sc.id
WHERE paap.atendimento_id = pronto_atendimento_atendimento.id
AND paap.is_parametrizado = 1
LIMIT 1
) as cid_codigo'
),
DB::raw(
'(
SELECT sc.nome
FROM sigtap.cid sc
INNER JOIN pronto_atendimento_atendimento_procedimento paap ON paap.cid_principal_id = sc.id
WHERE paap.atendimento_id = pronto_atendimento_atendimento.id
AND paap.is_parametrizado = 1
LIMIT 1
) as cid_nome'
),
DB::raw("
(SELECT class_risco.id
FROM pronto_atendimento_atendimento_classificacao_risco AS class_risco_atend
INNER JOIN pronto_atendimento_classificacao_risco AS class_risco
ON class_risco.id = class_risco_atend.classificacao_risco_id
WHERE class_risco_atend.atendimento_id = pronto_atendimento_atendimento.id
ORDER BY class_risco_atend.created_at desc
LIMIT 1) AS classificacao_risco_id
"),
'pronto_atendimento_atendimento.id as atendimento_id',
)
->join(
'cadastro_paciente',
'cadastro_paciente.id',
'pronto_atendimento_faa.paciente_id'
)
->join(
'cadastro_cidadao',
'cadastro_cidadao.id',
'cadastro_paciente.cidadao_id'
)
->join(
'cadastro_sexo',
'cadastro_sexo.id',
'cadastro_cidadao.sexo_id'
)
->join(
'pronto_atendimento_atendimento',
'pronto_atendimento_atendimento.faa_id',
'pronto_atendimento_faa.id'
)
->join(
'cadastro_lotacao',
'cadastro_lotacao.id',
'pronto_atendimento_faa.created_lotacao_id'
)
->join(
'pronto_atendimento_atendimento_recepcao',
'pronto_atendimento_atendimento_recepcao.atendimento_id',
'pronto_atendimento_atendimento.id'
)
->leftJoin(
'pronto_atendimento_faa_desfecho',
'pronto_atendimento_faa_desfecho.id',
'pronto_atendimento_faa.desfecho_id'
)
->leftJoin(
'cadastro_paciente_classificacao',
'cadastro_paciente_classificacao.id',
'cadastro_paciente.classificacao_id'
)
->leftJoin(
'painel_senha_fila',
'painel_senha_fila.id',
'pronto_atendimento_atendimento.fila_id'
)
->leftJoin(
'painel_senha_opcao_entrada',
'painel_senha_opcao_entrada.id',
'painel_senha_fila.opcao_entrada_id'
)
->where('pronto_atendimento_faa.finalizado', 0)
->where('pronto_atendimento_faa.cancelado', 0)
->whereNull('pronto_atendimento_faa.deleted_at')
->where('cadastro_lotacao.infraestrutura_id', $centroCustroLogado->infraestrutura_id)
->when(
request()->faixa_etaria_id,
fn ($query, $id) => $query->where('painel_senha_opcao_entrada.faixa_etaria_id', $id)
)
->when(
request()->servico_id,
fn ($query, $id) => $query->where('pronto_atendimento_atendimento_recepcao.servico_id', $id)
);
if (is_numeric(request()->get('faa_id'))) {
$faas->where('pronto_atendimento_faa.numero', request()->get('faa_id'));
} else {
if (is_numeric(request()->get('usuario_id'))) {
$faas->where(function ($query) {
$query->where(function ($query) {
$query->whereExists(
self::getExistsAndHasPlantao('pronto_atendimento_atendimento_triagem')
);
})
->orWhere(function ($query) {
$query->whereExists(
self::getExistsAndHasPlantao('pronto_atendimento_atendimento_medico')
);
})
->orWhere(function ($query) {
$query->whereExists(
self::getExistsAndHasPlantao('pronto_atendimento_atendimento_enfermagem')
);
})
->orWhere(function ($query) {
$query->whereExists(
self::getExistsAndHasPlantao('pronto_atendimento_pedido_exame')
);
})
->orWhere(function ($query) {
$query->whereExists(
self::getExistsAndHasPlantao('pronto_atendimento_paciente_observacao')
);
});
});
}
$faas->whereBetween(
'pronto_atendimento_atendimento_recepcao.atendido_em',
[$periodo['start'], $periodo['end']]
);
}
$fatoresRisco = self::getCidadaoFatoresRisco($faas);
return $faas->get()->map(function ($faa) use($fatoresRisco) {
$atendimento = Atendimento::where('faa_id', $faa->id)->with(['atendimentosMedico', 'fila', 'fila.centroCusto.setor'])->get()->last();
$atendimentosMedico = $atendimento->atendimentosMedico;
$fila = $atendimento->fila;
$firstSetorTipoId = self::getPrimeroSetorTipoIdEncaminhado($fila);
$firstAtendimento = self::getFirstAtendimento($atendimento, $firstSetorTipoId);
$dadosDesfecho = self::getDadosDesfecho($faa, $atendimentosMedico);
$fila = $atendimento->fila;
$setorEncontradoNaTriagem = false;
$setorAtual = null;
if ($fila && isset($fila->centroCusto)) {
$setor = $fila->centroCusto->setor;
if (isset($setor)) {
$setorAtual = $setor->nome;
$setorEncontradoNaTriagem = $setor->tipo_id === SetorTipo::TRIAGEM;
}
}
$previousDesfechoExtraviada = $dadosDesfecho['desfecho']['is_faa_extraviada'];
$procedimentoPadraoFaa = self::getProcedimentoPadraoFaa($faa, $firstAtendimento);
$exibirFatorRiscoGestante = $faa->sexo_id === Sexo::FEMININO && $faa->idade && $faa->idade >= 9 && $faa->idade <= 60;
return [
'atendimento_id' => $atendimento->id,
'data' => $faa->data,
'hora' => $faa->hora,
'data_nascimento' => $faa->data_nascimento,
'exibirFatorRiscoGestante' => $exibirFatorRiscoGestante,
'idade' => $faa->idade,
'id' => $faa->id,
'numero' => $faa->numero,
'sexo_id' => $faa->sexo_id,
'sexo_nome' => $faa->sexo_nome,
'reaberto_em' => $faa->reaberto_em,
'previous_desfecho_extraviada' => $previousDesfechoExtraviada,
'has_desfecho_medico_last_atendimento' => $dadosDesfecho['has_desfecho_medico_last_atendimento'],
'usuario' => self::getUsuarioPrimeiroAtendimento($atendimentosMedico, $firstSetorTipoId, $firstAtendimento),
'usuario_desfecho' => $dadosDesfecho['usuario'],
'procedimento_padrao' => $procedimentoPadraoFaa,
'usuario_procedimento_padrao' => self::getUsuarioProcedimentoPadrao($atendimento, $firstSetorTipoId, $firstAtendimento),
'cid' => [
'is_loaded' => true,
'id' => $faa->cid_id,
'codigo' => $faa->cid_codigo,
'nome' => $faa->cid_nome,
],
'desfecho' => $dadosDesfecho['desfecho'],
'evasao' => self::getEvasao($atendimentosMedico, $fila),
'encaminhamento_hospitalar' => self::getEncaminhamentoHospitalar($faa, $atendimento, $atendimentosMedico),
'obito' => self::getObito($faa, $atendimentosMedico),
'fatores_risco' => isset($fatoresRisco[$faa->cidadao_id]) ? $fatoresRisco[$faa->cidadao_id] : [],
'fator_risco_outro' => $faa->fator_risco_outro ?? '',
'paciente' => [
'id' => $faa->paciente_id,
'nome' => $faa->nome,
'nome_social' => $faa->nome_social,
'is_desconhecido' => $faa->sequencial_desconhecido_em != null,
'preferencia_nome_id' => $faa->preferencia_nome_id,
],
'classificacao_risco_id' => $faa->classificacao_risco_id,
'setor_esta_na_triagem' => $setorEncontradoNaTriagem,
'setor' => $setorAtual
];
});
}
private static function getDadosDesfecho($faa, $atendimentosMedico)
{
if (is_null($faa->desfecho_id)) {
if ($atendimentosMedico->isNotEmpty()) {
$lastAtendimento = $atendimentosMedico->last();
if ($lastAtendimento->desfecho) {
return [
'has_desfecho_medico_last_atendimento' => true,
'desfecho' => [
'id' => $lastAtendimento->desfecho->id,
'nome' => $lastAtendimento->desfecho->nome,
'is_faa_extraviada' => false,
],
'usuario' => [
'id' => $lastAtendimento->createdLotacao->usuario_id,
'lotacao_id' => $lastAtendimento->createdLotacao->id,
]
];
}
}
}
$isFaaExtraviada = $faa->desfecho_id == DesfechoEnum::FAA_EXTRAVIADA;
return [
'has_desfecho_medico_last_atendimento' => false,
'desfecho' => [
'id' => $isFaaExtraviada ? null : $faa->desfecho_id,
'nome' => $faa->desfecho_nome,
'is_faa_extraviada' => $isFaaExtraviada,
],
'usuario' => [
'id' => $faa->usuario_desfecho_id,
'lotacao_id' => $faa->lotacao_id,
]
];
}
private static function getUsuarioPrimeiroAtendimento($atendimentosMedico, $firstSetorTipoId, $firstAtendimento)
{
if (!in_array($firstSetorTipoId, [SetorTipo::ENFERMAGEM, SetorTipo::EXAMES])) {
$firstAtendimento = $atendimentosMedico->first();
}
return [
'id' => $firstAtendimento->createdLotacao->usuario->id ?? null,
'nome' => $firstAtendimento
? "{$firstAtendimento->createdLotacao->usuario->nome} - {$firstAtendimento->createdLotacao->ocupacao->nome}"
: null,
'lotacao_id' => $firstAtendimento->createdLotacao->id ?? null,
'is_loaded' => ($firstAtendimento->createdLotacao->usuario->id ?? null) != null
];
}
private static function getProcedimentoPadraoFaa($faa, $firstAtendimento)
{
$procedimento = $firstAtendimento ? $firstAtendimento->procedimentos->first(): null;
if (!is_null($procedimento)) {
return [
'is_loaded' => $procedimento->id ? true : false,
'id' => $procedimento->id,
'codigo' => $procedimento->procedimento->codigo,
'nome' => $procedimento->procedimento->nome,
'has_cid_principal' => !is_null($procedimento->procedimento->has_cid_principal)
];
}
return [
'is_loaded' => $faa->procedimento_padrao_id ? true : false,
'id' => $faa->procedimento_padrao_id ?? null,
'codigo' => $faa->procedimento_padrao_codigo ?? null,
'nome' => $faa->procedimento_padrao_nome ?? null,
'has_cid_principal' => !is_null($faa->procedimento_padrao_has_cid_principal)
];
}
private static function getUsuarioProcedimentoPadrao($atendimento, $firstSetorTipoId, $firstAtendimento)
{
$procedimento = $firstAtendimento ? $firstAtendimento->procedimentos->first(): null;
if (!in_array($firstSetorTipoId, [SetorTipo::ENFERMAGEM, SetorTipo::EXAMES]) || !isset($procedimento)) {
$procedimento = $atendimento->procedimentos
->where('is_parametrizado', true)
->last();
}
$nomeUsuario = null;
$lotacaoId = null;
$isLoaded = false;
if (!is_null($procedimento)) {
$nomeUsuario = $procedimento->lotacao
? "{$procedimento->lotacao->usuario->nome} - {$procedimento->lotacao->ocupacao->nome}"
: "{$procedimento->createdLotacao->usuario->nome} - {$procedimento->createdLotacao->ocupacao->nome}";
$lotacaoId = $procedimento->lotacao
? $procedimento->lotacao_id
: $procedimento->created_lotacao_id;
$isLoaded = true;
}
return [
'id' => $procedimento->lotacao->usuario->id
?? $procedimento->createdLotacao->usuario->id
?? null,
'nome' => $nomeUsuario,
'lotacao_id' => $lotacaoId,
'is_loaded' => $isLoaded,
];
}
private static function getPrimeroSetorTipoIdEncaminhado($fila)
{
if (is_null($fila)) {
return null;
}
return $fila->historico()->whereHas('centroCusto', function ($query) {
$query->whereHas('setor', function ($query) {
$query->where('tipo_id', '<>', SetorTipo::RECEPCAO);
});
})->first()->centroCusto->setor->tipo_id;
}
private static function getUsuarios($request)
{
$plantoes = self::getPlantoesBuilder($request)
->select(
'cadastro_usuario.id',
'cadastro_cidadao.nome',
'cadastro_lotacao.id as lotacao_id',
'cadastro_lotacao.ocupacao_id',
'sigtap.ocupacao.nome as ocupacao_nome',
'sigtap.ocupacao.codigo as ocupacao_codigo',
'pronto_atendimento_plantao.servico_id',
'cadastro_servico.nome as servico_nome',
)
->join('cadastro_usuario', 'cadastro_usuario.id', 'cadastro_lotacao.usuario_id')
->join('sigtap.ocupacao', 'sigtap.ocupacao.id', 'cadastro_lotacao.ocupacao_id')
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id')
->join('cadastro_servico', 'cadastro_servico.id', 'pronto_atendimento_plantao.servico_id')
->where('cadastro_lotacao.realiza_atendimento', 1)
->orderBy('cadastro_cidadao.nome')
->orderBy('sigtap.ocupacao.nome');
if (is_numeric($request->get('servico_id'))) {
$plantoes->where('pronto_atendimento_plantao.servico_id', $request->get('servico_id'));
}
if (is_numeric($request->get('faixa_etaria_id')) && $request->get('servico_id') != FaixaEtariaEnum::ADULTO) {
$plantoes->where('pronto_atendimento_plantao.faixa_etaria_id', $request->get('faixa_etaria_id'));
}
$especialidadesMedica = EncaminhamentoEspecialidade::all()->pluck('ocupacao_id');
return $plantoes->distinct()->get()->map(function ($usuario) use ($especialidadesMedica) {
$isMedico = $especialidadesMedica->contains($usuario->ocupacao_id)
&& $usuario->servico_id === Servico::CONSULTA_MEDICA;
return [
'id' => $usuario->id,
'nome' => "{$usuario->nome} - {$usuario->ocupacao_nome}",
'lotacao_id' => $usuario->lotacao_id,
'ocupacao' => [
'id' => $usuario->ocupacao_id,
'nome' => $usuario->ocupacao_nome,
'codigo' => $usuario->ocupacao_codigo,
],
'plantao' => self::getPlantoesUsuario($usuario->id),
'is_medico' => $isMedico,
];
});
}
private static function getServicos()
{
return self::getPlantoesBuilder(request())
->select(
'cadastro_servico.id as id',
'cadastro_servico.nome as nome',
)
->join('cadastro_servico', 'cadastro_servico.id', 'pronto_atendimento_plantao.servico_id')
->distinct()
->get();
}
private static function getFaixaEtaria()
{
return FaixaEtaria::orderBy('nome')->get();
}
private static function getDesfechos()
{
return Desfecho::all()->map(function ($desfecho) {
return [
'id' => $desfecho->id,
'nome' => $desfecho->nome,
];
});
}
private static function getEvasao($atendimentosMedico, $fila)
{
$motivo = $fila->motivo_evasao ?? null;
if (is_null($motivo)) {
if ($atendimentosMedico->isNotEmpty()) {
$lastAtendimento = $atendimentosMedico->last();
if ($lastAtendimento->desfecho_id) {
$motivo = $lastAtendimento->motivo_evasao;
}
}
}
return [
'motivo' => $motivo,
];
}
private static function getEncaminhamentoHospitalar($faa, $atendimento, $atendimentosMedico)
{
$lotacaoId = $faa->lotacao_id ?? null;
if (is_null($faa->desfecho_id)) {
if ($atendimentosMedico->isNotEmpty()) {
$lastAtendimento = $atendimentosMedico->last();
if ($lastAtendimento->desfecho_id) {
$lotacaoId = $lastAtendimento->created_lotacao_id;
}
}
}
$encaminhamentoHospitalar = $atendimento->encaminhamentosHospitalar->last();
return [
'lotacao_id' => $lotacaoId,
'cid' => Cid::find($encaminhamentoHospitalar->cid_id ?? null) ?? null,
'medico_hospitalar' => $encaminhamentoHospitalar->medico_hospitalar ?? null,
'observacoes' => $encaminhamentoHospitalar->observacoes ?? null,
'unidade_id' => $encaminhamentoHospitalar->unidade_id ?? null,
'unidade_nome' => $encaminhamentoHospitalar->unidade_nome ?? null,
'unidade_outra' => ($encaminhamentoHospitalar->unidade_nome ?? null) != null,
'quarto' => $encaminhamentoHospitalar->quarto ?? null,
'leito' => $encaminhamentoHospitalar->leito ?? null,
];
}
private static function getObito($faa, $atendimentosMedico)
{
$desfechoId = $faa->desfecho_id;
$lotacaoId = $faa->lotacao_id ?? null;
if (is_null($faa->desfecho_id)) {
if ($atendimentosMedico->isNotEmpty()) {
$lastAtendimento = $atendimentosMedico->last();
if ($lastAtendimento->desfecho_id) {
$desfechoId = $lastAtendimento->desfecho_id;
$lotacaoId = $lastAtendimento->created_lotacao_id;
}
}
}
if ($desfechoId !== DesfechoEnum::OBITO) {
return [
'lotacao_id' => null,
'dataObito' => null,
'horaObito' => null,
'declaracao' => null,
'cid' => null,
'causa' => null,
];
}
$paciente = Faa::findOrFail($faa->id)->paciente;
$obito = (new ObitoService($paciente->cidadao))->get();
return [
'causa' => $obito->causa,
'cid' => $obito->cid,
'cidadao_id' => $obito->cidadao_id,
'declaracao' => $obito->declaracao,
'id' => $obito->id,
'dataObito' => Carbon::createFromFormat('Y-m-d H:i:s', $obito->obito_em)->format('Y-m-d'),
'horaObito' => Carbon::createFromFormat('Y-m-d H:i:s', $obito->obito_em)->format('H:i'),
'lotacao_id' => $lotacaoId,
];
}
private static function getCidadaoFatoresRisco($faas)
{
$cidadaoIds = $faas->pluck('cidadao_id')->unique()->toArray();
$cidadaos = Cidadao::whereIn('id', $cidadaoIds)->get();
$result = [];
foreach ($cidadaos as $cidadao) {
foreach ($cidadao->fatoresRisco as $fatorRisco) {
$result[$cidadao->id][] = $fatorRisco->cidadaoFatorRisco->fator_risco_id;
}
}
return $result;
}
public static function getProcedimentosFaa()
{
$params = request()->all();
if(!isset($params['faa_id'])){
return [];
}
$atendimento = Faa::with('atendimentos')->findOrFail($params['faa_id'])->atendimentos->last();
$procedimentos = Procedimento::where('atendimento_id', $atendimento->id)
->with([
'lotacao.ocupacao', 'lotacao.usuario',
'createdLotacao.ocupacao', 'createdLotacao.usuario', 'createdLotacao.usuario.cidadao',
'cidPrincipal'
])
->get();
if (isset($params['procedimento_padrao_faa_codigo'])) {
$procedimentos = $procedimentos
->filter(fn ($p) => isset($p->procedimento) && $p->procedimento->codigo != $params['procedimento_padrao_faa_codigo'])
->values();
}
return $procedimentos->map(function ($item) {
$ocupacaoNome = $item->lotacao->ocupacao->nome
?? $item->createdLotacao->ocupacao->nome;
return [
'id' => $item->id,
'disabled' => !$item->from_fechamento_faa,
'data' => $item->realizado_em
? $item->realizado_em->format('d/m/Y')
: $item->created_at->format('d/m/Y'),
'usuario' => [
'nome' => ($item->lotacao->usuario->nome
?? $item->createdLotacao->usuario->nome) . " - {$ocupacaoNome}",
'lotacao_id' => $item->lotacao_id,
],
'ocupacao' => [
'nome' => $ocupacaoNome,
'codigo' => $item->lotacao->ocupacao->codigo
?? $item->createdLotacao->ocupacao->codigo,
],
'procedimento' => $item->procedimento,
'cid' => [
'id' => $item->cidPrincipal->id ?? null,
'nome' => $item->cidPrincipal->nome ?? null,
'codigo' => $item->cidPrincipal->codigo ?? null,
],
'plantao_id' => $item->plantao_id ?? null,
'quantidade' => $item->quantidade ?? 1,
'lotacao' => [
'ocupacao' => [
'id' => $item->createdLotacao->ocupacao->id ?? null,
'codigo' => $item->createdLotacao->ocupacao->codigo ?? null,
'nome' => $item->createdLotacao->ocupacao->nome ?? null,
],
'profissional' => [
'nome' => $item->createdLotacao->usuario->cidadao->nome ?? null,
],
],
'centro_custo' => [
'setor' => [
'nome' => $item->createdCentroCusto->setor->nome ?? null,
],
],
'classificacao_risco' => [
'nome' => (
$item->atendimentoMedico
?? $item->atendimentoTriagem
?? $item->atendimentoEnfermagem
?? $item->pacienteObservacao
)->classificacaoRisco->classificacaoRisco->nome ?? null,
],
];
})->values();
}
private static function getFatoresRisco()
{
$result = FatorRisco::orderBy('id')
->whereIn('id', [
FatorRiscoEnum::CANCERO,
FatorRiscoEnum::DIABETES,
FatorRiscoEnum::ETILISMO,
FatorRiscoEnum::HIPERTENSAO,
FatorRiscoEnum::OBESIDADE,
FatorRiscoEnum::PERFIL_SANGUINEO_ALTERADO,
FatorRiscoEnum::RADIOTERAPIA,
FatorRiscoEnum::TABAGISMO,
FatorRiscoEnum::USO_DE_MEDICAMENTOS_ANTINEOPLASICOS_OU_IMUNOSSUPRESSORES,
FatorRiscoEnum::OUTRO,
])
->get()
->map(fn ($fatorRisco) => [
'id' => $fatorRisco->id,
'nome' => $fatorRisco->nome,
]);
return $result;
}
private static function getFatoresRiscoGestante()
{
$result = FatorRisco::orderBy('nome')
->whereIn('id', [
FatorRiscoEnum::CANCERO,
FatorRiscoEnum::DIABETES,
FatorRiscoEnum::ETILISMO,
FatorRiscoEnum::HIPERTENSAO,
FatorRiscoEnum::OBESIDADE,
FatorRiscoEnum::PERFIL_SANGUINEO_ALTERADO,
FatorRiscoEnum::RADIOTERAPIA,
FatorRiscoEnum::TABAGISMO,
FatorRiscoEnum::USO_DE_MEDICAMENTOS_ANTINEOPLASICOS_OU_IMUNOSSUPRESSORES,
FatorRiscoEnum::OUTRO,
FatorRiscoEnum::GESTANTE,
])
->get()
->map(fn ($fatorRisco) => [
'id' => $fatorRisco->id,
'nome' => $fatorRisco->nome,
]);
return $result;
}
private static function getExistsAndHasPlantao($table)
{
return function ($query) use ($table) {
$query->select(DB::raw(1))
->from($table)
->join(
'pronto_atendimento_plantao',
'pronto_atendimento_plantao.id',
"{$table}.plantao_id"
)
->join(
'cadastro_lotacao',
'cadastro_lotacao.id',
'pronto_atendimento_plantao.lotacao_id'
)
->whereColumn(
"{$table}.atendimento_id",
'pronto_atendimento_atendimento.id'
)
->where(
'cadastro_lotacao.infraestrutura_id',
self::getCentroCustoLogado()->infraestrutura_id
);
if (is_numeric(request()->get('usuario_id'))) {
$query->where('cadastro_lotacao.usuario_id', request()->get('usuario_id'));
}
};
}
private static function getPeriodoFromRequest($request)
{
if (!is_null($request->get('faa_id'))) {
$atendimento = Atendimento::whereHas('faa', function ($query) use ($request) {
$query->where('numero', $request->get('faa_id'));
})
->firstOrFail();
$recepcao = Recepcao::where('atendimento_id', $atendimento->id)->firstOrFail();
$periodoStart = Carbon::parse($recepcao->atendido_em);
} else {
$periodoStart = self::getStartOfDay();
if (!is_null($request->get('start'))) {
$periodoStart = self::getStartOfDay(Carbon::createFromFormat('d/m/Y', $request->get('start')));
}
}
$periodoEnd = self::getEndOfDay();
if (!is_null($request->get('end'))) {
$periodoEnd = self::getEndOfDay(Carbon::createFromFormat('d/m/Y', $request->get('end')));
}
return [
'start' => $periodoStart,
'end' => $periodoEnd,
];
}
private static function getCentroCustoLogado()
{
return CentroCusto::findOrFail(auth()->payload()->get('centro_custo_id'));
}
public static function update($id)
{
$faa = Faa::findOrFail($id);
Validations::update($faa);
DB::transaction(function () use ($faa) {
$faa->desfecho_id = request()->desfecho_id;
$faa->finalizado = true;
$hora = request()->hora;
$atendimentoPraClassificacao = $faa->atendimentos->first();
if (request()->classificacao_risco_id !== null) {
if (request()->has('classificacao_risco_id')) {
$classificacaoRiscoId = request()->classificacao_risco_id;
ProntoAtendimentoAtendimentoClassificacaoRisco::create([
'atendimento_id' => $atendimentoPraClassificacao->id,
'classificacao_risco_id' => $classificacaoRiscoId,
]);
}
}
if (request()->desfecho_id !== DesfechoEnum::FAA_EXTRAVIADA) {
$procedimentosData = self::prepareProcedimentosData();
$ids = [];
$atendimento = $faa->atendimentos->first();
if (!empty($procedimentosData)) {
foreach ($procedimentosData as $procedimentoData) {
$save = true;
if (!is_null($procedimentoData['id'])) {
$procedimento = Procedimento::findOrFail($procedimentoData['id']);
$realizadoEm = $procedimento->realizado_em
? $procedimento->realizado_em->format('d/m/Y')
: null;
if (
$realizadoEm == $procedimentoData['realizado_em']->format('d/m/Y')
&& $procedimento->procedimento_id == $procedimentoData['procedimento_id']
&& $procedimento->quantidade == $procedimentoData['quantidade']
&& $procedimento->lotacao_id == $procedimentoData['lotacao_id']
&& $procedimento->is_parametrizado == $procedimentoData['is_parametrizado']
&& $procedimento->cid_principal_id == $procedimentoData['cid_principal_id']
) {
$save = false;
}
}
if ($save) {
$procedimento = $atendimento->procedimentos()->updateOrCreate(
['id' => $procedimentoData['id']],
$procedimentoData
);
self::setPlantaoStatusComAtendimento($procedimentoData, $atendimento, $hora);
}
$ids[] = $procedimento->id;
}
}
self::handleProcedimentoExcluidos($atendimento->id, $ids);
Procedimento::destroy(
Procedimento::where('atendimento_id', $atendimento->id)
->where('is_parametrizado', false)
->whereNotIn('id', $ids)
->pluck('id')
);
$faa->paciente->cidadao->fatoresRisco()->sync(request()->fatores_risco ?? []);
}
DesfechoService::store($faa);
$faa->save();
});
return $faa->fresh();
}
public static function cancelarFaa($id){
$faa = Faa::firstWhere('id', $id);
if(!$faa || !isset(request()->motivo_cancelamento)) {
return response()->json([
"error" => "Registro não encontrado ou motivo de cancelamento não informado"
], Response::HTTP_NOT_FOUND);
}
return $faa->update([
'motivo_cancelamento' => request()->motivo_cancelamento,
'cancelado' => true,
'desfecho_id' => DesfechoEnum::FAA_CANCELADA
]);
}
private static function prepareProcedimentosData()
{
$procedimentos = [];
foreach ((request()->procedimentos ?? []) as $procedimento) {
$procedimentos[] = [
'id' => $procedimento['id'],
'realizado_em' => Carbon::createFromFormat('d/m/Y', $procedimento['data']),
'procedimento_id' => $procedimento['procedimento_id'],
'quantidade' => $procedimento['quantidade'],
'lotacao_id' => $procedimento['lotacao_id'],
'is_parametrizado' => $procedimento['is_parametrizado'],
'cid_principal_id' => $procedimento['cid_id'],
];
}
return $procedimentos;
}
private static function setPlantaoStatusComAtendimento($procedimentoData, $atendimento, $hora)
{
$hour = substr($hora, 0, 2);
$minute = substr($hora, 3, 2);
$periodo = (new Carbon($procedimentoData['realizado_em']));
$periodo->hour($hour)->minute($minute)->second(0);
$plantao = DB::table('pronto_atendimento_plantao')
->select(
'pronto_atendimento_plantao.id',
)
->join('cadastro_lotacao', 'cadastro_lotacao.id', 'pronto_atendimento_plantao.lotacao_id')
->whereNull('pronto_atendimento_plantao.deleted_at')
->whereIn('pronto_atendimento_plantao.status_id', [Status::CONFIRMADO, Status::COM_ATENDIMENTO_AGENDADO])
->where('inicio', '<=', $periodo)
->where('fim', '>=', $periodo)
->where('cadastro_lotacao.id', $procedimentoData['lotacao_id'])
->first();
if (!$plantao) {
$periodoStart = (new Carbon($procedimentoData['realizado_em']));
$periodoStart->hour(0)->minute(0)->second(0);
$periodoEnd = (new Carbon($procedimentoData['realizado_em']));
$periodoEnd->hour(23)->minute(59)->second(59);
$plantao = DB::table('pronto_atendimento_plantao')
->select(
'pronto_atendimento_plantao.id',
)
->join('cadastro_lotacao', 'cadastro_lotacao.id', 'pronto_atendimento_plantao.lotacao_id')
->whereNull('pronto_atendimento_plantao.deleted_at')
->whereIn('pronto_atendimento_plantao.status_id', [Status::CONFIRMADO, Status::COM_ATENDIMENTO_AGENDADO])
->where(function ($query) use ($periodoStart, $periodoEnd) {
$query->whereBetween('inicio', [$periodoStart, $periodoEnd])
->orWhereBetween('fim', [$periodoStart, $periodoEnd]);
})
->where('cadastro_lotacao.id', $procedimentoData['lotacao_id'])
->first();
}
if ($plantao) {
Procedimento::where('atendimento_id', $atendimento->id)
->where('lotacao_id', $procedimentoData['lotacao_id'])
->where('procedimento_id', $procedimentoData['procedimento_id'])
->update(['plantao_id' => $plantao->id]);
PlantaoService::setStatusComAtendimento($plantao->id);
}
}
private static function handleProcedimentoExcluidos($atendimento_id, $ids)
{
$procedimentosExcluidos = Procedimento::where('atendimento_id', $atendimento_id)
->where('is_parametrizado', false)
->whereNotIn('id', $ids)
->whereNull('deleted_at')
->whereNotNull('plantao_id')
->whereNull('deleted_at')
->get();
if (!empty($procedimentosExcluidos)) {
foreach ($procedimentosExcluidos as $procedimentoExcluido) {
$verificaProcedimento = Procedimento::where('plantao_id', $procedimentoExcluido['plantao_id'])
->where('id', '<>', $procedimentoExcluido['id'])
->whereIn('id', $ids)
->whereNull('deleted_at')
->first();
if (!$verificaProcedimento) {
self::plantaoStatusConfirmado($procedimentoExcluido['plantao_id']);
}
}
}
}
private static function plantaoStatusConfirmado($plantao_id)
{
$hasAtendimento = Recepcao::where('plantao_id', $plantao_id)
->first();
if (!$hasAtendimento) {
$hasAtendimento = AtendimentoTriagem::where('plantao_id', $plantao_id)
->first();
}
if (!$hasAtendimento) {
$hasAtendimento = AtendimentoMedico::where('plantao_id', $plantao_id)
->first();
}
if (!$hasAtendimento) {
$hasAtendimento = AtendimentoEnfermagem::where('plantao_id', $plantao_id)
->first();
}
if (!$hasAtendimento) {
$hasAtendimento = PacienteObservacao::where('plantao_id', $plantao_id)
->first();
}
if (!$hasAtendimento) {
$hasAtendimento = PedidoExame::where('plantao_id', $plantao_id)
->first();
}
if (!$hasAtendimento) {
PlantaoService::setStatusConfirmado($plantao_id);
}
}
private static function getFirstAtendimento($atendimento, $firstSetorTipoId) {
if ($firstSetorTipoId === SetorTipo::ENFERMAGEM) {
return $atendimento->atendimentosEnfermagem->first();
}
if ($firstSetorTipoId === SetorTipo::EXAMES) {
return $atendimento->atendimentosExameImagem->first();
}
}
}