From 5bab55baaf0f50c4cc7ef016f7e13e5f0936ad80 Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Thu, 28 Jun 2018 09:56:21 -0300
Subject: [PATCH 01/38] Create school infrastructure file

---
 src/libs/routes/school_infrastructure.js | 558 +++++++++++++++++++++++
 1 file changed, 558 insertions(+)
 create mode 100644 src/libs/routes/school_infrastructure.js

diff --git a/src/libs/routes/school_infrastructure.js b/src/libs/routes/school_infrastructure.js
new file mode 100644
index 00000000..290bf1a0
--- /dev/null
+++ b/src/libs/routes/school_infrastructure.js
@@ -0,0 +1,558 @@
+const express = require('express');
+
+const infrastructureApp = 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 multiQuery = require(`${libs}/middlewares/multiQuery`);
+
+const response = require(`${libs}/middlewares/response`);
+
+const id2str = require(`${libs}/middlewares/id2str`);
+
+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();
+
+infrastructureApp.use(cache('15 day'));
+
+infrastructureApp.get('/year_range', (req, res, next) => {
+    req.sql.from('escola')
+    .field('MIN(escola.ano_censo)', 'start_year')
+    .field('MAX(escola.ano_censo)', 'end_year');
+    next();
+}, query, response('range'));
+
+infrastructureApp.get('/years', (req, res, next) => {
+    req.sql.from('escola')
+    .field('DISTINCT escola.ano_censo', 'year');
+    next();
+}, query, response('years'));
+
+infrastructureApp.get('/source', (req, res, next) => {
+    req.sql.from('fonte')
+    .field('fonte', 'source')
+    .where('tabela = \'escola\'');
+    next();
+}, query, response('source'));
+
+infrastructureApp.get('/location', (req, res, next) => {
+    req.result = [
+        {id: 1, name: 'Urbana'},
+        {id: 2, name: 'Rural'}
+    ];
+    next();
+}, response('location'));
+
+infrastructureApp.get('/rural_location', (req, res, next) => {
+    req.result = [
+        {id: 1, name: "Urbana"},
+        {id: 2, name: "Rural"},
+        {id: 3, name: "Rural - Área de assentamento"},
+        {id: 4, name: "Rural - Terra indígena"},
+        {id: 5, name: "Rural - Área remanescente de quilombos"},
+        {id: 6, name: "Rural - Unidade de uso sustentável"}
+    ];
+    next();
+}, response('rural_location'));
+
+infrastructureApp.get('/adm_dependency', (req, res, next) => {
+    req.sql.from('dependencia_adm')
+    .field('id')
+    .field('nome', 'name')
+    .where('id <= 4');
+    next();
+}, query, response('adm_dependency'));
+
+infrastructureApp.get('/adm_dependency_detailed', (req, res, next) => {
+    req.sql.from('dependencia_adm_priv')
+    .field('id', 'id')
+    .field('nome', 'name');
+    next();
+}, query, response('adm_dependency_detailed'));
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValueToField({
+    name: 'city',
+    table: 'municipio',
+    tableField: ['nome', 'id'],
+    resultField: ['city_name', 'city_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'municipio_id',
+        table: 'escola'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'city',
+    table: 'municipio',
+    tableField: 'id',
+    resultField: 'city_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'municipio_id',
+        table: 'escola'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}, 'filter').addValueToField({
+    name: 'state',
+    table: 'estado',
+    tableField: ['nome', 'id'],
+    resultField: ['state_name', 'state_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'estado_id',
+        table: 'escola'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'estado_id',
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'state',
+    table: 'estado',
+    tableField: 'id',
+    resultField: 'state_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'estado_id',
+        table: 'escola'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'estado_id',
+        foreignTable: 'escola'
+    }
+}, 'filter').addValue({
+    name: 'region',
+    table: 'regiao',
+    tableField: 'nome',
+    resultField: 'region_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'regiao_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'location',
+    table: 'escola',
+    tableField: 'cod_localizacao',
+    resultField: 'location_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_localizacao'
+    }
+}).addValue({
+    name: 'rural_location',
+    table: 'escola',
+    tableField: 'localidade_area_rural',
+    resultField: 'rural_location_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'localidade_area_rural'
+    }
+}).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: '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'
+    }
+});
+
+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;
+            }
+        }
+
+        if(objMatch) {
+            newObj.percentage = (objMatch.total / result.total) * 100;
+            newObj.partial = objMatch.total;
+            newObj.total = result.total
+            match.push(newObj);
+        }
+    });
+
+    return match;
+}
+
+infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
+    req.querySet = [];
+    req.queryIndex = {};
+
+    // Local de funcionamento
+    let allSchools = req.sql.clone();
+    allSchools.from('escola').field('COUNT(escola.id)', 'total')
+    .field("'Brasil'", 'name')
+    .field('escola.ano_censo', 'year')
+    .group('escola.ano_censo')
+    .where('escola.situacao_de_funcionamento = 1')
+    .order('escola.ano_censo');
+    req.queryIndex.allSchools = req.querySet.push(allSchools) - 1;
+
+    let schoolPlace = allSchools.clone();
+    schoolPlace.where('escola.func_predio_escolar = 1 AND escola.func_salas_empresa = 0 AND escola.func_templo_igreja = 0 AND escola.func_casa_professor = 0 AND escola.func_galpao = 0 AND escola.biblioteca = 1');
+    req.queryIndex.schoolPlace = req.querySet.push(schoolPlace) - 1;
+
+    // Bibliotecas
+    let allLibraries = allSchools.clone();
+    allLibraries.where('escola.func_predio_escolar = 1 AND escola.cod_localizacao = 1');
+    req.queryIndex.allLibraries = req.querySet.push(allLibraries) - 1;
+
+    let haveLibraries = allLibraries.clone();
+    haveLibraries.where('escola.biblioteca = 1');
+    req.queryIndex.haveLibraries = req.querySet.push(haveLibraries) - 1;
+
+    // Bibliotecas/Sala de leitura
+    let allLibrariesReadingRoom = allSchools.clone();
+    allLibrariesReadingRoom.where('escola.func_predio_escolar = 1 AND escola.cod_localizacao = 2');
+    req.queryIndex.allLibrariesReadingRoom = req.querySet.push(allLibrariesReadingRoom) - 1;
+
+    let haveLibrariesReadingRoom = allLibrariesReadingRoom.clone();
+    haveLibrariesReadingRoom.where('escola.sala_leitura = 1');
+    req.queryIndex.haveLibrariesReadingRoom = req.querySet.push(haveLibrariesReadingRoom) - 1;
+
+    // Laboratório de informática
+    let allInfLab = allSchools.clone();
+    allInfLab.where('escola.func_predio_escolar = 1')
+    .where('escola.reg_fund_ai = 1 OR escola.reg_fund_af = 1 OR escola.reg_medio_medio = 1 OR escola.reg_medio_integrado = 1 OR escola.reg_medio_normal = 1 OR escola.ensino_eja_fund = 1 OR escola.ensino_eja_medio = 1 OR escola.ensino_eja_prof = 1');
+    req.queryIndex.allInfLab = req.querySet.push(allInfLab) - 1;
+
+    let haveInfLab = allInfLab.clone();
+    haveInfLab.where('escola.lab_informatica = 1');
+    req.queryIndex.haveInfLab = req.querySet.push(haveInfLab) - 1;
+
+    // Laboratório de ciências
+    let allScienceLab = allInfLab.clone();
+    req.queryIndex.allScienceLab = req.querySet.push(allScienceLab) - 1;
+
+    let haveScienceLab = allScienceLab.clone();
+    haveScienceLab.where('escola.lab_ciencias = 1');
+    req.queryIndex.haveScienceLab = req.querySet.push(haveScienceLab) - 1;
+
+    // Parque infantil
+    let allKidsPark = allSchools.clone();
+    allKidsPark.where('escola.func_predio_escolar = 1')
+    .where('escola.reg_infantil_creche = 1 OR escola.reg_infantil_preescola = 1 OR escola.reg_fund_ai = 1 OR escola.esp_infantil_creche = 1 OR escola.esp_exclusiva_creche = 1 OR escola.reg_esp_exclusiva_fund_ai = 1');
+    req.queryIndex.allKidsPark = req.querySet.push(allKidsPark) - 1;
+
+    let haveKidsPark = allKidsPark.clone();
+    haveKidsPark.where('escola.parque_infantil = 1');
+    req.queryIndex.haveKidsPark = req.querySet.push(haveKidsPark) - 1;
+
+    // Berçário
+    let allCribs = allSchools.clone();
+    allCribs.where('escola.func_predio_escolar = 1')
+    .where('escola.reg_infantil_creche = 1 OR escola.esp_infantil_creche = 1');
+    req.queryIndex.allCribs = req.querySet.push(allCribs) - 1;
+
+    let haveCribs = allCribs.clone();
+    haveCribs.where('escola.bercario = 1');
+    req.queryIndex.haveCribs = req.querySet.push(haveCribs) - 1;
+
+    // Quadra
+    let allSportsCourt = allScienceLab.clone();
+    allSportsCourt.where('escola.cod_localizacao = 1');
+    req.queryIndex.allSportsCourt = req.querySet.push(allSportsCourt) - 1;
+
+    let haveSportsCourt = allSportsCourt.clone();
+    haveSportsCourt.where('escola.quadra_esportes = 1');
+    req.queryIndex.haveSportsCourt = req.querySet.push(haveSportsCourt) - 1;
+
+    // Quadra coberta
+    req.queryIndex.allCoveredSportsCourt = req.queryIndex.allSportsCourt;
+
+    let haveCoveredSportsCourt = allSportsCourt.clone();
+    haveCoveredSportsCourt.where('escola.quadra_esportes_coberta = 1');
+    req.queryIndex.haveCoveredSportsCourt = req.querySet.push(haveCoveredSportsCourt) - 1;
+
+    // Quadra Descoberta
+    let allUncoveredSportsCourt = allSportsCourt.clone();
+    allUncoveredSportsCourt.where('escola.quadra_esportes_coberta = 0');
+    req.queryIndex.allUncoveredSportsCourt = req.querySet.push(allUncoveredSportsCourt) - 1;
+
+    let haveUncoveredSportsCourt = allUncoveredSportsCourt.clone();
+    haveUncoveredSportsCourt.where('escola.quadra_esportes_descoberta = 1');
+    req.queryIndex.haveUncoveredSportsCourt = req.querySet.push(haveUncoveredSportsCourt) - 1;
+
+    // Sala de direção
+    let allDirectorRoom = allSchools.clone();
+    allDirectorRoom.where('escola.func_predio_escolar = 1 AND escola.cod_localizacao = 1');
+    req.queryIndex.allDirectorRoom = req.querySet.push(allDirectorRoom) - 1;
+
+    let haveDirectorRoom = allDirectorRoom.clone();
+    haveDirectorRoom.where('escola.sala_diretoria = 1');
+    req.queryIndex.haveDirectorRoom = req.querySet.push(haveDirectorRoom) - 1;
+
+    // Secretaria
+    let allSecretary = allSchools.clone();
+    allSecretary.where('escola.func_predio_escolar = 1');
+    req.queryIndex.allSecretary = req.querySet.push(allSecretary) - 1;
+
+    let haveSecretary = allSecretary.clone();
+    haveSecretary.where('escola.secretaria = 1');
+    req.queryIndex.haveSecretary = req.querySet.push(haveSecretary) - 1;
+
+    // Sala de professores
+    req.queryIndex.allTeacherRoom = req.queryIndex.allSecretary;
+
+    let haveTeacherRoom = allSecretary.clone();
+    haveTeacherRoom.where('escola.sala_professor = 1');
+    req.queryIndex.haveTeacherRoom = req.querySet.push(haveTeacherRoom) - 1;
+
+    // Cozinha
+    req.queryIndex.allKitchen = req.queryIndex.allSecretary;
+
+    let haveKitchen = allSecretary.clone();
+    haveKitchen.where('escola.cozinha = 1');
+    req.queryIndex.haveKitchen = req.querySet.push(haveKitchen) - 1;
+
+    // Despensa
+    req.queryIndex.allStoreroom = req.queryIndex.allSecretary;
+
+    let haveStoreroom = allSecretary.clone();
+    haveStoreroom.where('escola.despensa = 1');
+    req.queryIndex.haveStoreroom = req.querySet.push(haveStoreroom) - 1;
+
+    // Almoxarifado
+    req.queryIndex.allWarehouse = req.queryIndex.allSecretary;
+
+    let haveWarehouse = allSecretary.clone();
+    haveWarehouse.where('escola.almoxarifado = 1');
+    req.queryIndex.haveWarehouse = req.querySet.push(haveWarehouse) - 1;
+
+    // Internet
+    req.queryIndex.allInternet = req.queryIndex.allLibrariesReadingRoom;
+
+    let haveInternet = allLibrariesReadingRoom.clone();
+    haveInternet.where('escola.internet = 1');
+    req.queryIndex.haveInternet = req.querySet.push(haveInternet) - 1;
+
+    // Internet banda larga
+    req.queryIndex.allBroadbandInternet = req.queryIndex.allLibraries;
+
+    let haveBroadbandInternet = allLibraries.clone();
+    haveBroadbandInternet.where('escola.internet_banda_larga = 1');
+    req.queryIndex.haveBroadbandInternet = req.querySet.push(haveBroadbandInternet) - 1;
+
+    // Banheiro dentro do prédio
+    req.queryIndex.allInsideBathroom = req.queryIndex.allSecretary;
+
+    let haveInsideBathroom = allSecretary.clone();
+    haveInsideBathroom.where('escola.sanitario_dentro_predio = 1');
+    req.queryIndex.haveInsideBathroom = req.querySet.push(haveInsideBathroom) - 1;
+
+    // Banheiro adequado para educação infantil dentro do prédio
+    req.queryIndex.allInsideKidsBathroom = req.queryIndex.allKidsPark;
+
+    let haveInsideKidsBathroom = allKidsPark.clone();
+    haveInsideKidsBathroom.where('escola.sanitario_ei = 1');
+    req.queryIndex.haveInsideKidsBathroom = req.querySet.push(haveInsideKidsBathroom) - 1;
+
+    // Fornecimento de energia
+    req.queryIndex.allEletricEnergy = req.queryIndex.allSecretary;
+
+    let haveEletricEnergy = allSecretary.clone();
+    haveEletricEnergy.where('escola.fornecimento_energia = 1');
+    req.queryIndex.haveEletricEnergy = req.querySet.push(haveEletricEnergy) - 1;
+
+    // Abastecimento de água
+    req.queryIndex.allWaterSupply = req.queryIndex.allSecretary;
+
+    let haveWaterSupply = allSecretary.clone();
+    haveWaterSupply.where('escola.fornecimento_agua = 1');
+    req.queryIndex.haveWaterSupply = req.querySet.push(haveWaterSupply) - 1;
+
+    // Água filtrada
+    req.queryIndex.allFilteredWater = req.queryIndex.allSecretary;
+
+    let haveFilteredWater = allSecretary.clone();
+    haveFilteredWater.where('escola.agua_filtrada = 1');
+    req.queryIndex.haveFilteredWater = req.querySet.push(haveFilteredWater) - 1;
+
+    // Coleta de esgoto
+    req.queryIndex.allSewage = req.queryIndex.allSecretary;
+
+    let haveSewage = allSecretary.clone();
+    haveSewage.where('escola.esgoto_sanitario = 1');
+    req.queryIndex.haveSewage = req.querySet.push(haveSewage) - 1;
+
+    // Sala de recursos multifuncionais para Atendimento Educacional Especializado
+    req.queryIndex.allMultifunctionRoom = req.queryIndex.allSecretary;
+
+    let haveMultifunctionRoom = allSecretary.clone();
+    haveMultifunctionRoom.where('escola.sala_atendimento_especial = 1');
+    req.queryIndex.haveMultifunctionRoom = req.querySet.push(haveMultifunctionRoom) - 1;
+
+    // Banheiros adaptados para pessoas com deficiências
+    req.queryIndex.allSpecialBathroom = req.queryIndex.allSecretary;
+
+    let haveSpecialBathroom = allSecretary.clone();
+    haveSpecialBathroom.where('escola.sanitario_pne = 1');
+    req.queryIndex.haveSpecialBathroom = req.querySet.push(haveSpecialBathroom) - 1;
+
+    // Dependências adaptada para pessoas com deficiências
+    req.queryIndex.allAdaptedBuilding = req.queryIndex.allSecretary;
+
+    let haveAdaptedBuilding = allSecretary.clone();
+    haveAdaptedBuilding.where('escola.dependencias_pne = 1');
+    req.queryIndex.haveAdaptedBuilding = req.querySet.push(haveAdaptedBuilding) - 1;
+
+    next();
+}, multiQuery, (req, res, next) => {
+    // Faz o matching entre os resultados
+    let school_place = matchQueries(req.result[req.queryIndex.allSchools], req.result[req.queryIndex.schoolPlace]);
+    let libraries = matchQueries(req.result[req.queryIndex.allLibraries], req.result[req.queryIndex.haveLibraries]);
+    let libraries_reading_room = matchQueries(req.result[req.queryIndex.allLibrariesReadingRoom], req.result[req.queryIndex.haveLibrariesReadingRoom]);
+    let computer_lab = matchQueries(req.result[req.queryIndex.allInfLab], req.result[req.queryIndex.haveInfLab]);
+    let science_lab = matchQueries(req.result[req.queryIndex.allScienceLab], req.result[req.queryIndex.haveScienceLab]);
+    let kids_park = matchQueries(req.result[req.queryIndex.allKidsPark], req.result[req.queryIndex.haveKidsPark]);
+    let nursery = matchQueries(req.result[req.queryIndex.allCribs], req.result[req.queryIndex.haveCribs]);
+    let sports_court = matchQueries(req.result[req.queryIndex.allSportsCourt], req.result[req.queryIndex.haveSportsCourt]);
+    let covered_sports_court = matchQueries(req.result[req.queryIndex.allCoveredSportsCourt], req.result[req.queryIndex.haveCoveredSportsCourt]);
+    let uncovered_sports_court = matchQueries(req.result[req.queryIndex.allUncoveredSportsCourt], req.result[req.queryIndex.haveUncoveredSportsCourt]);
+    let director_room = matchQueries(req.result[req.queryIndex.allDirectorRoom], req.result[req.queryIndex.haveDirectorRoom]);
+    let secretary = matchQueries(req.result[req.queryIndex.allSecretary], req.result[req.queryIndex.haveSecretary]);
+    let teacher_room = matchQueries(req.result[req.queryIndex.allTeacherRoom], req.result[req.queryIndex.haveTeacherRoom]);
+    let kitchen = matchQueries(req.result[req.queryIndex.allKitchen], req.result[req.queryIndex.haveKitchen]);
+    let storeroom = matchQueries(req.result[req.queryIndex.allStoreroom], req.result[req.queryIndex.haveStoreroom]);
+    let warehouse = matchQueries(req.result[req.queryIndex.allWarehouse], req.result[req.queryIndex.haveWarehouse]);
+    let internet = matchQueries(req.result[req.queryIndex.allInternet], req.result[req.queryIndex.haveInternet]);
+    let broadband_internet = matchQueries(req.result[req.queryIndex.allBroadbandInternet], req.result[req.queryIndex.haveBroadbandInternet]);
+    let inside_bathroom = matchQueries(req.result[req.queryIndex.allInsideBathroom], req.result[req.queryIndex.haveInsideBathroom]);
+    let inside_kids_bathroom = matchQueries(req.result[req.queryIndex.allInsideKidsBathroom], req.result[req.queryIndex.haveInsideKidsBathroom]);
+    let eletric_energy = matchQueries(req.result[req.queryIndex.allEletricEnergy], req.result[req.queryIndex.haveEletricEnergy]);
+    let water_supply = matchQueries(req.result[req.queryIndex.allWaterSupply], req.result[req.queryIndex.haveWaterSupply]);
+    let filtered_water = matchQueries(req.result[req.queryIndex.allFilteredWater], req.result[req.queryIndex.haveFilteredWater]);
+    let sewage_treatment = matchQueries(req.result[req.queryIndex.allSewage], req.result[req.queryIndex.haveSewage]);
+    let special_multifunction_room = matchQueries(req.result[req.queryIndex.allMultifunctionRoom], req.result[req.queryIndex.haveMultifunctionRoom]);
+    let special_bathroom = matchQueries(req.result[req.queryIndex.allSpecialBathroom], req.result[req.queryIndex.haveSpecialBathroom]);
+    let adapted_building = matchQueries(req.result[req.queryIndex.allAdaptedBuilding], req.result[req.queryIndex.haveAdaptedBuilding]);
+
+    req.result = [{
+        school_place,
+        libraries,
+        libraries_reading_room,
+        computer_lab,
+        science_lab,
+        kids_park,
+        nursery,
+        sports_court,
+        covered_sports_court,
+        uncovered_sports_court,
+        director_room,
+        secretary,
+        teacher_room,
+        kitchen,
+        storeroom,
+        warehouse,
+        internet,
+        broadband_internet,
+        inside_bathroom,
+        inside_kids_bathroom,
+        eletric_energy,
+        water_supply,
+        filtered_water,
+        sewage_treatment,
+        special_multifunction_room,
+        special_bathroom,
+        adapted_building
+    }];
+
+    next();
+}, id2str.multitransform(false), response('infrastructure'));
+
+module.exports = infrastructureApp;
-- 
GitLab


From 9d6c34c1d9e612d6c94e6210304ebf046cee8478 Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Tue, 3 Jul 2018 10:35:17 -0300
Subject: [PATCH 02/38] Begin school infra

---
 src/libs/routes/school_infrastructure.js | 153 ++++++++++++++++-------
 1 file changed, 107 insertions(+), 46 deletions(-)

diff --git a/src/libs/routes/school_infrastructure.js b/src/libs/routes/school_infrastructure.js
index 290bf1a0..33d73165 100644
--- a/src/libs/routes/school_infrastructure.js
+++ b/src/libs/routes/school_infrastructure.js
@@ -280,140 +280,193 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     .field('escola.ano_censo', 'year')
     .group('escola.ano_censo')
     .where('escola.situacao_de_funcionamento = 1')
+    .where('escola.ensino_regular = 1 OR escola.ensino_eja = 1 OR escola.educacao_profissional = 1')
+    .where('escola.local_func_predio_escolar = 1')
+    .where('escola.dependencia_adm_id <= 3')
     .order('escola.ano_censo');
-    req.queryIndex.allSchools = req.querySet.push(allSchools) - 1;
-
-    let schoolPlace = allSchools.clone();
-    schoolPlace.where('escola.func_predio_escolar = 1 AND escola.func_salas_empresa = 0 AND escola.func_templo_igreja = 0 AND escola.func_casa_professor = 0 AND escola.func_galpao = 0 AND escola.biblioteca = 1');
-    req.queryIndex.schoolPlace = req.querySet.push(schoolPlace) - 1;
 
     // Bibliotecas
     let allLibraries = allSchools.clone();
-    allLibraries.where('escola.func_predio_escolar = 1 AND escola.cod_localizacao = 1');
+    allLibraries.where('escola.cod_localizacao = 1');
     req.queryIndex.allLibraries = req.querySet.push(allLibraries) - 1;
 
     let haveLibraries = allLibraries.clone();
     haveLibraries.where('escola.biblioteca = 1');
     req.queryIndex.haveLibraries = req.querySet.push(haveLibraries) - 1;
 
+    let needLibraries = allLibraries.clone();
+    needLibraries.where('escola.biblioteca = 0');
+    req.queryIndex.needLibraries = req.querySet.push(needLibraries) - 1;
+
     // Bibliotecas/Sala de leitura
     let allLibrariesReadingRoom = allSchools.clone();
-    allLibrariesReadingRoom.where('escola.func_predio_escolar = 1 AND escola.cod_localizacao = 2');
+    allLibrariesReadingRoom.where('escola.cod_localizacao = 2');
     req.queryIndex.allLibrariesReadingRoom = req.querySet.push(allLibrariesReadingRoom) - 1;
 
     let haveLibrariesReadingRoom = allLibrariesReadingRoom.clone();
-    haveLibrariesReadingRoom.where('escola.sala_leitura = 1');
+    haveLibrariesReadingRoom.where('escola.biblioteca_sala_leitura = 1');
     req.queryIndex.haveLibrariesReadingRoom = req.querySet.push(haveLibrariesReadingRoom) - 1;
 
+    let needLibrariesReadingRoom = allLibrariesReadingRoom.clone();
+    needLibrariesReadingRoom.where('escola.biblioteca_sala_leitura = 0');
+    req.queryIndex.needLibrariesReadingRoom = req.querySet.push(needLibrariesReadingRoom) - 1;
+
     // Laboratório de informática
     let allInfLab = allSchools.clone();
-    allInfLab.where('escola.func_predio_escolar = 1')
-    .where('escola.reg_fund_ai = 1 OR escola.reg_fund_af = 1 OR escola.reg_medio_medio = 1 OR escola.reg_medio_integrado = 1 OR escola.reg_medio_normal = 1 OR escola.ensino_eja_fund = 1 OR escola.ensino_eja_medio = 1 OR escola.ensino_eja_prof = 1');
+    allInfLab.where('escola.reg_infantil_preescola = 1 OR escola.reg_fund_ai = 1 OR escola.reg_fund_af = 1 OR escola.reg_medio_medio = 1 OR escola.reg_medio_integrado = 1 OR escola.reg_medio_normal = 1 OR escola.ensino_eja_fund = 1 OR escola.ensino_eja_medio = 1 OR escola.ensino_eja_prof = 1');
     req.queryIndex.allInfLab = req.querySet.push(allInfLab) - 1;
 
     let haveInfLab = allInfLab.clone();
     haveInfLab.where('escola.lab_informatica = 1');
     req.queryIndex.haveInfLab = req.querySet.push(haveInfLab) - 1;
 
+    let needInfLab = allInfLab.clone();
+    needInfLab.where('escola.lab_informatica = 0');
+    req.queryIndex.needInfLab = req.querySet.push(needInfLab) - 1;
+
     // Laboratório de ciências
-    let allScienceLab = allInfLab.clone();
+    let allScienceLab = allSchools.clone();
+    allScienceLab.where('escola.reg_fund_af = 1 OR escola.reg_medio_medio = 1 OR escola.reg_medio_integrado = 1 OR escola.reg_medio_normal = 1 OR escola.ensino_eja_fund = 1 OR escola.ensino_eja_medio = 1 OR escola.ensino_eja_prof = 1');
     req.queryIndex.allScienceLab = req.querySet.push(allScienceLab) - 1;
 
     let haveScienceLab = allScienceLab.clone();
     haveScienceLab.where('escola.lab_ciencias = 1');
     req.queryIndex.haveScienceLab = req.querySet.push(haveScienceLab) - 1;
 
+    let needScienceLab = allScienceLab.clone();
+    needScienceLab.where('escola.lab_ciencias = 0');
+    req.queryIndex.needScienceLab = req.querySet.push(needScienceLab) - 1;
+
     // Parque infantil
     let allKidsPark = allSchools.clone();
-    allKidsPark.where('escola.func_predio_escolar = 1')
-    .where('escola.reg_infantil_creche = 1 OR escola.reg_infantil_preescola = 1 OR escola.reg_fund_ai = 1 OR escola.esp_infantil_creche = 1 OR escola.esp_exclusiva_creche = 1 OR escola.reg_esp_exclusiva_fund_ai = 1');
+    allKidsPark.where('escola.reg_infantil_creche = 1 OR escola.reg_infantil_preescola = 1 OR escola.reg_fund_ai = 1');
     req.queryIndex.allKidsPark = req.querySet.push(allKidsPark) - 1;
 
     let haveKidsPark = allKidsPark.clone();
     haveKidsPark.where('escola.parque_infantil = 1');
     req.queryIndex.haveKidsPark = req.querySet.push(haveKidsPark) - 1;
 
+    let needKidsPark = allKidsPark.clone();
+    needKidsPark.where('escola.parque_infantil = 0');
+    req.queryIndex.needKidsPark = req.querySet.push(needKidsPark) - 1;
+
     // Berçário
     let allCribs = allSchools.clone();
-    allCribs.where('escola.func_predio_escolar = 1')
-    .where('escola.reg_infantil_creche = 1 OR escola.esp_infantil_creche = 1');
+    allCribs.where('escola.reg_infantil_creche = 1');
     req.queryIndex.allCribs = req.querySet.push(allCribs) - 1;
 
     let haveCribs = allCribs.clone();
     haveCribs.where('escola.bercario = 1');
     req.queryIndex.haveCribs = req.querySet.push(haveCribs) - 1;
 
-    // Quadra
-    let allSportsCourt = allScienceLab.clone();
-    allSportsCourt.where('escola.cod_localizacao = 1');
+    let needCribs = allCribs.clone();
+    needCribs.where('escola.bercario = 0');
+    req.queryIndex.needCribs = req.querySet.push(needCribs) - 1;
+
+    // Quadra Coberta
+    let allSportsCourt = allSchools.clone();
+    allSportsCourt.where('escola.reg_fund_ai = 1 OR escola.reg_fund_af = 1 OR escola.reg_medio_medio = 1 OR escola.reg_medio_integrado OR escola.reg_medio_normal = 1 OR escola.ensino_eja_fund = 1 OR escola.ensino_eja_medio = 1 OR escola.ensino_eja_prof = 1');
     req.queryIndex.allSportsCourt = req.querySet.push(allSportsCourt) - 1;
 
     let haveSportsCourt = allSportsCourt.clone();
     haveSportsCourt.where('escola.quadra_esportes = 1');
     req.queryIndex.haveSportsCourt = req.querySet.push(haveSportsCourt) - 1;
 
-    // Quadra coberta
-    req.queryIndex.allCoveredSportsCourt = req.queryIndex.allSportsCourt;
+    let needSportsCourt = allSportsCourt.clone();
+    needSportsCourt.where('escola.quadra_esportes = 0');
+    req.queryIndex.needSportsCourt = req.querySet.push(needSportsCourt) - 1;
+
+    // Cobertura de quadra esportiva
+    // FIXME: possível fixme no where
+    req.queryIndex.allSportsCourtCoverage = req.queryIndex.allSportsCourt;
+
+    let haveSportsCourtCoverage = allSportsCourt.clone();
+    haveSportsCourtCoverage.where('escola.quadra_esportes_descoberta = 1');
+    req.queryIndex.haveSportsCourtCoverage = req.querySet.push(haveSportsCourtCoverage) - 1;
+
+    let needSportsCourtCoverage = allSportsCourt.clone();
+    needSportsCourtCoverage.where('escola.quadra_esportes_descoberta = 0');
 
-    let haveCoveredSportsCourt = allSportsCourt.clone();
-    haveCoveredSportsCourt.where('escola.quadra_esportes_coberta = 1');
-    req.queryIndex.haveCoveredSportsCourt = req.querySet.push(haveCoveredSportsCourt) - 1;
+    // Pátio
+    req.queryIndex.allCourtyard = req.queryIndex.allSchools;
 
-    // Quadra Descoberta
-    let allUncoveredSportsCourt = allSportsCourt.clone();
-    allUncoveredSportsCourt.where('escola.quadra_esportes_coberta = 0');
-    req.queryIndex.allUncoveredSportsCourt = req.querySet.push(allUncoveredSportsCourt) - 1;
+    let haveCourtyard = allSchools.clone();
+    haveCourtyard.where('escola.patio_coberto = 1');
+    req.queryIndex.haveCourtyard = req.querySet.push(haveCourtyard) - 1;
 
-    let haveUncoveredSportsCourt = allUncoveredSportsCourt.clone();
-    haveUncoveredSportsCourt.where('escola.quadra_esportes_descoberta = 1');
-    req.queryIndex.haveUncoveredSportsCourt = req.querySet.push(haveUncoveredSportsCourt) - 1;
+    let needCourtyard = allSchools.clone();
+    needCourtyard.where('escola.patio_descoberto = 0');
+    req.queryIndex.needCourtyard = req.querySet.push(needCourtyard) - 1;
+
+    // Cobertura do Pátio
+    // TODO:
 
     // Sala de direção
-    let allDirectorRoom = allSchools.clone();
-    allDirectorRoom.where('escola.func_predio_escolar = 1 AND escola.cod_localizacao = 1');
-    req.queryIndex.allDirectorRoom = req.querySet.push(allDirectorRoom) - 1;
+    req.queryIndex.allDirectorRoom = req.queryIndex.allLibraries;
 
-    let haveDirectorRoom = allDirectorRoom.clone();
+    let haveDirectorRoom = allLibraries.clone();
     haveDirectorRoom.where('escola.sala_diretoria = 1');
     req.queryIndex.haveDirectorRoom = req.querySet.push(haveDirectorRoom) - 1;
 
+    let needDirectorRoom = allLibraries.clone();
+    needDirectorRoom.where('escola.sala_diretoria = 0');
+    req.queryIndex.needDirectorRoom = req.querySet.push(needDirectorRoom) - 1;
+
     // Secretaria
-    let allSecretary = allSchools.clone();
-    allSecretary.where('escola.func_predio_escolar = 1');
-    req.queryIndex.allSecretary = req.querySet.push(allSecretary) - 1;
+    req.queryIndex.allSecretary = req.queryIndex.allSchools;
 
-    let haveSecretary = allSecretary.clone();
+    let haveSecretary = allSchools.clone();
     haveSecretary.where('escola.secretaria = 1');
     req.queryIndex.haveSecretary = req.querySet.push(haveSecretary) - 1;
 
+    let needSecretary = allSchools.clone();
+    needSecretary.where('escola.secretaria = 0');
+    req.queryIndex.needSecretary = req.querySet.push(needSecretary) - 1;
+
     // Sala de professores
-    req.queryIndex.allTeacherRoom = req.queryIndex.allSecretary;
+    req.queryIndex.allTeacherRoom = req.queryIndex.allSchools;
 
-    let haveTeacherRoom = allSecretary.clone();
+    let haveTeacherRoom = allSchools.clone();
     haveTeacherRoom.where('escola.sala_professor = 1');
     req.queryIndex.haveTeacherRoom = req.querySet.push(haveTeacherRoom) - 1;
 
+    let needTeacherRoom = allSchools.clone();
+    needTeacherRoom.where('escola.sala_professor = 0');
+    req.queryIndex.needTeacherRoom = req.querySet.push(needTeacherRoom) - 1;
+
     // Cozinha
-    req.queryIndex.allKitchen = req.queryIndex.allSecretary;
+    req.queryIndex.allKitchen = req.queryIndex.allSchools;
 
-    let haveKitchen = allSecretary.clone();
+    let haveKitchen = allSchools.clone();
     haveKitchen.where('escola.cozinha = 1');
     req.queryIndex.haveKitchen = req.querySet.push(haveKitchen) - 1;
 
+    let needKitchen = allSchools.clone();
+    needKitchen.where('escola.cozinha = 0');
+    req.queryIndex.needKitchen = req.querySet.push(needKitchen) - 1;
+
     // Despensa
-    req.queryIndex.allStoreroom = req.queryIndex.allSecretary;
+    req.queryIndex.allStoreroom = req.queryIndex.allSchools;
 
-    let haveStoreroom = allSecretary.clone();
+    let haveStoreroom = allSchools.clone();
     haveStoreroom.where('escola.despensa = 1');
     req.queryIndex.haveStoreroom = req.querySet.push(haveStoreroom) - 1;
 
+    let needStoreroom = allSchools.clone();
+    needStoreroom.where('escola.despensa = 0');
+    req.queryIndex.needStoreroom = req.querySet.push(needStoreroom) - 1;
+
     // Almoxarifado
-    req.queryIndex.allWarehouse = req.queryIndex.allSecretary;
+    req.queryIndex.allWarehouse = req.queryIndex.allSchools;
 
-    let haveWarehouse = allSecretary.clone();
+    let haveWarehouse = allSchools.clone();
     haveWarehouse.where('escola.almoxarifado = 1');
     req.queryIndex.haveWarehouse = req.querySet.push(haveWarehouse) - 1;
 
+    let needWarehouse = allSchools.clone();
+    needWarehouse.where('escola.almoxarifado = 1');
+    req.queryIndex.needWarehouse = req.querySet.push(needWarehouse) - 1;
+
     // Internet
     req.queryIndex.allInternet = req.queryIndex.allLibrariesReadingRoom;
 
@@ -421,6 +474,10 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     haveInternet.where('escola.internet = 1');
     req.queryIndex.haveInternet = req.querySet.push(haveInternet) - 1;
 
+    let needInternet = allLibrariesReadingRoom.clone();
+    needInternet.where('escola.internet = 0');
+    req.queryIndex.needInternet = req.querySet.push(needInternet) - 1;
+
     // Internet banda larga
     req.queryIndex.allBroadbandInternet = req.queryIndex.allLibraries;
 
@@ -428,6 +485,10 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     haveBroadbandInternet.where('escola.internet_banda_larga = 1');
     req.queryIndex.haveBroadbandInternet = req.querySet.push(haveBroadbandInternet) - 1;
 
+    let needBroadbandInternet = allLibraries.clone();
+    needBroadbandInternet.where('escola.internet_banda_larga = 0');
+    req.queryIndex.needBroadbandInternet = req.querySet.push(needBroadbandInternet) - 1;
+
     // Banheiro dentro do prédio
     req.queryIndex.allInsideBathroom = req.queryIndex.allSecretary;
 
-- 
GitLab


From 1cf23495c97a4b673ebb0aa7db5b7f614fc6e402 Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Thu, 5 Jul 2018 10:00:10 -0300
Subject: [PATCH 03/38] Add route school infrastructure

---
 src/libs/routes/api.js                   |   3 +
 src/libs/routes/school_infrastructure.js | 181 +++++++++++++----------
 2 files changed, 107 insertions(+), 77 deletions(-)

diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index 70311ae0..7d9b7644 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -56,6 +56,8 @@ const downloads = require(`${libs}/routes/downloads`);
 
 const infrastructure = require(`${libs}/routes/infrastructure`);
 
+const schoolInfrastructure = require(`${libs}/routes/school_infrastructure`);
+
 const distributionFactor = require(`${libs}/routes/distributionFactor`);
 
 const siope = require(`${libs}/routes/siope`);
@@ -98,6 +100,7 @@ api.use('/reset', resetToken);
 api.use('/education_years', educationYears);
 api.use('/downloads', downloads);
 api.use('/infrastructure', infrastructure);
+api.use('/school_infrastructure', schoolInfrastructure);
 api.use('/distribution_factor', distributionFactor);
 api.use('/siope', siope);
 api.use('/out_of_school', outOfSchool);
diff --git a/src/libs/routes/school_infrastructure.js b/src/libs/routes/school_infrastructure.js
index 33d73165..5244b465 100644
--- a/src/libs/routes/school_infrastructure.js
+++ b/src/libs/routes/school_infrastructure.js
@@ -230,7 +230,7 @@ rqf.addField({
     }
 });
 
-function matchQueries(queryTotal, queryPartial) {
+function matchQueries(queryTotal, queryPartial, queryNeeded) {
     let match = [];
     queryTotal.forEach((result) => {
         let newObj = {};
@@ -240,7 +240,8 @@ function matchQueries(queryTotal, queryPartial) {
         });
         let index = keys.indexOf('total');
         if(index > -1) keys.splice(index, 1);
-        let objMatch = null;
+        let partialMatch = null;
+        let needMatch = null;
 
         for(let i = 0; i < queryPartial.length; ++i) {
             let partial = queryPartial[i];
@@ -253,15 +254,32 @@ function matchQueries(queryTotal, queryPartial) {
                 }
             }
             if(foundMatch) {
-                objMatch = partial;
+                partialMatch = partial;
                 break;
             }
         }
 
-        if(objMatch) {
-            newObj.percentage = (objMatch.total / result.total) * 100;
-            newObj.partial = objMatch.total;
-            newObj.total = result.total
+        for(let i = 0; i < queryNeeded.length; ++i) {
+            let needed = queryNeeded[i];
+            let foundMatch = true;
+            for(let j = 0; j < keys.length; ++j) {
+                let key = keys[j];
+                if(needed[key] !== result[key]) {
+                    foundMatch = false;
+                    break;
+                }
+            }
+            if(foundMatch) {
+                needMatch = needed;
+                break;
+            }
+        }
+
+        if(partialMatch && needMatch) {
+            newObj.percentage = (partialMatch.total / result.total) * 100;
+            newObj.partial = partialMatch.total;
+            newObj.total = result.total;
+            newObj.need_adaptation = needMatch.total;
             match.push(newObj);
         }
     });
@@ -284,6 +302,7 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     .where('escola.local_func_predio_escolar = 1')
     .where('escola.dependencia_adm_id <= 3')
     .order('escola.ano_censo');
+    req.queryIndex.allSchools = req.querySet.push(allSchools) - 1;
 
     // Bibliotecas
     let allLibraries = allSchools.clone();
@@ -386,20 +405,30 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
 
     let needSportsCourtCoverage = allSportsCourt.clone();
     needSportsCourtCoverage.where('escola.quadra_esportes_descoberta = 0');
+    req.queryIndex.needSportsCourtCoverage = req.querySet.push(needSportsCourtCoverage) - 1;
 
     // Pátio
     req.queryIndex.allCourtyard = req.queryIndex.allSchools;
 
     let haveCourtyard = allSchools.clone();
-    haveCourtyard.where('escola.patio_coberto = 1');
+    haveCourtyard.where('escola.patio_coberto = 1 OR escola.patio_descoberto = 1');
     req.queryIndex.haveCourtyard = req.querySet.push(haveCourtyard) - 1;
 
     let needCourtyard = allSchools.clone();
-    needCourtyard.where('escola.patio_descoberto = 0');
+    needCourtyard.where('escola.patio_descoberto = 0 AND escola.patio_descoberto = 0');
     req.queryIndex.needCourtyard = req.querySet.push(needCourtyard) - 1;
 
     // Cobertura do Pátio
-    // TODO:
+    // FIXME: possível fixme no where
+    req.queryIndex.allCourtyardCoverage = req.queryIndex.allSchools;
+
+    let haveCourtyardCoverage = allSchools.clone();
+    haveCourtyardCoverage.where('escola.patio_coberto=0 AND escola.patio_descoberto = 1');
+    req.queryIndex.haveCourtyardCoverage = req.querySet.push(haveCourtyardCoverage) - 1;
+
+    let needCourtyardCoverage = allSchools.clone();
+    needCourtyardCoverage.where('escola.patio_coberto=0 AND escola.patio_descoberto=0');
+    req.queryIndex.needCourtyardCoverage = req.querySet.push(needCourtyardCoverage) - 1;
 
     // Sala de direção
     req.queryIndex.allDirectorRoom = req.queryIndex.allLibraries;
@@ -489,13 +518,6 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     needBroadbandInternet.where('escola.internet_banda_larga = 0');
     req.queryIndex.needBroadbandInternet = req.querySet.push(needBroadbandInternet) - 1;
 
-    // Banheiro dentro do prédio
-    req.queryIndex.allInsideBathroom = req.queryIndex.allSecretary;
-
-    let haveInsideBathroom = allSecretary.clone();
-    haveInsideBathroom.where('escola.sanitario_dentro_predio = 1');
-    req.queryIndex.haveInsideBathroom = req.querySet.push(haveInsideBathroom) - 1;
-
     // Banheiro adequado para educação infantil dentro do prédio
     req.queryIndex.allInsideKidsBathroom = req.queryIndex.allKidsPark;
 
@@ -503,88 +525,95 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     haveInsideKidsBathroom.where('escola.sanitario_ei = 1');
     req.queryIndex.haveInsideKidsBathroom = req.querySet.push(haveInsideKidsBathroom) - 1;
 
-    // Fornecimento de energia
-    req.queryIndex.allEletricEnergy = req.queryIndex.allSecretary;
-
-    let haveEletricEnergy = allSecretary.clone();
-    haveEletricEnergy.where('escola.fornecimento_energia = 1');
-    req.queryIndex.haveEletricEnergy = req.querySet.push(haveEletricEnergy) - 1;
+    let needInsideKidsBathroom = allKidsPark.clone();
+    needInsideKidsBathroom.where('escola.sanitario_ei = 0');
+    req.queryIndex.needInsideKidsBathroom = req.querySet.push(needInsideKidsBathroom) - 1;
 
     // Abastecimento de água
-    req.queryIndex.allWaterSupply = req.queryIndex.allSecretary;
+    req.queryIndex.allWaterSupply = req.queryIndex.allSchools;
 
-    let haveWaterSupply = allSecretary.clone();
+    let haveWaterSupply = allSchools.clone();
     haveWaterSupply.where('escola.fornecimento_agua = 1');
     req.queryIndex.haveWaterSupply = req.querySet.push(haveWaterSupply) - 1;
 
+    let needWaterSupply = allSchools.clone();
+    needWaterSupply.where('escola.fornecimento_agua = 0');
+    req.queryIndex.needWaterSupply = req.querySet.push(needWaterSupply) - 1;
+
     // Água filtrada
-    req.queryIndex.allFilteredWater = req.queryIndex.allSecretary;
+    req.queryIndex.allFilteredWater = req.queryIndex.allSchools;
 
-    let haveFilteredWater = allSecretary.clone();
+    let haveFilteredWater = allSchools.clone();
     haveFilteredWater.where('escola.agua_filtrada = 1');
     req.queryIndex.haveFilteredWater = req.querySet.push(haveFilteredWater) - 1;
 
+    let needFilteredWater = allSchools.clone();
+    needFilteredWater.where('escola.agua_filtrada = 0');
+    req.queryIndex.needFilteredWater = req.querySet.push(needFilteredWater) - 1;
+
     // Coleta de esgoto
-    req.queryIndex.allSewage = req.queryIndex.allSecretary;
+    req.queryIndex.allSewage = req.queryIndex.allSchools;
 
-    let haveSewage = allSecretary.clone();
+    let haveSewage = allSchools.clone();
     haveSewage.where('escola.esgoto_sanitario = 1');
     req.queryIndex.haveSewage = req.querySet.push(haveSewage) - 1;
 
-    // Sala de recursos multifuncionais para Atendimento Educacional Especializado
-    req.queryIndex.allMultifunctionRoom = req.queryIndex.allSecretary;
+    let needSewage = allSchools.clone();
+    needSewage.where('escola.esgoto_sanitario = 0');
+    req.queryIndex.needSewage = req.querySet.push(needSewage) - 1;
+
+    // Dependências adaptada para pessoas com deficiências
+    req.queryIndex.allAdaptedBuilding = req.queryIndex.allSchools;
+
+    let haveAdaptedBuilding = allSchools.clone();
+    haveAdaptedBuilding.where('escola.dependencias_pne = 1');
+    req.queryIndex.haveAdaptedBuilding = req.querySet.push(haveAdaptedBuilding) - 1;
 
-    let haveMultifunctionRoom = allSecretary.clone();
-    haveMultifunctionRoom.where('escola.sala_atendimento_especial = 1');
-    req.queryIndex.haveMultifunctionRoom = req.querySet.push(haveMultifunctionRoom) - 1;
+    let needAdaptedBuilding = allSchools.clone();
+    needAdaptedBuilding.where('escola.dependencias_pne = 0');
+    req.queryIndex.needAdaptedBuilding = req.querySet.push(needAdaptedBuilding) - 1;
 
     // Banheiros adaptados para pessoas com deficiências
-    req.queryIndex.allSpecialBathroom = req.queryIndex.allSecretary;
+    req.queryIndex.allSpecialBathroom = req.queryIndex.allSchools;
 
-    let haveSpecialBathroom = allSecretary.clone();
+    let haveSpecialBathroom = allSchools.clone();
     haveSpecialBathroom.where('escola.sanitario_pne = 1');
     req.queryIndex.haveSpecialBathroom = req.querySet.push(haveSpecialBathroom) - 1;
 
-    // Dependências adaptada para pessoas com deficiências
-    req.queryIndex.allAdaptedBuilding = req.queryIndex.allSecretary;
+    let needSpecialBathroom = allSchools.clone();
+    needSpecialBathroom.where('escola.sanitario_pne = 1');
+    req.queryIndex.needSpecialBathroom = req.querySet.push(needSpecialBathroom) - 1;
 
-    let haveAdaptedBuilding = allSecretary.clone();
-    haveAdaptedBuilding.where('escola.dependencias_pne = 1');
-    req.queryIndex.haveAdaptedBuilding = req.querySet.push(haveAdaptedBuilding) - 1;
 
     next();
 }, multiQuery, (req, res, next) => {
     // Faz o matching entre os resultados
-    let school_place = matchQueries(req.result[req.queryIndex.allSchools], req.result[req.queryIndex.schoolPlace]);
-    let libraries = matchQueries(req.result[req.queryIndex.allLibraries], req.result[req.queryIndex.haveLibraries]);
-    let libraries_reading_room = matchQueries(req.result[req.queryIndex.allLibrariesReadingRoom], req.result[req.queryIndex.haveLibrariesReadingRoom]);
-    let computer_lab = matchQueries(req.result[req.queryIndex.allInfLab], req.result[req.queryIndex.haveInfLab]);
-    let science_lab = matchQueries(req.result[req.queryIndex.allScienceLab], req.result[req.queryIndex.haveScienceLab]);
-    let kids_park = matchQueries(req.result[req.queryIndex.allKidsPark], req.result[req.queryIndex.haveKidsPark]);
-    let nursery = matchQueries(req.result[req.queryIndex.allCribs], req.result[req.queryIndex.haveCribs]);
-    let sports_court = matchQueries(req.result[req.queryIndex.allSportsCourt], req.result[req.queryIndex.haveSportsCourt]);
-    let covered_sports_court = matchQueries(req.result[req.queryIndex.allCoveredSportsCourt], req.result[req.queryIndex.haveCoveredSportsCourt]);
-    let uncovered_sports_court = matchQueries(req.result[req.queryIndex.allUncoveredSportsCourt], req.result[req.queryIndex.haveUncoveredSportsCourt]);
-    let director_room = matchQueries(req.result[req.queryIndex.allDirectorRoom], req.result[req.queryIndex.haveDirectorRoom]);
-    let secretary = matchQueries(req.result[req.queryIndex.allSecretary], req.result[req.queryIndex.haveSecretary]);
-    let teacher_room = matchQueries(req.result[req.queryIndex.allTeacherRoom], req.result[req.queryIndex.haveTeacherRoom]);
-    let kitchen = matchQueries(req.result[req.queryIndex.allKitchen], req.result[req.queryIndex.haveKitchen]);
-    let storeroom = matchQueries(req.result[req.queryIndex.allStoreroom], req.result[req.queryIndex.haveStoreroom]);
-    let warehouse = matchQueries(req.result[req.queryIndex.allWarehouse], req.result[req.queryIndex.haveWarehouse]);
-    let internet = matchQueries(req.result[req.queryIndex.allInternet], req.result[req.queryIndex.haveInternet]);
-    let broadband_internet = matchQueries(req.result[req.queryIndex.allBroadbandInternet], req.result[req.queryIndex.haveBroadbandInternet]);
-    let inside_bathroom = matchQueries(req.result[req.queryIndex.allInsideBathroom], req.result[req.queryIndex.haveInsideBathroom]);
-    let inside_kids_bathroom = matchQueries(req.result[req.queryIndex.allInsideKidsBathroom], req.result[req.queryIndex.haveInsideKidsBathroom]);
-    let eletric_energy = matchQueries(req.result[req.queryIndex.allEletricEnergy], req.result[req.queryIndex.haveEletricEnergy]);
-    let water_supply = matchQueries(req.result[req.queryIndex.allWaterSupply], req.result[req.queryIndex.haveWaterSupply]);
-    let filtered_water = matchQueries(req.result[req.queryIndex.allFilteredWater], req.result[req.queryIndex.haveFilteredWater]);
-    let sewage_treatment = matchQueries(req.result[req.queryIndex.allSewage], req.result[req.queryIndex.haveSewage]);
-    let special_multifunction_room = matchQueries(req.result[req.queryIndex.allMultifunctionRoom], req.result[req.queryIndex.haveMultifunctionRoom]);
-    let special_bathroom = matchQueries(req.result[req.queryIndex.allSpecialBathroom], req.result[req.queryIndex.haveSpecialBathroom]);
-    let adapted_building = matchQueries(req.result[req.queryIndex.allAdaptedBuilding], req.result[req.queryIndex.haveAdaptedBuilding]);
+    let libraries = matchQueries(req.result[req.queryIndex.allLibraries], req.result[req.queryIndex.haveLibraries], req.result[req.queryIndex.needLibraries]);
+    let libraries_reading_room = matchQueries(req.result[req.queryIndex.allLibrariesReadingRoom], req.result[req.queryIndex.haveLibrariesReadingRoom], req.result[req.queryIndex.needLibrariesReadingRoom]);
+    let computer_lab = matchQueries(req.result[req.queryIndex.allInfLab], req.result[req.queryIndex.haveInfLab], req.result[req.queryIndex.needInfLab]);
+    let science_lab = matchQueries(req.result[req.queryIndex.allScienceLab], req.result[req.queryIndex.haveScienceLab], req.result[req.queryIndex.needScienceLab]);
+    let kids_park = matchQueries(req.result[req.queryIndex.allKidsPark], req.result[req.queryIndex.haveKidsPark], req.result[req.queryIndex.needKidsPark]);
+    let nursery = matchQueries(req.result[req.queryIndex.allCribs], req.result[req.queryIndex.haveCribs], req.result[req.queryIndex.needCribs]);
+    let sports_court = matchQueries(req.result[req.queryIndex.allSportsCourt], req.result[req.queryIndex.haveSportsCourt], req.result[req.queryIndex.needSportsCourt]);
+    let sports_court_coverage = matchQueries(req.result[req.queryIndex.allSportsCourtCoverage], req.result[req.queryIndex.haveSportsCourtCoverage], req.result[req.queryIndex.needSportsCourtCoverage]);
+    let courtyard = matchQueries(req.result[req.queryIndex.allCourtyard], req.result[req.queryIndex.haveCourtyard], req.result[req.queryIndex.needCourtyard]);
+    let courtyard_coverage = matchQueries(req.result[req.queryIndex.allCourtyardCoverage], req.result[req.queryIndex.haveCourtyardCoverage], req.result[req.queryIndex.needCourtyardCoverage]);
+    let director_room = matchQueries(req.result[req.queryIndex.allDirectorRoom], req.result[req.queryIndex.haveDirectorRoom], req.result[req.queryIndex.needDirectorRoom]);
+    let secretary = matchQueries(req.result[req.queryIndex.allSecretary], req.result[req.queryIndex.haveSecretary], req.result[req.queryIndex.needSecretary]);
+    let teacher_room = matchQueries(req.result[req.queryIndex.allTeacherRoom], req.result[req.queryIndex.haveTeacherRoom], req.result[req.queryIndex.needTeacherRoom]);
+    let kitchen = matchQueries(req.result[req.queryIndex.allKitchen], req.result[req.queryIndex.haveKitchen], req.result[req.queryIndex.needKitchen]);
+    let storeroom = matchQueries(req.result[req.queryIndex.allStoreroom], req.result[req.queryIndex.haveStoreroom], req.result[req.queryIndex.needStoreroom]);
+    let warehouse = matchQueries(req.result[req.queryIndex.allWarehouse], req.result[req.queryIndex.haveWarehouse], req.result[req.queryIndex.needWarehouse]);
+    let internet = matchQueries(req.result[req.queryIndex.allInternet], req.result[req.queryIndex.haveInternet], req.result[req.queryIndex.needInternet]);
+    let broadband_internet = matchQueries(req.result[req.queryIndex.allBroadbandInternet], req.result[req.queryIndex.haveBroadbandInternet], req.result[req.queryIndex.needBroadbandInternet]);
+    let inside_kids_bathroom = matchQueries(req.result[req.queryIndex.allInsideKidsBathroom], req.result[req.queryIndex.haveInsideKidsBathroom], req.result[req.queryIndex.needInsideKidsBathroom]);
+    let water_supply = matchQueries(req.result[req.queryIndex.allWaterSupply], req.result[req.queryIndex.haveWaterSupply], req.result[req.queryIndex.needWaterSupply]);
+    let filtered_water = matchQueries(req.result[req.queryIndex.allFilteredWater], req.result[req.queryIndex.haveFilteredWater], req.result[req.queryIndex.needFilteredWater]);
+    let sewage = matchQueries(req.result[req.queryIndex.allSewage], req.result[req.queryIndex.haveSewage], req.result[req.queryIndex.needSewage]);
+    let adapted_building = matchQueries(req.result[req.queryIndex.allAdaptedBuilding], req.result[req.queryIndex.haveAdaptedBuilding], req.result[req.queryIndex.needAdaptedBuilding]);
+    let special_bathroom = matchQueries(req.result[req.queryIndex.allSpecialBathroom], req.result[req.queryIndex.haveSpecialBathroom], req.result[req.queryIndex.needSpecialBathroom]);
 
     req.result = [{
-        school_place,
         libraries,
         libraries_reading_room,
         computer_lab,
@@ -592,8 +621,9 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         kids_park,
         nursery,
         sports_court,
-        covered_sports_court,
-        uncovered_sports_court,
+        sports_court_coverage,
+        courtyard,
+        courtyard_coverage,
         director_room,
         secretary,
         teacher_room,
@@ -602,15 +632,12 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         warehouse,
         internet,
         broadband_internet,
-        inside_bathroom,
         inside_kids_bathroom,
-        eletric_energy,
         water_supply,
         filtered_water,
-        sewage_treatment,
-        special_multifunction_room,
-        special_bathroom,
-        adapted_building
+        sewage,
+        adapted_building,
+        special_bathroom
     }];
 
     next();
-- 
GitLab


From 777487e3d569d0df970bac8fd164c87cb554597c Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Thu, 5 Jul 2018 11:07:11 -0300
Subject: [PATCH 04/38] Rename school infrastructure file

---
 src/libs/routes/api.js                                          | 2 +-
 .../{school_infrastructure.js => schoolInfrastructure.js}       | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename src/libs/routes/{school_infrastructure.js => schoolInfrastructure.js} (100%)

diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index 7d9b7644..e70a03d2 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -56,7 +56,7 @@ const downloads = require(`${libs}/routes/downloads`);
 
 const infrastructure = require(`${libs}/routes/infrastructure`);
 
-const schoolInfrastructure = require(`${libs}/routes/school_infrastructure`);
+const schoolInfrastructure = require(`${libs}/routes/schoolInfrastructure`);
 
 const distributionFactor = require(`${libs}/routes/distributionFactor`);
 
diff --git a/src/libs/routes/school_infrastructure.js b/src/libs/routes/schoolInfrastructure.js
similarity index 100%
rename from src/libs/routes/school_infrastructure.js
rename to src/libs/routes/schoolInfrastructure.js
-- 
GitLab


From 67b7e45d8829a9cd856fee77d25b791c047eac1e Mon Sep 17 00:00:00 2001
From: Fernando Erd <fce15@inf.ufpr.br>
Date: Thu, 5 Jul 2018 13:38:21 -0300
Subject: [PATCH 05/38] Add portalMec route

---
 src/libs/routes/api.js       |   4 ++
 src/libs/routes/portalMec.js | 136 +++++++++++++++++++++++++++++++++++
 2 files changed, 140 insertions(+)
 create mode 100644 src/libs/routes/portalMec.js

diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index 0a1b047f..6fcff09a 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -60,6 +60,8 @@ const distributionFactor = require(`${libs}/routes/distributionFactor`);
 
 const siope = require(`${libs}/routes/siope`);
 
+const verifyTeacher = require(`${libs}/routes/portalMec`);
+
 const outOfSchool = require(`${libs}/routes/outOfSchool`);
 
 const classroomCount = require(`${libs}/routes/classroomCount`);
@@ -107,5 +109,7 @@ api.use('/classroom_count', classroomCount);
 api.use('/daily_charge_amount', dailyChargeAmount);
 api.use('/transport', transport);
 api.use('/auxiliar', auxiliar);
+api.use('/verify_teacher', verifyTeacher);
+
 
 module.exports = api;
diff --git a/src/libs/routes/portalMec.js b/src/libs/routes/portalMec.js
new file mode 100644
index 00000000..afd84e8e
--- /dev/null
+++ b/src/libs/routes/portalMec.js
@@ -0,0 +1,136 @@
+const express = require('express');
+
+const portalMecApp = 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 id2str = require(`${libs}/middlewares/id2str`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+const addMissing = require(`${libs}/middlewares/addMissing`);
+
+const config = require(`${libs}/config`);
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
+
+let rqf = new ReqQueryFields();
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'day',
+    table: 'docente',
+    tableField: 'nasc_dia',
+    resultField: 'born_day_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        table: 'docente',
+        field: 'nasc_dia'
+    }
+}).addValue({
+    name: 'month',
+    table: 'docente',
+    tableField: 'nasc_mes_id',
+    resultField: 'born_month',
+    where: {
+        relation: '=',
+        type: 'integer',
+        table: 'docente',
+        field: 'nasc_mes'
+    }
+}).addValue({
+    name: 'year',
+    table: 'docente',
+    tableField: 'nasc_ano_id',
+    resultField: 'born_year',
+    where: {
+        relation: '=',
+        type: 'integer',
+        table: 'docente',
+        field: 'nasc_ano'
+    }
+}).addValue({
+    name: 'teacher',
+    table: 'docente',
+    tableField: 'id',
+    resultField: 'teacher_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        table: 'docente',
+        field: 'id'
+    }
+}).addValue({
+    name: 'min_year',
+    table: 'docente',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '>=',
+        type: 'integer',
+        table: 'docente',
+        field: 'ano_censo'
+    }
+}).addValue({
+    name: 'max_year',
+    table: 'docente',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '<=',
+        type: 'integer',
+        table: 'docente',
+        field: 'ano_censo'
+    }
+});
+
+portalMecApp.get('/', rqf.parse(), (req, res, next) => {
+
+    req.sql.field('docente.id')
+    .field('docente.ano_censo', 'year')
+    .field('docente.cod_quimica', 'Química')
+    .field('docente.cod_fisica', 'Física')
+    .field('docente.cod_matematica', 'Matemática')
+    .field('docente.cod_biologia', 'Biologia')
+    .field('docente.cod_ciencias', 'Ciências')
+    .field('docente.cod_literat_port', 'Língua/ Literatura Portuguesa')
+    .field('docente.cod_literat_ing', 'Língua/ Literatura estrangeira - Inglês')
+    .field('docente.cod_literat_esp', 'Língua/ Literatura estrangeira - Espanhol')
+    .field('docente.cod_literat_frances', 'Língua/ Literatura estrangeira - Francês')
+    .field('docente.literat_outra', 'Língua/ Literatura estrangeira - Outra')
+    .field('docente.cod_literat_indigena', 'Língua/ Literatura estrangeira - Língua Indígena')
+    .field('docente.cod_artes', 'Artes (Educação Artística, Teatro, Dança, Música, Artes Plásticas e outras)')
+    .field('docente.cod_ed_fisica', 'Educação Física')
+    .field('docente.cod_hist', 'História')
+    .field('docente.cod_geo', 'Geografia')
+    .field('docente.cod_filos', 'Filosofia')
+    .field('docente.cod_ensino_religioso', 'Ensino Religioso')
+    .field('docente.cod_estudos_sociais', 'Estudos Sociais')
+    .field('docente.cod_sociologia', 'Sociologia')
+    .field('docente.cod_inf_comp', 'Informática/ Computação')
+    .field('docente.cod_profissionalizante', 'Disciplinas profissionalizantes')
+    .field('docente.cod_disc_atendimento_especiais', 'Disciplinas voltadas ao atendimento às necessidades educacionais específicas dos alunos que são público alvo da educação especial e às práticas educacionais inclusivas')
+    .field('docente.cod_disc_diversidade_socio_cult', 'Disciplinas voltadas à diversidade sociocultural (Disciplinas pedagógicas)')
+    .field('docente.cod_libras', 'Libras')
+    .field('docente.cod_disciplina_pedag', 'Disciplinas pedagógicas')
+    .field('docente.cod_outras_disciplina', 'Outras disciplinas')
+    .from('docente')
+    next();
+
+}, rqf.build(), query, response('portalMec'));
+
+module.exports = portalMecApp;
-- 
GitLab


From 78499afd64dfdda38baf6e6dc3978212d8245728 Mon Sep 17 00:00:00 2001
From: Fernando Erd <fce15@inf.ufpr.br>
Date: Thu, 5 Jul 2018 15:27:19 -0300
Subject: [PATCH 06/38] Fix two var declaration

---
 src/libs/routes/transport.js | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/src/libs/routes/transport.js b/src/libs/routes/transport.js
index 38c81c9c..acc6ee9c 100644
--- a/src/libs/routes/transport.js
+++ b/src/libs/routes/transport.js
@@ -359,19 +359,6 @@ transportApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     .where('matricula.tipo <= 3');
     req.queryIndex.allEnrollmentTransport = req.querySet.push(allEnrollmentTransport) - 1;
 
-    let allEnrollmentTransport = req.sql.clone()
-    allEnrollmentTransport.field('COUNT(*)', 'total')
-    .field("'Brasil'", 'name')
-    .field('matricula.ano_censo', 'year')
-    .field('matricula.transporte_escolar_publico', 'use_transport_public_id')
-    .from('matricula')
-    .group('matricula.ano_censo')
-    .group('matricula.transporte_escolar_publico')
-    .order('matricula.ano_censo')
-    .where('matricula.tipo <= 3');
-    req.queryIndex.allEnrollmentTransport = req.querySet.push(allEnrollmentTransport) - 1;
-
-
     let allTransports = req.sql.clone()
     allTransports.field('COUNT(*)', 'total')
     .field("'Brasil'", 'name')
-- 
GitLab


From b7011cd92279fb534f7bae83acf422cba441e98d Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Fri, 6 Jul 2018 09:46:34 -0300
Subject: [PATCH 07/38] Fix sports court and courtyard coverage

---
 src/libs/routes/schoolInfrastructure.js | 33 +++++++++++--------------
 1 file changed, 14 insertions(+), 19 deletions(-)

diff --git a/src/libs/routes/schoolInfrastructure.js b/src/libs/routes/schoolInfrastructure.js
index 5244b465..969fa987 100644
--- a/src/libs/routes/schoolInfrastructure.js
+++ b/src/libs/routes/schoolInfrastructure.js
@@ -230,7 +230,7 @@ rqf.addField({
     }
 });
 
-function matchQueries(queryTotal, queryPartial, queryNeeded) {
+function matchQueries(queryTotal, queryPartial, queryNeeded, zeroPercentage=false) {
     let match = [];
     queryTotal.forEach((result) => {
         let newObj = {};
@@ -277,6 +277,7 @@ function matchQueries(queryTotal, queryPartial, queryNeeded) {
 
         if(partialMatch && needMatch) {
             newObj.percentage = (partialMatch.total / result.total) * 100;
+            if(zeroPercentage) newObj.percentage = 0;
             newObj.partial = partialMatch.total;
             newObj.total = result.total;
             newObj.need_adaptation = needMatch.total;
@@ -396,16 +397,13 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     req.queryIndex.needSportsCourt = req.querySet.push(needSportsCourt) - 1;
 
     // Cobertura de quadra esportiva
-    // FIXME: possível fixme no where
-    req.queryIndex.allSportsCourtCoverage = req.queryIndex.allSportsCourt;
+    let allSportsCourtCoverage = allSportsCourt.clone();
+    allSportsCourtCoverage.where('escola.quadra_esportes_descoberta = 1');
+    req.queryIndex.allSportsCourtCoverage = req.querySet.push(allSportsCourtCoverage);
 
-    let haveSportsCourtCoverage = allSportsCourt.clone();
-    haveSportsCourtCoverage.where('escola.quadra_esportes_descoberta = 1');
-    req.queryIndex.haveSportsCourtCoverage = req.querySet.push(haveSportsCourtCoverage) - 1;
+    req.queryIndex.haveSportsCourtCoverage = req.queryIndex.allSportsCourtCoverage;
 
-    let needSportsCourtCoverage = allSportsCourt.clone();
-    needSportsCourtCoverage.where('escola.quadra_esportes_descoberta = 0');
-    req.queryIndex.needSportsCourtCoverage = req.querySet.push(needSportsCourtCoverage) - 1;
+    req.queryIndex.needSportsCourtCoverage = req.queryIndex.allSportsCourtCoverage;
 
     // Pátio
     req.queryIndex.allCourtyard = req.queryIndex.allSchools;
@@ -419,16 +417,13 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     req.queryIndex.needCourtyard = req.querySet.push(needCourtyard) - 1;
 
     // Cobertura do Pátio
-    // FIXME: possível fixme no where
-    req.queryIndex.allCourtyardCoverage = req.queryIndex.allSchools;
+    let allCourtyardCoverage = allSchools.clone();
+    allCourtyardCoverage.where('escola.patio_coberto=0 AND escola.patio_descoberto = 1');
+    req.queryIndex.allCourtyardCoverage = req.querySet.push(allCourtyardCoverage) - 1;
 
-    let haveCourtyardCoverage = allSchools.clone();
-    haveCourtyardCoverage.where('escola.patio_coberto=0 AND escola.patio_descoberto = 1');
-    req.queryIndex.haveCourtyardCoverage = req.querySet.push(haveCourtyardCoverage) - 1;
+    req.queryIndex.haveCourtyardCoverage = req.queryIndex.allCourtyardCoverage;
 
-    let needCourtyardCoverage = allSchools.clone();
-    needCourtyardCoverage.where('escola.patio_coberto=0 AND escola.patio_descoberto=0');
-    req.queryIndex.needCourtyardCoverage = req.querySet.push(needCourtyardCoverage) - 1;
+    req.queryIndex.needCourtyardCoverage = req.queryIndex.allCourtyardCoverage;
 
     // Sala de direção
     req.queryIndex.allDirectorRoom = req.queryIndex.allLibraries;
@@ -595,9 +590,9 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     let kids_park = matchQueries(req.result[req.queryIndex.allKidsPark], req.result[req.queryIndex.haveKidsPark], req.result[req.queryIndex.needKidsPark]);
     let nursery = matchQueries(req.result[req.queryIndex.allCribs], req.result[req.queryIndex.haveCribs], req.result[req.queryIndex.needCribs]);
     let sports_court = matchQueries(req.result[req.queryIndex.allSportsCourt], req.result[req.queryIndex.haveSportsCourt], req.result[req.queryIndex.needSportsCourt]);
-    let sports_court_coverage = matchQueries(req.result[req.queryIndex.allSportsCourtCoverage], req.result[req.queryIndex.haveSportsCourtCoverage], req.result[req.queryIndex.needSportsCourtCoverage]);
+    let sports_court_coverage = matchQueries(req.result[req.queryIndex.allSportsCourtCoverage], req.result[req.queryIndex.haveSportsCourtCoverage], req.result[req.queryIndex.needSportsCourtCoverage], true);
     let courtyard = matchQueries(req.result[req.queryIndex.allCourtyard], req.result[req.queryIndex.haveCourtyard], req.result[req.queryIndex.needCourtyard]);
-    let courtyard_coverage = matchQueries(req.result[req.queryIndex.allCourtyardCoverage], req.result[req.queryIndex.haveCourtyardCoverage], req.result[req.queryIndex.needCourtyardCoverage]);
+    let courtyard_coverage = matchQueries(req.result[req.queryIndex.allCourtyardCoverage], req.result[req.queryIndex.haveCourtyardCoverage], req.result[req.queryIndex.needCourtyardCoverage], true);
     let director_room = matchQueries(req.result[req.queryIndex.allDirectorRoom], req.result[req.queryIndex.haveDirectorRoom], req.result[req.queryIndex.needDirectorRoom]);
     let secretary = matchQueries(req.result[req.queryIndex.allSecretary], req.result[req.queryIndex.haveSecretary], req.result[req.queryIndex.needSecretary]);
     let teacher_room = matchQueries(req.result[req.queryIndex.allTeacherRoom], req.result[req.queryIndex.haveTeacherRoom], req.result[req.queryIndex.needTeacherRoom]);
-- 
GitLab


From a6ccf741befefe1ea95c611eed35f9ded264b036 Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Mon, 9 Jul 2018 10:33:34 -0300
Subject: [PATCH 08/38] Add inside bathroom resulto to school infrastructure

---
 src/libs/routes/schoolInfrastructure.js | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/libs/routes/schoolInfrastructure.js b/src/libs/routes/schoolInfrastructure.js
index 969fa987..532dba73 100644
--- a/src/libs/routes/schoolInfrastructure.js
+++ b/src/libs/routes/schoolInfrastructure.js
@@ -513,6 +513,17 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     needBroadbandInternet.where('escola.internet_banda_larga = 0');
     req.queryIndex.needBroadbandInternet = req.querySet.push(needBroadbandInternet) - 1;
 
+    // Sanitário dentro do prédio
+    req.queryIndex.allInsideBathroom = req.queryIndex.allSchools;
+
+    let haveInsideBathroom = allSchools.clone();
+    haveInsideBathroom.where('escola.sanitario_dentro_predio = 1');
+    req.queryIndex.haveInsideBathroom = req.querySet.push(haveInsideBathroom) - 1;
+
+    let needInsideBathroom = allSchools.clone();
+    needInsideBathroom.where('escola.sanitario_dentro_predio = 0');
+    req.queryIndex.needInsideBathroom = req.querySet.push(needInsideBathroom) - 1;
+
     // Banheiro adequado para educação infantil dentro do prédio
     req.queryIndex.allInsideKidsBathroom = req.queryIndex.allKidsPark;
 
@@ -601,6 +612,7 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     let warehouse = matchQueries(req.result[req.queryIndex.allWarehouse], req.result[req.queryIndex.haveWarehouse], req.result[req.queryIndex.needWarehouse]);
     let internet = matchQueries(req.result[req.queryIndex.allInternet], req.result[req.queryIndex.haveInternet], req.result[req.queryIndex.needInternet]);
     let broadband_internet = matchQueries(req.result[req.queryIndex.allBroadbandInternet], req.result[req.queryIndex.haveBroadbandInternet], req.result[req.queryIndex.needBroadbandInternet]);
+    let inside_bathroom = matchQueries(req.result[req.queryIndex.allInsideBathroom], req.result[req.queryIndex.haveInsideBathroom], req.result[req.queryIndex.needInsideBathroom]);
     let inside_kids_bathroom = matchQueries(req.result[req.queryIndex.allInsideKidsBathroom], req.result[req.queryIndex.haveInsideKidsBathroom], req.result[req.queryIndex.needInsideKidsBathroom]);
     let water_supply = matchQueries(req.result[req.queryIndex.allWaterSupply], req.result[req.queryIndex.haveWaterSupply], req.result[req.queryIndex.needWaterSupply]);
     let filtered_water = matchQueries(req.result[req.queryIndex.allFilteredWater], req.result[req.queryIndex.haveFilteredWater], req.result[req.queryIndex.needFilteredWater]);
@@ -627,6 +639,7 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         warehouse,
         internet,
         broadband_internet,
+        inside_bathroom,
         inside_kids_bathroom,
         water_supply,
         filtered_water,
-- 
GitLab


From d4d39338bf867646e0c805275989880d8915cb0f Mon Sep 17 00:00:00 2001
From: Glenda <gpt16@inf.ufpr.br>
Date: Thu, 12 Jul 2018 09:33:25 -0300
Subject: [PATCH 09/38] fix auxiliar indicator filter

---
 src/libs/routes/auxiliar.js | 34 ++++++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/src/libs/routes/auxiliar.js b/src/libs/routes/auxiliar.js
index 21e7c5f5..a52ce99d 100644
--- a/src/libs/routes/auxiliar.js
+++ b/src/libs/routes/auxiliar.js
@@ -238,6 +238,36 @@ rqf.addField({
         foreign: 'escola_municipio_id',
         foreignTable: 'docente'
     }
+}, '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: 'docente'
+    }
+}, '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: 'docente'
+    }
 }, 'filter').addValue({
     name: 'location',
     table: 'docente',
@@ -298,7 +328,7 @@ auxiliarApp.get('/', rqf.parse(), (req, res, next) => {
   .from('docente')
   .group('docente.ano_censo')
   .order('docente.ano_censo')
-  .where('(docente.tipo_turma_id <= 3 AND docente.dependencia_adm_id > 1 AND docente.tipo_docente = 2)');
+  .where('(docente.tipo_turma_id <= 3 AND docente.tipo_docente = 2)');
   next();
 }, rqf.build(), query, addMissing(rqf), id2str.transform(), response('auxiliar'));
 
@@ -310,7 +340,7 @@ auxiliarApp.get('/count', rqf.parse(), (req, res, next) => {
   .from('docente')
   .group('docente.ano_censo')
   .order('docente.ano_censo')
-  .where('((docente.tipo_turma_id <= 3) AND (docente.dependencia_adm_id = 2 OR docente.dependencia_adm_id = 3) AND (docente.tipo_docente = 2))');
+  .where('(docente.tipo_turma_id <= 3 AND docente.dependencia_adm_id <= 3 AND docente.tipo_docente = 2)');
   next();
 }, rqf.build(), query, addMissing(rqf), id2str.transform(), response('auxiliar'));
 
-- 
GitLab


From 7e57501d74e0e27a469b00e2cb67a5f0b03cb209 Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Mon, 23 Jul 2018 09:29:16 -0300
Subject: [PATCH 10/38] Add eletrical power result to school infrastructure

Related: simcaq/SCRUM#421
---
 src/libs/routes/schoolInfrastructure.js | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/libs/routes/schoolInfrastructure.js b/src/libs/routes/schoolInfrastructure.js
index 532dba73..ebf51338 100644
--- a/src/libs/routes/schoolInfrastructure.js
+++ b/src/libs/routes/schoolInfrastructure.js
@@ -535,6 +535,17 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     needInsideKidsBathroom.where('escola.sanitario_ei = 0');
     req.queryIndex.needInsideKidsBathroom = req.querySet.push(needInsideKidsBathroom) - 1;
 
+    // Fornecimento de energia
+    req.queryIndex.allEletricPower = req.queryIndex.allSchools;
+
+    let haveEletricPower = allSchools.clone();
+    haveEletricPower.where('escola.fornecimento_energia = 1');
+    req.queryIndex.haveEletricPower = req.querySet.push(haveEletricPower) - 1;
+
+    let needEletricPower = allSchools.clone();
+    needEletricPower.where('escola.fornecimento_energia = 0');
+    req.queryIndex.needEletricPower = req.querySet.push(needEletricPower) - 1;
+
     // Abastecimento de água
     req.queryIndex.allWaterSupply = req.queryIndex.allSchools;
 
@@ -614,6 +625,7 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     let broadband_internet = matchQueries(req.result[req.queryIndex.allBroadbandInternet], req.result[req.queryIndex.haveBroadbandInternet], req.result[req.queryIndex.needBroadbandInternet]);
     let inside_bathroom = matchQueries(req.result[req.queryIndex.allInsideBathroom], req.result[req.queryIndex.haveInsideBathroom], req.result[req.queryIndex.needInsideBathroom]);
     let inside_kids_bathroom = matchQueries(req.result[req.queryIndex.allInsideKidsBathroom], req.result[req.queryIndex.haveInsideKidsBathroom], req.result[req.queryIndex.needInsideKidsBathroom]);
+    let eletrical_power = matchQueries(req.result[req.queryIndex.allEletricPower], req.result[req.queryIndex.haveEletricPower], req.result[req.queryIndex.needEletricPower]);
     let water_supply = matchQueries(req.result[req.queryIndex.allWaterSupply], req.result[req.queryIndex.haveWaterSupply], req.result[req.queryIndex.needWaterSupply]);
     let filtered_water = matchQueries(req.result[req.queryIndex.allFilteredWater], req.result[req.queryIndex.haveFilteredWater], req.result[req.queryIndex.needFilteredWater]);
     let sewage = matchQueries(req.result[req.queryIndex.allSewage], req.result[req.queryIndex.haveSewage], req.result[req.queryIndex.needSewage]);
@@ -641,6 +653,7 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         broadband_internet,
         inside_bathroom,
         inside_kids_bathroom,
+        eletrical_power,
         water_supply,
         filtered_water,
         sewage,
-- 
GitLab


From 5176a7cdc4dd84034a176319a0b844cf429225a9 Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Mon, 23 Jul 2018 09:47:16 -0300
Subject: [PATCH 11/38] Change adapted bathroom result in school infrastructure

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

diff --git a/src/libs/routes/schoolInfrastructure.js b/src/libs/routes/schoolInfrastructure.js
index ebf51338..c524b37a 100644
--- a/src/libs/routes/schoolInfrastructure.js
+++ b/src/libs/routes/schoolInfrastructure.js
@@ -630,7 +630,7 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     let filtered_water = matchQueries(req.result[req.queryIndex.allFilteredWater], req.result[req.queryIndex.haveFilteredWater], req.result[req.queryIndex.needFilteredWater]);
     let sewage = matchQueries(req.result[req.queryIndex.allSewage], req.result[req.queryIndex.haveSewage], req.result[req.queryIndex.needSewage]);
     let adapted_building = matchQueries(req.result[req.queryIndex.allAdaptedBuilding], req.result[req.queryIndex.haveAdaptedBuilding], req.result[req.queryIndex.needAdaptedBuilding]);
-    let special_bathroom = matchQueries(req.result[req.queryIndex.allSpecialBathroom], req.result[req.queryIndex.haveSpecialBathroom], req.result[req.queryIndex.needSpecialBathroom]);
+    let adapted_bathroom = matchQueries(req.result[req.queryIndex.allSpecialBathroom], req.result[req.queryIndex.haveSpecialBathroom], req.result[req.queryIndex.needSpecialBathroom]);
 
     req.result = [{
         libraries,
@@ -658,7 +658,7 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         filtered_water,
         sewage,
         adapted_building,
-        special_bathroom
+        adapted_bathroom
     }];
 
     next();
-- 
GitLab


From 00fb357eeb73a338d1209beeafa6745bd9a0c72e Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Mon, 23 Jul 2018 10:14:05 -0300
Subject: [PATCH 12/38] Fix total classroom needed math in classroom count

Related: simcaq/SCRUM#408
Problema 3 reportado em 2018-07-11
---
 src/libs/routes/classroomCount.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libs/routes/classroomCount.js b/src/libs/routes/classroomCount.js
index e3144507..bdec29e5 100644
--- a/src/libs/routes/classroomCount.js
+++ b/src/libs/routes/classroomCount.js
@@ -393,7 +393,7 @@ classroomCountApp.post('/', rqf.parse(), (req, res, next) => {
             // Total de salas
             educationLevel.enrollment.total_classrooms_needed = (educationLevel.enrollment.full_period_classes + educationLevel.enrollment.day_classes/2);
 
-            if(educationLevel.enrollment.night_classes > educationLevel.enrollment.day_classes) educationLevel.enrollment.total_classrooms_needed += (educationLevel.enrollment.night_classes - educationLevel.enrollment.day_classes);
+            if(educationLevel.enrollment.night_classes > (educationLevel.enrollment.day_classes/2)) educationLevel.enrollment.total_classrooms_needed += (educationLevel.enrollment.night_classes - (educationLevel.enrollment.day_classes/2));
 
             educationLevel.enrollment.total_classrooms_needed = Math.ceil(educationLevel.enrollment.total_classrooms_needed);
 
-- 
GitLab


From 4467a5280c1d08d9f62a1853303ea302e07fa82a Mon Sep 17 00:00:00 2001
From: Fernando Erd <fce15@inf.ufpr.br>
Date: Tue, 24 Jul 2018 09:52:27 -0300
Subject: [PATCH 13/38] Add new filters in enrollment

---
 src/libs/convert/ageRangeAll.js | 28 ++++++++++++++++++++
 src/libs/middlewares/id2str.js  | 10 +++++--
 src/libs/routes/enrollment.js   | 46 +++++++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+), 2 deletions(-)
 create mode 100644 src/libs/convert/ageRangeAll.js

diff --git a/src/libs/convert/ageRangeAll.js b/src/libs/convert/ageRangeAll.js
new file mode 100644
index 00000000..2b4cab9c
--- /dev/null
+++ b/src/libs/convert/ageRangeAll.js
@@ -0,0 +1,28 @@
+module.exports = function ageRange(id) {
+    switch (id) {
+        case 1:
+        return '0 a 3 anos';
+        case 2:
+        return '4 a 5 anos';
+        case 3:
+        return '6 a 10 anos';
+        case 4:
+        return '11 a 14 anos';
+        case 5:
+        return '15 a 17 anos';
+        case 6:
+        return '18 a 24 anos';
+        case 7:
+        return '25 a 29 anos';
+        case 8:
+        return '30 a 40 anos';
+        case 9:
+        return '41 a 50 anos';
+        case 10:
+        return '51 a 64 anos';
+        case 11:
+        return 'Mais que 64 anos';
+        default:
+        return 'Não declarada';
+    }
+};
diff --git a/src/libs/middlewares/id2str.js b/src/libs/middlewares/id2str.js
index c2fa1fab..0a0c2af9 100644
--- a/src/libs/middlewares/id2str.js
+++ b/src/libs/middlewares/id2str.js
@@ -20,6 +20,7 @@ const stateName = require(`${libs}/convert/stateName`);
 const contractType = require(`${libs}/convert/contractType`);
 const ethnicGroupPnad = require(`${libs}/convert/ethnicGroupPnad`);
 const ageRange = require(`${libs}/convert/ageRange`);
+const ageRangeAll = require(`${libs}/convert/ageRangeAll`);
 const fullAgeRange = require(`${libs}/convert/fullAgeRange`);
 const genderPnad = require(`${libs}/convert/genderPnad`);
 const fifthHouseholdIncome = require(`${libs}/convert/fifthHouseholdIncome`);
@@ -28,6 +29,7 @@ const educationLevelBasic = require(`${libs}/convert/educationLevelBasic`);
 const useTransport = require(`${libs}/convert/booleanVariable`);
 const useTransportPublic = require(`${libs}/convert/booleanVariable`);
 const transportationManager = require(`${libs}/convert/transportationManager`);
+const specialClass = require(`${libs}/convert/booleanVariable`);
 
 const ids = {
     gender_id: gender,
@@ -61,13 +63,15 @@ const ids = {
     contract_type_id: contractType,
     ethnic_group_pnad_id: ethnicGroupPnad,
     age_range_id: ageRange,
+    age_range_all_id: ageRangeAll,
     full_age_range_id: fullAgeRange,
     gender_pnad_id: genderPnad,
     fifth_household_income_id: fifthHouseholdIncome,
     extremes_household_income_id: extremesHouseholdIncome,
     use_transport_id: useTransport,
     use_transport_public_id: useTransportPublic,
-    transportation_manager_id: transportationManager
+    transportation_manager_id: transportationManager,
+    special_class_id: specialClass
 };
 
 function transform(removeId=false) {
@@ -130,10 +134,12 @@ module.exports = {
     contractType,
     ethnicGroupPnad,
     ageRange,
+    ageRangeAll,
     fullAgeRange,
     genderPnad,
     fifthHouseholdIncome,
     extremesHouseholdIncome,
     useTransport,
-    transportationManager
+    transportationManager,
+    specialClass
 };
diff --git a/src/libs/routes/enrollment.js b/src/libs/routes/enrollment.js
index 839eaba2..656df2a0 100644
--- a/src/libs/routes/enrollment.js
+++ b/src/libs/routes/enrollment.js
@@ -214,6 +214,32 @@ enrollmentApp.get('/integral_time', (req, res, next) => {
     next();
 }, response('integral_time'));
 
+enrollmentApp.get('/special_class', (req, res, next) => {
+    req.result = [
+        {id: null, name: 'Não Declarado'},
+        {id: 0, name: 'Não'},
+        {id: 1, name: 'Sim'}
+    ];
+    next();
+}, response('special_class'));
+
+enrollmentApp.get('/age_range_all', (req, res, next) => {
+    req.result = [
+        {id: 1, name: '0 a 3 anos'},
+        {id: 2, name: '4 a 5 anos'},
+        {id: 3, name: '6 a 10 anos'},
+        {id: 4, name: '11 a 14 anos'},
+        {id: 5, name: '15 a 17 anos'},
+        {id: 6, name: '18 a 24 anos'},
+        {id: 7, name: '25 a 29 anos'},
+        {id: 8, name: '30 a 40 anos'},
+        {id: 9, name: '41 a 50 anos'},
+        {id: 10, name: '51 a 64 anos'},
+        {id: 11, name: 'Mais que 64 anos'}
+    ];
+    next();
+}, response('age_range_all'));
+
 rqf.addField({
     name: 'filter',
     field: false,
@@ -452,6 +478,26 @@ rqf.addField({
       type: 'boolean',
       field: 'tempo_integral'
   }
+}).addValue({
+  name:'age_range_all',
+  table: 'matricula',
+  tableField: 'faixa_etaria_31_03',
+  resultField: 'age_range_all_id',
+  where: {
+      relation: '=',
+      type: 'integer',
+      field: 'faixa_etaria_31_03'
+  }
+}).addValue({
+  name:'special_class',
+  table: 'matricula',
+  tableField: 'exclusiva_especial',
+  resultField: 'special_class_id',
+  where: {
+      relation: '=',
+      type: 'boolean',
+      field: 'exclusiva_especial'
+  }
 });
 
 enrollmentApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
-- 
GitLab


From 9749cdfc6032102d5ce0d3f6e7bba1262d36ad78 Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Tue, 24 Jul 2018 10:09:08 -0300
Subject: [PATCH 14/38] Add information about school buildings in school
 infrastructure

Related: simcaq/SCRUM#421
---
 src/libs/routes/schoolInfrastructure.js | 62 +++++++++++++++++--------
 1 file changed, 43 insertions(+), 19 deletions(-)

diff --git a/src/libs/routes/schoolInfrastructure.js b/src/libs/routes/schoolInfrastructure.js
index c524b37a..c53a02af 100644
--- a/src/libs/routes/schoolInfrastructure.js
+++ b/src/libs/routes/schoolInfrastructure.js
@@ -305,29 +305,45 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     .order('escola.ano_censo');
     req.queryIndex.allSchools = req.querySet.push(allSchools) - 1;
 
+    let allUrbanSchools = allSchools.clone();
+    allUrbanSchools.where('escola.cod_localizacao = 1');
+    req.queryIndex.allUrbanSchools = req.querySet.push(allUrbanSchools) - 1;
+
+    let allCountrySchools = allSchools.clone();
+    allCountrySchools.where('escola.cod_localizacao = 2');
+    req.queryIndex.allCountrySchools = req.querySet.push(allCountrySchools) - 1;
+
+    let allSchoolsNotSchoolBuilding = req.sql.clone();
+    allSchoolsNotSchoolBuilding.from('escola').field('COUNT(escola.id)', 'total')
+    .field("'Brasil'", 'name')
+    .field('escola.ano_censo', 'year')
+    .group('escola.ano_censo')
+    .where('escola.situacao_de_funcionamento = 1')
+    .where('escola.ensino_regular = 1 OR escola.ensino_eja = 1 OR escola.educacao_profissional = 1')
+    .where('escola.local_func_predio_escolar = 0')
+    .where('escola.dependencia_adm_id <= 3')
+    .order('escola.ano_censo');
+    req.queryIndex.allSchoolsNotSchoolBuilding = req.querySet.push(allSchoolsNotSchoolBuilding) - 1;
+
     // Bibliotecas
-    let allLibraries = allSchools.clone();
-    allLibraries.where('escola.cod_localizacao = 1');
-    req.queryIndex.allLibraries = req.querySet.push(allLibraries) - 1;
+    req.queryIndex.allLibraries = req.queryIndex.allUrbanSchools;
 
-    let haveLibraries = allLibraries.clone();
+    let haveLibraries = allUrbanSchools.clone();
     haveLibraries.where('escola.biblioteca = 1');
     req.queryIndex.haveLibraries = req.querySet.push(haveLibraries) - 1;
 
-    let needLibraries = allLibraries.clone();
+    let needLibraries = allUrbanSchools.clone();
     needLibraries.where('escola.biblioteca = 0');
     req.queryIndex.needLibraries = req.querySet.push(needLibraries) - 1;
 
     // Bibliotecas/Sala de leitura
-    let allLibrariesReadingRoom = allSchools.clone();
-    allLibrariesReadingRoom.where('escola.cod_localizacao = 2');
-    req.queryIndex.allLibrariesReadingRoom = req.querySet.push(allLibrariesReadingRoom) - 1;
+    req.queryIndex.allLibrariesReadingRoom = req.queryIndex.allCountrySchools;
 
-    let haveLibrariesReadingRoom = allLibrariesReadingRoom.clone();
+    let haveLibrariesReadingRoom = allCountrySchools.clone();
     haveLibrariesReadingRoom.where('escola.biblioteca_sala_leitura = 1');
     req.queryIndex.haveLibrariesReadingRoom = req.querySet.push(haveLibrariesReadingRoom) - 1;
 
-    let needLibrariesReadingRoom = allLibrariesReadingRoom.clone();
+    let needLibrariesReadingRoom = allCountrySchools.clone();
     needLibrariesReadingRoom.where('escola.biblioteca_sala_leitura = 0');
     req.queryIndex.needLibrariesReadingRoom = req.querySet.push(needLibrariesReadingRoom) - 1;
 
@@ -428,11 +444,11 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     // Sala de direção
     req.queryIndex.allDirectorRoom = req.queryIndex.allLibraries;
 
-    let haveDirectorRoom = allLibraries.clone();
+    let haveDirectorRoom = allUrbanSchools.clone();
     haveDirectorRoom.where('escola.sala_diretoria = 1');
     req.queryIndex.haveDirectorRoom = req.querySet.push(haveDirectorRoom) - 1;
 
-    let needDirectorRoom = allLibraries.clone();
+    let needDirectorRoom = allUrbanSchools.clone();
     needDirectorRoom.where('escola.sala_diretoria = 0');
     req.queryIndex.needDirectorRoom = req.querySet.push(needDirectorRoom) - 1;
 
@@ -494,22 +510,22 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     // Internet
     req.queryIndex.allInternet = req.queryIndex.allLibrariesReadingRoom;
 
-    let haveInternet = allLibrariesReadingRoom.clone();
+    let haveInternet = allCountrySchools.clone();
     haveInternet.where('escola.internet = 1');
     req.queryIndex.haveInternet = req.querySet.push(haveInternet) - 1;
 
-    let needInternet = allLibrariesReadingRoom.clone();
+    let needInternet = allCountrySchools.clone();
     needInternet.where('escola.internet = 0');
     req.queryIndex.needInternet = req.querySet.push(needInternet) - 1;
 
     // Internet banda larga
     req.queryIndex.allBroadbandInternet = req.queryIndex.allLibraries;
 
-    let haveBroadbandInternet = allLibraries.clone();
+    let haveBroadbandInternet = allUrbanSchools.clone();
     haveBroadbandInternet.where('escola.internet_banda_larga = 1');
     req.queryIndex.haveBroadbandInternet = req.querySet.push(haveBroadbandInternet) - 1;
 
-    let needBroadbandInternet = allLibraries.clone();
+    let needBroadbandInternet = allUrbanSchools.clone();
     needBroadbandInternet.where('escola.internet_banda_larga = 0');
     req.queryIndex.needBroadbandInternet = req.querySet.push(needBroadbandInternet) - 1;
 
@@ -604,6 +620,10 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
 
     next();
 }, multiQuery, (req, res, next) => {
+    let schools_in_school_buildings = req.result[req.queryIndex.allSchools];
+    let urban_schools_in_school_buildings = req.result[req.queryIndex.allUrbanSchools];
+    let country_schools_in_school_buildings = req.result[req.queryIndex.allCountrySchools];
+    let schools_not_in_school_buildings = req.result[req.queryIndex.allSchoolsNotSchoolBuilding];
     // Faz o matching entre os resultados
     let libraries = matchQueries(req.result[req.queryIndex.allLibraries], req.result[req.queryIndex.haveLibraries], req.result[req.queryIndex.needLibraries]);
     let libraries_reading_room = matchQueries(req.result[req.queryIndex.allLibrariesReadingRoom], req.result[req.queryIndex.haveLibrariesReadingRoom], req.result[req.queryIndex.needLibrariesReadingRoom]);
@@ -633,6 +653,10 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     let adapted_bathroom = matchQueries(req.result[req.queryIndex.allSpecialBathroom], req.result[req.queryIndex.haveSpecialBathroom], req.result[req.queryIndex.needSpecialBathroom]);
 
     req.result = [{
+        schools_in_school_buildings,
+        urban_schools_in_school_buildings,
+        country_schools_in_school_buildings,
+        schools_not_in_school_buildings,
         libraries,
         libraries_reading_room,
         computer_lab,
@@ -653,12 +677,12 @@ infrastructureApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
         broadband_internet,
         inside_bathroom,
         inside_kids_bathroom,
-        eletrical_power,
+        eletric_energy: eletrical_power,
         water_supply,
         filtered_water,
-        sewage,
+        sewage_treatment: sewage,
         adapted_building,
-        adapted_bathroom
+        special_bathroom: adapted_bathroom
     }];
 
     next();
-- 
GitLab


From 508bfdce647cd4d3583f99added2d703e3a663de Mon Sep 17 00:00:00 2001
From: Glenda <gpt16@inf.ufpr.br>
Date: Tue, 24 Jul 2018 11:27:28 -0300
Subject: [PATCH 15/38] add class count route

---
 src/libs/routes/api.js        |   4 +-
 src/libs/routes/classCount.js | 359 ++++++++++++++++++++++++++++++++++
 2 files changed, 362 insertions(+), 1 deletion(-)
 create mode 100644 src/libs/routes/classCount.js

diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index 0049e3b7..dbdb0435 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -76,6 +76,8 @@ const dailyChargeAmount = require(`${libs}/routes/dailyChargeAmount`);
 
 const cub = require(`${libs}/routes/cub`);
 
+const classCount = require(`${libs}/routes/classCount`);
+
 api.get('/', (req, res) => {
     res.json({ msg: 'SimCAQ API is running' });
 });
@@ -116,6 +118,6 @@ api.use('/transport', transport);
 api.use('/cub', cub);
 api.use('/auxiliar', auxiliar);
 api.use('/verify_teacher', verifyTeacher);
-
+api.use('/class_count', classCount);
 
 module.exports = api;
diff --git a/src/libs/routes/classCount.js b/src/libs/routes/classCount.js
new file mode 100644
index 00000000..29aa2410
--- /dev/null
+++ b/src/libs/routes/classCount.js
@@ -0,0 +1,359 @@
+const express = require('express');
+
+const classCountApp = 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 addMissing = require(`${libs}/middlewares/addMissing`);
+
+const config = require(`${libs}/config`);
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
+
+let rqf = new ReqQueryFields();
+
+rqf.addField({
+  name: 'filter',
+  field: false,
+  where: true
+}).addField({
+  name: 'dims',
+  field: true,
+  where: false
+}).addValueToField({
+  name: 'city',
+  table: 'municipio',
+  tableField: ['nome', 'id'],
+  resultField: ['city_name', 'city_id'],
+  where: {
+    relation: '=',
+    type: 'integer',
+    field: 'municipio_id',
+    table: 'turma'
+  },
+  join: {
+    primary: 'id',
+    foreign: 'municipio_id',
+    foreignTable: 'turma'
+  }
+}, 'dims').addValueToField({
+  name: 'city',
+  table: 'municipio',
+  tableField: 'nome',
+  resultField: 'city_name',
+  where: {
+    relation: '=',
+    type: 'integer',
+    field: 'municipio_id',
+    table: 'turma'
+  },
+  join: {
+    primary: 'id',
+    foreign: 'municipio_id',
+    foreignTable: 'turma'
+  }
+}, 'filter')
+.addValue({
+  name: 'state',
+  table: 'estado',
+  tableField: 'nome',
+  resultField: 'state_name',
+  where: {
+    relation: '=',
+    type: 'integer',
+    field: 'estado_id',
+    table: 'turma'
+  },
+  join: {
+    primary: 'id',
+    foreign: 'estado_id',
+    foreignTable: 'turma'
+  }
+}).addValue({
+  name: 'region',
+  table: 'regiao',
+  tableField: 'nome',
+  resultField: 'region_name',
+  where: {
+    relation: '=',
+    type: 'integer',
+    field: 'id'
+  },
+  join: {
+    primary: 'id',
+    foreign: 'regiao_id',
+    foreignTable: 'turma'
+  }
+}).addValue({
+  name: 'min_year',
+  table: 'turma',
+  tableField: 'ano_censo',
+  resultField: 'year',
+  where: {
+    relation: '>=',
+    type: 'integer',
+    field: 'ano_censo'
+  }
+}).addValue({
+  name: 'max_year',
+  table: 'turma',
+  tableField: 'ano_censo',
+  resultField: 'year',
+  where: {
+    relation: '<=',
+    type: 'integer',
+    field: 'ano_censo'
+  }
+}).addValue({
+  name:'adm_dependency',
+  table: 'turma',
+  tableField: 'dependencia_adm_id',
+  resultField: 'adm_dependency_id',
+  where: {
+    relation: '=',
+    type: 'integer',
+    field: 'dependencia_adm_id'
+  }
+}).addValue({
+  name: 'location',
+  table: 'turma',
+  tableField: 'localizacao_id',
+  resultField: 'location_id',
+  where: {
+    relation: '=',
+    type: 'integer',
+    field: 'localizacao_id'
+  }
+}).addValue({
+  name: 'rural_location',
+  table: 'turma',
+  tableField: 'localidade_area_rural',
+  resultField: 'rural_location_id',
+  where: {
+    relation: '=',
+    type: 'integer',
+    field: 'localidade_area_rural'
+  }
+}).addValue({
+  name:'education_level_mod',
+  table: 'turma',
+  tableField: 'etapas_mod_ensino_segmento_id',
+  resultField: 'education_level_mod_id',
+  where: {
+    relation: '=',
+    type: 'integer',
+    field: 'etapas_mod_ensino_segmento_id'
+  }
+}).addValue({
+  name:'education_level_short',
+  table: 'turma',
+  tableField: 'etapa_resumida',
+  resultField: 'education_level_short_id',
+  where: {
+    relation: '=',
+    type: 'integer',
+    field: 'etapa_resumida'
+  }
+}).addValue({
+  name: 'adm_dependency_detailed',
+  table: 'turma',
+  tableField: 'dependencia_adm_priv',
+  resultField: 'adm_dependency_detailed_id',
+  where: {
+    relation: '=',
+    type: 'integer',
+    field: 'dependencia_adm_priv'
+  }
+}).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: 'turma'
+  }
+}, '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: 'turma'
+  }
+}, 'filter');
+
+classCountApp.get('/year_range', (req, res, next) => {
+  req.sql.from('escola')
+  .field('MIN(escola.ano_censo)', 'start_year')
+  .field('MAX(escola.ano_censo)', 'end_year');
+  next();
+}, query, response('range'));
+
+classCountApp.get('/years', (req, res, next) => {
+  req.sql.from('escola')
+  .field('DISTINCT escola.ano_censo', 'year');
+  next();
+}, query, response('years'));
+
+classCountApp.get('/adm_dependency', (req, res, next) => {
+  req.result = [];
+  for(let i = 1; i <= 4; ++i) {
+    req.result.push({
+      id: i,
+      name: id2str.admDependency(i)
+    });
+  };
+  next();
+}, response('adm_dependency'));
+
+classCountApp.get('/adm_dependency_detailed', (req, res, next) => {
+  req.result = [];
+  for(let i = 1; i <= 6; ++i) {
+    req.result.push({
+      id: i,
+      name: id2str.admDependencyPriv(i)
+    });
+  };
+  next();
+}, response('adm_dependency_detailed'));
+
+classCountApp.get('/location', (req, res, next) => {
+  req.result = [
+    {id: 1, name: 'Urbana'},
+    {id: 2, name: 'Rural'}
+  ];
+  next();
+}, response('location'));
+
+classCountApp.get('/rural_location', (req, res, next) => {
+  req.result = [
+    {id: 1, name: "Urbana"},
+    {id: 2, name: "Rural"},
+    {id: 3, name: "Rural - Área de assentamento"},
+    {id: 4, name: "Rural - Terra indígena"},
+    {id: 5, name: "Rural - Área remanescente de quilombos"},
+    {id: 6, name: "Rural - Unidade de uso sustentável"}
+  ];
+  next();
+}, response('rural_location'));
+
+classCountApp.get('/education_level_mod', (req, res, next) => {
+  req.result = [];
+  for(let i = 1; i <= 10; ++i) {
+    req.result.push({
+      id: i,
+      name: id2str.educationLevelMod(i)
+    });
+  }
+  req.result.push({
+    id: 99,
+    name: id2str.educationLevelMod(99)
+  });
+  next();
+}, response('education_level_mod'));
+
+classCountApp.get('/education_level_short', (req, res, next) => {
+  req.result = [];
+  for(let i = 1; i <= 7; ++i) {
+    req.result.push({
+      id: i,
+      name: id2str.educationLevelShort(i)
+    });
+  }
+  req.result.push({
+    id: 99,
+    name: id2str.educationLevelShort(99)
+  });
+  next();
+}, response('education_level_short'));
+
+classCountApp.get('/source', (req, res, next) => {
+  req.sql.from('fonte')
+  .field('fonte', 'source')
+  .where('tabela = \'turma\'');
+  next();
+}, query, response('source'));
+
+function mediaCalc(response) {
+  let obj = [];
+  response.forEach((result) => {
+    let newObj = {};
+    let keys = Object.keys(result);
+    keys.forEach((key) => {
+      if(key !== "total_classes" && key !== "total_enrollment")
+        newObj[key] = result[key]
+    })
+    newObj.total = result.total_enrollment / result.total_classes;
+    console.log("year: " + result.year);
+    console.log("soma: " + result.total_enrollment);
+    console.log("N: " + result.total_classes);
+    obj.push(newObj);
+  });
+  return(obj);
+}
+
+classCountApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
+  if(("education_level_mod" in req.dims) || ("education_level_mod" in req.filter)) {
+    req.sql.field('COUNT(turma.id)', 'total_classes')
+     .field('SUM(turma.num_matricula)', 'total_enrollment')
+     .field("'Brasil'", 'name')
+     .field('turma.ano_censo', 'year')
+     .from('turma')
+     .group('turma.ano_censo')
+     .order('turma.ano_censo')
+     .where('turma.tipo_turma_id = 0 AND turma.etapas_mod_ensino_segmento_id >= 1 AND turma.etapas_mod_ensino_segmento_id <= 10');
+     next();
+  } else {
+    res.status(400);
+    next({
+      status: 400,
+      message: 'Wrong/No filter specified'
+    });
+  }
+}, query, addMissing(rqf), id2str.transform(), (req, res, next) => {
+   const classCount = mediaCalc(req.result);
+   req.result = classCount;
+  next();
+}, response('class_count'));
+
+classCountApp.get('/count', rqf.parse(), rqf.build(), (req, res, next) => {
+  req.sql.field('COUNT(turma.id)', 'total_classes')
+   .field('SUM(turma.num_matricula)', 'total_enrollment')
+   .field("'Brasil'", 'name')
+   .field('turma.ano_censo', 'year')
+   .from('turma')
+   .group('turma.ano_censo')
+   .order('turma.ano_censo')
+   .where('turma.tipo_turma_id = 0 AND turma.etapa_resumida >= 1 AND turma.etapa_resumida <= 7 OR turma.etapa_resumida = 99');
+   next();
+}, query, addMissing(rqf), id2str.transform(), (req, res, next) => {
+  const classCount = mediaCalc(req.result);
+  req.result = classCount;
+  next();
+}, response('class_count'));
+
+module.exports = classCountApp;
-- 
GitLab


From ba5290837920f7490382a9b4278b45edb5c09bba Mon Sep 17 00:00:00 2001
From: Glenda <gpt16@inf.ufpr.br>
Date: Tue, 24 Jul 2018 11:40:46 -0300
Subject: [PATCH 16/38] fix education level short

---
 src/libs/routes/classCount.js | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/src/libs/routes/classCount.js b/src/libs/routes/classCount.js
index 29aa2410..45271880 100644
--- a/src/libs/routes/classCount.js
+++ b/src/libs/routes/classCount.js
@@ -308,9 +308,6 @@ function mediaCalc(response) {
         newObj[key] = result[key]
     })
     newObj.total = result.total_enrollment / result.total_classes;
-    console.log("year: " + result.year);
-    console.log("soma: " + result.total_enrollment);
-    console.log("N: " + result.total_classes);
     obj.push(newObj);
   });
   return(obj);
@@ -348,7 +345,7 @@ classCountApp.get('/count', rqf.parse(), rqf.build(), (req, res, next) => {
    .from('turma')
    .group('turma.ano_censo')
    .order('turma.ano_censo')
-   .where('turma.tipo_turma_id = 0 AND turma.etapa_resumida >= 1 AND turma.etapa_resumida <= 7 OR turma.etapa_resumida = 99');
+   .where('turma.tipo_turma_id = 0 AND ((turma.etapa_resumida >= 1 AND turma.etapa_resumida <= 7) OR turma.etapa_resumida = 99)');
    next();
 }, query, addMissing(rqf), id2str.transform(), (req, res, next) => {
   const classCount = mediaCalc(req.result);
-- 
GitLab


From 48d2e64b00e2fda3ebbedb3ea8717d803eb35d47 Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Wed, 25 Jul 2018 11:45:32 -0300
Subject: [PATCH 17/38] Fix bug in diagnosis and projection routes

---
 CHANGELOG.md                  |  4 ++++
 src/libs/routes/enrollment.js | 10 ++++++++++
 2 files changed, 14 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 33617dd1..c69a6fb8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](http://keepachangelog.com/)
 and this project adheres to [Semantic Versioning](http://semver.org/).
 
+## Unreleased
+### Changed
+- Fix bug in diagnosis and projection routes
+
 ## 1.4.2 - 2018-07-23
 ### Added
 - Added new url's in daily charge amount indicator
diff --git a/src/libs/routes/enrollment.js b/src/libs/routes/enrollment.js
index 839eaba2..869a1d82 100644
--- a/src/libs/routes/enrollment.js
+++ b/src/libs/routes/enrollment.js
@@ -503,6 +503,10 @@ enrollmentApp.get('/diagnosis', rqf.parse(), (req, res, next) => {
     let i = 0;
     while(i < enrollments.length) {
         let enrollment = enrollments[i];
+        if(!educationSchoolYear[enrollment.school_year_id]) {
+            ++i;
+            continue;
+        }
         let educationLevelHash = '' + enrollment.year + educationSchoolYear[enrollment.school_year_id].id;
         let schoolYearHash = '' + enrollment.year + enrollment.school_year_id;
 
@@ -702,12 +706,18 @@ enrollmentApp.get('/projection', rqf.parse(), (req, res, next) => {
         }
     }
 
+    console.log(educationSchoolYear);
+
     let result = [];
     let educationLevelSet = new Set();
     let schoolYearSet = new Set();
     let i = 0;
     while(i < enrollments.length) {
         let enrollment = enrollments[i];
+        if(!educationSchoolYear[enrollment.school_year_id]) {
+            ++i;
+            continue;
+        }
         let educationLevelHash = '' + enrollment.year + educationSchoolYear[enrollment.school_year_id].id;
         let schoolYearHash = '' + enrollment.year + enrollment.school_year_id;
 
-- 
GitLab


From c7f8e39471fe47c2069b180784be569310b3f4fc Mon Sep 17 00:00:00 2001
From: Glenda <gpt16@inf.ufpr.br>
Date: Tue, 7 Aug 2018 11:24:21 -0300
Subject: [PATCH 18/38] classCount: add average of the total year

---
 src/libs/routes/classCount.js | 46 ++++++++++++++++++++++++++++++++---
 1 file changed, 42 insertions(+), 4 deletions(-)

diff --git a/src/libs/routes/classCount.js b/src/libs/routes/classCount.js
index 45271880..225a8f39 100644
--- a/src/libs/routes/classCount.js
+++ b/src/libs/routes/classCount.js
@@ -331,9 +331,28 @@ classCountApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
       message: 'Wrong/No filter specified'
     });
   }
+}, rqf.build(), query, id2str.transform(), (req, res, next) => {
+    req.partial = req.result;
+    req.resetSql();
+    req.sql.field('COUNT(turma.id)', 'total_classes')
+     .field('SUM(turma.num_matricula)', 'total_enrollment')
+     .field("'Brasil'", 'name')
+     .field('turma.ano_censo', 'year')
+     .from('turma')
+     .group('turma.ano_censo')
+     .order('turma.ano_censo')
+     .where('turma.tipo_turma_id = 0 AND turma.etapas_mod_ensino_segmento_id >= 1 AND turma.etapas_mod_ensino_segmento_id <= 10');
+     next();
 }, query, addMissing(rqf), id2str.transform(), (req, res, next) => {
-   const classCount = mediaCalc(req.result);
-   req.result = classCount;
+  const classCount = mediaCalc(req.partial);
+  const yearClassCount = mediaCalc(req.result);
+  req.result = classCount;
+  yearClassCount.forEach((result) => {
+    let obj = {};
+    obj = result;
+    obj.label = "total_year_media";
+    req.result.push(obj);
+  })
   next();
 }, response('class_count'));
 
@@ -345,11 +364,30 @@ classCountApp.get('/count', rqf.parse(), rqf.build(), (req, res, next) => {
    .from('turma')
    .group('turma.ano_censo')
    .order('turma.ano_censo')
-   .where('turma.tipo_turma_id = 0 AND ((turma.etapa_resumida >= 1 AND turma.etapa_resumida <= 7) OR turma.etapa_resumida = 99)');
+   .where('turma.tipo_turma_id = 0 AND turma.dependencia_adm_id <= 3 AND ((turma.etapa_resumida >= 1 AND turma.etapa_resumida <= 7) OR turma.etapa_resumida = 99)');
    next();
+}, rqf.build(), query, id2str.transform(), (req, res, next) => {
+    req.partial = req.result;
+    req.resetSql();
+    req.sql.field('COUNT(turma.id)', 'total_classes')
+     .field('SUM(turma.num_matricula)', 'total_enrollment')
+     .field("'Brasil'", 'name')
+     .field('turma.ano_censo', 'year')
+     .from('turma')
+     .group('turma.ano_censo')
+     .order('turma.ano_censo')
+     .where('turma.tipo_turma_id = 0 AND turma.dependencia_adm_id <= 3 AND ((turma.etapa_resumida >= 1 AND turma.etapa_resumida <= 7) OR turma.etapa_resumida = 99)');
+     next();
 }, query, addMissing(rqf), id2str.transform(), (req, res, next) => {
-  const classCount = mediaCalc(req.result);
+  const classCount = mediaCalc(req.partial);
+  const yearClassCount = mediaCalc(req.result);
   req.result = classCount;
+  yearClassCount.forEach((result) => {
+    let obj = {};
+    obj = result;
+    obj.label = "total_year_media";
+    req.result.push(obj);
+  })
   next();
 }, response('class_count'));
 
-- 
GitLab


From 40603c041087c00bd0baec2313d224c8149b4907 Mon Sep 17 00:00:00 2001
From: Glenda <gpt16@inf.ufpr.br>
Date: Wed, 8 Aug 2018 10:21:30 -0300
Subject: [PATCH 19/38] fix total year media

---
 src/libs/routes/classCount.js | 53 ++++++++++++++++++++++-------------
 1 file changed, 33 insertions(+), 20 deletions(-)

diff --git a/src/libs/routes/classCount.js b/src/libs/routes/classCount.js
index 225a8f39..d415d5a3 100644
--- a/src/libs/routes/classCount.js
+++ b/src/libs/routes/classCount.js
@@ -334,6 +334,8 @@ classCountApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
 }, rqf.build(), query, id2str.transform(), (req, res, next) => {
     req.partial = req.result;
     req.resetSql();
+    req.dims = {};
+    req.filter = {};
     req.sql.field('COUNT(turma.id)', 'total_classes')
      .field('SUM(turma.num_matricula)', 'total_enrollment')
      .field("'Brasil'", 'name')
@@ -366,28 +368,39 @@ classCountApp.get('/count', rqf.parse(), rqf.build(), (req, res, next) => {
    .order('turma.ano_censo')
    .where('turma.tipo_turma_id = 0 AND turma.dependencia_adm_id <= 3 AND ((turma.etapa_resumida >= 1 AND turma.etapa_resumida <= 7) OR turma.etapa_resumida = 99)');
    next();
-}, rqf.build(), query, id2str.transform(), (req, res, next) => {
-    req.partial = req.result;
-    req.resetSql();
-    req.sql.field('COUNT(turma.id)', 'total_classes')
-     .field('SUM(turma.num_matricula)', 'total_enrollment')
-     .field("'Brasil'", 'name')
-     .field('turma.ano_censo', 'year')
-     .from('turma')
-     .group('turma.ano_censo')
-     .order('turma.ano_censo')
-     .where('turma.tipo_turma_id = 0 AND turma.dependencia_adm_id <= 3 AND ((turma.etapa_resumida >= 1 AND turma.etapa_resumida <= 7) OR turma.etapa_resumida = 99)');
+}, query, id2str.transform(), (req, res, next) => {
+      req.partial = [];
+      if(Object.keys(req.dims).length > 0 || Object.keys(req.filter).length > 0) {
+        req.partial = req.result;
+        req.resetSql();
+        req.dims = {};
+        req.filter = {};
+        req.sql.field('COUNT(turma.id)', 'total_classes')
+         .field('SUM(turma.num_matricula)', 'total_enrollment')
+         .field("'Brasil'", 'name')
+         .field('turma.ano_censo', 'year')
+         .from('turma')
+         .group('turma.ano_censo')
+         .order('turma.ano_censo')
+         .where('turma.tipo_turma_id = 0 AND turma.dependencia_adm_id <= 3 AND ((turma.etapa_resumida >= 1 AND turma.etapa_resumida <= 7) OR turma.etapa_resumida = 99)');
+     }
      next();
 }, query, addMissing(rqf), id2str.transform(), (req, res, next) => {
-  const classCount = mediaCalc(req.partial);
-  const yearClassCount = mediaCalc(req.result);
-  req.result = classCount;
-  yearClassCount.forEach((result) => {
-    let obj = {};
-    obj = result;
-    obj.label = "total_year_media";
-    req.result.push(obj);
-  })
+  if(req.partial.length > 0) {
+    const classCount = mediaCalc(req.partial);
+    const yearClassCount = mediaCalc(req.result);
+    req.result = classCount;
+    yearClassCount.forEach((result) => {
+      let obj = {};
+      obj = result;
+      obj.label = "total_year_media";
+      req.result.push(obj);
+    })
+  }
+  else {
+    const classCount = mediaCalc(req.result);
+    req.result = classCount;
+  }
   next();
 }, response('class_count'));
 
-- 
GitLab


From 9ad5925a5d2df0d5a806621c8897e219d92422f6 Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Tue, 14 Aug 2018 10:01:35 -0300
Subject: [PATCH 20/38] Change state dims in enrollment route

---
 src/libs/routes/enrollment.js | 49 ++++++++++++++++++++++++++++++-----
 1 file changed, 42 insertions(+), 7 deletions(-)

diff --git a/src/libs/routes/enrollment.js b/src/libs/routes/enrollment.js
index be8a722d..66268b11 100644
--- a/src/libs/routes/enrollment.js
+++ b/src/libs/routes/enrollment.js
@@ -323,7 +323,22 @@ rqf.addField({
         foreign: 'regiao_id',
         foreignTable: 'matricula'
     }
-}).addValue({
+}).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: 'matricula'
+    }
+}, 'dims').addValueToField({
     name: 'state',
     table: 'estado',
     tableField: 'nome',
@@ -338,7 +353,7 @@ rqf.addField({
         foreign: 'estado_id',
         foreignTable: 'matricula'
     }
-}).addValueToField({
+}, 'filter').addValueToField({
     name: 'city',
     table: 'municipio',
     tableField: ['nome', 'id'],
@@ -515,6 +530,8 @@ enrollmentApp.get('/download', passport.authenticate('bearer', { session: false
 
 enrollmentApp.get('/diagnosis', rqf.parse(), (req, res, next) => {
     req.dims = {};
+    req.dims.state = true;
+    req.dims.city = true;
     req.dims.school_year = true;
     req.dims.location = true;
     req.dims.adm_dependency_detailed = true;
@@ -553,8 +570,8 @@ enrollmentApp.get('/diagnosis', rqf.parse(), (req, res, next) => {
             ++i;
             continue;
         }
-        let educationLevelHash = '' + enrollment.year + educationSchoolYear[enrollment.school_year_id].id;
-        let schoolYearHash = '' + enrollment.year + enrollment.school_year_id;
+        let educationLevelHash = '' + enrollment.year + educationSchoolYear[enrollment.school_year_id].id + enrollment.city_id;
+        let schoolYearHash = '' + enrollment.year + enrollment.school_year_id + enrollment.city_id;
 
         let currentEducation = null;
         // Busca ou cria a etapa de ensino adequada
@@ -574,6 +591,10 @@ enrollmentApp.get('/diagnosis', rqf.parse(), (req, res, next) => {
             let obj = {
                 year: enrollment.year,
                 name: enrollment.name,
+                state_id: enrollment.state_id,
+                state_name: enrollment.state_name,
+                city_id: enrollment.city_id,
+                city_name: enrollment.city_name,
                 education_level_school_year_id: educationSchoolYear[enrollment.school_year_id].id,
                 education_level_school_year_name: educationSchoolYear[enrollment.school_year_id].name,
                 total: 0,
@@ -615,6 +636,10 @@ enrollmentApp.get('/diagnosis', rqf.parse(), (req, res, next) => {
             let obj = {
                 year: enrollment.year,
                 name: enrollment.name,
+                state_id: enrollment.state_id,
+                state_name: enrollment.state_name,
+                city_id: enrollment.city_id,
+                city_name: enrollment.city_name,
                 education_level_school_year_id: enrollment.school_year_id,
                 education_level_school_year_name: enrollment.school_year_name,
                 total: 0,
@@ -722,6 +747,8 @@ enrollmentApp.get('/diagnosis', rqf.parse(), (req, res, next) => {
 
 enrollmentApp.get('/projection', rqf.parse(), (req, res, next) => {
     req.dims = {};
+    req.dims.state = true;
+    req.dims.city = true;
     req.dims.location = true;
     req.dims.school_year = true;
     req.dims.adm_dependency = true;
@@ -764,11 +791,11 @@ enrollmentApp.get('/projection', rqf.parse(), (req, res, next) => {
             ++i;
             continue;
         }
-        let educationLevelHash = '' + enrollment.year + educationSchoolYear[enrollment.school_year_id].id;
-        let schoolYearHash = '' + enrollment.year + enrollment.school_year_id;
+        let educationLevelHash = '' + enrollment.year + educationSchoolYear[enrollment.school_year_id].id + enrollment.city_id;
+        let schoolYearHash = '' + enrollment.year + enrollment.school_year_id + enrollment.city_id;
 
         let currentEducation = null;
-        // Busca ou cria a etada de ensino adequada
+        // Busca ou cria a etapa de ensino adequada
         if(educationLevelSet.has(educationLevelHash)) {
             let j = 0;
             let edu = result[j];
@@ -785,6 +812,10 @@ enrollmentApp.get('/projection', rqf.parse(), (req, res, next) => {
             let obj = {
                 year: enrollment.year,
                 name: enrollment.name,
+                state_id: enrollment.state_id,
+                state_name: enrollment.state_name,
+                city_id: enrollment.city_id,
+                city_name: enrollment.city_name,
                 education_level_school_year_id: educationSchoolYear[enrollment.school_year_id].id,
                 education_level_school_year_name: educationSchoolYear[enrollment.school_year_id].name,
                 urban_day_total: 0,
@@ -814,6 +845,10 @@ enrollmentApp.get('/projection', rqf.parse(), (req, res, next) => {
             let obj = {
                 year: enrollment.year,
                 name: enrollment.name,
+                state_id: enrollment.state_id,
+                state_name: enrollment.state_name,
+                city_id: enrollment.city_id,
+                city_name: enrollment.city_name,
                 education_level_school_year_id: enrollment.school_year_id,
                 education_level_school_year_name: enrollment.school_year_name,
                 urban_day_total: 0,
-- 
GitLab


From 7f6c1746212dc1b6dcdce42a3a3f3f8330dc579b Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Tue, 14 Aug 2018 10:02:24 -0300
Subject: [PATCH 21/38] Update changelog

---
 CHANGELOG.md | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1ed5abe2..9b07f941 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](http://keepachangelog.com/)
 and this project adheres to [Semantic Versioning](http://semver.org/).
 
+## UNRELEASED
+- Dimension state in route enrollment now returns state name and id
+
 ## 1.5.0 - 2018-07-30
 ### Added
 - Add portaMec route
-- 
GitLab


From 3265b4150f50dbca6d41b8de5a1f1461b3fe2429 Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Tue, 14 Aug 2018 10:05:13 -0300
Subject: [PATCH 22/38] Update CHANGELOG

---
 CHANGELOG.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index fe0690db..9597ea65 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](http://keepachangelog.com/)
 and this project adheres to [Semantic Versioning](http://semver.org/).
 
+## 1.6.0 - 2018-08-14
+### Added
+- Add school infrastructure route
+
 ## 1.5.0 - 2018-07-30
 ### Added
 - Add portaMec route
-- 
GitLab


From bea5eaa3e3add0081677edca6873ec59ed15e874 Mon Sep 17 00:00:00 2001
From: Fernando Erd <fce15@inf.ufpr.br>
Date: Tue, 14 Aug 2018 10:39:51 -0300
Subject: [PATCH 23/38] Portal Mec INEP route

---
 src/libs/routes/api.js           |  3 ++
 src/libs/routes/portalMecInep.js | 59 ++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+)
 create mode 100644 src/libs/routes/portalMecInep.js

diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index dbdb0435..8d5aefbd 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -78,6 +78,8 @@ const cub = require(`${libs}/routes/cub`);
 
 const classCount = require(`${libs}/routes/classCount`);
 
+const portalMecInep = require(`${libs}/routes/portalMecInep`);
+
 api.get('/', (req, res) => {
     res.json({ msg: 'SimCAQ API is running' });
 });
@@ -119,5 +121,6 @@ api.use('/cub', cub);
 api.use('/auxiliar', auxiliar);
 api.use('/verify_teacher', verifyTeacher);
 api.use('/class_count', classCount);
+api.use('/poltal_mec_inep', portalMecInep);
 
 module.exports = api;
diff --git a/src/libs/routes/portalMecInep.js b/src/libs/routes/portalMecInep.js
new file mode 100644
index 00000000..9ef8dd93
--- /dev/null
+++ b/src/libs/routes/portalMecInep.js
@@ -0,0 +1,59 @@
+const express = require('express');
+
+const portalMecInepApp = 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 id2str = require(`${libs}/middlewares/id2str`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+const addMissing = require(`${libs}/middlewares/addMissing`);
+
+const config = require(`${libs}/config`);
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
+
+let rqf = new ReqQueryFields();
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'school_cod',
+    table: 'escola',
+    tableField: 'id',
+    resultField: 'school_cod_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        table: 'escola',
+        field: 'id'
+    }
+});
+
+portalMecInepApp.get('/', rqf.parse(), (req, res, next) => {
+
+    req.sql.field('DISTINCT escola.id', 'id')
+    .from('escola')
+    .join('estado', null, 'estado.id=escola.estado_id')
+    .field('estado.nome', 'state_name')
+    .join('municipio', null, 'municipio.id=escola.municipio_id')
+    .field('municipio.nome', 'city_name')
+
+    next();
+
+}, rqf.build(), query, response('portalMec_inep'));
+
+module.exports = portalMecInepApp;
-- 
GitLab


From fca5e0c31e97f1352b15b41a231e9d3ca5465904 Mon Sep 17 00:00:00 2001
From: Fernando Erd <fce15@inf.ufpr.br>
Date: Tue, 14 Aug 2018 10:42:59 -0300
Subject: [PATCH 24/38] Add school_name return

---
 src/libs/routes/portalMecInep.js | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/libs/routes/portalMecInep.js b/src/libs/routes/portalMecInep.js
index 9ef8dd93..980e84bf 100644
--- a/src/libs/routes/portalMecInep.js
+++ b/src/libs/routes/portalMecInep.js
@@ -46,12 +46,14 @@ rqf.addField({
 portalMecInepApp.get('/', rqf.parse(), (req, res, next) => {
 
     req.sql.field('DISTINCT escola.id', 'id')
+    .field('escola.nome_escola', 'school_name')
     .from('escola')
     .join('estado', null, 'estado.id=escola.estado_id')
     .field('estado.nome', 'state_name')
     .join('municipio', null, 'municipio.id=escola.municipio_id')
     .field('municipio.nome', 'city_name')
 
+
     next();
 
 }, rqf.build(), query, response('portalMec_inep'));
-- 
GitLab


From 2de870d36367a55ddc1c61a9855968b39bf707d2 Mon Sep 17 00:00:00 2001
From: Glenda <gpt16@inf.ufpr.br>
Date: Tue, 14 Aug 2018 10:52:21 -0300
Subject: [PATCH 25/38] add portal mec school name route

---
 src/libs/routes/api.js                 |   3 +
 src/libs/routes/portalMecSchoolName.js | 115 +++++++++++++++++++++++++
 2 files changed, 118 insertions(+)
 create mode 100644 src/libs/routes/portalMecSchoolName.js

diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index dbdb0435..4964ed0e 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -78,6 +78,8 @@ const cub = require(`${libs}/routes/cub`);
 
 const classCount = require(`${libs}/routes/classCount`);
 
+const portalMecSchoolName = require(`${libs}/routes/portalMecSchoolName`);
+
 api.get('/', (req, res) => {
     res.json({ msg: 'SimCAQ API is running' });
 });
@@ -119,5 +121,6 @@ api.use('/cub', cub);
 api.use('/auxiliar', auxiliar);
 api.use('/verify_teacher', verifyTeacher);
 api.use('/class_count', classCount);
+api.use('/school_name', portalMecSchoolName);
 
 module.exports = api;
diff --git a/src/libs/routes/portalMecSchoolName.js b/src/libs/routes/portalMecSchoolName.js
new file mode 100644
index 00000000..f1d0aeb4
--- /dev/null
+++ b/src/libs/routes/portalMecSchoolName.js
@@ -0,0 +1,115 @@
+const express = require('express');
+
+const portalMecSchoolName = 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 id2str = require(`${libs}/middlewares/id2str`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+const request = require(`request`);
+
+const config = require(`${libs}/config`);
+
+const passport = require('passport');
+
+const download = require(`${libs}/middlewares/downloadDatabase`);
+
+const addMissing = require(`${libs}/middlewares/addMissing`);
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
+
+let rqf = new ReqQueryFields();
+
+// Return location
+portalMecSchoolName.get('/year_range', cache('15 day'), (req, res, next) => {
+    req.sql.from('escola')
+    .field('MIN(escola.ano_censo)', 'start_year')
+    .field('MAX(escola.ano_censo)', 'end_year');
+    next();
+}, query, response('range'));
+
+portalMecSchoolName.get('/years', cache('15 day'), (req, res, next) => {
+    req.sql.from('escola').
+    field('DISTINCT escola.ano_censo', 'year');
+    next();
+}, query, response('years'));
+
+portalMecSchoolName.get('/source', (req, res, next) => {
+    req.sql.from('fonte')
+    .field('fonte', 'source')
+    .where('tabela = \'escola\'');
+    next();
+}, query, response('source'));
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addValue({
+    name: 'city',
+    table: 'municipio',
+    tableField: 'nome',
+    resultField: 'city_name',
+    where: {
+        relation: 'LIKE',
+        type: 'string',
+        field: 'nome',
+        table: 'municipio'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'state',
+    table: 'estado',
+    tableField: 'sigla',
+    resultField: 'state_name',
+    where: {
+        relation: 'LIKE',
+        type: 'string',
+        field: 'sigla',
+        table: 'estado'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'estado_id',
+        foreignTable: 'escola'
+    }
+});
+
+portalMecSchoolName.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
+  if(("state" in req.filter) && ("city" in req.filter)) {
+    console.log(req.filter);
+    req.sql.from('escola')
+        .field('DISTINCT escola.id')
+        .field('escola.nome_escola', 'name')
+        .join('municipio', null, 'municipio.id=escola.municipio_id')
+        .field('municipio.nome', 'city_name')
+        .join('estado', null, 'estado.id=escola.estado_id')
+        .field('estado.sigla', 'state_name')
+        delete req.filter.state;
+        delete req.filter.city;
+        next();
+  }
+  else {
+    res.status(400);
+    next({
+      status: 400,
+      message: 'Wrong/No filter specified'
+    });
+  }
+}, query, response('school_name'));
+
+module.exports = portalMecSchoolName;
-- 
GitLab


From 07cf75a41138f70f2945bd94b86e9e68c03d9772 Mon Sep 17 00:00:00 2001
From: Glenda <gpt16@inf.ufpr.br>
Date: Tue, 14 Aug 2018 10:57:53 -0300
Subject: [PATCH 26/38] fix name portal mec route

---
 src/libs/routes/api.js                 | 2 +-
 src/libs/routes/portalMecSchoolName.js | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index 5fb447e2..1bcfbf40 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -123,7 +123,7 @@ api.use('/cub', cub);
 api.use('/auxiliar', auxiliar);
 api.use('/verify_teacher', verifyTeacher);
 api.use('/class_count', classCount);
-api.use('/school_name', portalMecSchoolName);
+api.use('/portal_mec_school_name', portalMecSchoolName);
 api.use('/poltal_mec_inep', portalMecInep);
 
 module.exports = api;
diff --git a/src/libs/routes/portalMecSchoolName.js b/src/libs/routes/portalMecSchoolName.js
index f1d0aeb4..7a3a9c74 100644
--- a/src/libs/routes/portalMecSchoolName.js
+++ b/src/libs/routes/portalMecSchoolName.js
@@ -110,6 +110,6 @@ portalMecSchoolName.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
       message: 'Wrong/No filter specified'
     });
   }
-}, query, response('school_name'));
+}, query, response('portalMec_schoolName'));
 
 module.exports = portalMecSchoolName;
-- 
GitLab


From 4e8259b4cf3837759e7b34fac2a845b0a41ee9e4 Mon Sep 17 00:00:00 2001
From: Glenda <gpt16@inf.ufpr.br>
Date: Tue, 14 Aug 2018 12:03:02 -0300
Subject: [PATCH 27/38] school search

---
 src/libs/routes/portalMecSchoolName.js |  7 ++--
 src/libs/routes/school.js              | 50 +++++++++++++++++++++-----
 2 files changed, 44 insertions(+), 13 deletions(-)

diff --git a/src/libs/routes/portalMecSchoolName.js b/src/libs/routes/portalMecSchoolName.js
index 7a3a9c74..4ae56ff0 100644
--- a/src/libs/routes/portalMecSchoolName.js
+++ b/src/libs/routes/portalMecSchoolName.js
@@ -91,16 +91,13 @@ rqf.addField({
 
 portalMecSchoolName.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
   if(("state" in req.filter) && ("city" in req.filter)) {
-    console.log(req.filter);
     req.sql.from('escola')
-        .field('DISTINCT escola.id')
+        .field('escola.id')
         .field('escola.nome_escola', 'name')
         .join('municipio', null, 'municipio.id=escola.municipio_id')
         .field('municipio.nome', 'city_name')
-        .join('estado', null, 'estado.id=escola.estado_id')
+        .join('estado', null, 'estado.id=municipio.estado_id')
         .field('estado.sigla', 'state_name')
-        delete req.filter.state;
-        delete req.filter.city;
         next();
   }
   else {
diff --git a/src/libs/routes/school.js b/src/libs/routes/school.js
index 33b5e1cf..24acede6 100644
--- a/src/libs/routes/school.js
+++ b/src/libs/routes/school.js
@@ -167,6 +167,11 @@ rqf.addField({
     name: 'filter',
     field: false,
     where: true
+
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
 }).addValue({
     name: 'id',
     table: 'escola',
@@ -219,7 +224,42 @@ rqf.addField({
         field: 'ano_censo',
         table: 'escola'
     }
-});
+}).addField({
+    name: 'search',
+    field: false,
+    where: true
+}).addValueToField({
+    name: 'city_name',
+    table: 'municipio',
+    tableField: [ 'nome', 'id' ],
+    resultField: ['city_name', 'city_id' ],
+    where: {
+        relation: 'LIKE',
+        type: 'string',
+        field: 'nome'
+    },
+    join: {
+      primary: 'id',
+      foreign: 'municipio_id',
+      foreignTable: 'escola'
+    }
+}, 'search')
+.addValueToField({
+    name: 'state_name',
+    table: 'estado',
+    tableField: ['nome', 'id' ],
+    resultField: ['state_name', 'state_id' ],
+    where: {
+        relation: 'LIKE',
+        type: 'string',
+        field: 'sigla'
+    },
+    join: {
+      primary: 'id',
+      foreign: 'estado_id',
+      foreignTable: 'escola'
+    }
+}, 'search');
 
 rqfCount.addField({
     name: 'filter',
@@ -464,13 +504,7 @@ rqfCount.addField({
     }
 });
 schoolApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
-    if(typeof req.filter === 'undefined' || Object.keys(req.filter).length === 0) {
-        res.status(400);
-        next({
-            status: 400,
-            message: 'Wrong/No filter specified'
-        });
-    }
+
     req.sql.from('escola')
         .field('escola.id')
         .field('escola.ano_censo', 'year')
-- 
GitLab


From ebd139ac1d176057e9200eb7e78c5bc130f15914 Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Wed, 15 Aug 2018 09:50:31 -0300
Subject: [PATCH 28/38] Add dontGroup parameter in RQF

---
 src/libs/middlewares/reqQueryFields.js | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/libs/middlewares/reqQueryFields.js b/src/libs/middlewares/reqQueryFields.js
index 5b28567f..61f98963 100644
--- a/src/libs/middlewares/reqQueryFields.js
+++ b/src/libs/middlewares/reqQueryFields.js
@@ -240,13 +240,17 @@ class ReqQueryFields {
                         if (Array.isArray(value.resultField)) {
                             value.tableField.forEach((f, i) => {
                                 sql.field(table+'.'+f, value.resultField[i] || f)
-                                    .group(table+'.'+f)
+                                if(!value.dontGroup) {
+                                    sql.group(table+'.'+f)
                                     .order(table+'.'+f);
+                                }
                             })
                         }else{
                             sql.field(table+'.'+value.tableField, value.resultField || value.tableField)
-                                .order(table+'.'+value.tableField)
+                            if(!value.dontGroup) {
+                                sql.order(table+'.'+value.tableField)
                                 .group(table+'.'+value.tableField);
+                            }
                         }
                     }
                     // Se o valor é um campo para ser usado no WHERE
-- 
GitLab


From 4dafbd3e65494ea0e26b6b5ab41c9de0eb1d8c38 Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Wed, 15 Aug 2018 09:51:06 -0300
Subject: [PATCH 29/38] Remove route portalMecSchoolName

---
 src/libs/routes/api.js                 |   3 -
 src/libs/routes/portalMecSchoolName.js | 112 -------------------------
 2 files changed, 115 deletions(-)
 delete mode 100644 src/libs/routes/portalMecSchoolName.js

diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index 1bcfbf40..8d5aefbd 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -78,8 +78,6 @@ const cub = require(`${libs}/routes/cub`);
 
 const classCount = require(`${libs}/routes/classCount`);
 
-const portalMecSchoolName = require(`${libs}/routes/portalMecSchoolName`);
-
 const portalMecInep = require(`${libs}/routes/portalMecInep`);
 
 api.get('/', (req, res) => {
@@ -123,7 +121,6 @@ api.use('/cub', cub);
 api.use('/auxiliar', auxiliar);
 api.use('/verify_teacher', verifyTeacher);
 api.use('/class_count', classCount);
-api.use('/portal_mec_school_name', portalMecSchoolName);
 api.use('/poltal_mec_inep', portalMecInep);
 
 module.exports = api;
diff --git a/src/libs/routes/portalMecSchoolName.js b/src/libs/routes/portalMecSchoolName.js
deleted file mode 100644
index 4ae56ff0..00000000
--- a/src/libs/routes/portalMecSchoolName.js
+++ /dev/null
@@ -1,112 +0,0 @@
-const express = require('express');
-
-const portalMecSchoolName = 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 id2str = require(`${libs}/middlewares/id2str`);
-
-const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
-
-const request = require(`request`);
-
-const config = require(`${libs}/config`);
-
-const passport = require('passport');
-
-const download = require(`${libs}/middlewares/downloadDatabase`);
-
-const addMissing = require(`${libs}/middlewares/addMissing`);
-
-const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
-
-let rqf = new ReqQueryFields();
-
-// Return location
-portalMecSchoolName.get('/year_range', cache('15 day'), (req, res, next) => {
-    req.sql.from('escola')
-    .field('MIN(escola.ano_censo)', 'start_year')
-    .field('MAX(escola.ano_censo)', 'end_year');
-    next();
-}, query, response('range'));
-
-portalMecSchoolName.get('/years', cache('15 day'), (req, res, next) => {
-    req.sql.from('escola').
-    field('DISTINCT escola.ano_censo', 'year');
-    next();
-}, query, response('years'));
-
-portalMecSchoolName.get('/source', (req, res, next) => {
-    req.sql.from('fonte')
-    .field('fonte', 'source')
-    .where('tabela = \'escola\'');
-    next();
-}, query, response('source'));
-
-rqf.addField({
-    name: 'filter',
-    field: false,
-    where: true
-}).addValue({
-    name: 'city',
-    table: 'municipio',
-    tableField: 'nome',
-    resultField: 'city_name',
-    where: {
-        relation: 'LIKE',
-        type: 'string',
-        field: 'nome',
-        table: 'municipio'
-    },
-    join: {
-        primary: 'id',
-        foreign: 'municipio_id',
-        foreignTable: 'escola'
-    }
-}).addValue({
-    name: 'state',
-    table: 'estado',
-    tableField: 'sigla',
-    resultField: 'state_name',
-    where: {
-        relation: 'LIKE',
-        type: 'string',
-        field: 'sigla',
-        table: 'estado'
-    },
-    join: {
-        primary: 'id',
-        foreign: 'estado_id',
-        foreignTable: 'escola'
-    }
-});
-
-portalMecSchoolName.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
-  if(("state" in req.filter) && ("city" in req.filter)) {
-    req.sql.from('escola')
-        .field('escola.id')
-        .field('escola.nome_escola', 'name')
-        .join('municipio', null, 'municipio.id=escola.municipio_id')
-        .field('municipio.nome', 'city_name')
-        .join('estado', null, 'estado.id=municipio.estado_id')
-        .field('estado.sigla', 'state_name')
-        next();
-  }
-  else {
-    res.status(400);
-    next({
-      status: 400,
-      message: 'Wrong/No filter specified'
-    });
-  }
-}, query, response('portalMec_schoolName'));
-
-module.exports = portalMecSchoolName;
-- 
GitLab


From 74670a3c0b6a438bd48dd12a6b4aab5742da8bab Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Wed, 15 Aug 2018 09:51:45 -0300
Subject: [PATCH 30/38] Change school route to use don't group in search

---
 src/libs/routes/school.js | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/src/libs/routes/school.js b/src/libs/routes/school.js
index 24acede6..83069774 100644
--- a/src/libs/routes/school.js
+++ b/src/libs/routes/school.js
@@ -167,11 +167,6 @@ rqf.addField({
     name: 'filter',
     field: false,
     where: true
-
-}).addField({
-    name: 'dims',
-    field: true,
-    where: false
 }).addValue({
     name: 'id',
     table: 'escola',
@@ -226,13 +221,14 @@ rqf.addField({
     }
 }).addField({
     name: 'search',
-    field: false,
+    field: true,
     where: true
 }).addValueToField({
     name: 'city_name',
     table: 'municipio',
-    tableField: [ 'nome', 'id' ],
-    resultField: ['city_name', 'city_id' ],
+    tableField: 'nome',
+    resultField: 'city_name',
+    dontGroup: true,
     where: {
         relation: 'LIKE',
         type: 'string',
@@ -247,8 +243,9 @@ rqf.addField({
 .addValueToField({
     name: 'state_name',
     table: 'estado',
-    tableField: ['nome', 'id' ],
-    resultField: ['state_name', 'state_id' ],
+    tableField: 'nome',
+    resultField: 'state_name',
+    dontGroup: true,
     where: {
         relation: 'LIKE',
         type: 'string',
-- 
GitLab


From 61288b10fac873c882182b9af4fe8ea09fc117c3 Mon Sep 17 00:00:00 2001
From: Fernando Erd <fce15@inf.ufpr.br>
Date: Thu, 16 Aug 2018 10:20:41 -0300
Subject: [PATCH 31/38] Add new filter in enrollment

---
 src/libs/middlewares/id2str.js | 11 ++++++--
 src/libs/routes/enrollment.js  | 47 ++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/src/libs/middlewares/id2str.js b/src/libs/middlewares/id2str.js
index c2fa1fab..0c71b4cc 100644
--- a/src/libs/middlewares/id2str.js
+++ b/src/libs/middlewares/id2str.js
@@ -20,6 +20,7 @@ const stateName = require(`${libs}/convert/stateName`);
 const contractType = require(`${libs}/convert/contractType`);
 const ethnicGroupPnad = require(`${libs}/convert/ethnicGroupPnad`);
 const ageRange = require(`${libs}/convert/ageRange`);
+const ageRangeAll = require(`${libs}/convert/ageRangeAll`);
 const fullAgeRange = require(`${libs}/convert/fullAgeRange`);
 const genderPnad = require(`${libs}/convert/genderPnad`);
 const fifthHouseholdIncome = require(`${libs}/convert/fifthHouseholdIncome`);
@@ -28,6 +29,8 @@ const educationLevelBasic = require(`${libs}/convert/educationLevelBasic`);
 const useTransport = require(`${libs}/convert/booleanVariable`);
 const useTransportPublic = require(`${libs}/convert/booleanVariable`);
 const transportationManager = require(`${libs}/convert/transportationManager`);
+const specialClass = require(`${libs}/convert/booleanVariable`);
+
 
 const ids = {
     gender_id: gender,
@@ -61,13 +64,15 @@ const ids = {
     contract_type_id: contractType,
     ethnic_group_pnad_id: ethnicGroupPnad,
     age_range_id: ageRange,
+    age_range_all_id: ageRangeAll,
     full_age_range_id: fullAgeRange,
     gender_pnad_id: genderPnad,
     fifth_household_income_id: fifthHouseholdIncome,
     extremes_household_income_id: extremesHouseholdIncome,
     use_transport_id: useTransport,
     use_transport_public_id: useTransportPublic,
-    transportation_manager_id: transportationManager
+    transportation_manager_id: transportationManager,
+    special_class_id: specialClass
 };
 
 function transform(removeId=false) {
@@ -130,10 +135,12 @@ module.exports = {
     contractType,
     ethnicGroupPnad,
     ageRange,
+    ageRangeAll,
     fullAgeRange,
     genderPnad,
     fifthHouseholdIncome,
     extremesHouseholdIncome,
     useTransport,
-    transportationManager
+    transportationManager,
+    specialClass
 };
diff --git a/src/libs/routes/enrollment.js b/src/libs/routes/enrollment.js
index 839eaba2..83ef3f9c 100644
--- a/src/libs/routes/enrollment.js
+++ b/src/libs/routes/enrollment.js
@@ -214,6 +214,33 @@ enrollmentApp.get('/integral_time', (req, res, next) => {
     next();
 }, response('integral_time'));
 
+enrollmentApp.get('/special_class', (req, res, next) => {
+    req.result = [
+        {id: null, name: 'Não Declarado'},
+        {id: 0, name: 'Não'},
+        {id: 1, name: 'Sim'}
+    ];
+    next();
+}, response('special_class'));
+
+enrollmentApp.get('/age_range_all', (req, res, next) => {
+    req.result = [
+        {id: 1, name: '0 a 3 anos'},
+        {id: 2, name: '4 a 5 anos'},
+        {id: 3, name: '6 a 10 anos'},
+        {id: 4, name: '11 a 14 anos'},
+        {id: 5, name: '15 a 17 anos'},
+        {id: 6, name: '18 a 24 anos'},
+        {id: 7, name: '25 a 29 anos'},
+        {id: 8, name: '30 a 40 anos'},
+        {id: 9, name: '41 a 50 anos'},
+        {id: 10, name: '51 a 64 anos'},
+        {id: 11, name: 'Mais que 64 anos'}
+    ];
+    next();
+}, response('age_range_all'));
+
+
 rqf.addField({
     name: 'filter',
     field: false,
@@ -452,6 +479,26 @@ rqf.addField({
       type: 'boolean',
       field: 'tempo_integral'
   }
+}).addValue({
+  name:'age_range_all',
+  table: 'matricula',
+  tableField: 'faixa_etaria_31_03',
+  resultField: 'age_range_all_id',
+  where: {
+      relation: '=',
+      type: 'integer',
+      field: 'faixa_etaria_31_03'
+  }
+}).addValue({
+  name:'special_class',
+  table: 'matricula',
+  tableField: 'exclusiva_especial',
+  resultField: 'special_class_id',
+  where: {
+      relation: '=',
+      type: 'boolean',
+      field: 'exclusiva_especial'
+  }
 });
 
 enrollmentApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
-- 
GitLab


From d2a12c0cba98975af5edab800e77fb7771ceaa99 Mon Sep 17 00:00:00 2001
From: Glenda <gpt16@inf.ufpr.br>
Date: Thu, 16 Aug 2018 10:25:26 -0300
Subject: [PATCH 32/38] fix auxiliar route

---
 src/libs/routes/auxiliar.js | 34 ++++++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/src/libs/routes/auxiliar.js b/src/libs/routes/auxiliar.js
index 21e7c5f5..a52ce99d 100644
--- a/src/libs/routes/auxiliar.js
+++ b/src/libs/routes/auxiliar.js
@@ -238,6 +238,36 @@ rqf.addField({
         foreign: 'escola_municipio_id',
         foreignTable: 'docente'
     }
+}, '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: 'docente'
+    }
+}, '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: 'docente'
+    }
 }, 'filter').addValue({
     name: 'location',
     table: 'docente',
@@ -298,7 +328,7 @@ auxiliarApp.get('/', rqf.parse(), (req, res, next) => {
   .from('docente')
   .group('docente.ano_censo')
   .order('docente.ano_censo')
-  .where('(docente.tipo_turma_id <= 3 AND docente.dependencia_adm_id > 1 AND docente.tipo_docente = 2)');
+  .where('(docente.tipo_turma_id <= 3 AND docente.tipo_docente = 2)');
   next();
 }, rqf.build(), query, addMissing(rqf), id2str.transform(), response('auxiliar'));
 
@@ -310,7 +340,7 @@ auxiliarApp.get('/count', rqf.parse(), (req, res, next) => {
   .from('docente')
   .group('docente.ano_censo')
   .order('docente.ano_censo')
-  .where('((docente.tipo_turma_id <= 3) AND (docente.dependencia_adm_id = 2 OR docente.dependencia_adm_id = 3) AND (docente.tipo_docente = 2))');
+  .where('(docente.tipo_turma_id <= 3 AND docente.dependencia_adm_id <= 3 AND docente.tipo_docente = 2)');
   next();
 }, rqf.build(), query, addMissing(rqf), id2str.transform(), response('auxiliar'));
 
-- 
GitLab


From 16fb0ff5b08ab4e59bb19918fcd1e78b73e31255 Mon Sep 17 00:00:00 2001
From: Glenda <gpt16@inf.ufpr.br>
Date: Thu, 16 Aug 2018 10:27:23 -0300
Subject: [PATCH 33/38] update changelog

---
 CHANGELOG.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9597ea65..764149d9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 ## 1.6.0 - 2018-08-14
 ### Added
 - Add school infrastructure route
+### Changed
+- Fix auxiliar indicator
 
 ## 1.5.0 - 2018-07-30
 ### Added
-- 
GitLab


From fdd2701aaa865fd68874aea4bf2259ed0b5ae0e8 Mon Sep 17 00:00:00 2001
From: Fernando Erd <fce15@inf.ufpr.br>
Date: Thu, 16 Aug 2018 10:50:48 -0300
Subject: [PATCH 34/38] Update Changelog

---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 764149d9..b44a1f7c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 ## 1.6.0 - 2018-08-14
 ### Added
 - Add school infrastructure route
+- Add new filters in enrollment route
 ### Changed
 - Fix auxiliar indicator
 
-- 
GitLab


From b6ca6e08bac8f50dcaf1738e78741ff65077255e Mon Sep 17 00:00:00 2001
From: Fernando Erd <fce15@inf.ufpr.br>
Date: Thu, 16 Aug 2018 11:11:20 -0300
Subject: [PATCH 35/38] PortalMecInep route

---
 src/libs/routes/api.js           |  4 +++
 src/libs/routes/portalMecInep.js | 60 ++++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+)
 create mode 100644 src/libs/routes/portalMecInep.js

diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index 49fc2a8d..9806dc85 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -74,6 +74,9 @@ const dailyChargeAmount = require(`${libs}/routes/dailyChargeAmount`);
 
 const cub = require(`${libs}/routes/cub`);
 
+const portalMecInep = require(`${libs}/routes/portalMecInep`);
+
+
 api.get('/', (req, res) => {
     res.json({ msg: 'SimCAQ API is running' });
 });
@@ -113,5 +116,6 @@ api.use('/transport', transport);
 api.use('/cub', cub);
 api.use('/auxiliar', auxiliar);
 api.use('/verify_teacher', verifyTeacher);
+api.use('/poltal_mec_inep', portalMecInep);
 
 module.exports = api;
diff --git a/src/libs/routes/portalMecInep.js b/src/libs/routes/portalMecInep.js
new file mode 100644
index 00000000..0f0eb5d1
--- /dev/null
+++ b/src/libs/routes/portalMecInep.js
@@ -0,0 +1,60 @@
+const express = require('express');
+
+const portalMecInepApp = 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 id2str = require(`${libs}/middlewares/id2str`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+const addMissing = require(`${libs}/middlewares/addMissing`);
+
+const config = require(`${libs}/config`);
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
+
+let rqf = new ReqQueryFields();
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'school_cod',
+    table: 'escola',
+    tableField: 'id',
+    resultField: 'school_cod_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        table: 'escola',
+        field: 'id'
+    }
+});
+
+portalMecInepApp.get('/', rqf.parse(), (req, res, next) => {
+
+    req.sql.field('DISTINCT escola.id', 'id')
+    .field('escola.nome_escola', 'school_name')
+    .from('escola')
+    .join('estado', null, 'estado.id=escola.estado_id')
+    .field('estado.nome', 'state_name')
+    .join('municipio', null, 'municipio.id=escola.municipio_id')
+    .field('municipio.nome', 'city_name')
+
+    next();
+
+}, rqf.build(), query, response('portalMec_inep'));
+
+module.exports = portalMecInepApp;
-- 
GitLab


From 45135ca4aa89041010fcdd18e68ca98d9043b5b5 Mon Sep 17 00:00:00 2001
From: Fernando Erd <fce15@inf.ufpr.br>
Date: Thu, 16 Aug 2018 11:12:59 -0300
Subject: [PATCH 36/38] Update changelog

---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index b44a1f7c..e03ae02d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 ### Added
 - Add school infrastructure route
 - Add new filters in enrollment route
+- Add portal mec inep route
 ### Changed
 - Fix auxiliar indicator
 
-- 
GitLab


From ae0cbf5c54f0ceb740ed539163fd7053a9346d68 Mon Sep 17 00:00:00 2001
From: Fernando Erd <fce15@inf.ufpr.br>
Date: Thu, 16 Aug 2018 11:38:11 -0300
Subject: [PATCH 37/38] Fix url name in portal mec inep route

---
 src/libs/routes/api.js           | 2 +-
 src/libs/routes/portalMecInep.js | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index db8f6eba..9d873484 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -119,6 +119,6 @@ api.use('/transport', transport);
 api.use('/cub', cub);
 api.use('/auxiliar', auxiliar);
 api.use('/verify_teacher', verifyTeacher);
-api.use('/poltal_mec_inep', portalMecInep);
+api.use('/portal_mec_inep', portalMecInep);
 
 module.exports = api;
diff --git a/src/libs/routes/portalMecInep.js b/src/libs/routes/portalMecInep.js
index 0f0eb5d1..2b235891 100644
--- a/src/libs/routes/portalMecInep.js
+++ b/src/libs/routes/portalMecInep.js
@@ -46,7 +46,7 @@ rqf.addField({
 portalMecInepApp.get('/', rqf.parse(), (req, res, next) => {
 
     req.sql.field('DISTINCT escola.id', 'id')
-    .field('escola.nome_escola', 'school_name')
+    .field('escola.nome_escola', 'name')
     .from('escola')
     .join('estado', null, 'estado.id=escola.estado_id')
     .field('estado.nome', 'state_name')
-- 
GitLab


From 1c2550a36c25f5fb1ff5b604ec0c3a8316031c32 Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Fri, 17 Aug 2018 09:49:33 -0300
Subject: [PATCH 38/38] Update CHANGELOG

---
 CHANGELOG.md | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9b07f941..9f8bbd6c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,7 +5,18 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
 and this project adheres to [Semantic Versioning](http://semver.org/).
 
 ## UNRELEASED
+### Added
 - Dimension state in route enrollment now returns state name and id
+- School route now has a search parameter. You can search by city name or state abbreviation
+- Added all age range convertion
+- Added special class and all age range to id2str
+- Added school infratructure route
+- Added INEP route for Portal MEC
+### Changed
+- Add property "don't group" in RQF to dismiss the group by and order by clause
+- Change RQF filters in auxiliar route
+- Fix total classrooms needed bug in classroom count
+- Add special class and all age range to enrollment route
 
 ## 1.5.0 - 2018-07-30
 ### Added
-- 
GitLab