From 9ba6c0287315a5c4d86a16827ac85bb80f3af468 Mon Sep 17 00:00:00 2001 From: Lewis <lgtg20@inf.ufpr.br> Date: Tue, 13 Aug 2024 14:43:28 -0300 Subject: [PATCH 1/2] employees aggregate --- src/libs/convert/educationLevelModDoc.js | 42 +++ src/libs/convert/specialEducationDoc.js | 31 ++ src/libs/middlewares/aggregateData.js | 17 +- src/libs/middlewares/id2str.js | 11 +- src/libs/routes_v1/api.js | 4 + src/libs/routes_v1/employeesAggregate.js | 414 +++++++++++++++++++++++ 6 files changed, 515 insertions(+), 4 deletions(-) create mode 100644 src/libs/convert/educationLevelModDoc.js create mode 100644 src/libs/convert/specialEducationDoc.js create mode 100644 src/libs/routes_v1/employeesAggregate.js diff --git a/src/libs/convert/educationLevelModDoc.js b/src/libs/convert/educationLevelModDoc.js new file mode 100644 index 00000000..2113df92 --- /dev/null +++ b/src/libs/convert/educationLevelModDoc.js @@ -0,0 +1,42 @@ +/* +Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR + +This file is part of simcaq-node. + +simcaq-node is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +simcaq-node is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with simcaq-node. If not, see <https://www.gnu.org/licenses/>. +*/ + +module.exports = function educationLevelModDoc(id) { + switch (id) { + case 1: + return 'Creche'; + case 2: + return 'Pré-Escola'; + case 3: + return 'Ensino Fundamental - anos iniciais'; + case 4: + return 'Ensino Fundamental - anos finais'; + case 5: + return 'Ensino Médio'; + case 6: + return 'Profissional'; + case 7: + return 'EJA - Ensino Fundamental'; + case 8: + return 'EJA - Ensino Médio'; + default: + return 'Não classificada'; + } +}; diff --git a/src/libs/convert/specialEducationDoc.js b/src/libs/convert/specialEducationDoc.js new file mode 100644 index 00000000..7ec9335c --- /dev/null +++ b/src/libs/convert/specialEducationDoc.js @@ -0,0 +1,31 @@ +/* +Copyright (C) 2022 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR + +This file is part of simcaq-node. + +simcaq-node is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +simcaq-node is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with simcaq-node. If not, see <https://www.gnu.org/licenses/>. +*/ + +module.exports = function specialEducationDoc(id) { + switch (id) { + case 1: + return 'Classe Comum'; + case 2: + return 'Classe Especial'; + default: + return 'Não definido'; + } +}; + diff --git a/src/libs/middlewares/aggregateData.js b/src/libs/middlewares/aggregateData.js index 714830df..3ea93de3 100644 --- a/src/libs/middlewares/aggregateData.js +++ b/src/libs/middlewares/aggregateData.js @@ -20,13 +20,26 @@ const convert = { integral_time_agg: 'integralTime', period_agg: 'period', modality_integral_time: 'educationLevelBasic', - special_education: 'specialEducation' + special_education: 'specialEducation', + special_education_doc: 'specialEducationDoc', + education_level_mod_doc: 'educationLevelModDoc' } function aggregateData(req, res, next) { if (req.query.dims) { const newResult = [] - const aggregateFields = ['gender', 'age_range', 'ethnic_group', 'education_level_mod_agg', 'integral_time_agg', 'period_agg', 'modality_integral_time', 'special_education'] + const aggregateFields = [ + 'gender', + 'age_range', + 'ethnic_group', + 'education_level_mod_agg', + 'education_level_mod_doc', + 'integral_time_agg', + 'period_agg', + 'modality_integral_time', + 'special_education', + 'special_education_doc' + ] let id; const fields = req.query.dims.split(','); let currentAggregateField; diff --git a/src/libs/middlewares/id2str.js b/src/libs/middlewares/id2str.js index 1d7b3de4..1971d0a0 100644 --- a/src/libs/middlewares/id2str.js +++ b/src/libs/middlewares/id2str.js @@ -117,6 +117,9 @@ const modalityShift = require(`${libs}/convert/modalityShift`); const incomeRange = require(`${libs}/convert/incomeRange`); const ageRangeAggregate = require(`${libs}/convert/ageRangeAggregate`); const specialEducation = require(`${libs}/convert/specialEducation`); +const specialEducationDoc = require(`${libs}/convert/specialEducationDoc`); +const educationLevelModDoc = require(`${libs}/convert/educationLevelModDoc`); + const ids = { gender_id: gender, @@ -226,7 +229,9 @@ const ids = { metro_code_id: metroCode, modality_shift_id: modalityShift, income_range_id: incomeRange, - special_education: specialEducation + special_education: specialEducation, + special_education_doc: specialEducationDoc, + education_level_mod_doc: educationLevelModDoc }; function transform(removeId=false) { @@ -358,5 +363,7 @@ module.exports = { metroCode, modalityShift, incomeRange, - specialEducation + specialEducation, + specialEducationDoc, + educationLevelModDoc }; diff --git a/src/libs/routes_v1/api.js b/src/libs/routes_v1/api.js index 17af8276..4e1d3e8e 100644 --- a/src/libs/routes_v1/api.js +++ b/src/libs/routes_v1/api.js @@ -145,6 +145,8 @@ const newPnad = require(`${libs}/routes_v1/newPnad`); const enrollmentAggregate = require(`${libs}/routes_v1/enrollmentAggregate`); +const employeesAggregate = require(`${libs}/routes_v1/employeesAggregate`); + const email = require(`${libs}/routes_v1/email`); api.get('/', (req, res) => { @@ -208,6 +210,8 @@ api.use('/message', message); api.use('/course_students', courseStudents); api.use('/new_pnad', newPnad); api.use('/enrollmentAggregate', enrollmentAggregate); +api.use('/employeesAggregate', employeesAggregate); + //Publication api.use('/publication', publication); diff --git a/src/libs/routes_v1/employeesAggregate.js b/src/libs/routes_v1/employeesAggregate.js new file mode 100644 index 00000000..14654df9 --- /dev/null +++ b/src/libs/routes_v1/employeesAggregate.js @@ -0,0 +1,414 @@ +/* +Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR + +This file is part of simcaq-node. + +simcaq-node is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +simcaq-node is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with simcaq-node. If not, see <https://www.gnu.org/licenses/>. +*/ + +const express = require('express'); +const { result } = require('lodash'); + +const employeesAggregateApp = express.Router(); + +const libs = `${process.cwd()}/libs`; + +const log = require(`${libs}/log`)(module); + +const squel = require('squel'); + +const query = require(`${libs}/middlewares/query`).query; + +const response = require(`${libs}/middlewares/response`); + +const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`); + +const aggregateData = require(`${libs}/middlewares/aggregateData`); + +const id2str = require(`${libs}/middlewares/id2str`); + +const config = require(`${libs}/config`); + +const addMissing = require(`${libs}/middlewares/addMissing`); + +const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware; + +employeesAggregateApp.use(cache('15 day')); + +let rqf = new ReqQueryFields(); + +employeesAggregateApp.get('/years', (req, res, next) => { + req.sql.from('escola') + .field('DISTINCT escola.ano_censo', 'year') + .where('escola.ano_censo >= 2021') + next(); +}, query, response('years')); + +employeesAggregateApp.get('/education_level_mod_doc', (req, res, next) => { + req.result = [] + + for (let i = 1; i <= 13; i++) { + req.result.push({ + id: i, name: id2str.educationLevelModDoc(i) + }); + } + next(); +}, response('education_level_mod_doc')); + +employeesAggregateApp.get('/region', (req, res, next) => { + req.result = [] + + for (let i = 0; i <= 5; i++) { + req.result.push({ + id: i, name: id2str.regionCode(i) + }); + } + + next(); +}, response('period_agg')); + +employeesAggregateApp.get('/state', (req, res, next) => { + req.result = [] + for (let i = 11; i < 54; i++) { + if (id2str.stateName(i) !== 'Não declarada') { + req.result.push({ + id: i, name: id2str.stateName(i) + }); + } + } + + next(); +}, response('state')); + +employeesAggregateApp.get('/special_education_doc', (req, res, next) => { + req.result = [] + + for (let i = 1; i <= 2; i++) { + req.result.push({ + id: i, name: id2str.specialEducationDoc(i) + }); + } + + next(); +}, response('special_education_doc')); + + +rqf.addField({ + name: 'filter', + field: false, + where: true +}).addField({ + name: 'dims', + field: true, + where: false +}).addValue({ + name: 'adm_dependency', + table: 'escola', + tableField: 'dependencia_adm_id', + resultField: 'adm_dependency_id', + where: { + relation: '=', + type: 'integer', + field: 'dependencia_adm_id' + } +}).addValue({ + name: 'adm_dependency_detailed', + table: 'escola', + tableField: 'dependencia_adm_priv', + resultField: 'adm_dependency_detailed_id', + where: { + relation: '=', + type: 'integer', + field: 'dependencia_adm_priv' + } +}).addValue({ + name: 'education_level_mod', + table: 'escola', + tableField: 'etapas_mod_ensino_segmento_id', + resultField: 'education_level_mod_id', + where: { + relation: '=', + type: 'integer', + field: 'etapas_mod_ensino_segmento_id' + } +}).addValue({ + name:'integral_time', + table: 'escola', + tableField: 'tempo_integral', + resultField: 'integral_time_id', + where: { + relation: '=', + type: 'integer', + field: 'tempo_integral' + } + }).addValue({ + name: 'education_level_short', + table: 'escola', + tableField: 'etapa_resumida', + resultField: 'education_level_short_id', + where: { + relation: '=', + type: 'integer', + field: 'etapa_resumida' + } +}).addValue({ + name: 'region', + table: 'regiao', + tableField: ['nome', 'id'], + resultField: ['region_name', 'region_id'], + where: { + relation: '=', + type: 'integer', + field: 'id' + }, + join: { + primary: 'id', + foreign: 'regiao_id', + foreignTable: 'escola' + } +}).addValue({ + name: 'mesoregion', + table: 'municipio', + tableField: ['nome_mesorregiao', 'mesorregiao_id'], + resultField: ['mesoregion_name', 'mesoregion_id'], + where: { + relation: '=', + type: 'integer', + field: 'mesorregiao_id', + table: 'municipio' + }, + join: { + primary: 'id', + foreign: 'municipio_id', + foreignTable: 'escola' + } +}).addValue({ + name: 'microregion', + table: 'municipio', + tableField: ['nome_microrregiao', 'microrregiao_id'], + resultField: ['microregion_name', 'microregion_id'], + where: { + relation: '=', + type: 'integer', + field: 'microrregiao_id', + table: 'municipio' + }, + join: { + primary: 'id', + foreign: 'municipio_id', + foreignTable: 'escola' + } +}).addValue({ + name: 'min_year', + table: 'escola', + tableField: 'ano_censo', + resultField: 'year', + where: { + relation: '>=', + type: 'integer', + field: 'ano_censo', + }, +}).addValue({ + name: 'max_year', + table: 'escola', + tableField: 'ano_censo', + resultField: 'year', + where: { + relation: '<=', + type: 'integer', + field: 'ano_censo', + }, +}).addValueToField({ + name: 'state', + table: 'estado', + tableField: ['nome', 'id'], + resultField: ['state_name', 'state_id'], + where: { + relation: '=', + type: 'integer', + field: 'id' + }, + join: { + primary: 'id', + foreign: 'estado_id', + foreignTable: 'escola' + } +}, 'dims').addValueToField({ + name: 'state', + table: 'estado', + tableField: 'nome', + resultField: 'state_name', + where: { + relation: '=', + type: 'integer', + field: 'id' + }, + join: { + primary: 'id', + foreign: 'estado_id', + foreignTable: 'escola' + } +}, 'filter').addValueToField({ + name: 'city', + table: 'municipio', + tableField: ['nome', 'id'], + resultField: ['city_name', 'city_id'], + where: { + relation: '=', + type: 'integer', + field: 'id' + }, + join: { + primary: 'id', + foreign: 'municipio_id', + foreignTable: 'escola' + } +}, 'dims').addValueToField({ + name: 'city', + table: 'municipio', + tableField: 'nome', + resultField: 'city_name', + where: { + relation: '=', + type: 'integer', + field: 'id' + }, + join: { + primary: 'id', + foreign: 'municipio_id', + foreignTable: 'escola' + } +}, 'filter').addValueToField({ + name: 'school', + table: 'escola', + tableField: ['nome_escola', 'id'], + resultField: ['school_name', 'school_id'], + where: { + relation: '=', + type: 'integer', + field: 'id' + }, + join: { + primary: ['id', 'ano_censo'], + foreign: ['escola_id', 'ano_censo'], + foreignTable: 'escola' + } +}, 'dims').addValueToField({ + name: 'locale_id', + table: 'escola', + tableField: 'localizacao_id', + resultField: 'locale_id', + where: { + relation: '=', + type: 'integer', + field: 'localizacao_id' + } +}, 'dims').addValueToField({ + name: 'school_id', + table: 'escola', + tableField: 'id', + resultField: 'school_id', + where: { + relation: '=', + type: 'integer', + field: 'id' + }, + join: { + primary: ['id', 'ano_censo'], + foreign: ['escola_id', 'ano_censo'], + foreignTable: 'escola' + } +}, 'dims').addValueToField({ + name: 'school', + table: 'escola', + tableField: 'nome_escola', + resultField: 'school_name', + where: { + relation: '=', + type: 'integer', + field: 'id' + }, + join: { + primary: ['id', 'ano_censo'], + foreign: ['escola_id', 'ano_censo'], + foreignTable: 'escola' + } +}, 'filter').addValue({ + name: 'location', + table: 'escola', + tableField: 'localizacao_id', + resultField: 'location_id', + where: { + relation: '=', + type: 'integer', + field: 'localizacao_id' + } +}).addValue({ + name: 'diff_location', + table: 'escola', + tableField: 'localizacao_diferenciada_par', + resultField: 'diff_location_id', + where: { + relation: '=', + type: 'integer', + field: 'localizacao_diferenciada_par' + } +}); + +// Return all cities +employeesAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => { + + if (req.query.filter && !req.query.filter.includes('school')) + return; + + if (req.query.filter == undefined) + return; + + if (req.query.dims && req.query.dims.includes('education_level_mod_doc')) { + req.sql.from('escola') + .field('SUM(escola.qt_doc_inf_cre)', 'total_cre') + .field('SUM(escola.qt_doc_inf_pre)', 'total_pre') + .field('SUM(escola.qt_doc_fund_ai)', 'total_fund_ai') + .field('SUM(escola.qt_doc_fund_af)', 'total_fund_af') + .field('SUM(escola.qt_doc_med)', 'total_med') + .field('SUM(escola.qt_doc_prof)', 'total_prof') + .field('SUM(escola.qt_doc_eja_fund)', 'total_eja_fund') + .field('SUM(escola.qt_doc_eja_med)', 'total_eja_med') + .field('escola.ano_censo', 'year') + .group('escola.ano_censo') + .order('escola.ano_censo') + .where('escola.situacao_funcionamento_pareada = 1 and (escola.ensino_regular = 1 or escola.ensino_eja = 1 or escola.educacao_profissional = 1)'); + } + else if (req.query.dims && req.query.dims.includes('special_education_doc')) { + req.sql.from('escola') + .field('SUM(escola.qt_doc_esp_cc)', 'total_esp_cc') + .field('SUM(escola.qt_doc_esp_ce)', 'total_esp_ce') + .field('escola.ano_censo', 'year') + .group('escola.ano_censo') + .order('escola.ano_censo') + .where('escola.situacao_funcionamento_pareada = 1 and (escola.ensino_regular = 1 or escola.ensino_eja = 1 or escola.educacao_profissional = 1)'); + } + else { + req.sql.from('escola') + .field('SUM(escola.qt_doc_bas)', 'total') + .field('escola.ano_censo', 'year') + .group('escola.ano_censo') + .order('escola.ano_censo') + .where('escola.situacao_funcionamento_pareada = 1 and (escola.ensino_regular = 1 or escola.ensino_eja = 1 or escola.educacao_profissional = 1)'); + } + next(); +}, query, aggregateData, id2str.transform(false), response('enrollment_aggregate')); + +module.exports = employeesAggregateApp; -- GitLab From 113dd143fcbf0e1648a5861284dde7d25dae90d6 Mon Sep 17 00:00:00 2001 From: Lewis <lgtg20@inf.ufpr.br> Date: Wed, 14 Aug 2024 12:46:53 -0300 Subject: [PATCH 2/2] Working --- src/libs/routes_v1/employeesAggregate.js | 108 ++--------------------- 1 file changed, 5 insertions(+), 103 deletions(-) diff --git a/src/libs/routes_v1/employeesAggregate.js b/src/libs/routes_v1/employeesAggregate.js index 14654df9..ab5102ce 100644 --- a/src/libs/routes_v1/employeesAggregate.js +++ b/src/libs/routes_v1/employeesAggregate.js @@ -59,7 +59,7 @@ employeesAggregateApp.get('/years', (req, res, next) => { employeesAggregateApp.get('/education_level_mod_doc', (req, res, next) => { req.result = [] - for (let i = 1; i <= 13; i++) { + for (let i = 1; i <= 8; i++) { req.result.push({ id: i, name: id2str.educationLevelModDoc(i) }); @@ -67,31 +67,6 @@ employeesAggregateApp.get('/education_level_mod_doc', (req, res, next) => { next(); }, response('education_level_mod_doc')); -employeesAggregateApp.get('/region', (req, res, next) => { - req.result = [] - - for (let i = 0; i <= 5; i++) { - req.result.push({ - id: i, name: id2str.regionCode(i) - }); - } - - next(); -}, response('period_agg')); - -employeesAggregateApp.get('/state', (req, res, next) => { - req.result = [] - for (let i = 11; i < 54; i++) { - if (id2str.stateName(i) !== 'Não declarada') { - req.result.push({ - id: i, name: id2str.stateName(i) - }); - } - } - - next(); -}, response('state')); - employeesAggregateApp.get('/special_education_doc', (req, res, next) => { req.result = [] @@ -113,56 +88,6 @@ rqf.addField({ name: 'dims', field: true, where: false -}).addValue({ - name: 'adm_dependency', - table: 'escola', - tableField: 'dependencia_adm_id', - resultField: 'adm_dependency_id', - where: { - relation: '=', - type: 'integer', - field: 'dependencia_adm_id' - } -}).addValue({ - name: 'adm_dependency_detailed', - table: 'escola', - tableField: 'dependencia_adm_priv', - resultField: 'adm_dependency_detailed_id', - where: { - relation: '=', - type: 'integer', - field: 'dependencia_adm_priv' - } -}).addValue({ - name: 'education_level_mod', - table: 'escola', - tableField: 'etapas_mod_ensino_segmento_id', - resultField: 'education_level_mod_id', - where: { - relation: '=', - type: 'integer', - field: 'etapas_mod_ensino_segmento_id' - } -}).addValue({ - name:'integral_time', - table: 'escola', - tableField: 'tempo_integral', - resultField: 'integral_time_id', - where: { - relation: '=', - type: 'integer', - field: 'tempo_integral' - } - }).addValue({ - name: 'education_level_short', - table: 'escola', - tableField: 'etapa_resumida', - resultField: 'education_level_short_id', - where: { - relation: '=', - type: 'integer', - field: 'etapa_resumida' - } }).addValue({ name: 'region', table: 'regiao', @@ -345,36 +270,13 @@ rqf.addField({ foreign: ['escola_id', 'ano_censo'], foreignTable: 'escola' } -}, 'filter').addValue({ - name: 'location', - table: 'escola', - tableField: 'localizacao_id', - resultField: 'location_id', - where: { - relation: '=', - type: 'integer', - field: 'localizacao_id' - } -}).addValue({ - name: 'diff_location', - table: 'escola', - tableField: 'localizacao_diferenciada_par', - resultField: 'diff_location_id', - where: { - relation: '=', - type: 'integer', - field: 'localizacao_diferenciada_par' - } -}); +}, 'filter'); // Return all cities employeesAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => { - if (req.query.filter && !req.query.filter.includes('school')) - return; - - if (req.query.filter == undefined) - return; + if ((req.query.filter && !req.query.filter.includes('school')) || req.query.filter == undefined) + throw 'Filtro escola deve ser selecionado.'; if (req.query.dims && req.query.dims.includes('education_level_mod_doc')) { req.sql.from('escola') @@ -409,6 +311,6 @@ employeesAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => { .where('escola.situacao_funcionamento_pareada = 1 and (escola.ensino_regular = 1 or escola.ensino_eja = 1 or escola.educacao_profissional = 1)'); } next(); -}, query, aggregateData, id2str.transform(false), response('enrollment_aggregate')); +}, query, aggregateData, id2str.transform(false), response('employees_aggregate')); module.exports = employeesAggregateApp; -- GitLab