Inconsistencia::CNES_DA_UNIDADE_COM_TAMANHO_DIFERENTE_DE_7_CARACTERES, IbgeIsValid::class => Inconsistencia::IBGE_DO_MUNICIPIO_SEM_PREENCHIMENTO_OU_INVALIDO, IbgeIsRequired::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, BairroIsRequired::class => Inconsistencia::BAIRRO_SEM_PREENCHIMENTO, CepIsRequired::class => Inconsistencia::CEP_SEM_PREENCHIMENTO, LogradouroIsRequired::class => Inconsistencia::NOME_LOGRADOURO_SEM_PREENCHIMENTO, UfIsRequired::class => Inconsistencia::UF_SEM_PREENCHIMENTO, LogradouroTipoIsRequired::class => Inconsistencia::TIPO_DE_LOGRADOURO_SEM_PREENCHIMENTO, MicroAreaIsRequired::class => Inconsistencia::MICROAREA_DO_PACIENTE_SEM_PREENCHIMENTO, ZonaIsRequired::class => Inconsistencia::ZONA_SEM_PREENCHIMENTO, ResponsavelTecnicoIsRequired::class => Inconsistencia::NOME_RESPONSAVEL_TECNICO_SEM_PREENCHIMENTO, ]; 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'); $fichasCadastroDomiciliar = DB::table('atencao_basica_cadastro_domiciliar') ->select([ 'atencao_basica_cadastro_domiciliar.id as id', 'atencao_basica_cadastro_domiciliar.usuario_id as usuario_id', 'atencao_basica_cadastro_domiciliar.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', 'logradouro.bairro_id as logradouro_bairro_id', 'logradouro.cep as logradouro_cep', 'logradouro.nome AS logradouro_nome', 'endereco.numero as endereco_numero', 'municipio.ibge as logradouro_municipio_ibge', 'estado.codigo as uf_codigo', 'logradouro_tipo.codigo as logradouro_tipo_codigo', 'atencao_basica_cadastro_domiciliar.domicilio_id', 'atencao_basica_cadastro_domiciliar.fora_area', 'atencao_basica_cadastro_domiciliar.microarea_id as logradouro_microarea_id', 'atencao_basica_cadastro_domiciliar.domicilio_zona_id', 'atencao_basica_cadastro_domiciliar.situacao_domicilio_id', 'atencao_basica_cadastro_domiciliar.instituicao_nome_responsavel_tecnico', 'atencao_basica_cadastro_imovel_tipo.codigo_esus as imovel_tipo_codigo_esus', ]) ->join('atencao_basica_parametrizacao_equipe', 'atencao_basica_parametrizacao_equipe.id', 'atencao_basica_cadastro_domiciliar.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_cadastro_domiciliar.usuario_id') ->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id') ->join('sigtap.ocupacao', 'sigtap.ocupacao.id', 'atencao_basica_cadastro_domiciliar.usuario_ocupacao_id') ->join('cadastro_domicilio', 'cadastro_domicilio.id', 'atencao_basica_cadastro_domiciliar.domicilio_id') ->join('atencao_basica_cadastro_imovel_tipo', 'atencao_basica_cadastro_imovel_tipo.id', 'atencao_basica_cadastro_domiciliar.imovel_tipo_id') ->leftJoin('cadastro_endereco as endereco', 'endereco.id', 'cadastro_domicilio.endereco_id') ->leftJoin('cadastro_logradouro as logradouro', 'logradouro.id', 'endereco.logradouro_id') ->leftJoin('cadastro_logradouro_tipo as logradouro_tipo', 'logradouro_tipo.id', 'logradouro.tipo_id') ->leftJoin('intranet.cadastro_municipio as municipio', 'municipio.id', 'logradouro.municipio_id') ->leftJoin('intranet.cadastro_estado as estado', 'estado.id', 'municipio.estado_id') ->whereBetween('atencao_basica_cadastro_domiciliar.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_cadastro_domiciliar.usuario_id', request()->usuario_id)) ->get(); if ($fichasCadastroDomiciliar->isEmpty()) { return []; } $residentesPorDomicilio = self::loadResidentes( $fichasCadastroDomiciliar->pluck('domicilio_id')->filter()->unique()->all() ); $groupedList = []; foreach ($fichasCadastroDomiciliar as $ficha) { $errosHeader = RelatorioInconsistenciaService::validHeader($ficha, Permissao::CADASTRO_DOMICILIAR); $errosAtendimento = self::validAtendimento($ficha); $errors = $errosHeader->merge($errosAtendimento); $baseDescriptions = self::mapErrorsToDescriptions($errors, $inconsistencias); foreach ($residentesPorDomicilio[$ficha->domicilio_id] ?? [] as $residente) { $errorDescriptions = collect($baseDescriptions->all()); if ( $errosAtendimento->isNotEmpty() && !Cns::isValid($residente->cns) && !Cpf::isValid($residente->cpf) ) { $descricao = $inconsistencias[Inconsistencia::CNS_DO_RESPONSAVEL_FAMILIAR_INVALIDO] ?? null; if ($descricao !== null) { $errorDescriptions->push($descricao); } } if ($errorDescriptions->isEmpty()) { continue; } $key = $ficha->data_atendimento . '|' . $residente->paciente_id . '|' . $ficha->usuario_id; if (!isset($groupedList[$key])) { $groupedList[$key] = [ 'data' => (new Carbon($ficha->data_atendimento))->format('d/m/Y'), 'ficha' => 'Cadastro domiciliar', 'paciente_nome' => $residente->paciente_nome, 'paciente_nome_social' => $residente->paciente_nome_social, 'paciente_preferencia_nome_id' => $residente->paciente_preferencia_nome_id, 'paciente_prontuario' => $residente->paciente_prontuario, 'paciente_cns' => $residente->cns ? MaskUtil::getCnsMasked($residente->cns) : '-', 'paciente_cpf' => $residente->cpf ? MaskUtil::getCpfMasked($residente->cpf) : '-', 'profissional' => $ficha->profissional_nome, '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 { $descriptions = collect(); foreach ($errors as $error) { $inconsistenciaId = self::ERROR_MAP[$error] ?? null; if ($inconsistenciaId === null) { continue; } $descricao = $inconsistencias[$inconsistenciaId] ?? null; if ($descricao !== null) { $descriptions->push($descricao); } } return $descriptions; } private static function validAtendimento($cadastro): Collection { $errors = collect(); if (!BairroIsRequired::isValid($cadastro->logradouro_bairro_id)) { $errors->push(BairroIsRequired::class); } if (!CepIsRequired::isValid($cadastro->logradouro_cep)) { $errors->push(CepIsRequired::class); } if (!IbgeIsRequired::isValid($cadastro->logradouro_municipio_ibge)) { $errors->push(IbgeIsRequired::class); } if (!IbgeIsValid::isValid($cadastro->logradouro_municipio_ibge)) { $errors->push(IbgeIsValid::class); } if (!LogradouroIsRequired::isValid($cadastro->logradouro_nome)) { $errors->push(LogradouroIsRequired::class); } if (!UfIsRequired::isValid($cadastro->uf_codigo)) { $errors->push(UfIsRequired::class); } if (!LogradouroTipoIsRequired::isValid($cadastro->logradouro_tipo_codigo)) { $errors->push(LogradouroTipoIsRequired::class); } if (!$cadastro->fora_area && !MicroAreaIsRequired::isValid($cadastro->logradouro_microarea_id)) { $errors->push(MicroAreaIsRequired::class); } if (!ZonaIsRequired::isValid($cadastro->domicilio_zona_id)) { $errors->push(ZonaIsRequired::class); } if (self::handleTipoImovelPermanencia($cadastro->imovel_tipo_codigo_esus) && !ResponsavelTecnicoIsRequired::isValid($cadastro->instituicao_nome_responsavel_tecnico)) { $errors->push(ResponsavelTecnicoIsRequired::class); } return $errors; } private static function loadResidentes(array $domicilioIds): array { if (empty($domicilioIds)) { return []; } $rows = DB::table('cadastro_cidadao') ->select([ 'cadastro_cidadao.domicilio_id', 'atencao_basica_cadastro_individual.responsavel AS responsavel', 'atencao_basica_cadastro_individual.responsavel_cidadao_id AS responsavel_cidadao_id', 'cadastro_cidadao.data_nascimento', 'cadastro_cidadao.cns', 'cadastro_cidadao.cpf', 'cadastro_cidadao.nome as paciente_nome', 'cadastro_cidadao.nome_social as paciente_nome_social', 'cadastro_cidadao.preferencia_nome_id as paciente_preferencia_nome_id', 'atencao_basica_cadastro_individual.renda_mensal as renda_responsavel', 'cadastro_paciente.id as paciente_id', DB::raw('LPAD(cadastro_paciente.prontuario,7,0) AS paciente_prontuario'), ]) ->join('cadastro_paciente', 'cadastro_paciente.cidadao_id', 'cadastro_cidadao.id') ->join('atencao_basica_cadastro_individual', 'atencao_basica_cadastro_individual.paciente_id', 'cadastro_paciente.id') ->whereIn('cadastro_cidadao.domicilio_id', $domicilioIds) ->where('atencao_basica_cadastro_individual.responsavel', true) ->whereNotExists(function ($query) { $query->select(DB::raw(1)) ->from('cadastro_obito') ->whereColumn('cadastro_obito.cidadao_id', 'cadastro_cidadao.id'); }) ->get(); $porDomicilio = []; foreach ($rows as $row) { $porDomicilio[$row->domicilio_id][] = $row; } return $porDomicilio; } private static function handleTipoImovelPermanencia($tipoImovel): bool { return $tipoImovel == ImovelTipo::ABRIGO || $tipoImovel == ImovelTipo::INSTITUICAO_LONGA_PERMANENCIA_IDOSOS || $tipoImovel == ImovelTipo::UNIDADE_PRISIONAL || $tipoImovel == ImovelTipo::UNIDADE_MEDIDA_SOCIO_EDUCATIVA || $tipoImovel == ImovelTipo::DELEGACIA; } }