Inconsistencia::CNES_DA_UNIDADE_COM_TAMANHO_DIFERENTE_DE_7_CARACTERES, IbgeIsValid::class => Inconsistencia::IBGE_DO_MUNICIPIO_SEM_PREENCHIMENTO_OU_INVALIDO, Cns::class => Inconsistencia::CNS_DO_PROFISSIONAL_INVALIDO, OcupacaoIsAllowed::class => Inconsistencia::OCUPACAO_DO_USUARIO_SEM_PERMISSAO_PARA_REGISTRAR_A_FICHA, DataAtendimentoIsValid::class => Inconsistencia::DATA_ATENDIMENTO_INVALIDO, ]; private const ATENDIMENTO_ERROR_MAP = [ CnsPaciente::class => Inconsistencia::CNS_DO_PACIENTE_INVALIDO, Cpf::class => Inconsistencia::CPF_DO_PACIENTE_INVALIDO, DataNascimentoIsRequired::class => Inconsistencia::DATA_NASCIMENTO_SEM_PREENCHIMENTO, DataNascimentoIsValid::class => Inconsistencia::DATA_DE_NASCIMENTO_POSTERIOR_A_DATA_DE_ATENDIMENTO_SUPERIOR_A_130_ANOS_OU_NAO_PREENCHIDA, LocalAtendimentoIsRequired::class => Inconsistencia::LOCAL_DE_ATENDIMENTO_SEM_PREENCHIMENTO, LocalAtendimentoIsValid::class => Inconsistencia::LOCAL_DE_ATENDIMENTO_INVALIDO, TurnoIsRequired::class => Inconsistencia::TURNO_SEM_PREENCHIMENTO, SexoIsRequired::class => Inconsistencia::SEXO_DO_PACIENTE_SEM_PREENCHIMENTO, AlturaLimitIsValid::class => Inconsistencia::ALTURA_DO_PACIENTE_MENOR_QUE_20_OU_MAIOR_QUE_250_CM, CircunferenciaAbdominalLimitIsValid::class => Inconsistencia::CIRCUNFERENCIA_ABDOMINAL_DO_PACIENTE_MENOR_QUE_0_OU_MAIOR_QUE_99999_CM, FrequenciaCardiacaLimitIsValid::class => Inconsistencia::FREQUENCIA_CARDIACA_DO_PACIENTE_MENOR_QUE_0_OU_MAIOR_QUE_999_BPM, FrequenciaRespiratoriaLimitIsValid::class => Inconsistencia::FREQUENCIA_RESPIRATORIA_DO_PACIENTE_MENOR_QUE_0_OU_MAIOR_QUE_200_MPM, GlicemiaLimitIsValid::class => Inconsistencia::GLICEMIA_DO_PACIENTE_MENOR_QUE_0_OU_MAIOR_QUE_800_KG, MomentoColetaGlicemiaIsRequired::class => Inconsistencia::MOMENTO_COLETA_GLICEMIA_SEM_PREENCHIMENTO, PerimetroCefalicoLimitIsValid::class => Inconsistencia::PERIMETRO_CEFALICO_MENOR_QUE_10_OU_MAIOR_QUE_200, PerimetroPanturrilhaLimitIsValid::class => Inconsistencia::PERIMETRO_PANTURRILHA_DO_PACIENTE_MENOR_QUE_10_OU_MAIOR_QUE_99_CM, PesoLimitIsValid::class => Inconsistencia::PESO_DO_PACIENTE_MENOR_QUE_0_5_OU_MAIOR_QUE_500_KG, PressaoArterialDiastolicaLimitIsValid::class => Inconsistencia::PRESSAO_ARTERIAL_DIASTOLICA_DO_PACIENTE_MENOR_QUE_0_OU_MAIOR_QUE_999_MMHG, PressaoArterialSistolicaLimitIsValid::class => Inconsistencia::PRESSAO_ARTERIAL_SISTOLICA_DO_PACIENTE_MENOR_QUE_0_OU_MAIOR_QUE_999_MMHG, SaturacaoO2LimitIsValid::class => Inconsistencia::SATURACAO_O2_DO_PACIENTE_MENOR_QUE_0_OU_MAIOR_QUE_100_PORCENTO, TemperaturaLimitIsValid::class => Inconsistencia::TEMPERATURA_DO_PACIENTE_MENOR_QUE_20_OU_MAIOR_QUE_45_GRAUS, TipoAtendimentoIsRequired::class => Inconsistencia::TIPO_DE_ATENDIMENTO_SEM_PREENCHIMENTO, TipoAtendimentoIsValid::class => Inconsistencia::TIPO_DE_ATENDIMENTO_INVALIDO, ProblemaCondicaoIsRequired::class => Inconsistencia::PROBLEMA_OU_CONDICAO_SEM_PREENCHIMENTO, ProblemaCondicaoCiapIsDuplicated::class => Inconsistencia::CIAP2_EM_DUPLICIDADE, ProblemaCondicaoCiapIsValid::class => Inconsistencia::PROBLEMA_E_CONDICAO_COM_CIAP2_INVALIDO, ProblemaCondicaoCidIsDuplicated::class => Inconsistencia::CID_EM_DUPLICIDADE, ProblemaCondicaoCidIsValid::class => Inconsistencia::PROBLEMA_E_CONDICAO_COM_CID10_INVALIDO, ]; public static function index() { $mes_ano = request()->mes_ano; $date = Carbon::createFromFormat('mY', $mes_ano); $start = $date->copy()->startOfMonth()->toDateString(); $end = $date->copy()->endOfMonth()->toDateString(); $inconsistencias = DB::table('atencao_basica_inconsistencia') ->select('id', 'descricao') ->get() ->pluck('descricao', 'id'); $fichasAtendimentoIndividual = DB::table('atencao_basica_atendimento_individual') ->select([ 'atencao_basica_atendimento_individual.id as id', 'atencao_basica_atendimento_individual.usuario_id as usuario_id', 'atencao_basica_atendimento_individual.data_usuario_responsavel as data_atendimento', 'cadastro_unidade.cnes as unidade_cnes', 'cadastro_municipio.ibge as municipio_ibge', 'sigtap.ocupacao.codigo as ocupacao_codigo', 'cadastro_cidadao.cns AS usuario_cns', 'cadastro_cidadao.nome AS profissional_nome', 'paciente_cidadao.cns as paciente_cns', 'paciente_cidadao.cpf as paciente_cpf', 'paciente_cidadao.nome as paciente_nome', 'paciente_cidadao.nome_social as paciente_nome_social', 'paciente_cidadao.preferencia_nome_id as paciente_preferencia_nome_id', 'paciente_cidadao.data_nascimento as paciente_data_nascimento', DB::raw("TIMESTAMPDIFF(YEAR, paciente_cidadao.data_nascimento, NOW()) AS paciente_idade"), 'paciente_cidadao.sexo_id as paciente_sexo_id', DB::raw('LPAD(cadastro_paciente.prontuario,7,0) AS paciente_prontuario'), 'atencao_basica_atendimento_individual.local_atendimento_id', 'atencao_basica_atendimento_individual.turno_id', 'atencao_basica_atendimento_individual.tipo_atendimento_id', 'atencao_basica_atendimento_individual.perimetro_cefalico', 'atencao_basica_atendimento_individual.peso', 'atencao_basica_atendimento_individual.altura', 'atencao_basica_atendimento_individual.temperatura', 'atencao_basica_atendimento_individual.pressao_arterial', 'atencao_basica_atendimento_individual.frequencia_respiratoria', 'atencao_basica_atendimento_individual.frequencia_cardiaca', 'atencao_basica_atendimento_individual.saturacao_o2', 'atencao_basica_atendimento_individual.circunferencia_abdominal', 'atencao_basica_atendimento_individual.perimetro_panturrilha', 'atencao_basica_atendimento_individual.glicemia', 'atencao_basica_atendimento_individual.momento_coleta_id', 'atencao_basica_atendimento_individual.paciente_id', ]) ->join('atencao_basica_parametrizacao_equipe', 'atencao_basica_parametrizacao_equipe.id', 'atencao_basica_atendimento_individual.equipe_id') ->join('cadastro_unidade', 'cadastro_unidade.id', 'atencao_basica_parametrizacao_equipe.unidade_id') ->join('cadastro_infraestrutura', 'cadastro_infraestrutura.id', 'atencao_basica_parametrizacao_equipe.infraestrutura_id') ->leftJoin('cadastro_endereco', 'cadastro_endereco.id', 'cadastro_infraestrutura.endereco_id') ->leftJoin('cadastro_logradouro', 'cadastro_logradouro.id', 'cadastro_endereco.logradouro_id') ->leftJoin('intranet.cadastro_municipio', 'cadastro_municipio.id', 'cadastro_logradouro.municipio_id') ->join('cadastro_usuario', 'cadastro_usuario.id', 'atencao_basica_atendimento_individual.usuario_id') ->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id') ->join('sigtap.ocupacao', 'sigtap.ocupacao.id', 'atencao_basica_atendimento_individual.usuario_ocupacao_id') ->join('cadastro_paciente', 'cadastro_paciente.id', 'atencao_basica_atendimento_individual.paciente_id') ->join('cadastro_cidadao as paciente_cidadao', 'paciente_cidadao.id', 'cadastro_paciente.cidadao_id') ->whereBetween('atencao_basica_atendimento_individual.data_usuario_responsavel', [$start, $end]) ->when(request()->unidade_id, fn ($query) => $query->where('atencao_basica_parametrizacao_equipe.unidade_id', request()->unidade_id)) ->when(request()->infraestrutura_id, fn ($query) => $query->where('atencao_basica_parametrizacao_equipe.infraestrutura_id', request()->infraestrutura_id)) ->when(request()->usuario_id, fn ($query) => $query->where('atencao_basica_atendimento_individual.usuario_id', request()->usuario_id)) ->get(); if ($fichasAtendimentoIndividual->isEmpty()) { return []; } $atendimentoIds = $fichasAtendimentoIndividual->pluck('id')->all(); $problemasCondicoesPorAtendimento = self::loadProblemasCondicoes($atendimentoIds); $groupedList = []; foreach ($fichasAtendimentoIndividual as $ficha) { $problemasCondicoes = $problemasCondicoesPorAtendimento[$ficha->id] ?? collect(); $errors = RelatorioInconsistenciaService::validHeader($ficha, Permissao::ATENDIMENTO_INDIVIDUAL) ->merge(self::validAtendimento($ficha, $problemasCondicoes)); $errorDescriptions = self::mapErrorsToDescriptions($errors, $inconsistencias); if ($errorDescriptions->isEmpty()) { continue; } $key = $ficha->data_atendimento . '|' . $ficha->paciente_id . '|' . $ficha->usuario_id; if (!isset($groupedList[$key])) { $groupedList[$key] = [ 'data' => (new Carbon($ficha->data_atendimento))->format('d/m/Y'), 'ficha' => 'Atendimento individual', 'paciente_nome' => $ficha->paciente_nome, 'paciente_nome_social' => $ficha->paciente_nome_social, 'paciente_preferencia_nome_id' => $ficha->paciente_preferencia_nome_id, 'paciente_prontuario' => $ficha->paciente_prontuario, 'profissional' => $ficha->profissional_nome, 'paciente_cns' => $ficha->paciente_cns ? MaskUtil::getCnsMasked($ficha->paciente_cns) : '-', 'paciente_cpf' => $ficha->paciente_cpf ? MaskUtil::getCpfMasked($ficha->paciente_cpf) : '-', 'erros' => $errorDescriptions, ]; } else { $groupedList[$key]['erros'] = $groupedList[$key]['erros']->merge($errorDescriptions); } } $result = []; foreach ($groupedList as $group) { $unique = $group['erros']->unique(); $group['erros'] = $unique->implode('
'); $group['total_erros'] = $unique->count(); $result[] = $group; } return $result; } private static function mapErrorsToDescriptions(Collection $errors, Collection $inconsistencias): Collection { $map = self::HEADER_ERROR_MAP + self::ATENDIMENTO_ERROR_MAP; $descriptions = collect(); foreach ($errors as $error) { $inconsistenciaId = $map[$error] ?? null; if ($inconsistenciaId === null) { continue; } $descricao = $inconsistencias[$inconsistenciaId] ?? null; if ($descricao !== null) { $descriptions->push($descricao); } } return $descriptions; } private static function validAtendimento($atendimento, Collection $problemasCondicoes) { $errors = collect(); if (!Cns::isValid($atendimento->paciente_cns) && !Cpf::isValid($atendimento->paciente_cpf)) { $errors->push(CnsPaciente::class); $errors->push(Cpf::class); } if (!DataNascimentoIsRequired::isValid($atendimento->paciente_data_nascimento)) { $errors->push(DataNascimentoIsRequired::class); } if (!DataNascimentoIsValid::isValid([ 'data_nascimento' => $atendimento->paciente_data_nascimento, 'data_atendimento' => $atendimento->data_atendimento ])) { $errors->push(DataNascimentoIsValid::class); } if (!LocalAtendimentoIsRequired::isValid($atendimento->local_atendimento_id)) { $errors->push(LocalAtendimentoIsRequired::class); } if (!LocalAtendimentoIsValid::isValid($atendimento->local_atendimento_id)) { $errors->push(LocalAtendimentoIsValid::class); } if (!TipoAtendimentoIsRequired::isValid($atendimento->tipo_atendimento_id)) { $errors->push(TipoAtendimentoIsRequired::class); } if (!TipoAtendimentoIsValid::isValid($atendimento->tipo_atendimento_id)) { $errors->push(TipoAtendimentoIsValid::class); } if (!TurnoIsRequired::isValid($atendimento->turno_id)) { $errors->push(TurnoIsRequired::class); } if (!SexoIsRequired::isValid($atendimento->paciente_sexo_id)) { $errors->push(SexoIsRequired::class); } if (!AlturaLimitIsValid::isValid($atendimento->altura)) { $errors->push(AlturaLimitIsValid::class); } if (!CircunferenciaAbdominalLimitIsValid::isValid($atendimento->circunferencia_abdominal)) { $errors->push(CircunferenciaAbdominalLimitIsValid::class); } if (!FrequenciaCardiacaLimitIsValid::isValid($atendimento->frequencia_cardiaca)) { $errors->push(FrequenciaCardiacaLimitIsValid::class); } if (!FrequenciaRespiratoriaLimitIsValid::isValid($atendimento->frequencia_respiratoria)) { $errors->push(FrequenciaRespiratoriaLimitIsValid::class); } if (!GlicemiaLimitIsValid::isValid($atendimento->glicemia)) { $errors->push(GlicemiaLimitIsValid::class); } if (!is_null($atendimento->glicemia) && !MomentoColetaGlicemiaIsRequired::isValid($atendimento->momento_coleta_id)) { $errors->push(MomentoColetaGlicemiaIsRequired::class); } if (!PerimetroCefalicoLimitIsValid::isValid($atendimento->perimetro_cefalico)) { $errors->push(PerimetroCefalicoLimitIsValid::class); } if (!PerimetroPanturrilhaLimitIsValid::isValid($atendimento->perimetro_panturrilha)) { $errors->push(PerimetroPanturrilhaLimitIsValid::class); } if (!PesoLimitIsValid::isValid($atendimento->peso)) { $errors->push(PesoLimitIsValid::class); } if (!PressaoArterialDiastolicaLimitIsValid::isValid($atendimento->pressao_arterial)) { $errors->push(PressaoArterialDiastolicaLimitIsValid::class); } if (!PressaoArterialSistolicaLimitIsValid::isValid($atendimento->pressao_arterial)) { $errors->push(PressaoArterialSistolicaLimitIsValid::class); } if (!SaturacaoO2LimitIsValid::isValid($atendimento->saturacao_o2)) { $errors->push(SaturacaoO2LimitIsValid::class); } if (!TemperaturaLimitIsValid::isValid($atendimento->temperatura)) { $errors->push(TemperaturaLimitIsValid::class); } if (!ProblemaCondicaoIsRequired::isValid($problemasCondicoes)) { $errors->push(ProblemaCondicaoIsRequired::class); } if (!ProblemaCondicaoCiapIsDuplicated::isValid($problemasCondicoes)) { $errors->push(ProblemaCondicaoCiapIsDuplicated::class); } if (!ProblemaCondicaoCiapIsValid::isValid($problemasCondicoes, $atendimento->paciente_idade)) { $errors->push(ProblemaCondicaoCiapIsValid::class); } if (!ProblemaCondicaoCidIsDuplicated::isValid($problemasCondicoes)) { $errors->push(ProblemaCondicaoCidIsDuplicated::class); } if (!ProblemaCondicaoCidIsValid::isValid($problemasCondicoes)) { $errors->push(ProblemaCondicaoCidIsValid::class); } return $errors; } private static function loadProblemasCondicoes(array $atendimentoIds): array { if (empty($atendimentoIds)) { return []; } $problemasCondicoesRaw = DB::table('atencao_basica_atendimento_individual_problema_condicao as pc') ->leftJoin('geral_ciap as ciap', 'ciap.id', 'pc.ciap_id') ->leftJoin('sigtap.cid as cid', 'cid.id', 'pc.cid_id') ->whereIn('pc.atendimento_individual_id', $atendimentoIds) ->select([ 'pc.atendimento_individual_id', 'ciap.id as ciap_id', 'cid.id as cid_id', 'ciap.codigo as ciap_codigo', 'ciap.grupo_id as ciap_grupo_id', 'cid.codigo as cid_codigo', DB::raw("IF (cid.codigo LIKE 'Z34%', 1, 0) as is_cid_familia_Z34"), ]) ->get() ->groupBy('atendimento_individual_id'); $codigosEsusPorAtendimento = self::loadCodigosEsusPorAtendimento($atendimentoIds); $ciapsPorCodigoEsus = self::loadCiapsPorCodigoEsus( collect($codigosEsusPorAtendimento)->flatten()->unique()->values()->all() ); $resultado = []; foreach ($atendimentoIds as $id) { $problemasCondicoes = collect($problemasCondicoesRaw[$id] ?? []) ->map(function ($pc) { $pc->atendimento_individual_id = null; $pc->is_cid_familia_Z34 = (bool) $pc->is_cid_familia_Z34; return $pc; }) ->values(); $codigosEsus = collect($codigosEsusPorAtendimento[$id] ?? [])->values(); if (self::isCodigoEsusEspecial($codigosEsus)) { $problemasCondicoes->push((object) [ 'codigo_esus' => $codigosEsus, ]); } else { $ciapsAdicionais = collect(); $vistos = []; foreach ($codigosEsus as $codigo) { foreach ($ciapsPorCodigoEsus[$codigo] ?? [] as $ciap) { if (!isset($vistos[$ciap->ciap_id])) { $ciapsAdicionais->push($ciap); $vistos[$ciap->ciap_id] = true; } } } $problemasCondicoes = $problemasCondicoes->concat($ciapsAdicionais)->values(); } $resultado[$id] = $problemasCondicoes; } return $resultado; } private static function loadCodigosEsusPorAtendimento(array $atendimentoIds): array { $fontes = [ ['atencao_basica_atendimento_individual_condicao_avaliada', 'atencao_basica_cadastro_condicao_avaliada', 'condicao_avaliada_id'], ['atencao_basica_atendimento_individual_doenca_transmissivel', 'atencao_basica_cadastro_doenca_transmissivel', 'doenca_transmissivel_id'], ['atencao_basica_atendimento_individual_rastreamento', 'atencao_basica_cadastro_rastreamento', 'rastreamento_id'], ]; $codigosPorAtendimento = []; foreach ($fontes as [$tabelaLink, $tabelaCadastro, $fk]) { $rows = DB::table($tabelaLink) ->join($tabelaCadastro, "{$tabelaCadastro}.id", "{$tabelaLink}.{$fk}") ->whereIn("{$tabelaLink}.atendimento_individual_id", $atendimentoIds) ->select( "{$tabelaLink}.atendimento_individual_id", "{$tabelaCadastro}.codigo_esus" ) ->get(); foreach ($rows as $row) { $codigosPorAtendimento[$row->atendimento_individual_id][] = $row->codigo_esus; } } return $codigosPorAtendimento; } private static function loadCiapsPorCodigoEsus(array $codigos): array { if (empty($codigos)) { return []; } $rows = DB::table('geral_ciap_codigo_esus') ->join('geral_ciap', 'geral_ciap.id', 'geral_ciap_codigo_esus.ciap_id') ->whereIn('geral_ciap_codigo_esus.codigo', $codigos) ->select( 'geral_ciap_codigo_esus.codigo as esus_codigo', 'geral_ciap.id', 'geral_ciap.codigo', 'geral_ciap.grupo_id' ) ->get(); $ciapsPorCodigo = []; foreach ($rows as $row) { $ciapsPorCodigo[$row->esus_codigo][] = (object) [ 'ciap_id' => $row->id, 'cid_id' => null, 'ciap_codigo' => $row->codigo, 'ciap_grupo_id' => $row->grupo_id, 'cid_codigo' => null, 'is_cid_familia_Z34' => false, ]; } return $ciapsPorCodigo; } private static function isCodigoEsusEspecial(Collection $codigosEsus): bool { return $codigosEsus->contains(CondicaoAvaliadaCodigoEsus::SAUDE_MENTAL) || $codigosEsus->contains(CondicaoAvaliadaCodigoEsus::SAUDE_SEXUAL_E_REPRODUTIVA) || $codigosEsus->contains(CondicaoAvaliadaCodigoEsus::REABILITACAO) || $codigosEsus->contains(RastreamentoCodigoEsus::CANCER_MAMA) || $codigosEsus->contains(RastreamentoCodigoEsus::CANCER_COLO_UTERO); } }