From 9e0225bbdfa350d29f551d3f8ee2adec46d0fc75 Mon Sep 17 00:00:00 2001
From: Lewis <lgtg20@inf.ufpr.br>
Date: Wed, 28 Aug 2024 14:29:23 -0300
Subject: [PATCH 01/26] Add federative entity route

---
 .../convert/educationLevelModEntityAgg.js     |  56 ++
 .../convert/educationLevelModEntitySeg.js     |  40 ++
 src/libs/middlewares/aggregateData.js         |   8 +-
 src/libs/middlewares/id2str.js                |  11 +-
 src/libs/routes_v1/api.js                     |   3 +
 src/libs/routes_v1/federativeEntity.js        | 542 ++++++++++++++++++
 6 files changed, 655 insertions(+), 5 deletions(-)
 create mode 100644 src/libs/convert/educationLevelModEntityAgg.js
 create mode 100644 src/libs/convert/educationLevelModEntitySeg.js
 create mode 100644 src/libs/routes_v1/federativeEntity.js

diff --git a/src/libs/convert/educationLevelModEntityAgg.js b/src/libs/convert/educationLevelModEntityAgg.js
new file mode 100644
index 00000000..a9fb4fbc
--- /dev/null
+++ b/src/libs/convert/educationLevelModEntityAgg.js
@@ -0,0 +1,56 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+   
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function educationLevelShort(id) {
+    switch (id) {
+        case 1:
+        return 'Creche';
+        case 2:
+        return 'Pré-Escola';
+        case 3:
+        return 'Ensino Fundamental - anos iniciais';
+        case 4:
+        return 'Ensino Fundamental - anos finais';
+        case 5:
+        return 'Ensino Médio Propedêutico';
+        case 6:
+        return 'Ensino Médio Normal Magistério';
+        case 7:
+        return 'Ensino Médio Integrado';
+        case 8:
+        return 'Educação Profissional Técnica - Associado ao Nível Médio';
+        case 9:
+        return 'Educação Profissional Técnica - Concomitante';
+        case 10:
+        return 'Educação Profissional Técnica - Subsequente';
+        case 11:
+        return 'Educação Profissional - Misto';
+        case 12:
+        return 'Educação Profissional FIC Concomitante';
+        case 13:
+        return 'Educacao Profissional FIC Integrado EJA';
+        case 14:
+        return 'EJA Ensino Fundamental';
+        case 15:
+        return 'EJA Ensino Médio';
+        default:
+        return 'Não classificada';
+    }
+};
diff --git a/src/libs/convert/educationLevelModEntitySeg.js b/src/libs/convert/educationLevelModEntitySeg.js
new file mode 100644
index 00000000..fedf7d56
--- /dev/null
+++ b/src/libs/convert/educationLevelModEntitySeg.js
@@ -0,0 +1,40 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+   
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function educationLevelShort(id) {
+    switch (id) {
+        case 1:
+        return 'Educação Infantil';
+        case 2:
+        return 'Ensino Fundamental';
+        case 3:
+        return 'Ensino Médio';
+        case 4:
+        return 'Educação Profissional';
+        case 5:
+        return 'Educação Profissional Técnica de Nível Médio';
+        case 6:
+        return 'Educação Profissional FIC';
+        case 7:
+        return 'EJA';
+        default:
+        return 'Não classificada';
+    }
+};
diff --git a/src/libs/middlewares/aggregateData.js b/src/libs/middlewares/aggregateData.js
index 3ea93de3..4059a2f0 100644
--- a/src/libs/middlewares/aggregateData.js
+++ b/src/libs/middlewares/aggregateData.js
@@ -22,7 +22,9 @@ const convert = {
     modality_integral_time: 'educationLevelBasic',
     special_education: 'specialEducation',
     special_education_doc: 'specialEducationDoc',
-    education_level_mod_doc: 'educationLevelModDoc'
+    education_level_mod_doc: 'educationLevelModDoc',
+    education_level_mod_entity_seg: 'educationLevelModEntitySeg',
+    education_level_mod_entity_agg: 'educationLevelModEntityAgg'
 }
 
 function aggregateData(req, res, next) {
@@ -38,7 +40,9 @@ function aggregateData(req, res, next) {
             'period_agg', 
             'modality_integral_time', 
             'special_education',
-            'special_education_doc'
+            'special_education_doc',
+            'education_level_mod_entity_seg',
+            'education_level_mod_entity_agg'
         ]
         let id;
         const fields = req.query.dims.split(',');
diff --git a/src/libs/middlewares/id2str.js b/src/libs/middlewares/id2str.js
index 1971d0a0..d940606b 100644
--- a/src/libs/middlewares/id2str.js
+++ b/src/libs/middlewares/id2str.js
@@ -119,7 +119,8 @@ const ageRangeAggregate = require(`${libs}/convert/ageRangeAggregate`);
 const specialEducation = require(`${libs}/convert/specialEducation`);
 const specialEducationDoc = require(`${libs}/convert/specialEducationDoc`);
 const educationLevelModDoc = require(`${libs}/convert/educationLevelModDoc`);
-
+const educationLevelModEntitySeg = require(`${libs}/convert/educationLevelModEntitySeg`);
+const educationLevelModEntityAgg = require(`${libs}/convert/educationLevelModEntityAgg`);
 
 const ids = {
     gender_id: gender,
@@ -231,7 +232,9 @@ const ids = {
     income_range_id: incomeRange,
     special_education: specialEducation,
     special_education_doc: specialEducationDoc,
-    education_level_mod_doc: educationLevelModDoc
+    education_level_mod_doc: educationLevelModDoc,
+    education_level_mod_entity_seg: educationLevelModEntitySeg,
+    education_level_mod_entity_agg: educationLevelModEntityAgg
 };
 
 function transform(removeId=false) {
@@ -365,5 +368,7 @@ module.exports = {
     incomeRange,
     specialEducation,
     specialEducationDoc,
-    educationLevelModDoc
+    educationLevelModDoc,
+    educationLevelModEntitySeg,
+    educationLevelModEntityAgg
 };
diff --git a/src/libs/routes_v1/api.js b/src/libs/routes_v1/api.js
index ba036951..e9fbd8fd 100644
--- a/src/libs/routes_v1/api.js
+++ b/src/libs/routes_v1/api.js
@@ -149,6 +149,8 @@ const enrollmentAggregate = require(`${libs}/routes_v1/enrollmentAggregate`);
 
 const employeesAggregate = require(`${libs}/routes_v1/employeesAggregate`);
 
+const federativeEntity = require(`${libs}/routes_v1/federativeEntity`);
+
 const email = require(`${libs}/routes_v1/email`);
 
 api.get('/', (req, res) => {
@@ -214,6 +216,7 @@ api.use('/new_pnad', newPnad);
 api.use('/rate_school_new', rateSchoolNew)
 api.use('/enrollmentAggregate', enrollmentAggregate);
 api.use('/employeesAggregate', employeesAggregate);
+api.use('/federativeEntity', federativeEntity);
 
 
 //Publication 
diff --git a/src/libs/routes_v1/federativeEntity.js b/src/libs/routes_v1/federativeEntity.js
new file mode 100644
index 00000000..df39c381
--- /dev/null
+++ b/src/libs/routes_v1/federativeEntity.js
@@ -0,0 +1,542 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+const express = require('express');
+const { result } = require('lodash');
+
+const federativeEntityApp = express.Router();
+
+const libs = `${process.cwd()}/libs`;
+
+const log = require(`${libs}/log`)(module);
+
+const squel = require('squel');
+
+const query = require(`${libs}/middlewares/query`).query;
+
+const response = require(`${libs}/middlewares/response`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+const aggregateData = require(`${libs}/middlewares/aggregateData`);
+
+const id2str = require(`${libs}/middlewares/id2str`);
+
+const config = require(`${libs}/config`);
+
+const addMissing = require(`${libs}/middlewares/addMissing`);
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
+
+federativeEntityApp.use(cache('15 day'));
+
+let rqf = new ReqQueryFields();
+
+federativeEntityApp.get('/years', (req, res, next) => {
+    req.sql.from('escola')
+    .field('DISTINCT escola.ano_censo', 'year')
+    .where('escola.ano_censo >= 2021')
+    next();
+}, query, response('years'));
+
+federativeEntityApp.get('/adm_dependency', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 5; i++) {
+        req.result.push({
+            id: i, name: id2str.admDependency(i)
+        });
+    }
+    next();
+}, response('adm_dependency'));
+
+federativeEntityApp.get('/adm_dependency_detailed', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 9; i++) {
+        req.result.push({
+            id: i, name: id2str.admDependencyPriv(i)
+        });
+    }
+    next();
+}, response('adm_dependency_detailed'));
+
+federativeEntityApp.get('/education_level_mod_agg', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 13; i++) {
+        req.result.push({
+            id: i, name: id2str.educationLevelMod(i)
+        });
+    }
+    next();
+}, response('education_level_mod_agg'));
+
+federativeEntityApp.get('/integral_time_agg', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 3; i++) {
+        req.result.push({
+            id: i, name: id2str.integralTime(i)
+        });
+    }
+    next();
+}, response('integral_time_agg')); 
+
+federativeEntityApp.get('/location', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 2; i++) {
+        req.result.push({
+            id: i, name: id2str.location(i)
+        });
+    }
+    next();
+}, response('location'));
+
+federativeEntityApp.get('/diff_location', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 4; i++) {
+        req.result.push({
+            id: i, name: id2str.diffLocation(i)
+        });
+    }
+
+    req.result.push({
+        id: 8, name: 'Área onde se localizam povos e comunidades tradicionais'
+    })
+
+    next();
+}, response('diff_location'));
+
+federativeEntityApp.get('/modality_integral_time', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 7; i++) {
+        req.result.push({
+            id: i, name: id2str.educationLevelBasic(i)
+        });
+    }
+
+    next();
+}, response('modality_integral_time'));
+
+federativeEntityApp.get('/gender', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 2; i++) {
+        req.result.push({
+            id: i, name: id2str.gender(i)
+        });
+    }
+
+    next();
+}, response('gender'));
+
+federativeEntityApp.get('/age_range', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 7; i++) {
+        req.result.push({
+            id: i, name: id2str.ageRangeAggregate(i)
+        });
+    }
+
+    next();
+}, response('age_range'));
+
+federativeEntityApp.get('/ethnic_group', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 6; i++) {
+        req.result.push({
+            id: i, name: id2str.ethnicGroup(i)
+        });
+    }
+
+    next();
+}, response('ethnic_group'));
+
+federativeEntityApp.get('/period_agg', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 5; i++) {
+        req.result.push({
+            id: i, name: id2str.period(i)
+        });
+    }
+
+    next();
+}, response('period_agg'));
+
+federativeEntityApp.get('/region', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 5; i++) {
+        req.result.push({
+            id: i, name: id2str.regionCode(i)
+        });
+    }
+
+    next();
+}, response('period_agg'));
+
+federativeEntityApp.get('/state', (req, res, next) => {
+    req.result = []
+    for (let i = 11; i < 54; i++) {
+        if (id2str.stateName(i) !== 'Não declarada') {
+            req.result.push({
+                id: i, name: id2str.stateName(i)
+            });
+        }
+    }
+
+    next();
+}, response('state'));
+
+federativeEntityApp.get('/special_education', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 2; i++) {
+        req.result.push({
+            id: i, name: id2str.specialEducation(i)
+        });
+    }
+
+    next();
+}, response('special_education'));
+
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'adm_dependency',
+    table: 'escola',
+    tableField: 'dependencia_adm_id',
+    resultField: 'adm_dependency_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'dependencia_adm_id'
+    }
+}).addValue({
+    name: 'adm_dependency_detailed',
+    table: 'escola',
+    tableField: 'dependencia_adm_priv',
+    resultField: 'adm_dependency_detailed_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'dependencia_adm_priv'
+    }
+}).addValue({
+    name: 'education_level_mod',
+    table: 'escola',
+    tableField: 'etapas_mod_ensino_segmento_id',
+    resultField: 'education_level_mod_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'etapas_mod_ensino_segmento_id'
+    }
+}).addValue({
+    name:'integral_time',
+    table: 'escola',
+    tableField: 'tempo_integral',
+    resultField: 'integral_time_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'tempo_integral'
+    }
+  }).addValue({
+    name: 'education_level_short',
+    table: 'escola',
+    tableField: 'etapa_resumida',
+    resultField: 'education_level_short_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'etapa_resumida'
+    }
+}).addValue({
+    name: 'region',
+    table: 'regiao',
+    tableField: ['nome', 'id'],
+    resultField: ['region_name', 'region_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'regiao_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'mesoregion',
+    table: 'municipio',
+    tableField: ['nome_mesorregiao', 'mesorregiao_id'],
+    resultField: ['mesoregion_name', 'mesoregion_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'mesorregiao_id',
+        table: 'municipio'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'microregion',
+    table: 'municipio',
+    tableField: ['nome_microrregiao', 'microrregiao_id'],
+    resultField: ['microregion_name', 'microregion_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'microrregiao_id',
+        table: 'municipio'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'min_year',
+    table: 'escola',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '>=',
+        type: 'integer',
+        field: 'ano_censo',
+    },
+}).addValue({
+    name: 'max_year',
+    table: 'escola',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '<=',
+        type: 'integer',
+        field: 'ano_censo',
+    },
+}).addValueToField({
+    name: 'state',
+    table: 'estado',
+    tableField: ['nome', 'id'],
+    resultField: ['state_name', 'state_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'estado_id',
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'state',
+    table: 'estado',
+    tableField: 'nome',
+    resultField: 'state_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'estado_id',
+        foreignTable: 'escola'
+    }
+}, 'filter').addValueToField({
+    name: 'city',
+    table: 'municipio',
+    tableField: ['nome', 'id'],
+    resultField: ['city_name', 'city_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'city',
+    table: 'municipio',
+    tableField: 'nome',
+    resultField: 'city_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}, 'filter').addValueToField({
+    name: 'school',
+    table: 'escola',
+    tableField: ['nome_escola', 'id'],
+    resultField: ['school_name', 'school_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: ['id', 'ano_censo'],
+        foreign: ['escola_id', 'ano_censo'],
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'locale_id',
+    table: 'escola',
+    tableField: 'localizacao_id',
+    resultField: 'locale_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'localizacao_id'
+    }
+}, 'dims').addValueToField({
+    name: 'school_id',
+    table: 'escola',
+    tableField: 'id',
+    resultField: 'school_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: ['id', 'ano_censo'],
+        foreign: ['escola_id', 'ano_censo'],
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'school',
+    table: 'escola',
+    tableField: 'nome_escola',
+    resultField: 'school_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: ['id', 'ano_censo'],
+        foreign: ['escola_id', 'ano_censo'],
+        foreignTable: 'escola'
+    }
+}, 'filter').addValue({
+    name: 'location',
+    table: 'escola',
+    tableField: 'localizacao_id',
+    resultField: 'location_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'localizacao_id'
+    }
+}).addValue({
+    name: 'diff_location',
+    table: 'escola',
+    tableField: 'localizacao_diferenciada_par',
+    resultField: 'diff_location_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'localizacao_diferenciada_par'
+    }
+});
+
+federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
+
+    console.log(req.query);
+
+    if (req.query.dims && req.query.dims.includes('education_level_mod_entity_seg'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_ed_inf_total)', 'total_doc_ed_inf_total')
+        .field('SUM(docentes_sinopse.num_doc_en_fund_total)', 'total_doc_en_fund_total')
+        .field('SUM(docentes_sinopse.num_doc_en_medio_total)', 'total_doc_en_medio_total')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_total)', 'total_doc_ed_prof_total')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_tec_total)', 'total_doc_ed_prof_tec_total')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_fic_total)', 'total_doc_ed_prof_fic_total')
+        .field('SUM(docentes_sinopse.num_doc_eja_total)', 'total_doc_eja_total')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where('docentes_sinopse.cod_reg = 0');
+    }
+    else if (req.query.dims && req.query.dims.includes('education_level_mod_entity_agg'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_ed_inf_creche)', 'total_doc_ed_inf_creche')
+        .field('SUM(docentes_sinopse.num_doc_ed_inf_pre_escola)', 'total_doc_ed_inf_pre_escola')
+        .field('SUM(docentes_sinopse.num_doc_en_fund_anos_iniciais)', 'total_doc_en_fund_anos_iniciais')
+        .field('SUM(docentes_sinopse.num_doc_en_fund_anos_finais)', 'total_doc_en_fund_anos_finais')
+        .field('SUM(docentes_sinopse.num_doc_en_medio_propedeutico)', 'total_doc_en_medio_propedeutico')
+        .field('SUM(docentes_sinopse.num_doc_en_medio_normal_magisterio)', 'total_doc_en_medio_normal_magisterio')
+        .field('SUM(docentes_sinopse.num_doc_en_medio_integrado)', 'total_doc_en_medio_integrado')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_en_medio)', 'total_doc_ed_prof_en_medio')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_tec_concomitante)', 'total_doc_ed_prof_tec_concomitante')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_tec_subsequente)', 'total_doc_ed_prof_tec_subsequente')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_tec_misto)', 'total_doc_ed_prof_tec_misto')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_fic_concomitante)', 'total_doc_ed_prof_fic_concomitante')
+        .field('SUM(docentes_sinopse.num_doc_ed_prof_fic_integrado_eja)', 'total_doc_ed_prof_fic_integrado_eja')
+        .field('SUM(docentes_sinopse.num_doc_eja_en_fund)', 'total_doc_eja_en_fund')
+        .field('SUM(docentes_sinopse.num_doc_eja_en_medio)', 'total_doc_eja_en_medio')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where('docentes_sinopse.cod_reg = 0');
+    }
+    else {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.qt_mat_bas)', 'total')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo');
+    }
+    next();
+}, query, aggregateData, id2str.transform(false), response('federative_entity'));
+
+module.exports = federativeEntityApp;
-- 
GitLab


From f16154447d6e4b440fac4e97bcb5932c24230d53 Mon Sep 17 00:00:00 2001
From: Lewis <lgtg20@inf.ufpr.br>
Date: Fri, 30 Aug 2024 14:01:29 -0300
Subject: [PATCH 02/26] All aggregate data working

---
 src/libs/convert/ageRangeEntity.js       |  40 ++++++
 src/libs/convert/postGraduationEntity.js |  32 +++++
 src/libs/middlewares/aggregateData.js    |  18 ++-
 src/libs/middlewares/id2str.js           |  10 +-
 src/libs/routes_v1/federativeEntity.js   | 173 +++++++++++++----------
 5 files changed, 198 insertions(+), 75 deletions(-)
 create mode 100644 src/libs/convert/ageRangeEntity.js
 create mode 100644 src/libs/convert/postGraduationEntity.js

diff --git a/src/libs/convert/ageRangeEntity.js b/src/libs/convert/ageRangeEntity.js
new file mode 100644
index 00000000..f9ca149b
--- /dev/null
+++ b/src/libs/convert/ageRangeEntity.js
@@ -0,0 +1,40 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+   
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function ageRangeEntity(id) {
+    switch (id) {
+        case 1:
+        return 'Até 24 anos';
+        case 2:
+        return '25 a 29 anos';
+        case 3:
+        return '30 a 39 anos';
+        case 4:
+        return '40 a 49 anos';
+        case 5:
+        return '50 a 54 anos';
+        case 6:
+        return '55 a 59 anos';
+        case 7:
+        return '60 anos ou mais';
+        default:
+        return 'Não declarada';
+    }
+};
diff --git a/src/libs/convert/postGraduationEntity.js b/src/libs/convert/postGraduationEntity.js
new file mode 100644
index 00000000..49e8d08a
--- /dev/null
+++ b/src/libs/convert/postGraduationEntity.js
@@ -0,0 +1,32 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+   
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function ageRange(id) {
+    switch (id) {
+        case 1:
+        return 'Pós-Graduação Especialização';
+        case 2:
+        return 'Pós-Graduação Mestrado';
+        case 3:
+        return 'Pós-Graduação Doutorado';
+        default:
+        return '';
+    }
+};
diff --git a/src/libs/middlewares/aggregateData.js b/src/libs/middlewares/aggregateData.js
index 4059a2f0..3dadee22 100644
--- a/src/libs/middlewares/aggregateData.js
+++ b/src/libs/middlewares/aggregateData.js
@@ -24,7 +24,14 @@ const convert = {
     special_education_doc: 'specialEducationDoc',
     education_level_mod_doc: 'educationLevelModDoc',
     education_level_mod_entity_seg: 'educationLevelModEntitySeg',
-    education_level_mod_entity_agg: 'educationLevelModEntityAgg'
+    education_level_mod_entity_agg: 'educationLevelModEntityAgg',
+    adm_dependency_entity_agg: 'newPnadAdmDependency',
+    adm_dependency_entity: 'admDependency',
+    location_entity: 'location',
+    gender_entity: 'gender',
+    age_range_entity: 'ageRangeEntity',
+    post_graduation_entity: 'postGraduationEntity',
+    contract_type_entity: 'contractType'
 }
 
 function aggregateData(req, res, next) {
@@ -42,7 +49,14 @@ function aggregateData(req, res, next) {
             'special_education',
             'special_education_doc',
             'education_level_mod_entity_seg',
-            'education_level_mod_entity_agg'
+            'education_level_mod_entity_agg',
+            'adm_dependency_entity_agg',
+            'adm_dependency_entity',
+            'location_entity',
+            'gender_entity',
+            'age_range_entity',
+            'post_graduation_entity',
+            'contract_type_entity'
         ]
         let id;
         const fields = req.query.dims.split(',');
diff --git a/src/libs/middlewares/id2str.js b/src/libs/middlewares/id2str.js
index d940606b..08a1ebed 100644
--- a/src/libs/middlewares/id2str.js
+++ b/src/libs/middlewares/id2str.js
@@ -121,6 +121,8 @@ const specialEducationDoc = require(`${libs}/convert/specialEducationDoc`);
 const educationLevelModDoc = require(`${libs}/convert/educationLevelModDoc`);
 const educationLevelModEntitySeg = require(`${libs}/convert/educationLevelModEntitySeg`);
 const educationLevelModEntityAgg = require(`${libs}/convert/educationLevelModEntityAgg`);
+const ageRangeEntity = require(`${libs}/convert/ageRangeEntity`);
+const postGraduationEntity = require(`${libs}/convert/postGraduationEntity`);
 
 const ids = {
     gender_id: gender,
@@ -234,7 +236,9 @@ const ids = {
     special_education_doc: specialEducationDoc,
     education_level_mod_doc: educationLevelModDoc,
     education_level_mod_entity_seg: educationLevelModEntitySeg,
-    education_level_mod_entity_agg: educationLevelModEntityAgg
+    education_level_mod_entity_agg: educationLevelModEntityAgg,
+    age_range_entity: ageRangeEntity,
+    post_graduation_entity: postGraduationEntity
 };
 
 function transform(removeId=false) {
@@ -370,5 +374,7 @@ module.exports = {
     specialEducationDoc,
     educationLevelModDoc,
     educationLevelModEntitySeg,
-    educationLevelModEntityAgg
+    educationLevelModEntityAgg,
+    ageRangeEntity,
+    postGraduationEntity
 };
diff --git a/src/libs/routes_v1/federativeEntity.js b/src/libs/routes_v1/federativeEntity.js
index df39c381..9de0dfbf 100644
--- a/src/libs/routes_v1/federativeEntity.js
+++ b/src/libs/routes_v1/federativeEntity.js
@@ -233,56 +233,6 @@ rqf.addField({
     name: 'dims',
     field: true,
     where: false
-}).addValue({
-    name: 'adm_dependency',
-    table: 'escola',
-    tableField: 'dependencia_adm_id',
-    resultField: 'adm_dependency_id',
-    where: {
-        relation: '=',
-        type: 'integer',
-        field: 'dependencia_adm_id'
-    }
-}).addValue({
-    name: 'adm_dependency_detailed',
-    table: 'escola',
-    tableField: 'dependencia_adm_priv',
-    resultField: 'adm_dependency_detailed_id',
-    where: {
-        relation: '=',
-        type: 'integer',
-        field: 'dependencia_adm_priv'
-    }
-}).addValue({
-    name: 'education_level_mod',
-    table: 'escola',
-    tableField: 'etapas_mod_ensino_segmento_id',
-    resultField: 'education_level_mod_id',
-    where: {
-        relation: '=',
-        type: 'integer',
-        field: 'etapas_mod_ensino_segmento_id'
-    }
-}).addValue({
-    name:'integral_time',
-    table: 'escola',
-    tableField: 'tempo_integral',
-    resultField: 'integral_time_id',
-    where: {
-        relation: '=',
-        type: 'integer',
-        field: 'tempo_integral'
-    }
-  }).addValue({
-    name: 'education_level_short',
-    table: 'escola',
-    tableField: 'etapa_resumida',
-    resultField: 'education_level_short_id',
-    where: {
-        relation: '=',
-        type: 'integer',
-        field: 'etapa_resumida'
-    }
 }).addValue({
     name: 'region',
     table: 'regiao',
@@ -295,8 +245,8 @@ rqf.addField({
     },
     join: {
         primary: 'id',
-        foreign: 'regiao_id',
-        foreignTable: 'escola'
+        foreign: 'cod_reg',
+        foreignTable: 'docentes_sinopse'
     }
 }).addValue({
     name: 'mesoregion',
@@ -332,7 +282,7 @@ rqf.addField({
     }
 }).addValue({
     name: 'min_year',
-    table: 'escola',
+    table: 'docentes_sinopse',
     tableField: 'ano_censo',
     resultField: 'year',
     where: {
@@ -342,7 +292,7 @@ rqf.addField({
     },
 }).addValue({
     name: 'max_year',
-    table: 'escola',
+    table: 'docentes_sinopse',
     tableField: 'ano_censo',
     resultField: 'year',
     where: {
@@ -412,7 +362,7 @@ rqf.addField({
     }
 }, 'filter').addValueToField({
     name: 'school',
-    table: 'escola',
+    table: 'docentes_sinopse',
     tableField: ['nome_escola', 'id'],
     resultField: ['school_name', 'school_id'],
     where: {
@@ -427,7 +377,7 @@ rqf.addField({
     }
 }, 'dims').addValueToField({
     name: 'locale_id',
-    table: 'escola',
+    table: 'docentes_sinopse',
     tableField: 'localizacao_id',
     resultField: 'locale_id',
     where: {
@@ -437,7 +387,7 @@ rqf.addField({
     }
 }, 'dims').addValueToField({
     name: 'school_id',
-    table: 'escola',
+    table: 'docentes_sinopse',
     tableField: 'id',
     resultField: 'school_id',
     where: {
@@ -452,7 +402,7 @@ rqf.addField({
     }
 }, 'dims').addValueToField({
     name: 'school',
-    table: 'escola',
+    table: 'docentes_sinopse',
     tableField: 'nome_escola',
     resultField: 'school_name',
     where: {
@@ -467,7 +417,7 @@ rqf.addField({
     }
 }, 'filter').addValue({
     name: 'location',
-    table: 'escola',
+    table: 'docentes_sinopse',
     tableField: 'localizacao_id',
     resultField: 'location_id',
     where: {
@@ -475,16 +425,6 @@ rqf.addField({
         type: 'integer',
         field: 'localizacao_id'
     }
-}).addValue({
-    name: 'diff_location',
-    table: 'escola',
-    tableField: 'localizacao_diferenciada_par',
-    resultField: 'diff_location_id',
-    where: {
-        relation: '=',
-        type: 'integer',
-        field: 'localizacao_diferenciada_par'
-    }
 });
 
 federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
@@ -529,12 +469,103 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .order('docentes_sinopse.ano_censo')
         .where('docentes_sinopse.cod_reg = 0');
     }
+    else if (req.query.dims && req.query.dims.includes('special_education'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_ed_especial_classe_comum)', 'total_doc_ed_especial_classe_comum')
+        .field('SUM(docentes_sinopse.num_doc_ed_especial_classe_exclusiva)', 'total_doc_ed_especial_classe_exclusiva')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where('docentes_sinopse.cod_reg = 0');
+    }
+    else if (req.query.dims && req.query.dims.includes('adm_dependency_entity_agg'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_dependencia_adm_pub)', 'total_doc_dependencia_adm_pub')
+        .field('SUM(docentes_sinopse.num_doc_dependencia_adm_priv)', 'total_doc_dependencia_adm_priv')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where('docentes_sinopse.cod_reg = 0');
+    }
+    else if (req.query.dims && req.query.dims.includes('adm_dependency_entity'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_dependencia_adm_federal)', 'total_doc_dependencia_adm_federal')
+        .field('SUM(docentes_sinopse.num_doc_dependencia_adm_estadual)', 'total_doc_dependencia_adm_estadual')
+        .field('SUM(docentes_sinopse.num_doc_dependencia_adm_municipal)', 'total_doc_dependencia_adm_municipal')
+        .field('SUM(docentes_sinopse.num_doc_dependencia_adm_priv)', 'total_doc_dependencia_adm_priv')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where('docentes_sinopse.cod_reg = 0');
+    }
+    else if (req.query.dims && req.query.dims.includes('location_entity'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_loc_urbana_total)', 'total_doc_loc_urbana_total')
+        .field('SUM(docentes_sinopse.num_doc_loc_rural_total)', 'total_doc_loc_rural_total')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where('docentes_sinopse.cod_reg = 0');
+    }
+    else if (req.query.dims && req.query.dims.includes('gender_entity'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_masc_total)', 'total_doc_masc_total')
+        .field('SUM(docentes_sinopse.num_doc_fem_total)', 'total_doc_fem_total')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where('docentes_sinopse.cod_reg = 0');
+    }
+    else if (req.query.dims && req.query.dims.includes('age_range_entity'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_fem_24 + docentes_sinopse.num_doc_masc_24)', 'total_doc_24')
+        .field('SUM(docentes_sinopse.num_doc_fem_25_29 + docentes_sinopse.num_doc_masc_25_29)', 'total_doc_25_29')
+        .field('SUM(docentes_sinopse.num_doc_fem_30_39 + docentes_sinopse.num_doc_masc_30_39)', 'total_doc_30_39')
+        .field('SUM(docentes_sinopse.num_doc_fem_40_49 + docentes_sinopse.num_doc_masc_40_49)', 'total_doc_40_49')
+        .field('SUM(docentes_sinopse.num_doc_fem_50_54 + docentes_sinopse.num_doc_masc_50_54)', 'total_doc_50_54')
+        .field('SUM(docentes_sinopse.num_doc_fem_55_59 + docentes_sinopse.num_doc_masc_55_59)', 'total_doc_55_59')
+        .field('SUM(docentes_sinopse.num_doc_fem_60_mais + docentes_sinopse.num_doc_masc_60_mais)', 'total_doc_60_mais')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where('docentes_sinopse.cod_reg = 0');
+    }
+    else if (req.query.dims && req.query.dims.includes('post_graduation_entity'))
+    {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_esc_pos_grad_especializacao)', 'total_doc_esc_pos_grad_especializacao')
+        .field('SUM(docentes_sinopse.num_doc_esc_pos_grad_mestrado)', 'total_doc_esc_pos_grad_mestrado')
+        .field('SUM(docentes_sinopse.num_doc_esc_pos_grad_doutorado)', 'total_doc_esc_pos_grad_doutorado')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where('docentes_sinopse.cod_reg = 0');
+    }
+    else if (req.query.dims && req.query.dims.includes('contract_type_entity'))
+    {
+            req.sql.from('docentes_sinopse')
+            .field('SUM(docentes_sinopse.num_doc_vinc_concursado_efetivo_estavel_total)', 'total_doc_vinc_concursado_efetivo_estavel_total')
+            .field('SUM(docentes_sinopse.num_doc_vinc_contrato_temp_total)', 'total_doc_vinc_contrato_temp_total')
+            .field('SUM(docentes_sinopse.num_doc_vinc_contrato_terceirizado_total)', 'total_doc_vinc_contrato_terceirizado_total')
+            .field('SUM(docentes_sinopse.num_doc_vinc_contrato_clt_total)', 'total_doc_vinc_contrato_clt_total')
+            .field('docentes_sinopse.ano_censo', 'year')
+            .group('docentes_sinopse.ano_censo')
+            .order('docentes_sinopse.ano_censo')
+            .where('docentes_sinopse.cod_reg = 0');
+    }
     else {
         req.sql.from('docentes_sinopse')
-        .field('SUM(docentes_sinopse.qt_mat_bas)', 'total')
+        .field('SUM(docentes_sinopse.num_doc_ed_bas_total)', 'total')
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
-        .order('docentes_sinopse.ano_censo');
+        .order('docentes_sinopse.ano_censo')
+        .where('docentes_sinopse.cod_uf = 0');
     }
     next();
 }, query, aggregateData, id2str.transform(false), response('federative_entity'));
-- 
GitLab


From 5f8ac5715ea9e1e99c322153e2967c9863e96609 Mon Sep 17 00:00:00 2001
From: Lewis <lgtg20@inf.ufpr.br>
Date: Wed, 4 Sep 2024 19:08:44 -0300
Subject: [PATCH 03/26] Bug fix region for federative entity

---
 src/libs/routes_v1/federativeEntity.js | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/src/libs/routes_v1/federativeEntity.js b/src/libs/routes_v1/federativeEntity.js
index 9de0dfbf..fb200e65 100644
--- a/src/libs/routes_v1/federativeEntity.js
+++ b/src/libs/routes_v1/federativeEntity.js
@@ -312,8 +312,8 @@ rqf.addField({
     },
     join: {
         primary: 'id',
-        foreign: 'estado_id',
-        foreignTable: 'escola'
+        foreign: 'cod_uf',
+        foreignTable: 'docentes_sinopse'
     }
 }, 'dims').addValueToField({
     name: 'state',
@@ -327,8 +327,8 @@ rqf.addField({
     },
     join: {
         primary: 'id',
-        foreign: 'estado_id',
-        foreignTable: 'escola'
+        foreign: 'cod_uf',
+        foreignTable: 'docentes_sinopse'
     }
 }, 'filter').addValueToField({
     name: 'city',
@@ -559,7 +559,15 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
             .order('docentes_sinopse.ano_censo')
             .where('docentes_sinopse.cod_reg = 0');
     }
-    else {
+    else if (req.query.dims && req.query.dims.includes('state')) {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_ed_bas_total)', 'total')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where('docentes_sinopse.cod_mun = 0');
+    }
+    else if (req.query.dims && req.query.dims.includes('region')) {
         req.sql.from('docentes_sinopse')
         .field('SUM(docentes_sinopse.num_doc_ed_bas_total)', 'total')
         .field('docentes_sinopse.ano_censo', 'year')
@@ -567,6 +575,14 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .order('docentes_sinopse.ano_censo')
         .where('docentes_sinopse.cod_uf = 0');
     }
+    else {
+        req.sql.from('docentes_sinopse')
+        .field('SUM(docentes_sinopse.num_doc_ed_bas_total)', 'total')
+        .field('docentes_sinopse.ano_censo', 'year')
+        .group('docentes_sinopse.ano_censo')
+        .order('docentes_sinopse.ano_censo')
+        .where('docentes_sinopse.cod_reg = 0');
+    }
     next();
 }, query, aggregateData, id2str.transform(false), response('federative_entity'));
 
-- 
GitLab


From 482c2882d39d315700049ad6a87006bbd7e3ca27 Mon Sep 17 00:00:00 2001
From: fgs21 <fgs21@inf.ufpr.br>
Date: Thu, 5 Sep 2024 09:27:35 -0300
Subject: [PATCH 04/26] [ADD] Creating courseAggregate route

---
 src/libs/routes_v1/api.js             |   3 +
 src/libs/routes_v1/courseAggregate.js | 520 ++++++++++++++++++++++++++
 2 files changed, 523 insertions(+)
 create mode 100644 src/libs/routes_v1/courseAggregate.js

diff --git a/src/libs/routes_v1/api.js b/src/libs/routes_v1/api.js
index ba036951..d84fc342 100644
--- a/src/libs/routes_v1/api.js
+++ b/src/libs/routes_v1/api.js
@@ -149,6 +149,8 @@ const enrollmentAggregate = require(`${libs}/routes_v1/enrollmentAggregate`);
 
 const employeesAggregate = require(`${libs}/routes_v1/employeesAggregate`);
 
+const courseAggregate = require(`${libs}/routes_v1/courseAggregate`);
+
 const email = require(`${libs}/routes_v1/email`);
 
 api.get('/', (req, res) => {
@@ -214,6 +216,7 @@ api.use('/new_pnad', newPnad);
 api.use('/rate_school_new', rateSchoolNew)
 api.use('/enrollmentAggregate', enrollmentAggregate);
 api.use('/employeesAggregate', employeesAggregate);
+api.use('/course_aggregate', courseAggregate);
 
 
 //Publication 
diff --git a/src/libs/routes_v1/courseAggregate.js b/src/libs/routes_v1/courseAggregate.js
new file mode 100644
index 00000000..9b372c38
--- /dev/null
+++ b/src/libs/routes_v1/courseAggregate.js
@@ -0,0 +1,520 @@
+/*
+Copyright (C) 2024 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+const express = require('express');
+
+const CourseAggregateApp = express.Router();
+
+const libs = `${process.cwd()}/libs`;
+
+const squel = require('squel');
+
+const query = require(`${libs}/middlewares/query`).query;
+
+const response = require(`${libs}/middlewares/response`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+const id2str = require(`${libs}/middlewares/id2str`);
+
+const config = require(`${libs}/config`); 
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
+
+let rqf = new ReqQueryFields();
+
+CourseAggregateApp.use(cache('15 day'));
+
+CourseAggregateApp.get('/years', (req, res, next) => {
+    req.sql.from('curso_superior_agregado')
+    .field('DISTINCT curso_superior_agregado.ano_censo', 'year')
+    next();
+}, query, response('years'));
+
+courseAggregateApp.get('/upper_adm_dependency', (req, res, next) => {
+    req.result = [];
+    for(let i = 1; i <= 7; ++i) {
+        req.result.push({
+            id: i,
+            name: id2str.upperAdmDependency(i)
+        });
+    };
+    next();
+}, response('upper_adm_dependency'));
+
+courseCountApp.get('/academic_organization', (req, res, next) => {
+    req.result = [];
+    for(let i = 1; i <= 5; ++i) {
+        req.result.push({
+            id: i,
+            name: id2str.academicOrganization(i)
+        });
+    };
+    next();
+}, response('academic_organization'));
+
+courseCountApp.get('/academic_level', (req, res, next) => {
+    req.result = [];
+    for(let i = 1; i <= 4; ++i) {
+        req.result.push({
+            id: i,
+            name: id2str.academicLevel(i)
+        });
+    };
+    next();
+}, response('academic_level'));
+
+CourseAggregateApp.get('/new_pnad_adm_dependency', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 3; i++) {
+        req.result.push({
+            id: i, name: id2str.newPnadAdmDependency(i)
+        });
+    }
+    req.result.push({id: 99, name: id2str.newPnadAdmDependency(99)});
+    next();
+}, response('new_pnad_adm_dependency'));
+
+CourseAggregateApp.get('/region', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 6; i++) {
+        req.result.push({
+            id: i, name: id2str.regionCode(i)
+        });
+    }
+
+    next();
+}, response('region'));
+
+CourseAggregateApp.get('/cap_code', (req, res, next) => {
+    req.result = []
+    for (let i = 11; i < 54; i++) {
+        if (id2str.capitalCode(i) !== 'Não informado') {
+        req.result.push({
+            id: i, name: id2str.capitalCode(i)
+        });
+        }
+    }
+    req.result.push({id: 99, name: id2str.capitalCode(99)});
+
+    next();
+}, response('cap_code'));
+
+CourseAggregateApp.get('/metro_code', (req, res, next) => {
+    req.result = []
+    for (let i = 13; i < 53; i++) {
+        if (id2str.metroCode(i) !== 'Não informado') {
+        req.result.push({
+            id: i, name: id2str.metroCode(i)
+        });
+        }
+    }
+    req.result.push({id: 99, name: id2str.metroCode(99)});
+
+    next();
+}, response('metro_code'));
+
+CourseAggregateApp.get('/attended_modality', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 16; i++) {
+        req.result.push({
+            id: i, name: id2str.attendedModality(i)
+        });
+    }
+    // Remove the option with id equals 10 => This option exists in the database, a better solution to this would be remove the option from the database
+    req.result.splice(req.result.findIndex((item) => item.id === 10), 1);
+    req.result.push({id: 99, name: id2str.attendedModality(99)});
+    next();
+}, response('attended_modality'));
+
+CourseAggregateApp.get('/income_range', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 8; i++) {
+        req.result.push({
+            id: i, name: id2str.incomeRange(i)
+        });
+    }
+    req.result.push({id: 9, name: id2str.incomeRange(9)});
+    next();
+}, response('income_range'));
+
+CourseAggregateApp.get('/attends_school', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 3; i++) {
+        req.result.push({
+            id: i, name: id2str.attendsSchool(i)
+        });
+    }
+    next();
+}, response('attends_school'));
+
+CourseAggregateApp.get('/gender', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 3; i++) {
+        req.result.push({
+            id: i, name: id2str.gender(i)
+        });
+    }
+    next();
+}, response('gender'));
+
+CourseAggregateApp.get('/new_pnad_ethnic_group', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 6; i++) {
+        req.result.push({
+            id: i, name: id2str.ethnicGroupNewPnad(i)
+        });
+    }
+    req.result.push({id: 9, name: id2str.ethnicGroupNewPnad(9)});
+    next();
+}, response('new_pnad_ethnic_group'));
+
+CourseAggregateApp.get('/bolsa_familia', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 3; i++) {
+        req.result.push({
+            id: i, name: id2str.attendsSchool(i)
+        });
+    }
+    req.result.push({id: 9, name: id2str.attendsSchool(9)});
+    next();
+}, response('bolsa_familia'));
+
+CourseAggregateApp.get('/modality', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 4; i++) {
+        req.result.push({
+            id: i, name: id2str.modality(i)
+        });
+    }
+    req.result.push({id: 99, name: id2str.modality(99)});
+    next();
+}, response('modality'));
+
+CourseAggregateApp.get('/modality_shift', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 8; i++) {
+        req.result.push({
+            id: i, name: id2str.modalityShift(i)
+        });
+    }
+    req.result.push({id: 9, name: id2str.modalityShift(9)});
+    req.result.push({id: 99, name: id2str.modalityShift(99)});
+    next();
+}, response('modality_shift'));
+
+CourseAggregateApp.get('/state', (req, res, next) => {
+    req.result = []
+    for (let i = 11; i < 54; i++) {
+        if (id2str.stateName(i) !== 'Não declarada') {
+            req.result.push({
+                id: i, name: id2str.stateName(i)
+            });
+        }
+    }
+    req.result.push({id: 99, name: id2str.stateName(99)});
+
+    next();
+}, response('state'));
+
+CourseAggregateApp.get('/age_range_all', (req, res, next) => {
+    req.result = []
+    for (let i = 1; i < 12; i++) {
+        req.result.push({
+            id: i, name: id2str.ageRangeAll(i)
+        });
+    }
+
+    next();
+}, response('age_range_all'));
+
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'adm_category',
+    table: 'curso_superior_agregado',
+    tableField: 'id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    }
+}).addValue({
+    name: 'state',
+    table: 'estado',
+    tableField: ['id', 'nome'],
+    resultField: ['state_id', 'state_nome'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id',
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_uf',
+        foreignTable: 'curso_superior_agregado'
+    }
+}).addValue({
+    name: 'state_not',
+    table: 'estado',
+    tableField: ['nome', 'id'],
+    resultField: ['state_name', 'state_id'],
+    where: {
+        relation: '<>',
+        type: 'integer',
+        field: 'cod_uf',
+        table: 'curso_superior_agregado'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_uf',
+        foreignTable: 'curso_superior_agregado'
+    }
+}).addValue({
+    name: 'years_of_study',
+    table: 'curso_superior_agregado',
+    tableField: 'anos_de_estudo',
+    resultField: 'years_of_study_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'anos_de_estudo'
+    }
+}).addValue({
+    name: 'instruction_level',
+    table: 'curso_superior_agregado',
+    tableField: 'nivel_de_instrucao',
+    resultField: 'instruction_level_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'nivel_de_instrucao'
+    }
+}).addValue({
+    name: 'new_pnad_adm_dependency',
+    table: 'curso_superior_agregado',
+    tableField: 'dependencia_adm',
+    resultField: 'new_pnad_adm_dependency_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'dependencia_adm'
+    }
+}).addValue({
+    name: 'attends_school',
+    table: 'curso_superior_agregado',
+    tableField: 'frequenta_escola',
+    resultField: 'attends_school_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'frequenta_escola'
+    }
+}).addValue({
+    name: 'modality',
+    table: 'curso_superior_agregado',
+    tableField: 'modalidade',
+    resultField: 'modality_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'modalidade'
+    }
+}).addValue({
+    name: 'attended_modality',
+    table: 'curso_superior_agregado',
+    tableField: 'nivel_etapa_modalidade_freq',
+    resultField: 'attended_modality_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'nivel_etapa_modalidade_freq'
+    }
+}).addValue({
+    name: 'illiteracy',
+    table: 'curso_superior_agregado',
+    tableField: 'analfabetismo',
+    resultField: 'illiteracy_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'analfabetismo'
+    }
+}).addValue({
+    name: 'modality_shift',
+    table: 'curso_superior_agregado',
+    tableField: 'turno_nivel_etapa',
+    resultField: 'modality_shift_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'turno_nivel_etapa'
+    }
+}).addValue({
+    name: 'bolsa_familia',
+    table: 'curso_superior_agregado',
+    tableField: 'recebeu_rendimentos_de_programa_bolsa_familia',
+    resultField: 'bolsa_familia_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'recebeu_rendimentos_de_programa_bolsa_familia'
+    }
+}).addValue({
+    name: 'new_pnad_ethnic_group',
+    table: 'curso_superior_agregado',
+    tableField: 'cor_raca',
+    resultField: 'new_pnad_ethnic_group_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cor_raca'
+    }
+}).addValue({
+    name: 'age_range_all',
+    table: 'curso_superior_agregado',
+    tableField: 'faixa_etaria',
+    resultField: 'age_range_all_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'faixa_etaria'
+    }
+}).addValue({
+    name: 'income_range',
+    table: 'curso_superior_agregado',
+    tableField: 'faixa_rendimento_aux',
+    resultField: 'income_range_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'faixa_rendimento_aux'
+    }
+}).addValue({
+    name: 'gender',
+    table: 'curso_superior_agregado',
+    tableField: 'sexo',
+    resultField: 'gender_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'sexo'
+    }
+}).addValue({
+    name: 'cap_code',
+    table: 'curso_superior_agregado',
+    tableField: 'cod_cap',
+    resultField: 'cap_code_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_cap'
+    }
+}).addValue({
+    name: 'region',
+    table: 'curso_superior_agregado',
+    tableField: 'cod_regiao',
+    resultField: 'region_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_regiao'
+    }
+}).addValue({
+    name: 'metro_code',
+    table: 'curso_superior_agregado',
+    tableField: 'cod_rm_ride',
+    resultField: 'metro_code_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_rm_ride'
+    }
+}).addValue({
+    name: 'min_year',
+    table: 'curso_superior_agregado',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '>=',
+        type: 'integer',
+        field: 'ano_censo'
+    }
+}).addValue({
+    name: 'max_year',
+    table: 'curso_superior_agregado',
+    tableField: '',
+    resultField: 'year',
+    where: {
+        relation: '<=',
+        type: 'integer',
+        field: 'ano_censo'
+    }
+}).addField({
+    name: 'search',
+    field: false,
+    where: true
+}).addValueToField({
+    name: 'name',
+    table: 'curso_superior_agregado',
+    tableField: 'nome',
+    where: {
+        relation: 'LIKE',
+        type: 'string',
+        field: 'nome'
+    }
+}, 'search').addValue({
+    name: 'mesoregion',
+    table: 'curso_superior_agregado',
+    tableField: 'mesorregiao_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'mesorregiao_id'
+    }
+}).addValue({
+    name: 'microregion',
+    table: 'curso_superior_agregado',
+    tableField: 'microrregiao_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'microrregiao_id'
+    }
+});
+
+CourseAggregateApp.get('/', rqf.parse(), rqf.build(),  (req, res, next) => {
+    req.sql.from('curso_superior_agregado')
+    .field('count(distinct(cod_curso))', 'total')
+    .field('curso_superior_agregado.ano_censo', 'year')
+    .group('curso_superior_agregado.ano_censo')
+    .order('curso_superior_agregado.ano_censo')
+    console.log(req.sql.toString())
+    next();
+}, query, id2str.transform(false), response('curso_superior_agregado'));
+
+module.exports = CourseAggregateApp;
-- 
GitLab


From 7f3c3d5fe03ef92173fabe095958611fd7a09bab Mon Sep 17 00:00:00 2001
From: fgs21 <fgs21@inf.ufpr.br>
Date: Thu, 5 Sep 2024 09:36:25 -0300
Subject: [PATCH 05/26] [FIX] Trying to match the 2 queries right

---
 src/libs/routes_v1/rateSchoolNew.js | 53 ++++++++++++++++++++++-------
 1 file changed, 41 insertions(+), 12 deletions(-)

diff --git a/src/libs/routes_v1/rateSchoolNew.js b/src/libs/routes_v1/rateSchoolNew.js
index a6ae0218..c6ca6a00 100644
--- a/src/libs/routes_v1/rateSchoolNew.js
+++ b/src/libs/routes_v1/rateSchoolNew.js
@@ -308,20 +308,49 @@ rqf.addField({
     }
 });
 
-// The queries are matched and the total is calculated
-function matchQueries(attendsSchoolObj, populationObj) {
-    let match = [];
-
-    for (let i = 0; i < attendsSchoolObj.length; i++) {
-        let newObj = attendsSchoolObj[i];
-
-        newObj.total = (attendsSchoolObj[i].total / populationObj[i].total) * 100;
+/* 
+    The queries are matched and the total is calculated.
+    This function is necessary to match the results of the
+    2 queries with the right pair. In some queries, the result
+    doesn't exist in one of the 2, so, we need to run this algorithm
+    to match them right.
+*/
 
-        newObj.age_range_id = newObj.faixa_etaria;
-        delete newObj.faixa_etaria;
+function matchQueries(queryTotal, queryPartial) {
+    let match = [];
+    queryTotal.forEach((result) => {
+        let newObj = {};
+        let keys = Object.keys(result);
+        keys.forEach((key) => {
+            newObj[key] = result[key];
+        });
+        let index = keys.indexOf('total');
+        if(index > -1) keys.splice(index, 1);
+        let objMatch = null;
+
+        for(let i = 0; i < queryPartial.length; ++i) {
+            let partial = queryPartial[i];
+            let foundMatch = true;
+            for(let j = 0; j < keys.length; ++j) {
+                let key = keys[j];
+                if(partial[key] !== result[key]) {
+                    foundMatch = false;
+                    break;
+                }
+            }
+            if(foundMatch) {
+                objMatch = partial;
+                break;
+            }
+        }
 
-        match.push(newObj);
-    }
+        if(objMatch) {
+            newObj.denominator = result.total;
+            newObj.partial = objMatch.total;
+            newObj.total = (objMatch.total / result.total) * 100;
+            match.push(newObj);
+        }
+    });
 
     return match;
 }
-- 
GitLab


From 927e8e15f269825bdd3bed973f0cd7a125cec9a4 Mon Sep 17 00:00:00 2001
From: fgs21 <fgs21@inf.ufpr.br>
Date: Thu, 5 Sep 2024 09:52:47 -0300
Subject: [PATCH 06/26] [FIX] matchQueries() parameters switched

---
 src/libs/routes_v1/rateSchoolNew.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libs/routes_v1/rateSchoolNew.js b/src/libs/routes_v1/rateSchoolNew.js
index c6ca6a00..237edfa1 100644
--- a/src/libs/routes_v1/rateSchoolNew.js
+++ b/src/libs/routes_v1/rateSchoolNew.js
@@ -316,7 +316,7 @@ rqf.addField({
     to match them right.
 */
 
-function matchQueries(queryTotal, queryPartial) {
+function matchQueries(queryPartial, queryTotal) {
     let match = [];
     queryTotal.forEach((result) => {
         let newObj = {};
-- 
GitLab


From 12651034de00229f458766fe98b0589c64a5ea75 Mon Sep 17 00:00:00 2001
From: Lewis <lgtg20@inf.ufpr.br>
Date: Thu, 5 Sep 2024 16:02:43 -0300
Subject: [PATCH 07/26] Refactor federativeEntity route to include state and
 region filters

---
 src/libs/routes_v1/federativeEntity.js | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/libs/routes_v1/federativeEntity.js b/src/libs/routes_v1/federativeEntity.js
index fb200e65..4a356247 100644
--- a/src/libs/routes_v1/federativeEntity.js
+++ b/src/libs/routes_v1/federativeEntity.js
@@ -429,8 +429,6 @@ rqf.addField({
 
 federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
 
-    console.log(req.query);
-
     if (req.query.dims && req.query.dims.includes('education_level_mod_entity_seg'))
     {
         req.sql.from('docentes_sinopse')
@@ -559,7 +557,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
             .order('docentes_sinopse.ano_censo')
             .where('docentes_sinopse.cod_reg = 0');
     }
-    else if (req.query.dims && req.query.dims.includes('state')) {
+    else if ((req.query.dims && req.query.dims.includes('state')) || (req.query.filter && req.query.filter.includes('state'))) {
         req.sql.from('docentes_sinopse')
         .field('SUM(docentes_sinopse.num_doc_ed_bas_total)', 'total')
         .field('docentes_sinopse.ano_censo', 'year')
@@ -567,7 +565,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .order('docentes_sinopse.ano_censo')
         .where('docentes_sinopse.cod_mun = 0');
     }
-    else if (req.query.dims && req.query.dims.includes('region')) {
+    else if ((req.query.dims && req.query.dims.includes('region')) || (req.query.filter && req.query.filter.includes('region'))) {
         req.sql.from('docentes_sinopse')
         .field('SUM(docentes_sinopse.num_doc_ed_bas_total)', 'total')
         .field('docentes_sinopse.ano_censo', 'year')
-- 
GitLab


From 9aab5ca064a399efe313336136cd89a9aafb9b49 Mon Sep 17 00:00:00 2001
From: Lewis <lgtg20@inf.ufpr.br>
Date: Thu, 5 Sep 2024 19:25:46 -0300
Subject: [PATCH 08/26] Bug fix enrollmentAggregate and federativeEntity

---
 src/libs/convert/diffLocation.js           |  2 ++
 src/libs/convert/specialEducationEntity.js | 31 ++++++++++++++++++++++
 src/libs/middlewares/aggregateData.js      |  2 ++
 src/libs/middlewares/id2str.js             |  7 +++--
 src/libs/routes_v1/enrollmentAggregate.js  |  4 +--
 src/libs/routes_v1/federativeEntity.js     |  8 +++---
 6 files changed, 46 insertions(+), 8 deletions(-)
 create mode 100644 src/libs/convert/specialEducationEntity.js

diff --git a/src/libs/convert/diffLocation.js b/src/libs/convert/diffLocation.js
index 16441ca7..aadc9cf6 100644
--- a/src/libs/convert/diffLocation.js
+++ b/src/libs/convert/diffLocation.js
@@ -30,5 +30,7 @@ module.exports = function location(id) {
             return 'Área remanescente de quilombos';
 		case 8:
 			return 'Área onde se localizam povos e comunidades tradicionais';
+        default:
+            return 'Não definido';
     }
 };
diff --git a/src/libs/convert/specialEducationEntity.js b/src/libs/convert/specialEducationEntity.js
new file mode 100644
index 00000000..b358c4ed
--- /dev/null
+++ b/src/libs/convert/specialEducationEntity.js
@@ -0,0 +1,31 @@
+/*
+Copyright (C) 2022 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function specialEducation(id) {
+    switch (id) {
+        case 1:
+        return 'Classe Comum';
+        case 2:
+        return 'Classe Exclusiva';
+        default:
+        return 'Não definido';
+    }
+};
+  
diff --git a/src/libs/middlewares/aggregateData.js b/src/libs/middlewares/aggregateData.js
index 3dadee22..aaa1ede4 100644
--- a/src/libs/middlewares/aggregateData.js
+++ b/src/libs/middlewares/aggregateData.js
@@ -22,6 +22,7 @@ const convert = {
     modality_integral_time: 'educationLevelBasic',
     special_education: 'specialEducation',
     special_education_doc: 'specialEducationDoc',
+    special_education_entity: 'specialEducationEntity',
     education_level_mod_doc: 'educationLevelModDoc',
     education_level_mod_entity_seg: 'educationLevelModEntitySeg',
     education_level_mod_entity_agg: 'educationLevelModEntityAgg',
@@ -48,6 +49,7 @@ function aggregateData(req, res, next) {
             'modality_integral_time', 
             'special_education',
             'special_education_doc',
+            'special_education_entity',
             'education_level_mod_entity_seg',
             'education_level_mod_entity_agg',
             'adm_dependency_entity_agg',
diff --git a/src/libs/middlewares/id2str.js b/src/libs/middlewares/id2str.js
index 08a1ebed..078df393 100644
--- a/src/libs/middlewares/id2str.js
+++ b/src/libs/middlewares/id2str.js
@@ -118,6 +118,7 @@ const incomeRange = require(`${libs}/convert/incomeRange`);
 const ageRangeAggregate = require(`${libs}/convert/ageRangeAggregate`);
 const specialEducation = require(`${libs}/convert/specialEducation`);
 const specialEducationDoc = require(`${libs}/convert/specialEducationDoc`);
+const specialEducationEntity = require(`${libs}/convert/specialEducationEntity`);
 const educationLevelModDoc = require(`${libs}/convert/educationLevelModDoc`);
 const educationLevelModEntitySeg = require(`${libs}/convert/educationLevelModEntitySeg`);
 const educationLevelModEntityAgg = require(`${libs}/convert/educationLevelModEntityAgg`);
@@ -238,7 +239,8 @@ const ids = {
     education_level_mod_entity_seg: educationLevelModEntitySeg,
     education_level_mod_entity_agg: educationLevelModEntityAgg,
     age_range_entity: ageRangeEntity,
-    post_graduation_entity: postGraduationEntity
+    post_graduation_entity: postGraduationEntity,
+    special_education_entity: specialEducationEntity
 };
 
 function transform(removeId=false) {
@@ -376,5 +378,6 @@ module.exports = {
     educationLevelModEntitySeg,
     educationLevelModEntityAgg,
     ageRangeEntity,
-    postGraduationEntity
+    postGraduationEntity,
+    specialEducationEntity
 };
diff --git a/src/libs/routes_v1/enrollmentAggregate.js b/src/libs/routes_v1/enrollmentAggregate.js
index d266d240..08d55ddb 100644
--- a/src/libs/routes_v1/enrollmentAggregate.js
+++ b/src/libs/routes_v1/enrollmentAggregate.js
@@ -114,7 +114,7 @@ enrollmentAggregateApp.get('/location', (req, res, next) => {
 enrollmentAggregateApp.get('/diff_location', (req, res, next) => {
     req.result = []
 
-    for (let i = 0; i <= 4; i++) {
+    for (let i = 0; i < 4; i++) {
         req.result.push({
             id: i, name: id2str.diffLocation(i)
         });
@@ -587,7 +587,7 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('SUM(escola.qt_mat_bas)', 'total')
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
-        .order('escola.ano_censo');
+        .order('escola.ano_censo')
     }
     next();
 }, query, aggregateData, id2str.transform(false), response('enrollment_aggregate'));
diff --git a/src/libs/routes_v1/federativeEntity.js b/src/libs/routes_v1/federativeEntity.js
index 4a356247..0b0c2b5c 100644
--- a/src/libs/routes_v1/federativeEntity.js
+++ b/src/libs/routes_v1/federativeEntity.js
@@ -212,17 +212,17 @@ federativeEntityApp.get('/state', (req, res, next) => {
     next();
 }, response('state'));
 
-federativeEntityApp.get('/special_education', (req, res, next) => {
+federativeEntityApp.get('/special_education_entity', (req, res, next) => {
     req.result = []
 
     for (let i = 1; i <= 2; i++) {
         req.result.push({
-            id: i, name: id2str.specialEducation(i)
+            id: i, name: id2str.specialEducationEntity(i)
         });
     }
 
     next();
-}, response('special_education'));
+}, response('special_education_entity'));
 
 
 rqf.addField({
@@ -467,7 +467,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .order('docentes_sinopse.ano_censo')
         .where('docentes_sinopse.cod_reg = 0');
     }
-    else if (req.query.dims && req.query.dims.includes('special_education'))
+    else if (req.query.dims && req.query.dims.includes('special_education_entity'))
     {
         req.sql.from('docentes_sinopse')
         .field('SUM(docentes_sinopse.num_doc_ed_especial_classe_comum)', 'total_doc_ed_especial_classe_comum')
-- 
GitLab


From e2818eeef576e3edcea33e46a4cd53d26201cd37 Mon Sep 17 00:00:00 2001
From: fgs21 <fgs21@inf.ufpr.br>
Date: Wed, 11 Sep 2024 10:45:04 -0300
Subject: [PATCH 09/26] [ADD] First test version done, updating to test in
 development

---
 src/libs/routes_v1/courseAggregate.js | 347 +++++++++-----------------
 1 file changed, 119 insertions(+), 228 deletions(-)

diff --git a/src/libs/routes_v1/courseAggregate.js b/src/libs/routes_v1/courseAggregate.js
index 9b372c38..9be3a7ed 100644
--- a/src/libs/routes_v1/courseAggregate.js
+++ b/src/libs/routes_v1/courseAggregate.js
@@ -48,7 +48,7 @@ CourseAggregateApp.get('/years', (req, res, next) => {
     next();
 }, query, response('years'));
 
-courseAggregateApp.get('/upper_adm_dependency', (req, res, next) => {
+CourseAggregateApp.get('/upper_adm_dependency', (req, res, next) => {
     req.result = [];
     for(let i = 1; i <= 7; ++i) {
         req.result.push({
@@ -59,7 +59,7 @@ courseAggregateApp.get('/upper_adm_dependency', (req, res, next) => {
     next();
 }, response('upper_adm_dependency'));
 
-courseCountApp.get('/academic_organization', (req, res, next) => {
+CourseAggregateAppApp.get('/academic_organization', (req, res, next) => {
     req.result = [];
     for(let i = 1; i <= 5; ++i) {
         req.result.push({
@@ -70,7 +70,7 @@ courseCountApp.get('/academic_organization', (req, res, next) => {
     next();
 }, response('academic_organization'));
 
-courseCountApp.get('/academic_level', (req, res, next) => {
+CourseAggregateAppApp.get('/academic_level', (req, res, next) => {
     req.result = [];
     for(let i = 1; i <= 4; ++i) {
         req.result.push({
@@ -81,16 +81,16 @@ courseCountApp.get('/academic_level', (req, res, next) => {
     next();
 }, response('academic_level'));
 
-CourseAggregateApp.get('/new_pnad_adm_dependency', (req, res, next) => {
-    req.result = []
-    for (let i = 1; i < 3; i++) {
+CourseAggregateApp.get('/upper_education_mod', (req, res, next) => {
+    req.result = [];
+    for(let i = 1; i <= 2; ++i) {
         req.result.push({
-            id: i, name: id2str.newPnadAdmDependency(i)
+            id: i,
+            name: id2str.upperEducationMod(i)
         });
-    }
-    req.result.push({id: 99, name: id2str.newPnadAdmDependency(99)});
+    };
     next();
-}, response('new_pnad_adm_dependency'));
+}, response('upper_education_mod'));
 
 CourseAggregateApp.get('/region', (req, res, next) => {
     req.result = []
@@ -131,94 +131,72 @@ CourseAggregateApp.get('/metro_code', (req, res, next) => {
     next();
 }, response('metro_code'));
 
-CourseAggregateApp.get('/attended_modality', (req, res, next) => {
-    req.result = []
-    for (let i = 1; i < 16; i++) {
-        req.result.push({
-            id: i, name: id2str.attendedModality(i)
-        });
-    }
-    // Remove the option with id equals 10 => This option exists in the database, a better solution to this would be remove the option from the database
-    req.result.splice(req.result.findIndex((item) => item.id === 10), 1);
-    req.result.push({id: 99, name: id2str.attendedModality(99)});
+CourseAggregateAppApp.get('/is_free', (req, res, next) => {
+    req.result = [
+        {id: null, name: 'Não Classificado'},
+        {id: 0, name: 'Não'},
+        {id: 1, name: 'Sim'}
+    ];
     next();
-}, response('attended_modality'));
+}, response('is_free'));
 
-CourseAggregateApp.get('/income_range', (req, res, next) => {
-    req.result = []
-    for (let i = 1; i < 8; i++) {
-        req.result.push({
-            id: i, name: id2str.incomeRange(i)
-        });
-    }
-    req.result.push({id: 9, name: id2str.incomeRange(9)});
-    next();
-}, response('income_range'));
 
-CourseAggregateApp.get('/attends_school', (req, res, next) => {
-    req.result = []
-    for (let i = 1; i < 3; i++) {
-        req.result.push({
-            id: i, name: id2str.attendsSchool(i)
-        });
-    }
-    next();
-}, response('attends_school'));
-
-CourseAggregateApp.get('/gender', (req, res, next) => {
-    req.result = []
-    for (let i = 1; i < 3; i++) {
-        req.result.push({
-            id: i, name: id2str.gender(i)
-        });
-    }
-    next();
-}, response('gender'));
-
-CourseAggregateApp.get('/new_pnad_ethnic_group', (req, res, next) => {
-    req.result = []
-    for (let i = 1; i < 6; i++) {
+CourseAggregateApp.get('/cine_geral', (req, res, next) => {
+    req.result = [];
+    for(let i = 1; i <= 10; ++i) {
         req.result.push({
-            id: i, name: id2str.ethnicGroupNewPnad(i)
+            id: i,
+            name: id2str.cineGeral(i)
         });
-    }
-    req.result.push({id: 9, name: id2str.ethnicGroupNewPnad(9)});
+    };
     next();
-}, response('new_pnad_ethnic_group'));
+}, response('cine_geral'));
 
-CourseAggregateApp.get('/bolsa_familia', (req, res, next) => {
-    req.result = []
-    for (let i = 1; i < 3; i++) {
-        req.result.push({
-            id: i, name: id2str.attendsSchool(i)
-        });
-    }
-    req.result.push({id: 9, name: id2str.attendsSchool(9)});
+CourseAggregateApp.get('/cine_specific', (req, res, next) => {
+    req.result = [];
+    const defaultCase = null;
+    for(let i = 1; i <= 104; ++i) {
+        let obj = {
+            id: i,
+            name: id2str.cineSpecific(i)
+        };
+        if (obj.name !== id2str.cineSpecific(defaultCase)){
+            req.result.push(obj);
+        }
+    };
+    req.result.push({
+        id: defaultCase,
+        name: id2str.cineSpecific(defaultCase)
+    });
     next();
-}, response('bolsa_familia'));
+}, response('cine_specific'));
 
-CourseAggregateApp.get('/modality', (req, res, next) => {
-    req.result = []
-    for (let i = 1; i < 4; i++) {
-        req.result.push({
-            id: i, name: id2str.modality(i)
-        });
-    }
-    req.result.push({id: 99, name: id2str.modality(99)});
+CourseAggregateApp.get('/cine_detailed', (req, res, next) => {
+    req.result = [];
+    const defaultCase = null;
+    for(let i = 11; i <= 1041; ++i) {
+        let obj = {
+            id: i,
+            name: id2str.cineDetailed(i)
+        };
+        if (obj.name !== id2str.cineDetailed(defaultCase)){
+            req.result.push(obj);
+        }
+    };
+    req.result.push({
+        id: defaultCase,
+        name: id2str.cineDetailed(defaultCase)
+    });
     next();
-}, response('modality'));
+}, response('cine_detailed'));
 
-CourseAggregateApp.get('/modality_shift', (req, res, next) => {
-    req.result = []
-    for (let i = 1; i < 8; i++) {
-        req.result.push({
-            id: i, name: id2str.modalityShift(i)
-        });
-    }
-    req.result.push({id: 9, name: id2str.modalityShift(9)});
-    req.result.push({id: 99, name: id2str.modalityShift(99)});
+CourseAggregateApp.get('/university', (req, res, next) => {
+    req.sql.from('curso_superior_agregado')
+    .field('DISTINCT curso_superior_agregado.cod_ies', 'cod')
+    .field('ies_ens_superior.cod_ies', 'nome')
+    .join('ies_ens_superior', null, 'curso_superior_agregado.cod_ies = ies_ens_superior.cod_ies and curso_superior_agregado.ano_censo = ies_ens_superior.ano_censo')
     next();
-}, response('modality_shift'));
+}, query, response('university'));
 
 CourseAggregateApp.get('/state', (req, res, next) => {
     req.result = []
@@ -234,18 +212,6 @@ CourseAggregateApp.get('/state', (req, res, next) => {
     next();
 }, response('state'));
 
-CourseAggregateApp.get('/age_range_all', (req, res, next) => {
-    req.result = []
-    for (let i = 1; i < 12; i++) {
-        req.result.push({
-            id: i, name: id2str.ageRangeAll(i)
-        });
-    }
-
-    next();
-}, response('age_range_all'));
-
-
 rqf.addField({
     name: 'filter',
     field: false,
@@ -255,13 +221,14 @@ rqf.addField({
     field: true,
     where: false
 }).addValue({
-    name: 'adm_category',
+    name: 'upper_adm_dependency',
     table: 'curso_superior_agregado',
-    tableField: 'id',
+    tableField: 'tp_categ_adm',
+    resultField: 'upper_adm_dependency_id',
     where: {
         relation: '=',
         type: 'integer',
-        field: 'id'
+        field: 'tp_categ_adm'
     }
 }).addValue({
     name: 'state',
@@ -279,150 +246,89 @@ rqf.addField({
         foreignTable: 'curso_superior_agregado'
     }
 }).addValue({
-    name: 'state_not',
-    table: 'estado',
-    tableField: ['nome', 'id'],
-    resultField: ['state_name', 'state_id'],
-    where: {
-        relation: '<>',
-        type: 'integer',
-        field: 'cod_uf',
-        table: 'curso_superior_agregado'
-    },
-    join: {
-        primary: 'id',
-        foreign: 'cod_uf',
-        foreignTable: 'curso_superior_agregado'
-    }
-}).addValue({
-    name: 'years_of_study',
-    table: 'curso_superior_agregado',
-    tableField: 'anos_de_estudo',
-    resultField: 'years_of_study_id',
-    where: {
-        relation: '=',
-        type: 'integer',
-        field: 'anos_de_estudo'
-    }
-}).addValue({
-    name: 'instruction_level',
-    table: 'curso_superior_agregado',
-    tableField: 'nivel_de_instrucao',
-    resultField: 'instruction_level_id',
-    where: {
-        relation: '=',
-        type: 'integer',
-        field: 'nivel_de_instrucao'
-    }
-}).addValue({
-    name: 'new_pnad_adm_dependency',
-    table: 'curso_superior_agregado',
-    tableField: 'dependencia_adm',
-    resultField: 'new_pnad_adm_dependency_id',
-    where: {
-        relation: '=',
-        type: 'integer',
-        field: 'dependencia_adm'
-    }
-}).addValue({
-    name: 'attends_school',
-    table: 'curso_superior_agregado',
-    tableField: 'frequenta_escola',
-    resultField: 'attends_school_id',
-    where: {
-        relation: '=',
-        type: 'integer',
-        field: 'frequenta_escola'
-    }
-}).addValue({
-    name: 'modality',
-    table: 'curso_superior_agregado',
-    tableField: 'modalidade',
-    resultField: 'modality_id',
-    where: {
-        relation: '=',
-        type: 'integer',
-        field: 'modalidade'
-    }
-}).addValue({
-    name: 'attended_modality',
+    name: 'academic_organization',
     table: 'curso_superior_agregado',
-    tableField: 'nivel_etapa_modalidade_freq',
-    resultField: 'attended_modality_id',
+    tableField: 'tp_org_acad',
+    resultField: 'academic_organization_id',
     where: {
         relation: '=',
         type: 'integer',
-        field: 'nivel_etapa_modalidade_freq'
+        field: 'tp_org_aca'
     }
 }).addValue({
-    name: 'illiteracy',
+    name: 'academic_level',
     table: 'curso_superior_agregado',
-    tableField: 'analfabetismo',
-    resultField: 'illiteracy_id',
+    tableField: 'tp_grau_acad',
+    resultField: 'academic_level_id',
     where: {
         relation: '=',
         type: 'integer',
-        field: 'analfabetismo'
+        field: 'tp_grau_acad'
     }
 }).addValue({
-    name: 'modality_shift',
+    name: 'upper_education_mod',
     table: 'curso_superior_agregado',
-    tableField: 'turno_nivel_etapa',
-    resultField: 'modality_shift_id',
+    tableField: 'tp_modal_ens',
+    resultField: 'upper_education_mod_id',
     where: {
         relation: '=',
         type: 'integer',
-        field: 'turno_nivel_etapa'
+        field: 'tp_modal_ens'
     }
 }).addValue({
-    name: 'bolsa_familia',
+    name: 'is_free',
     table: 'curso_superior_agregado',
-    tableField: 'recebeu_rendimentos_de_programa_bolsa_familia',
-    resultField: 'bolsa_familia_id',
+    tableField: 'in_gratuito',
+    resultField: 'is_free_id',
     where: {
         relation: '=',
-        type: 'integer',
-        field: 'recebeu_rendimentos_de_programa_bolsa_familia'
+        type: 'boolean',
+        field: 'in_gratuito'
     }
 }).addValue({
-    name: 'new_pnad_ethnic_group',
+    name: 'cine_geral',
     table: 'curso_superior_agregado',
-    tableField: 'cor_raca',
-    resultField: 'new_pnad_ethnic_group_id',
+    tableField: 'cod_cine_area_geral',
+    resultField: 'cine_geral_id',
     where: {
         relation: '=',
         type: 'integer',
-        field: 'cor_raca'
+        field: 'cod_cine_area_geral'
     }
 }).addValue({
-    name: 'age_range_all',
+    name: 'cine_specific',
     table: 'curso_superior_agregado',
-    tableField: 'faixa_etaria',
-    resultField: 'age_range_all_id',
+    tableField: 'cod_cine_area_esp',
+    resultField: 'cine_specific_id',
     where: {
         relation: '=',
         type: 'integer',
-        field: 'faixa_etaria'
+        field: 'cod_cine_area_esp'
     }
 }).addValue({
-    name: 'income_range',
+    name: 'cine_detailed',
     table: 'curso_superior_agregado',
-    tableField: 'faixa_rendimento_aux',
-    resultField: 'income_range_id',
+    tableField: 'cod_cine_area_detalhada',
+    resultField: 'cine_detailed_id',
     where: {
         relation: '=',
         type: 'integer',
-        field: 'faixa_rendimento_aux'
+        field: 'cod_cine_area_detalhada'
     }
 }).addValue({
-    name: 'gender',
-    table: 'curso_superior_agregado',
-    tableField: 'sexo',
-    resultField: 'gender_id',
+    name: 'university',
+    table: 'ies_ens_superior',
+    tableField: ['cod_ies', 'nome_ies'],
+    resultField: ['university_id', 'university_name'],
     where: {
         relation: '=',
         type: 'integer',
-        field: 'sexo'
+        field: 'cod_ies'
+    },
+    join: {
+        primary: ['cod_ies', 'ano_censo'],
+        foreign: ['cod_ies', 'ano_censo'],
+        foreignTable: 'curso_superior_agregado'
     }
 }).addValue({
     name: 'cap_code',
@@ -474,36 +380,21 @@ rqf.addField({
         type: 'integer',
         field: 'ano_censo'
     }
-}).addField({
-    name: 'search',
-    field: false,
-    where: true
-}).addValueToField({
-    name: 'name',
-    table: 'curso_superior_agregado',
-    tableField: 'nome',
-    where: {
-        relation: 'LIKE',
-        type: 'string',
-        field: 'nome'
-    }
-}, 'search').addValue({
-    name: 'mesoregion',
-    table: 'curso_superior_agregado',
-    tableField: 'mesorregiao_id',
-    where: {
-        relation: '=',
-        type: 'integer',
-        field: 'mesorregiao_id'
-    }
 }).addValue({
-    name: 'microregion',
-    table: 'curso_superior_agregado',
-    tableField: 'microrregiao_id',
+    name: 'city',
+    table: 'municipio',
+    tableField: ['id', 'nome'],
+    resultField: ['city_id', 'city_name'],
     where: {
         relation: '=',
         type: 'integer',
-        field: 'microrregiao_id'
+        field: 'id',
+        table: 'municipio'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_mun',
+        foreignTable: 'curso_superior_agregado'
     }
 });
 
@@ -515,6 +406,6 @@ CourseAggregateApp.get('/', rqf.parse(), rqf.build(),  (req, res, next) => {
     .order('curso_superior_agregado.ano_censo')
     console.log(req.sql.toString())
     next();
-}, query, id2str.transform(false), response('curso_superior_agregado'));
+}, query, id2str.transform(false), response('course_aggregate'));
 
 module.exports = CourseAggregateApp;
-- 
GitLab


From 6ccbd774768cc7382f684fe2eaed6b53bc62fe96 Mon Sep 17 00:00:00 2001
From: fgs21 <fgs21@inf.ufpr.br>
Date: Wed, 11 Sep 2024 11:04:56 -0300
Subject: [PATCH 10/26] [FIX] CourseAggregateApp name fix

---
 src/libs/routes_v1/courseAggregate.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/libs/routes_v1/courseAggregate.js b/src/libs/routes_v1/courseAggregate.js
index 9be3a7ed..b9dc7f61 100644
--- a/src/libs/routes_v1/courseAggregate.js
+++ b/src/libs/routes_v1/courseAggregate.js
@@ -59,7 +59,7 @@ CourseAggregateApp.get('/upper_adm_dependency', (req, res, next) => {
     next();
 }, response('upper_adm_dependency'));
 
-CourseAggregateAppApp.get('/academic_organization', (req, res, next) => {
+CourseAggregateApp.get('/academic_organization', (req, res, next) => {
     req.result = [];
     for(let i = 1; i <= 5; ++i) {
         req.result.push({
@@ -70,7 +70,7 @@ CourseAggregateAppApp.get('/academic_organization', (req, res, next) => {
     next();
 }, response('academic_organization'));
 
-CourseAggregateAppApp.get('/academic_level', (req, res, next) => {
+CourseAggregateApp.get('/academic_level', (req, res, next) => {
     req.result = [];
     for(let i = 1; i <= 4; ++i) {
         req.result.push({
@@ -131,7 +131,7 @@ CourseAggregateApp.get('/metro_code', (req, res, next) => {
     next();
 }, response('metro_code'));
 
-CourseAggregateAppApp.get('/is_free', (req, res, next) => {
+CourseAggregateApp.get('/is_free', (req, res, next) => {
     req.result = [
         {id: null, name: 'Não Classificado'},
         {id: 0, name: 'Não'},
-- 
GitLab


From be1511b4c0a548c3b377d1e65d0811ce4dd6bc94 Mon Sep 17 00:00:00 2001
From: fgs21 <fgs21@inf.ufpr.br>
Date: Wed, 11 Sep 2024 11:33:16 -0300
Subject: [PATCH 11/26] [FIX] Fixing 'where' of the base query

---
 src/libs/routes_v1/courseAggregate.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/libs/routes_v1/courseAggregate.js b/src/libs/routes_v1/courseAggregate.js
index b9dc7f61..5ec2a3cb 100644
--- a/src/libs/routes_v1/courseAggregate.js
+++ b/src/libs/routes_v1/courseAggregate.js
@@ -402,6 +402,7 @@ CourseAggregateApp.get('/', rqf.parse(), rqf.build(),  (req, res, next) => {
     req.sql.from('curso_superior_agregado')
     .field('count(distinct(cod_curso))', 'total')
     .field('curso_superior_agregado.ano_censo', 'year')
+    .where('curso_superior_agregado.tp_nivel_acad = 1 AND qtd_cursos = 1')
     .group('curso_superior_agregado.ano_censo')
     .order('curso_superior_agregado.ano_censo')
     console.log(req.sql.toString())
-- 
GitLab


From c965932fb5948165ceaaf6931764cd4eec0babf5 Mon Sep 17 00:00:00 2001
From: fgs21 <fgs21@inf.ufpr.br>
Date: Thu, 12 Sep 2024 09:37:57 -0300
Subject: [PATCH 12/26] [FIX] Fixing /course_aggregate/university query

---
 src/libs/routes_v1/courseAggregate.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libs/routes_v1/courseAggregate.js b/src/libs/routes_v1/courseAggregate.js
index 5ec2a3cb..dbfb002f 100644
--- a/src/libs/routes_v1/courseAggregate.js
+++ b/src/libs/routes_v1/courseAggregate.js
@@ -193,7 +193,7 @@ CourseAggregateApp.get('/cine_detailed', (req, res, next) => {
 CourseAggregateApp.get('/university', (req, res, next) => {
     req.sql.from('curso_superior_agregado')
     .field('DISTINCT curso_superior_agregado.cod_ies', 'cod')
-    .field('ies_ens_superior.cod_ies', 'nome')
+    .field('ies_ens_superior.nome_ies', 'nome')
     .join('ies_ens_superior', null, 'curso_superior_agregado.cod_ies = ies_ens_superior.cod_ies and curso_superior_agregado.ano_censo = ies_ens_superior.ano_censo')
     next();
 }, query, response('university'));
-- 
GitLab


From 2e905451cf7003030c9178cc31c7e8b3715265bf Mon Sep 17 00:00:00 2001
From: fgs21 <fgs21@inf.ufpr.br>
Date: Fri, 13 Sep 2024 11:20:07 -0300
Subject: [PATCH 13/26] [FIX] Region filter column name fixed

---
 src/libs/routes_v1/courseAggregate.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libs/routes_v1/courseAggregate.js b/src/libs/routes_v1/courseAggregate.js
index dbfb002f..01773c05 100644
--- a/src/libs/routes_v1/courseAggregate.js
+++ b/src/libs/routes_v1/courseAggregate.js
@@ -343,12 +343,12 @@ rqf.addField({
 }).addValue({
     name: 'region',
     table: 'curso_superior_agregado',
-    tableField: 'cod_regiao',
+    tableField: 'cod_reg',
     resultField: 'region_id',
     where: {
         relation: '=',
         type: 'integer',
-        field: 'cod_regiao'
+        field: 'cod_reg'
     }
 }).addValue({
     name: 'metro_code',
-- 
GitLab


From 8320b5f8d6761ce97b5501441e1e3d4e891daa3e Mon Sep 17 00:00:00 2001
From: Lewis <lgtg20@inf.ufpr.br>
Date: Mon, 16 Sep 2024 23:26:44 -0300
Subject: [PATCH 14/26] Fix column name

---
 src/libs/routes_v1/universityLocalOffer.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libs/routes_v1/universityLocalOffer.js b/src/libs/routes_v1/universityLocalOffer.js
index 535094c4..88ed5ac0 100644
--- a/src/libs/routes_v1/universityLocalOffer.js
+++ b/src/libs/routes_v1/universityLocalOffer.js
@@ -84,7 +84,7 @@ rqf.addField({
     },
     join: {
         primary: 'nome',
-        foreign: 'nome_regiao_ies',
+        foreign: 'nome_regiao',
         foreignTable: 'localoferta_ens_superior'
     }
 
-- 
GitLab


From 2b0f7d7a4d5afd5a2133f48fbbc1f6db95c5e8f7 Mon Sep 17 00:00:00 2001
From: fgs21 <fgs21@inf.ufpr.br>
Date: Mon, 30 Sep 2024 10:46:04 -0300
Subject: [PATCH 15/26] [FIX] Fixing filter tp_org_acad

---
 src/libs/routes_v1/courseAggregate.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libs/routes_v1/courseAggregate.js b/src/libs/routes_v1/courseAggregate.js
index 01773c05..fdc6bd88 100644
--- a/src/libs/routes_v1/courseAggregate.js
+++ b/src/libs/routes_v1/courseAggregate.js
@@ -253,7 +253,7 @@ rqf.addField({
     where: {
         relation: '=',
         type: 'integer',
-        field: 'tp_org_aca'
+        field: 'tp_org_acad'
     }
 }).addValue({
     name: 'academic_level',
-- 
GitLab


From 94da1d736aa568654e091b04787952abc7573e2c Mon Sep 17 00:00:00 2001
From: fgs21 <fgs21@inf.ufpr.br>
Date: Tue, 8 Oct 2024 11:38:08 -0300
Subject: [PATCH 16/26] [ADD] Trying to search for university in
 courseAggregate

---
 src/libs/routes_v1/courseAggregate.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libs/routes_v1/courseAggregate.js b/src/libs/routes_v1/courseAggregate.js
index fdc6bd88..4fde328f 100644
--- a/src/libs/routes_v1/courseAggregate.js
+++ b/src/libs/routes_v1/courseAggregate.js
@@ -316,7 +316,7 @@ rqf.addField({
         field: 'cod_cine_area_detalhada'
     }
 }).addValue({
-    name: 'university',
+    name: 'universityLocalOffer',
     table: 'ies_ens_superior',
     tableField: ['cod_ies', 'nome_ies'],
     resultField: ['university_id', 'university_name'],
-- 
GitLab


From 87e65daa8fe9b31bc0254687bb848d9586667cff Mon Sep 17 00:00:00 2001
From: fgs21 <fgs21@inf.ufpr.br>
Date: Wed, 9 Oct 2024 09:44:11 -0300
Subject: [PATCH 17/26] [ADD] Creating new route to list all the universities
 above 2020

---
 src/libs/routes_v1/api.js                    |  3 +
 src/libs/routes_v1/uniLocalOfferAggregate.js | 89 ++++++++++++++++++++
 2 files changed, 92 insertions(+)
 create mode 100644 src/libs/routes_v1/uniLocalOfferAggregate.js

diff --git a/src/libs/routes_v1/api.js b/src/libs/routes_v1/api.js
index 1abfe6f0..bffc8b5d 100644
--- a/src/libs/routes_v1/api.js
+++ b/src/libs/routes_v1/api.js
@@ -155,6 +155,8 @@ const federativeEntity = require(`${libs}/routes_v1/federativeEntity`);
 
 const email = require(`${libs}/routes_v1/email`);
 
+const uniLocalOfferAggregate = require(`${libs}/routes_v1/uniLocalOfferAggregate`)
+
 api.get('/', (req, res) => {
     res.json({ msg: 'SimCAQ API v1 is running' });
 });
@@ -220,6 +222,7 @@ api.use('/enrollmentAggregate', enrollmentAggregate);
 api.use('/employeesAggregate', employeesAggregate);
 api.use('/course_aggregate', courseAggregate);
 api.use('/federativeEntity', federativeEntity);
+api.use('/uni_offer_aggregate', uniLocalOfferAggregate);
 
 
 //Publication 
diff --git a/src/libs/routes_v1/uniLocalOfferAggregate.js b/src/libs/routes_v1/uniLocalOfferAggregate.js
new file mode 100644
index 00000000..bed9d5b0
--- /dev/null
+++ b/src/libs/routes_v1/uniLocalOfferAggregate.js
@@ -0,0 +1,89 @@
+/*
+Copyright (C) 2024 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+const express = require('express');
+
+const uniLocalOfferAggregateApp = express.Router();
+
+const libs = `${process.cwd()}/libs`;
+
+const query = require(`${libs}/middlewares/query`).query;
+
+const response = require(`${libs}/middlewares/response`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+const config = require(`${libs}/config`); 
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
+
+let rqf = new ReqQueryFields();
+
+uniLocalOfferAggregateApp.use(cache('15 day'));
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'state',
+    table: 'estado',
+    tableField: ['id', 'nome'],
+    resultField: ['state_id', 'state_nome'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id',
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_uf',
+        foreignTable: 'curso_superior_agregado'
+    }
+}).addValue({
+    name: 'city',
+    table: 'municipio',
+    tableField: ['id', 'nome'],
+    resultField: ['city_id', 'city_name'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id',
+        table: 'municipio'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'cod_mun',
+        foreignTable: 'curso_superior_agregado'
+    }
+});
+
+
+uniLocalOfferAggregateApp.get('/', (req, res, next) => {
+    req.sql.from('curso_superior_agregado')
+    .field('DISTINCT curso_superior_agregado.cod_ies', 'cod')
+    .field('ies_ens_superior.nome_ies', 'nome')
+    .join('ies_ens_superior', null, 'curso_superior_agregado.cod_ies = ies_ens_superior.cod_ies and curso_superior_agregado.ano_censo = ies_ens_superior.ano_censo')
+    next();
+}, query, response('uni_offer_aggregate'));
\ No newline at end of file
-- 
GitLab


From ef7e957c3587f170bf9496bc63446b4e837bf60d Mon Sep 17 00:00:00 2001
From: fgs21 <fgs21@inf.ufpr.br>
Date: Wed, 9 Oct 2024 10:02:11 -0300
Subject: [PATCH 18/26] [ADD] Adding module.export to new route file

---
 src/libs/routes_v1/uniLocalOfferAggregate.js | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/libs/routes_v1/uniLocalOfferAggregate.js b/src/libs/routes_v1/uniLocalOfferAggregate.js
index bed9d5b0..184bc60d 100644
--- a/src/libs/routes_v1/uniLocalOfferAggregate.js
+++ b/src/libs/routes_v1/uniLocalOfferAggregate.js
@@ -79,11 +79,12 @@ rqf.addField({
     }
 });
 
-
 uniLocalOfferAggregateApp.get('/', (req, res, next) => {
     req.sql.from('curso_superior_agregado')
     .field('DISTINCT curso_superior_agregado.cod_ies', 'cod')
     .field('ies_ens_superior.nome_ies', 'nome')
     .join('ies_ens_superior', null, 'curso_superior_agregado.cod_ies = ies_ens_superior.cod_ies and curso_superior_agregado.ano_censo = ies_ens_superior.ano_censo')
     next();
-}, query, response('uni_offer_aggregate'));
\ No newline at end of file
+}, query, response('uni_offer_aggregate'));
+
+module.exports = uniLocalOfferAggregateApp;
\ No newline at end of file
-- 
GitLab


From cee0eee2ecda809fec64d0ff53d98d5b41168ed3 Mon Sep 17 00:00:00 2001
From: fgs21 <fgs21@inf.ufpr.br>
Date: Wed, 9 Oct 2024 10:59:32 -0300
Subject: [PATCH 19/26] [ADD] Adding rqf builders to the route, where it can
 build the query with filters/dims

---
 src/libs/routes_v1/uniLocalOfferAggregate.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/libs/routes_v1/uniLocalOfferAggregate.js b/src/libs/routes_v1/uniLocalOfferAggregate.js
index 184bc60d..28f6abdf 100644
--- a/src/libs/routes_v1/uniLocalOfferAggregate.js
+++ b/src/libs/routes_v1/uniLocalOfferAggregate.js
@@ -79,11 +79,12 @@ rqf.addField({
     }
 });
 
-uniLocalOfferAggregateApp.get('/', (req, res, next) => {
+uniLocalOfferAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     req.sql.from('curso_superior_agregado')
     .field('DISTINCT curso_superior_agregado.cod_ies', 'cod')
     .field('ies_ens_superior.nome_ies', 'nome')
     .join('ies_ens_superior', null, 'curso_superior_agregado.cod_ies = ies_ens_superior.cod_ies and curso_superior_agregado.ano_censo = ies_ens_superior.ano_censo')
+    .order('curso_superior_agregado.cod_ies')
     next();
 }, query, response('uni_offer_aggregate'));
 
-- 
GitLab


From bf7a6dacc8ef53beee68097bb935f0ff1c7f1a6f Mon Sep 17 00:00:00 2001
From: fgs21 <fgs21@inf.ufpr.br>
Date: Wed, 9 Oct 2024 11:34:03 -0300
Subject: [PATCH 20/26] [ADD] Changing route return names

---
 src/libs/routes_v1/uniLocalOfferAggregate.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libs/routes_v1/uniLocalOfferAggregate.js b/src/libs/routes_v1/uniLocalOfferAggregate.js
index 28f6abdf..ab50ef37 100644
--- a/src/libs/routes_v1/uniLocalOfferAggregate.js
+++ b/src/libs/routes_v1/uniLocalOfferAggregate.js
@@ -81,8 +81,8 @@ rqf.addField({
 
 uniLocalOfferAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     req.sql.from('curso_superior_agregado')
-    .field('DISTINCT curso_superior_agregado.cod_ies', 'cod')
-    .field('ies_ens_superior.nome_ies', 'nome')
+    .field('DISTINCT curso_superior_agregado.cod_ies', 'id')
+    .field('ies_ens_superior.nome_ies', 'name')
     .join('ies_ens_superior', null, 'curso_superior_agregado.cod_ies = ies_ens_superior.cod_ies and curso_superior_agregado.ano_censo = ies_ens_superior.ano_censo')
     .order('curso_superior_agregado.cod_ies')
     next();
-- 
GitLab


From e450bde4bff13edf286568c46f8a6e11860eaeb7 Mon Sep 17 00:00:00 2001
From: fgs21 <fgs21@inf.ufpr.br>
Date: Wed, 9 Oct 2024 11:55:54 -0300
Subject: [PATCH 21/26] [ADD] Adding new filters and new fields to query

---
 src/libs/routes_v1/uniLocalOfferAggregate.js | 33 ++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/src/libs/routes_v1/uniLocalOfferAggregate.js b/src/libs/routes_v1/uniLocalOfferAggregate.js
index ab50ef37..f50afff1 100644
--- a/src/libs/routes_v1/uniLocalOfferAggregate.js
+++ b/src/libs/routes_v1/uniLocalOfferAggregate.js
@@ -46,6 +46,36 @@ rqf.addField({
     name: 'dims',
     field: true,
     where: false
+}).addValue({
+    name: 'min_year',
+    table: 'curso_superior_agregado',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '>=',
+        type: 'integer',
+        field: 'ano_censo'
+    }
+}).addValue({
+    name: 'max_year',
+    table: 'curso_superior_agregado',
+    tableField: '',
+    resultField: 'year',
+    where: {
+        relation: '<=',
+        type: 'integer',
+        field: 'ano_censo'
+    }
+}).addValue({
+    name: 'region',
+    table: 'curso_superior_agregado',
+    tableField: 'cod_reg',
+    resultField: 'region_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_reg'
+    }
 }).addValue({
     name: 'state',
     table: 'estado',
@@ -83,6 +113,9 @@ uniLocalOfferAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) =>
     req.sql.from('curso_superior_agregado')
     .field('DISTINCT curso_superior_agregado.cod_ies', 'id')
     .field('ies_ens_superior.nome_ies', 'name')
+    .field('curso_superior_agregado.cod_mun', 'city_id')
+    .field('curso_superior_agregado.cod_uf', 'state_id')
+    .field('curso_superior_agregado.cod_reg', 'region_id')
     .join('ies_ens_superior', null, 'curso_superior_agregado.cod_ies = ies_ens_superior.cod_ies and curso_superior_agregado.ano_censo = ies_ens_superior.ano_censo')
     .order('curso_superior_agregado.cod_ies')
     next();
-- 
GitLab


From 5b1b6c62867727ed78836b94b4f7fbc738d28e0e Mon Sep 17 00:00:00 2001
From: fgs21 <fgs21@inf.ufpr.br>
Date: Wed, 9 Oct 2024 13:20:19 -0300
Subject: [PATCH 22/26] [FIX] Changing 'universityLocalOffer' filter to
 'uni_offer_aggregate' in courseAggregate route

---
 src/libs/routes_v1/courseAggregate.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libs/routes_v1/courseAggregate.js b/src/libs/routes_v1/courseAggregate.js
index 4fde328f..78ae89a7 100644
--- a/src/libs/routes_v1/courseAggregate.js
+++ b/src/libs/routes_v1/courseAggregate.js
@@ -316,7 +316,7 @@ rqf.addField({
         field: 'cod_cine_area_detalhada'
     }
 }).addValue({
-    name: 'universityLocalOffer',
+    name: 'uni_offer_aggregate',
     table: 'ies_ens_superior',
     tableField: ['cod_ies', 'nome_ies'],
     resultField: ['university_id', 'university_name'],
-- 
GitLab


From 8e60594c2691496be1557d8a43a4a7b9a469eed0 Mon Sep 17 00:00:00 2001
From: Lewis <lgtg20@inf.ufpr.br>
Date: Fri, 11 Oct 2024 12:04:50 -0300
Subject: [PATCH 23/26] Fix issues 906, 909, 910

---
 src/libs/convert/educationLevelBasic.js   |  6 +-
 src/libs/convert/totalDoc.js              | 23 ++++++++
 src/libs/middlewares/aggregateData.js     |  6 +-
 src/libs/middlewares/id2str.js            |  7 ++-
 src/libs/routes_v1/employeesAggregate.js  |  8 +++
 src/libs/routes_v1/enrollmentAggregate.js | 27 ++++++---
 src/libs/routes_v1/federativeEntity.js    | 70 +++++++++++++++++------
 7 files changed, 114 insertions(+), 33 deletions(-)
 create mode 100644 src/libs/convert/totalDoc.js

diff --git a/src/libs/convert/educationLevelBasic.js b/src/libs/convert/educationLevelBasic.js
index 3d166fe5..7c242b07 100644
--- a/src/libs/convert/educationLevelBasic.js
+++ b/src/libs/convert/educationLevelBasic.js
@@ -24,11 +24,11 @@ module.exports = function educationLevelBasic(id) {
         return 'Creche';
         case 2:
         return 'Pré-Escola';
-        case 4:
+        case 3:
         return 'Ensino Fundamental - anos iniciais';
-        case 5:
+        case 4:
         return 'Ensino Fundamental - anos finais';
-        case 6:
+        case 5:
         return 'Ensino Médio';
         default:
         return 'Não classificada';
diff --git a/src/libs/convert/totalDoc.js b/src/libs/convert/totalDoc.js
new file mode 100644
index 00000000..09f947c8
--- /dev/null
+++ b/src/libs/convert/totalDoc.js
@@ -0,0 +1,23 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function totalDoc(id) {
+    return '';
+};
diff --git a/src/libs/middlewares/aggregateData.js b/src/libs/middlewares/aggregateData.js
index aaa1ede4..b9b14eee 100644
--- a/src/libs/middlewares/aggregateData.js
+++ b/src/libs/middlewares/aggregateData.js
@@ -32,7 +32,8 @@ const convert = {
     gender_entity: 'gender',
     age_range_entity: 'ageRangeEntity',
     post_graduation_entity: 'postGraduationEntity',
-    contract_type_entity: 'contractType'
+    contract_type_entity: 'contractType',
+    total_doc: "totalDoc"
 }
 
 function aggregateData(req, res, next) {
@@ -58,7 +59,8 @@ function aggregateData(req, res, next) {
             'gender_entity',
             'age_range_entity',
             'post_graduation_entity',
-            'contract_type_entity'
+            'contract_type_entity',
+            'total_doc'
         ]
         let id;
         const fields = req.query.dims.split(',');
diff --git a/src/libs/middlewares/id2str.js b/src/libs/middlewares/id2str.js
index 078df393..a53196e2 100644
--- a/src/libs/middlewares/id2str.js
+++ b/src/libs/middlewares/id2str.js
@@ -124,6 +124,7 @@ const educationLevelModEntitySeg = require(`${libs}/convert/educationLevelModEnt
 const educationLevelModEntityAgg = require(`${libs}/convert/educationLevelModEntityAgg`);
 const ageRangeEntity = require(`${libs}/convert/ageRangeEntity`);
 const postGraduationEntity = require(`${libs}/convert/postGraduationEntity`);
+const totalDoc = require(`${libs}/convert/totalDoc`);
 
 const ids = {
     gender_id: gender,
@@ -240,7 +241,8 @@ const ids = {
     education_level_mod_entity_agg: educationLevelModEntityAgg,
     age_range_entity: ageRangeEntity,
     post_graduation_entity: postGraduationEntity,
-    special_education_entity: specialEducationEntity
+    special_education_entity: specialEducationEntity,
+    total_doc: totalDoc
 };
 
 function transform(removeId=false) {
@@ -379,5 +381,6 @@ module.exports = {
     educationLevelModEntityAgg,
     ageRangeEntity,
     postGraduationEntity,
-    specialEducationEntity
+    specialEducationEntity,
+    totalDoc
 };
diff --git a/src/libs/routes_v1/employeesAggregate.js b/src/libs/routes_v1/employeesAggregate.js
index ab5102ce..9fc52918 100644
--- a/src/libs/routes_v1/employeesAggregate.js
+++ b/src/libs/routes_v1/employeesAggregate.js
@@ -302,6 +302,14 @@ employeesAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .order('escola.ano_censo')
         .where('escola.situacao_funcionamento_pareada = 1 and (escola.ensino_regular = 1 or escola.ensino_eja = 1 or escola.educacao_profissional = 1)');
     }
+    else if (req.query.dims && req.query.dims.includes('total_doc')) {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_doc_bas)', 'total_doc_bas')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('escola.situacao_funcionamento_pareada = 1 and (escola.ensino_regular = 1 or escola.ensino_eja = 1 or escola.educacao_profissional = 1)');
+    }
     else {
         req.sql.from('escola')
         .field('SUM(escola.qt_doc_bas)', 'total')
diff --git a/src/libs/routes_v1/enrollmentAggregate.js b/src/libs/routes_v1/enrollmentAggregate.js
index 08d55ddb..b44bb70a 100644
--- a/src/libs/routes_v1/enrollmentAggregate.js
+++ b/src/libs/routes_v1/enrollmentAggregate.js
@@ -70,7 +70,7 @@ enrollmentAggregateApp.get('/adm_dependency', (req, res, next) => {
 enrollmentAggregateApp.get('/adm_dependency_detailed', (req, res, next) => {
     req.result = []
 
-    for (let i = 1; i <= 9; i++) {
+    for (let i = 1; i <= 8; i++) {
         req.result.push({
             id: i, name: id2str.admDependencyPriv(i)
         });
@@ -481,9 +481,10 @@ rqf.addField({
     tableField: 'localizacao_diferenciada_par',
     resultField: 'diff_location_id',
     where: {
-        relation: '=',
+        relation: 'is not null',
         type: 'integer',
-        field: 'localizacao_diferenciada_par'
+        field: 'localizacao_diferenciada_par',
+        value: 'null'
     }
 });
 
@@ -499,7 +500,8 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('SUM(escola.qt_mat_bas_fem)', 'total_fem')
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
-        .order('escola.ano_censo');
+        .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null');
     }
     else if (req.query.dims && req.query.dims.includes('age_range')) {
         req.sql.from('escola')
@@ -511,7 +513,8 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('SUM(escola.qt_mat_bas_18_mais)', 'total_18_mais')
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
-        .order('escola.ano_censo');
+        .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null')
     }
     else if (req.query.dims && req.query.dims.includes('ethnic_group')) {
         req.sql.from('escola')
@@ -523,7 +526,8 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('SUM(escola.qt_mat_bas_indigena)', 'total_indigena')
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
-        .order('escola.ano_censo');
+        .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null')
     }
     else if (req.query.dims && req.query.dims.includes('education_level_mod_agg')) {
         req.sql.from('escola')
@@ -539,7 +543,9 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('SUM(escola.qt_mat_prof_agg)', 'total_prof')
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
-        .order('escola.ano_censo');
+        .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null');
+
     }
     else if (req.query.dims && req.query.dims.includes('integral_time_agg')) {
         req.sql.from('turma,escola')
@@ -549,7 +555,7 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
         .order('escola.ano_censo')
-        .where('turma.tipo_atendimento_id <= 2 and turma.escola_id = escola.id and turma.ano_censo = escola.ano_censo');
+        .where('turma.tipo_atendimento_id <= 2 and turma.escola_id = escola.id and turma.ano_censo = escola.ano_censo and escola.localizacao_diferenciada_par is not null');
     }
     else if (req.query.dims && req.query.dims.includes('period_agg')) {
         req.sql.from('turma,escola')
@@ -561,7 +567,7 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
         .order('escola.ano_censo')
-        .where('turma.tipo_atendimento_id <= 2 and turma.escola_id = escola.id and turma.ano_censo = escola.ano_censo');
+        .where('turma.tipo_atendimento_id <= 2 and turma.escola_id = escola.id and turma.ano_censo = escola.ano_censo and escola.localizacao_diferenciada_par is not null');
     }
     else if (req.query.dims && req.query.dims.includes('modality_integral_time')) {
         req.sql.from('escola')
@@ -573,6 +579,7 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
         .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null');
     }
     else if (req.query.dims && req.query.dims.includes('special_education')) {
         req.sql.from('escola')
@@ -581,6 +588,7 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
         .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null');
     }
     else {
         req.sql.from('escola')
@@ -588,6 +596,7 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
         .order('escola.ano_censo')
+        .where('escola.localizacao_diferenciada_par is not null');
     }
     next();
 }, query, aggregateData, id2str.transform(false), response('enrollment_aggregate'));
diff --git a/src/libs/routes_v1/federativeEntity.js b/src/libs/routes_v1/federativeEntity.js
index 0b0c2b5c..40668f76 100644
--- a/src/libs/routes_v1/federativeEntity.js
+++ b/src/libs/routes_v1/federativeEntity.js
@@ -342,8 +342,8 @@ rqf.addField({
     },
     join: {
         primary: 'id',
-        foreign: 'municipio_id',
-        foreignTable: 'escola'
+        foreign: 'cod_mun',
+        foreignTable: 'docentes_sinopse'
     }
 }, 'dims').addValueToField({
     name: 'city',
@@ -357,8 +357,8 @@ rqf.addField({
     },
     join: {
         primary: 'id',
-        foreign: 'municipio_id',
-        foreignTable: 'escola'
+        foreign: 'cod_mun',
+        foreignTable: 'docentes_sinopse'
     }
 }, 'filter').addValueToField({
     name: 'school',
@@ -428,6 +428,42 @@ rqf.addField({
 });
 
 federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
+    let whereRule = '';
+    const filtersObject = {}
+
+    req.query.filter.split(',').forEach((filter) => {
+        let [key, value] = filter.split(':');
+        filtersObject[key] = Number(JSON.parse(value));
+    })
+
+    if (req.query.filter && req.query.filter.includes('city')) {
+        whereRule = 'docentes_sinopse.cod_mun = ' + filtersObject.city;
+    }
+    else if (req.query.filter && req.query.filter.includes('state')) {
+        whereRule = 'docentes_sinopse.cod_uf = ' + filtersObject.state + 
+            ((req.query.dims && req.query.dims.includes('city')) ? '' : ' AND docentes_sinopse.cod_mun = 0');
+    }
+    else if (req.query.filter && req.query.filter.includes('region')) {
+        whereRule = 'docentes_sinopse.cod_reg = ' + filtersObject.region + 
+            ((req.query.dims !== undefined && req.query.dims.includes('state')) 
+                ? ' AND docentes_sinopse.cod_mun = 0'
+                : (req.query.dims !== undefined && req.query.dims.includes('city')) 
+                    ? '' 
+                    : ' AND docentes_sinopse.cod_uf = 0');
+                
+    }
+    else {
+        whereRule = (req.query.dims && req.query.dims.includes('region')) 
+            ? 'docentes_sinopse.cod_uf = 0'
+            : (req.query.dims && req.query.dims.includes('state'))
+                ? 'docentes_sinopse.cod_mun = 0' 
+                : (req.query.dims && req.query.dims.includes('city'))
+                    ? ''
+                    : 'docentes_sinopse.cod_reg = 0'
+                
+    }
+
+    console.log(whereRule);
 
     if (req.query.dims && req.query.dims.includes('education_level_mod_entity_seg'))
     {
@@ -442,7 +478,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     else if (req.query.dims && req.query.dims.includes('education_level_mod_entity_agg'))
     {
@@ -465,7 +501,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     else if (req.query.dims && req.query.dims.includes('special_education_entity'))
     {
@@ -475,7 +511,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     else if (req.query.dims && req.query.dims.includes('adm_dependency_entity_agg'))
     {
@@ -485,7 +521,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     else if (req.query.dims && req.query.dims.includes('adm_dependency_entity'))
     {
@@ -497,7 +533,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     else if (req.query.dims && req.query.dims.includes('location_entity'))
     {
@@ -507,7 +543,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     else if (req.query.dims && req.query.dims.includes('gender_entity'))
     {
@@ -517,7 +553,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     else if (req.query.dims && req.query.dims.includes('age_range_entity'))
     {
@@ -532,7 +568,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     else if (req.query.dims && req.query.dims.includes('post_graduation_entity'))
     {
@@ -543,7 +579,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     else if (req.query.dims && req.query.dims.includes('contract_type_entity'))
     {
@@ -555,7 +591,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
             .field('docentes_sinopse.ano_censo', 'year')
             .group('docentes_sinopse.ano_censo')
             .order('docentes_sinopse.ano_censo')
-            .where('docentes_sinopse.cod_reg = 0');
+            .where(whereRule);
     }
     else if ((req.query.dims && req.query.dims.includes('state')) || (req.query.filter && req.query.filter.includes('state'))) {
         req.sql.from('docentes_sinopse')
@@ -563,7 +599,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_mun = 0');
+        .where(whereRule);
     }
     else if ((req.query.dims && req.query.dims.includes('region')) || (req.query.filter && req.query.filter.includes('region'))) {
         req.sql.from('docentes_sinopse')
@@ -571,7 +607,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_uf = 0');
+        .where(whereRule);
     }
     else {
         req.sql.from('docentes_sinopse')
@@ -579,7 +615,7 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('docentes_sinopse.ano_censo', 'year')
         .group('docentes_sinopse.ano_censo')
         .order('docentes_sinopse.ano_censo')
-        .where('docentes_sinopse.cod_reg = 0');
+        .where(whereRule);
     }
     next();
 }, query, aggregateData, id2str.transform(false), response('federative_entity'));
-- 
GitLab


From 32fb486f6e0363d349719e7e8af0e7f5d5a00b1e Mon Sep 17 00:00:00 2001
From: Lewis <lgtg20@inf.ufpr.br>
Date: Mon, 14 Oct 2024 12:02:06 -0300
Subject: [PATCH 24/26] Refactor education degree entity conversion functions

---
 src/libs/convert/educationDegreeEntity.js | 32 +++++++++++++++++++++++
 src/libs/middlewares/aggregateData.js     |  6 +++--
 src/libs/middlewares/id2str.js            |  7 +++--
 src/libs/routes_v1/enrollmentAggregate.js | 24 +++++++++++++++++
 src/libs/routes_v1/federativeEntity.js    | 23 ++++++++++++++++
 5 files changed, 88 insertions(+), 4 deletions(-)
 create mode 100644 src/libs/convert/educationDegreeEntity.js

diff --git a/src/libs/convert/educationDegreeEntity.js b/src/libs/convert/educationDegreeEntity.js
new file mode 100644
index 00000000..e16ba13f
--- /dev/null
+++ b/src/libs/convert/educationDegreeEntity.js
@@ -0,0 +1,32 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function educationDegreeEntity(id) {
+    switch (id) {
+        case 1:
+            return 'Ensino Fundamental';
+        case 2:
+            return 'Ensino Médio';
+        case 3:
+            return 'Graduação Com Licenciatura';
+        case 4:
+            return 'Graduação Sem Licenciatura';
+    }
+};
diff --git a/src/libs/middlewares/aggregateData.js b/src/libs/middlewares/aggregateData.js
index b9b14eee..864c2f54 100644
--- a/src/libs/middlewares/aggregateData.js
+++ b/src/libs/middlewares/aggregateData.js
@@ -33,7 +33,8 @@ const convert = {
     age_range_entity: 'ageRangeEntity',
     post_graduation_entity: 'postGraduationEntity',
     contract_type_entity: 'contractType',
-    total_doc: "totalDoc"
+    total_doc: "totalDoc",
+    education_degree_entity: "educationDegreeEntity"
 }
 
 function aggregateData(req, res, next) {
@@ -60,7 +61,8 @@ function aggregateData(req, res, next) {
             'age_range_entity',
             'post_graduation_entity',
             'contract_type_entity',
-            'total_doc'
+            'total_doc',
+            'education_degree_entity'
         ]
         let id;
         const fields = req.query.dims.split(',');
diff --git a/src/libs/middlewares/id2str.js b/src/libs/middlewares/id2str.js
index a53196e2..f366d90a 100644
--- a/src/libs/middlewares/id2str.js
+++ b/src/libs/middlewares/id2str.js
@@ -125,6 +125,7 @@ const educationLevelModEntityAgg = require(`${libs}/convert/educationLevelModEnt
 const ageRangeEntity = require(`${libs}/convert/ageRangeEntity`);
 const postGraduationEntity = require(`${libs}/convert/postGraduationEntity`);
 const totalDoc = require(`${libs}/convert/totalDoc`);
+const educationDegreeEntity = require(`${libs}/convert/educationDegreeEntity`);
 
 const ids = {
     gender_id: gender,
@@ -242,7 +243,8 @@ const ids = {
     age_range_entity: ageRangeEntity,
     post_graduation_entity: postGraduationEntity,
     special_education_entity: specialEducationEntity,
-    total_doc: totalDoc
+    total_doc: totalDoc,
+    education_degree_entity: educationDegreeEntity
 };
 
 function transform(removeId=false) {
@@ -382,5 +384,6 @@ module.exports = {
     ageRangeEntity,
     postGraduationEntity,
     specialEducationEntity,
-    totalDoc
+    totalDoc,
+    educationDegreeEntity
 };
diff --git a/src/libs/routes_v1/enrollmentAggregate.js b/src/libs/routes_v1/enrollmentAggregate.js
index b44bb70a..034aae7f 100644
--- a/src/libs/routes_v1/enrollmentAggregate.js
+++ b/src/libs/routes_v1/enrollmentAggregate.js
@@ -78,6 +78,20 @@ enrollmentAggregateApp.get('/adm_dependency_detailed', (req, res, next) => {
     next();
 }, response('adm_dependency_detailed'));
 
+enrollmentAggregateApp.get('/government_agreement', cache('15 day'), (req, res, next) => {
+    req.result = [{
+        id: "null",
+        name: id2str.governmentAgreement("null")
+    }];
+    for(let i = 1; i <= 6; ++i) {
+        req.result.push({
+            id: i,
+            name: id2str.governmentAgreement(i)
+        });
+    };
+    next();
+}, response('government_agreement'));
+
 enrollmentAggregateApp.get('/education_level_mod_agg', (req, res, next) => {
     req.result = []
 
@@ -486,6 +500,16 @@ rqf.addField({
         field: 'localizacao_diferenciada_par',
         value: 'null'
     }
+}).addValue({
+    name: 'government_agreement',
+    table: 'escola',
+    tableField: 'dependencia_convenio_publico',
+    resultField: 'government_agreement_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'dependencia_convenio_publico'
+    }
 });
 
 // Return all cities
diff --git a/src/libs/routes_v1/federativeEntity.js b/src/libs/routes_v1/federativeEntity.js
index 40668f76..661907c5 100644
--- a/src/libs/routes_v1/federativeEntity.js
+++ b/src/libs/routes_v1/federativeEntity.js
@@ -67,6 +67,17 @@ federativeEntityApp.get('/adm_dependency', (req, res, next) => {
     next();
 }, response('adm_dependency'));
 
+federativeEntityApp.get('/education_degree_entity', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 4; i++) {
+        req.result.push({
+            id: i, name: id2str.educationDegreeEntity(i)
+        });
+    }
+    next();
+}, response('education_degree_entity'));
+
 federativeEntityApp.get('/adm_dependency_detailed', (req, res, next) => {
     req.result = []
 
@@ -535,6 +546,18 @@ federativeEntityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .order('docentes_sinopse.ano_censo')
         .where(whereRule);
     }
+    else if (req.query.dims && req.query.dims.includes('education_degree_entity'))
+        {
+            req.sql.from('docentes_sinopse')
+            .field('SUM(docentes_sinopse.num_doc_esc_en_fund)', 'total_num_doc_esc_en_fund')
+            .field('SUM(docentes_sinopse.num_doc_esc_en_medio)', 'total_num_doc_esc_en_medio')
+            .field('SUM(docentes_sinopse.num_doc_esc_grad_com_licenciatura)', 'total_num_doc_esc_grad_com_licenciatura')
+            .field('SUM(docentes_sinopse.num_doc_esc_grad_sem_licenciatura)', 'total_num_doc_esc_grad_sem_licenciatura')
+            .field('docentes_sinopse.ano_censo', 'year')
+            .group('docentes_sinopse.ano_censo')
+            .order('docentes_sinopse.ano_censo')
+            .where(whereRule);
+        }
     else if (req.query.dims && req.query.dims.includes('location_entity'))
     {
         req.sql.from('docentes_sinopse')
-- 
GitLab


From 01e40a0d0a8cffada2f4de5fdd29849dc7b77419 Mon Sep 17 00:00:00 2001
From: Lewis <lgtg20@inf.ufpr.br>
Date: Tue, 15 Oct 2024 09:46:43 -0300
Subject: [PATCH 25/26] Add route for government_agreement

---
 src/libs/middlewares/aggregateData.js     | 3 ++-
 src/libs/routes_v1/enrollmentAggregate.js | 8 +++-----
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/src/libs/middlewares/aggregateData.js b/src/libs/middlewares/aggregateData.js
index 864c2f54..5acac924 100644
--- a/src/libs/middlewares/aggregateData.js
+++ b/src/libs/middlewares/aggregateData.js
@@ -34,7 +34,8 @@ const convert = {
     post_graduation_entity: 'postGraduationEntity',
     contract_type_entity: 'contractType',
     total_doc: "totalDoc",
-    education_degree_entity: "educationDegreeEntity"
+    education_degree_entity: "educationDegreeEntity",
+    government_agreement: "governmentAgreement"
 }
 
 function aggregateData(req, res, next) {
diff --git a/src/libs/routes_v1/enrollmentAggregate.js b/src/libs/routes_v1/enrollmentAggregate.js
index 034aae7f..bb4ef2bf 100644
--- a/src/libs/routes_v1/enrollmentAggregate.js
+++ b/src/libs/routes_v1/enrollmentAggregate.js
@@ -78,11 +78,9 @@ enrollmentAggregateApp.get('/adm_dependency_detailed', (req, res, next) => {
     next();
 }, response('adm_dependency_detailed'));
 
-enrollmentAggregateApp.get('/government_agreement', cache('15 day'), (req, res, next) => {
-    req.result = [{
-        id: "null",
-        name: id2str.governmentAgreement("null")
-    }];
+enrollmentAggregateApp.get('/government_agreement', (req, res, next) => {
+    req.result = []
+    
     for(let i = 1; i <= 6; ++i) {
         req.result.push({
             id: i,
-- 
GitLab


From f866f7de8b5ad89b80dc05f3b81517e4b5433e3a Mon Sep 17 00:00:00 2001
From: Lewis <lgtg20@inf.ufpr.br>
Date: Tue, 29 Oct 2024 10:09:22 -0300
Subject: [PATCH 26/26] Fix current issues

---
 src/libs/convert/educationLevelModAgg.js  | 2 ++
 src/libs/middlewares/aggregateData.js     | 1 -
 src/libs/routes_v1/employeesAggregate.js  | 8 --------
 src/libs/routes_v1/enrollmentAggregate.js | 4 ++--
 4 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/src/libs/convert/educationLevelModAgg.js b/src/libs/convert/educationLevelModAgg.js
index c55a7e8f..6ebfa627 100644
--- a/src/libs/convert/educationLevelModAgg.js
+++ b/src/libs/convert/educationLevelModAgg.js
@@ -40,6 +40,8 @@ module.exports = function educationLevelMod(id) {
         return 'EJA - EF e EM Integrado - tecnico';
         case 10:
         return 'Educacao Profissional - concomitante e subsequente';
+        case 11:
+        return 'suporte_total'
         default:
         return 'Não classificada';
     }
diff --git a/src/libs/middlewares/aggregateData.js b/src/libs/middlewares/aggregateData.js
index 5acac924..eed373dd 100644
--- a/src/libs/middlewares/aggregateData.js
+++ b/src/libs/middlewares/aggregateData.js
@@ -62,7 +62,6 @@ function aggregateData(req, res, next) {
             'age_range_entity',
             'post_graduation_entity',
             'contract_type_entity',
-            'total_doc',
             'education_degree_entity'
         ]
         let id;
diff --git a/src/libs/routes_v1/employeesAggregate.js b/src/libs/routes_v1/employeesAggregate.js
index 9fc52918..ab5102ce 100644
--- a/src/libs/routes_v1/employeesAggregate.js
+++ b/src/libs/routes_v1/employeesAggregate.js
@@ -302,14 +302,6 @@ employeesAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .order('escola.ano_censo')
         .where('escola.situacao_funcionamento_pareada = 1 and (escola.ensino_regular = 1 or escola.ensino_eja = 1 or escola.educacao_profissional = 1)');
     }
-    else if (req.query.dims && req.query.dims.includes('total_doc')) {
-        req.sql.from('escola')
-        .field('SUM(escola.qt_doc_bas)', 'total_doc_bas')
-        .field('escola.ano_censo', 'year')
-        .group('escola.ano_censo')
-        .order('escola.ano_censo')
-        .where('escola.situacao_funcionamento_pareada = 1 and (escola.ensino_regular = 1 or escola.ensino_eja = 1 or escola.educacao_profissional = 1)');
-    }
     else {
         req.sql.from('escola')
         .field('SUM(escola.qt_doc_bas)', 'total')
diff --git a/src/libs/routes_v1/enrollmentAggregate.js b/src/libs/routes_v1/enrollmentAggregate.js
index bb4ef2bf..7e8cd3fa 100644
--- a/src/libs/routes_v1/enrollmentAggregate.js
+++ b/src/libs/routes_v1/enrollmentAggregate.js
@@ -493,10 +493,9 @@ rqf.addField({
     tableField: 'localizacao_diferenciada_par',
     resultField: 'diff_location_id',
     where: {
-        relation: 'is not null',
+        relation: '=',
         type: 'integer',
         field: 'localizacao_diferenciada_par',
-        value: 'null'
     }
 }).addValue({
     name: 'government_agreement',
@@ -563,6 +562,7 @@ enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         .field('SUM(escola.qt_mat_eja_med_agg)', 'total_eja_med')
         .field('SUM(escola.qt_mat_eja_fund_fic + escola.qt_mat_eja_med_fic + escola.qt_mat_eja_med_tec)', 'total_tec')
         .field('SUM(escola.qt_mat_prof_agg)', 'total_prof')
+        .field('SUM(escola.qt_mat_bas)', 'total_total')
         .field('escola.ano_censo', 'year')
         .group('escola.ano_censo')
         .order('escola.ano_censo')
-- 
GitLab