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

181 lines
7.2 KiB
PHP

<?php
namespace App\Services\Mobile\ConectaCidadao\ExameLaboratorial;
use App\Enums\ExameLaboratorial\StatusAgendamento;
use App\Models\ExameLaboratorial\Parametrizacao\IntegracaoAplicativo;
use App\Services\Service;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
class LaudoService extends Service
{
public static function laudos(): array
{
self::validarVisualizacaoHabilitada();
$paciente = auth('mobile')->user();
return DB::table('exame_laboratorial_agendamento as agendamento')
->join('cadastro_unidade as unidade_sol', 'unidade_sol.id', 'agendamento.unidade_id')
->join('cadastro_infraestrutura as infra_sol', 'infra_sol.id', 'agendamento.infraestrutura_id')
->join('cadastro_unidade as unidade_col', 'unidade_col.id', 'agendamento.coleta_unidade_id')
->leftJoin('cadastro_usuario as medico', 'medico.id', 'agendamento.medico_id')
->leftJoin('cadastro_cidadao as cidadao_medico', 'cidadao_medico.id', 'medico.cidadao_id')
->where('agendamento.paciente_id', $paciente->id)
->where(function ($q) {
$q->whereExists(function ($sub) {
$sub->select(DB::raw(1))
->from('exame_laboratorial_agendamento_exame as exame')
->whereColumn('exame.agendamento_id', 'agendamento.id')
->where('exame.status_id', StatusAgendamento::ASSINADO);
})
->orWhereExists(function ($sub) {
$sub->select(DB::raw(1))
->from('exame_laboratorial_agendamento_laudo as laudo')
->whereColumn('laudo.agendamento_id', 'agendamento.id')
->where(function ($l) {
$l->whereNotNull('laudo.arquivo')
->orWhereNotNull('laudo.url');
});
});
})
->orderByDesc('agendamento.data')
->get(
[
'agendamento.id',
'agendamento.data',
'unidade_sol.nome_fantasia as unidade_solicitante',
'unidade_col.nome_fantasia as unidade_coleta',
'cidadao_medico.nome as medico_nome',
]
)
->map(
fn($item) =>
[
'id' => $item->id,
'data' => $item->data,
'unidade_solicitante' => $item->unidade_solicitante,
'unidade_coleta' => $item->unidade_coleta,
'medico' => $item->medico_nome,
'exames' => self::getExamesComLaudo($item->id),
]
)
->values()
->toArray();
}
private static function getExamesComLaudo(int $agendamentoId): array
{
$examesAssinados = DB::table('exame_laboratorial_agendamento_exame as exame')
->join('parametrizacao_exame as param_exame', 'param_exame.id', 'exame.exame_id')
->leftJoin('cadastro_usuario as prof_assinatura', 'prof_assinatura.id', 'exame.assinatura_profissional_id')
->leftJoin('cadastro_cidadao as cidadao_assinatura', 'cidadao_assinatura.id', 'prof_assinatura.cidadao_id')
->where('exame.agendamento_id', $agendamentoId)
->where('exame.status_id', StatusAgendamento::ASSINADO)
->get(
[
'exame.id',
'param_exame.nome',
'param_exame.sigla_exame',
'exame.data_assinatura',
'cidadao_assinatura.nome as assinado_por',
'exame.entregue',
'exame.impressao',
]
)
->map(
fn($exame) =>
[
'id' => $exame->id,
'nome' => $exame->nome,
'sigla_exame' => $exame->sigla_exame,
'data_assinatura' => $exame->data_assinatura,
'assinado_por' => $exame->assinado_por,
'status_laudo' => self::resolverStatusLaudo($exame->entregue, $exame->impressao),
'origem' => 'assinatura_eletronica',
]
)
->toArray();
$laudosAnexados = DB::table('exame_laboratorial_agendamento_laudo as laudo')
->where('laudo.agendamento_id', $agendamentoId)
->where(function ($q) {
$q->whereNotNull('laudo.arquivo')
->orWhereNotNull('laudo.url');
})
->orderBy('laudo.ordem')
->get(
[
'laudo.id',
'laudo.arquivo',
'laudo.url',
'laudo.is_enviado_webservice',
'laudo.ordem',
]
)
->map(
fn($laudo) =>
[
'id' => $laudo->id,
'ordem' => $laudo->ordem,
'origem' => $laudo->is_enviado_webservice ? 'externo_prestador' : 'importacao_manual',
'url_download' => $laudo->url
?? ($laudo->arquivo
? url("api/mobile/conecta-cidadao/exame-laboratorial/laudo/{$laudo->id}/download")
: null),
]
)
->toArray();
return [
'assinados' => $examesAssinados,
'laudos_anexados' => $laudosAnexados,
];
}
public static function download(int $laudoId): array
{
$paciente = auth('mobile')->user();
$laudo = DB::table('exame_laboratorial_agendamento_laudo as laudo')
->join('exame_laboratorial_agendamento as agendamento', 'agendamento.id', 'laudo.agendamento_id')
->where('laudo.id', $laudoId)
->where('agendamento.paciente_id', $paciente->id)
->whereNotNull('laudo.arquivo')
->first(['laudo.arquivo']);
abort_if(is_null($laudo), Response::HTTP_NOT_FOUND, 'Laudo não encontrado.');
$caminho = 'exame-laboratorial' . DIRECTORY_SEPARATOR . 'laudos' . DIRECTORY_SEPARATOR . app('config')->get('database.default') . DIRECTORY_SEPARATOR . $laudo->arquivo;
abort_if(!Storage::exists($caminho), Response::HTTP_NOT_FOUND, 'Arquivo do laudo não encontrado.');
return [
'nome' => $laudo->arquivo,
'caminho' => Storage::path($caminho),
];
}
private static function resolverStatusLaudo(bool $entregue, bool $impressao): string
{
if ($entregue) {
return 'entregue';
}
return $impressao ? 'pendente_entrega' : 'pendente_impressao';
}
private static function validarVisualizacaoHabilitada(): void
{
$parametrizacao = IntegracaoAplicativo::first();
if (!($parametrizacao->habilita_visualizacao_laudo_conectasus_cidadao ?? false)) {
abort(Response::HTTP_FORBIDDEN, 'A visualização de laudos não está habilitada para o aplicativo.');
}
}
}