This commit is contained in:
@@ -0,0 +1,326 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Mobile\ConectaCidadao\Farmacia;
|
||||
|
||||
use App\Enums\Geral\MedidaTempo;
|
||||
use App\Models\Farmacia\AppCidadaoLog;
|
||||
use App\Models\Farmacia\ParametrizacaoAppCidadao;
|
||||
use App\Services\Service;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class ReceitaService extends Service
|
||||
{
|
||||
public static function index(): array
|
||||
{
|
||||
$parametrizacao = ParametrizacaoAppCidadao::first();
|
||||
|
||||
if (!($parametrizacao->permite_envio_receitas_medicas ?? false)) {
|
||||
|
||||
return ['habilitado' => false];
|
||||
}
|
||||
|
||||
$pacienteId = auth('mobile')->user()->id;
|
||||
$perPage = (int) request()->input('per_page', 15);
|
||||
$page = (int) request()->input('page', 1);
|
||||
|
||||
$todos = self::queryAmbulatorioIds($pacienteId)->get()->map(
|
||||
function ($r) {
|
||||
return (array) $r;
|
||||
}
|
||||
);
|
||||
|
||||
$total = $todos->count();
|
||||
$lastPage = max(1, (int) ceil($total / $perPage));
|
||||
$page = max(1, min($page, $lastPage));
|
||||
$slice = $todos->sortByDesc('data')->slice(($page - 1) * $perPage, $perPage)->values();
|
||||
$ids = $slice->pluck('id')->toArray();
|
||||
|
||||
$receitas = collect();
|
||||
|
||||
if (!empty($ids)) {
|
||||
|
||||
$rows = self::queryAmbulatorioDetalhes($ids)->get();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$receitas->push(
|
||||
[
|
||||
'id' => $row->prescricao_id,
|
||||
'data_emissao' => $row->data_receita,
|
||||
'validade' => null,
|
||||
'situacao' => 'ativa',
|
||||
'unidade' => $row->unidade_nome,
|
||||
'prescritor' => $row->prescritor_nome,
|
||||
'total_itens' => $row->total_itens,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
self::log($pacienteId, 'LISTA_RECEITAS');
|
||||
|
||||
return [
|
||||
'habilitado' => true,
|
||||
'data' => $receitas->sortByDesc('data_emissao')->values(),
|
||||
'current_page' => $page,
|
||||
'last_page' => $lastPage,
|
||||
'total' => $total,
|
||||
'per_page' => $perPage,
|
||||
];
|
||||
}
|
||||
|
||||
public static function show(int $id): array
|
||||
{
|
||||
$parametrizacao = ParametrizacaoAppCidadao::first();
|
||||
|
||||
if (!($parametrizacao->permite_envio_receitas_medicas ?? false)) {
|
||||
|
||||
return ['habilitado' => false];
|
||||
}
|
||||
|
||||
$pacienteId = auth('mobile')->user()->id;
|
||||
|
||||
$pacienteNome = DB::table('cadastro_paciente')
|
||||
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_paciente.cidadao_id')
|
||||
->where('cadastro_paciente.id', $pacienteId)
|
||||
->value('cadastro_cidadao.nome');
|
||||
|
||||
$header = DB::table('ambulatorio_atendimento_soap_prescricao_medicamento as prescricao')
|
||||
->select(
|
||||
'prescricao.id',
|
||||
'prescricao.created_at as data_receita',
|
||||
'prescritor_cidadao.nome as prescritor_nome',
|
||||
'cadastro_unidade.nome_fantasia as unidade_nome',
|
||||
'cid.codigo as cid_codigo',
|
||||
'cid.nome as cid_nome'
|
||||
)
|
||||
->join('ambulatorio_atendimento_soap as soap', 'soap.id', 'prescricao.soap_id')
|
||||
->join('ambulatorio_atendimento as atendimento', 'atendimento.id', 'soap.atendimento_id')
|
||||
->leftJoin('cadastro_lotacao', 'cadastro_lotacao.id', 'prescricao.created_lotacao_id')
|
||||
->leftJoin('cadastro_usuario', 'cadastro_usuario.id', 'cadastro_lotacao.usuario_id')
|
||||
->leftJoin('cadastro_cidadao as prescritor_cidadao', 'prescritor_cidadao.id', 'cadastro_usuario.cidadao_id')
|
||||
->leftJoin('cadastro_infraestrutura', 'cadastro_infraestrutura.id', 'cadastro_lotacao.infraestrutura_id')
|
||||
->leftJoin('cadastro_unidade', 'cadastro_unidade.id', 'cadastro_infraestrutura.unidade_id')
|
||||
->leftJoin(
|
||||
DB::raw('(SELECT soap_id, MIN(cid_id) as cid_id FROM ambulatorio_atendimento_soap_problema_condicao WHERE cid_id IS NOT NULL GROUP BY soap_id) as cond'),
|
||||
'cond.soap_id',
|
||||
'=',
|
||||
'soap.id'
|
||||
)
|
||||
->leftJoin('sigtap.cid as cid', 'cid.id', 'cond.cid_id')
|
||||
->where('prescricao.id', $id)
|
||||
->where(function ($q) use ($pacienteId) {
|
||||
$q->whereExists(function ($q2) use ($pacienteId) {
|
||||
$q2->select(DB::raw(1))
|
||||
->from('ambulatorio_agendamento as ag')
|
||||
->whereColumn('ag.id', 'atendimento.agendamento_id')
|
||||
->where('ag.paciente_id', $pacienteId);
|
||||
})->orWhereExists(function ($q2) use ($pacienteId) {
|
||||
$q2->select(DB::raw(1))
|
||||
->from('ambulatorio_demanda_espontanea as de')
|
||||
->whereColumn('de.id', 'atendimento.demanda_espontanea_id')
|
||||
->where('de.paciente_id', $pacienteId);
|
||||
});
|
||||
})
|
||||
->first();
|
||||
|
||||
abort_if(!$header, Response::HTTP_NOT_FOUND);
|
||||
|
||||
$itens = DB::table('ambulatorio_atendimento_soap_prescricao_medicamento_item as item')
|
||||
->select(
|
||||
'item.id',
|
||||
'item.material_id',
|
||||
'item.descricao as item_descricao',
|
||||
'item.justificativa',
|
||||
'item.dose',
|
||||
'item.intervalo',
|
||||
'item.duracao',
|
||||
'item.duracao_medida_tempo_id',
|
||||
'item.recomendacoes',
|
||||
'medida_tempo.nome as intervalo_medida_tempo_nome',
|
||||
'unidade_medida.nome as apresentacao_unidade_medida',
|
||||
'cadastro_via_administracao.nome as via_administracao',
|
||||
DB::raw("CASE WHEN item.material_id IS NOT NULL THEN cadastro_material.descricao ELSE item.descricao END AS material_descricao")
|
||||
)
|
||||
->leftJoin('cadastro_material', 'cadastro_material.id', 'item.material_id')
|
||||
->leftJoin('cadastro_unidade_medida AS unidade_medida', 'unidade_medida.id', 'item.unidade_medida_id')
|
||||
->leftJoin('geral_medida_tempo as medida_tempo', 'medida_tempo.id', 'item.intervalo_medida_tempo_id')
|
||||
->leftJoin('cadastro_via_administracao', 'cadastro_via_administracao.id', 'cadastro_material.via_administracao_id')
|
||||
->where('item.prescricao_medicamento_id', $id)
|
||||
->get()
|
||||
->map(
|
||||
function ($item) {
|
||||
return [
|
||||
'id' => $item->id,
|
||||
'tipo' => is_null($item->material_id) ? 'nao_padronizado' : 'padronizado',
|
||||
'medicamento' => $item->material_descricao,
|
||||
'justificativa' => is_null($item->material_id) ? $item->justificativa : null,
|
||||
'posologia_texto' => self::montarPosologiaTexto($item),
|
||||
'posologia_incompleta' => is_null($item->intervalo),
|
||||
'unidade_medida' => $item->apresentacao_unidade_medida,
|
||||
'intervalo_tempo' => $item->intervalo,
|
||||
'intervalo_medida_tempo' => $item->intervalo_medida_tempo_nome,
|
||||
'durante_tempo' => self::calcularDuracaoEmDias($item->duracao, $item->duracao_medida_tempo_id),
|
||||
'via_administracao' => $item->via_administracao,
|
||||
'recomendacoes' => $item->recomendacoes,
|
||||
];
|
||||
}
|
||||
);
|
||||
|
||||
self::log($pacienteId, 'DETALHE_RECEITA', $id);
|
||||
|
||||
return [
|
||||
'id' => $header->id,
|
||||
'paciente' => $pacienteNome,
|
||||
'data_emissao' => $header->data_receita,
|
||||
'validade' => null,
|
||||
'situacao' => 'ativa',
|
||||
'cid' => [
|
||||
'codigo' => $header->cid_codigo,
|
||||
'descricao' => $header->cid_nome,
|
||||
],
|
||||
'prescritor' => $header->prescritor_nome,
|
||||
'unidade' => $header->unidade_nome,
|
||||
'itens' => $itens,
|
||||
];
|
||||
}
|
||||
|
||||
private static function queryAmbulatorioIds(int $pacienteId)
|
||||
{
|
||||
return DB::table('ambulatorio_atendimento_soap_prescricao_medicamento as prescricao')
|
||||
->select('prescricao.id', 'prescricao.created_at as data')
|
||||
->join('ambulatorio_atendimento_soap as soap', 'soap.id', 'prescricao.soap_id')
|
||||
->join('ambulatorio_atendimento as atendimento', 'atendimento.id', 'soap.atendimento_id')
|
||||
->where('prescricao.solicitacao_fechada', false)
|
||||
->where(function ($q) use ($pacienteId) {
|
||||
$q->whereExists(function ($q2) use ($pacienteId) {
|
||||
$q2->select(DB::raw(1))
|
||||
->from('ambulatorio_agendamento as ag')
|
||||
->whereColumn('ag.id', 'atendimento.agendamento_id')
|
||||
->where('ag.paciente_id', $pacienteId);
|
||||
})->orWhereExists(function ($q2) use ($pacienteId) {
|
||||
$q2->select(DB::raw(1))
|
||||
->from('ambulatorio_demanda_espontanea as de')
|
||||
->whereColumn('de.id', 'atendimento.demanda_espontanea_id')
|
||||
->where('de.paciente_id', $pacienteId);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private static function queryAmbulatorioDetalhes(array $ids)
|
||||
{
|
||||
return DB::table('ambulatorio_atendimento_soap_prescricao_medicamento as prescricao')
|
||||
->select(
|
||||
'prescricao.id as prescricao_id',
|
||||
'prescricao.created_at as data_receita',
|
||||
'prescritor_cidadao.nome as prescritor_nome',
|
||||
'cadastro_unidade.nome_fantasia as unidade_nome',
|
||||
DB::raw('(SELECT COUNT(*) FROM ambulatorio_atendimento_soap_prescricao_medicamento_item WHERE prescricao_medicamento_id = prescricao.id) as total_itens')
|
||||
)
|
||||
->leftJoin('cadastro_lotacao', 'cadastro_lotacao.id', 'prescricao.created_lotacao_id')
|
||||
->leftJoin('cadastro_usuario', 'cadastro_usuario.id', 'cadastro_lotacao.usuario_id')
|
||||
->leftJoin('cadastro_cidadao as prescritor_cidadao', 'prescritor_cidadao.id', 'cadastro_usuario.cidadao_id')
|
||||
->leftJoin('cadastro_infraestrutura', 'cadastro_infraestrutura.id', 'cadastro_lotacao.infraestrutura_id')
|
||||
->leftJoin('cadastro_unidade', 'cadastro_unidade.id', 'cadastro_infraestrutura.unidade_id')
|
||||
->whereIn('prescricao.id', $ids);
|
||||
}
|
||||
|
||||
private static function calcularDuracaoEmDias(?int $duracao, ?int $medidaTempoId): ?int
|
||||
{
|
||||
if (is_null($duracao)) {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($medidaTempoId === MedidaTempo::HORAS) {
|
||||
|
||||
return max(1, (int) ceil($duracao / 24));
|
||||
}
|
||||
|
||||
if ($medidaTempoId === MedidaTempo::SEMANAS) {
|
||||
|
||||
return $duracao * 7;
|
||||
}
|
||||
|
||||
if ($medidaTempoId === MedidaTempo::MESES) {
|
||||
|
||||
return $duracao * 30;
|
||||
}
|
||||
|
||||
return $duracao;
|
||||
}
|
||||
|
||||
private static function pluralizar(string $nome, int $valor): string
|
||||
{
|
||||
if (strpos($nome, '(es)') !== false) {
|
||||
|
||||
return $valor === 1
|
||||
? str_replace('(es)', '', $nome)
|
||||
: str_replace('(es)', 'es', $nome);
|
||||
}
|
||||
|
||||
if (strpos($nome, '(s)') !== false) {
|
||||
|
||||
return $valor === 1
|
||||
? str_replace('(s)', '', $nome)
|
||||
: str_replace('(s)', 's', $nome);
|
||||
}
|
||||
|
||||
return $nome;
|
||||
}
|
||||
|
||||
private static function montarPosologiaTexto($row): ?string
|
||||
{
|
||||
$texto = '';
|
||||
|
||||
if (!is_null($row->dose)) {
|
||||
|
||||
$dose = (float) trim($row->dose);
|
||||
$texto .= fmod($dose, 1) == 0 ? (int) $dose : number_format($dose, 2, ',', '.');
|
||||
|
||||
if ($row->apresentacao_unidade_medida) {
|
||||
|
||||
$texto .= ' ' . strtolower($row->apresentacao_unidade_medida);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_null($row->intervalo)) {
|
||||
|
||||
$intervalo = (int) $row->intervalo;
|
||||
|
||||
if ($row->intervalo_medida_tempo_nome) {
|
||||
|
||||
$unidade = strtolower(self::pluralizar($row->intervalo_medida_tempo_nome, $intervalo));
|
||||
$texto .= $intervalo === 1
|
||||
? " a cada {$unidade}"
|
||||
: " a cada {$intervalo} {$unidade}";
|
||||
} else {
|
||||
|
||||
$texto .= " a cada {$intervalo}";
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_null($row->duracao)) {
|
||||
|
||||
$dias = self::calcularDuracaoEmDias((int) $row->duracao, $row->duracao_medida_tempo_id);
|
||||
|
||||
if (!is_null($dias)) {
|
||||
|
||||
$texto .= $dias === 1 ? ' durante 1 dia' : " durante {$dias} dias";
|
||||
}
|
||||
}
|
||||
|
||||
return empty($texto) ? null : $texto;
|
||||
}
|
||||
|
||||
private static function log(int $pacienteId, string $tipoAcao, ?int $receitaId = null): void
|
||||
{
|
||||
AppCidadaoLog::create(
|
||||
[
|
||||
'paciente_id' => $pacienteId,
|
||||
'receita_id' => $receitaId,
|
||||
'tipo_acao' => $tipoAcao,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user