Files
rkm-conectasus-ci-sandbox/api/app/Services/ProntoAtendimento/Atendimento/RetroativoService.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

426 lines
15 KiB
PHP

<?php
namespace App\Services\ProntoAtendimento\Atendimento;
use App\Enums\Cadastro\SujeitoAtencao\Classificacao;
use App\Enums\ProntoAtendimento\Atendimento\Desfecho;
use App\Enums\ProntoAtendimento\Atendimento\OrigemEntrada as AtendimentoOrigemEntrada;
use App\Models\Cadastro\Parametrizacao\ParametrizacaoPermissaoUsuario;
use App\Models\Cadastro\SujeitoAtencao\Lotacao;
use App\Models\Cadastro\SujeitoAtencao\Paciente;
use App\Models\Cadastro\SujeitoAtencao\PacienteClassificacao;
use App\Models\Cadastro\SujeitoAtencao\Sexo;
use App\Models\Cns\TermoInvalido;
use App\Models\ProntoAtendimento\Atendimento\Faa;
use App\Models\ProntoAtendimento\Atendimento\OrigemEntrada;
use App\Rules\CnsTermoValido;
use App\Rules\NomeCompleto;
use App\Services\Cadastro\SujeitoAtencao\PacienteDesconhecidoSaveService;
use App\Utils\MaskUtil;
use Carbon\Carbon;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
class RetroativoService
{
public static function create()
{
$now = Carbon::now();
$pacienteIdentificado = null;
if (is_numeric(request()->paciente_id)) {
$paciente = Paciente::findOrFail(request()->paciente_id);
$endereco = '';
if ($paciente->cidadao->domicilio_id) {
$endereco = $paciente->cidadao->domicilio->endereco;
$endereco = $endereco->completo . ' - ' . MaskUtil::getCepMasked($endereco->logradouro->cep);
}
$pacienteIdentificado = [
'prontuario' => $paciente->prontuario,
'classificacao_id' => $paciente->classificacao_id,
'cns' => $paciente->cidadao->cns,
'nome' => $paciente->cidadao->nome,
'nome_social' => $paciente->cidadao->nome_social,
'nome_mae' => $paciente->cidadao->nome_mae ?? '',
'sexo' => [
'id' => $paciente->cidadao->sexo->id,
'descricao' => $paciente->cidadao->sexo->descricao,
],
'preferencia_nome_id' => $paciente->cidadao->preferencia_nome_id ?? null,
'data_nascimento' => $paciente->cidadao->data_nascimento->format('d/m/Y'),
'idade' => $paciente->cidadao->idade,
'endereco' => $endereco,
'telefones' => $paciente->cidadao->telefones->map(fn ($telefone) => [
'id' => $telefone->id,
'numero' => MaskUtil::getPhoneMasked($telefone->numero),
'observacao' => $telefone->observacao ?? '',
'autoriza_sms' => $telefone->autoriza_sms,
'principal' => $telefone->principal,
]),
];
}
$lotacao = Lotacao::findOrFail(auth()->payload()->get('lotacao_id'));
$permissaoUsuario = ParametrizacaoPermissaoUsuario::where('usuario_id', $lotacao->usuario_id)
->where('infraestrutura_id', $lotacao->infraestrutura_id)
->first();
$countUsuario = ParametrizacaoPermissaoUsuario::count();
$classificacoes = $permissaoUsuario
? PacienteClassificacao::orderBy('descricao')
->get()
->filter(function ($classificacao) use ($permissaoUsuario) {
$exibe = false;
switch ($classificacao->id) {
case Classificacao::MUNICIPE:
$exibe = $permissaoUsuario->municipe;
break;
case Classificacao::PROVISORIO:
$exibe = $permissaoUsuario->provisorio;
break;
case Classificacao::OUTRO_MUNICIPIO:
$exibe = $permissaoUsuario->outro_municipio;
break;
}
return $exibe ? [
'id' => $classificacao->id,
'descricao' => $classificacao->descricao
] : null;
})
->values()
: [];
return [
'form' => [
'data_atual_menos_um_ano' => $now->copy()->subYear()->format('d/m/Y'),
'data_atual' => $now->format('d/m/Y'),
'data_registro' => $now->format('Y-m-d'),
'isEncaminhamento' => false,
'sem_acompanhante' => true,
'paciente_identificado' => $pacienteIdentificado,
'origem_unidade_value' => 'interna',
'unidade_encaminhamento' => null,
'paciente_desconhecido' => [
'sexos' => Sexo::orderBy('descricao')
->get()
->map(fn ($sexo) => [
'id' => $sexo->id,
'descricao' => $sexo->descricao
]),
],
'origens_entrada' => OrigemEntrada::orderBy('nome')
->get()
->map(fn ($origem) => [
'id' => $origem->id,
'nome' => $origem->nome,
]),
'origens_unidade' => [
[ 'id' => 'interna', 'nome' => 'INTERNA' ],
[ 'id' => 'externa', 'nome' => 'EXTERNA' ],
],
'faa_aberta' => self::getFaaAberta(request()->paciente_id),
'classificacoes' => $classificacoes,
'is_permissao_cadastro' => $countUsuario === 0 ? true : false,
],
'model' => [
'acompanhante' => null,
'atendido_em' => null,
'atendido_hora' => null,
'medico_samu' => null,
'medico_solicitante_encaminhamento' => null,
'motivo_atendimento' => null,
'observacao' => null,
'origem_entrada_id' => AtendimentoOrigemEntrada::ESPONTANEA,
'unidade_encaminhamento_id' => null,
'unidade_externa_encaminhamento_id' => null,
'paciente_desconhecido' => [
'sexo_id' => null,
'caracteristicas_fisicas' => null,
],
],
'adittional' => [
'termos_invalidos' => TermoInvalido::all()->map(fn ($termo) => $termo->descricao),
]
];
}
public static function pacienteHasAtendimento($pacienteId)
{
if (is_numeric($pacienteId)) {
$faa = Faa::with('atendimentos.fila')
->where('paciente_id', $pacienteId)
->whereHas('atendimentos.fila', function($query) {
$query
->whereHas('centroCusto', function($query) {
$query->where(
'infraestrutura_id',
Lotacao::findOrFail(auth()->payload()->get('lotacao_id'))->infraestrutura_id
);
});
})
->where(function($query) {
$query->whereNull('desfecho_id')
->orWhere('desfecho_id', Desfecho::EVASAO);
})
->first();
if ($faa) {
$setor = null;
$emitidoEm = null;
$procedimentos = 0;
$faa->atendimentos->map(function($atendimento) use (&$setor, &$procedimentos, &$emitidoEm) {
$emitidoEm = $atendimento->fila->emitido_em;
$setor = $atendimento->fila->centroCusto->setor;
$procedimentos = $atendimento->procedimentos->count();
});
$emitidoEm = Carbon::parse($emitidoEm)->format('Y-m-d');
if ($emitidoEm === Carbon::now()->format('Y-m-d')) {
if ($procedimentos > 0) {
return response()->json(['message' => 'Paciente já está em atendimento no setor de ' . $setor['nome']
. '. Finalize o atendimento para iniciar um novo.'], Response::HTTP_BAD_REQUEST);
}
}
}
if (is_null($faa)) {
$faa = Faa::where('paciente_id', $pacienteId)
->where('finalizado', false)
->whereHas('createdCentroCusto', function ($query) {
$query->where(
'infraestrutura_id',
Lotacao::findOrFail(auth()->payload()->get('lotacao_id'))->infraestrutura_id
);
})
->first();
if ($faa) {
return [
'message' => 'Paciente já está em atendimento no setor de ' . $faa->createdCentroCusto->setor->nome . '. Finalize o atendimento para iniciar um novo.',
'response' => Response::HTTP_BAD_REQUEST
];
}
}
}
return false;
}
public static function getFaaAberta($pacienteId)
{
if (is_numeric($pacienteId)) {
$faa = Faa::with('atendimentos.fila')
->where('paciente_id', $pacienteId)
->whereHas('atendimentos.fila', function($query) {
$query
->whereHas('centroCusto', function($query) {
$query->where(
'infraestrutura_id',
Lotacao::findOrFail(auth()->payload()->get('lotacao_id'))->infraestrutura_id
);
});
})
->where(function($query) {
$query->whereNull('desfecho_id')
->orWhere('desfecho_id', Desfecho::EVASAO);
})
->first();
if ($faa) {
$setor = null;
$emitidoEm = null;
$procedimentos = 0;
$faa->atendimentos->map(function($atendimento) use (&$setor, &$procedimentos, &$emitidoEm) {
$emitidoEm = $atendimento->fila->emitido_em;
$setor = $atendimento->fila->centroCusto->setor;
$procedimentos = $atendimento->procedimentos->count();
});
$emitidoEm = Carbon::parse($emitidoEm)->format('Y-m-d');
if ($emitidoEm === Carbon::now()->format('Y-m-d')) {
if ($procedimentos > 0) {
return response()->json(['message' => 'Paciente já está em atendimento no setor de ' . $setor['nome']
. '. Finalize o atendimento para iniciar um novo.'], Response::HTTP_BAD_REQUEST);
}
if ($faa->desfecho_id == null) {
return [
'alert_faa_aberta' => true,
'setor' => $setor['nome'],
];
}
}
}
}
return false;
}
public static function store()
{
self::validations();
$recepcao = null;
$params = self::getParams();
DB::transaction(function () use (&$recepcao, $params) {
$pacienteId = self::savePaciente($params['paciente'], $params['atendido_em']);
$faa = Faa::create(['paciente_id' => $pacienteId]);
$atendimento = $faa->atendimentos()->create();
$recepcao = self::saveAtendimentoRecepcao($atendimento, $params);
});
return $recepcao->refresh();
}
private static function getParams()
{
$params = request()->all();
if (isset($params['medico_samu'])) {
$params['medico_samu'] = mb_strtoupper($params['medico_samu']);
}
if (isset($params['acompanhante'])) {
$params['acompanhante'] = mb_strtoupper($params['acompanhante']);
}
if (isset($params['medico_solicitante_encaminhamento'])) {
$params['medico_solicitante_encaminhamento'] = mb_strtoupper($params['medico_solicitante_encaminhamento']);
}
return $params;
}
private static function savePaciente($params, $atendidoEm)
{
if (isset($params['id'])) {
return $params['id'];
}
return (new PacienteDesconhecidoSaveService(
$atendidoEm,
$params['sexo_id'],
$params['caracteristicas_fisicas'] ?? null
))->save()->id;
}
private static function saveAtendimentoRecepcao($atendimento, $params)
{
return $atendimento->recepcao()->create([
'atendido_em' => Carbon::createFromFormat('d-m-Y H:i', $params['atendido_em']),
'urgente' => false,
'origem_entrada_id' => $params['origem_entrada_id'] ?? null,
'medico_samu' => $params['medico_samu'] ?? null,
'motivo_atendimento' => $params['motivo_atendimento'] ?? null,
'acompanhante' => $params['acompanhante'] ?? null,
'unidade_encaminhamento_id' => $params['unidade_encaminhamento_id'] ?? null,
'unidade_externa_encaminhamento_id' => $params['unidade_externa_encaminhamento_id'] ?? null,
'medico_solicitante_encaminhamento' => $params['medico_solicitante_encaminhamento'] ?? null,
'observacao' => $params['observacao'] ?? null,
]);
}
private static function validations()
{
return request()->validate([
'paciente' => [
'required',
'array'
],
'paciente.id' => [
'nullable',
'integer'
],
'paciente.sexo_id' => [
'required_without:paciente.id',
'nullable',
'integer'
],
'paciente.caracteristicas_fisicas' => [
'required_without:paciente.id',
'string',
'max:500'
],
'atendido_em' => [
'required',
'date_format:d-m-Y H:i',
'before_or_equal:now'
],
'origem_entrada_id' => ['nullable', 'integer'],
'medico_samu' => [
'nullable',
'string',
'max:150'
],
"motivo_atendimento" => [
'required',
'nullable',
'string',
'max:3000'
],
"acompanhante" => [
'nullable',
'string',
'between:6,150',
new NomeCompleto,
new CnsTermoValido(['attribute' => 'Acompanhante']),
],
"unidade_encaminhamento_id" => [
'nullable',
'integer'
],
"unidade_externa_encaminhamento_id" => [
'nullable',
'integer'
],
"medico_solicitante_encaminhamento" => [
'nullable',
'string',
'between:6,150',
new NomeCompleto,
],
"observacao" => [
'nullable',
'string',
'max:500'
],
],
[
'atendido_em.before_or_equal' => 'O início do atendimento deve ser anterior ou igual hora atual.'
]);
}
}