Files
rkm-conectasus-ci-sandbox/api/app/Services/AtencaoBasica/RelatorioCuidadoPessoaHipertensaoService.php
Antonio Lopes dos Santos afec302c3e
All checks were successful
build-api-image / build (push) Successful in 51s
init commit
2026-08-04 16:52:02 -03:00

1680 lines
88 KiB
PHP

<?php
namespace App\Services\AtencaoBasica;
use App\Enums\AtencaoBasica\AtendimentoIndividual\CondicaoAvaliada;
use App\Enums\AtencaoBasica\CadastroIndividual\SaidaCidadao;
use App\Enums\AtencaoBasica\Parametrizacao\AreaTipo;
use App\Enums\Sigtap\Procedimento;
use App\Models\AtencaoBasica\Parametrizacao\Equipe;
use App\Models\Cadastro\Estabelecimento\Unidade;
use App\Models\Cadastro\SujeitoAtencao\Paciente;
use App\Models\Cadastro\SujeitoAtencao\Sexo;
use App\Services\Geral\AgeService;
use App\Services\Service;
use App\Utils\DataUtil;
use App\Utils\MaskUtil;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class RelatorioCuidadoPessoaHipertensaoService extends Service
{
public static function index()
{
$params = self::getParams();
$resultadoEquipes = self::getResultadoPorEquipes($params);
$equipes = $resultadoEquipes->equipes;
$totalizadores = $resultadoEquipes->totalizadores;
$pacientes = $params->busca_ativa ? self::getResultadoPorPacientes($params) : collect();
return (object) [
'equipes' => $equipes,
'pacientes' => $pacientes,
'totalizadores' => $totalizadores,
];
}
private static function getResultadoPorEquipes($params)
{
$equipesBuilder = DB::table('atencao_basica_cadastro_individual AS cadastro_individual')
->join('cadastro_paciente AS paciente', 'paciente.id', 'cadastro_individual.paciente_id')
->join('cadastro_cidadao as cidadao', 'cidadao.id', 'paciente.cidadao_id')
->join('atencao_basica_parametrizacao_equipe AS equipe', 'equipe.id', 'cadastro_individual.equipe_id')
->join('atencao_basica_parametrizacao_area AS area', 'area.id', 'equipe.area_id')
->join('cadastro_unidade AS unidade', 'unidade.id', 'equipe.unidade_id')
->join('atencao_basica_atendimento_individual AS atendimento_individual', fn ($q) => $q
->on('atendimento_individual.paciente_id', 'paciente.id')
->where('atendimento_individual.id', fn ($q) => $q
->select('atendimento_individual2.id')
->from('atencao_basica_atendimento_individual AS atendimento_individual2')
->whereColumn('atendimento_individual2.paciente_id', 'paciente.id')
->where(fn ($q) => $q
->whereExists(fn ($q) => $q
->selectRaw(1)
->from('atencao_basica_atendimento_individual_problema_condicao AS problema_condicao')
->leftJoin('geral_ciap AS ciap', 'ciap.id', 'problema_condicao.ciap_id')
->leftJoin('sigtap.cid AS cid', 'cid.id', 'problema_condicao.cid_id')
->whereColumn('problema_condicao.atendimento_individual_id', 'atendimento_individual2.id')
->where(fn ($q) => $q
->whereIn('ciap.codigo', self::getCiapsHipertensao())
->orWhereIn('cid.codigo', self::getCidsHipertensao())
)
)
->orWhereExists(fn ($q) => $q
->selectRaw(1)
->from('atencao_basica_atendimento_individual_condicao_avaliada AS atendimento_individual_condicao_avaliada')
->whereColumn('atendimento_individual_condicao_avaliada.atendimento_individual_id', 'atendimento_individual2.id')
->where('atendimento_individual_condicao_avaliada.condicao_avaliada_id', CondicaoAvaliada::HIPERTENSAO_ARTERIAL)
)
)
->where('atendimento_individual2.data_usuario_responsavel', '<=', $params->periodo['end']->format('Y-m-d'))
->orderBy('atendimento_individual2.data_usuario_responsavel')
->limit(1)
)
)
->leftJoin('atencao_basica_parametrizacao_microarea AS microarea', 'microarea.id', 'equipe.microarea_id')
->leftJoin('atencao_basica_cadastro_domiciliar AS cadastro_domiciliar', 'cadastro_domiciliar.domicilio_id', 'cidadao.domicilio_id')
->leftJoin('cadastro_obito AS obito', fn ($j) => $j
->on('obito.cidadao_id', 'cidadao.id')
->whereNull('obito.deleted_at')
)
->select([
'unidade.nome_fantasia AS unidade_nome_fantasia',
'microarea.id AS microarea_id',
DB::raw("CONCAT(
CASE
WHEN area.numero_ine IS NOT NULL THEN CONCAT('INE: ', area.numero_ine)
ELSE ''
END,
CASE
WHEN area.descricao IS NOT NULL AND area.numero_ine IS NOT NULL THEN ' - Área: '
WHEN area.descricao IS NOT NULL THEN 'Área: '
ELSE ''
END,
COALESCE(area.descricao, ''),
CASE
WHEN microarea.descricao IS NOT NULL
AND (area.numero_ine IS NOT NULL OR area.descricao IS NOT NULL) THEN ' - Microárea: '
WHEN microarea.descricao IS NOT NULL THEN 'Microárea: '
ELSE ''
END,
COALESCE(microarea.descricao, '')
) AS equipe_descricao"),
DB::raw("COUNT(DISTINCT (cadastro_individual.paciente_id)) AS denominador"),
DB::raw("GROUP_CONCAT(DISTINCT(cadastro_individual.paciente_id) SEPARATOR '#') AS pacientes"),
DB::raw("
SUM(
IF(
(
SELECT TRUE
FROM atencao_basica_atendimento_individual abai
INNER JOIN sigtap.ocupacao o ON o.id = abai.usuario_ocupacao_id
WHERE abai.paciente_id = paciente.id
AND abai.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abai.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 6 MONTH)
AND abai.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND (
o.codigo LIKE '2231%' OR
o.codigo LIKE '2235%' OR
o.codigo LIKE '2251%' OR
o.codigo LIKE '2252%' OR
o.codigo LIKE '2253%'
)
LIMIT 1
),
1,
0
)
) AS quantidade_boa_pratica_a
"),
DB::raw("
SUM(
IF(
(
SELECT TRUE
FROM atencao_basica_atendimento_individual abai
INNER JOIN sigtap.ocupacao o ON o.id = abai.usuario_ocupacao_id
WHERE abai.paciente_id = paciente.id
AND abai.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abai.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 6 MONTH)
AND abai.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND abai.pressao_arterial IS NOT NULL
AND (
o.codigo = '515105' OR
o.codigo LIKE '2231%' OR
o.codigo LIKE '2235%' OR
o.codigo LIKE '2251%' OR
o.codigo LIKE '2252%' OR
o.codigo LIKE '2253%' OR
o.codigo LIKE '3222%'
)
LIMIT 1
) OR (
SELECT TRUE
FROM atencao_basica_procedimento_atendimento_procedimento abpap
INNER JOIN atencao_basica_procedimento_atendimento abpa ON abpa.id = abpap.procedimento_atendimento_id
INNER JOIN atencao_basica_procedimento abp ON abp.id = abpa.procedimento_id
INNER JOIN sigtap.ocupacao o ON o.id = abp.ocupacao_id
INNER JOIN sigtap.procedimento p ON p.id = abpap.procedimento_id
WHERE abpa.paciente_id = paciente.id
AND abp.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abp.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 6 MONTH)
AND abp.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND p.codigo = '" . Procedimento::AFERICAO_PRESSAO_ARTERIAL . "'
AND (
o.codigo = '515105' OR
o.codigo LIKE '2231%' OR
o.codigo LIKE '2235%' OR
o.codigo LIKE '2251%' OR
o.codigo LIKE '2252%' OR
o.codigo LIKE '2253%' OR
o.codigo LIKE '3222%'
)
LIMIT 1
) OR (
SELECT TRUE
FROM atencao_basica_visita_domiciliar abvd
INNER JOIN sigtap.ocupacao o ON o.id = abvd.usuario_ocupacao_id
WHERE abvd.paciente_id = paciente.id
AND abvd.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abvd.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 6 MONTH)
AND abvd.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND abvd.afericao_pa IS NOT NULL
AND (
o.codigo = '515105' OR
o.codigo LIKE '2231%' OR
o.codigo LIKE '2235%' OR
o.codigo LIKE '2251%' OR
o.codigo LIKE '2252%' OR
o.codigo LIKE '2253%' OR
o.codigo LIKE '3222%'
)
LIMIT 1
),
1,
0
)
) AS quantidade_boa_pratica_b
"),
DB::raw("
SUM(
IF(
(
SELECT TRUE
FROM atencao_basica_atendimento_individual abai
INNER JOIN sigtap.ocupacao o ON o.id = abai.usuario_ocupacao_id
WHERE abai.paciente_id = paciente.id
AND abai.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abai.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 12 MONTH)
AND abai.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND abai.peso IS NOT NULL
AND abai.altura IS NOT NULL
AND (
o.codigo = '515105' OR
o.codigo LIKE '2231%' OR
o.codigo LIKE '2235%' OR
o.codigo LIKE '2251%' OR
o.codigo LIKE '2252%' OR
o.codigo LIKE '2253%' OR
o.codigo LIKE '3222%'
)
LIMIT 1
) OR (
SELECT TRUE
FROM atencao_basica_procedimento_atendimento abpa
INNER JOIN atencao_basica_procedimento abp ON abp.id = abpa.procedimento_id
INNER JOIN sigtap.ocupacao o ON o.id = abp.ocupacao_id
WHERE abpa.paciente_id = paciente.id
AND abp.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abp.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 12 MONTH)
AND abp.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND (
EXISTS (
SELECT 1
FROM atencao_basica_procedimento_atendimento_procedimento abpap
INNER JOIN sigtap.procedimento sp ON sp.id = abpap.procedimento_id
WHERE abpap.procedimento_atendimento_id = abpa.id
AND sp.codigo = " . Procedimento::AVALIACAO_ANTROPOMETRICA . "
)
OR (
EXISTS (
SELECT 1
FROM atencao_basica_procedimento_atendimento_procedimento abpap
INNER JOIN sigtap.procedimento sp ON sp.id = abpap.procedimento_id
WHERE abpap.procedimento_atendimento_id = abpa.id
AND sp.codigo = " . Procedimento::MEDICAO_DE_ALTURA . "
) AND EXISTS (
SELECT 1
FROM atencao_basica_procedimento_atendimento_procedimento abpap
INNER JOIN sigtap.procedimento sp ON sp.id = abpap.procedimento_id
WHERE abpap.procedimento_atendimento_id = abpa.id
AND sp.codigo = " . Procedimento::MEDICAO_DE_PESO . "
)
)
)
AND (
o.codigo = '515105' OR
o.codigo LIKE '2231%' OR
o.codigo LIKE '2235%' OR
o.codigo LIKE '2251%' OR
o.codigo LIKE '2252%' OR
o.codigo LIKE '2253%' OR
o.codigo LIKE '3222%'
)
LIMIT 1
) OR (
SELECT TRUE
FROM atencao_basica_atividade_coletiva_participante abacp
INNER JOIN atencao_basica_atividade_coletiva abac ON abac.id = abacp.atividade_coletiva_id
INNER JOIN sigtap.ocupacao o ON o.id = abac.usuario_ocupacao_id
WHERE abacp.paciente_id = paciente.id
AND abac.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abac.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 12 MONTH)
AND abac.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND abacp.peso IS NOT NULL
AND abacp.altura IS NOT NULL
AND (
o.codigo = '515105' OR
o.codigo LIKE '2231%' OR
o.codigo LIKE '2235%' OR
o.codigo LIKE '2251%' OR
o.codigo LIKE '2252%' OR
o.codigo LIKE '2253%' OR
o.codigo LIKE '3222%'
)
LIMIT 1
) OR (
SELECT TRUE
FROM atencao_basica_visita_domiciliar abvd
INNER JOIN sigtap.ocupacao o ON o.id = abvd.usuario_ocupacao_id
WHERE abvd.paciente_id = paciente.id
AND abvd.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abvd.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 12 MONTH)
AND abvd.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND abvd.peso IS NOT NULL
AND abvd.altura IS NOT NULL
AND (
o.codigo = '515105' OR
o.codigo LIKE '2231%' OR
o.codigo LIKE '2235%' OR
o.codigo LIKE '2251%' OR
o.codigo LIKE '2252%' OR
o.codigo LIKE '2253%' OR
o.codigo LIKE '3222%'
)
LIMIT 1
),
1,
0
)
) AS quantidade_boa_pratica_c
"),
DB::raw("
SUM(
IF(
(
SELECT COUNT(*) >= 2 AND TIMESTAMPDIFF (
DAY,
MIN(abvd.data_usuario_responsavel),
MAX(abvd.data_usuario_responsavel)
) >= 30
FROM atencao_basica_visita_domiciliar abvd
INNER JOIN atencao_basica_parametrizacao_equipe abpe ON abpe.id = abvd.equipe_id
INNER JOIN atencao_basica_parametrizacao_area abpa ON abpa.id = abpe.area_id
INNER JOIN sigtap.ocupacao o ON o.id = abvd.usuario_ocupacao_id
WHERE abvd.paciente_id = paciente.id
AND abpa.tipo_id = " . AreaTipo::EQUIPE_DE_SAUDE_DA_FAMILIA . "
AND abvd.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abvd.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 12 MONTH)
AND abvd.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND (
o.codigo = '322255' OR
o.codigo = '515105'
)
),
1,
0
)
) AS quantidade_boa_pratica_d
")
])
->whereIn('area.tipo_id', self::getTiposEquipes())
->where(fn ($q) => $q
->where(fn ($q) => $q
->whereNull('cadastro_individual.saida_cidadao_id')
->orWhere('cadastro_individual.saida_cidadao_id', '<>', SaidaCidadao::MUDANCA_DE_TERRITORIO)
)
->orWhere(fn ($q) => $q
->where('cadastro_individual.saida_cidadao_id', SaidaCidadao::MUDANCA_DE_TERRITORIO)
->where('cadastro_individual.motivo_saida_data', '>', $params->periodo['end']->format('Y-m-d'))
)
)
->where(fn ($q) => $q
->whereNull('obito.obito_em')
->orWhere('obito.obito_em', '>', $params->periodo['end']->format('Y-m-d H:i:s'))
)
->when($params->unidade_id, fn ($q, $id) => $q->where('equipe.unidade_id', $id))
->when($params->equipe_id, fn ($q, $id) => $q->where('cadastro_individual.equipe_id', $id))
->when($params->sexo_id, fn ($q, $id) => $q->where('cidadao.sexo_id', $id))
->when(!is_null($params->idade_minima), fn ($q) => $q
->whereRaw("TIMESTAMPDIFF(YEAR, cidadao.data_nascimento, CURRENT_DATE) >= ?", [$params->idade_minima]))
->when(!is_null($params->idade_maxima), fn ($q) => $q
->whereRaw("TIMESTAMPDIFF(YEAR, cidadao.data_nascimento, CURRENT_DATE) <= ?", [$params->idade_maxima]))
->when($params->paciente_id, fn ($q, $id) => $q->where('cadastro_individual.paciente_id', $id))
->when(!$params->fora_area, fn ($q) => $q
->whereNotNull('cadastro_domiciliar.id')
->where(fn ($sub) => $sub
->whereNull('cadastro_domiciliar.fora_area')
->orWhere('cadastro_domiciliar.fora_area', 0)
))
->groupBy(
'unidade.nome_fantasia',
'microarea.id',
'equipe_descricao'
);
self::setOrderByEquipe($equipesBuilder);
$equipes = $equipesBuilder->get();
$pacientesIds = [];
$microareasIds = [];
$equipes->each(function ($equipe) use (&$pacientesIds, &$microareasIds, $params) {
$equipe->numerador = 0;
$pontuacao = 0;
if (in_array('A', $params->boas_praticas)) {
$equipe->numerador += $equipe->quantidade_boa_pratica_a * 25;
$equipe->boa_pratica_a = self::round(($equipe->quantidade_boa_pratica_a / $equipe->denominador) * 100);
if ($equipe->quantidade_boa_pratica_a > 0) {
$pontuacao += 25;
}
}
if (in_array('B', $params->boas_praticas)) {
$equipe->numerador += $equipe->quantidade_boa_pratica_b * 25;
$equipe->boa_pratica_b = self::round(($equipe->quantidade_boa_pratica_b / $equipe->denominador) * 100);
if ($equipe->quantidade_boa_pratica_b > 0) {
$pontuacao += 25;
}
}
if (in_array('C', $params->boas_praticas)) {
$equipe->numerador += $equipe->quantidade_boa_pratica_c * 25;
$equipe->boa_pratica_c = self::round(($equipe->quantidade_boa_pratica_c / $equipe->denominador) * 100);
if ($equipe->quantidade_boa_pratica_c > 0) {
$pontuacao += 25;
}
}
if (in_array('D', $params->boas_praticas)) {
$equipe->numerador += $equipe->quantidade_boa_pratica_d * 25;
$equipe->boa_pratica_d = self::round(($equipe->quantidade_boa_pratica_d / $equipe->denominador) * 100);
if ($equipe->quantidade_boa_pratica_d > 0) {
$pontuacao += 25;
}
}
$equipe->resultado = self::round(($equipe->numerador / ($equipe->denominador * 100)) * 100);
$classificacao = self::getClassificacao($pontuacao);
$equipe->classificacao_resultado_ordenacao = $classificacao['ordenacao'];
$equipe->classificacao_resultado = $classificacao['texto'];
$pacientesIds = array_merge($pacientesIds, explode('#', $equipe->pacientes));
if (!is_null($equipe->microarea_id)) {
$microareasIds[] = $equipe->microarea_id;
}
unset($equipe->pacientes, $equipe->microarea_id);
});
$columnsSortBy = collect([
'numerador',
'resultado',
'classificacao_resultado',
'boa_pratica_a',
'boa_pratica_b',
'boa_pratica_c',
'boa_pratica_d',
]);
if ($columnsSortBy->contains(request()->equipe_sort_by)) {
$sortBy = request()->equipe_sort_by === 'classificacao_resultado'
? 'classificacao_resultado_ordenacao'
: request()->equipe_sort_by;
$equipes = (DataUtil::getBooleanValueFromStringBoolean(request()->equipe_sort_desc)
? $equipes->sortByDesc($sortBy)
: $equipes->sortBy($sortBy)
)->values();
}
$denominador = $totalPacientes = collect($pacientesIds)->unique()->count();
$totalEquipes = $equipes->count();
$totalMicroareas = collect($microareasIds)->unique()->count();
$numerador = $equipes->sum('numerador');
$resultado = 0;
$boaPraticaA = 0;
$boaPraticaB = 0;
$boaPraticaC = 0;
$boaPraticaD = 0;
if ($denominador > 0) {
$resultado = self::round(($numerador / ($denominador * 100)) * 100);
if (in_array('A', $params->boas_praticas)) {
$boaPraticaA = self::round(($equipes->sum('quantidade_boa_pratica_a') / $denominador) * 100);
}
if (in_array('B', $params->boas_praticas)) {
$boaPraticaB = self::round(($equipes->sum('quantidade_boa_pratica_b') / $denominador) * 100);
}
if (in_array('C', $params->boas_praticas)) {
$boaPraticaC = self::round(($equipes->sum('quantidade_boa_pratica_c') / $denominador) * 100);
}
if (in_array('D', $params->boas_praticas)) {
$boaPraticaD = self::round(($equipes->sum('quantidade_boa_pratica_d') / $denominador) * 100);
}
}
return (object) [
'equipes' => $equipes,
'totalizadores' => (object) [
'total_pacientes' => $totalPacientes,
'total_equipes' => $totalEquipes,
'total_microareas' => $totalMicroareas,
'denominador' => $denominador,
'numerador' => $numerador,
'resultado' => $resultado,
'boa_pratica_a' => $boaPraticaA,
'boa_pratica_b' => $boaPraticaB,
'boa_pratica_c' => $boaPraticaC,
'boa_pratica_d' => $boaPraticaD,
],
];
}
private static function getClassificacao($pontuacao)
{
if ($pontuacao > 75 && $pontuacao <= 100) {
return ['ordenacao' => 'otimo', 'texto' => 'Ótimo'];
}
else if ($pontuacao > 50 && $pontuacao <= 75) {
return ['ordenacao' => 'bom', 'texto' => 'Bom'];
}
else if ($pontuacao > 25 && $pontuacao <= 50) {
return ['ordenacao' => 'suficiente', 'texto' => 'Suficiente'];
}
return ['ordenacao' => 'regular', 'texto' => 'Regular'];
}
private static function setOrderByEquipe($builder)
{
$columns = [
'unidade_nome_fantasia' => 'unidade.nome_fantasia',
'equipe_descricao' => 'equipe_descricao',
'denominador' => 'denominador',
];
if (is_null(request()->equipe_sort_by) || !isset($columns[request()->equipe_sort_by])) {
$builder->orderByRaw(join(', ', $columns));
return;
}
$column = $columns[request()->equipe_sort_by];
$direction = DataUtil::getBooleanValueFromStringBoolean(request()->equipe_sort_desc) ? 'DESC' : 'ASC';
unset($columns[request()->equipe_sort_by]);
$builder->orderByRaw("{$column} {$direction}, " . join(', ', $columns));
}
private static function getResultadoPorPacientes($params)
{
$pacientesBuilder = DB::table('cadastro_paciente as paciente')
->join('cadastro_cidadao as cidadao', 'cidadao.id', 'paciente.cidadao_id')
->join('atencao_basica_cadastro_individual AS cadastro_individual', 'cadastro_individual.paciente_id', 'paciente.id')
->join('atencao_basica_parametrizacao_equipe AS equipe', 'equipe.id', 'cadastro_individual.equipe_id')
->join('atencao_basica_parametrizacao_area AS area', 'area.id', 'equipe.area_id')
->join('cadastro_unidade AS unidade', 'unidade.id', 'equipe.unidade_id')
->join('atencao_basica_atendimento_individual AS atendimento_individual', fn ($q) => $q
->on('atendimento_individual.paciente_id', 'paciente.id')
->where('atendimento_individual.id', fn ($q) => $q
->select('atendimento_individual2.id')
->from('atencao_basica_atendimento_individual AS atendimento_individual2')
->whereColumn('atendimento_individual2.paciente_id', 'paciente.id')
->where(fn ($q) => $q
->whereExists(fn ($q) => $q
->selectRaw(1)
->from('atencao_basica_atendimento_individual_problema_condicao AS problema_condicao')
->leftJoin('geral_ciap AS ciap', 'ciap.id', 'problema_condicao.ciap_id')
->leftJoin('sigtap.cid AS cid', 'cid.id', 'problema_condicao.cid_id')
->whereColumn('problema_condicao.atendimento_individual_id', 'atendimento_individual2.id')
->where(fn ($q) => $q
->whereIn('ciap.codigo', self::getCiapsHipertensao())
->orWhereIn('cid.codigo', self::getCidsHipertensao())
)
)
->orWhereExists(fn ($q) => $q
->selectRaw(1)
->from('atencao_basica_atendimento_individual_condicao_avaliada AS atendimento_individual_condicao_avaliada')
->whereColumn('atendimento_individual_condicao_avaliada.atendimento_individual_id', 'atendimento_individual2.id')
->where('atendimento_individual_condicao_avaliada.condicao_avaliada_id', CondicaoAvaliada::HIPERTENSAO_ARTERIAL)
)
)
->where('atendimento_individual2.data_usuario_responsavel', '<=', $params->periodo['end']->format('Y-m-d'))
->orderBy('atendimento_individual2.data_usuario_responsavel')
->limit(1)
)
)
->leftJoin('atencao_basica_parametrizacao_microarea AS microarea', 'microarea.id', 'equipe.microarea_id')
->leftJoin('cadastro_sexo AS sexo', 'sexo.id', 'cidadao.sexo_id')
->leftJoin('cadastro_cidadao_telefone AS telefone', fn ($j) => $j
->on('telefone.cidadao_id', 'cidadao.id')
->where('telefone.id', fn ($q) => $q
->select('telefone2.id')
->from('cadastro_cidadao_telefone AS telefone2')
->whereColumn('telefone2.cidadao_id', 'cidadao.id')
->where('telefone2.principal', true)
->limit(1)
)
)
->leftJoin('cadastro_domicilio AS domicilio', 'domicilio.id', 'cidadao.domicilio_id')
->leftJoin('cadastro_endereco AS endereco', 'endereco.id', '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('cadastro_bairro AS bairro', 'bairro.id', 'logradouro.bairro_id')
->leftJoin('intranet.cadastro_municipio AS municipio', 'municipio.id', 'logradouro.municipio_id')
->leftJoin('intranet.cadastro_estado AS estado', 'estado.id', 'municipio.estado_id')
->leftJoin('cadastro_paciente_responsavel AS paciente_responsavel', 'paciente_responsavel.paciente_id', 'paciente.id')
->leftJoin('cadastro_usuario AS usuario_responsavel', 'usuario_responsavel.id', 'paciente_responsavel.responsavel_usuario_id')
->leftJoin('cadastro_cidadao AS cidadao_responsavel', 'cidadao_responsavel.id', 'usuario_responsavel.cidadao_id')
->leftJoin('atencao_basica_cadastro_domiciliar AS cadastro_domiciliar', 'cadastro_domiciliar.domicilio_id', 'domicilio.id')
->leftJoin('atencao_basica_parametrizacao_microarea AS cadastro_domiciliar_microarea', 'cadastro_domiciliar_microarea.id', 'cadastro_domiciliar.microarea_id')
->leftJoin('atencao_basica_parametrizacao_area AS cadastro_domiciliar_area', 'cadastro_domiciliar_area.id', 'cadastro_domiciliar_microarea.area_id')
->leftJoin('cadastro_obito AS obito', fn ($j) => $j
->on('obito.cidadao_id', 'cidadao.id')
->whereNull('obito.deleted_at')
)
->select([
'unidade.nome_fantasia AS unidade_nome_fantasia',
DB::raw("CONCAT(
CASE
WHEN area.numero_ine IS NOT NULL THEN CONCAT('INE: ', area.numero_ine)
ELSE ''
END,
CASE
WHEN area.descricao IS NOT NULL AND area.numero_ine IS NOT NULL THEN ' - Área: '
WHEN area.descricao IS NOT NULL THEN 'Área: '
ELSE ''
END,
COALESCE(area.descricao, ''),
CASE
WHEN microarea.descricao IS NOT NULL
AND (area.numero_ine IS NOT NULL OR area.descricao IS NOT NULL) THEN ' - Microárea: '
WHEN microarea.descricao IS NOT NULL THEN 'Microárea: '
ELSE ''
END,
COALESCE(microarea.descricao, '')
) AS equipe_descricao"),
'cidadao.nome AS paciente_nome',
'sexo.descricao AS sexo_descricao',
DB::raw("CONCAT(
CASE
WHEN cadastro_domiciliar_area.numero_ine IS NOT NULL THEN CONCAT('INE: ', cadastro_domiciliar_area.numero_ine)
ELSE ''
END,
CASE
WHEN cadastro_domiciliar_area.descricao IS NOT NULL AND cadastro_domiciliar_area.numero_ine IS NOT NULL THEN ' - Área: '
WHEN cadastro_domiciliar_area.descricao IS NOT NULL THEN 'Área: '
ELSE ''
END,
COALESCE(cadastro_domiciliar_area.descricao, ''),
CASE
WHEN cadastro_domiciliar_microarea.descricao IS NOT NULL
AND (cadastro_domiciliar_area.numero_ine IS NOT NULL OR cadastro_domiciliar_area.descricao IS NOT NULL) THEN ' - Microárea: '
WHEN cadastro_domiciliar_microarea.descricao IS NOT NULL THEN 'Microárea: '
ELSE ''
END,
COALESCE(cadastro_domiciliar_microarea.descricao, '')
) AS microarea_descricao"),
DB::raw("
CASE
WHEN cadastro_domiciliar_area.numero_ine IS NULL
AND cadastro_domiciliar_area.descricao IS NULL
AND cadastro_domiciliar_microarea.descricao IS NULL THEN 'Não informada'
ELSE CONCAT(
CASE
WHEN cadastro_domiciliar_area.numero_ine IS NOT NULL THEN CONCAT('INE: ', cadastro_domiciliar_area.numero_ine)
ELSE ''
END,
CASE
WHEN cadastro_domiciliar_area.descricao IS NOT NULL AND cadastro_domiciliar_area.numero_ine IS NOT NULL THEN ' - Área: '
WHEN cadastro_domiciliar_area.descricao IS NOT NULL THEN 'Área: '
ELSE ''
END,
COALESCE(cadastro_domiciliar_area.descricao, ''),
CASE
WHEN cadastro_domiciliar_microarea.descricao IS NOT NULL
AND (cadastro_domiciliar_area.numero_ine IS NOT NULL OR cadastro_domiciliar_area.descricao IS NOT NULL) THEN ' - Microárea: '
WHEN cadastro_domiciliar_microarea.descricao IS NOT NULL THEN 'Microárea: '
ELSE ''
END,
COALESCE(cadastro_domiciliar_microarea.descricao, '')
)
END AS area_microarea_domicilio
"),
'cidadao_responsavel.nome AS usuario_cadastro_nome',
'cidadao.data_nascimento',
'telefone.numero AS telefone_principal',
DB::raw("CONCAT(
logradouro_tipo.descricao,
' ',
logradouro.nome,
', ',
IF(endereco.numero IS NULL, 'S/N', endereco.numero),
' - ',
bairro.nome,
', ',
municipio.nome,
' - ',
estado.uf
) AS endereco"),
'area.tipo_id AS area_tipo_id',
DB::raw("
IF(
(
SELECT TRUE
FROM atencao_basica_atendimento_individual abai
INNER JOIN sigtap.ocupacao o ON o.id = abai.usuario_ocupacao_id
WHERE abai.paciente_id = paciente.id
AND abai.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abai.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 6 MONTH)
AND abai.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND (
o.codigo LIKE '2231%' OR
o.codigo LIKE '2235%' OR
o.codigo LIKE '2251%' OR
o.codigo LIKE '2252%' OR
o.codigo LIKE '2253%'
)
LIMIT 1
),
1,
0
) AS boa_pratica_a
"),
DB::raw("
IF(
(
SELECT TRUE
FROM atencao_basica_atendimento_individual abai
INNER JOIN sigtap.ocupacao o ON o.id = abai.usuario_ocupacao_id
WHERE abai.paciente_id = paciente.id
AND abai.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abai.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 6 MONTH)
AND abai.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND abai.pressao_arterial IS NOT NULL
AND (
o.codigo = '515105' OR
o.codigo LIKE '2231%' OR
o.codigo LIKE '2235%' OR
o.codigo LIKE '2251%' OR
o.codigo LIKE '2252%' OR
o.codigo LIKE '2253%' OR
o.codigo LIKE '3222%'
)
LIMIT 1
) OR (
SELECT TRUE
FROM atencao_basica_procedimento_atendimento_procedimento abpap
INNER JOIN atencao_basica_procedimento_atendimento abpa ON abpa.id = abpap.procedimento_atendimento_id
INNER JOIN atencao_basica_procedimento abp ON abp.id = abpa.procedimento_id
INNER JOIN sigtap.ocupacao o ON o.id = abp.ocupacao_id
INNER JOIN sigtap.procedimento p ON p.id = abpap.procedimento_id
WHERE abpa.paciente_id = paciente.id
AND abp.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abp.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 6 MONTH)
AND abp.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND p.codigo = '" . Procedimento::AFERICAO_PRESSAO_ARTERIAL . "'
AND (
o.codigo = '515105' OR
o.codigo LIKE '2231%' OR
o.codigo LIKE '2235%' OR
o.codigo LIKE '2251%' OR
o.codigo LIKE '2252%' OR
o.codigo LIKE '2253%' OR
o.codigo LIKE '3222%'
)
LIMIT 1
) OR (
SELECT TRUE
FROM atencao_basica_visita_domiciliar abvd
INNER JOIN sigtap.ocupacao o ON o.id = abvd.usuario_ocupacao_id
WHERE abvd.paciente_id = paciente.id
AND abvd.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abvd.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 6 MONTH)
AND abvd.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND abvd.afericao_pa IS NOT NULL
AND (
o.codigo = '515105' OR
o.codigo LIKE '2231%' OR
o.codigo LIKE '2235%' OR
o.codigo LIKE '2251%' OR
o.codigo LIKE '2252%' OR
o.codigo LIKE '2253%' OR
o.codigo LIKE '3222%'
)
LIMIT 1
),
1,
0
) AS boa_pratica_b
"),
DB::raw("
IF(
(
SELECT TRUE
FROM atencao_basica_atendimento_individual abai
INNER JOIN sigtap.ocupacao o ON o.id = abai.usuario_ocupacao_id
WHERE abai.paciente_id = paciente.id
AND abai.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abai.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 12 MONTH)
AND abai.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND abai.peso IS NOT NULL
AND abai.altura IS NOT NULL
AND (
o.codigo = '515105' OR
o.codigo LIKE '2231%' OR
o.codigo LIKE '2235%' OR
o.codigo LIKE '2251%' OR
o.codigo LIKE '2252%' OR
o.codigo LIKE '2253%' OR
o.codigo LIKE '3222%'
)
LIMIT 1
) OR (
SELECT TRUE
FROM atencao_basica_procedimento_atendimento abpa
INNER JOIN atencao_basica_procedimento abp ON abp.id = abpa.procedimento_id
INNER JOIN sigtap.ocupacao o ON o.id = abp.ocupacao_id
WHERE abpa.paciente_id = paciente.id
AND abp.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abp.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 12 MONTH)
AND abp.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND (
EXISTS (
SELECT 1
FROM atencao_basica_procedimento_atendimento_procedimento abpap
INNER JOIN sigtap.procedimento sp ON sp.id = abpap.procedimento_id
WHERE abpap.procedimento_atendimento_id = abpa.id
AND sp.codigo = " . Procedimento::AVALIACAO_ANTROPOMETRICA . "
)
OR (
EXISTS (
SELECT 1
FROM atencao_basica_procedimento_atendimento_procedimento abpap
INNER JOIN sigtap.procedimento sp ON sp.id = abpap.procedimento_id
WHERE abpap.procedimento_atendimento_id = abpa.id
AND sp.codigo = " . Procedimento::MEDICAO_DE_ALTURA . "
) AND EXISTS (
SELECT 1
FROM atencao_basica_procedimento_atendimento_procedimento abpap
INNER JOIN sigtap.procedimento sp ON sp.id = abpap.procedimento_id
WHERE abpap.procedimento_atendimento_id = abpa.id
AND sp.codigo = " . Procedimento::MEDICAO_DE_PESO . "
)
)
)
AND (
o.codigo = '515105' OR
o.codigo LIKE '2231%' OR
o.codigo LIKE '2235%' OR
o.codigo LIKE '2251%' OR
o.codigo LIKE '2252%' OR
o.codigo LIKE '2253%' OR
o.codigo LIKE '3222%'
)
LIMIT 1
) OR (
SELECT TRUE
FROM atencao_basica_atividade_coletiva_participante abacp
INNER JOIN atencao_basica_atividade_coletiva abac ON abac.id = abacp.atividade_coletiva_id
INNER JOIN sigtap.ocupacao o ON o.id = abac.usuario_ocupacao_id
WHERE abacp.paciente_id = paciente.id
AND abac.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abac.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 12 MONTH)
AND abac.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND abacp.peso IS NOT NULL
AND abacp.altura IS NOT NULL
AND (
o.codigo = '515105' OR
o.codigo LIKE '2231%' OR
o.codigo LIKE '2235%' OR
o.codigo LIKE '2251%' OR
o.codigo LIKE '2252%' OR
o.codigo LIKE '2253%' OR
o.codigo LIKE '3222%'
)
LIMIT 1
) OR (
SELECT TRUE
FROM atencao_basica_visita_domiciliar abvd
INNER JOIN sigtap.ocupacao o ON o.id = abvd.usuario_ocupacao_id
WHERE abvd.paciente_id = paciente.id
AND abvd.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abvd.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 12 MONTH)
AND abvd.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND abvd.peso IS NOT NULL
AND abvd.altura IS NOT NULL
AND (
o.codigo = '515105' OR
o.codigo LIKE '2231%' OR
o.codigo LIKE '2235%' OR
o.codigo LIKE '2251%' OR
o.codigo LIKE '2252%' OR
o.codigo LIKE '2253%' OR
o.codigo LIKE '3222%'
)
LIMIT 1
),
1,
0
) AS boa_pratica_c
"),
DB::raw("
IF(
(
SELECT COUNT(*) >= 2 AND TIMESTAMPDIFF (
DAY,
MIN(abvd.data_usuario_responsavel),
MAX(abvd.data_usuario_responsavel)
) >= 30
FROM atencao_basica_visita_domiciliar abvd
INNER JOIN atencao_basica_parametrizacao_equipe abpe ON abpe.id = abvd.equipe_id
INNER JOIN atencao_basica_parametrizacao_area abpa ON abpa.id = abpe.area_id
INNER JOIN sigtap.ocupacao o ON o.id = abvd.usuario_ocupacao_id
WHERE abvd.paciente_id = paciente.id
AND abpa.tipo_id = " . AreaTipo::EQUIPE_DE_SAUDE_DA_FAMILIA . "
AND abvd.data_usuario_responsavel >= atendimento_individual.data_usuario_responsavel
AND abvd.data_usuario_responsavel >= DATE_SUB('" . $params->periodo['end']->format('Y-m-d') . "', INTERVAL 12 MONTH)
AND abvd.data_usuario_responsavel <= '" . $params->periodo['end']->format('Y-m-d') . "'
AND (
o.codigo = '322255' OR
o.codigo = '515105'
)
),
1,
0
) AS boa_pratica_d
"),
])
->whereIn('area.tipo_id', self::getTiposEquipes())
->where(fn ($q) => $q
->where(fn ($q) => $q
->whereNull('cadastro_individual.saida_cidadao_id')
->orWhere('cadastro_individual.saida_cidadao_id', '<>', SaidaCidadao::MUDANCA_DE_TERRITORIO)
)
->orWhere(fn ($q) => $q
->where('cadastro_individual.saida_cidadao_id', SaidaCidadao::MUDANCA_DE_TERRITORIO)
->where('cadastro_individual.motivo_saida_data', '>', $params->periodo['end']->format('Y-m-d'))
)
)
->where(fn ($q) => $q
->whereNull('obito.obito_em')
->orWhere('obito.obito_em', '>', $params->periodo['end']->format('Y-m-d H:i:s'))
)
->when($params->unidade_id, fn ($q, $id) => $q->where('equipe.unidade_id', $id))
->when($params->equipe_id, fn ($q, $id) => $q->where('cadastro_individual.equipe_id', $id))
->when($params->sexo_id, fn ($q, $id) => $q->where('cidadao.sexo_id', $id))
->when(!is_null($params->idade_minima), fn ($q) => $q
->whereRaw("TIMESTAMPDIFF(YEAR, cidadao.data_nascimento, CURRENT_DATE) >= ?", [$params->idade_minima]))
->when(!is_null($params->idade_maxima), fn ($q) => $q
->whereRaw("TIMESTAMPDIFF(YEAR, cidadao.data_nascimento, CURRENT_DATE) <= ?", [$params->idade_maxima]))
->when($params->paciente_id, fn ($q, $id) => $q->where('cadastro_individual.paciente_id', $id))
->when(!$params->fora_area, fn ($q) => $q
->whereNotNull('cadastro_domiciliar.id')
->where(fn ($sub) => $sub
->whereNull('cadastro_domiciliar.fora_area')
->orWhere('cadastro_domiciliar.fora_area', 0)
))
->groupBy('cadastro_individual.id');
self::setOrderByPaciente($pacientesBuilder);
$pacientes = $pacientesBuilder->get();
$pacientes->each(function ($paciente) use ($params) {
$paciente->idade = $paciente->data_nascimento
? AgeService::getFormattedAge(Carbon::create($paciente->data_nascimento)->toDate())
: null;
if ($paciente->telefone_principal) {
$paciente->telefone_principal = MaskUtil::getPhoneMasked($paciente->telefone_principal);
}
$paciente->boa_pratica_a = (bool) $paciente->boa_pratica_a;
$paciente->boa_pratica_b = (bool) $paciente->boa_pratica_b;
$paciente->boa_pratica_c = (bool) $paciente->boa_pratica_c;
$paciente->boa_pratica_d = (bool) $paciente->boa_pratica_d;
$paciente->pontuacao_total = 0;
if (in_array('A', $params->boas_praticas) && $paciente->boa_pratica_a) $paciente->pontuacao_total += 25;
if (in_array('B', $params->boas_praticas) && $paciente->boa_pratica_b) $paciente->pontuacao_total += 25;
if (in_array('C', $params->boas_praticas) && $paciente->boa_pratica_c) $paciente->pontuacao_total += 25;
if (in_array('D', $params->boas_praticas) && $paciente->boa_pratica_d) $paciente->pontuacao_total += 25;
$paciente->is_equipe_eap = $paciente->area_tipo_id === AreaTipo::EQUIPE_DE_ATENCAO_PRIMARIA;
if ($paciente->is_equipe_eap) {
$paciente->boa_pratica_d = true;
}
unset($paciente->area_tipo_id);
});
$pacientes = $pacientes->filter(function ($paciente) use ($params) {
foreach ($params->boas_praticas as $boaPratica) {
if (!$paciente->{'boa_pratica_' . Str::lower($boaPratica)}) {
return true;
}
}
return false;
})->values();
$columnsSortBy = collect([
'pontuacao_total'
]);
if ($columnsSortBy->contains(request()->paciente_sort_by)) {
$pacientes = (DataUtil::getBooleanValueFromStringBoolean(request()->paciente_sort_desc)
? $pacientes->sortByDesc(request()->paciente_sort_by)
: $pacientes->sortBy(request()->paciente_sort_by)
)->values();
}
return $pacientes;
}
private static function setOrderByPaciente($builder)
{
$columns = [
'unidade_nome_fantasia' => 'unidade.nome_fantasia',
'equipe_descricao' => 'equipe_descricao',
'paciente_nome' => 'cidadao.nome',
'sexo_descricao' => 'sexo.descricao',
'idade' => 'cidadao.data_nascimento',
'microarea_descricao' => 'microarea_descricao',
'area_microarea_domicilio' => 'area_microarea_domicilio',
'usuario_cadastro_nome' => 'cidadao_responsavel.nome',
'data_nascimento' => 'cidadao.data_nascimento',
'telefone_principal' => 'telefone.numero',
'endereco' => 'endereco',
];
if (is_null(request()->paciente_sort_by) || !isset($columns[request()->paciente_sort_by])) {
$builder->orderByRaw(join(', ', $columns));
return;
}
$column = $columns[request()->paciente_sort_by];
$sortDesc = DataUtil::getBooleanValueFromStringBoolean(request()->paciente_sort_desc);
if (request()->paciente_sort_by === 'idade') {
$sortDesc = !$sortDesc;
}
$direction = $sortDesc ? 'DESC' : 'ASC';
unset($columns[request()->paciente_sort_by]);
$builder->orderByRaw("{$column} {$direction}, " . join(', ', $columns));
}
private static function round($value)
{
if (fmod($value, 1) === 0.0) {
return $value;
}
return round($value, 2);
}
public static function create()
{
$boasPraticas = self::getBoasPraticas();
return [
'additionals' => [
'data_atual' => Carbon::now()->format('d/m/Y'),
],
'form' => [
'quadrimestres_anos' => self::getQuadrimestres(),
'unidades' => [],
'equipes' => [],
'boas_praticas' => $boasPraticas,
'sexos' => [],
],
'model' => [
'periodo' => ['start' => null, 'end' => null],
'quadrimestre_ano' => null,
'quadrimestre' => null,
'unidade_id' => null,
'equipe_id' => null,
'boas_praticas' => $boasPraticas->pluck('value')->toArray(),
'busca_ativa' => false,
'sexo_id' => null,
'idade_minima' => null,
'idade_maxima' => null,
'paciente' => null,
'fora_area' => false,
],
];
}
public static function list()
{
$params = self::getParams();
switch (request()->listar) {
case 'unidades': {
return [
'unidades' => self::getUnidades($params),
'equipes' => self::getEquipes($params),
'sexos' => self::getSexos($params),
];
}
case 'equipes': {
return [
'equipes' => self::getEquipes($params),
'sexos' => self::getSexos($params),
];
}
case 'sexos': {
return [
'sexos' => self::getSexos($params),
];
}
}
}
private static function getParams()
{
$params = (object) [
'unidade_id' => request()->get('unidade_id'),
'equipe_id' => request()->get('equipe_id'),
'boas_praticas' => request()->get('boas_praticas', []),
'busca_ativa' => DataUtil::getBooleanValueFromStringBoolean(request()->get('busca_ativa', 'false')),
'sexo_id' => request()->get('sexo_id'),
'idade_minima' => request()->get('idade_minima'),
'idade_maxima' => request()->get('idade_maxima'),
'paciente_id' => request()->get('paciente_id'),
'fora_area' => DataUtil::getBooleanValueFromStringBoolean(request()->get('fora_area', 'false')),
];
if (is_null(request()->get('periodo'))) {
$ano = request()->get('quadrimestre_ano');
$quadrimestre = request()->get('quadrimestre');
if ($quadrimestre == 1) {
$mesInicial = 1;
$mesFinal = 4;
}
else if ($quadrimestre == 2) {
$mesInicial = 5;
$mesFinal = 8;
}
else {
$mesInicial = 9;
$mesFinal = 12;
}
$params->periodo = [
'start' => Carbon::create($ano, $mesInicial, 1)->setTime(0, 0, 0),
'end' => Carbon::create($ano, $mesFinal)->endOfMonth()->setTime(23, 59, 59)
];
}
else {
$params->periodo = [
'start' => Carbon::createFromFormat('d/m/Y', request()->get('periodo')['start'])->setTime(0, 0, 0),
'end' => Carbon::createFromFormat('d/m/Y', request()->get('periodo')['end'])->setTime(23, 59, 59)
];
}
return $params;
}
private static function getQuadrimestres()
{
$anos = collect();
$anoInicial = 2020;
$anoAtual = Carbon::now()->year;
$mesAtual = Carbon::now()->month;
$ano = $anoAtual;
while ($ano >= $anoInicial) {
for ($i = 1; $i <= 3; $i++) {
$meses = null;
if ($i === 1) {
$meses = 'Janeiro - Abril';
}
else if ($i === 2) {
$meses = 'Maio - Agosto';
}
else {
$meses = 'Setembro - Dezembro';
}
if ($ano === $anoAtual && (
($i === 2 && $mesAtual <= 4)
|| ($i === 3 && $mesAtual <= 8)
)) {
continue;
}
$anoQuadrimenstre = $anos->firstWhere('value', $ano);
if (is_null($anoQuadrimenstre)) {
$anoQuadrimenstre = (object) [
'value' => $ano,
'text' => $ano,
'quadrimestres' => collect(),
];
$anos->push($anoQuadrimenstre);
}
$anoQuadrimenstre->quadrimestres->push((object) [
'value' => $i,
'text' => "{$i}º ({$meses})"
]);
}
$ano--;
}
return $anos;
}
private static function getUnidades($params)
{
return DB::table('cadastro_unidade AS unidade')
->select([
'unidade.id',
'unidade.nome_fantasia',
])
->whereExists(fn ($q) => $q
->selectRaw(1)
->from('atencao_basica_cadastro_individual AS cadastro_individual')
->join('cadastro_paciente AS paciente', 'paciente.id', 'cadastro_individual.paciente_id')
->join('atencao_basica_parametrizacao_equipe AS equipe', 'equipe.id', 'cadastro_individual.equipe_id')
->join('atencao_basica_parametrizacao_area AS area', 'area.id', 'equipe.area_id')
->join('atencao_basica_atendimento_individual AS atendimento_individual', fn ($q) => $q
->on('atendimento_individual.paciente_id', 'paciente.id')
->where('atendimento_individual.id', fn ($q) => $q
->select('atendimento_individual2.id')
->from('atencao_basica_atendimento_individual AS atendimento_individual2')
->whereColumn('atendimento_individual2.paciente_id', 'paciente.id')
->where(fn ($q) => $q
->whereExists(fn ($q) => $q
->selectRaw(1)
->from('atencao_basica_atendimento_individual_problema_condicao AS problema_condicao')
->leftJoin('geral_ciap AS ciap', 'ciap.id', 'problema_condicao.ciap_id')
->leftJoin('sigtap.cid AS cid', 'cid.id', 'problema_condicao.cid_id')
->whereColumn('problema_condicao.atendimento_individual_id', 'atendimento_individual2.id')
->where(fn ($q) => $q
->whereIn('ciap.codigo', self::getCiapsHipertensao())
->orWhereIn('cid.codigo', self::getCidsHipertensao())
)
)
->orWhereExists(fn ($q) => $q
->selectRaw(1)
->from('atencao_basica_atendimento_individual_condicao_avaliada AS atendimento_individual_condicao_avaliada')
->whereColumn('atendimento_individual_condicao_avaliada.atendimento_individual_id', 'atendimento_individual2.id')
->where('atendimento_individual_condicao_avaliada.condicao_avaliada_id', CondicaoAvaliada::HIPERTENSAO_ARTERIAL)
)
)
->where('atendimento_individual2.data_usuario_responsavel', '<=', $params->periodo['end']->format('Y-m-d'))
->orderBy('atendimento_individual2.data_usuario_responsavel')
->limit(1)
)
)
->leftJoin('cadastro_obito AS obito', fn ($j) => $j
->on('obito.cidadao_id', 'paciente.cidadao_id')
->whereNull('obito.deleted_at')
)
->whereColumn('equipe.unidade_id', 'unidade.id')
->whereIn('area.tipo_id', self::getTiposEquipes())
->where(fn ($q) => $q
->where(fn ($q) => $q
->whereNull('cadastro_individual.saida_cidadao_id')
->orWhere('cadastro_individual.saida_cidadao_id', '<>', SaidaCidadao::MUDANCA_DE_TERRITORIO)
)
->orWhere(fn ($q) => $q
->where('cadastro_individual.saida_cidadao_id', SaidaCidadao::MUDANCA_DE_TERRITORIO)
->where('cadastro_individual.motivo_saida_data', '>', $params->periodo['end']->format('Y-m-d'))
)
)
->where(fn ($q) => $q
->whereNull('obito.obito_em')
->orWhere('obito.obito_em', '>', $params->periodo['end']->format('Y-m-d H:i:s'))
)
)
->orderBy('unidade.nome_fantasia')
->get();
}
private static function getEquipes($params)
{
return DB::table('atencao_basica_parametrizacao_equipe AS equipe')
->join('atencao_basica_parametrizacao_area AS area', 'area.id', 'equipe.area_id')
->leftJoin('atencao_basica_parametrizacao_microarea AS microarea', 'microarea.id', 'equipe.microarea_id')
->select([
'equipe.id AS id',
DB::raw("CONCAT(
CASE
WHEN area.numero_ine IS NOT NULL THEN CONCAT('INE: ', area.numero_ine)
ELSE ''
END,
CASE
WHEN area.descricao IS NOT NULL AND area.numero_ine IS NOT NULL THEN ' - Área: '
WHEN area.descricao IS NOT NULL THEN 'Área: '
ELSE ''
END,
COALESCE(area.descricao, ''),
CASE
WHEN microarea.descricao IS NOT NULL
AND (area.numero_ine IS NOT NULL OR area.descricao IS NOT NULL) THEN ' - Microárea: '
WHEN microarea.descricao IS NOT NULL THEN 'Microárea: '
ELSE ''
END,
COALESCE(microarea.descricao, '')
) AS descricao"),
])
->whereIn('area.tipo_id', self::getTiposEquipes())
->when($params->unidade_id, fn ($q, $id) => $q->where('equipe.unidade_id', $id))
->whereExists(fn ($q) => $q
->selectRaw(1)
->from('atencao_basica_cadastro_individual AS cadastro_individual')
->join('cadastro_paciente AS paciente', 'paciente.id', 'cadastro_individual.paciente_id')
->join('atencao_basica_atendimento_individual AS atendimento_individual', fn ($q) => $q
->on('atendimento_individual.paciente_id', 'paciente.id')
->where('atendimento_individual.id', fn ($q) => $q
->select('atendimento_individual2.id')
->from('atencao_basica_atendimento_individual AS atendimento_individual2')
->whereColumn('atendimento_individual2.paciente_id', 'paciente.id')
->where(fn ($q) => $q
->whereExists(fn ($q) => $q
->selectRaw(1)
->from('atencao_basica_atendimento_individual_problema_condicao AS problema_condicao')
->leftJoin('geral_ciap AS ciap', 'ciap.id', 'problema_condicao.ciap_id')
->leftJoin('sigtap.cid AS cid', 'cid.id', 'problema_condicao.cid_id')
->whereColumn('problema_condicao.atendimento_individual_id', 'atendimento_individual2.id')
->where(fn ($q) => $q
->whereIn('ciap.codigo', self::getCiapsHipertensao())
->orWhereIn('cid.codigo', self::getCidsHipertensao())
)
)
->orWhereExists(fn ($q) => $q
->selectRaw(1)
->from('atencao_basica_atendimento_individual_condicao_avaliada AS atendimento_individual_condicao_avaliada')
->whereColumn('atendimento_individual_condicao_avaliada.atendimento_individual_id', 'atendimento_individual2.id')
->where('atendimento_individual_condicao_avaliada.condicao_avaliada_id', CondicaoAvaliada::HIPERTENSAO_ARTERIAL)
)
)
->where('atendimento_individual2.data_usuario_responsavel', '<=', $params->periodo['end']->format('Y-m-d'))
->orderBy('atendimento_individual2.data_usuario_responsavel')
->limit(1)
)
)
->leftJoin('cadastro_obito AS obito', fn ($j) => $j
->on('obito.cidadao_id', 'paciente.cidadao_id')
->whereNull('obito.deleted_at')
)
->whereColumn('cadastro_individual.equipe_id', 'equipe.id')
->where(fn ($q) => $q
->where(fn ($q) => $q
->whereNull('cadastro_individual.saida_cidadao_id')
->orWhere('cadastro_individual.saida_cidadao_id', '<>', SaidaCidadao::MUDANCA_DE_TERRITORIO)
)
->orWhere(fn ($q) => $q
->where('cadastro_individual.saida_cidadao_id', SaidaCidadao::MUDANCA_DE_TERRITORIO)
->where('cadastro_individual.motivo_saida_data', '>', $params->periodo['end']->format('Y-m-d'))
)
)
->where(fn ($q) => $q
->whereNull('obito.obito_em')
->orWhere('obito.obito_em', '>', $params->periodo['end']->format('Y-m-d H:i:s'))
)
)
->orderBy('descricao')
->get();
}
private static function getBoasPraticas()
{
return collect([
(object) ['value' => 'A', 'text' => 'A - Consulta nos últimos 6 meses (Entender proposito do filtro de data)'],
(object) ['value' => 'B', 'text' => 'B - Pressão arterial nos últimos 6 meses'],
(object) ['value' => 'C', 'text' => 'C - Peso e altura nos últimos 12 meses'],
(object) ['value' => 'D', 'text' => 'D - 2 visitas domiciliares'],
]);
}
private static function getSexos($params)
{
return DB::table('cadastro_sexo AS sexo')
->select(
'sexo.id',
'sexo.descricao',
)
->whereExists(fn ($q) => $q
->selectRaw(1)
->from('atencao_basica_cadastro_individual AS cadastro_individual')
->join('cadastro_paciente AS paciente', 'paciente.id', 'cadastro_individual.paciente_id')
->join('cadastro_cidadao AS cidadao', 'cidadao.id', 'paciente.cidadao_id')
->join('atencao_basica_parametrizacao_equipe AS equipe', 'equipe.id', 'cadastro_individual.equipe_id')
->join('atencao_basica_parametrizacao_area AS area', 'area.id', 'equipe.area_id')
->join('atencao_basica_atendimento_individual AS atendimento_individual', fn ($q) => $q
->on('atendimento_individual.paciente_id', 'paciente.id')
->where('atendimento_individual.id', fn ($q) => $q
->select('atendimento_individual2.id')
->from('atencao_basica_atendimento_individual AS atendimento_individual2')
->whereColumn('atendimento_individual2.paciente_id', 'paciente.id')
->where(fn ($q) => $q
->whereExists(fn ($q) => $q
->selectRaw(1)
->from('atencao_basica_atendimento_individual_problema_condicao AS problema_condicao')
->leftJoin('geral_ciap AS ciap', 'ciap.id', 'problema_condicao.ciap_id')
->leftJoin('sigtap.cid AS cid', 'cid.id', 'problema_condicao.cid_id')
->whereColumn('problema_condicao.atendimento_individual_id', 'atendimento_individual2.id')
->where(fn ($q) => $q
->whereIn('ciap.codigo', self::getCiapsHipertensao())
->orWhereIn('cid.codigo', self::getCidsHipertensao())
)
)
->orWhereExists(fn ($q) => $q
->selectRaw(1)
->from('atencao_basica_atendimento_individual_condicao_avaliada AS atendimento_individual_condicao_avaliada')
->whereColumn('atendimento_individual_condicao_avaliada.atendimento_individual_id', 'atendimento_individual2.id')
->where('atendimento_individual_condicao_avaliada.condicao_avaliada_id', CondicaoAvaliada::HIPERTENSAO_ARTERIAL)
)
)
->where('atendimento_individual2.data_usuario_responsavel', '<=', $params->periodo['end']->format('Y-m-d'))
->orderBy('atendimento_individual2.data_usuario_responsavel')
->limit(1)
)
)
->leftJoin('cadastro_obito AS obito', fn ($j) => $j
->on('obito.cidadao_id', 'paciente.cidadao_id')
->whereNull('obito.deleted_at')
)
->whereColumn('cidadao.sexo_id', 'sexo.id')
->whereIn('area.tipo_id', self::getTiposEquipes())
->where(fn ($q) => $q
->where(fn ($q) => $q
->whereNull('cadastro_individual.saida_cidadao_id')
->orWhere('cadastro_individual.saida_cidadao_id', '<>', SaidaCidadao::MUDANCA_DE_TERRITORIO)
)
->orWhere(fn ($q) => $q
->where('cadastro_individual.saida_cidadao_id', SaidaCidadao::MUDANCA_DE_TERRITORIO)
->where('cadastro_individual.motivo_saida_data', '>', $params->periodo['end']->format('Y-m-d'))
)
)
->where(fn ($q) => $q
->whereNull('obito.obito_em')
->orWhere('obito.obito_em', '>', $params->periodo['end']->format('Y-m-d H:i:s'))
)
->when($params->unidade_id, fn ($q, $id) => $q->where('equipe.unidade_id', $id))
->when($params->equipe_id, fn ($q, $id) => $q->where('cadastro_individual.equipe_id', $id))
)
->orderBy('sexo.descricao')
->get();
}
public static function autocompletePaciente()
{
$params = self::getParams();
return DB::table('cadastro_paciente as paciente')
->join('cadastro_cidadao as cidadao', 'cidadao.id', 'paciente.cidadao_id')
->join('atencao_basica_cadastro_individual AS cadastro_individual', 'cadastro_individual.paciente_id', 'paciente.id')
->join('atencao_basica_parametrizacao_equipe AS equipe', 'equipe.id', 'cadastro_individual.equipe_id')
->join('atencao_basica_parametrizacao_area AS area', 'area.id', 'equipe.area_id')
->join('atencao_basica_atendimento_individual AS atendimento_individual', fn ($q) => $q
->on('atendimento_individual.paciente_id', 'paciente.id')
->where('atendimento_individual.id', fn ($q) => $q
->select('atendimento_individual2.id')
->from('atencao_basica_atendimento_individual AS atendimento_individual2')
->whereColumn('atendimento_individual2.paciente_id', 'paciente.id')
->where(fn ($q) => $q
->whereExists(fn ($q) => $q
->selectRaw(1)
->from('atencao_basica_atendimento_individual_problema_condicao AS problema_condicao')
->leftJoin('geral_ciap AS ciap', 'ciap.id', 'problema_condicao.ciap_id')
->leftJoin('sigtap.cid AS cid', 'cid.id', 'problema_condicao.cid_id')
->whereColumn('problema_condicao.atendimento_individual_id', 'atendimento_individual2.id')
->where(fn ($q) => $q
->whereIn('ciap.codigo', self::getCiapsHipertensao())
->orWhereIn('cid.codigo', self::getCidsHipertensao())
)
)
->orWhereExists(fn ($q) => $q
->selectRaw(1)
->from('atencao_basica_atendimento_individual_condicao_avaliada AS atendimento_individual_condicao_avaliada')
->whereColumn('atendimento_individual_condicao_avaliada.atendimento_individual_id', 'atendimento_individual2.id')
->where('atendimento_individual_condicao_avaliada.condicao_avaliada_id', CondicaoAvaliada::HIPERTENSAO_ARTERIAL)
)
)
->where('atendimento_individual2.data_usuario_responsavel', '<=', $params->periodo['end']->format('Y-m-d'))
->orderBy('atendimento_individual2.data_usuario_responsavel')
->limit(1)
)
)
->leftJoin('atencao_basica_cadastro_domiciliar AS cadastro_domiciliar', 'cadastro_domiciliar.domicilio_id', 'cidadao.domicilio_id')
->leftJoin('cadastro_obito AS obito', fn ($j) => $j
->on('obito.cidadao_id', 'cidadao.id')
->whereNull('obito.deleted_at')
)
->whereIn('area.tipo_id', self::getTiposEquipes())
->where(fn ($q) => $q
->where(fn ($q) => $q
->whereNull('cadastro_individual.saida_cidadao_id')
->orWhere('cadastro_individual.saida_cidadao_id', '<>', SaidaCidadao::MUDANCA_DE_TERRITORIO)
)
->orWhere(fn ($q) => $q
->where('cadastro_individual.saida_cidadao_id', SaidaCidadao::MUDANCA_DE_TERRITORIO)
->where('cadastro_individual.motivo_saida_data', '>', $params->periodo['end']->format('Y-m-d'))
)
)
->where(fn ($q) => $q
->whereNull('obito.obito_em')
->orWhere('obito.obito_em', '>', $params->periodo['end']->format('Y-m-d H:i:s'))
)
->when($params->unidade_id, fn ($q, $id) => $q->where('equipe.unidade_id', $id))
->when($params->equipe_id, fn ($q, $id) => $q->where('cadastro_individual.equipe_id', $id))
->when($params->sexo_id, fn ($q, $id) => $q->where('cidadao.sexo_id', $id))
->when(!is_null($params->idade_minima), fn ($q) => $q
->whereRaw("TIMESTAMPDIFF(YEAR, cidadao.data_nascimento, CURRENT_DATE) >= ?", [$params->idade_minima]))
->when(!is_null($params->idade_maxima), fn ($q) => $q
->whereRaw("TIMESTAMPDIFF(YEAR, cidadao.data_nascimento, CURRENT_DATE) <= ?", [$params->idade_maxima]))
->when(!$params->fora_area, fn ($q) => $q
->whereNotNull('cadastro_domiciliar.id')
->where(fn ($sub) => $sub
->whereNull('cadastro_domiciliar.fora_area')
->orWhere('cadastro_domiciliar.fora_area', 0)
))
->select(
'paciente.id',
'cidadao.nome'
)
->distinct();
}
public static function getPrintExportData()
{
$data = self::index();
$data->pacientes->each(function ($paciente) {
if (!is_null($paciente->data_nascimento)) {
$paciente->data_nascimento = Carbon::create($paciente->data_nascimento)->format('d/m/Y');
}
});
$quadrimestre = '';
if (request()->quadrimestre == 1) {
$quadrimestre = "1º (Janeiro - Abril)";
}
else if (request()->quadrimestre == 2) {
$quadrimestre = "2º (Maio - Agosto)";
}
else if (request()->quadrimestre == 3) {
$quadrimestre = "3º (Setembro - Dezembro)";
}
$unidade = request()->unidade_id
? Unidade::findOrFail(request()->unidade_id)->nome_fantasia
: 'Todas';
$equipe = 'Todas';
if (request()->equipe_id) {
$equipeModel = Equipe::findOrFail(request()->equipe_id);
$equipe = '';
if (!is_null($equipeModel->area->numero_ine)) {
$equipe .= "INE: {$equipeModel->area->numero_ine}";
}
if (!is_null($equipeModel->area->descricao) && !is_null($equipeModel->area->numero_ine)) {
$equipe .= ' - Área: ';
}
else if (!is_null($equipeModel->area->descricao)) {
$equipe .= 'Área: ';
}
if (!is_null($equipeModel->area->descricao)) {
$equipe .= $equipeModel->area->descricao;
}
if (isset($equipeModel->microarea->descricao)
&& (!is_null($equipeModel->area->numero_ine) || !is_null($equipeModel->area->descricao))
) {
$equipe .= ' - Microárea: ';
}
else if (isset($equipeModel->microarea->descricao)) {
$equipe .= 'Microárea: ';
}
if (isset($equipeModel->microarea->descricao)) {
$equipe .= $equipeModel->microarea->descricao;
}
}
$boasPraticas = 'Todas';
if (count(request()->boas_praticas) === 1) {
$boasPraticas = self::getBoasPraticas()->where('value', request()->boas_praticas[0])->first()->text;
}
else if (count(request()->boas_praticas) < self::getBoasPraticas()->count()) {
$boasPraticas = count(request()->boas_praticas) . ' selecionadas';
}
$sexo = request()->sexo_id
? Sexo::findOrFail(request()->sexo_id)->descricao
: 'Todos';
$paciente = request()->paciente_id
? Paciente::findOrFail(request()->paciente_id)->cidadao->nome
: '';
$isBuscaAtiva = DataUtil::isStringTrue(request()->busca_ativa);
$isForaArea = DataUtil::isStringTrue(request()->fora_area);
return [
'periodoDe' => request()->periodo['start'] ?? '',
'periodoAte' => request()->periodo['end'] ?? '',
'quadrimestreAno' => request()->quadrimestre_ano,
'quadrimestre' => $quadrimestre,
'unidade' => $unidade,
'equipe' => $equipe,
'boasPraticas' => $boasPraticas,
'buscaAtiva' => $isBuscaAtiva ? 'Sim' : 'Não',
'foraArea' => $isForaArea ? 'Sim' : 'Não',
'isBuscaAtiva' => $isBuscaAtiva,
'sexo' => $sexo,
'idadeMinima' => request()->idade_minima,
'idadeMaxima' => request()->idade_maxima,
'paciente' => $paciente,
'equipes' => $data->equipes,
'pacientes' => $data->pacientes,
'totalizadores' => $data->totalizadores,
'colunasPacientes' => collect(request()->colunas_pacientes),
'boasPraticasSelecionadas' => collect(request()->boas_praticas)
];
}
private static function getTiposEquipes()
{
return [
AreaTipo::EQUIPE_DE_SAUDE_DA_FAMILIA,
AreaTipo::EQUIPE_DE_ATENCAO_PRIMARIA,
];
}
private static function getCiapsHipertensao()
{
return [
'K86',
'K87',
];
}
private static function getCidsHipertensao()
{
return [
'I10',
'I11',
'I110',
'I119',
'I12',
'I120',
'I129',
'I13',
'I130',
'I131',
'I132',
'I139',
'I15',
'I150',
'I151',
'I152',
'I158',
'I159',
'O10',
'O100',
'O101',
'O102',
'O103',
'O104',
'O109',
'O11',
];
}
}