This commit is contained in:
@@ -0,0 +1,996 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\AtencaoBasica;
|
||||
|
||||
use App\Enums\AtencaoBasica\Parametrizacao\AreaTipo;
|
||||
use App\Enums\AtencaoBasica\VisitaDomiciliar\MotivoVisita;
|
||||
use App\Enums\AtencaoBasica\RelatorioCuidadoDesenvolvimentoInfantil\CboBoasPratricasAeBEnum;
|
||||
use App\Enums\AtencaoBasica\RelatorioCuidadoDesenvolvimentoInfantil\CboBoasPratricasCEnum;
|
||||
use App\Enums\AtencaoBasica\RelatorioCuidadoDesenvolvimentoInfantil\CboBoasPratricasDEnum;
|
||||
use App\Enums\AtencaoBasica\RelatorioCuidadoDesenvolvimentoInfantil\ClassificacaoEnum;
|
||||
use App\Enums\AtencaoBasica\RelatorioCuidadoDesenvolvimentoInfantil\ProcedimentosBoasPraticasC;
|
||||
use App\Enums\AtencaoBasica\RelatorioCuidadoDesenvolvimentoInfantil\VacinasEsquemaVacinalEnum;
|
||||
use App\Enums\Cadastro\SujeitoAtencao\Sexo;
|
||||
use App\Services\Service;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class RelatorioCuidadoDesenvolvimentoInfantilService extends Service
|
||||
{
|
||||
private const MAPA_INDICADORES = [
|
||||
'A' => 'indicadorA',
|
||||
'B' => 'indicadorB',
|
||||
'C' => 'indicadorC',
|
||||
'D' => 'indicadorD',
|
||||
'E' => 'indicadorE',
|
||||
];
|
||||
private const CONSULTAS_MINIMAS = 9;
|
||||
private const DIAS_LIMITE_PRIMEIRA_CONSULTA = 30;
|
||||
private const ANOS_LIMITE_PUBLICO_ALVO = 2;
|
||||
private const DIAS_LIMITE_SEGUNDA_VISITA = 180;
|
||||
|
||||
public static function create()
|
||||
{
|
||||
return [
|
||||
'form' => [
|
||||
'unidades' => [],
|
||||
'infraestruturas' => [],
|
||||
'equipes' => [],
|
||||
'anos' => self::getAnos(),
|
||||
'quadrimestres' => self::getQuadrimestres(),
|
||||
'sexo' => [
|
||||
['id' => Sexo::MASCULINO, 'sexo' => 'Masculino'],
|
||||
['id' => Sexo::FEMININO, 'sexo' => 'Feminino'],
|
||||
],
|
||||
'boas_praticas' => self::getBoasPraticas(),
|
||||
],
|
||||
'model' => [
|
||||
'periodo' => ['start' => null, 'end' => null],
|
||||
'ano' => null,
|
||||
'quadrimestre' => null,
|
||||
'unidade_id' => null,
|
||||
'infraestrutura_id' => null,
|
||||
'equipe_id' => null,
|
||||
'sexo_id' => null,
|
||||
'boasPraticas' => ['A', 'B', 'C', 'D', 'E'],
|
||||
'faixa_etaria' => [
|
||||
'inicial' => ['anos' => null, 'meses' => null, 'dias' => null],
|
||||
'final' => ['anos' => null, 'meses' => null, 'dias' => null],
|
||||
],
|
||||
'paciente_id' => null,
|
||||
'buscaAtiva' => null,
|
||||
'foraArea' => false,
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function index($request)
|
||||
{
|
||||
$params = self::getParams($request);
|
||||
$dadosPaciente = self::getDadosPaciente($params);
|
||||
$boasPraticasSelecionadas = !empty($params->boas_praticas) ? $params->boas_praticas : ['A', 'B', 'C', 'D', 'E'];
|
||||
|
||||
$dadosMensais = self::getDadosPacientePorMes($params);
|
||||
|
||||
$totais = self::calcularTotais($dadosPaciente);
|
||||
$metricasBoasPraticas = self::calcularMetricasBoasPraticas($dadosPaciente, $totais['totalPacientes'], $boasPraticasSelecionadas);
|
||||
$pontosPorPaciente = self::calcularPontosPorPaciente($dadosPaciente, $boasPraticasSelecionadas);
|
||||
|
||||
$denominador = $totais['totalPacientes'];
|
||||
$numerador = array_sum($pontosPorPaciente);
|
||||
$resultado = self::calcularResultadoMedioMensal($dadosMensais, $boasPraticasSelecionadas);
|
||||
|
||||
return [
|
||||
'totalizadores' => self::getTotalizadores($totais, $metricasBoasPraticas, $denominador, $numerador, $resultado),
|
||||
'resultadoPorEquipe' => self::getResultadoPorEquipe($dadosPaciente, $boasPraticasSelecionadas, $dadosMensais),
|
||||
'buscaAtiva' => $params->busca_ativa ? self::getBuscaAtiva($dadosPaciente, $boasPraticasSelecionadas) : [],
|
||||
'data' => $dadosPaciente,
|
||||
'boasPraticasSelecionadas' => $boasPraticasSelecionadas,
|
||||
];
|
||||
}
|
||||
|
||||
public static function list($request)
|
||||
{
|
||||
$params = self::getParams($request);
|
||||
|
||||
switch (request()->listar) {
|
||||
case 'unidades': {
|
||||
$dadosListagem = self::getDadosListagem($params);
|
||||
return [
|
||||
'unidades' => self::getUnidades($params, $dadosListagem),
|
||||
'infraestruturas' => self::getInfraestruturas($params, $dadosListagem),
|
||||
'equipes' => self::getEquipes($params, $dadosListagem),
|
||||
];
|
||||
}
|
||||
case 'infraestruturas': {
|
||||
$dadosListagem = self::getDadosListagem($params);
|
||||
return [
|
||||
'infraestruturas' => self::getInfraestruturas($params, $dadosListagem),
|
||||
'equipes' => self::getEquipes($params, $dadosListagem),
|
||||
];
|
||||
}
|
||||
case 'equipes': {
|
||||
$dadosListagem = self::getDadosListagem($params);
|
||||
return [
|
||||
'equipes' => self::getEquipes($params, $dadosListagem),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
private static function calcularTotais($dados)
|
||||
{
|
||||
return [
|
||||
'totalPacientes' => $dados->pluck('pacienteId')->unique()->count(),
|
||||
'totalEquipes' => $dados->pluck('equipeId')->unique()->count(),
|
||||
'totalMicroareas' => $dados->pluck('equipeDescricao')->unique()->count(),
|
||||
];
|
||||
}
|
||||
|
||||
private static function calcularMetricasBoasPraticas($dados, $totalPacientes, array $boasPraticasSelecionadas)
|
||||
{
|
||||
$metricas = [];
|
||||
|
||||
foreach ($boasPraticasSelecionadas as $pratica) {
|
||||
$campo = self::MAPA_INDICADORES[$pratica] ?? null;
|
||||
if (!$campo) continue;
|
||||
|
||||
$count = $dados->where($campo, true)->pluck('pacienteId')->unique()->count();
|
||||
$metricas[$pratica] = [
|
||||
'pacientes' => $count,
|
||||
'percentual' => $totalPacientes > 0 ? round(($count / $totalPacientes) * 100, 2) : 0,
|
||||
];
|
||||
}
|
||||
|
||||
return $metricas;
|
||||
}
|
||||
|
||||
private static function calcularPontosPorPaciente($dados, array $boasPraticasSelecionadas)
|
||||
{
|
||||
$pontos = [];
|
||||
|
||||
foreach ($dados->pluck('pacienteId')->unique() as $pacienteId) {
|
||||
$paciente = $dados->where('pacienteId', $pacienteId)->first();
|
||||
$pontos[$pacienteId] = self::calcularPontosPaciente($paciente, $boasPraticasSelecionadas);
|
||||
}
|
||||
|
||||
return $pontos;
|
||||
}
|
||||
|
||||
private static function calcularPontosPaciente($paciente, array $boasPraticasSelecionadas)
|
||||
{
|
||||
$pontos = 0;
|
||||
|
||||
foreach ($boasPraticasSelecionadas as $pratica) {
|
||||
$campo = self::MAPA_INDICADORES[$pratica] ?? null;
|
||||
if ($campo && $paciente->{$campo}) {
|
||||
$pontos += 20;
|
||||
}
|
||||
}
|
||||
|
||||
return $pontos;
|
||||
}
|
||||
|
||||
private static function calcularResultadoFinal($denominador, $numerador, $maxPontosPorPaciente = 100)
|
||||
{
|
||||
if ($denominador <= 0 || $numerador <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return round(($numerador / ($denominador * $maxPontosPorPaciente)) * 100, 2);
|
||||
}
|
||||
|
||||
private static function gerarSubperiodosMensais(array $periodo): array
|
||||
{
|
||||
$subperiodos = [];
|
||||
$current = $periodo['start']->copy()->startOfMonth()->startOfDay();
|
||||
$periodoEnd = $periodo['end']->copy();
|
||||
|
||||
while ($current->lte($periodoEnd)) {
|
||||
$monthEnd = $current->copy()->endOfMonth()->endOfDay();
|
||||
$subStart = $current->lt($periodo['start']) ? $periodo['start']->copy() : $current->copy();
|
||||
$subEnd = $monthEnd->gt($periodoEnd) ? $periodoEnd->copy() : $monthEnd;
|
||||
|
||||
$subperiodos[] = ['start' => $subStart, 'end' => $subEnd];
|
||||
|
||||
$current->addMonthNoOverflow()->startOfMonth();
|
||||
}
|
||||
|
||||
return $subperiodos;
|
||||
}
|
||||
|
||||
private static function getDadosPacientePorMes($params): array
|
||||
{
|
||||
$dadosMensais = [];
|
||||
|
||||
foreach (self::gerarSubperiodosMensais($params->periodo) as $subperiodo) {
|
||||
$paramsmes = (object) (array) $params;
|
||||
$paramsmes->periodo = $subperiodo;
|
||||
$dadosMensais[] = self::getDadosPaciente($paramsmes);
|
||||
}
|
||||
|
||||
return $dadosMensais;
|
||||
}
|
||||
|
||||
private static function calcularResultadoMedioMensal(array $dadosMensais, array $boasPraticasSelecionadas): float
|
||||
{
|
||||
$resultados = [];
|
||||
$maxPontos = count($boasPraticasSelecionadas) * 20;
|
||||
|
||||
foreach ($dadosMensais as $dadosMes) {
|
||||
$totais = self::calcularTotais($dadosMes);
|
||||
$pontos = self::calcularPontosPorPaciente($dadosMes, $boasPraticasSelecionadas);
|
||||
$resultados[] = self::calcularResultadoFinal(
|
||||
$totais['totalPacientes'],
|
||||
array_sum($pontos),
|
||||
$maxPontos
|
||||
);
|
||||
}
|
||||
|
||||
return count($resultados) > 0
|
||||
? round(array_sum($resultados) / count($resultados), 2)
|
||||
: 0;
|
||||
}
|
||||
|
||||
private static function calcularPercentuaisPorEquipe($pacientes, $totalPacientes, array $boasPraticasSelecionadas)
|
||||
{
|
||||
$percentuais = [];
|
||||
|
||||
foreach ($boasPraticasSelecionadas as $pratica) {
|
||||
$campo = self::MAPA_INDICADORES[$pratica] ?? null;
|
||||
if (!$campo) continue;
|
||||
|
||||
$count = $pacientes->where($campo, true)->pluck('pacienteId')->unique()->count();
|
||||
$percentuais['percentual' . $pratica] = $totalPacientes > 0
|
||||
? round(($count / $totalPacientes) * 100, 2)
|
||||
: 0;
|
||||
}
|
||||
|
||||
return $percentuais;
|
||||
}
|
||||
|
||||
private static function getTotalizadores($totais, $metricasBoasPraticas, $denominador, $numerador, $resultado)
|
||||
{
|
||||
return [
|
||||
'totalPacientes' => $totais['totalPacientes'],
|
||||
'totalEquipes' => $totais['totalEquipes'],
|
||||
'totalMicroareas' => $totais['totalMicroareas'],
|
||||
'denominador' => $denominador,
|
||||
'numerador' => $numerador,
|
||||
'resultado' => $resultado,
|
||||
'boasPraticas' => $metricasBoasPraticas,
|
||||
'semPublicoAlvo' => $denominador === 0,
|
||||
];
|
||||
}
|
||||
|
||||
private static function getClassificacao($resultado)
|
||||
{
|
||||
if ($resultado > 75) return ClassificacaoEnum::OTIMO;
|
||||
if ($resultado > 50) return ClassificacaoEnum::BOM;
|
||||
if ($resultado > 25) return ClassificacaoEnum::SUFICIENTE;
|
||||
|
||||
return ClassificacaoEnum::REGULAR;
|
||||
}
|
||||
|
||||
private static function getResultadoPorEquipe($dados, array $boasPraticasSelecionadas, array $dadosMensais = [])
|
||||
{
|
||||
$maxPontos = count($boasPraticasSelecionadas) * 20;
|
||||
|
||||
$resultadosMensaisPorEquipe = [];
|
||||
foreach ($dadosMensais as $dadosMes) {
|
||||
foreach ($dadosMes->groupBy('equipeId') as $equipeId => $pacientesMes) {
|
||||
$totalMes = $pacientesMes->pluck('pacienteId')->unique()->count();
|
||||
$pontosMes = array_sum(self::calcularPontosPorPaciente($pacientesMes, $boasPraticasSelecionadas));
|
||||
$resultadosMensaisPorEquipe[$equipeId][] = self::calcularResultadoFinal($totalMes, $pontosMes, $maxPontos);
|
||||
}
|
||||
}
|
||||
|
||||
$resultado = [];
|
||||
|
||||
foreach ($dados->groupBy('equipeId') as $equipeId => $pacientes) {
|
||||
$primeiro = $pacientes->first();
|
||||
$totalPacientes = $pacientes->pluck('pacienteId')->unique()->count();
|
||||
|
||||
$percentuais = self::calcularPercentuaisPorEquipe($pacientes, $totalPacientes, $boasPraticasSelecionadas);
|
||||
$pontos = self::calcularPontosPorPaciente($pacientes, $boasPraticasSelecionadas);
|
||||
|
||||
$denominador = $totalPacientes;
|
||||
$numerador = array_sum($pontos);
|
||||
|
||||
if (!empty($resultadosMensaisPorEquipe[$equipeId])) {
|
||||
$mensais = $resultadosMensaisPorEquipe[$equipeId];
|
||||
$resultadoEquipe = round(array_sum($mensais) / count($mensais), 2);
|
||||
} else {
|
||||
$resultadoEquipe = self::calcularResultadoFinal($denominador, $numerador, $maxPontos);
|
||||
}
|
||||
|
||||
$resultado[] = array_merge([
|
||||
'unidadeNomeFantasia' => $primeiro->unidadeNomeFantasia,
|
||||
'equipeDescricao' => $primeiro->equipeDescricao,
|
||||
'denominador' => $denominador,
|
||||
'numerador' => $numerador,
|
||||
'resultado' => $resultadoEquipe,
|
||||
'classificacao' => self::getClassificacao($resultadoEquipe),
|
||||
], $percentuais);
|
||||
}
|
||||
|
||||
return $resultado;
|
||||
}
|
||||
|
||||
private static function getBuscaAtiva($dados, array $boasPraticasSelecionadas)
|
||||
{
|
||||
$sexoMap = self::obterMapaSexo();
|
||||
$resultado = [];
|
||||
|
||||
foreach ($dados->unique('pacienteId') as $paciente) {
|
||||
$pontos = 0;
|
||||
$pendencias = [];
|
||||
|
||||
foreach ($boasPraticasSelecionadas as $pratica) {
|
||||
$campo = self::MAPA_INDICADORES[$pratica] ?? null;
|
||||
if (!$campo) continue;
|
||||
|
||||
if ($paciente->$campo) {
|
||||
$pontos += 20;
|
||||
} else {
|
||||
$pendencias[] = $pratica;
|
||||
}
|
||||
}
|
||||
|
||||
$dataNascimento = Carbon::parse($paciente->pacienteDataNascimento);
|
||||
$idade = $dataNascimento->diffInYears(Carbon::now());
|
||||
$meses = $dataNascimento->copy()->addYears($idade)->diffInMonths(Carbon::now());
|
||||
|
||||
if (empty($pendencias)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$resultado[] = [
|
||||
'unidadeNomeFantasia' => $paciente->unidadeNomeFantasia,
|
||||
'equipeDescricao' => $paciente->equipeDescricao,
|
||||
'pacienteNome' => $paciente->pacienteNome,
|
||||
'pacienteId' => $paciente->pacienteId,
|
||||
'pacienteSexo' => $sexoMap[$paciente->pacienteSexo] ?? 'Indefinido',
|
||||
'idadeCompleta' => "$idade anos e $meses meses",
|
||||
'usuarioResponsavelNome' => $paciente->usuarioResponsavelNome,
|
||||
'pacienteDataNascimento' => $dataNascimento->format('d/m/Y'),
|
||||
'pacienteTelefone' => $paciente->pacienteTelefone,
|
||||
'pacienteEndereco' => $paciente->pacienteEndereco,
|
||||
'areaMicroareaDomicilio' => $paciente->areaMicroareaDomicilio,
|
||||
'indicadorA' => $paciente->indicadorA,
|
||||
'indicadorB' => $paciente->indicadorB,
|
||||
'indicadorC' => $paciente->indicadorC,
|
||||
'indicadorD' => $paciente->indicadorD,
|
||||
'indicadorE' => $paciente->indicadorE,
|
||||
'areaTipoId' => $paciente->area_tipo_id,
|
||||
'pontuacaoTotal' => $pontos,
|
||||
];
|
||||
}
|
||||
|
||||
return $resultado;
|
||||
}
|
||||
|
||||
private static function baseQueryCadastroIndividual($params)
|
||||
{
|
||||
$periodoInicial = $params->periodo['start']->copy()->startOfDay();
|
||||
|
||||
return DB::table('atencao_basica_cadastro_individual')
|
||||
->join('cadastro_paciente', 'cadastro_paciente.id', 'atencao_basica_cadastro_individual.paciente_id')
|
||||
->join('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_paciente.cidadao_id')
|
||||
->leftJoin('cadastro_cidadao_telefone', function ($join) {
|
||||
$join->on('cadastro_cidadao_telefone.cidadao_id', 'cadastro_cidadao.id')
|
||||
->where('cadastro_cidadao_telefone.principal', 1)
|
||||
->whereNull('cadastro_cidadao_telefone.deleted_at');
|
||||
})
|
||||
->leftJoin('cadastro_domicilio', 'cadastro_domicilio.id', 'cadastro_cidadao.domicilio_id')
|
||||
->leftJoin('cadastro_endereco', 'cadastro_endereco.id', 'cadastro_domicilio.endereco_id')
|
||||
->leftJoin('cadastro_logradouro', 'cadastro_logradouro.id', 'cadastro_endereco.logradouro_id')
|
||||
->leftJoin('cadastro_bairro', 'cadastro_bairro.id', 'cadastro_logradouro.bairro_id')
|
||||
->join('cadastro_usuario', 'cadastro_usuario.id', 'atencao_basica_cadastro_individual.usuario_id')
|
||||
->join('cadastro_cidadao as cidadaoUsuario', 'cidadaoUsuario.id', 'cadastro_usuario.cidadao_id')
|
||||
->join('atencao_basica_parametrizacao_equipe', 'atencao_basica_parametrizacao_equipe.id', 'atencao_basica_cadastro_individual.equipe_id')
|
||||
->join('cadastro_infraestrutura', 'cadastro_infraestrutura.id', 'atencao_basica_parametrizacao_equipe.infraestrutura_id')
|
||||
->join('cadastro_unidade', 'cadastro_unidade.id', 'cadastro_infraestrutura.unidade_id')
|
||||
->join('atencao_basica_parametrizacao_area', 'atencao_basica_parametrizacao_area.id', 'atencao_basica_parametrizacao_equipe.area_id')
|
||||
->leftJoin('atencao_basica_parametrizacao_microarea', 'atencao_basica_parametrizacao_microarea.id', 'atencao_basica_parametrizacao_equipe.microarea_id')
|
||||
->leftJoin('atencao_basica_cadastro_domiciliar', 'atencao_basica_cadastro_domiciliar.domicilio_id', 'cadastro_cidadao.domicilio_id')
|
||||
->leftJoin('atencao_basica_parametrizacao_microarea as microareaDomicilio', 'microareaDomicilio.id', 'atencao_basica_cadastro_domiciliar.microarea_id')
|
||||
->leftJoin('atencao_basica_parametrizacao_area as areaDomicilio', 'areaDomicilio.id', 'microareaDomicilio.area_id')
|
||||
->leftJoin('cadastro_obito', function ($join) {
|
||||
$join->on('cadastro_cidadao.id', 'cadastro_obito.cidadao_id')
|
||||
->whereNull('cadastro_obito.deleted_at');
|
||||
})
|
||||
->where(function ($query) use ($periodoInicial) {
|
||||
$query->whereNull('cadastro_obito.id')
|
||||
->orWhere('cadastro_obito.obito_em', '>=', $periodoInicial);
|
||||
})
|
||||
->where(function ($query) use ($periodoInicial) {
|
||||
$query->whereNull('atencao_basica_cadastro_individual.saida_cidadao_id')
|
||||
->orWhere('atencao_basica_cadastro_individual.motivo_saida_data', '>=', $periodoInicial);
|
||||
})
|
||||
->where('cadastro_cidadao.data_nascimento', '>=', self::getDataNascimentoLimite($params))
|
||||
->whereIn('atencao_basica_parametrizacao_area.tipo_id', self::getAreaTipos())
|
||||
->when($params->unidade_id, fn ($q) => $q->where('cadastro_unidade.id', $params->unidade_id))
|
||||
->when($params->infraestrutura_id, fn ($q) => $q->where('cadastro_infraestrutura.id', $params->infraestrutura_id))
|
||||
->when($params->equipe_id, fn ($q) => $q->where('atencao_basica_parametrizacao_equipe.id', $params->equipe_id))
|
||||
->when(!$params->fora_area, function ($q) {
|
||||
$q->whereNotNull('atencao_basica_cadastro_domiciliar.id')
|
||||
->where(function ($sub) {
|
||||
$sub->whereNull('atencao_basica_cadastro_domiciliar.fora_area')
|
||||
->orWhere('atencao_basica_cadastro_domiciliar.fora_area', 0);
|
||||
});
|
||||
})
|
||||
->when(self::hasFaixaEtaria($params), fn ($q) => self::aplicarFiltroFaixaEtaria($q, $params));
|
||||
}
|
||||
|
||||
private static function selectEquipeDescricao()
|
||||
|
||||
{
|
||||
|
||||
return DB::raw('concat(
|
||||
|
||||
"Area: ", COALESCE(atencao_basica_parametrizacao_area.descricao, "Não informada"),
|
||||
|
||||
" Microarea: ", COALESCE(atencao_basica_parametrizacao_microarea.descricao, "Não informada"),
|
||||
|
||||
" - INE: ", COALESCE(atencao_basica_parametrizacao_area.numero_ine, "Não informada")
|
||||
|
||||
) as equipeDescricao');
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static function getDadosListagem($params)
|
||||
{
|
||||
return self::baseQueryCadastroIndividual($params)
|
||||
->select([
|
||||
'cadastro_unidade.id as unidadeId',
|
||||
'cadastro_unidade.nome_fantasia as unidadeNomeFantasia',
|
||||
'cadastro_infraestrutura.id as infraestruturaId',
|
||||
DB::raw('COALESCE(cadastro_infraestrutura.nome, cadastro_unidade.nome_fantasia) as infraestruturaNome'),
|
||||
'atencao_basica_parametrizacao_equipe.id as equipeId',
|
||||
self::selectEquipeDescricao(),
|
||||
])
|
||||
->distinct()
|
||||
->get();
|
||||
}
|
||||
|
||||
public static function getDadosPaciente($params)
|
||||
{
|
||||
$pacientes = self::baseQueryCadastroIndividual($params)
|
||||
->select([
|
||||
'atencao_basica_cadastro_individual.id',
|
||||
'cadastro_cidadao.nome as pacienteNome',
|
||||
'cadastro_paciente.id as pacienteId',
|
||||
'cadastro_cidadao.data_nascimento as pacienteDataNascimento',
|
||||
'cadastro_cidadao.sexo_id as pacienteSexo',
|
||||
'cadastro_unidade.id as unidadeId',
|
||||
'cadastro_unidade.nome_fantasia as unidadeNomeFantasia',
|
||||
'cadastro_infraestrutura.id as infraestruturaId',
|
||||
'cidadaoUsuario.nome as usuarioResponsavelNome',
|
||||
'cadastro_cidadao_telefone.numero as pacienteTelefone',
|
||||
'atencao_basica_parametrizacao_area.numero_ine as pacienteIne',
|
||||
'atencao_basica_parametrizacao_area.tipo_id as area_tipo_id',
|
||||
'atencao_basica_cadastro_domiciliar.fora_area as pacienteForaArea',
|
||||
DB::raw('CASE
|
||||
WHEN areaDomicilio.descricao IS NULL AND microareaDomicilio.descricao IS NULL THEN "Não informada"
|
||||
ELSE concat("Area: ", COALESCE(areaDomicilio.descricao, "Não informada"), " / Microarea: ", COALESCE(microareaDomicilio.descricao, "Não informada"))
|
||||
END as areaMicroareaDomicilio'),
|
||||
DB::raw('concat(cadastro_logradouro.nome, ", ", cadastro_endereco.numero, " - ", cadastro_bairro.nome, " - ", cadastro_logradouro.cep) as pacienteEndereco'),
|
||||
DB::raw('COALESCE(cadastro_infraestrutura.nome, cadastro_unidade.nome_fantasia) as infraestruturaNome'),
|
||||
'atencao_basica_parametrizacao_equipe.id as equipeId',
|
||||
self::selectEquipeDescricao(),
|
||||
])
|
||||
->when($params->sexo_id, fn ($q) => $q->where('cadastro_cidadao.sexo_id', $params->sexo_id))
|
||||
->when($params->paciente_id, fn ($q) => $q->where('cadastro_paciente.id', $params->paciente_id))
|
||||
->get();
|
||||
|
||||
if ($pacientes->isEmpty()) {
|
||||
return $pacientes;
|
||||
}
|
||||
|
||||
$periodoFinal = Carbon::parse($params->periodo['end'])->endOfDay();
|
||||
$pacienteIds = $pacientes->pluck('pacienteId')->unique()->toArray();
|
||||
$indicadoresA = self::getBoaPraticaA($pacienteIds, $periodoFinal);
|
||||
$indicadoresB = self::getBoaPraticaB($pacienteIds, $periodoFinal);
|
||||
$indicadoresC = self::getBoaPraticaC($pacienteIds, $periodoFinal);
|
||||
$indicadoresD = self::getBoaPraticaD($pacienteIds, $periodoFinal);
|
||||
$indicadoresE = self::getBoaPraticaE($pacienteIds, $pacientes, $periodoFinal);
|
||||
|
||||
return $pacientes->map(function ($item) use ($indicadoresA, $indicadoresB, $indicadoresC, $indicadoresD, $indicadoresE) {
|
||||
$keyIne = trim($item->pacienteId) . '-' . trim($item->pacienteIne ?? '');
|
||||
$item->indicadorA = $indicadoresA[$keyIne] ?? false;
|
||||
$item->indicadorB = $indicadoresB[$keyIne] ?? false;
|
||||
$item->indicadorC = $indicadoresC[$keyIne] ?? false;
|
||||
$item->indicadorD = $indicadoresD[$keyIne] ?? false;
|
||||
$item->indicadorE = $indicadoresE[$item->pacienteId] ?? false;
|
||||
return $item;
|
||||
});
|
||||
}
|
||||
|
||||
private static function getBoaPraticaA(array $pacienteIds, $periodoFinal): array
|
||||
{
|
||||
return DB::table('atencao_basica_atendimento_individual as ai')
|
||||
->join('cadastro_paciente as cp', 'cp.id', 'ai.paciente_id')
|
||||
->join('cadastro_cidadao as cc', 'cc.id', 'cp.cidadao_id')
|
||||
->join('sigtap.ocupacao as oc', 'oc.id', 'ai.usuario_ocupacao_id')
|
||||
->join('atencao_basica_parametrizacao_equipe as pe', 'pe.id', 'ai.equipe_id')
|
||||
->join('atencao_basica_parametrizacao_area as pa', 'pa.id', 'pe.area_id')
|
||||
->select(['ai.paciente_id', 'pa.numero_ine'])
|
||||
->where('ai.data_usuario_responsavel', '<=', $periodoFinal)
|
||||
->whereIn('oc.codigo', CboBoasPratricasAeBEnum::all())
|
||||
->whereIn('ai.paciente_id', $pacienteIds)
|
||||
->whereRaw('TIMESTAMPDIFF(DAY, cc.data_nascimento, ai.data_usuario_responsavel) <= ' . self::DIAS_LIMITE_PRIMEIRA_CONSULTA)
|
||||
->distinct()
|
||||
->get()
|
||||
->mapWithKeys(fn ($registro) => [trim($registro->paciente_id) . '-' . trim($registro->numero_ine) => true])
|
||||
->toArray();
|
||||
}
|
||||
|
||||
private static function getBoaPraticaB(array $pacienteIds, $periodoFinal): array
|
||||
{
|
||||
return DB::table('atencao_basica_atendimento_individual as ai')
|
||||
->join('cadastro_paciente as cp', 'cp.id', 'ai.paciente_id')
|
||||
->join('cadastro_cidadao as cc', 'cc.id', 'cp.cidadao_id')
|
||||
->join('sigtap.ocupacao as oc', 'oc.id', 'ai.usuario_ocupacao_id')
|
||||
->join('atencao_basica_parametrizacao_equipe as pe', 'pe.id', 'ai.equipe_id')
|
||||
->join('atencao_basica_parametrizacao_area as pa', 'pa.id', 'pe.area_id')
|
||||
->select(['ai.paciente_id', 'pa.numero_ine'])
|
||||
->where('ai.data_usuario_responsavel', '<=', $periodoFinal)
|
||||
->whereIn('oc.codigo', CboBoasPratricasAeBEnum::all())
|
||||
->whereIn('ai.paciente_id', $pacienteIds)
|
||||
->whereRaw('TIMESTAMPDIFF(YEAR, cc.data_nascimento, ai.data_usuario_responsavel) <= ' . self::ANOS_LIMITE_PUBLICO_ALVO)
|
||||
->groupBy(['ai.paciente_id', 'pa.numero_ine'])
|
||||
->havingRaw('COUNT(ai.id) >= ' . self::CONSULTAS_MINIMAS)
|
||||
->get()
|
||||
->mapWithKeys(fn ($registro) => [trim($registro->paciente_id) . '-' . trim($registro->numero_ine) => true])
|
||||
->toArray();
|
||||
}
|
||||
|
||||
private static function getBoaPraticaC(array $pacienteIds, $periodoFinal): array
|
||||
{
|
||||
$counts = [];
|
||||
|
||||
$accumulate = function ($registros) use (&$counts) {
|
||||
foreach ($registros as $registro) {
|
||||
$key = trim($registro->paciente_id) . '-' . trim($registro->numero_ine);
|
||||
$counts[$key] = ($counts[$key] ?? 0) + $registro->cnt;
|
||||
}
|
||||
};
|
||||
|
||||
$accumulate(
|
||||
DB::table('atencao_basica_atendimento_individual as ai')
|
||||
->join('atencao_basica_parametrizacao_equipe as pe', 'pe.id', 'ai.equipe_id')
|
||||
->join('atencao_basica_parametrizacao_area as pa', 'pa.id', 'pe.area_id')
|
||||
->join('sigtap.ocupacao as oc', 'oc.id', 'ai.usuario_ocupacao_id')
|
||||
->select(['ai.paciente_id', 'pa.numero_ine', DB::raw('COUNT(*) as cnt')])
|
||||
->where('ai.data_usuario_responsavel', '<=', $periodoFinal)
|
||||
->whereIn('oc.codigo', CboBoasPratricasCEnum::all())
|
||||
->whereIn('ai.paciente_id', $pacienteIds)
|
||||
->whereNotNull('ai.peso')
|
||||
->whereNotNull('ai.altura')
|
||||
->groupBy(['ai.paciente_id', 'pa.numero_ine'])
|
||||
->get()
|
||||
);
|
||||
|
||||
$accumulate(
|
||||
DB::table('atencao_basica_atividade_coletiva as ac')
|
||||
->join('atencao_basica_atividade_coletiva_participante as acp', 'acp.atividade_coletiva_id', 'ac.id')
|
||||
->join('atencao_basica_parametrizacao_equipe as pe', 'pe.id', 'ac.equipe_id')
|
||||
->join('atencao_basica_parametrizacao_area as pa', 'pa.id', 'pe.area_id')
|
||||
->join('sigtap.ocupacao as oc', 'oc.id', 'ac.usuario_ocupacao_id')
|
||||
->select(['acp.paciente_id', 'pa.numero_ine', DB::raw('COUNT(*) as cnt')])
|
||||
->where('ac.data_cadastro', '<=', $periodoFinal)
|
||||
->whereIn('oc.codigo', CboBoasPratricasCEnum::all())
|
||||
->whereIn('acp.paciente_id', $pacienteIds)
|
||||
->whereNotNull('acp.peso')
|
||||
->whereNotNull('acp.altura')
|
||||
->groupBy(['acp.paciente_id', 'pa.numero_ine'])
|
||||
->get()
|
||||
);
|
||||
|
||||
$accumulate(
|
||||
DB::table('atencao_basica_visita_domiciliar as vd')
|
||||
->join('atencao_basica_parametrizacao_equipe as pe', 'pe.id', 'vd.equipe_id')
|
||||
->join('atencao_basica_parametrizacao_area as pa', 'pa.id', 'pe.area_id')
|
||||
->join('sigtap.ocupacao as oc', 'oc.id', 'vd.usuario_ocupacao_id')
|
||||
->select(['vd.paciente_id', 'pa.numero_ine', DB::raw('COUNT(*) as cnt')])
|
||||
->where('vd.data_usuario_responsavel', '<=', $periodoFinal)
|
||||
->whereIn('oc.codigo', CboBoasPratricasCEnum::all())
|
||||
->whereIn('vd.paciente_id', $pacienteIds)
|
||||
->whereNotNull('vd.peso')
|
||||
->whereNotNull('vd.altura')
|
||||
->groupBy(['vd.paciente_id', 'pa.numero_ine'])
|
||||
->get()
|
||||
);
|
||||
|
||||
$accumulate(
|
||||
DB::table('atencao_basica_procedimento as p')
|
||||
->join('atencao_basica_parametrizacao_equipe as pe', 'pe.id', 'p.equipe_id')
|
||||
->join('atencao_basica_parametrizacao_area as pa', 'pa.id', 'pe.area_id')
|
||||
->join('atencao_basica_procedimento_atendimento as pa_att', 'pa_att.procedimento_id', 'p.id')
|
||||
->join('atencao_basica_procedimento_atendimento_procedimento as pap', 'pap.procedimento_atendimento_id', 'pa_att.id')
|
||||
->join('sigtap.ocupacao as oc', 'oc.id', 'p.ocupacao_id')
|
||||
->select(['pa_att.paciente_id', 'pa.numero_ine', DB::raw('COUNT(*) as cnt')])
|
||||
->where('p.data_usuario_responsavel', '<=', $periodoFinal)
|
||||
->whereIn('oc.codigo', CboBoasPratricasCEnum::all())
|
||||
->whereIn('pap.procedimento_id', ProcedimentosBoasPraticasC::all())
|
||||
->whereIn('pa_att.paciente_id', $pacienteIds)
|
||||
->groupBy(['pa_att.paciente_id', 'pa.numero_ine'])
|
||||
->get()
|
||||
);
|
||||
|
||||
return array_filter($counts, fn ($totalRegistros) => $totalRegistros >= self::CONSULTAS_MINIMAS);
|
||||
}
|
||||
|
||||
private static function getBoaPraticaD(array $pacienteIds, $periodoFinal): array
|
||||
{
|
||||
return DB::table('atencao_basica_visita_domiciliar as vd')
|
||||
->join('cadastro_paciente as cp', 'cp.id', 'vd.paciente_id')
|
||||
->join('cadastro_cidadao as cc', 'cc.id', 'cp.cidadao_id')
|
||||
->join('sigtap.ocupacao as oc', 'oc.id', 'vd.usuario_ocupacao_id')
|
||||
->join('atencao_basica_parametrizacao_equipe as pe', 'pe.id', 'vd.equipe_id')
|
||||
->join('atencao_basica_parametrizacao_area as pa', 'pa.id', 'pe.area_id')
|
||||
->select(['vd.paciente_id', 'pa.numero_ine'])
|
||||
->where('vd.data_usuario_responsavel', '<=', $periodoFinal)
|
||||
->whereIn('oc.codigo', CboBoasPratricasDEnum::all())
|
||||
->whereIn('pa.tipo_id', [AreaTipo::EQUIPE_DE_ATENCAO_PRIMARIA])
|
||||
->whereIn('vd.paciente_id', $pacienteIds)
|
||||
->whereExists(function ($subquery) {
|
||||
$subquery->select(DB::raw(1))
|
||||
->from('atencao_basica_visita_domiciliar_motivo_visita')
|
||||
->whereColumn('atencao_basica_visita_domiciliar_motivo_visita.visita_domiciliar_id', 'vd.id')
|
||||
->whereIn('atencao_basica_visita_domiciliar_motivo_visita.motivo_visita_id', [MotivoVisita::RECEM_NASCIDO, MotivoVisita::CRIANCA]);
|
||||
})
|
||||
->groupBy(['vd.paciente_id', 'pa.numero_ine'])
|
||||
->havingRaw('SUM(CASE WHEN TIMESTAMPDIFF(DAY, cc.data_nascimento, vd.data_usuario_responsavel) <= ' . self::DIAS_LIMITE_PRIMEIRA_CONSULTA . ' THEN 1 ELSE 0 END) >= 1')
|
||||
->havingRaw('SUM(CASE WHEN TIMESTAMPDIFF(DAY, cc.data_nascimento, vd.data_usuario_responsavel) > ' . self::DIAS_LIMITE_PRIMEIRA_CONSULTA . ' AND TIMESTAMPDIFF(DAY, cc.data_nascimento, vd.data_usuario_responsavel) <= ' . self::DIAS_LIMITE_SEGUNDA_VISITA . ' THEN 1 ELSE 0 END) >= 1')
|
||||
->get()
|
||||
->mapWithKeys(fn ($registro) => [trim($registro->paciente_id) . '-' . trim($registro->numero_ine) => true])
|
||||
->toArray();
|
||||
}
|
||||
|
||||
private static function getBoaPraticaE(array $pacienteIds, $pacientes, $periodoFinal): array
|
||||
{
|
||||
$gruposVacinais = self::getGruposVacinais();
|
||||
$allVacinas = array_unique(array_merge(...array_column($gruposVacinais, 'vacinas')));
|
||||
|
||||
$aplicacoes = DB::table('imunizacao_registro_aplicacao as ira')
|
||||
->join('imunizacao_entrada_vacina as iev', 'iev.id', 'ira.entrada_vacina_id')
|
||||
->join('cadastro_vacina as cv', 'cv.id', 'iev.vacina_id')
|
||||
->select(['ira.paciente_id', 'ira.data_aplicacao', 'cv.codigo_ria'])
|
||||
->where('ira.data_aplicacao', '<=', $periodoFinal)
|
||||
->whereIn('ira.paciente_id', $pacienteIds)
|
||||
->whereIn('cv.codigo_ria', $allVacinas)
|
||||
->distinct()
|
||||
->get()
|
||||
->groupBy('paciente_id');
|
||||
|
||||
$atualizacoes = DB::table('imunizacao_registro_atualizacao as iru')
|
||||
->join('cadastro_vacina as cv', 'cv.id', 'iru.vacina_id')
|
||||
->select(['iru.paciente_id', 'iru.data_atualizacao', 'cv.codigo_ria'])
|
||||
->where('iru.data_atualizacao', '<=', $periodoFinal)
|
||||
->whereIn('iru.paciente_id', $pacienteIds)
|
||||
->whereIn('cv.codigo_ria', $allVacinas)
|
||||
->distinct()
|
||||
->get()
|
||||
->groupBy('paciente_id');
|
||||
|
||||
$dataNascimentoMap = $pacientes->pluck('pacienteDataNascimento', 'pacienteId')->toArray();
|
||||
|
||||
$resultado = [];
|
||||
foreach ($pacienteIds as $pacienteId) {
|
||||
$registros = ($aplicacoes[$pacienteId] ?? collect())->merge($atualizacoes[$pacienteId] ?? collect());
|
||||
$dataNascimento = Carbon::parse($dataNascimentoMap[$pacienteId] ?? null);
|
||||
$valido = true;
|
||||
|
||||
foreach ($gruposVacinais as $grupo) {
|
||||
$registrosGrupo = $registros->whereIn('codigo_ria', $grupo['vacinas'])->values();
|
||||
$dnValidacao = isset($grupo['idadeMinMeses']) ? $dataNascimento : null;
|
||||
|
||||
if (!self::validarGrupoVacinal($registrosGrupo, $grupo['dosesMinimas'], $grupo['intervaloDias'], $dnValidacao, $grupo['idadeMinMeses'] ?? null)) {
|
||||
$valido = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$resultado[$pacienteId] = $valido;
|
||||
}
|
||||
|
||||
return $resultado;
|
||||
}
|
||||
|
||||
private static function getGruposVacinais(): array
|
||||
{
|
||||
return [
|
||||
['vacinas' => [
|
||||
VacinasEsquemaVacinalEnum::VACINA_HEPATITE_B_RECOMBINANTE,
|
||||
VacinasEsquemaVacinalEnum::VACINA_HAEMOPHILUS_INFLUENZA_B_CONJUGADA,
|
||||
VacinasEsquemaVacinalEnum::VACINA_DTPA_HIB_POLIO_INATIVA,
|
||||
VacinasEsquemaVacinalEnum::VACINA_DTP_HIB,
|
||||
VacinasEsquemaVacinalEnum::VACINA_DTP_HB_HIB,
|
||||
VacinasEsquemaVacinalEnum::VACINA_HEXAVALENTE,
|
||||
VacinasEsquemaVacinalEnum::VACINA_TRIPLA_BACTERIANA,
|
||||
VacinasEsquemaVacinalEnum::VACINA_TRIPLA_ACELULAR_INFANTIL,
|
||||
], 'dosesMinimas' => 3, 'intervaloDias' => 30],
|
||||
['vacinas' => [
|
||||
VacinasEsquemaVacinalEnum::VACINA_POLIOMIELITE_INATIVADA,
|
||||
VacinasEsquemaVacinalEnum::VACINA_DTPA_HIB_POLIO_INATIVA,
|
||||
VacinasEsquemaVacinalEnum::VACINA_HEXAVALENTE,
|
||||
], 'dosesMinimas' => 3, 'intervaloDias' => 30],
|
||||
['vacinas' => [
|
||||
VacinasEsquemaVacinalEnum::VACINA_TRIPLA_VIRAL,
|
||||
], 'dosesMinimas' => 2, 'intervaloDias' => 0, 'idadeMinMeses' => 12],
|
||||
['vacinas' => [
|
||||
VacinasEsquemaVacinalEnum::VACINA_PNEUMOCOCICA_10V,
|
||||
VacinasEsquemaVacinalEnum::VACINA_PNEUMOCOCICA_13V,
|
||||
VacinasEsquemaVacinalEnum::VACINA_PNEUMOCOCICA_15V,
|
||||
], 'dosesMinimas' => 2, 'intervaloDias' => 30],
|
||||
['vacinas' => [
|
||||
VacinasEsquemaVacinalEnum::VACINA_TRIPLA_ACELULAR_POLIOMIELITE_INATIVADA,
|
||||
], 'dosesMinimas' => 1, 'intervaloDias' => 0],
|
||||
['vacinas' => [
|
||||
VacinasEsquemaVacinalEnum::VACINA_TETRA_VIRAL,
|
||||
], 'dosesMinimas' => 1, 'intervaloDias' => 0],
|
||||
['vacinas' => [
|
||||
VacinasEsquemaVacinalEnum::VACINA_PNEUMOCOCICA_20V,
|
||||
], 'dosesMinimas' => 1, 'intervaloDias' => 0],
|
||||
];
|
||||
}
|
||||
|
||||
private static function validarGrupoVacinal($registros, $dosesMinimas, $intervaloDias = 0, $dataNascimento = null, $idadeMinMeses = null)
|
||||
{
|
||||
$registros = $registros->map(function ($item) {
|
||||
$item->data = $item->data_aplicacao ?? $item->data_atualizacao;
|
||||
return $item;
|
||||
})->sortBy('data')->values();
|
||||
|
||||
if ($idadeMinMeses !== null && $dataNascimento) {
|
||||
$registros = $registros->filter(function ($item) use ($dataNascimento, $idadeMinMeses) {
|
||||
return Carbon::parse($item->data)->diffInMonths($dataNascimento) >= $idadeMinMeses;
|
||||
})->values();
|
||||
}
|
||||
|
||||
$dosesValidas = [];
|
||||
$ultimaDataValida = null;
|
||||
|
||||
foreach ($registros as $item) {
|
||||
$dataAtual = Carbon::parse($item->data);
|
||||
|
||||
if (!$ultimaDataValida) {
|
||||
$dosesValidas[] = $dataAtual;
|
||||
$ultimaDataValida = $dataAtual;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($intervaloDias === 0) {
|
||||
$dosesValidas[] = $dataAtual;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($ultimaDataValida->diffInDays($dataAtual) >= $intervaloDias) {
|
||||
$dosesValidas[] = $dataAtual;
|
||||
$ultimaDataValida = $dataAtual;
|
||||
}
|
||||
}
|
||||
|
||||
return count($dosesValidas) >= $dosesMinimas;
|
||||
}
|
||||
|
||||
private static function getEquipes($params, $dadosListagem = null)
|
||||
{
|
||||
$dadosListagem = $dadosListagem ?? self::getDadosListagem($params);
|
||||
|
||||
return $dadosListagem
|
||||
->when($params->unidade_id, fn ($collection) => $collection->where('unidadeId', $params->unidade_id))
|
||||
->when($params->infraestrutura_id, fn ($collection) => $collection->where('infraestruturaId', $params->infraestrutura_id))
|
||||
->map(fn ($item) => (object) ['id' => $item->equipeId, 'descricao' => $item->equipeDescricao])
|
||||
->filter(fn ($item) => !is_null($item->id))
|
||||
->unique('id')
|
||||
->sortBy('descricao')
|
||||
->values();
|
||||
}
|
||||
|
||||
private static function getInfraestruturas($params, $dadosListagem = null)
|
||||
{
|
||||
$dadosListagem = $dadosListagem ?? self::getDadosListagem($params);
|
||||
|
||||
return $dadosListagem
|
||||
->when($params->unidade_id, fn ($collection) => $collection->where('unidadeId', $params->unidade_id))
|
||||
->map(fn ($item) => (object) ['id' => $item->infraestruturaId, 'nome' => $item->infraestruturaNome])
|
||||
->filter(fn ($item) => !is_null($item->id))
|
||||
->unique('id')
|
||||
->sortBy('nome')
|
||||
->values();
|
||||
}
|
||||
|
||||
private static function getUnidades($params, $dadosListagem = null)
|
||||
{
|
||||
$dadosListagem = $dadosListagem ?? self::getDadosListagem($params);
|
||||
|
||||
return $dadosListagem
|
||||
->map(fn ($item) => (object) ['id' => $item->unidadeId, 'nome_fantasia' => $item->unidadeNomeFantasia])
|
||||
->filter(fn ($item) => !is_null($item->id))
|
||||
->unique('id')
|
||||
->sortBy('nome_fantasia')
|
||||
->values();
|
||||
}
|
||||
|
||||
private static function getParams($request)
|
||||
{
|
||||
$faixaEtaria = self::formatarFaixaEtaria($request->input('faixa_etaria', []));
|
||||
|
||||
return (object) [
|
||||
'periodo' => self::obterPeriodoRequest($request),
|
||||
'quadrimestre' => $request->input('quadrimestre'),
|
||||
'unidade_id' => $request->input('unidade_id'),
|
||||
'infraestrutura_id' => $request->input('infraestrutura_id'),
|
||||
'equipe_id' => $request->input('equipe_id'),
|
||||
'sexo_id' => $request->input('sexo_id'),
|
||||
'boas_praticas' => $request->input('boas_praticas') ?? [],
|
||||
'faixa_etaria' => $faixaEtaria,
|
||||
'paciente_id' => $request->input('paciente_id'),
|
||||
'busca_ativa' => $request->input('busca_ativa') ?? false,
|
||||
'fora_area' => $request->input('fora_area') ?? false,
|
||||
];
|
||||
}
|
||||
|
||||
private static function obterPeriodoRequest($request)
|
||||
{
|
||||
$periodoPorQuadrimestre = self::getPeriodoPorQuadrimestre($request->input('quadrimestre'));
|
||||
|
||||
if ($periodoPorQuadrimestre) {
|
||||
return $periodoPorQuadrimestre;
|
||||
}
|
||||
|
||||
$periodo = $request->input('periodo');
|
||||
|
||||
return [
|
||||
'start' => Carbon::createFromFormat('d/m/Y', $periodo['start'])->setTime(0, 0, 0),
|
||||
'end' => Carbon::createFromFormat('d/m/Y', $periodo['end'])->setTime(23, 59, 59),
|
||||
];
|
||||
}
|
||||
|
||||
private static function getPeriodoPorQuadrimestre($quadrimestre)
|
||||
{
|
||||
if (empty($quadrimestre) || !str_contains($quadrimestre, '-')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
[$ano, $numero] = array_pad(explode('-', $quadrimestre), 2, null);
|
||||
|
||||
$faixas = [
|
||||
1 => ['inicio' => [1, 1], 'fim' => [4, 30]],
|
||||
2 => ['inicio' => [5, 1], 'fim' => [8, 31]],
|
||||
3 => ['inicio' => [9, 1], 'fim' => [12, 31]],
|
||||
];
|
||||
|
||||
$numero = (int) $numero;
|
||||
$ano = (int) $ano;
|
||||
|
||||
if (!isset($faixas[$numero]) || $ano < 2020) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'start' => Carbon::create($ano, $faixas[$numero]['inicio'][0], $faixas[$numero]['inicio'][1])->startOfDay(),
|
||||
'end' => Carbon::create($ano, $faixas[$numero]['fim'][0], $faixas[$numero]['fim'][1])->endOfDay(),
|
||||
];
|
||||
}
|
||||
|
||||
private static function formatarFaixaEtaria($faixaEtaria)
|
||||
{
|
||||
$sanitizar = function ($value, $max) {
|
||||
if ($value === null || $value === '') {
|
||||
return null;
|
||||
}
|
||||
return max(0, min((int) $value, $max));
|
||||
};
|
||||
|
||||
return [
|
||||
'inicial' => [
|
||||
'anos' => $sanitizar($faixaEtaria['inicial']['anos'] ?? null, 2),
|
||||
'meses' => $sanitizar($faixaEtaria['inicial']['meses'] ?? null, 11),
|
||||
'dias' => $sanitizar($faixaEtaria['inicial']['dias'] ?? null, 30),
|
||||
],
|
||||
'final' => [
|
||||
'anos' => $sanitizar($faixaEtaria['final']['anos'] ?? null, 2),
|
||||
'meses' => $sanitizar($faixaEtaria['final']['meses'] ?? null, 11),
|
||||
'dias' => $sanitizar($faixaEtaria['final']['dias'] ?? null, 30),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
private static function hasFaixaEtaria($params)
|
||||
{
|
||||
$faixaEtaria = $params->faixa_etaria ?? ['inicial' => [], 'final' => []];
|
||||
$inicial = $faixaEtaria['inicial'] ?? [];
|
||||
$final = $faixaEtaria['final'] ?? [];
|
||||
|
||||
return isset($inicial['anos']) || isset($inicial['meses']) || isset($inicial['dias'])
|
||||
|| isset($final['anos']) || isset($final['meses']) || isset($final['dias']);
|
||||
}
|
||||
|
||||
private static function idadeParaDataNascimento(Carbon $referencia, array $idade)
|
||||
{
|
||||
return $referencia
|
||||
->copy()
|
||||
->subYears((int) ($idade['anos'] ?? 0))
|
||||
->subMonths((int) ($idade['meses'] ?? 0))
|
||||
->subDays((int) ($idade['dias'] ?? 0));
|
||||
}
|
||||
|
||||
private static function aplicarFiltroFaixaEtaria($query, $params)
|
||||
{
|
||||
$referencia = Carbon::today()->endOfDay();
|
||||
$inicial = $params->faixa_etaria['inicial'];
|
||||
$final = $params->faixa_etaria['final'];
|
||||
|
||||
$temInicial = isset($inicial['anos']) || isset($inicial['meses']) || isset($inicial['dias']);
|
||||
$temFinal = isset($final['anos']) || isset($final['meses']) || isset($final['dias']);
|
||||
|
||||
if ($temFinal) {
|
||||
$nascimentoMinimo = self::idadeParaDataNascimento($referencia, $final);
|
||||
$query->whereDate('cadastro_cidadao.data_nascimento', '>', $nascimentoMinimo->toDateString());
|
||||
}
|
||||
|
||||
if ($temInicial) {
|
||||
$nascimentoMaximo = self::idadeParaDataNascimento($referencia, $inicial);
|
||||
$query->whereDate('cadastro_cidadao.data_nascimento', '<=', $nascimentoMaximo->toDateString());
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
private static function getDataNascimentoLimite($params)
|
||||
{
|
||||
return $params->periodo['end']->copy()->subYears(2);
|
||||
}
|
||||
|
||||
private static function getAreaTipos()
|
||||
{
|
||||
return [
|
||||
AreaTipo::EQUIPE_DE_SAUDE_DA_FAMILIA,
|
||||
AreaTipo::EQUIPE_DE_ATENCAO_PRIMARIA,
|
||||
];
|
||||
}
|
||||
|
||||
private static function obterMapaSexo()
|
||||
{
|
||||
return [
|
||||
Sexo::MASCULINO => 'Masculino',
|
||||
Sexo::FEMININO => 'Feminino',
|
||||
];
|
||||
}
|
||||
|
||||
private static function getAnos()
|
||||
{
|
||||
$anos = [];
|
||||
for ($ano = now()->year; $ano >= 2020; $ano--) {
|
||||
$anos[] = ['id' => $ano, 'descricao' => (string) $ano];
|
||||
}
|
||||
return $anos;
|
||||
}
|
||||
|
||||
private static function getQuadrimestres()
|
||||
{
|
||||
return [
|
||||
['id' => 1, 'descricao' => '1º Quadrimestre (Jan - Abr)', 'inicio' => '01-01', 'fim' => '04-30'],
|
||||
['id' => 2, 'descricao' => '2º Quadrimestre (Mai - Ago)', 'inicio' => '05-01', 'fim' => '08-31'],
|
||||
['id' => 3, 'descricao' => '3º Quadrimestre (Set - Dez)', 'inicio' => '09-01', 'fim' => '12-31'],
|
||||
];
|
||||
}
|
||||
|
||||
private static function getBoasPraticas()
|
||||
{
|
||||
return collect([
|
||||
['value' => 'A', 'text' => 'A - 1ª consulta até 30 dias de idade'],
|
||||
['value' => 'B', 'text' => 'B - 9 consultas até 2 anos de idade'],
|
||||
['value' => 'C', 'text' => 'C - 9 registros simultâneos de peso e altura'],
|
||||
['value' => 'D', 'text' => 'D - 2 visitas domiciliares'],
|
||||
['value' => 'E', 'text' => 'E - Vacinação completa'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user