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, ] ); } }