id); } $receita = new Receita; $receita->fill(array_fill_keys($receita->getFillable(), null)); $receita->isReceitaSus = true; $receita->isRemedioEmCasa = false; $item = new ReceitaItem; $item->fill(array_fill_keys($item->getFillable(), null)); $item->id = null; $item->entregue = null; $item->continuo = false; $item->estoque = 0; $item->escolheu_entrada_item_manualmente = false; $item->entrada_itens = []; $item->possui_entrada_com_lote = false; $item->supervisor_id = null; $item->dispensado_em = null; $item->programa = null; $medicamentosNaoPadronizados = new MedicamentoNaoPadronizado; $medicamentosNaoPadronizados->fill(array_fill_keys($medicamentosNaoPadronizados->getFillable(), null)); $medicamentosNaoPadronizados->id = null; $parametrizacaoLimitePrescricaoMedicamento = ParametrizacaoLimitePrescricaoMedicamento::first(); $limitePrescricaoMedicamento = isset($parametrizacaoLimitePrescricaoMedicamento) ? $parametrizacaoLimitePrescricaoMedicamento->limite_dias : 180; $paciente = self::getPaciente($pacienteId); $lastUpdated = self::getLastUpdated($paciente); $medicamentoSupervisor = ParametrizacaoMedicamentoSupervisor::first(); $parametrizacaoPosologia = ParametrizacaoPosologia::first(); $currentLotacao = self::getCurrentLotacao(); $cliente = Cliente::where('link', app('config')->get('database.default'))->firstOrFail(); $parametrizacaoDispensacao = ParametrizacaoDispensacao::first(); return [ 'additionals' => [ 'permissoes_atualizacao_cadastro_paciente' => self::getPermissoesAtualizacaoCadastroPaciente(), ], 'form' => [ 'data_atual' => Carbon::now()->format('d/m/Y'), 'paciente' => $paciente, 'ultima_atualizacao_cadastral' => $lastUpdated, 'unidades_medida_tempo' => self::getUnidadesMedidaTempo(), 'receitas_pendentes' => self::getReceitasPendentes($paciente), 'receitas_historico' => self::getHistoricoReceitas($pacienteId), 'medicamentos_nao_padronizados_cadastrados' => self::getMedicamentosNaoPadronizadosCadastrados(), 'medicamento_supervisor_dispensar' => $medicamentoSupervisor->dispensar ?? null, 'posologia_is_obrigatorio' => $parametrizacaoPosologia->is_obrigatorio ?? null, 'cliente' => [ 'sistema' => [ 'ramo_atividade' => [ 'nome' => $cliente->sistema->ramoAtividade->nome ?? null, ], 'nome' => $cliente->sistema->nome ?? null, 'versao' => $cliente->sistema->versao ?? null, ], 'municipio' => [ 'estado' => [ 'uf' => $cliente->municipio->estado->uf ?? null, ], 'nome' => $cliente->municipio->nome ?? null, ], 'nome' => $cliente->nome ?? null, 'email' => $cliente->email ?? null, 'site' => $cliente->site ?? null, 'logotipo' => $cliente->logotipo ?? null, ], 'usuario' => $currentLotacao->usuario->cidadao->nome, 'unidade' => $currentLotacao->infraestrutura->unidade->nome_fantasia, 'telefone' => MaskUtil::getPhoneMasked($currentLotacao->infraestrutura->telefone), 'solicitacoes_medicamentos' => ($parametrizacaoDispensacao->utiliza_solicitacao_medicamentos_ambulatorio ?? false) ? self::getSolicitacoesMedicamentos($pacienteId) : [], ], 'model' => array_merge( $receita->makeHidden(['id'])->toArray(), [ 'medico_solicitante' => null, 'cid' => null, 'item' => $item->toArray(), 'items' => [], 'receitas_pendentes_deleted' => [], 'items_entregas_estornados' => [], 'medicamento_nao_padronizado' => $medicamentosNaoPadronizados->toArray(), 'medicamentos_nao_padronizados' => self::getMedicamentosNaoPadronizados($pacienteId), 'limite_dias_prescricao_medicamento'=> $limitePrescricaoMedicamento, 'paciente' => [ 'id' => $paciente->id, 'observacao' => $paciente->observacao, 'save' => null, ], ], ), ]; } private static function getPaciente($id) { return Paciente::with( 'unidade', 'cidadao.domicilio.endereco.logradouro.municipio.estado', 'responsavel.usuario.cidadao', 'responsavel.equipe.area', 'responsavel.equipe.microarea', )->findOrFail($id); } private static function getUnidadesMedidaTempo() { return DB::table('geral_medida_tempo') ->select( 'id', 'nome' ) ->get(); } private static function getReceitasPendentes($paciente) { $receitas = DB::table('farmacia_receita') ->select( 'farmacia_receita.id', 'farmacia_receita.ambulatorio_prescricao_medicamento_id', 'farmacia_receita.usuario_id', DB::raw('DATE_FORMAT(farmacia_receita.data_receita, "%d/%m/%Y") AS data_receita'), 'farmacia_receita.numero_notificacao', 'farmacia_receita.cid_id', 'farmacia_receita.is_receita_sus', 'farmacia_receita.is_remedio_em_casa', 'farmacia_receita.observacao', 'farmacia_receita_item.id AS item_id', 'farmacia_receita_item.durante_tempo', 'farmacia_receita_item.intervalo_medida_tempo_id', 'farmacia_receita_item.intervalo_tempo', 'farmacia_receita_item.material_id', 'farmacia_receita_item.observacao AS item_observacao', 'farmacia_receita_item.prescrito', 'farmacia_receita_item.proxima_retirada', 'farmacia_receita_item.quantidade', 'farmacia_receita_item.receita_id', 'usuario_cidadao.nome AS usuario_nome', 'cid.codigo AS cid_codigo', 'cid.nome AS cid_nome', DB::raw(MaterialService::getDescricaoCompletaRaw( 'cadastro_material', 'cadastro_apresentacao', 'apresentacao_unidade_medida' ) . " AS material_descricao"), DB::raw("TRIM(cadastro_material.quantidade)+0 AS material_quantidade"), 'cadastro_apresentacao.nome AS material_apresentacao', DB::raw(" ( SELECT frie.quantidade FROM farmacia_receita_item_entrega frie WHERE frie.receita_item_id = farmacia_receita_item.id AND frie.pendente = 1 ) AS saldo "), DB::raw(" ( SELECT DATE_FORMAT(frie.dispensado_em, '%d/%m/%Y') FROM farmacia_receita_item_entrega frie WHERE frie.receita_item_id = farmacia_receita_item.id AND frie.pendente = 0 AND frie.estornado = 0 ORDER BY frie.id DESC LIMIT 1 ) AS ultima_saida ") ) ->join( 'cadastro_usuario', 'cadastro_usuario.id', 'farmacia_receita.usuario_id' ) ->join( 'cadastro_cidadao AS usuario_cidadao', 'usuario_cidadao.id', 'cadastro_usuario.cidadao_id' ) ->leftJoin( 'sigtap.cid AS cid', 'sigtap.cid.id', 'farmacia_receita.cid_id', ) ->join( 'farmacia_receita_item', 'farmacia_receita_item.receita_id', 'farmacia_receita.id' ) ->join( 'geral_medida_tempo', 'geral_medida_tempo.id', 'farmacia_receita_item.intervalo_medida_tempo_id', ) ->join( 'cadastro_material', 'cadastro_material.id', 'farmacia_receita_item.material_id' ) ->join( 'cadastro_apresentacao', 'cadastro_apresentacao.id', 'cadastro_material.apresentacao_id' ) ->join( 'cadastro_centro_custo as centro_custo', 'centro_custo.id', 'farmacia_receita.created_centro_custo_id' ) ->leftJoin( 'cadastro_unidade_medida as apresentacao_unidade_medida', 'apresentacao_unidade_medida.id', 'cadastro_material.apresentacao_unidade_medida_id' ) ->where('centro_custo.id', self::getCentroCustoLogado()->id) ->where('farmacia_receita.paciente_id', $paciente->id) ->whereExists(function ($query) { $query->select(DB::raw(1)) ->from('farmacia_receita_item_entrega') ->whereColumn( 'farmacia_receita_item_entrega.receita_item_id', 'farmacia_receita_item.id' ) ->where('farmacia_receita_item_entrega.pendente', true); }) ->get(); $collectionReceitas = collect([]); $receitas->map(function ($receita) use (&$collectionReceitas, $receitas) { if (!$collectionReceitas->contains('id', $receita->id)) { $collectionReceitas->push( [ 'id' => $receita->id, 'ambulatorio_prescricao_medicamento_id' => $receita->ambulatorio_prescricao_medicamento_id, 'usuario_id' => $receita->usuario_id, 'medico_solicitante' => [ 'id' => $receita->usuario_id, 'cidadao_nome' => $receita->usuario_nome, ], 'data_receita' => $receita->data_receita, 'numero_notificacao' => $receita->numero_notificacao, 'cid_id' => $receita->cid_id, 'cid' => [ 'id' => $receita->cid_id, 'nome' => $receita->cid_nome, 'codigo' => $receita->cid_codigo, ], 'is_receita_sus' => $receita->is_receita_sus == 1 ? true : false, 'is_remedio_em_casa' => $receita->is_remedio_em_casa == 1 ? true : false, 'observacao' => $receita->observacao, 'items' => self::getReceitaPendenteItems($receitas, $receita->id), ] ); } }); return $collectionReceitas; } public static function getMedicamentosAVencer() { $quantidadeMedicamentosAvencer = DB::query()->fromSub(DB::table('cadastro_material') ->select(DB::raw(1)) ->join('cadastro_grupo', 'cadastro_grupo.id', 'cadastro_material.grupo_id') ->join('almoxarifado_entrada_item', function ($join) { $join->on('almoxarifado_entrada_item.material_id', 'cadastro_material.id') ->whereExists(function ($query) { $query ->select(DB::raw('1')) ->from('almoxarifado_entrada') ->whereColumn('almoxarifado_entrada.id', 'almoxarifado_entrada_item.entrada_id') ->where('almoxarifado_entrada.finalizada', true) ->where('almoxarifado_entrada.centro_custo_id', self::getCurrentCentroCusto()->id); }); }) ->whereNull('cadastro_material.deleted_at') ->whereNotNull('almoxarifado_entrada_item.lote') ->where('cadastro_grupo.grupo_tipo_id', GrupoTipo::MEDICAMENTO) ->where('cadastro_material.is_ativo', true) ->whereRaw('DATEDIFF(almoxarifado_entrada_item.validade_lote, CURRENT_DATE) < 90') ->groupBy( 'cadastro_material.id', 'almoxarifado_entrada_item.lote', 'almoxarifado_entrada_item.validade_lote', ) ->havingRaw("(COALESCE(SUM( COALESCE(almoxarifado_entrada_item.quantidade, 0) - COALESCE(( SELECT SUM(almoxarifado_saida_item_entrada_item.quantidade_saida) FROM almoxarifado_saida_item_entrada_item JOIN almoxarifado_saida_item ON almoxarifado_saida_item.id = almoxarifado_saida_item_entrada_item.saida_item_id JOIN almoxarifado_saida ON almoxarifado_saida.id = almoxarifado_saida_item.saida_id WHERE almoxarifado_saida_item_entrada_item.entrada_item_id = almoxarifado_entrada_item.id AND almoxarifado_saida.finalizada = 1 ), 0) ), 0)) > 0") , 'sub')->count(); return ['medicamentos_a_vencer' => $quantidadeMedicamentosAvencer > 0 ? true : false]; } private static function getReceitaPendenteItems($receitas, $receitaId) { return $receitas->where('id', $receitaId)->map(function ($receita) { $material = Material::with('grupo')->findOrFail($receita->material_id); $programa = collect([]); if($material->grupo->grupo_tipo_id === GrupoTipo::MEDICAMENTO) { if($material->is_programa_remedio_em_casa) $programa->push("Programa remédio em casa"); if($material->is_alto_custo) $programa->push("Alto custo"); if($material->is_acao_judicial) $programa->push("Ação judicial"); if($material->is_remume) $programa->push("REMUME"); } $material->programa = $programa->isNotEmpty() ? implode(', ', $programa->toArray()) : '-'; $estoque = AlmoxarifadoService::getEstoque($receita->material_id); $entregue = $receita->saldo > $estoque['total'] ? $estoque['total'] : $receita->saldo; $entradaItensData = AlmoxarifadoService::getEntradaItensData( $receita->material_id, [ 'escolheu_entrada_item_manualmente' => false, 'quantidade' => $entregue, ] ); $entradaItensAutomaticos = []; foreach ($entradaItensData as $entradaItemId => $entradaItemData) { $entradaItensAutomaticos[] = [ 'entrada_item_id' => $entradaItemId, 'quantidade_saida' => $entradaItemData['quantidade_saida'], ]; } $entradaItens = collect($estoque['por_entrada']) ->map(function ($entradaItem) use ($entradaItensAutomaticos) { $entradaItem['quantidade_saida'] = collect($entradaItensAutomaticos) ->where('entrada_item_id', $entradaItem['entrada_item_id']) ->first()['quantidade_saida'] ?? 0; return $entradaItem; }); return [ 'id' => $receita->item_id, 'material_id' => $receita->material_id, 'material' => [ 'id' => $receita->material_id, 'descricao' => $receita->material_descricao, 'descricao_completa' => $receita->material_descricao, 'apresentacao' => Str::upper($receita->material_apresentacao), 'quantidade' => $receita->material_quantidade, ], 'quantidade' => $receita->quantidade, 'intervalo_tempo' => $receita->intervalo_tempo, 'intervalo_medida_tempo_id' => $receita->intervalo_medida_tempo_id, 'durante_tempo' => $receita->durante_tempo, 'prescrito' => $receita->prescrito, 'programa' => $material->programa, 'entregue' => $entregue, 'saldo' => $receita->saldo, 'ultima_saida' => $receita->ultima_saida, 'estoque' => $estoque['total'], 'escolheu_entrada_item_manualmente' => false, 'entrada_itens' => $entradaItens, 'possui_entrada_com_lote' => !is_null($entradaItens->whereNotNull('lote')->first()), 'proxima_retirada' => $receita->proxima_retirada ? (new Carbon($receita->proxima_retirada))->format('d/m/Y') : null, 'vencimento_receita' => $receita->proxima_retirada ? self::getVencimentoReceita($receita)->format('d/m/Y') : null, 'observacao' => $receita->item_observacao, ]; }) ->values(); } public static function getVencimentoReceita($receitaItem) { $proximaRetirada = new Carbon($receitaItem->proxima_retirada); if ($receitaItem->saldo > 0 && !is_null($receitaItem->prescrito)) { $multiplier = self::getMultiplierUnidadeTempoDurante($receitaItem->intervalo_medida_tempo_id); $days = ceil((($multiplier * $receitaItem->durante_tempo) / $receitaItem->prescrito) * $receitaItem->saldo); return $proximaRetirada->addDays($days); } return $proximaRetirada; } public static function getMultiplierUnidadeTempoDurante($intervaloMedidaTempoId) { switch ($intervaloMedidaTempoId) { case MedidaTempo::SEMANAS: return 7; case MedidaTempo::MESES: return 3; } return 1; } public static function getHistoricoReceitas($pacienteId) { $receitas = DB::table('farmacia_receita') ->select( 'farmacia_receita.id', 'farmacia_receita.is_remedio_em_casa', 'farmacia_receita.observacao', 'cadastro_unidade.nome_fantasia', 'medico_cidadao.nome AS medico_solicitante', 'usuario_cidadao.nome AS usuario_nome', 'farmacia_receita_item.prescrito', 'farmacia_receita_item_entrega.id AS receita_item_entrega_id', 'farmacia_receita_item_entrega.quantidade AS entregue', 'farmacia_receita_item_entrega.saida_item_id', 'farmacia_receita_item.observacao AS item_observacao', DB::raw(" IF(cadastro_infraestrutura.nome IS NULL, cadastro_unidade.nome_fantasia, cadastro_infraestrutura.nome )as infraestrutura_nome, DATE_FORMAT(farmacia_receita.data_receita, '%d/%m/%Y') AS data_receita, DATE_FORMAT(farmacia_receita_item_entrega.dispensado_em, '%d/%m/%Y %H:%i') AS dispensado_em, DATE_FORMAT(farmacia_receita_item.proxima_retirada, '%d/%m/%Y') AS proxima_retirada, " . MaterialService::getDescricaoCompletaRaw( 'cadastro_material', 'cadastro_apresentacao', 'apresentacao_unidade_medida' ) . " AS material_descricao, CAST(almoxarifado_saida.created_at AS DATE) as data_saida, farmacia_receita_item_entrega.estornado AS estornado "), ) ->join( 'farmacia_receita_item', 'farmacia_receita_item.receita_id', 'farmacia_receita.id' ) ->join( 'farmacia_receita_item_entrega', 'farmacia_receita_item_entrega.receita_item_id', 'farmacia_receita_item.id' ) ->join( 'almoxarifado_saida_item', 'almoxarifado_saida_item.id', 'farmacia_receita_item_entrega.saida_item_id' ) ->join( 'almoxarifado_saida', 'almoxarifado_saida.id', 'almoxarifado_saida_item.saida_id' ) ->join( 'cadastro_material', 'cadastro_material.id', 'farmacia_receita_item.material_id' ) ->join( 'cadastro_apresentacao', 'cadastro_apresentacao.id', 'cadastro_material.apresentacao_id' ) ->join( 'cadastro_centro_custo as centro_custo', 'centro_custo.id', 'farmacia_receita.created_centro_custo_id' ) ->leftJoin( 'cadastro_usuario', 'cadastro_usuario.id', 'farmacia_receita.usuario_id' ) ->leftJoin( 'cadastro_cidadao AS medico_cidadao', 'medico_cidadao.id', 'cadastro_usuario.cidadao_id' ) ->leftJoin( 'cadastro_lotacao', 'cadastro_lotacao.id', 'farmacia_receita.created_lotacao_id' ) ->leftJoin( 'cadastro_infraestrutura', 'cadastro_infraestrutura.id', 'cadastro_lotacao.infraestrutura_id' ) ->leftJoin( 'cadastro_unidade', 'cadastro_unidade.id', 'cadastro_infraestrutura.unidade_id' ) ->leftJoin( 'cadastro_usuario AS usuario_lotacao', 'usuario_lotacao.id', 'cadastro_lotacao.usuario_id' ) ->leftJoin( 'cadastro_cidadao AS usuario_cidadao', 'usuario_cidadao.id', 'usuario_lotacao.cidadao_id' ) ->leftJoin( 'cadastro_unidade_medida as apresentacao_unidade_medida', 'apresentacao_unidade_medida.id', 'cadastro_material.apresentacao_unidade_medida_id' ) ->where('farmacia_receita.paciente_id', $pacienteId) ->where('farmacia_receita_item_entrega.pendente', false) ->when(DataUtil::isStringBoolean(request()->query('programa_remedio_em_casa')), function ($query) { $isProgramaRemedioEmCasa = DataUtil::getBooleanValueFromStringBoolean(request()->query('programa_remedio_em_casa')); if ($isProgramaRemedioEmCasa) { $query->where('farmacia_receita.is_remedio_em_casa', $isProgramaRemedioEmCasa); } }); $complete = request()->query('complete'); if (!$complete || ($complete && DataUtil::isStringBoolean($complete))) { if (!$complete || !DataUtil::getBooleanValueFromStringBoolean($complete)) { $date = Carbon::now()->subMonths(6)->startOfDay(); $receitas->where('farmacia_receita_item_entrega.created_at', '>=', $date); } } $collectionReceitas = collect([]); $receitas = $receitas->get(); $receitas->map(function ($receita) use (&$collectionReceitas, $receitas) { if (!$collectionReceitas->contains('id', $receita->id)) { $collectionReceitas->push([ 'id' => $receita->id, 'data_receita' => $receita->data_receita, 'nome_fantasia' => $receita->nome_fantasia, 'infraestrutura' => $receita->infraestrutura_nome, 'medico_solicitante' => $receita->medico_solicitante, 'observacao' => $receita->observacao, 'is_remedio_em_casa' => $receita->is_remedio_em_casa, 'items' => self::getReceitaHistoricoItems($receitas, $receita->id), ]); } }); $paciente = Paciente::find($pacienteId); DB::table('farmacia_historico_dispensacao_v1') ->where('cidadao_id', $paciente->cidadao->id) ->when(!$complete, fn($q) => $q->where('data_solicitacao', '>=', Carbon::now()->subMonths(6)->startOfDay())) ->get() ->each(function($query) use (&$collectionReceitas, $paciente) { $collectionReceitas->push([ 'id' => null, 'id_v1' => $query->id, 'data_receita' => Carbon::parse($query->data_solicitacao)->format('d/m/Y'), 'nome_fantasia' => $query->nome_unidade, 'infraestrutura' => $query->nome_unidade, 'medico_solicitante' => $query->nome_medico, 'observacao' => $query->observacao, 'items' => [ [ 'receita_item_entrega_id' => null, 'material' => [ 'descricao' => $query->nome_medicamento, ], 'lotes' => [$query->lote], 'dispensado_em' => Carbon::parse($query->data_hora_dispensacao)->format('d/m/Y H:i'), 'prescrito' => $query->quantidade_receita, 'entregue' => $query->quantidade, 'proxima_retirada' => Carbon::parse($query->data_proxima_retirada)->format('d/m/Y'), 'observacao' => $query->observacao, 'data_saida' => null, 'estornado' => null, 'estorno_salvo' => null, ] ], ]); }); return $collectionReceitas->sortByDesc(fn($q) => Carbon::createFromFormat('d/m/Y', $q['data_receita'])->timestamp)->values()->all(); } private static function getReceitaHistoricoItems($receitas, $receitaId) { return $receitas->where('id', $receitaId)->map(function ($receita) { $lotes = collect(); SaidaItem::findOrFail($receita->saida_item_id)->entradaItens ->each(function ($entradaItem) use ($lotes) { if ($entradaItem->lote != null) { $loteExistente = $lotes->first(function ($lote) use ($entradaItem) { return $lote === "{$entradaItem->lote} ({$entradaItem->validade_lote->format('d/m/Y')})"; }); if (!$loteExistente) { $lotes->push("{$entradaItem->lote} ({$entradaItem->validade_lote->format('d/m/Y')})"); } } }); return [ 'receita_item_entrega_id' => $receita->receita_item_entrega_id, 'material' => [ 'descricao' => $receita->material_descricao, ], 'lotes' => $lotes, 'dispensado_em' => $receita->dispensado_em, 'usuario_nome' => $receita->usuario_nome, 'prescrito' => $receita->prescrito, 'entregue' => $receita->entregue, 'proxima_retirada' => $receita->proxima_retirada, 'observacao' => $receita->item_observacao, 'data_saida' => $receita->data_saida, 'estornado' => $receita->estornado, 'estorno_salvo' => $receita->estornado, ]; }) ->values(); } private static function getMedicamentosNaoPadronizados($pacienteId) { return DB::table('farmacia_medicamento_nao_padronizado') ->select( 'farmacia_medicamento_nao_padronizado.id', DB::raw("DATE_FORMAT(farmacia_medicamento_nao_padronizado.data_receita, '%d/%m/%Y') as data_receita"), 'cadastro_usuario.id AS usuario_id', 'cadastro_cidadao.nome AS medico_solicitante', 'farmacia_medicamento_nao_padronizado.medicamento_nao_padronizado_id', 'cadastro_medicamento_nao_padronizado.descricao as medicamento', 'farmacia_medicamento_nao_padronizado.quantidade' ) ->join( 'cadastro_medicamento_nao_padronizado', 'cadastro_medicamento_nao_padronizado.id', 'farmacia_medicamento_nao_padronizado.medicamento_nao_padronizado_id' ) ->join( 'cadastro_usuario', 'cadastro_usuario.id', 'farmacia_medicamento_nao_padronizado.usuario_id' ) ->join( 'cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id' ) ->join( 'cadastro_centro_custo as centro_custo', 'centro_custo.id', 'farmacia_medicamento_nao_padronizado.created_centro_custo_id' ) ->where('centro_custo.id', self::getCentroCustoLogado()->id) ->where('paciente_id', $pacienteId) ->get() ->map(function ($item) { return [ 'id' => $item->id, 'data_receita' => $item->data_receita, 'medico_solicitante' => [ 'id' => $item->usuario_id, 'cidadao_nome' => $item->medico_solicitante, ], 'medicamento' => [ 'id' => $item->medicamento_nao_padronizado_id, 'descricao' => $item->medicamento ], 'quantidade' => $item->quantidade, 'deleted' => false, 'save' => false, ]; }); } private static function getMedicamentosNaoPadronizadosCadastrados() { return DB::table('cadastro_medicamento_nao_padronizado') ->select( 'cadastro_medicamento_nao_padronizado.id', 'cadastro_medicamento_nao_padronizado.descricao', ) ->join( 'cadastro_centro_custo as centro_custo', 'centro_custo.id', 'cadastro_medicamento_nao_padronizado.created_centro_custo_id' ) ->where('centro_custo.id', self::getCentroCustoLogado()->id) ->get(); } private static function getSolicitacoesMedicamentos($pacienteId) { return DB::table('ambulatorio_atendimento_soap_prescricao_medicamento as prescricao') ->join('ambulatorio_atendimento_soap as soap', 'soap.id', 'prescricao.soap_id') ->join('ambulatorio_atendimento as atendimento', 'atendimento.id', 'soap.atendimento_id') ->join('cadastro_lotacao as lotacao', 'lotacao.id', 'prescricao.created_lotacao_id') ->join('cadastro_infraestrutura as infraestrutura', 'infraestrutura.id', 'lotacao.infraestrutura_id') ->join('cadastro_unidade as unidade', 'unidade.id', 'infraestrutura.unidade_id') ->join('cadastro_usuario as usuario', 'usuario.id', 'lotacao.usuario_id') ->join('cadastro_cidadao as cidadao', 'cidadao.id', 'usuario.cidadao_id') ->leftJoin('ambulatorio_atendimento_soap_problema_condicao as problema_condicao', fn ($j) => $j ->on('problema_condicao.soap_id', 'soap.id') ->where('problema_condicao.id', fn ($q) => $q ->select('id') ->from('ambulatorio_atendimento_soap_problema_condicao') ->whereColumn('soap_id', 'soap.id') ->whereNotNull('cid_id') ->limit(1) ) ) ->leftJoin('sigtap.cid as cid', 'cid.id', 'problema_condicao.cid_id') ->where('prescricao.solicitacao_fechada', false) ->where(fn ($q) => $q ->whereExists(fn ($q) => $q ->select(DB::raw(1)) ->from('ambulatorio_agendamento as agendamento') ->whereColumn('agendamento.id', 'atendimento.agendamento_id') ->where('agendamento.paciente_id', $pacienteId) ) ->orWhereExists(fn ($q) => $q ->select(DB::raw(1)) ->from('ambulatorio_demanda_espontanea as demanda_espontanea') ->whereColumn('demanda_espontanea.id', 'atendimento.demanda_espontanea_id') ->where('demanda_espontanea.paciente_id', $pacienteId) ) ) ->orderBy('prescricao.created_at') ->selectRaw(" prescricao.id as prescricao_id, prescricao.created_at as data_hora, IF(infraestrutura.nome IS NULL, unidade.nome_fantasia, CONCAT(unidade.nome_fantasia, ' - ', infraestrutura.nome) ) as unidade_infraestrutura, usuario.id as usuario_id, cidadao.nome as usuario_nome, cid.id as cid_id, cid.codigo as cid_codigo, cid.nome as cid_nome ") ->get() ->map(function ($solicitacao) { $solicitacao->descartado = false; return $solicitacao; }); } public static function getItensSolicitacaoMedicamento($prescricaoId) { return DB::table('ambulatorio_atendimento_soap_prescricao_medicamento_item as item') ->leftJoin('cadastro_material as material', 'material.id', 'item.material_id') ->leftJoin('cadastro_grupo as grupo', 'grupo.id', 'material.grupo_id') ->leftJoin('cadastro_apresentacao as apresentacao', 'apresentacao.id', 'material.apresentacao_id') ->leftJoin( 'cadastro_unidade_medida as apresentacao_unidade_medida', 'apresentacao_unidade_medida.id', 'material.apresentacao_unidade_medida_id') ->where('item.prescricao_medicamento_id', $prescricaoId) ->selectRaw(" item.descricao, item.material_id, " . MaterialService::getDescricaoCompletaRaw( 'material', 'apresentacao', 'apresentacao_unidade_medida' ) . " as material_descricao_completa, CAST(material.quantidade AS INTEGER) as material_quantidade, material.is_programa_remedio_em_casa as material_is_programa_remedio_em_casa, material.is_alto_custo as material_is_alto_custo, material.is_acao_judicial as material_is_acao_judicial, material.is_remume as material_is_remume, apresentacao_unidade_medida.nome as material_apresentacao_unidade_medida_nome, grupo.grupo_tipo_id as material_grupo_tipo_id, item.dose, item.frequencia_vezes, item.turno_id, item.intervalo, item.intervalo_medida_tempo_id, item.duracao, item.duracao_medida_tempo_id, item.recomendacoes, item.is_uso_continuo, item.is_dose_unica ") ->get() ->filter(fn ($i) => is_numeric($i->dose) && is_null($i->frequencia_vezes) && is_null($i->turno_id)) ->map(function ($item) { if (!is_null($item->duracao) && !is_null($item->intervalo_medida_tempo_id)) { $item->duracao = self::getDuracaoConvertida( $item->duracao, $item->duracao_medida_tempo_id, $item->intervalo_medida_tempo_id ); } $item->is_uso_continuo = (bool) $item->is_uso_continuo; $item->is_dose_unica = (bool) $item->is_dose_unica; $programa = collect([]); if ($item->material_grupo_tipo_id === GrupoTipo::MEDICAMENTO) { if ((bool) $item->material_is_programa_remedio_em_casa) { $programa->push("Programa remédio em casa"); } if ((bool) $item->material_is_alto_custo) { $programa->push("Alto custo"); } if ((bool) $item->material_is_acao_judicial) { $programa->push("Ação judicial"); } if ((bool) $item->material_is_remume) { $programa->push("REMUME"); } } $item->programa = $programa->isNotEmpty() ? implode(', ', $programa->toArray()) : '-'; $estoque = AlmoxarifadoService::getEstoque($item->material_id); $prescrito = self::getQuantidadePrescrita([ 'quantidade' => $item->dose, 'intervalo_tempo' => $item->intervalo, 'intervalo_medida_tempo_id' => $item->intervalo_medida_tempo_id, 'durante_tempo' => $item->duracao, 'material_quantidade' => $item->material_quantidade, 'is_dose_unica' => $item->is_dose_unica, 'is_uso_continuo' => $item->is_uso_continuo, ]); $entregue = is_null($prescrito) ? 0 : ($prescrito > $estoque['total'] ? $estoque['total'] : $prescrito); $entradaItensData = AlmoxarifadoService::getEntradaItensData( $item->material_id, [ 'escolheu_entrada_item_manualmente' => false, 'quantidade' => $entregue, ] ); $entradaItensAutomaticos = []; foreach ($entradaItensData as $entradaItemId => $entradaItemData) { $entradaItensAutomaticos[] = [ 'entrada_item_id' => $entradaItemId, 'quantidade_saida' => $entradaItemData['quantidade_saida'], ]; } $entradaItens = collect($estoque['por_entrada']) ->map(function ($entradaItem) use ($entradaItensAutomaticos) { $entradaItem['quantidade_saida'] = collect($entradaItensAutomaticos) ->where('entrada_item_id', $entradaItem['entrada_item_id']) ->first()['quantidade_saida'] ?? 0; return $entradaItem; }); $item->estoque = $estoque['total']; $item->prescrito = $prescrito; $item->entregue = $entregue; $item->escolheu_entrada_item_manualmente = false; $item->entrada_itens = $entradaItens; $item->possui_entrada_com_lote = !is_null($entradaItens->whereNotNull('lote')->first()); unset( $item->material_grupo_tipo_id, $item->material_is_programa_remedio_em_casa, $item->material_is_alto_custo, $item->material_is_acao_judicial, $item->material_is_remume ); return $item; }) ->filter(fn ($i) => !is_null($i->entregue) && $i->entregue > 0) ->values(); } private static function getDuracaoConvertida($duracao, $duracaoMedidaTempoId, $intervaloMedidaTempoId) { $duracao = (int) $duracao; if (collect([MedidaTempo::MINUTOS, MedidaTempo::HORAS, MedidaTempo::DIAS])->contains($intervaloMedidaTempoId)) { $duracaoEmDias = null; if ($duracaoMedidaTempoId === MedidaTempo::DIAS) { $duracaoEmDias = $duracao; } else if ($duracaoMedidaTempoId === MedidaTempo::SEMANAS) { $duracaoEmDias = $duracao * 7; } else if ($duracaoMedidaTempoId === MedidaTempo::MESES) { $duracaoEmDias = $duracao * 30; } return $duracaoEmDias; } return $duracao; } private static function getQuantidadePrescrita($params) { if (!is_numeric($params['quantidade'])) { return null; } $calc = function ($intervaloTempo, $intervaloMedidaTempoId, $duranteTempo) use ($params) { $quantidade = (int) $params['quantidade']; $materialQuantidade = (float) $params['material_quantidade']; $multiplier = self::getUnidadeMedidaTempoMultiplier($intervaloMedidaTempoId); return ceil($quantidade * $multiplier / $intervaloTempo * $duranteTempo / $materialQuantidade); }; if ($params['is_dose_unica']) { if (!is_numeric($params['durante_tempo'])) { return null; } return $calc(1, MedidaTempo::DIAS, (int) $params['durante_tempo']); } else if ($params['is_uso_continuo'] || !is_numeric($params['durante_tempo'])) { $parametrizacaoLimitePrescricaoMedicamento = ParametrizacaoLimitePrescricaoMedicamento::first(); $limiteDias = isset($parametrizacaoLimitePrescricaoMedicamento) ? (int) $parametrizacaoLimitePrescricaoMedicamento->limite_dias : null; if (!is_numeric($params['intervalo_tempo']) || is_null($params['intervalo_medida_tempo_id']) || is_null($limiteDias) || $limiteDias === 0 ) { return null; } $duranteTempo = self::getDuracaoConvertida($limiteDias, MedidaTempo::DIAS, $params['intervalo_medida_tempo_id']); return $calc((int) $params['intervalo_tempo'], $params['intervalo_medida_tempo_id'], $duranteTempo); } else { if (!is_numeric($params['intervalo_tempo']) || is_null($params['intervalo_medida_tempo_id'])) { return null; } return $calc((int) $params['intervalo_tempo'], $params['intervalo_medida_tempo_id'], (int) $params['durante_tempo']); } } private static function getUnidadeMedidaTempoMultiplier($intervaloMedidaTempoId) { switch ($intervaloMedidaTempoId) { case MedidaTempo::MINUTOS: return 24 * 60; case MedidaTempo::HORAS: return 24; case MedidaTempo::DIAS: return 1; case MedidaTempo::SEMANAS: return 1; case MedidaTempo::MESES: return 1; default: return 0; } } public static function getUltimaRetirada() { $params = request()->all(); return DB::table('farmacia_receita_item') ->select( DB::raw("DATE_FORMAT(farmacia_receita_item.proxima_retirada, '%d/%m/%Y') AS proxima_retirada"), ) ->join( 'farmacia_receita', 'farmacia_receita.id', 'farmacia_receita_item.receita_id' ) ->where('farmacia_receita_item.material_id', $params['material_id']) ->where('farmacia_receita.paciente_id', $params['paciente_id']) ->orderByDesc('farmacia_receita_item.id') ->first(); } public static function getSupervisor() { return [ 'supervisores' => Supervisor::where('usuario_id', request()->supervisor_id) ->where('infraestrutura_id', self::getCentroCustoLogado()->infraestrutura_id) ->get() ->map(fn ($supervisor) => [ 'id' => $supervisor->id, 'usuario_id' => $supervisor->usuario_id, ]), ]; } public static function show($id) { return Receita::findOrFail($id); } public static function store() { self::validate(); $receita = null; DB::transaction(function () use (&$receita) { $params = request()->all(); if ($params['paciente']['save'] === true) { $paciente = Paciente::findOrFail($params['paciente_id']); $paciente->observacao = $params['paciente']['observacao']; $paciente->save(); } $params['items'] = collect($params['items']); if ($params['items']->count() > 0) { $paciente = Paciente::findOrFail($params['paciente_id']); $paciente->observacao = $params['paciente']['observacao']; $paciente->save(); $receita = Receita::create($params)->fresh(); $receitaItemEntregas = collect(); $receita->operadores = collect([]); $params['items']->map(function ($item) use ($receita, $receitaItemEntregas) { $item['receita_id'] = $receita->id; $receitaItem = ReceitaItem::create($item); $now = Carbon::now(); $dispensadoEm = new Carbon($item['dispensado_em']); $dispensadoEm->setTime($now->hour, $now->minute, $now->second); $receita['dispensado_em'] = $dispensadoEm->format('d/m/Y'); $receita['hora_atendimento'] = $dispensadoEm->format('H:i'); $receitaItemEntregaSaved = ReceitaItemEntrega::create([ 'receita_item_id' => $receitaItem->id, 'quantidade' => $item['entregue'], 'dispensado_em' => $dispensadoEm, ]); if (!$receita->operadores->contains($receitaItemEntregaSaved->createdLotacao->usuario->cidadao->nome)) { $receita->operadores->push($receitaItemEntregaSaved->createdLotacao->usuario->cidadao->nome); } $receitaItemEntregas->push([ 'receita_item_entrega_id' => $receitaItemEntregaSaved->id, 'material_id' => $receitaItem->material_id, 'quantidade' => $receitaItemEntregaSaved->quantidade, 'escolheu_entrada_item_manualmente' => $item['escolheu_entrada_item_manualmente'], 'entrada_itens' => $item['entrada_itens'], ]); if ($item['entregue'] < $item['prescrito']) { ReceitaItemEntrega::create([ 'receita_item_id' => $receitaItem->id, 'quantidade' => $item['prescrito'] - $item['entregue'], 'pendente' => true, ]); } }); $saidaItens = AlmoxarifadoService::saveSaidaDeDispensacaoDaFarmacia($receitaItemEntregas); $saidaItens->each(function ($data) { ReceitaItemEntrega::findOrFail($data['receita_item_entrega_id']) ->update(['saida_item_id' => $data['saida_item_id']]); }); if (!is_null($params['ambulatorio_prescricao_medicamento_id'])) { AtendimentoSoapPrescricaoMedicamento::where('id', $params['ambulatorio_prescricao_medicamento_id']) ->update(['solicitacao_fechada' => true]); } } if (count($params['solicitacoes_medicamentos_descartadas']) > 0) { AtendimentoSoapPrescricaoMedicamento::whereIn('id', $params['solicitacoes_medicamentos_descartadas']) ->update(['solicitacao_fechada' => true]); } if (count($params['medicamentos_nao_padronizados']) > 0) { self::saveMedicamentosNaoPadronizados($params['medicamentos_nao_padronizados']); } if (count($params['receitas_pendentes_deleted']) > 0) { self::destroyItemsPendentesEntrega($params['receitas_pendentes_deleted']); } if (count($params['items_entregas_estornados']) > 0) { self::estornarItensEntregas($params['items_entregas_estornados']); } if (isset($params['fila_id'])) { FilaAtendimentoService::finalize($params['fila_id']); } }); return $receita; } public static function update($id) { self::validate(); $receita = self::show($id); DB::transaction(function () use (&$receita) { $params = request()->all(); $params['paciente_id'] = $params['paciente']['id']; $params['items'] = collect($params['items']); $paciente = Paciente::findOrFail($params['paciente_id']); $paciente->observacao = $params['paciente']['observacao']; $paciente->save(); $receita->observacao = $params['observacao']; $receitaItemEntregas = collect(); $receita->operadores = collect([]); $params['items']->map(function ($item) use ($receita, $receitaItemEntregas) { $receitaItem = ReceitaItem::findOrFail($item['id']); $receitaItem->observacao = $item['observacao']; $receitaItem->proxima_retirada = $item['proxima_retirada']; $receitaItem->save(); $now = Carbon::now(); $dispensadoEm = new Carbon($item['dispensado_em']); $dispensadoEm->setTime($now->hour, $now->minute, $now->second); $receita['dispensado_em'] = $dispensadoEm->format('d/m/Y'); $receita['hora_atendimento'] = $dispensadoEm->format('H:i'); $receitaItemEntregaSaved = ReceitaItemEntrega::where('receita_item_id', $receitaItem->id) ->where('pendente', 1) ->first(); $receitaItemEntregaSaved->update([ 'quantidade' => $item['entregue'], 'pendente' => false, 'dispensado_em' => $dispensadoEm, ]); if (!$receita->operadores->contains($receitaItemEntregaSaved->createdLotacao->usuario->cidadao->nome)) { $receita->operadores->push($receitaItemEntregaSaved->createdLotacao->usuario->cidadao->nome); } $receitaItemEntregaSaved->refresh(); $receitaItemEntregas->push([ 'receita_item_entrega_id' => $receitaItemEntregaSaved->id, 'material_id' => $receitaItem->material_id, 'quantidade' => $receitaItemEntregaSaved->quantidade, 'escolheu_entrada_item_manualmente' => $item['escolheu_entrada_item_manualmente'], 'entrada_itens' => $item['entrada_itens'], ]); if ($item['entregue'] < $item['saldo']) { ReceitaItemEntrega::create([ 'receita_item_id' => $receitaItem->id, 'quantidade' => $item['saldo'] - $item['entregue'], 'pendente' => true ]); } }); if ($receitaItemEntregas->isNotEmpty()) { $saidaItens = AlmoxarifadoService::saveSaidaDeDispensacaoDaFarmacia($receitaItemEntregas); $saidaItens->each(function ($data) { ReceitaItemEntrega::findOrFail($data['receita_item_entrega_id']) ->update(['saida_item_id' => $data['saida_item_id']]); }); } if (count($params['medicamentos_nao_padronizados']) > 0) { self::saveMedicamentosNaoPadronizados($params['medicamentos_nao_padronizados']); } if (count($params['receitas_pendentes_deleted']) > 0) { self::destroyItemsPendentesEntrega($params['receitas_pendentes_deleted']); } if (count($params['items_entregas_estornados']) > 0) { self::estornarItensEntregas($params['items_entregas_estornados']); } }); return $receita; } private static function saveMedicamentosNaoPadronizados($medicamentosNaoPadronizados) { $medicamentosNaoPadronizados = collect($medicamentosNaoPadronizados); $medicamentosNaoPadronizados->map(function ($medicamento) { if (isset($medicamento['deleted']) && $medicamento['deleted']) { MedicamentoNaoPadronizado::findOrFail($medicamento['id'])->delete(); } else { if (!is_null($medicamento['id'])) { $medicFind = MedicamentoNaoPadronizado::findOrFail($medicamento['id']); $medicFind->fill($medicamento); $medicFind->save(); } else { $medic = new MedicamentoNaoPadronizado; MedicamentoNaoPadronizado::create($medic->fill($medicamento)->toArray()); } } }); } private static function destroyItemsPendentesEntrega($items) { $items = collect($items); $items->map(function ($item) { ReceitaItemEntrega::where('receita_item_id', $item['id']) ->where('pendente', 1) ->delete(); }); } private static function estornarItensEntregas($itensEntregasEstornados) { foreach ($itensEntregasEstornados as $itemEntregaId) { $entrega = ReceitaItemEntrega::findOrFail($itemEntregaId); EstornoDispensacaoService::estornar($entrega); } } public static function validate() { $params = request()->all(); $rules = [ 'ambulatorio_prescricao_medicamento_id' => [ 'nullable', 'integer', ], 'usuario_id' => [ 'nullable', 'integer', Rule::requiredIf(fn () => count($params['items'])), ], 'data_receita' => [ 'nullable', 'date_format:Y-m-d', 'before_or_equal:now', Rule::requiredIf(fn () => count($params['items'])), ], 'numero_notificacao' => [ 'nullable', 'string', 'max:8' ], 'cid_id' => [ 'nullable', 'integer' ], 'is_receita_sus' => [ 'required', 'boolean' ], 'is_remedio_em_casa' => [ 'required', 'boolean' ], 'observacao' => [ 'nullable', 'string', 'between:3,300' ], 'items' => [ 'nullable', 'array' ], 'items.*.receita_id' => [ 'nullable', 'integer', ], 'items.*.material_id' => [ 'required', 'integer' ], 'dispensado_em' => [ 'nullable', 'date_format:Y-m-d H:i', 'before_or_equal:now', ], 'items.*.quantidade' => [ 'nullable', 'numeric', 'min:0.01', 'required_if:farmacia_parametrizacao_posologia.is_obrigatorio,true', ], 'items.*.intervalo_tempo' => [ 'nullable', 'integer', 'required_if:farmacia_parametrizacao_posologia.is_obrigatorio,true', ], 'items.*.intervalo_medida_tempo_id' => [ 'nullable', 'integer', 'required_if:farmacia_parametrizacao_posologia.is_obrigatorio,true', ], 'items.*.durante_tempo' => [ 'nullable', 'integer' ], 'items.*.prescrito' => [ 'nullable', 'numeric' ], 'items.*.proxima_retirada' => [ 'required', 'date_format:Y-m-d', ], 'items.*.observacao' => [ 'nullable', 'string', 'between:3,300' ], 'items.*.retiradas' => [ 'nullable', 'array' ], 'items.*.entregas.*.receita_item_id' => [ 'required', 'integer' ], 'items.*.entregas.*.quantidade' => [ 'required', 'integer' ] ]; $messages = [ 'items.*.intervalo_tempo.integer' => 'O campo "intervalo de tempo" deve ser um número inteiro.' ]; request()->validate($rules, $messages); } public static function getReceitaDispensada($receitaId, $items = []) { $receita = DB::table('farmacia_receita') ->select( 'farmacia_receita.id', DB::raw(" DATE_FORMAT( ( SELECT MAX(frie.dispensado_em) ultima_entrega FROM farmacia_receita_item_entrega frie JOIN farmacia_receita_item fri ON fri.id = frie.receita_item_id WHERE fri.receita_id = farmacia_receita.id AND frie.pendente = 0 AND frie.estornado = 0 ), '%d/%m/%Y %H:%i' ) AS dispensado_em "), 'farmacia_receita.is_remedio_em_casa', 'cidadao_paciente.nome AS nome_paciente', 'cidadao_paciente.nome_social AS nome_social_paciente', 'cidadao_paciente.preferencia_nome_id', 'cidadao_paciente.data_nascimento AS data_nascimento_paciente', 'cadastro_paciente.prontuario AS prontuario_paciente', 'cidadao_medico_solicitante.nome AS nome_medico_solicitante', 'cadastro_logradouro_tipo.descricao AS tipo_logradouro_descricao', 'cadastro_logradouro.nome AS logradouro_nome', 'cadastro_logradouro.cep AS logradouro_cep', DB::raw("COALESCE(cadastro_endereco.numero, 'S/N') AS endereco_numero"), 'cadastro_bairro.nome AS endereco_bairro_nome', 'intranet.cadastro_municipio.nome AS endereco_municipio_nome', 'intranet.cadastro_estado.uf AS endereco_uf', 'unidade_referencia.nome_fantasia AS paciente_unidade_referencia' ) ->join( 'cadastro_paciente', 'cadastro_paciente.id', 'farmacia_receita.paciente_id' ) ->join( 'cadastro_cidadao AS cidadao_paciente', 'cidadao_paciente.id', 'cadastro_paciente.cidadao_id' ) ->join( 'cadastro_lotacao AS lotacao_usuario', 'lotacao_usuario.id', 'farmacia_receita.created_lotacao_id', ) ->join( 'cadastro_usuario AS usuario_medico_solicitante', 'usuario_medico_solicitante.id', 'farmacia_receita.usuario_id' ) ->join( 'cadastro_cidadao AS cidadao_medico_solicitante', 'cidadao_medico_solicitante.id', 'usuario_medico_solicitante.cidadao_id' ) ->leftJoin( 'cadastro_unidade AS unidade_referencia', 'unidade_referencia.id', 'cadastro_paciente.unidade_id', ) ->leftJoin('cadastro_domicilio', 'cadastro_domicilio.id', 'cidadao_paciente.domicilio_id') ->leftJoin('cadastro_endereco', 'cadastro_endereco.id', 'cadastro_domicilio.endereco_id') ->leftJoin('cadastro_logradouro', 'cadastro_logradouro.id', 'cadastro_endereco.logradouro_id') ->leftJoin('cadastro_logradouro_tipo', 'cadastro_logradouro_tipo.id', 'cadastro_logradouro.tipo_id') ->leftJoin('cadastro_bairro', 'cadastro_bairro.id', 'cadastro_logradouro.bairro_id') ->leftJoin('intranet.cadastro_municipio', 'cadastro_municipio.id', 'cadastro_logradouro.municipio_id') ->leftJoin('intranet.cadastro_estado', 'cadastro_estado.id', 'cadastro_municipio.estado_id') ->where('farmacia_receita.id', $receitaId) ->first(); $receita->itens = self::getReceitaDispensadaItem($receitaId, $items); $receita->operadores = collect([]); $receita->itens->map(function ($item) use (&$receita) { if (!$receita->operadores->contains($item->nome_usuario)) { $receita->operadores->push($item->nome_usuario); } }); return $receita; } public static function printReceitaDispensada($receitaId, $items = []) { $receita = DB::table('farmacia_receita') ->select( 'farmacia_receita.id', DB::raw(" DATE_FORMAT( ( SELECT MAX(frie.dispensado_em) ultima_entrega FROM farmacia_receita_item_entrega frie JOIN farmacia_receita_item fri ON fri.id = frie.receita_item_id WHERE fri.receita_id = farmacia_receita.id AND frie.pendente = 0 AND frie.estornado = 0 ), '%d/%m/%Y %H:%i' ) AS dispensado_em "), 'farmacia_receita.is_remedio_em_casa', 'cidadao_paciente.nome AS nome_paciente', 'cidadao_paciente.nome_social AS nome_social_paciente', 'cidadao_paciente.preferencia_nome_id', 'cidadao_paciente.data_nascimento AS data_nascimento_paciente', 'cadastro_paciente.prontuario AS prontuario_paciente', 'cidadao_medico_solicitante.nome AS nome_medico_solicitante', 'cadastro_logradouro_tipo.descricao AS tipo_logradouro_descricao', 'cadastro_logradouro.nome AS logradouro_nome', 'cadastro_logradouro.cep AS logradouro_cep', DB::raw("COALESCE(cadastro_endereco.numero, 'S/N') AS endereco_numero"), 'cadastro_bairro.nome AS endereco_bairro_nome', 'intranet.cadastro_municipio.nome AS endereco_municipio_nome', 'intranet.cadastro_estado.uf AS endereco_uf', DB::raw(" COALESCE( unidade_referencia.nome_fantasia, 'NÃO INFORMADO NO CADASTRO DO PACIENTE' ) AS paciente_unidade_referencia ") ) ->join( 'cadastro_paciente', 'cadastro_paciente.id', 'farmacia_receita.paciente_id' ) ->join( 'cadastro_cidadao AS cidadao_paciente', 'cidadao_paciente.id', 'cadastro_paciente.cidadao_id' ) ->join( 'cadastro_lotacao AS lotacao_usuario', 'lotacao_usuario.id', 'farmacia_receita.created_lotacao_id', ) ->join( 'cadastro_usuario AS usuario_medico_solicitante', 'usuario_medico_solicitante.id', 'farmacia_receita.usuario_id' ) ->join( 'cadastro_cidadao AS cidadao_medico_solicitante', 'cidadao_medico_solicitante.id', 'usuario_medico_solicitante.cidadao_id' ) ->leftJoin( 'cadastro_unidade AS unidade_referencia', 'unidade_referencia.id', 'cadastro_paciente.unidade_id', ) ->leftJoin('cadastro_domicilio', 'cadastro_domicilio.id', 'cidadao_paciente.domicilio_id') ->leftJoin('cadastro_endereco', 'cadastro_endereco.id', 'cadastro_domicilio.endereco_id') ->leftJoin('cadastro_logradouro', 'cadastro_logradouro.id', 'cadastro_endereco.logradouro_id') ->leftJoin('cadastro_logradouro_tipo', 'cadastro_logradouro_tipo.id', 'cadastro_logradouro.tipo_id') ->leftJoin('cadastro_bairro', 'cadastro_bairro.id', 'cadastro_logradouro.bairro_id') ->leftJoin('intranet.cadastro_municipio', 'cadastro_municipio.id', 'cadastro_logradouro.municipio_id') ->leftJoin('intranet.cadastro_estado', 'cadastro_estado.id', 'cadastro_municipio.estado_id') ->where('farmacia_receita.id', $receitaId) ->first(); $receita->itens = self::getReceitaDispensadaItem($receitaId, $items); $receita->operadores = collect([]); $receita->itens->map(function ($item) use (&$receita) { if (!$receita->operadores->contains($item->nome_usuario)) { $receita->operadores->push($item->nome_usuario); } }); $receita->data_nascimento_paciente = (new Carbon($receita->data_nascimento_paciente))->format('d/m/Y'); $receita->itens->map(function ($item) { $item->vencimento_receita = $item->proxima_retirada ? self::getVencimentoReceita($item)->format('d/m/Y') : null; $item->proxima_retirada = $item->proxima_retirada ? (new Carbon($item->proxima_retirada))->format('d/m/Y') : null; $item->material = [ 'descricao_completa' => $item->material_descricao ]; $entradaItens = SaidaItem::findOrFail($item->saida_item_id)->entradaItens->map(function ($entradaItem) { return [ 'lote' => $entradaItem->lote, 'validade_lote' => $entradaItem->validade_lote ? $entradaItem->validade_lote->format('d/m/Y') : null, 'quantidade_saida' => $entradaItem->pivotSaidaItemEntradaItem->quantidade_saida, ]; }); $entradaItens = $entradaItens->groupBy(function ($item) { return $item['lote'] . '_' . $item['validade_lote']; }); $entradaItens = $entradaItens->values()->map(function ($item) { $totalQuantidadeSaida = $item->sum('quantidade_saida'); $firstItem = $item->first(); return [ 'lote' => $firstItem['lote'], 'validade_lote' => $firstItem['validade_lote'], 'quantidade_saida' => $totalQuantidadeSaida, ]; }); $item->entradaItens = $entradaItens->all(); }); $dispensadoEm = Carbon::createFromFormat('d/m/Y H:i', $receita->dispensado_em); $receita->dispensado_em = $dispensadoEm->format('d/m/Y'); $receita->hora_atendimento = $dispensadoEm->format('H:i'); return $receita; } public static function printReceitaHistorico($id) { $query = DB::table('farmacia_historico_dispensacao_v1')->find($id); $data_hora_dispensacao = Carbon::parse($query->data_hora_dispensacao); return [ 'operadores' => [], 'nome_medico_solicitante' => $query->nome_medico, 'itens' => [ [ 'material' => [ 'descricao_completa' => $query->nome_medicamento ], 'prescrito' => $query->quantidade_receita, 'proxima_retirada' => Carbon::parse($query->data_proxima_retirada)->format('d/m/Y'), 'entrada_itens' => [ [ 'lote' => $query->lote, 'dispensado_em' => Carbon::parse($query->data_hora_dispensacao)->format('d/m/Y H:i'), 'quantidade_saida' => $query->quantidade, 'observacao' => $query->observacao, ] ] ] ], 'dispensado_em' => $data_hora_dispensacao->format('d/m/Y'), 'hora_atendimento' => $data_hora_dispensacao->format('H:i') ]; } private static function getReceitaDispensadaItem($receitaId, $items = []) { $receitaItem = DB::table('farmacia_receita_item') ->select( 'farmacia_receita_item.id AS item_id', 'farmacia_receita_item.durante_tempo', 'farmacia_receita_item.intervalo_medida_tempo_id', 'farmacia_receita_item.intervalo_tempo', 'farmacia_receita_item.material_id', 'farmacia_receita_item.observacao AS item_observacao', 'farmacia_receita_item.prescrito', 'farmacia_receita_item.proxima_retirada', 'farmacia_receita_item.quantidade', 'farmacia_receita_item.receita_id', 'farmacia_receita_item_entrega.quantidade AS retirado', 'farmacia_receita_item_entrega.saida_item_id', 'cidadao_usuario.nome AS nome_usuario', DB::raw(" " . MaterialService::getDescricaoCompletaRaw( 'cadastro_material', 'cadastro_apresentacao', 'apresentacao_unidade_medida' ) . " AS material_descricao, DATE_FORMAT(farmacia_receita_item_entrega.dispensado_em, '%d/%m/%Y %H:%i') AS dispensado_em, ( SELECT frie.quantidade FROM farmacia_receita_item_entrega frie WHERE frie.receita_item_id = farmacia_receita_item.id AND frie.pendente = 1 ) AS saldo "), ) ->join( 'cadastro_material', 'cadastro_material.id', 'farmacia_receita_item.material_id' ) ->join( 'cadastro_apresentacao', 'cadastro_apresentacao.id', 'cadastro_material.apresentacao_id' ) ->join( 'farmacia_receita_item_entrega', 'farmacia_receita_item_entrega.receita_item_id', 'farmacia_receita_item.id' ) ->join( 'cadastro_lotacao', 'cadastro_lotacao.id', 'farmacia_receita_item_entrega.created_lotacao_id' ) ->join( 'cadastro_usuario AS usuario_lotacao', 'usuario_lotacao.id', 'cadastro_lotacao.usuario_id' ) ->join( 'cadastro_cidadao AS cidadao_usuario', 'cidadao_usuario.id', 'usuario_lotacao.cidadao_id' ) ->leftJoin( 'cadastro_unidade_medida as apresentacao_unidade_medida', 'apresentacao_unidade_medida.id', 'cadastro_material.apresentacao_unidade_medida_id' ) ->where('farmacia_receita_item.receita_id', $receitaId) ->where('farmacia_receita_item_entrega.pendente', false) ->where('farmacia_receita_item_entrega.estornado', false); $items = collect($items); if ($items->count() > 0) { $receitaItem->whereIn('farmacia_receita_item_entrega.receita_item_id', $items->pluck('id')->toArray()); } return $receitaItem->get(); } private static function getCentroCustoLogado() { return CentroCusto::findOrFail(auth()->payload()->get('centro_custo_id')); } public static function getDataProximaRetirada($fromDate, $item) { $fromDate->setTime(0, 0, 0); $getMultiplierUnidadeTempoDurante = function ($unidadesMedidaTempoDurante) { switch ($unidadesMedidaTempoDurante) { case MedidaTempo::SEMANAS: return 7; case MedidaTempo::MESES: return 30; default: return 1; } }; $getUnidadeMedidaTempoMultiplier = function ($intervaloMedidaTempoId) { switch ($intervaloMedidaTempoId) { case MedidaTempo::MINUTOS: return 24 * 60; case MedidaTempo::HORAS: return 24; case MedidaTempo::DIAS: return 1; case MedidaTempo::SEMANAS: return 1; case MedidaTempo::MESES: return 1; default: return 0; } }; $multiplier = $getMultiplierUnidadeTempoDurante($item['intervalo_medida_tempo_id']); if ($item['continuo']) { $unidadeMedidaTempoMultiplier = $getUnidadeMedidaTempoMultiplier($item['intervalo_medida_tempo_id']); $entregueXmaterialQuantidade = $item['entregue'] * $item['material']['quantidade']; $days = $entregueXmaterialQuantidade / (($unidadeMedidaTempoMultiplier / $item['intervalo_tempo']) * $item['quantidade']); return $fromDate->addDays(round($days)); } if ($item['durante_tempo']) { $days = $multiplier * $item['durante_tempo']; if ($item['prescrito'] != $item['entregue']) { $diff = $item['prescrito'] / $item['entregue']; $days = $item['durante_tempo'] / $diff; } return $fromDate->addDays(round($days)); } return null; } private static function getPermissoesAtualizacaoCadastroPaciente() { $parametrizacao = CnsService::getParametrizacao(); if (!is_null($parametrizacao)) { $lotacao = self::getCurrentLotacao(); return DB::table('cadastro_parametrizacao_permissao_usuario') ->select([ 'municipe', 'provisorio', 'outro_municipio', ]) ->where('infraestrutura_id', $lotacao->infraestrutura_id) ->where('usuario_id', $lotacao->usuario_id) ->get() ->first(); } return null; } private static function getLastUpdated($paciente) { $updatedPaciente = $paciente->updated_at; $updatedCidadao = $paciente->cidadao->updated_at ?? null; if ($updatedPaciente && $updatedCidadao) { $data = $updatedPaciente > $updatedCidadao ? $updatedPaciente : $updatedCidadao; } else { $data = $updatedPaciente ?? $updatedCidadao; } return $data ? $data->format('d/m/Y') : null; } }