This commit is contained in:
@@ -0,0 +1,438 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\AtencaoBasica\RelatorioInconsistencia;
|
||||
|
||||
use App\Enums\AtencaoBasica\Exportacao\Inconsistencia;
|
||||
use App\Enums\AtencaoBasica\Parametrizacao\Permissao;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnesIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnsPaciente;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CondicaoAvaliacaoDomiciliarIsValidForFicha;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CondutaDesfechoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\IbgeIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\LocalAtendimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\LocalAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\OcupacaoIsAllowed;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProblemaCondicaoCiapIsDuplicated;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProblemaCondicaoCiapIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProblemaCondicaoCidIsDuplicated;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProblemaCondicaoCidIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProblemaCondicaoCidOuCiapIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProblemaCondicaoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProcedimentoLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\SexoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TipoAtendimentoDomiciliarIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TipoAtendimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TipoModalidadeIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TurnoIsRequired;
|
||||
use App\Rules\Cns;
|
||||
use App\Rules\Cpf;
|
||||
use App\Services\Service;
|
||||
use App\Utils\MaskUtil;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class FichaAtendimentoDomiciliarService extends Service
|
||||
{
|
||||
private const ERROR_MAP = [
|
||||
CnesIsValid::class => 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,
|
||||
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,
|
||||
CondutaDesfechoIsRequired::class => Inconsistencia::CONDUTA_DESFECHO_SEM_PREENCHIMENTO,
|
||||
SexoIsRequired::class => Inconsistencia::SEXO_DO_PACIENTE_SEM_PREENCHIMENTO,
|
||||
ProcedimentoLimitIsValid::class => Inconsistencia::PACIENTE_COM_MAIS_DE_20_PROCEDIMENTOS_INSERIDOS,
|
||||
TipoAtendimentoIsRequired::class => Inconsistencia::TIPO_DE_ATENDIMENTO_SEM_PREENCHIMENTO,
|
||||
TipoAtendimentoDomiciliarIsValid::class => Inconsistencia::MODALIDADE_INVALIDA,
|
||||
TipoModalidadeIsRequired::class => Inconsistencia::MODALIDADE_SEM_PREENCHIMENTO,
|
||||
CondicaoAvaliacaoDomiciliarIsValidForFicha::class => Inconsistencia::CONDICAO_AVALIADA_INVALIDA,
|
||||
ProblemaCondicaoIsRequired::class => Inconsistencia::PROBLEMA_OU_CONDICAO_SEM_PREENCHIMENTO,
|
||||
ProblemaCondicaoCidOuCiapIsRequired::class => Inconsistencia::PROBLEMA_E_CONDICAO_SEM_CIAP2_E_SEM_CID10,
|
||||
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');
|
||||
|
||||
$fichasAtendimentoDomiciliar = DB::table('atencao_basica_atendimento_domiciliar')
|
||||
->select([
|
||||
'atencao_basica_atendimento_domiciliar.id as id',
|
||||
'atencao_basica_atendimento_domiciliar.usuario_id as usuario_id',
|
||||
'atencao_basica_atendimento_domiciliar.data 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',
|
||||
])
|
||||
->join('atencao_basica_parametrizacao_equipe', 'atencao_basica_parametrizacao_equipe.id', 'atencao_basica_atendimento_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_atendimento_domiciliar.usuario_id')
|
||||
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id')
|
||||
->join('sigtap.ocupacao', 'sigtap.ocupacao.id', 'atencao_basica_atendimento_domiciliar.ocupacao_id')
|
||||
->whereBetween('atencao_basica_atendimento_domiciliar.data', [$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_domiciliar.usuario_id', request()->usuario_id))
|
||||
->get();
|
||||
|
||||
if ($fichasAtendimentoDomiciliar->isEmpty()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$atendimentosPorFicha = self::loadAtendimentos($fichasAtendimentoDomiciliar->pluck('id')->all());
|
||||
|
||||
$allAtendimentoIds = [];
|
||||
|
||||
foreach ($atendimentosPorFicha as $atendimentos) {
|
||||
|
||||
foreach ($atendimentos as $atendimento) {
|
||||
$allAtendimentoIds[] = $atendimento->id;
|
||||
}
|
||||
}
|
||||
|
||||
$problemasCondicoesPorAtendimento = self::loadProblemasCondicoes($allAtendimentoIds);
|
||||
|
||||
$groupedList = [];
|
||||
|
||||
foreach ($fichasAtendimentoDomiciliar as $ficha) {
|
||||
|
||||
$errosHeader = RelatorioInconsistenciaService::validHeader($ficha, Permissao::ATENDIMENTO_DOMICILIAR);
|
||||
|
||||
foreach ($atendimentosPorFicha[$ficha->id] ?? [] as $atendimento) {
|
||||
|
||||
$problemasCondicoes = $problemasCondicoesPorAtendimento[$atendimento->id] ?? collect();
|
||||
|
||||
$errors = $errosHeader->merge(self::validAtendimento($atendimento, $ficha, $problemasCondicoes));
|
||||
$errorDescriptions = self::mapErrorsToDescriptions($errors, $inconsistencias);
|
||||
|
||||
if ($errorDescriptions->isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$key = $ficha->data_atendimento . '|' . $atendimento->paciente_id . '|' . $ficha->usuario_id;
|
||||
|
||||
if (!isset($groupedList[$key])) {
|
||||
|
||||
$groupedList[$key] = [
|
||||
'data' => (new Carbon($ficha->data_atendimento))->format('d/m/Y'),
|
||||
'ficha' => 'Atendimento domiciliar',
|
||||
'paciente_nome' => $atendimento->paciente_nome,
|
||||
'paciente_nome_social' => $atendimento->paciente_nome_social,
|
||||
'paciente_preferencia_nome_id' => $atendimento->paciente_preferencia_nome_id,
|
||||
'paciente_prontuario' => $atendimento->paciente_prontuario,
|
||||
'paciente_cns' => $atendimento->paciente_cns ? MaskUtil::getCnsMasked($atendimento->paciente_cns) : '-',
|
||||
'paciente_cpf' => $atendimento->paciente_cpf ? MaskUtil::getCpfMasked($atendimento->paciente_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('<br />');
|
||||
$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($atendimento, $fichaAtendimentoDomiciliar, Collection $problemasCondicoes): Collection
|
||||
{
|
||||
$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' => $fichaAtendimentoDomiciliar->data_atendimento
|
||||
])) {
|
||||
$errors->push(DataNascimentoIsValid::class);
|
||||
}
|
||||
|
||||
if (!LocalAtendimentoIsRequired::isValid($atendimento->local_atendimento_id)) {
|
||||
$errors->push(LocalAtendimentoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!TipoAtendimentoIsRequired::isValid($atendimento->tipo_atendimento_id)) {
|
||||
$errors->push(TipoAtendimentoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!TipoAtendimentoDomiciliarIsValid::isValid($atendimento->tipo_atendimento_id)) {
|
||||
$errors->push(TipoAtendimentoDomiciliarIsValid::class);
|
||||
}
|
||||
|
||||
if (!TipoModalidadeIsRequired::isValid($atendimento)) {
|
||||
$errors->push(TipoModalidadeIsRequired::class);
|
||||
}
|
||||
|
||||
if (!CondicaoAvaliacaoDomiciliarIsValidForFicha::isValid($atendimento)) {
|
||||
$errors->push(CondicaoAvaliacaoDomiciliarIsValidForFicha::class);
|
||||
}
|
||||
|
||||
if (!TurnoIsRequired::isValid($atendimento->turno_id)) {
|
||||
$errors->push(TurnoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!CondutaDesfechoIsRequired::isValid($atendimento->conduta_desfecho_id)) {
|
||||
$errors->push(CondutaDesfechoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!SexoIsRequired::isValid($atendimento->paciente_sexo_id)) {
|
||||
$errors->push(SexoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!ProblemaCondicaoIsRequired::isValid($problemasCondicoes)) {
|
||||
$errors->push(ProblemaCondicaoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!ProblemaCondicaoCidOuCiapIsRequired::isValid($problemasCondicoes)) {
|
||||
$errors->push(ProblemaCondicaoCidOuCiapIsRequired::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 loadAtendimentos(array $fichaIds): array
|
||||
{
|
||||
if (empty($fichaIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rows = DB::table('atencao_basica_atendimento_domiciliar_atendimento as ad')
|
||||
->select([
|
||||
'ad.id as id',
|
||||
'ad.atendimento_domiciliar_id',
|
||||
'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',
|
||||
'paciente_cidadao.sexo_id as paciente_sexo_id',
|
||||
DB::raw('LPAD(cadastro_paciente.prontuario,7,0) AS paciente_prontuario'),
|
||||
'ad.local_atendimento_id',
|
||||
'ad.turno_id',
|
||||
'ad.tipo_atendimento_id',
|
||||
'ad.modalidade_id',
|
||||
'ad.conduta_desfecho_id',
|
||||
'ad.paciente_id',
|
||||
DB::raw('TIMESTAMPDIFF(YEAR, paciente_cidadao.data_nascimento, NOW()) AS paciente_idade'),
|
||||
])
|
||||
->join('cadastro_paciente', 'cadastro_paciente.id', 'ad.paciente_id')
|
||||
->join('cadastro_cidadao as paciente_cidadao', 'paciente_cidadao.id', 'cadastro_paciente.cidadao_id')
|
||||
->whereIn('ad.atendimento_domiciliar_id', $fichaIds)
|
||||
->get();
|
||||
|
||||
$porFicha = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$porFicha[$row->atendimento_domiciliar_id][] = $row;
|
||||
}
|
||||
|
||||
return $porFicha;
|
||||
}
|
||||
|
||||
private static function loadProblemasCondicoes(array $atendimentoIds): array
|
||||
{
|
||||
if (empty($atendimentoIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$problemasCondicoesRaw = DB::table('atencao_basica_atendimento_domiciliar_atend_problema_condicao as pc')
|
||||
->select([
|
||||
'pc.atendimento_domiciliar_atendimento_id',
|
||||
'pc.ciap_id',
|
||||
'pc.cid_id',
|
||||
'geral_ciap.codigo as ciap_codigo',
|
||||
'geral_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"),
|
||||
])
|
||||
->leftJoin('geral_ciap', 'geral_ciap.id', 'pc.ciap_id')
|
||||
->leftJoin('sigtap.cid', 'cid.id', 'pc.cid_id')
|
||||
->whereIn('pc.atendimento_domiciliar_atendimento_id', $atendimentoIds)
|
||||
->get()
|
||||
->groupBy('atendimento_domiciliar_atendimento_id');
|
||||
|
||||
$codigosEsusPorAtendimento = self::loadCodigosEsus($atendimentoIds);
|
||||
|
||||
$todosCodigos = collect($codigosEsusPorAtendimento)->flatten()->unique()->values()->all();
|
||||
|
||||
$ciapsPorCodigoEsus = self::loadCiapsPorCodigoEsus($todosCodigos);
|
||||
|
||||
$resultado = [];
|
||||
|
||||
foreach ($atendimentoIds as $id) {
|
||||
|
||||
$problemasCondicoes = collect($problemasCondicoesRaw[$id] ?? [])
|
||||
->map(function ($pc) {
|
||||
$pc->atendimento_domiciliar_atendimento_id = null;
|
||||
$pc->is_cid_familia_Z34 = (bool) $pc->is_cid_familia_Z34;
|
||||
return $pc;
|
||||
})
|
||||
->values();
|
||||
|
||||
$ciapsAdicionais = collect();
|
||||
$vistos = [];
|
||||
|
||||
foreach ($codigosEsusPorAtendimento[$id] ?? [] as $codigo) {
|
||||
|
||||
foreach ($ciapsPorCodigoEsus[$codigo] ?? [] as $ciap) {
|
||||
|
||||
if (!isset($vistos[$ciap->ciap_id])) {
|
||||
$ciapsAdicionais->push($ciap);
|
||||
$vistos[$ciap->ciap_id] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$resultado[$id] = $problemasCondicoes->concat($ciapsAdicionais)->values();
|
||||
}
|
||||
|
||||
return $resultado;
|
||||
}
|
||||
|
||||
private static function loadCodigosEsus(array $atendimentoIds): array
|
||||
{
|
||||
$fontes = [
|
||||
['atencao_basica_atendimento_domiciliar_atend_condicao_avaliada', 'atencao_basica_cadastro_condicao_avaliada', 'condicao_avaliada_id'],
|
||||
['atencao_basica_atendimento_domiciliar_atend_doenca_transmissivel', 'atencao_basica_cadastro_doenca_transmissivel', 'doenca_transmissivel_id'],
|
||||
['atencao_basica_atendimento_domiciliar_atend_rastreamento', 'atencao_basica_cadastro_rastreamento', 'rastreamento_id'],
|
||||
];
|
||||
|
||||
$codigos = [];
|
||||
|
||||
foreach ($fontes as [$tabelaLink, $tabelaCadastro, $fk]) {
|
||||
|
||||
$rows = DB::table($tabelaLink)
|
||||
->join($tabelaCadastro, "{$tabelaCadastro}.id", "{$tabelaLink}.{$fk}")
|
||||
->whereIn("{$tabelaLink}.atendimento_domiciliar_atendimento_id", $atendimentoIds)
|
||||
->select(
|
||||
"{$tabelaLink}.atendimento_domiciliar_atendimento_id",
|
||||
"{$tabelaCadastro}.codigo_esus"
|
||||
)
|
||||
->get();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$codigos[$row->atendimento_domiciliar_atendimento_id][] = $row->codigo_esus;
|
||||
}
|
||||
}
|
||||
|
||||
return $codigos;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,495 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\AtencaoBasica\RelatorioInconsistencia;
|
||||
|
||||
use App\Enums\AtencaoBasica\Exportacao\Inconsistencia;
|
||||
use App\Enums\AtencaoBasica\AtendimentoIndividual\CondicaoAvaliadaCodigoEsus;
|
||||
use App\Enums\AtencaoBasica\AtendimentoIndividual\RastreamentoCodigoEsus;
|
||||
use App\Enums\AtencaoBasica\Parametrizacao\Permissao;
|
||||
use App\Rules\AtencaoBasica\Exportacao\AlturaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CircunferenciaAbdominalLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnesIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnsPaciente;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\FrequenciaCardiacaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\FrequenciaRespiratoriaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\GlicemiaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\IbgeIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\LocalAtendimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\LocalAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\MomentoColetaGlicemiaIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\OcupacaoIsAllowed;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PerimetroCefalicoLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PerimetroPanturrilhaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PesoLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PressaoArterialDiastolicaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PressaoArterialSistolicaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProblemaCondicaoCiapIsDuplicated;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProblemaCondicaoCiapIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProblemaCondicaoCidIsDuplicated;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProblemaCondicaoCidIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProblemaCondicaoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\SaturacaoO2LimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\SexoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TemperaturaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TipoAtendimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TipoAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TurnoIsRequired;
|
||||
use App\Rules\Cns;
|
||||
use App\Rules\Cpf;
|
||||
use App\Services\Service;
|
||||
use App\Utils\MaskUtil;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class FichaAtendimentoIndividualService extends Service
|
||||
{
|
||||
private const HEADER_ERROR_MAP = [
|
||||
CnesIsValid::class => 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('<br />');
|
||||
$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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,512 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\AtencaoBasica\RelatorioInconsistencia;
|
||||
|
||||
use App\Enums\AtencaoBasica\Exportacao\Inconsistencia;
|
||||
use App\Enums\AtencaoBasica\Parametrizacao\Permissao;
|
||||
use App\Rules\AtencaoBasica\Exportacao\AlturaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CircunferenciaAbdominalLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnesIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnsPaciente;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CondutaEncaminhamentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CondutaEncaminhamentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\FrequenciaCardiacaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\FrequenciaRespiratoriaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\GestanteIsValidForFicha;
|
||||
use App\Rules\AtencaoBasica\Exportacao\GlicemiaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\IbgeIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\LocalAtendimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\LocalAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\MomentoColetaGlicemiaIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\OcupacaoIsAllowed;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PerimetroCefalicoLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PerimetroPanturrilhaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PesoLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PressaoArterialDiastolicaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PressaoArterialSistolicaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProblemaCondicaoCiapIsDuplicated;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProblemaCondicaoCiapIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProblemaCondicaoCidIsDuplicated;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProblemaCondicaoCidIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProblemaCondicaoCidOuCiapIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProblemaCondicaoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProcedimentoLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\SaturacaoO2LimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\SexoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TemperaturaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TipoAtendimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TipoAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TipoConsultaIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TipoConsultaIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TurnoIsRequired;
|
||||
use App\Rules\Cns;
|
||||
use App\Rules\Cpf;
|
||||
use App\Services\Service;
|
||||
use App\Utils\MaskUtil;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class FichaAtendimentoOdontologicoService extends Service
|
||||
{
|
||||
private const ERROR_MAP = [
|
||||
CnesIsValid::class => 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,
|
||||
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,
|
||||
GestanteIsValidForFicha::class => Inconsistencia::GESTANTE_PREENCHIDO_PARA_PACIENTES_DO_SEXO_MASCULINO,
|
||||
CondutaEncaminhamentoIsValid::class => Inconsistencia::CONDUTA_OU_ENCAMINHAMENTO_INVALIDO,
|
||||
CondutaEncaminhamentoIsRequired::class => Inconsistencia::CONDUTA_OU_ENCAMINHAMENTO_SEM_PREENCHIMENTO,
|
||||
TipoConsultaIsRequired::class => Inconsistencia::TIPO_CONSULTA_SEM_PREENCHIMENTO,
|
||||
TipoConsultaIsValid::class => Inconsistencia::TIPO_CONSULTA_INVALIDO,
|
||||
SexoIsRequired::class => Inconsistencia::SEXO_DO_PACIENTE_SEM_PREENCHIMENTO,
|
||||
ProcedimentoLimitIsValid::class => Inconsistencia::PACIENTE_COM_MAIS_DE_20_PROCEDIMENTOS_INSERIDOS,
|
||||
TipoAtendimentoIsRequired::class => Inconsistencia::TIPO_DE_ATENDIMENTO_SEM_PREENCHIMENTO,
|
||||
TipoAtendimentoIsValid::class => Inconsistencia::TIPO_DE_ATENDIMENTO_INVALIDO,
|
||||
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,
|
||||
ProblemaCondicaoIsRequired::class => Inconsistencia::PROBLEMA_OU_CONDICAO_SEM_PREENCHIMENTO,
|
||||
ProblemaCondicaoCidOuCiapIsRequired::class => Inconsistencia::PROBLEMA_E_CONDICAO_SEM_CIAP2_E_SEM_CID10,
|
||||
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');
|
||||
|
||||
$fichasAtendimentoOdontologico = DB::table('atencao_basica_atendimento_odontologico')
|
||||
->select([
|
||||
'atencao_basica_atendimento_odontologico.id as id',
|
||||
'atencao_basica_atendimento_odontologico.usuario_id as usuario_id',
|
||||
'atencao_basica_atendimento_odontologico.data_atendimento 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_odontologico.local_atendimento_id',
|
||||
'atencao_basica_atendimento_odontologico.turno_id',
|
||||
'atencao_basica_atendimento_odontologico.tipo_atendimento_id',
|
||||
'atencao_basica_atendimento_odontologico.tipo_consulta_id',
|
||||
'atencao_basica_atendimento_odontologico.paciente_id',
|
||||
'atencao_basica_atendimento_odontologico.gestante',
|
||||
'atencao_basica_atendimento_odontologico.perimetro_cefalico',
|
||||
'atencao_basica_atendimento_odontologico.peso',
|
||||
'atencao_basica_atendimento_odontologico.altura',
|
||||
'atencao_basica_atendimento_odontologico.temperatura',
|
||||
'atencao_basica_atendimento_odontologico.pressao_arterial',
|
||||
'atencao_basica_atendimento_odontologico.frequencia_respiratoria',
|
||||
'atencao_basica_atendimento_odontologico.frequencia_cardiaca',
|
||||
'atencao_basica_atendimento_odontologico.saturacao_o2',
|
||||
'atencao_basica_atendimento_odontologico.circunferencia_abdominal',
|
||||
'atencao_basica_atendimento_odontologico.perimetro_panturrilha',
|
||||
'atencao_basica_atendimento_odontologico.glicemia',
|
||||
'atencao_basica_atendimento_odontologico.momento_coleta_id',
|
||||
])
|
||||
->join('atencao_basica_parametrizacao_equipe', 'atencao_basica_parametrizacao_equipe.id', 'atencao_basica_atendimento_odontologico.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_odontologico.usuario_id')
|
||||
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id')
|
||||
->join('sigtap.ocupacao', 'sigtap.ocupacao.id', 'atencao_basica_atendimento_odontologico.ocupacao_id')
|
||||
->join('cadastro_paciente', 'cadastro_paciente.id', 'atencao_basica_atendimento_odontologico.paciente_id')
|
||||
->join('cadastro_cidadao as paciente_cidadao', 'paciente_cidadao.id', 'cadastro_paciente.cidadao_id')
|
||||
->whereBetween('atencao_basica_atendimento_odontologico.data_atendimento', [$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_odontologico.usuario_id', request()->usuario_id))
|
||||
->get();
|
||||
|
||||
if ($fichasAtendimentoOdontologico->isEmpty()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$atendimentoIds = $fichasAtendimentoOdontologico->pluck('id')->all();
|
||||
$problemasCondicoesPorAtendimento = self::loadProblemasCondicoes($atendimentoIds);
|
||||
|
||||
$groupedList = [];
|
||||
|
||||
foreach ($fichasAtendimentoOdontologico as $ficha) {
|
||||
|
||||
$problemasCondicoes = $problemasCondicoesPorAtendimento[$ficha->id] ?? collect();
|
||||
|
||||
$errors = RelatorioInconsistenciaService::validHeader($ficha, Permissao::ATENDIMENTO_ODONTOLOGICO)
|
||||
->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 odontológico',
|
||||
'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('<br />');
|
||||
$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($atendimento, Collection $problemasCondicoes): Collection
|
||||
{
|
||||
$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 (!GestanteIsValidForFicha::isValid($atendimento)) {
|
||||
$errors->push(GestanteIsValidForFicha::class);
|
||||
}
|
||||
|
||||
if (!CondutaEncaminhamentoIsRequired::isValid($atendimento)) {
|
||||
$errors->push(CondutaEncaminhamentoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!CondutaEncaminhamentoIsValid::isValid($atendimento)) {
|
||||
$errors->push(CondutaEncaminhamentoIsValid::class);
|
||||
}
|
||||
|
||||
if (!TipoConsultaIsRequired::isValid($atendimento)) {
|
||||
$errors->push(TipoConsultaIsRequired::class);
|
||||
}
|
||||
|
||||
if (!TipoConsultaIsValid::isValid($atendimento)) {
|
||||
$errors->push(TipoConsultaIsValid::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 (!ProblemaCondicaoCidOuCiapIsRequired::isValid($problemasCondicoes)) {
|
||||
$errors->push(ProblemaCondicaoCidOuCiapIsRequired::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_odontologico_problema_condicao as pc')
|
||||
->select([
|
||||
'pc.atendimento_odontologico_id',
|
||||
'pc.ciap_id',
|
||||
'pc.cid_id',
|
||||
'geral_ciap.codigo as ciap_codigo',
|
||||
'geral_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"),
|
||||
])
|
||||
->leftJoin('geral_ciap', 'geral_ciap.id', 'pc.ciap_id')
|
||||
->leftJoin('sigtap.cid', 'cid.id', 'pc.cid_id')
|
||||
->whereIn('pc.atendimento_odontologico_id', $atendimentoIds)
|
||||
->get()
|
||||
->groupBy('atendimento_odontologico_id');
|
||||
|
||||
$codigosEsusPorAtendimento = self::loadCodigosEsus($atendimentoIds);
|
||||
|
||||
$todosCodigos = collect($codigosEsusPorAtendimento)->flatten()->unique()->values()->all();
|
||||
|
||||
$ciapsPorCodigoEsus = self::loadCiapsPorCodigoEsus($todosCodigos);
|
||||
|
||||
$resultado = [];
|
||||
|
||||
foreach ($atendimentoIds as $id) {
|
||||
|
||||
$problemasCondicoes = collect($problemasCondicoesRaw[$id] ?? [])
|
||||
->map(function ($pc) {
|
||||
$pc->atendimento_odontologico_id = null;
|
||||
$pc->is_cid_familia_Z34 = (bool) $pc->is_cid_familia_Z34;
|
||||
return $pc;
|
||||
})
|
||||
->values();
|
||||
|
||||
$ciapsExistentes = $problemasCondicoes->pluck('ciap_id')->filter()->flip()->all();
|
||||
|
||||
$ciapsAdicionais = collect();
|
||||
$vistos = [];
|
||||
|
||||
foreach ($codigosEsusPorAtendimento[$id] ?? [] as $codigo) {
|
||||
|
||||
foreach ($ciapsPorCodigoEsus[$codigo] ?? [] as $ciap) {
|
||||
|
||||
if (isset($ciapsExistentes[$ciap->ciap_id]) || isset($vistos[$ciap->ciap_id])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ciapsAdicionais->push($ciap);
|
||||
$vistos[$ciap->ciap_id] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$resultado[$id] = $problemasCondicoes->concat($ciapsAdicionais)->values();
|
||||
}
|
||||
|
||||
return $resultado;
|
||||
}
|
||||
|
||||
private static function loadCodigosEsus(array $atendimentoIds): array
|
||||
{
|
||||
$fontes = [
|
||||
['atencao_basica_atendimento_odontologico_condicao_avaliada', 'atencao_basica_cadastro_condicao_avaliada', 'condicao_avaliada_id'],
|
||||
['atencao_basica_atendimento_odontologico_doenca_transmissivel', 'atencao_basica_cadastro_doenca_transmissivel', 'doenca_transmissivel_id'],
|
||||
['atencao_basica_atendimento_odontologico_rastreamento', 'atencao_basica_cadastro_rastreamento', 'rastreamento_id'],
|
||||
];
|
||||
|
||||
$codigos = [];
|
||||
|
||||
foreach ($fontes as [$tabelaLink, $tabelaCadastro, $fk]) {
|
||||
|
||||
$rows = DB::table($tabelaLink)
|
||||
->join($tabelaCadastro, "{$tabelaCadastro}.id", "{$tabelaLink}.{$fk}")
|
||||
->whereIn("{$tabelaLink}.atendimento_odontologico_id", $atendimentoIds)
|
||||
->select(
|
||||
"{$tabelaLink}.atendimento_odontologico_id",
|
||||
"{$tabelaCadastro}.codigo_esus"
|
||||
)
|
||||
->get();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$codigos[$row->atendimento_odontologico_id][] = $row->codigo_esus;
|
||||
}
|
||||
}
|
||||
|
||||
return $codigos;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\AtencaoBasica\RelatorioInconsistencia;
|
||||
|
||||
use App\Enums\AtencaoBasica\Exportacao\Inconsistencia;
|
||||
use App\Enums\AtencaoBasica\Parametrizacao\Permissao;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnesIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnsPaciente;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\IbgeIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\OcupacaoIsAllowed;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TurnoIsRequired;
|
||||
use App\Rules\Cns;
|
||||
use App\Rules\Cpf;
|
||||
use App\Services\Service;
|
||||
use App\Utils\MaskUtil;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class FichaAtividadeColetivaService extends Service
|
||||
{
|
||||
private const ERROR_MAP = [
|
||||
CnesIsValid::class => 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,
|
||||
TurnoIsRequired::class => Inconsistencia::TURNO_SEM_PREENCHIMENTO,
|
||||
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,
|
||||
];
|
||||
|
||||
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');
|
||||
|
||||
$fichasAtividadeColetiva = DB::table('atencao_basica_atividade_coletiva')
|
||||
->select([
|
||||
'atencao_basica_atividade_coletiva.id as id',
|
||||
'atencao_basica_atividade_coletiva.turno_id',
|
||||
'atencao_basica_atividade_coletiva.usuario_id as usuario_id',
|
||||
'cadastro_cidadao.cns AS usuario_cns',
|
||||
'cadastro_cidadao.nome AS profissional_nome',
|
||||
'atencao_basica_atividade_coletiva.data_usuario_responsavel as data_atendimento',
|
||||
'cadastro_unidade.cnes as unidade_cnes',
|
||||
'cadastro_municipio.ibge as municipio_ibge',
|
||||
'sigtap.ocupacao.codigo as ocupacao_codigo',
|
||||
])
|
||||
->join('atencao_basica_parametrizacao_equipe', 'atencao_basica_parametrizacao_equipe.id', 'atencao_basica_atividade_coletiva.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_atividade_coletiva.usuario_id')
|
||||
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id')
|
||||
->join('sigtap.ocupacao', 'sigtap.ocupacao.id', 'atencao_basica_atividade_coletiva.usuario_ocupacao_id')
|
||||
->whereBetween('atencao_basica_atividade_coletiva.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_atividade_coletiva.usuario_id', request()->usuario_id))
|
||||
->get();
|
||||
|
||||
if ($fichasAtividadeColetiva->isEmpty()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$atividadeIds = $fichasAtividadeColetiva->pluck('id')->all();
|
||||
$residentesPorAtividade = self::loadResidentes($atividadeIds);
|
||||
|
||||
$groupedList = [];
|
||||
|
||||
foreach ($fichasAtividadeColetiva as $ficha) {
|
||||
|
||||
$errosHeader = RelatorioInconsistenciaService::validHeader($ficha, Permissao::ATIVIDADE_COLETIVA);
|
||||
|
||||
foreach ($residentesPorAtividade[$ficha->id] ?? [] as $residente) {
|
||||
|
||||
$errors = $errosHeader->merge(self::validAtendimento($ficha, $residente));
|
||||
$errorDescriptions = self::mapErrorsToDescriptions($errors, $inconsistencias);
|
||||
|
||||
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' => 'Atividade coletiva',
|
||||
'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('<br />');
|
||||
$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, $residente): Collection
|
||||
{
|
||||
$errors = collect();
|
||||
|
||||
if (!TurnoIsRequired::isValid($cadastro->turno_id)) {
|
||||
$errors->push(TurnoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!Cns::isValid($residente->cns) && !Cpf::isValid($residente->cpf)) {
|
||||
$errors->push(CnsPaciente::class);
|
||||
$errors->push(Cpf::class);
|
||||
}
|
||||
|
||||
if (!DataNascimentoIsRequired::isValid($residente->data_nascimento)) {
|
||||
$errors->push(DataNascimentoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!DataNascimentoIsValid::isValid([
|
||||
'data_nascimento' => $residente->data_nascimento,
|
||||
'data_atendimento' => $cadastro->data_atendimento
|
||||
])) {
|
||||
$errors->push(DataNascimentoIsValid::class);
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
private static function loadResidentes(array $atividadeIds): array
|
||||
{
|
||||
if (empty($atividadeIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rows = DB::table('atencao_basica_atividade_coletiva_participante')
|
||||
->select([
|
||||
'atencao_basica_atividade_coletiva_participante.atividade_coletiva_id',
|
||||
'cadastro_cidadao.data_nascimento',
|
||||
'cadastro_cidadao.sexo_id',
|
||||
'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',
|
||||
'cadastro_paciente.id as paciente_id',
|
||||
DB::raw('LPAD(cadastro_paciente.prontuario,7,0) AS paciente_prontuario'),
|
||||
])
|
||||
->join('cadastro_paciente', 'cadastro_paciente.id', 'atencao_basica_atividade_coletiva_participante.paciente_id')
|
||||
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_paciente.cidadao_id')
|
||||
->whereIn('atencao_basica_atividade_coletiva_participante.atividade_coletiva_id', $atividadeIds)
|
||||
->whereNotExists(function ($query) {
|
||||
$query->select(DB::raw(1))
|
||||
->from('cadastro_obito')
|
||||
->whereColumn('cadastro_obito.cidadao_id', 'cadastro_cidadao.id');
|
||||
})
|
||||
->get();
|
||||
|
||||
$porAtividade = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$porAtividade[$row->atividade_coletiva_id][] = $row;
|
||||
}
|
||||
|
||||
return $porAtividade;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\AtencaoBasica\RelatorioInconsistencia;
|
||||
|
||||
use App\Enums\AtencaoBasica\Exportacao\Inconsistencia;
|
||||
use App\Enums\AtencaoBasica\Parametrizacao\Permissao;
|
||||
use App\Enums\Cadastro\SujeitoAtencao\RacaCor;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CidAavaliacaoIsDuplicate;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CidIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnesIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnsPaciente;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ConclusaoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\IbgeIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\OcupacaoIsAllowed;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProcedenciaIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\RacaCorIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\SexoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TurnoIsRequired;
|
||||
use App\Rules\Cns;
|
||||
use App\Rules\Cpf;
|
||||
use App\Services\Service;
|
||||
use App\Utils\MaskUtil;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class FichaAvaliacaoElegibilidadeService extends Service
|
||||
{
|
||||
private const FICHA_LABEL = 'Avaliaçăo de elegibilidade e admissăo';
|
||||
|
||||
private const ERROR_MAP = [
|
||||
CnesIsValid::class => 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,
|
||||
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,
|
||||
TurnoIsRequired::class => Inconsistencia::TURNO_SEM_PREENCHIMENTO,
|
||||
SexoIsRequired::class => Inconsistencia::SEXO_DO_PACIENTE_SEM_PREENCHIMENTO,
|
||||
RacaCorIsRequired::class => Inconsistencia::RACA_COR_SEM_PREENCHIMENTO,
|
||||
ProcedenciaIsRequired::class => Inconsistencia::PROCEDENCIA_SEM_PREENCHIMENTO,
|
||||
ConclusaoIsRequired::class => Inconsistencia::CONCLUSAO_SEM_PREENCHIMENTO,
|
||||
CidIsRequired::class => Inconsistencia::CID_PRINCIPAL_SEM_PREENCHIMENTO,
|
||||
CidAavaliacaoIsDuplicate::class => Inconsistencia::CID_EM_DUPLICIDADE,
|
||||
];
|
||||
|
||||
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');
|
||||
|
||||
$fichasAvaliacao = DB::table('atencao_basica_avaliacao')
|
||||
->select([
|
||||
'atencao_basica_avaliacao.id as id',
|
||||
'atencao_basica_avaliacao.usuario_id as usuario_id',
|
||||
'atencao_basica_avaliacao.data 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.raca_cor_id as paciente_raca_cor_id',
|
||||
'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',
|
||||
'paciente_cidadao.sexo_id as paciente_sexo_id',
|
||||
DB::raw('LPAD(cadastro_paciente.prontuario,7,0) AS paciente_prontuario'),
|
||||
'atencao_basica_avaliacao.turno_id',
|
||||
'atencao_basica_avaliacao.paciente_id',
|
||||
'atencao_basica_avaliacao.procedencia_id',
|
||||
'atencao_basica_avaliacao.conclusao_id',
|
||||
'atencao_basica_avaliacao.cid_primario',
|
||||
'atencao_basica_avaliacao.cid_secundario',
|
||||
'atencao_basica_avaliacao.cid_terciario',
|
||||
'atencao_basica_avaliacao.cns_cuidador',
|
||||
'atencao_basica_avaliacao.cpf_cuidador',
|
||||
])
|
||||
->join('atencao_basica_parametrizacao_equipe', 'atencao_basica_parametrizacao_equipe.id', 'atencao_basica_avaliacao.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_avaliacao.usuario_id')
|
||||
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id')
|
||||
->join('sigtap.ocupacao', 'sigtap.ocupacao.id', 'atencao_basica_avaliacao.ocupacao_id')
|
||||
->join('cadastro_paciente', 'cadastro_paciente.id', 'atencao_basica_avaliacao.paciente_id')
|
||||
->join('cadastro_cidadao as paciente_cidadao', 'paciente_cidadao.id', 'cadastro_paciente.cidadao_id')
|
||||
->whereBetween('atencao_basica_avaliacao.data', [$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_avaliacao.usuario_id', request()->usuario_id))
|
||||
->get();
|
||||
|
||||
$groupedList = [];
|
||||
|
||||
foreach ($fichasAvaliacao as $ficha) {
|
||||
|
||||
$errosHeader = RelatorioInconsistenciaService::validHeader($ficha, Permissao::AVALIACAO_ELEGIBILIDADE_ADMISSAO);
|
||||
$errosAtendimento = self::validAtendimento($ficha);
|
||||
|
||||
$errors = $errosHeader->merge($errosAtendimento);
|
||||
$errorDescriptions = self::mapErrorsToDescriptions($errors, $inconsistencias);
|
||||
|
||||
if (
|
||||
$errosAtendimento->isNotEmpty()
|
||||
&& ($ficha->cns_cuidador || $ficha->cpf_cuidador)
|
||||
&& !Cns::isValid($ficha->paciente_cns)
|
||||
&& !Cpf::isValid($ficha->paciente_cpf)
|
||||
) {
|
||||
|
||||
$descricao = $inconsistencias[Inconsistencia::CNS_DO_CUIDADOR_INVALIDO] ?? null;
|
||||
|
||||
if ($descricao !== null) {
|
||||
$errorDescriptions->push($descricao);
|
||||
}
|
||||
}
|
||||
|
||||
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' => self::FICHA_LABEL,
|
||||
'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,
|
||||
'paciente_cns' => $ficha->paciente_cns ? MaskUtil::getCnsMasked($ficha->paciente_cns) : '-',
|
||||
'paciente_cpf' => $ficha->paciente_cpf ? MaskUtil::getCpfMasked($ficha->paciente_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('<br />');
|
||||
$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($ficha): Collection
|
||||
{
|
||||
$errors = collect();
|
||||
|
||||
if (!Cns::isValid($ficha->paciente_cns) && !Cpf::isValid($ficha->paciente_cpf)) {
|
||||
$errors->push(CnsPaciente::class);
|
||||
$errors->push(Cpf::class);
|
||||
}
|
||||
|
||||
if (!DataNascimentoIsRequired::isValid($ficha->paciente_data_nascimento)) {
|
||||
$errors->push(DataNascimentoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!DataNascimentoIsValid::isValid([
|
||||
'data_nascimento' => $ficha->paciente_data_nascimento,
|
||||
'data_atendimento' => $ficha->data_atendimento
|
||||
])) {
|
||||
$errors->push(DataNascimentoIsValid::class);
|
||||
}
|
||||
|
||||
if (!TurnoIsRequired::isValid($ficha->turno_id)) {
|
||||
$errors->push(TurnoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!SexoIsRequired::isValid($ficha->paciente_sexo_id)) {
|
||||
$errors->push(SexoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!RacaCorIsRequired::isValid($ficha->paciente_raca_cor_id)) {
|
||||
$errors->push(RacaCorIsRequired::class);
|
||||
}
|
||||
|
||||
if ($ficha->paciente_raca_cor_id == RacaCor::SEM_INFORMACAO) {
|
||||
$errors->push(RacaCorIsRequired::class);
|
||||
}
|
||||
|
||||
if (!ProcedenciaIsRequired::isValid($ficha->procedencia_id)) {
|
||||
$errors->push(ProcedenciaIsRequired::class);
|
||||
}
|
||||
|
||||
if (!ConclusaoIsRequired::isValid($ficha->conclusao_id)) {
|
||||
$errors->push(ConclusaoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!CidIsRequired::isValid($ficha->cid_primario)) {
|
||||
$errors->push(CidIsRequired::class);
|
||||
}
|
||||
|
||||
if (!CidAavaliacaoIsDuplicate::isValid($ficha)) {
|
||||
$errors->push(CidAavaliacaoIsDuplicate::class);
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\AtencaoBasica\RelatorioInconsistencia;
|
||||
|
||||
use App\Enums\AtencaoBasica\CadastroDomiciliar\ImovelTipo;
|
||||
use App\Enums\AtencaoBasica\Exportacao\Inconsistencia;
|
||||
use App\Enums\AtencaoBasica\Parametrizacao\Permissao;
|
||||
use App\Rules\AtencaoBasica\Exportacao\BairroIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CepIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnesIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\IbgeIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\IbgeIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\LogradouroIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\LogradouroTipoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\MicroAreaIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\OcupacaoIsAllowed;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ResponsavelTecnicoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\UfIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ZonaIsRequired;
|
||||
use App\Rules\Cns;
|
||||
use App\Rules\Cpf;
|
||||
use App\Services\Service;
|
||||
use App\Utils\MaskUtil;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class FichaCadastroDomiciliarService extends Service
|
||||
{
|
||||
private const ERROR_MAP = [
|
||||
CnesIsValid::class => 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('<br />');
|
||||
$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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\AtencaoBasica\RelatorioInconsistencia;
|
||||
|
||||
use App\Enums\AtencaoBasica\Exportacao\Inconsistencia;
|
||||
use App\Enums\AtencaoBasica\Parametrizacao\Permissao;
|
||||
use App\Enums\Cadastro\SujeitoAtencao\LocalNascimento;
|
||||
use App\Enums\Cadastro\SujeitoAtencao\Nacionalidade;
|
||||
use App\Enums\Cadastro\SujeitoAtencao\RacaCor;
|
||||
use App\Rules\AtencaoBasica\Exportacao\AlimentosAcabaramIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnesIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnsPaciente;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ComeuALgunsAlimentosIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataEntradaIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\EtniaIndigenaIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\IbgeIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\OcupacaoIsAllowed;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PaisNascimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PaisNascimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\RacaCorIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\SexoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TelefoneIsRequired;
|
||||
use App\Rules\Cns;
|
||||
use App\Rules\Cpf;
|
||||
use App\Services\Service;
|
||||
use App\Utils\MaskUtil;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class FichaCadastroIndividualService extends Service
|
||||
{
|
||||
private const ERROR_MAP = [
|
||||
CnesIsValid::class => 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,
|
||||
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,
|
||||
SexoIsRequired::class => Inconsistencia::SEXO_DO_PACIENTE_SEM_PREENCHIMENTO,
|
||||
RacaCorIsRequired::class => Inconsistencia::RACA_COR_SEM_PREENCHIMENTO,
|
||||
TelefoneIsRequired::class => Inconsistencia::TELEFONE_CELULAR_INVALIDO,
|
||||
PaisNascimentoIsRequired::class => Inconsistencia::PAIS_NASCIMENTO_SEM_PREENCHIMENTO,
|
||||
DataEntradaIsRequired::class => Inconsistencia::DATA_ENTRADA_BRASIL_SEM_PREENCHIMENTO,
|
||||
PaisNascimentoIsValid::class => Inconsistencia::PAIS_NASCIMENTO_INVALIDO,
|
||||
EtniaIndigenaIsRequired::class => Inconsistencia::ETNIA_SEM_PREENCHIMENTO_QUANDO_RACA_DO_PACIENTE_E_INDIGENA,
|
||||
AlimentosAcabaramIsRequired::class => Inconsistencia::ALIMENTOS_ACABARAM_SEM_PREENCHIMENTO,
|
||||
ComeuALgunsAlimentosIsRequired::class => Inconsistencia::COMEU_APENAS_ALGUNS_ALIMENTOS_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');
|
||||
|
||||
$fichasCadastroIndividual = DB::table('atencao_basica_cadastro_individual')
|
||||
->select([
|
||||
'atencao_basica_cadastro_individual.id as id',
|
||||
'atencao_basica_cadastro_individual.usuario_id as usuario_id',
|
||||
'atencao_basica_cadastro_individual.alimentos_acabaram',
|
||||
'atencao_basica_cadastro_individual.comeu_alguns_alimentos',
|
||||
'atencao_basica_cadastro_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',
|
||||
DB::raw('LPAD(cadastro_paciente.prontuario,7,0) AS paciente_prontuario'),
|
||||
'responsavel_cidadao.cns as responsavel_cns',
|
||||
'responsavel_cidadao.cpf as responsavel_cpf',
|
||||
'paciente_cidadao.data_nascimento as paciente_data_nascimento',
|
||||
'paciente_cidadao.sexo_id as paciente_sexo_id',
|
||||
'paciente_cidadao.raca_cor_id as paciente_raca_cor_id',
|
||||
'atencao_basica_cadastro_individual.paciente_id',
|
||||
'atencao_basica_cadastro_individual.responsavel_cidadao_id',
|
||||
'paciente_cidadao.nacionalidade_id',
|
||||
'paciente_cidadao.pais_nascimento_id',
|
||||
'paciente_cidadao.etnia_indigena_id',
|
||||
'paciente_cidadao.local_nascimento_id',
|
||||
'entrada_brasil.data_entrada',
|
||||
DB::raw("
|
||||
(
|
||||
SELECT numero
|
||||
FROM cadastro_cidadao_telefone
|
||||
WHERE cadastro_cidadao_telefone.cidadao_id = paciente_cidadao.id
|
||||
AND cadastro_cidadao_telefone.principal = TRUE
|
||||
LIMIT 1
|
||||
) AS paciente_telefone
|
||||
"),
|
||||
])
|
||||
->join('atencao_basica_parametrizacao_equipe', 'atencao_basica_parametrizacao_equipe.id', 'atencao_basica_cadastro_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_cadastro_individual.usuario_id')
|
||||
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id')
|
||||
->join('sigtap.ocupacao', 'sigtap.ocupacao.id', 'atencao_basica_cadastro_individual.usuario_ocupacao_id')
|
||||
->join('cadastro_paciente', 'cadastro_paciente.id', 'atencao_basica_cadastro_individual.paciente_id')
|
||||
->join('cadastro_cidadao as paciente_cidadao', 'paciente_cidadao.id', 'cadastro_paciente.cidadao_id')
|
||||
->leftJoin('cadastro_cidadao as responsavel_cidadao', 'responsavel_cidadao.id', 'atencao_basica_cadastro_individual.responsavel_cidadao_id')
|
||||
->leftJoin('cadastro_estrangeiro_entrada_brasil as entrada_brasil', 'entrada_brasil.cidadao_id', 'paciente_cidadao.id')
|
||||
->whereBetween('atencao_basica_cadastro_individual.data_usuario_responsavel', [$start, $end])
|
||||
->whereNull('cadastro_paciente.deleted_at')
|
||||
->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_individual.usuario_id', request()->usuario_id))
|
||||
->get();
|
||||
|
||||
$groupedList = [];
|
||||
|
||||
foreach ($fichasCadastroIndividual as $ficha) {
|
||||
|
||||
$errosHeader = RelatorioInconsistenciaService::validHeader($ficha, Permissao::CADASTRO_INDIVIDUAL);
|
||||
$errosAtendimento = self::validAtendimento($ficha);
|
||||
|
||||
$errors = $errosHeader->merge($errosAtendimento);
|
||||
$errorDescriptions = self::mapErrorsToDescriptions($errors, $inconsistencias);
|
||||
|
||||
if (
|
||||
$errosAtendimento->isNotEmpty()
|
||||
&& $ficha->responsavel_cidadao_id
|
||||
&& !Cns::isValid($ficha->responsavel_cns)
|
||||
&& !Cpf::isValid($ficha->responsavel_cpf)
|
||||
) {
|
||||
|
||||
$descricao = $inconsistencias[Inconsistencia::CNS_DO_RESPONSAVEL_FAMILIAR_INVALIDO] ?? null;
|
||||
|
||||
if ($descricao !== null) {
|
||||
$errorDescriptions->push($descricao);
|
||||
}
|
||||
}
|
||||
|
||||
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' => 'Cadastro 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,
|
||||
'paciente_cns' => $ficha->paciente_cns ? MaskUtil::getCnsMasked($ficha->paciente_cns) : '-',
|
||||
'paciente_cpf' => $ficha->paciente_cpf ? MaskUtil::getCpfMasked($ficha->paciente_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('<br />');
|
||||
$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 (!Cns::isValid($cadastro->paciente_cns) && !Cpf::isValid($cadastro->paciente_cpf)) {
|
||||
$errors->push(CnsPaciente::class);
|
||||
$errors->push(Cpf::class);
|
||||
}
|
||||
|
||||
if (!DataNascimentoIsRequired::isValid($cadastro->paciente_data_nascimento)) {
|
||||
$errors->push(DataNascimentoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!DataNascimentoIsValid::isValid([
|
||||
'data_nascimento' => $cadastro->paciente_data_nascimento,
|
||||
'data_atendimento' => $cadastro->data_atendimento
|
||||
])) {
|
||||
$errors->push(DataNascimentoIsValid::class);
|
||||
}
|
||||
|
||||
if (!SexoIsRequired::isValid($cadastro->paciente_sexo_id)) {
|
||||
$errors->push(SexoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!RacaCorIsRequired::isValid($cadastro->paciente_raca_cor_id)) {
|
||||
$errors->push(RacaCorIsRequired::class);
|
||||
}
|
||||
|
||||
if ($cadastro->paciente_raca_cor_id == RacaCor::SEM_INFORMACAO) {
|
||||
$errors->push(RacaCorIsRequired::class);
|
||||
}
|
||||
|
||||
if (($cadastro->nacionalidade_id == Nacionalidade::BRASILEIRO || $cadastro->nacionalidade_id == Nacionalidade::NATURALIZADO_BRASILEIRO)
|
||||
&& !TelefoneIsRequired::isValid($cadastro->paciente_telefone)) {
|
||||
$errors->push(TelefoneIsRequired::class);
|
||||
}
|
||||
|
||||
if ($cadastro->nacionalidade_id == Nacionalidade::ESTRANGEIRO && !PaisNascimentoIsRequired::isValid($cadastro->pais_nascimento_id)) {
|
||||
$errors->push(PaisNascimentoIsRequired::class);
|
||||
}
|
||||
|
||||
if ($cadastro->nacionalidade_id == LocalNascimento::EM_OUTRO_PAIS && !DataEntradaIsRequired::isValid($cadastro->data_entrada) && $cadastro->nacionalidade_id == Nacionalidade::ESTRANGEIRO) {
|
||||
$errors->push(DataEntradaIsRequired::class);
|
||||
}
|
||||
|
||||
if ($cadastro->nacionalidade_id == Nacionalidade::BRASILEIRO && !PaisNascimentoIsValid::isValid($cadastro->pais_nascimento_id)) {
|
||||
$errors->push(PaisNascimentoIsValid::class);
|
||||
}
|
||||
|
||||
if ($cadastro->paciente_raca_cor_id == RacaCor::INDIGENA && !EtniaIndigenaIsRequired::isValid($cadastro->etnia_indigena_id)) {
|
||||
$errors->push(EtniaIndigenaIsRequired::class);
|
||||
}
|
||||
|
||||
if (
|
||||
(!is_null($cadastro->comeu_alguns_alimentos) && ($cadastro->comeu_alguns_alimentos == true || $cadastro->comeu_alguns_alimentos == false))
|
||||
&& $cadastro->alimentos_acabaram === null
|
||||
) {
|
||||
$errors->push(AlimentosAcabaramIsRequired::class);
|
||||
}
|
||||
|
||||
if (
|
||||
(!is_null($cadastro->alimentos_acabaram) && ($cadastro->alimentos_acabaram == true || $cadastro->alimentos_acabaram == false))
|
||||
&& $cadastro->comeu_alguns_alimentos === null
|
||||
) {
|
||||
$errors->push(ComeuALgunsAlimentosIsRequired::class);
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\AtencaoBasica\RelatorioInconsistencia;
|
||||
|
||||
use App\Enums\AtencaoBasica\Exportacao\Inconsistencia;
|
||||
use App\Enums\AtencaoBasica\Parametrizacao\Permissao;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnesIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnsPaciente;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ExameIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ExameIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\IbgeIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\OcupacaoIsAllowed;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TurnoIsRequired;
|
||||
use App\Rules\Cns;
|
||||
use App\Rules\Cpf;
|
||||
use App\Services\Service;
|
||||
use App\Utils\MaskUtil;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class FichaComplementarService extends Service
|
||||
{
|
||||
private const ERROR_MAP = [
|
||||
CnesIsValid::class => 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,
|
||||
CnsPaciente::class => Inconsistencia::CNS_DO_PACIENTE_INVALIDO,
|
||||
Cpf::class => Inconsistencia::CPF_DO_PACIENTE_INVALIDO,
|
||||
TurnoIsRequired::class => Inconsistencia::TURNO_SEM_PREENCHIMENTO,
|
||||
ExameIsRequired::class => Inconsistencia::NENHUM_EXAME_PREENCHIDO,
|
||||
ExameIsValid::class => Inconsistencia::EXAME_COM_DATA_PREENCHIDA_E_SEM_RESULTADO,
|
||||
];
|
||||
|
||||
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');
|
||||
|
||||
$fichasComplementar = DB::table('atencao_basica_ficha_complementar')
|
||||
->select([
|
||||
'atencao_basica_ficha_complementar.id as id',
|
||||
'atencao_basica_ficha_complementar.usuario_id as usuario_id',
|
||||
'atencao_basica_ficha_complementar.data_atendimento 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',
|
||||
DB::raw('LPAD(cadastro_paciente.prontuario,7,0) AS paciente_prontuario'),
|
||||
'atencao_basica_ficha_complementar.turno_id',
|
||||
'atencao_basica_ficha_complementar.paciente_id',
|
||||
'atencao_basica_ficha_complementar.data_realizacao_teste_olhinho',
|
||||
'atencao_basica_ficha_complementar.resultado_teste_olhinho_id',
|
||||
'atencao_basica_ficha_complementar.data_realizacao_fundo_olho',
|
||||
'atencao_basica_ficha_complementar.resultado_fundo_olho_id',
|
||||
'atencao_basica_ficha_complementar.data_realizacao_teste_orelhinha',
|
||||
'atencao_basica_ficha_complementar.resultado_teste_orelhinha_id',
|
||||
'atencao_basica_ficha_complementar.data_realizacao_us_transfontanela',
|
||||
'atencao_basica_ficha_complementar.resultado_us_transfontanela_id',
|
||||
'atencao_basica_ficha_complementar.data_realizacao_tomografia_computadorizada',
|
||||
'atencao_basica_ficha_complementar.resultado_tomografia_computadorizada_id',
|
||||
'atencao_basica_ficha_complementar.data_realizacao_ressonancia_magnetica',
|
||||
'atencao_basica_ficha_complementar.resultado_ressonancia_magnetica_id',
|
||||
])
|
||||
->join('atencao_basica_parametrizacao_equipe', 'atencao_basica_parametrizacao_equipe.id', 'atencao_basica_ficha_complementar.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_ficha_complementar.usuario_id')
|
||||
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id')
|
||||
->join('sigtap.ocupacao', 'sigtap.ocupacao.id', 'atencao_basica_ficha_complementar.cbo_id')
|
||||
->join('cadastro_paciente', 'cadastro_paciente.id', 'atencao_basica_ficha_complementar.paciente_id')
|
||||
->join('cadastro_cidadao as paciente_cidadao', 'paciente_cidadao.id', 'cadastro_paciente.cidadao_id')
|
||||
->whereBetween('atencao_basica_ficha_complementar.data_atendimento', [$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_ficha_complementar.usuario_id', request()->usuario_id))
|
||||
->get();
|
||||
|
||||
if ($fichasComplementar->isEmpty()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$responsaveisPorPaciente = self::loadResponsaveis(
|
||||
$fichasComplementar->pluck('paciente_id')->unique()->all()
|
||||
);
|
||||
|
||||
$groupedList = [];
|
||||
|
||||
foreach ($fichasComplementar as $ficha) {
|
||||
|
||||
$errosHeader = RelatorioInconsistenciaService::validHeader($ficha, Permissao::FICHA_COMPLEMENTAR);
|
||||
$errosAtendimento = self::validAtendimento($ficha);
|
||||
|
||||
$errors = $errosHeader->merge($errosAtendimento);
|
||||
$errorDescriptions = self::mapErrorsToDescriptions($errors, $inconsistencias);
|
||||
|
||||
if ($errosAtendimento->isNotEmpty()) {
|
||||
|
||||
$responsavel = $responsaveisPorPaciente[$ficha->paciente_id] ?? null;
|
||||
|
||||
if ($responsavel && !Cns::isValid($responsavel->cns) && !Cpf::isValid($responsavel->cpf)) {
|
||||
|
||||
$descricao = $inconsistencias[Inconsistencia::CNS_DO_RESPONSAVEL_FAMILIAR_INVALIDO] ?? null;
|
||||
|
||||
if ($descricao !== null) {
|
||||
$errorDescriptions->push($descricao);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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' => 'Ficha complementar',
|
||||
'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,
|
||||
'paciente_cns' => $ficha->paciente_cns ? MaskUtil::getCnsMasked($ficha->paciente_cns) : '-',
|
||||
'paciente_cpf' => $ficha->paciente_cpf ? MaskUtil::getCpfMasked($ficha->paciente_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('<br />');
|
||||
$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($atendimento): Collection
|
||||
{
|
||||
$errors = collect();
|
||||
|
||||
if (!Cns::isValid($atendimento->paciente_cns) && !Cpf::isValid($atendimento->paciente_cpf)) {
|
||||
$errors->push(CnsPaciente::class);
|
||||
$errors->push(Cpf::class);
|
||||
}
|
||||
|
||||
if (!TurnoIsRequired::isValid($atendimento->turno_id)) {
|
||||
$errors->push(TurnoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!ExameIsRequired::isValid($atendimento)) {
|
||||
$errors->push(ExameIsRequired::class);
|
||||
}
|
||||
|
||||
if (!ExameIsValid::isValid($atendimento)) {
|
||||
$errors->push(ExameIsValid::class);
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
private static function loadResponsaveis(array $pacienteIds): array
|
||||
{
|
||||
if (empty($pacienteIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return DB::table('atencao_basica_cadastro_individual')
|
||||
->whereIn('paciente_id', $pacienteIds)
|
||||
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'atencao_basica_cadastro_individual.responsavel_cidadao_id')
|
||||
->select(
|
||||
'atencao_basica_cadastro_individual.paciente_id',
|
||||
'cadastro_cidadao.cns',
|
||||
'cadastro_cidadao.cpf'
|
||||
)
|
||||
->get()
|
||||
->keyBy('paciente_id')
|
||||
->all();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\AtencaoBasica\RelatorioInconsistencia;
|
||||
|
||||
use App\Enums\AtencaoBasica\Exportacao\Inconsistencia;
|
||||
use App\Enums\AtencaoBasica\MarcadorConsumoAlimentar\GrupoPerguntas;
|
||||
use App\Enums\AtencaoBasica\Parametrizacao\Permissao;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnesIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnsPaciente;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\IbgeIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\LocalAtendimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\LocalAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\OcupacaoIsAllowed;
|
||||
use App\Rules\Cns;
|
||||
use App\Rules\Cpf;
|
||||
use App\Services\Service;
|
||||
use App\Utils\MaskUtil;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class FichaConsumoAlimentarService extends Service
|
||||
{
|
||||
private const FICHA_LABEL = 'Ficha de marcadores de consumo alimentar';
|
||||
|
||||
private const ERROR_MAP = [
|
||||
CnesIsValid::class => 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,
|
||||
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,
|
||||
];
|
||||
|
||||
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');
|
||||
|
||||
$fichasPorGrupo = [
|
||||
GrupoPerguntas::CRIANCAS_MENORES_6_MESES => self::queryFichas($start, $end)
|
||||
->whereRaw('TIMESTAMPDIFF(MONTH, cadastro_cidadao.data_nascimento, atencao_basica_consumo_alimentar.data_atendimento) < 6')
|
||||
->get(),
|
||||
GrupoPerguntas::CRIANCAS_DE_6_A_23_MESES => self::queryFichas($start, $end)
|
||||
->whereRaw('TIMESTAMPDIFF(MONTH, cadastro_cidadao.data_nascimento, atencao_basica_consumo_alimentar.data_atendimento) >= 6')
|
||||
->whereRaw('TIMESTAMPDIFF(MONTH, cadastro_cidadao.data_nascimento, atencao_basica_consumo_alimentar.data_atendimento) <= 23')
|
||||
->get(),
|
||||
GrupoPerguntas::CRIANCAS_ACIMA_DE_2_ANOS => self::queryFichas($start, $end)
|
||||
->whereRaw('TIMESTAMPDIFF(YEAR, paciente_cidadao.data_nascimento, atencao_basica_consumo_alimentar.data_atendimento) >= 2')
|
||||
->get(),
|
||||
];
|
||||
|
||||
$allFichaIds = collect($fichasPorGrupo)
|
||||
->flatMap(fn ($collection) => $collection->pluck('id'))
|
||||
->unique()
|
||||
->all();
|
||||
|
||||
if (empty($allFichaIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$perguntasFaltandoPorFicha = self::computeMissingResponses($allFichaIds);
|
||||
|
||||
$groupedList = [];
|
||||
|
||||
foreach ($fichasPorGrupo as $codigoGrupo => $fichas) {
|
||||
|
||||
foreach ($fichas as $ficha) {
|
||||
|
||||
$errors = RelatorioInconsistenciaService::validHeader($ficha, Permissao::MARCADORES_DE_CONSUMO_ALIMENTAR)
|
||||
->merge(self::validConsumo($ficha));
|
||||
|
||||
$errorDescriptions = self::mapErrorsToDescriptions($errors, $inconsistencias);
|
||||
|
||||
$faltaResposta = in_array(
|
||||
$codigoGrupo,
|
||||
$perguntasFaltandoPorFicha[$ficha->id] ?? [],
|
||||
true
|
||||
);
|
||||
|
||||
if ($faltaResposta) {
|
||||
|
||||
$descricao = $inconsistencias[Inconsistencia::PERGUNTA_SEM_RESPOSTA] ?? null;
|
||||
|
||||
if ($descricao !== null) {
|
||||
$errorDescriptions->push($descricao);
|
||||
}
|
||||
}
|
||||
|
||||
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' => self::FICHA_LABEL,
|
||||
'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('<br />');
|
||||
$group['total_erros'] = $unique->count();
|
||||
$result[] = $group;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private static function queryFichas(string $start, string $end)
|
||||
{
|
||||
return DB::table('atencao_basica_consumo_alimentar')
|
||||
->select([
|
||||
'atencao_basica_consumo_alimentar.id as id',
|
||||
'atencao_basica_consumo_alimentar.usuario_id as usuario_id',
|
||||
'atencao_basica_consumo_alimentar.data_atendimento as data_atendimento',
|
||||
'cadastro_unidade.cnes as unidade_cnes',
|
||||
'cadastro_municipio.ibge as municipio_ibge',
|
||||
'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',
|
||||
'paciente_cidadao.sexo_id as paciente_sexo_id',
|
||||
DB::raw('LPAD(cadastro_paciente.prontuario,7,0) AS paciente_prontuario'),
|
||||
'sigtap.ocupacao.codigo as ocupacao_codigo',
|
||||
'atencao_basica_consumo_alimentar.paciente_id as paciente_id',
|
||||
'atencao_basica_consumo_alimentar.local_atendimento_id as local_atendimento_id',
|
||||
])
|
||||
->join('atencao_basica_parametrizacao_equipe', 'atencao_basica_parametrizacao_equipe.id', 'atencao_basica_consumo_alimentar.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_consumo_alimentar.usuario_id')
|
||||
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id')
|
||||
->join('sigtap.ocupacao', 'sigtap.ocupacao.id', 'atencao_basica_consumo_alimentar.cbo_id')
|
||||
->join('cadastro_paciente', 'cadastro_paciente.id', 'atencao_basica_consumo_alimentar.paciente_id')
|
||||
->join('cadastro_cidadao as paciente_cidadao', 'paciente_cidadao.id', 'cadastro_paciente.cidadao_id')
|
||||
->whereBetween('atencao_basica_consumo_alimentar.data_atendimento', [$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_consumo_alimentar.usuario_id', request()->usuario_id));
|
||||
}
|
||||
|
||||
private static function computeMissingResponses(array $fichaIds): array
|
||||
{
|
||||
if (empty($fichaIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$perguntasPorGrupo = DB::table('atencao_basica_marcador_consumo_alimentar_perguntas')
|
||||
->select('id', 'codigo_grupo')
|
||||
->get()
|
||||
->groupBy('codigo_grupo')
|
||||
->map(fn ($items) => $items->pluck('id')->all())
|
||||
->all();
|
||||
|
||||
$respostasPorFicha = DB::table('atencao_basica_marcador_consumo_alimentar_pergunta_resposta')
|
||||
->whereIn('marcador_consumo_alimentar_id', $fichaIds)
|
||||
->select('marcador_consumo_alimentar_id', 'pergunta_id')
|
||||
->get()
|
||||
->groupBy('marcador_consumo_alimentar_id')
|
||||
->map(fn ($items) => $items->pluck('pergunta_id')->unique()->flip()->all())
|
||||
->all();
|
||||
|
||||
$faltandoPorFicha = [];
|
||||
|
||||
foreach ($fichaIds as $fichaId) {
|
||||
|
||||
$respondidas = $respostasPorFicha[$fichaId] ?? [];
|
||||
|
||||
foreach ($perguntasPorGrupo as $codigoGrupo => $perguntaIds) {
|
||||
|
||||
foreach ($perguntaIds as $perguntaId) {
|
||||
|
||||
if (!isset($respondidas[$perguntaId])) {
|
||||
$faltandoPorFicha[$fichaId][] = $codigoGrupo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $faltandoPorFicha;
|
||||
}
|
||||
|
||||
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 validConsumo($consumo): Collection
|
||||
{
|
||||
$errors = collect();
|
||||
|
||||
if (!Cns::isValid($consumo->paciente_cns) && !Cpf::isValid($consumo->paciente_cpf)) {
|
||||
$errors->push(CnsPaciente::class);
|
||||
$errors->push(Cpf::class);
|
||||
}
|
||||
|
||||
if (!DataNascimentoIsRequired::isValid($consumo->paciente_data_nascimento)) {
|
||||
$errors->push(DataNascimentoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!DataNascimentoIsValid::isValid([
|
||||
'data_nascimento' => $consumo->paciente_data_nascimento,
|
||||
'data_atendimento' => $consumo->data_atendimento
|
||||
])) {
|
||||
$errors->push(DataNascimentoIsValid::class);
|
||||
}
|
||||
|
||||
if (!LocalAtendimentoIsRequired::isValid($consumo->local_atendimento_id)) {
|
||||
$errors->push(LocalAtendimentoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!LocalAtendimentoIsValid::isValid($consumo->local_atendimento_id)) {
|
||||
$errors->push(LocalAtendimentoIsValid::class);
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,557 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\AtencaoBasica\RelatorioInconsistencia;
|
||||
|
||||
use App\Enums\AtencaoBasica\Exportacao\Inconsistencia;
|
||||
use App\Enums\AtencaoBasica\Parametrizacao\Permissao;
|
||||
use App\Enums\Sigtap\Procedimento;
|
||||
use App\Rules\AtencaoBasica\Exportacao\AlturaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CircunferenciaAbdominalLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnesIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnsPaciente;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\FrequenciaCardiacaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\FrequenciaRespiratoriaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\GlicemiaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\IbgeIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\LocalAtendimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\LocalAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\MomentoColetaGlicemiaIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\OcupacaoIsAllowed;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PerimetroCefalicoLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PerimetroPanturrilhaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PesoLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PressaoArterialDiastolicaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PressaoArterialSistolicaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProcedimentoIsDuplicate;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProcedimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProcedimentoIsValidForFicha;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ProcedimentoLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\SaturacaoO2LimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TemperaturaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TurnoIsRequired;
|
||||
use App\Rules\Cns;
|
||||
use App\Rules\Cpf;
|
||||
use App\Services\Service;
|
||||
use App\Utils\MaskUtil;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class FichaProcedimentoService extends Service
|
||||
{
|
||||
private const FICHA_LABEL = 'Procedimento';
|
||||
|
||||
private const HEADER_ERROR_MAP = [
|
||||
CnesIsValid::class => 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 PACIENTE_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,
|
||||
ProcedimentoLimitIsValid::class => Inconsistencia::PACIENTE_COM_MAIS_DE_20_PROCEDIMENTOS_INSERIDOS,
|
||||
ProcedimentoIsValidForFicha::class => Inconsistencia::PROCEDIMENTO_INVALIDO,
|
||||
ProcedimentoIsRequired::class => Inconsistencia::PROCEDIMENTO_INVALIDO,
|
||||
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,
|
||||
];
|
||||
|
||||
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');
|
||||
|
||||
$fichasProcedimento = DB::table('atencao_basica_procedimento')
|
||||
->select([
|
||||
'atencao_basica_procedimento.id as id',
|
||||
'atencao_basica_procedimento.usuario_id as usuario_id',
|
||||
'atencao_basica_procedimento.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',
|
||||
'atencao_basica_procedimento.afericao_pa as afericao_pa',
|
||||
'atencao_basica_procedimento.afericao_temperatura as afericao_temperatura',
|
||||
'atencao_basica_procedimento.curativo_simples as curativo_simples',
|
||||
'atencao_basica_procedimento.coleta_material_exame_laboratorial as coleta_material_exame_laboratorial',
|
||||
'atencao_basica_procedimento.glicemia_capilar as glicemia_capilar',
|
||||
'atencao_basica_procedimento.medicao_altura as medicao_altura',
|
||||
'atencao_basica_procedimento.medicao_peso as medicao_peso',
|
||||
])
|
||||
->join('atencao_basica_parametrizacao_equipe', 'atencao_basica_parametrizacao_equipe.id', 'atencao_basica_procedimento.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')
|
||||
->join('cadastro_usuario', 'cadastro_usuario.id', 'atencao_basica_procedimento.usuario_id')
|
||||
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id')
|
||||
->join('sigtap.ocupacao', 'sigtap.ocupacao.id', 'atencao_basica_procedimento.ocupacao_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')
|
||||
->whereBetween('atencao_basica_procedimento.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_procedimento.usuario_id', request()->usuario_id))
|
||||
->get();
|
||||
|
||||
if ($fichasProcedimento->isEmpty()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$fichaIds = $fichasProcedimento->pluck('id')->all();
|
||||
|
||||
$atendimentosPorFicha = self::loadAtendimentos($fichaIds);
|
||||
$atendimentoCountPorFicha = self::countAtendimentosPorFicha($fichaIds);
|
||||
|
||||
$allAtendimentoIds = collect($atendimentosPorFicha)
|
||||
->flatMap(fn ($items) => collect($items)->pluck('id'))
|
||||
->all();
|
||||
|
||||
$procedimentosPorAtendimento = self::loadProcedimentos($allAtendimentoIds);
|
||||
$procedimentoCountByAtendimento = self::countAuxiliares($allAtendimentoIds);
|
||||
|
||||
$groupedList = [];
|
||||
|
||||
foreach ($fichasProcedimento as $ficha) {
|
||||
|
||||
$errosHeader = RelatorioInconsistenciaService::validHeader($ficha, Permissao::PROCEDIMENTOS);
|
||||
$headerDescriptions = self::mapErrors($errosHeader, self::HEADER_ERROR_MAP, $inconsistencias);
|
||||
|
||||
$procedimentoCount = $atendimentoCountPorFicha[$ficha->id] ?? 0;
|
||||
$fichaDescriptions = self::collectProcedimentoErrors($ficha, $procedimentoCount, $inconsistencias);
|
||||
|
||||
$fichaSemPacienteDescriptions = collect($headerDescriptions->all())->merge($fichaDescriptions);
|
||||
|
||||
if ($fichaSemPacienteDescriptions->isNotEmpty()) {
|
||||
|
||||
$key = $ficha->data_atendimento . '||' . $ficha->usuario_id;
|
||||
|
||||
if (!isset($groupedList[$key])) {
|
||||
|
||||
$groupedList[$key] = [
|
||||
'data' => (new Carbon($ficha->data_atendimento))->format('d/m/Y'),
|
||||
'ficha' => self::FICHA_LABEL,
|
||||
'paciente_nome' => null,
|
||||
'paciente_nome_social' => null,
|
||||
'paciente_preferencia_nome_id' => null,
|
||||
'paciente_prontuario' => null,
|
||||
'paciente_cns' => '-',
|
||||
'paciente_cpf' => '-',
|
||||
'profissional' => $ficha->profissional_nome,
|
||||
'erros' => $fichaSemPacienteDescriptions,
|
||||
];
|
||||
} else {
|
||||
$groupedList[$key]['erros'] = $groupedList[$key]['erros']->merge($fichaSemPacienteDescriptions);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($atendimentosPorFicha[$ficha->id] ?? [] as $atendimento) {
|
||||
|
||||
$counts = $procedimentoCountByAtendimento[$atendimento->id] ?? [
|
||||
'procedimentos' => 0,
|
||||
'administracao' => 0,
|
||||
'pequena_cirurgia' => 0,
|
||||
'teste_rapido' => 0,
|
||||
];
|
||||
|
||||
$procedimentos = $procedimentosPorAtendimento[$atendimento->id] ?? collect();
|
||||
|
||||
$errosPaciente = self::validPaciente($atendimento, $procedimentos, $counts);
|
||||
$pacienteDescriptions = self::mapErrors($errosPaciente, self::PACIENTE_ERROR_MAP, $inconsistencias);
|
||||
|
||||
if ($pacienteDescriptions->isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$key = $ficha->data_atendimento . '|' . $atendimento->paciente_id . '|' . $ficha->usuario_id;
|
||||
|
||||
if (!isset($groupedList[$key])) {
|
||||
|
||||
$groupedList[$key] = [
|
||||
'data' => (new Carbon($ficha->data_atendimento))->format('d/m/Y'),
|
||||
'ficha' => self::FICHA_LABEL,
|
||||
'paciente_nome' => $atendimento->paciente_nome,
|
||||
'paciente_nome_social' => $atendimento->paciente_nome_social,
|
||||
'paciente_preferencia_nome_id' => $atendimento->paciente_preferencia_nome_id,
|
||||
'paciente_prontuario' => $atendimento->paciente_prontuario,
|
||||
'paciente_cns' => $atendimento->paciente_cns ? MaskUtil::getCnsMasked($atendimento->paciente_cns) : '-',
|
||||
'paciente_cpf' => $atendimento->paciente_cpf ? MaskUtil::getCpfMasked($atendimento->paciente_cpf) : '-',
|
||||
'profissional' => $ficha->profissional_nome,
|
||||
'erros' => $pacienteDescriptions,
|
||||
];
|
||||
} else {
|
||||
$groupedList[$key]['erros'] = $groupedList[$key]['erros']->merge($pacienteDescriptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($groupedList as $group) {
|
||||
|
||||
$unique = $group['erros']->unique();
|
||||
$group['erros'] = $unique->implode('<br />');
|
||||
$group['total_erros'] = $unique->count();
|
||||
$result[] = $group;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private static function mapErrors(Collection $errors, array $map, Collection $inconsistencias): Collection
|
||||
{
|
||||
$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 collectProcedimentoErrors($procedimento, int $procedimentoAtendimentoCount, Collection $inconsistencias): Collection
|
||||
{
|
||||
$descriptions = collect();
|
||||
|
||||
$consolidadoPreenchido = $procedimento->afericao_pa
|
||||
|| $procedimento->afericao_temperatura
|
||||
|| $procedimento->curativo_simples
|
||||
|| $procedimento->coleta_material_exame_laboratorial
|
||||
|| $procedimento->glicemia_capilar
|
||||
|| $procedimento->medicao_altura
|
||||
|| $procedimento->medicao_peso;
|
||||
|
||||
$individualPreenchido = $procedimentoAtendimentoCount > 0;
|
||||
|
||||
if ($procedimentoAtendimentoCount > 99) {
|
||||
|
||||
$descricao = $inconsistencias[Inconsistencia::FICHA_COM_MAIS_DE_99_PACIENTES_INSERIDOS] ?? null;
|
||||
|
||||
if ($descricao !== null) {
|
||||
$descriptions->push($descricao);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$consolidadoPreenchido && !$individualPreenchido) {
|
||||
|
||||
$descricao = $inconsistencias[Inconsistencia::NENHUM_PROCEDIMENTO_CONSOLIDADO_OU_INDIVIDUALIZADO_PREENCHIDO] ?? null;
|
||||
|
||||
if ($descricao !== null) {
|
||||
$descriptions->push($descricao);
|
||||
}
|
||||
}
|
||||
|
||||
return $descriptions;
|
||||
}
|
||||
|
||||
private static function validPaciente($atendimento, Collection $procedimentos, array $counts): Collection
|
||||
{
|
||||
$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 (!TurnoIsRequired::isValid($atendimento->turno_id)) {
|
||||
$errors->push(TurnoIsRequired::class);
|
||||
}
|
||||
|
||||
foreach ($procedimentos as $procedimento) {
|
||||
|
||||
if ($procedimento->is_duplicate) {
|
||||
$errors->push(ProcedimentoIsDuplicate::class);
|
||||
}
|
||||
|
||||
if ($procedimento->is_invalid_for_ficha) {
|
||||
$errors->push(ProcedimentoIsValidForFicha::class);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ProcedimentoLimitIsValid::isValid($counts['procedimentos'])) {
|
||||
$errors->push(ProcedimentoLimitIsValid::class);
|
||||
}
|
||||
|
||||
$procedimentosTotais = $counts['procedimentos'] + $counts['administracao'] + $counts['pequena_cirurgia'] + $counts['teste_rapido'];
|
||||
|
||||
if (!ProcedimentoIsRequired::isValid($atendimento, $procedimentosTotais)) {
|
||||
$errors->push(ProcedimentoIsRequired::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_capilar)) {
|
||||
$errors->push(GlicemiaLimitIsValid::class);
|
||||
}
|
||||
|
||||
if (!is_null($atendimento->glicemia_capilar) && !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->afericao_pa)) {
|
||||
$errors->push(PressaoArterialDiastolicaLimitIsValid::class);
|
||||
}
|
||||
|
||||
if (!PressaoArterialSistolicaLimitIsValid::isValid($atendimento->afericao_pa)) {
|
||||
$errors->push(PressaoArterialSistolicaLimitIsValid::class);
|
||||
}
|
||||
|
||||
if (!SaturacaoO2LimitIsValid::isValid($atendimento->saturacao_o2)) {
|
||||
$errors->push(SaturacaoO2LimitIsValid::class);
|
||||
}
|
||||
|
||||
if (!TemperaturaLimitIsValid::isValid($atendimento->temperatura)) {
|
||||
$errors->push(TemperaturaLimitIsValid::class);
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
private static function loadAtendimentos(array $fichaIds): array
|
||||
{
|
||||
if (empty($fichaIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rows = DB::table('atencao_basica_procedimento_atendimento')
|
||||
->select(
|
||||
'atencao_basica_procedimento_atendimento.id as id',
|
||||
'atencao_basica_procedimento_atendimento.procedimento_id',
|
||||
'cadastro_cidadao.cns as paciente_cns',
|
||||
'cadastro_cidadao.cpf as paciente_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',
|
||||
'cadastro_cidadao.data_nascimento as paciente_data_nascimento',
|
||||
'cadastro_cidadao.sexo_id as paciente_sexo_id',
|
||||
DB::raw('LPAD(cadastro_paciente.prontuario,7,0) AS paciente_prontuario'),
|
||||
'fp.data_usuario_responsavel as data_atendimento',
|
||||
'atencao_basica_procedimento_atendimento.paciente_id as paciente_id',
|
||||
'atencao_basica_procedimento_atendimento.local_atendimento_id as local_atendimento_id',
|
||||
'atencao_basica_procedimento_atendimento.turno_id as turno_id',
|
||||
'atencao_basica_procedimento_atendimento.escuta_inicial as escuta_inicial',
|
||||
'atencao_basica_procedimento_atendimento.peso',
|
||||
'atencao_basica_procedimento_atendimento.altura',
|
||||
'atencao_basica_procedimento_atendimento.temperatura',
|
||||
'atencao_basica_procedimento_atendimento.perimetro_cefalico',
|
||||
'atencao_basica_procedimento_atendimento.frequencia_respiratoria',
|
||||
'atencao_basica_procedimento_atendimento.frequencia_cardiaca',
|
||||
'atencao_basica_procedimento_atendimento.saturacao_o2',
|
||||
'atencao_basica_procedimento_atendimento.circunferencia_abdominal',
|
||||
'atencao_basica_procedimento_atendimento.perimetro_panturrilha',
|
||||
'atencao_basica_procedimento_atendimento.momento_coleta_id',
|
||||
'atencao_basica_procedimento_atendimento.afericao_pa',
|
||||
'atencao_basica_procedimento_atendimento.glicemia_capilar',
|
||||
)
|
||||
->join('cadastro_paciente', 'cadastro_paciente.id', 'atencao_basica_procedimento_atendimento.paciente_id')
|
||||
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_paciente.cidadao_id')
|
||||
->join('atencao_basica_procedimento as fp', 'fp.id', 'atencao_basica_procedimento_atendimento.procedimento_id')
|
||||
->whereIn('atencao_basica_procedimento_atendimento.procedimento_id', $fichaIds)
|
||||
->get();
|
||||
|
||||
$porFicha = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$porFicha[$row->procedimento_id][] = $row;
|
||||
}
|
||||
|
||||
return $porFicha;
|
||||
}
|
||||
|
||||
private static function countAtendimentosPorFicha(array $fichaIds): array
|
||||
{
|
||||
if (empty($fichaIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return DB::table('atencao_basica_procedimento_atendimento')
|
||||
->whereIn('procedimento_id', $fichaIds)
|
||||
->select('procedimento_id', DB::raw('COUNT(*) AS total'))
|
||||
->groupBy('procedimento_id')
|
||||
->pluck('total', 'procedimento_id')
|
||||
->all();
|
||||
}
|
||||
|
||||
private static function loadProcedimentos(array $atendimentoIds): array
|
||||
{
|
||||
if (empty($atendimentoIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rows = DB::table('atencao_basica_procedimento_atendimento_procedimento')
|
||||
->whereIn('procedimento_atendimento_id', $atendimentoIds)
|
||||
->select('procedimento_atendimento_id', 'procedimento_id')
|
||||
->get();
|
||||
|
||||
$procedimentoIds = $rows->pluck('procedimento_id')->unique()->filter()->values()->all();
|
||||
$codigoInvalido = self::loadCodigosInvalidos($procedimentoIds);
|
||||
|
||||
$countByKey = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$key = $row->procedimento_atendimento_id . ':' . $row->procedimento_id;
|
||||
$countByKey[$key] = ($countByKey[$key] ?? 0) + 1;
|
||||
}
|
||||
|
||||
$porAtendimento = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
|
||||
$key = $row->procedimento_atendimento_id . ':' . $row->procedimento_id;
|
||||
|
||||
$porAtendimento[$row->procedimento_atendimento_id][] = (object) [
|
||||
'procedimento_atendimento_id' => $row->procedimento_atendimento_id,
|
||||
'procedimento_id' => $row->procedimento_id,
|
||||
'is_duplicate' => $countByKey[$key] > 1,
|
||||
'is_invalid_for_ficha' => $codigoInvalido[$row->procedimento_id] ?? false,
|
||||
];
|
||||
}
|
||||
|
||||
return array_map(fn ($items) => collect($items), $porAtendimento);
|
||||
}
|
||||
|
||||
private static function loadCodigosInvalidos(array $procedimentoIds): array
|
||||
{
|
||||
if (empty($procedimentoIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rows = DB::table('sigtap.procedimento')
|
||||
->whereIn('id', $procedimentoIds)
|
||||
->select('id', 'codigo')
|
||||
->get();
|
||||
|
||||
$map = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$map[$row->id] = $row->codigo == Procedimento::ESCUTA_INICIAL_ORIENTACAO_ACOLHIMENTO_A_DEMANDA_ESPONT_NEA;
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
private static function countAuxiliares(array $atendimentoIds): array
|
||||
{
|
||||
if (empty($atendimentoIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$fontes = [
|
||||
'procedimentos' => 'atencao_basica_procedimento_atendimento_procedimento',
|
||||
'administracao' => 'atencao_basica_procedimento_via_administracao',
|
||||
'pequena_cirurgia' => 'atencao_basica_procedimento_atendimento_pequena_cirurgia',
|
||||
'teste_rapido' => 'atencao_basica_procedimento_atendimento_teste_rapido',
|
||||
];
|
||||
|
||||
$counts = [];
|
||||
|
||||
foreach ($atendimentoIds as $id) {
|
||||
$counts[$id] = [
|
||||
'procedimentos' => 0,
|
||||
'administracao' => 0,
|
||||
'pequena_cirurgia' => 0,
|
||||
'teste_rapido' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($fontes as $chave => $tabela) {
|
||||
|
||||
$rows = DB::table($tabela)
|
||||
->whereIn('procedimento_atendimento_id', $atendimentoIds)
|
||||
->select('procedimento_atendimento_id', DB::raw('COUNT(*) AS total'))
|
||||
->groupBy('procedimento_atendimento_id')
|
||||
->get();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$counts[$row->procedimento_atendimento_id][$chave] = (int) $row->total;
|
||||
}
|
||||
}
|
||||
|
||||
return $counts;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,460 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\AtencaoBasica\RelatorioInconsistencia;
|
||||
|
||||
use App\Enums\AtencaoBasica\Exportacao\Imunobiologico;
|
||||
use App\Enums\AtencaoBasica\Exportacao\Inconsistencia;
|
||||
use App\Enums\AtencaoBasica\Exportacao\VacinaAplicadaExterior;
|
||||
use App\Enums\AtencaoBasica\Parametrizacao\Permissao;
|
||||
use App\Rules\AtencaoBasica\Exportacao\AplicadoExteriorIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnesIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnsPaciente;
|
||||
use App\Rules\AtencaoBasica\Exportacao\ComunicanteHanseniaseIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataRegistroAnteriorIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataRegistroAnteriorIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DoseIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\EstrategiaIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\EstrategiaIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\EstrategiaIsValidForFicha;
|
||||
use App\Rules\AtencaoBasica\Exportacao\FabricanteIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\FabricanteIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\GestanteIsValidForFicha;
|
||||
use App\Rules\AtencaoBasica\Exportacao\GrupoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\GrupoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\IbgeIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\LocalAtendimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\LocalAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\LoteIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\OcupacaoIsAllowed;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PuerperaAndGestanteIsChecked;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PuerperaIsValidForFicha;
|
||||
use App\Rules\AtencaoBasica\Exportacao\VacinaIsDuplicate;
|
||||
use App\Rules\AtencaoBasica\Exportacao\VacinaIsValid;
|
||||
use App\Rules\Cns;
|
||||
use App\Rules\Cpf;
|
||||
use App\Services\Service;
|
||||
use App\Utils\MaskUtil;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class FichaVacinacaoService extends Service
|
||||
{
|
||||
private const FICHA_LABEL = 'Ficha de vacinação';
|
||||
|
||||
private const HEADER_ERROR_MAP = [
|
||||
CnesIsValid::class => 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 PACIENTE_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,
|
||||
GestanteIsValidForFicha::class => Inconsistencia::GESTANTE_PREENCHIDO_PARA_PACIENTES_DO_SEXO_MASCULINO,
|
||||
PuerperaIsValidForFicha::class => Inconsistencia::PUERPERA_PREENCHIDO_PARA_PACIENTES_DO_SEXO_MASCULINO,
|
||||
PuerperaAndGestanteIsChecked::class => Inconsistencia::GESTANTE_E_PUERPERA_AMBOS_PREENCHIDOS,
|
||||
ComunicanteHanseniaseIsRequired::class => Inconsistencia::COMUNICANTE_HANSENIASE_SEM_PREENCHIMENTO,
|
||||
];
|
||||
|
||||
private const VACINA_ERROR_MAP = [
|
||||
EstrategiaIsValid::class => Inconsistencia::ESTRATEGIA_INVALIDA,
|
||||
EstrategiaIsRequired::class => Inconsistencia::ESTRATEGIA_SEM_PREENCHIMENTO,
|
||||
DoseIsValid::class => Inconsistencia::DOSE_INVALIDA,
|
||||
LoteIsRequired::class => Inconsistencia::LOTE_EM_PREENCHIMENTO,
|
||||
DataRegistroAnteriorIsRequired::class => Inconsistencia::DATA_REGISTRO_ANTERIOR_SEM_PREENCHIMENTO,
|
||||
FabricanteIsRequired::class => Inconsistencia::FABRICANTE_SEM_PREENCHIMENTO,
|
||||
AplicadoExteriorIsRequired::class => Inconsistencia::APLICADO_EXTERIOR_SEM_PREENCHIMENTO,
|
||||
GrupoIsRequired::class => Inconsistencia::GRUPO_SEM_PREENCHIMENTO,
|
||||
GrupoIsValid::class => Inconsistencia::GRUPO_INVALIDO,
|
||||
VacinaIsDuplicate::class => Inconsistencia::VACINA_DUPLICADA,
|
||||
VacinaIsValid::class => Inconsistencia::VACINA_INVALIDA,
|
||||
];
|
||||
|
||||
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');
|
||||
|
||||
$fichasVacinacao = DB::table('atencao_basica_ficha_vacinacao')
|
||||
->select([
|
||||
'atencao_basica_ficha_vacinacao.id as id',
|
||||
'atencao_basica_ficha_vacinacao.usuario_id as usuario_id',
|
||||
'atencao_basica_ficha_vacinacao.data_atendimento as data_atendimento',
|
||||
'cadastro_unidade.cnes as unidade_cnes',
|
||||
'cadastro_municipio.ibge as municipio_ibge',
|
||||
'cadastro_cidadao.cns AS usuario_cns',
|
||||
'cadastro_cidadao.nome AS profissional_nome',
|
||||
'sigtap.ocupacao.codigo as ocupacao_codigo',
|
||||
])
|
||||
->join('atencao_basica_parametrizacao_equipe', 'atencao_basica_parametrizacao_equipe.id', 'atencao_basica_ficha_vacinacao.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_ficha_vacinacao.usuario_id')
|
||||
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id')
|
||||
->join('sigtap.ocupacao', 'sigtap.ocupacao.id', 'atencao_basica_ficha_vacinacao.ocupacao_id')
|
||||
->whereBetween('atencao_basica_ficha_vacinacao.data_atendimento', [$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_ficha_vacinacao.usuario_id', request()->usuario_id))
|
||||
->get();
|
||||
|
||||
if ($fichasVacinacao->isEmpty()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$vacinacoesPorFicha = self::loadVacinacoes($fichasVacinacao->pluck('id')->all());
|
||||
|
||||
$todosVacinacaoIds = [];
|
||||
|
||||
foreach ($vacinacoesPorFicha as $vacinacoes) {
|
||||
|
||||
foreach ($vacinacoes as $vacinacao) {
|
||||
$todosVacinacaoIds[] = $vacinacao->id;
|
||||
}
|
||||
}
|
||||
|
||||
$itensPorVacinacao = self::loadVacinacaoItens($todosVacinacaoIds);
|
||||
|
||||
$groupedList = [];
|
||||
|
||||
foreach ($fichasVacinacao as $ficha) {
|
||||
|
||||
$errosHeader = RelatorioInconsistenciaService::validHeader($ficha, Permissao::FICHA_DE_VACINACAO);
|
||||
$headerDescriptions = self::mapErrors($errosHeader, self::HEADER_ERROR_MAP, $inconsistencias);
|
||||
|
||||
foreach ($vacinacoesPorFicha[$ficha->id] ?? [] as $vacinacao) {
|
||||
|
||||
$errosVacinacao = self::validVacinacao($vacinacao, $ficha->data_atendimento);
|
||||
$pacienteDescriptions = self::mapErrors($errosVacinacao, self::PACIENTE_ERROR_MAP, $inconsistencias);
|
||||
|
||||
$vacinaDescriptions = collect();
|
||||
|
||||
foreach ($itensPorVacinacao[$vacinacao->id] ?? [] as $item) {
|
||||
|
||||
$errosVacina = self::validVacina($item, $vacinacao->paciente_data_nascimento, $vacinacao->hanseniase);
|
||||
$vacinaDescriptions = $vacinaDescriptions->merge(
|
||||
self::mapVacinaErrors($errosVacina, $item, $inconsistencias)
|
||||
);
|
||||
}
|
||||
|
||||
$errorDescriptions = collect($headerDescriptions->all())
|
||||
->merge($pacienteDescriptions)
|
||||
->merge($vacinaDescriptions);
|
||||
|
||||
if ($errorDescriptions->isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$key = $ficha->data_atendimento . '|' . $vacinacao->paciente_id . '|' . $ficha->usuario_id;
|
||||
|
||||
if (!isset($groupedList[$key])) {
|
||||
|
||||
$groupedList[$key] = [
|
||||
'data' => (new Carbon($ficha->data_atendimento))->format('d/m/Y'),
|
||||
'ficha' => self::FICHA_LABEL,
|
||||
'paciente_nome' => $vacinacao->paciente_nome,
|
||||
'paciente_cns' => $vacinacao->paciente_cns ? MaskUtil::getCnsMasked($vacinacao->paciente_cns) : '-',
|
||||
'paciente_cpf' => $vacinacao->paciente_cpf ? MaskUtil::getCpfMasked($vacinacao->paciente_cpf) : '-',
|
||||
'paciente_nome_social' => $vacinacao->paciente_nome_social,
|
||||
'paciente_preferencia_nome_id' => $vacinacao->paciente_preferencia_nome_id,
|
||||
'paciente_prontuario' => $vacinacao->paciente_prontuario,
|
||||
'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('<br />');
|
||||
$group['total_erros'] = $unique->count();
|
||||
$result[] = $group;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private static function mapErrors(Collection $errors, array $map, Collection $inconsistencias): Collection
|
||||
{
|
||||
$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 mapVacinaErrors(Collection $errors, $item, Collection $inconsistencias): Collection
|
||||
{
|
||||
$descriptions = collect();
|
||||
|
||||
foreach ($errors as $error) {
|
||||
|
||||
if ($error === EstrategiaIsValidForFicha::class) {
|
||||
|
||||
$descricao = $inconsistencias[Inconsistencia::ESTRATEGIA_INCORRETA] ?? null;
|
||||
|
||||
if ($descricao !== null) {
|
||||
$descriptions->push($descricao . ' - ' . $item->vacina_descricao);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($error === FabricanteIsValid::class) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$inconsistenciaId = self::VACINA_ERROR_MAP[$error] ?? null;
|
||||
|
||||
if ($inconsistenciaId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$descricao = $inconsistencias[$inconsistenciaId] ?? null;
|
||||
|
||||
if ($descricao !== null) {
|
||||
$descriptions->push($descricao);
|
||||
}
|
||||
}
|
||||
|
||||
return $descriptions;
|
||||
}
|
||||
|
||||
private static function handleVacinaAplicadaExterior($item): bool
|
||||
{
|
||||
return $item->registro_anterior && in_array($item->vacina_codigo, VacinaAplicadaExterior::getConstants());
|
||||
}
|
||||
|
||||
private static function validVacinacao($vacinacao, $data_atendimento): Collection
|
||||
{
|
||||
$errors = collect();
|
||||
|
||||
if (!Cns::isValid($vacinacao->paciente_cns) && !Cpf::isValid($vacinacao->paciente_cpf)) {
|
||||
$errors->push(CnsPaciente::class);
|
||||
$errors->push(Cpf::class);
|
||||
}
|
||||
|
||||
if (!DataNascimentoIsRequired::isValid($vacinacao->paciente_data_nascimento)) {
|
||||
$errors->push(DataNascimentoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!DataNascimentoIsValid::isValid([
|
||||
'data_nascimento' => $vacinacao->paciente_data_nascimento,
|
||||
'data_atendimento' => $data_atendimento
|
||||
])) {
|
||||
$errors->push(DataNascimentoIsValid::class);
|
||||
}
|
||||
|
||||
if (!LocalAtendimentoIsRequired::isValid($vacinacao->local_atendimento_id)) {
|
||||
$errors->push(LocalAtendimentoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!LocalAtendimentoIsValid::isValid($vacinacao->local_atendimento_id)) {
|
||||
$errors->push(LocalAtendimentoIsValid::class);
|
||||
}
|
||||
|
||||
if (!GestanteIsValidForFicha::isValid($vacinacao)) {
|
||||
$errors->push(GestanteIsValidForFicha::class);
|
||||
}
|
||||
|
||||
if (!PuerperaIsValidForFicha::isValid($vacinacao)) {
|
||||
$errors->push(PuerperaIsValidForFicha::class);
|
||||
}
|
||||
|
||||
if (PuerperaAndGestanteIsChecked::isValid($vacinacao)) {
|
||||
$errors->push(PuerperaAndGestanteIsChecked::class);
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
private static function validVacina($item, $pacienteDataNascimento, $hanseniase): Collection
|
||||
{
|
||||
$errors = collect();
|
||||
|
||||
if (!$item->registro_anterior && !EstrategiaIsValid::isValid($item->estrategia_codigo)) {
|
||||
$errors->push(EstrategiaIsValid::class);
|
||||
}
|
||||
|
||||
if ($item->registro_anterior) {
|
||||
|
||||
if (!EstrategiaIsValidForFicha::isValid($item)) {
|
||||
$errors->push(EstrategiaIsValidForFicha::class);
|
||||
}
|
||||
}
|
||||
|
||||
if (!DoseIsValid::isValid($item->dose_id)) {
|
||||
$errors->push(DoseIsValid::class);
|
||||
}
|
||||
|
||||
if (!$item->registro_anterior && !LoteIsRequired::isValid($item->entrada_lote)) {
|
||||
$errors->push(LoteIsRequired::class);
|
||||
}
|
||||
|
||||
if ($item->registro_anterior && !DataRegistroAnteriorIsRequired::isValid($item->data)) {
|
||||
$errors->push(DataRegistroAnteriorIsRequired::class);
|
||||
}
|
||||
|
||||
if (!$item->registro_anterior && !FabricanteIsRequired::isValid($item->produtor_id)) {
|
||||
$errors->push(FabricanteIsRequired::class);
|
||||
}
|
||||
|
||||
if (!DataRegistroAnteriorIsValid::isValid([
|
||||
'registro_anterior' => $item->registro_anterior,
|
||||
'data' => $item->data,
|
||||
'data_nascimento' => $pacienteDataNascimento
|
||||
])) {
|
||||
$errors->push(DataRegistroAnteriorIsValid::class);
|
||||
}
|
||||
|
||||
if ($item->produtor_nome && $item->vacina_codigo && !FabricanteIsValid::isValid(['fabricante' => $item->produtor_nome, 'vacina' => $item->vacina_codigo])) {
|
||||
$errors->push(FabricanteIsValid::class);
|
||||
}
|
||||
|
||||
if (self::handleVacinaAplicadaExterior($item) && !AplicadoExteriorIsRequired::isValid($item->aplicado_exterior)) {
|
||||
$errors->push(AplicadoExteriorIsRequired::class);
|
||||
}
|
||||
|
||||
if (!$item->registro_anterior && !GrupoIsRequired::isValid($item->grupo_id)) {
|
||||
$errors->push(GrupoIsRequired::class);
|
||||
}
|
||||
|
||||
if ($item->registro_anterior && !GrupoIsValid::isValid($item->grupo_id)) {
|
||||
$errors->push(GrupoIsValid::class);
|
||||
}
|
||||
|
||||
if (VacinaIsDuplicate::isValid($item)) {
|
||||
$errors->push(VacinaIsDuplicate::class);
|
||||
}
|
||||
|
||||
if (!$item->registro_anterior && !VacinaIsValid::isValid($item)) {
|
||||
$errors->push(VacinaIsValid::class);
|
||||
}
|
||||
|
||||
if ($item->vacina_codigo == Imunobiologico::BCG
|
||||
&& !ComunicanteHanseniaseIsRequired::isValid($hanseniase)) {
|
||||
|
||||
$errors->push(ComunicanteHanseniaseIsRequired::class);
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
private static function loadVacinacoes(array $fichaIds): array
|
||||
{
|
||||
if (empty($fichaIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rows = DB::table('atencao_basica_vacinacao_paciente as vacinacao')
|
||||
->select(
|
||||
'vacinacao.id as id',
|
||||
'vacinacao.vacinacao_id',
|
||||
'cadastro_cidadao.cns as paciente_cns',
|
||||
'cadastro_cidadao.cpf as paciente_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',
|
||||
'cadastro_cidadao.data_nascimento as paciente_data_nascimento',
|
||||
'cadastro_cidadao.sexo_id as paciente_sexo_id',
|
||||
DB::raw('LPAD(cadastro_paciente.prontuario,7,0) AS paciente_prontuario'),
|
||||
'vacinacao.paciente_id as paciente_id',
|
||||
'vacinacao.local_atendimento_id as local_atendimento_id',
|
||||
'vacinacao.gestante as gestante',
|
||||
'vacinacao.puerpera as puerpera',
|
||||
'vacinacao.hanseniase as hanseniase',
|
||||
)
|
||||
->join('cadastro_paciente', 'cadastro_paciente.id', 'vacinacao.paciente_id')
|
||||
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_paciente.cidadao_id')
|
||||
->whereIn('vacinacao.vacinacao_id', $fichaIds)
|
||||
->get();
|
||||
|
||||
$porFicha = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$porFicha[$row->vacinacao_id][] = $row;
|
||||
}
|
||||
|
||||
return $porFicha;
|
||||
}
|
||||
|
||||
private static function loadVacinacaoItens(array $vacinacaoIds): array
|
||||
{
|
||||
if (empty($vacinacaoIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rows = DB::table('atencao_basica_vacinacao_paciente_item as item')
|
||||
->select(
|
||||
'item.estrategia_id as estrategia_id',
|
||||
'imunizacao_estrategia.codigo_rnds as estrategia_codigo',
|
||||
'item.vacina_id as vacina_id',
|
||||
'cadastro_vacina.nome as vacina_descricao',
|
||||
'item.dose_id as dose_id',
|
||||
'imunizacao_dose.codigo_esus as dose_codigo',
|
||||
'item.registro_anterior as registro_anterior',
|
||||
'item.produtor_id as produtor_id',
|
||||
'item.grupo_id as grupo_id',
|
||||
'item.aplicado_exterior as aplicado_exterior',
|
||||
'item.data as data',
|
||||
'item.vacinacao_paciente_id as vacinacao_paciente_id',
|
||||
'cadastro_vacina.codigo as vacina_codigo',
|
||||
'imunizacao_produtor.nome as produtor_nome',
|
||||
'imunizacao_entrada_vacina.lote as entrada_lote',
|
||||
)
|
||||
->join('cadastro_vacina', 'cadastro_vacina.id', 'item.vacina_id')
|
||||
->leftJoin('imunizacao_produtor', 'imunizacao_produtor.id', 'item.produtor_id')
|
||||
->leftJoin('imunizacao_entrada_vacina', 'imunizacao_entrada_vacina.id', 'item.entrada_id')
|
||||
->leftJoin('imunizacao_estrategia', 'imunizacao_estrategia.id', 'item.estrategia_id')
|
||||
->leftJoin('imunizacao_dose', 'imunizacao_dose.id', 'item.dose_id')
|
||||
->whereIn('item.vacinacao_paciente_id', $vacinacaoIds)
|
||||
->get();
|
||||
|
||||
$porVacinacao = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$porVacinacao[$row->vacinacao_paciente_id][] = $row;
|
||||
}
|
||||
|
||||
return $porVacinacao;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,274 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\AtencaoBasica\RelatorioInconsistencia;
|
||||
|
||||
use App\Enums\AtencaoBasica\CadastroDomiciliar\ImovelTipo;
|
||||
use App\Enums\AtencaoBasica\Exportacao\Inconsistencia;
|
||||
use App\Enums\AtencaoBasica\Parametrizacao\Permissao;
|
||||
use App\Rules\AtencaoBasica\Exportacao\AlturaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnesIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnsPaciente;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataAtendimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DataNascimentoIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\DesfechoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\GlicemiaIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\GlicemiaLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\IbgeIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\LatitudeIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\LongitudeIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\MomentoColetaGlicemiaIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\MotivoVisitaIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\OcupacaoIsAllowed;
|
||||
use App\Rules\AtencaoBasica\Exportacao\PesoLimitIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\SexoIsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TipoImovelsRequired;
|
||||
use App\Rules\AtencaoBasica\Exportacao\TurnoIsRequired;
|
||||
use App\Rules\Cns;
|
||||
use App\Rules\Cpf;
|
||||
use App\Services\Service;
|
||||
use App\Utils\MaskUtil;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class FichaVisitaDomiciliarService extends Service
|
||||
{
|
||||
private const ERROR_MAP = [
|
||||
CnesIsValid::class => 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,
|
||||
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,
|
||||
MotivoVisitaIsValid::class => Inconsistencia::MOTIVO_INVALIDO,
|
||||
TipoImovelsRequired::class => Inconsistencia::TIPO_IMOVEL_SEM_PREENCHIMENTO,
|
||||
DesfechoIsRequired::class => Inconsistencia::DESFECHO_SEM_PREENCHIMENTO,
|
||||
LatitudeIsRequired::class => Inconsistencia::LATITUDE_SEM_PREENCHIMENTO,
|
||||
LongitudeIsRequired::class => Inconsistencia::LONGITUDE_SEM_PREENCHIMENTO,
|
||||
TurnoIsRequired::class => Inconsistencia::TURNO_SEM_PREENCHIMENTO,
|
||||
SexoIsRequired::class => Inconsistencia::SEXO_DO_PACIENTE_SEM_PREENCHIMENTO,
|
||||
GlicemiaLimitIsValid::class => Inconsistencia::GLICEMIA_DO_PACIENTE_MENOR_QUE_0_OU_MAIOR_QUE_800_KG,
|
||||
GlicemiaIsRequired::class => Inconsistencia::GLICEMIA_SEM_PREENCHIMENTO,
|
||||
MomentoColetaGlicemiaIsRequired::class => Inconsistencia::MOMENTO_COLETA_GLICEMIA_SEM_PREENCHIMENTO,
|
||||
PesoLimitIsValid::class => Inconsistencia::PESO_DO_PACIENTE_MENOR_QUE_0_5_OU_MAIOR_QUE_500_KG,
|
||||
AlturaLimitIsValid::class => Inconsistencia::ALTURA_DO_PACIENTE_MENOR_QUE_20_OU_MAIOR_QUE_250_CM,
|
||||
];
|
||||
|
||||
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');
|
||||
|
||||
$fichasVisitaDomiciliar = DB::table('atencao_basica_visita_domiciliar')
|
||||
->select([
|
||||
'atencao_basica_visita_domiciliar.id as id',
|
||||
'atencao_basica_visita_domiciliar.usuario_id as usuario_id',
|
||||
'atencao_basica_visita_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',
|
||||
'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',
|
||||
'paciente_cidadao.sexo_id as paciente_sexo_id',
|
||||
DB::raw('LPAD(cadastro_paciente.prontuario,7,0) AS paciente_prontuario'),
|
||||
'atencao_basica_visita_domiciliar.turno_id',
|
||||
'atencao_basica_visita_domiciliar.peso',
|
||||
'atencao_basica_visita_domiciliar.altura',
|
||||
'atencao_basica_visita_domiciliar.paciente_id',
|
||||
'atencao_basica_visita_domiciliar.imovel_tipo_id',
|
||||
'atencao_basica_visita_domiciliar.latitude',
|
||||
'atencao_basica_visita_domiciliar.longitude',
|
||||
'atencao_basica_visita_domiciliar.visita_compartilhada',
|
||||
'atencao_basica_visita_domiciliar.temperatura',
|
||||
'atencao_basica_visita_domiciliar.afericao_pa',
|
||||
'atencao_basica_visita_domiciliar.glicemia',
|
||||
'atencao_basica_visita_domiciliar.momento_coleta_id',
|
||||
'atencao_basica_visita_domiciliar.desfecho_id',
|
||||
'atencao_basica_cadastro_imovel_tipo.codigo_esus as imovel_tipo_codigo_esus',
|
||||
])
|
||||
->join('atencao_basica_parametrizacao_equipe', 'atencao_basica_parametrizacao_equipe.id', 'atencao_basica_visita_domiciliar.equipe_id')
|
||||
->join('atencao_basica_cadastro_imovel_tipo', 'atencao_basica_cadastro_imovel_tipo.id', 'atencao_basica_visita_domiciliar.imovel_tipo_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_visita_domiciliar.usuario_id')
|
||||
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id')
|
||||
->join('sigtap.ocupacao', 'sigtap.ocupacao.id', 'atencao_basica_visita_domiciliar.usuario_ocupacao_id')
|
||||
->join('cadastro_paciente', 'cadastro_paciente.id', 'atencao_basica_visita_domiciliar.paciente_id')
|
||||
->join('cadastro_cidadao as paciente_cidadao', 'paciente_cidadao.id', 'cadastro_paciente.cidadao_id')
|
||||
->whereBetween('atencao_basica_visita_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_visita_domiciliar.usuario_id', request()->usuario_id))
|
||||
->get();
|
||||
|
||||
$groupedList = [];
|
||||
|
||||
foreach ($fichasVisitaDomiciliar as $ficha) {
|
||||
|
||||
$errors = RelatorioInconsistenciaService::validHeader($ficha, Permissao::VISITA_DOMICILIAR)
|
||||
->merge(self::validAtendimento($ficha));
|
||||
|
||||
$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' => 'Visita Domiciliar',
|
||||
'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,
|
||||
'paciente_cns' => $ficha->paciente_cns ? MaskUtil::getCnsMasked($ficha->paciente_cns) : '-',
|
||||
'paciente_cpf' => $ficha->paciente_cpf ? MaskUtil::getCpfMasked($ficha->paciente_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('<br />');
|
||||
$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($ficha): Collection
|
||||
{
|
||||
$errors = collect();
|
||||
|
||||
if (!Cns::isValid($ficha->paciente_cns) && !Cpf::isValid($ficha->paciente_cpf)) {
|
||||
$errors->push(CnsPaciente::class);
|
||||
$errors->push(Cpf::class);
|
||||
}
|
||||
|
||||
if (self::getTipoImovelValido($ficha->imovel_tipo_codigo_esus) && !DataNascimentoIsRequired::isValid($ficha->paciente_data_nascimento)) {
|
||||
$errors->push(DataNascimentoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!DataNascimentoIsValid::isValid([
|
||||
'data_nascimento' => $ficha->paciente_data_nascimento,
|
||||
'data_atendimento' => $ficha->data_atendimento
|
||||
])) {
|
||||
$errors->push(DataNascimentoIsValid::class);
|
||||
}
|
||||
|
||||
if (!MotivoVisitaIsValid::isValid($ficha)) {
|
||||
$errors->push(MotivoVisitaIsValid::class);
|
||||
}
|
||||
|
||||
if (!TurnoIsRequired::isValid($ficha->turno_id)) {
|
||||
$errors->push(TurnoIsRequired::class);
|
||||
}
|
||||
|
||||
if ($ficha->longitude && !LatitudeIsRequired::isValid($ficha->latitude)) {
|
||||
$errors->push(LatitudeIsRequired::class);
|
||||
}
|
||||
|
||||
if ($ficha->latitude && !LongitudeIsRequired::isValid($ficha->longitude)) {
|
||||
$errors->push(LongitudeIsRequired::class);
|
||||
}
|
||||
|
||||
if (!DesfechoIsRequired::isValid($ficha->desfecho_id)) {
|
||||
$errors->push(DesfechoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!TipoImovelsRequired::isValid($ficha->imovel_tipo_id)) {
|
||||
$errors->push(TipoImovelsRequired::class);
|
||||
}
|
||||
|
||||
if (!SexoIsRequired::isValid($ficha->paciente_sexo_id)) {
|
||||
$errors->push(SexoIsRequired::class);
|
||||
}
|
||||
|
||||
if (!GlicemiaLimitIsValid::isValid($ficha->glicemia)) {
|
||||
$errors->push(GlicemiaLimitIsValid::class);
|
||||
}
|
||||
|
||||
if ($ficha->momento_coleta_id && !GlicemiaIsRequired::isValid($ficha->glicemia)) {
|
||||
$errors->push(GlicemiaIsRequired::class);
|
||||
}
|
||||
|
||||
if ($ficha->glicemia && !MomentoColetaGlicemiaIsRequired::isValid($ficha->momento_coleta_id)) {
|
||||
$errors->push(MomentoColetaGlicemiaIsRequired::class);
|
||||
}
|
||||
|
||||
if (!PesoLimitIsValid::isValid($ficha->peso)) {
|
||||
$errors->push(PesoLimitIsValid::class);
|
||||
}
|
||||
|
||||
if (!AlturaLimitIsValid::isValid($ficha->altura)) {
|
||||
$errors->push(AlturaLimitIsValid::class);
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
private static function getTipoImovelValido($tipoImovelId): bool
|
||||
{
|
||||
return $tipoImovelId == ImovelTipo::DOMICILIO
|
||||
|| $tipoImovelId == ImovelTipo::ABRIGO
|
||||
|| $tipoImovelId == ImovelTipo::INSTITUICAO_LONGA_PERMANENCIA_IDOSOS
|
||||
|| $tipoImovelId == ImovelTipo::UNIDADE_PRISIONAL
|
||||
|| $tipoImovelId == ImovelTipo::UNIDADE_MEDIDA_SOCIO_EDUCATIVA
|
||||
|| $tipoImovelId == ImovelTipo::DELEGACIA
|
||||
|| $tipoImovelId == ImovelTipo::OUTROS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,375 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\AtencaoBasica\RelatorioInconsistencia;
|
||||
|
||||
use App\Enums\AtencaoBasica\Parametrizacao\Permissao;
|
||||
use App\Models\AtencaoBasica\Parametrizacao\Equipe;
|
||||
use App\Models\AtencaoBasica\Parametrizacao\OutrosPermissao;
|
||||
use App\Models\Cadastro\Estabelecimento\Infraestrutura;
|
||||
use App\Models\Cadastro\Estabelecimento\Unidade;
|
||||
use App\Models\Cadastro\SujeitoAtencao\Usuario;
|
||||
use App\Rules\AtencaoBasica\Exportacao\CnesIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\IbgeIsValid;
|
||||
use App\Rules\AtencaoBasica\Exportacao\OcupacaoIsAllowed;
|
||||
use App\Rules\Cns;
|
||||
use App\Services\Service;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class RelatorioInconsistenciaService extends Service
|
||||
{
|
||||
private const ACTIVITY_TABLES = [
|
||||
['atencao_basica_avaliacao', 'data'],
|
||||
['atencao_basica_cadastro_domiciliar', 'data_usuario_responsavel'],
|
||||
['atencao_basica_cadastro_individual', 'data_usuario_responsavel'],
|
||||
['atencao_basica_ficha_complementar', 'data_atendimento'],
|
||||
['atencao_basica_consumo_alimentar', 'data_atendimento'],
|
||||
['atencao_basica_procedimento', 'data_usuario_responsavel'],
|
||||
['atencao_basica_visita_domiciliar', 'data_usuario_responsavel'],
|
||||
['atencao_basica_atendimento_domiciliar', 'data'],
|
||||
['atencao_basica_atendimento_individual', 'data_usuario_responsavel'],
|
||||
['atencao_basica_atendimento_odontologico', 'data_atendimento'],
|
||||
['atencao_basica_atividade_coletiva', 'data_usuario_responsavel'],
|
||||
];
|
||||
|
||||
public static function index()
|
||||
{
|
||||
return [
|
||||
'form' => self::getFormData(),
|
||||
'model' => self::getModelData(),
|
||||
];
|
||||
}
|
||||
|
||||
private static function getFormData()
|
||||
{
|
||||
return [
|
||||
'fichas' => self::getFichas(),
|
||||
'data_atual' => Carbon::now()->format('Y-m-d'),
|
||||
'mesesAno' => self::getPeriodo(),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getFichas()
|
||||
{
|
||||
return DB::table('atencao_basica_parametrizacao_outros_permissao')
|
||||
->select([
|
||||
'id',
|
||||
'descricao'
|
||||
])
|
||||
->orderBy('atencao_basica_parametrizacao_outros_permissao.descricao')
|
||||
->get();
|
||||
}
|
||||
|
||||
private static function getDateRange(string $mes_ano): array
|
||||
{
|
||||
$date = Carbon::createFromFormat('mY', $mes_ano);
|
||||
|
||||
return [
|
||||
$date->copy()->startOfMonth()->toDateString(),
|
||||
$date->copy()->endOfMonth()->toDateString(),
|
||||
];
|
||||
}
|
||||
|
||||
private static function getActiveEquipeIds(string $start, string $end): array
|
||||
{
|
||||
$equipeIds = [];
|
||||
|
||||
foreach (self::ACTIVITY_TABLES as [$table, $dateCol]) {
|
||||
|
||||
$ids = DB::table($table)
|
||||
->whereBetween($dateCol, [$start, $end])
|
||||
->distinct()
|
||||
->pluck('equipe_id')
|
||||
->all();
|
||||
|
||||
foreach ($ids as $id) {
|
||||
|
||||
if ($id !== null) {
|
||||
$equipeIds[$id] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_keys($equipeIds);
|
||||
}
|
||||
|
||||
public static function getUnidades()
|
||||
{
|
||||
[$start, $end] = self::getDateRange(request()->mes_ano);
|
||||
|
||||
$equipeIds = self::getActiveEquipeIds($start, $end);
|
||||
|
||||
if (empty($equipeIds)) {
|
||||
return collect();
|
||||
}
|
||||
|
||||
return DB::table('cadastro_unidade')
|
||||
->select(['id', 'nome_fantasia'])
|
||||
->whereIn('id', function ($q) use ($equipeIds) {
|
||||
$q->select('unidade_id')
|
||||
->from('atencao_basica_parametrizacao_equipe')
|
||||
->whereIn('id', $equipeIds)
|
||||
->whereNotNull('unidade_id');
|
||||
})
|
||||
->orderBy('nome_fantasia')
|
||||
->get();
|
||||
}
|
||||
|
||||
public static function getInfraestruturas()
|
||||
{
|
||||
[$start, $end] = self::getDateRange(request()->mes_ano);
|
||||
|
||||
$equipeIds = self::getActiveEquipeIds($start, $end);
|
||||
|
||||
if (empty($equipeIds)) {
|
||||
|
||||
return [
|
||||
'infraestruturas' => collect(),
|
||||
'usuarios' => self::getUsuarios(),
|
||||
];
|
||||
}
|
||||
|
||||
$infraestruturaIds = DB::table('atencao_basica_parametrizacao_equipe')
|
||||
->whereIn('id', $equipeIds)
|
||||
->whereNotNull('infraestrutura_id')
|
||||
->when(request()->unidade_id, fn ($q) => $q->where('unidade_id', request()->unidade_id))
|
||||
->distinct()
|
||||
->pluck('infraestrutura_id')
|
||||
->all();
|
||||
|
||||
$infraestruturas = DB::table('cadastro_infraestrutura')
|
||||
->select([
|
||||
'cadastro_infraestrutura.id',
|
||||
DB::raw('COALESCE(cadastro_infraestrutura.nome, cadastro_unidade.nome_fantasia) AS nome'),
|
||||
])
|
||||
->join('cadastro_unidade', 'cadastro_unidade.id', 'cadastro_infraestrutura.unidade_id')
|
||||
->whereIn('cadastro_infraestrutura.id', $infraestruturaIds)
|
||||
->when(request()->unidade_id, fn ($q) => $q->where('cadastro_infraestrutura.unidade_id', request()->unidade_id))
|
||||
->orderBy('nome')
|
||||
->get();
|
||||
|
||||
return [
|
||||
'infraestruturas' => $infraestruturas,
|
||||
'usuarios' => self::getUsuarios(),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getUsuarios()
|
||||
{
|
||||
[$start, $end] = self::getDateRange(request()->mes_ano);
|
||||
|
||||
$equipeIds = null;
|
||||
|
||||
if (request()->unidade_id || request()->infraestrutura_id) {
|
||||
|
||||
$equipeIds = DB::table('atencao_basica_parametrizacao_equipe')
|
||||
->when(request()->unidade_id, fn ($q) => $q->where('unidade_id', request()->unidade_id))
|
||||
->when(request()->infraestrutura_id, fn ($q) => $q->where('infraestrutura_id', request()->infraestrutura_id))
|
||||
->pluck('id')
|
||||
->all();
|
||||
|
||||
if (empty($equipeIds)) {
|
||||
return collect();
|
||||
}
|
||||
}
|
||||
|
||||
$usuarioIds = [];
|
||||
|
||||
foreach (self::ACTIVITY_TABLES as [$table, $dateCol]) {
|
||||
|
||||
$ids = DB::table($table)
|
||||
->whereBetween($dateCol, [$start, $end])
|
||||
->when($equipeIds, fn ($q) => $q->whereIn('equipe_id', $equipeIds))
|
||||
->distinct()
|
||||
->pluck('usuario_id')
|
||||
->all();
|
||||
|
||||
foreach ($ids as $id) {
|
||||
|
||||
if ($id !== null) {
|
||||
$usuarioIds[$id] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($usuarioIds)) {
|
||||
return collect();
|
||||
}
|
||||
|
||||
return DB::table('cadastro_usuario')
|
||||
->select('cadastro_usuario.id', 'cadastro_cidadao.nome')
|
||||
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id')
|
||||
->whereIn('cadastro_usuario.id', array_keys($usuarioIds))
|
||||
->orderBy('cadastro_cidadao.nome')
|
||||
->get();
|
||||
}
|
||||
|
||||
public static function getPeriodo()
|
||||
{
|
||||
$dataAtual = Carbon::now();
|
||||
$dataInicial = $dataAtual->copy()->subYear();
|
||||
$mesesAnos = [];
|
||||
|
||||
while ($dataAtual >= $dataInicial) {
|
||||
|
||||
$mesesAnos[] = [
|
||||
'value' => $dataAtual->format('mY'),
|
||||
'text' => ucfirst($dataAtual->translatedFormat('F/Y')),
|
||||
];
|
||||
|
||||
$dataAtual->subMonth();
|
||||
}
|
||||
|
||||
return $mesesAnos;
|
||||
}
|
||||
|
||||
private static function getModelData()
|
||||
{
|
||||
return [
|
||||
'periodo' => [
|
||||
'start' => null,
|
||||
'end' => null,
|
||||
],
|
||||
'unidade_id' => null,
|
||||
'infraestrutura_id' => null,
|
||||
'usuario_id' => null,
|
||||
'ficha_id' => null,
|
||||
'mesAno' => null,
|
||||
];
|
||||
}
|
||||
|
||||
public static function list()
|
||||
{
|
||||
$errors = collect();
|
||||
|
||||
if (!request()->ficha_id || request()->ficha_id == Permissao::MARCADORES_DE_CONSUMO_ALIMENTAR) {
|
||||
|
||||
$errors = $errors->merge(FichaConsumoAlimentarService::index());
|
||||
}
|
||||
|
||||
if (!request()->ficha_id || request()->ficha_id == Permissao::PROCEDIMENTOS) {
|
||||
|
||||
$errors = $errors->merge(FichaProcedimentoService::index());
|
||||
}
|
||||
|
||||
if (!request()->ficha_id || request()->ficha_id == Permissao::ATENDIMENTO_INDIVIDUAL) {
|
||||
|
||||
$errors = $errors->merge(FichaAtendimentoIndividualService::index());
|
||||
}
|
||||
|
||||
if (!request()->ficha_id || request()->ficha_id == Permissao::ATENDIMENTO_ODONTOLOGICO) {
|
||||
|
||||
$errors = $errors->merge(FichaAtendimentoOdontologicoService::index());
|
||||
}
|
||||
|
||||
if (!request()->ficha_id || request()->ficha_id == Permissao::ATENDIMENTO_DOMICILIAR) {
|
||||
|
||||
$errors = $errors->merge(FichaAtendimentoDomiciliarService::index());
|
||||
}
|
||||
|
||||
if (!request()->ficha_id || request()->ficha_id == Permissao::FICHA_COMPLEMENTAR) {
|
||||
|
||||
$errors = $errors->merge(FichaComplementarService::index());
|
||||
}
|
||||
|
||||
if (!request()->ficha_id || request()->ficha_id == Permissao::VISITA_DOMICILIAR) {
|
||||
|
||||
$errors = $errors->merge(FichaVisitaDomiciliarService::index());
|
||||
}
|
||||
|
||||
if (!request()->ficha_id || request()->ficha_id == Permissao::AVALIACAO_ELEGIBILIDADE_ADMISSAO) {
|
||||
|
||||
$errors = $errors->merge(FichaAvaliacaoElegibilidadeService::index());
|
||||
}
|
||||
|
||||
if (!request()->ficha_id || request()->ficha_id == Permissao::CADASTRO_INDIVIDUAL) {
|
||||
|
||||
$errors = $errors->merge(FichaCadastroIndividualService::index());
|
||||
}
|
||||
|
||||
if (!request()->ficha_id || request()->ficha_id == Permissao::CADASTRO_DOMICILIAR) {
|
||||
|
||||
$errors = $errors->merge(FichaCadastroDomiciliarService::index());
|
||||
}
|
||||
|
||||
if (!request()->ficha_id || request()->ficha_id == Permissao::ATIVIDADE_COLETIVA) {
|
||||
|
||||
$errors = $errors->merge(FichaAtividadeColetivaService::index());
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
|
||||
public static function getEquipes()
|
||||
{
|
||||
return DB::table('atencao_basica_atendimento_odontologico as atendimento')
|
||||
->select('equipe.id')
|
||||
->join('atencao_basica_parametrizacao_equipe as equipe', 'equipe.id', 'atendimento.equipe_id')
|
||||
->join('cadastro_unidade as unidade', 'unidade.id', 'equipe.unidade_id')
|
||||
->where('atendimento.data_atendimento', '>=', request()->data_inicial)
|
||||
->where('atendimento.data_atendimento', '<=', request()->data_final)
|
||||
->when(request()->unidade_id, function($query) {
|
||||
$query->where('atendimento.unidade_id', request()->unidade_id);
|
||||
})
|
||||
->orderBy('equipe.id')
|
||||
->groupBy('equipe.id')
|
||||
->get();
|
||||
}
|
||||
|
||||
public static function getPrintExportData()
|
||||
{
|
||||
$items = self::list();
|
||||
|
||||
return [
|
||||
'items' => $items,
|
||||
'competencia' => self::getCompetencia(request()->mes_ano),
|
||||
'unidade' => request()->unidade_id ? Unidade::find(request()->unidade_id)->nome_fantasia : 'Todas',
|
||||
'infraestrutura' => request()->infraestrutura_id ? Infraestrutura::find(request()->infraestrutura_id)->nome : 'Todos',
|
||||
'usuario' => request()->usuario_id ? Usuario::find(request()->usuario_id)->nome : 'Todos',
|
||||
'ficha' => request()->ficha_id ? OutrosPermissao::find(request()->ficha_id)->descricao : 'Todas',
|
||||
'colunas' => collect(request()->selectedCols),
|
||||
];
|
||||
}
|
||||
|
||||
private static function getCompetencia($date_str)
|
||||
{
|
||||
|
||||
$month_names = [
|
||||
"Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho",
|
||||
"Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"
|
||||
];
|
||||
|
||||
$month_index = intval(substr($date_str, 0, 2)) - 1;
|
||||
$year_str = substr($date_str, 2);
|
||||
|
||||
$month_name = $month_names[$month_index];
|
||||
|
||||
$formatted_date = "{$month_name}/{$year_str}";
|
||||
|
||||
return $formatted_date;
|
||||
}
|
||||
|
||||
public static function validHeader($ficha, $funcionalidade)
|
||||
{
|
||||
$errors = collect();
|
||||
|
||||
if (!CnesIsValid::isValid($ficha->unidade_cnes)) {
|
||||
$errors->push(CnesIsValid::class);
|
||||
}
|
||||
|
||||
if (!IbgeIsValid::isValid($ficha->municipio_ibge)) {
|
||||
$errors->push(IbgeIsValid::class);
|
||||
}
|
||||
|
||||
if (!Cns::isValid($ficha->usuario_cns)) {
|
||||
$errors->push(Cns::class);
|
||||
}
|
||||
|
||||
if (!OcupacaoIsAllowed::isValid(['permissao_id' => $funcionalidade, 'ocupacao' => $ficha->ocupacao_codigo])) {
|
||||
$errors->push(OcupacaoIsAllowed::class);
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user