diff --git a/src/libs/convert/admDependencyCursos.js b/src/libs/convert/admDependencyCursos.js new file mode 100644 index 0000000000000000000000000000000000000000..cf9235e3e169cf85b8bc8644db6299f1fb5e4d9b --- /dev/null +++ b/src/libs/convert/admDependencyCursos.js @@ -0,0 +1,41 @@ +/* +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 admDependencyCursos(id) { + switch (id) { + case 1: + return 'Pública Federal'; + case 2: + return 'Pública Estadual'; + case 3: + return 'Pública Municipal'; + case 4: + return 'Privada com fins lucrativos'; + case 5: + return 'Privada sem fins lucrativos'; + case 6: + return 'Confessional'; + case 7: + return 'Especial'; + default: + return 'Não classificada'; + } +}; + diff --git a/src/libs/convert/ageRangeCescu.js b/src/libs/convert/ageRangeCescu.js new file mode 100644 index 0000000000000000000000000000000000000000..60393c1441e0a06548738c655d3307c4bce4e136 --- /dev/null +++ b/src/libs/convert/ageRangeCescu.js @@ -0,0 +1,43 @@ +/* +Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR + +This file is part of simcaq-node. + +simcaq-node is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +simcaq-node is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with simcaq-node. If not, see <https://www.gnu.org/licenses/>. +*/ + +module.exports = function ageRange(id) { + switch (id) { + case 1: + return 'Até 17 anos de idade'; + case 2: + return 'De 18 a 24 anos de idade'; + case 3: + return 'De 25 a 29 anos de idade'; + case 4: + return 'De 30 a 34 anos de idade'; + case 5: + return 'De 35 a 39 anos de idade'; + case 6: + return 'De 40 a 49 anos de idade'; + case 7: + return 'De 50 a 59 anos de idade'; + case 8: + return 'De 60 ou mais anos de idade'; + default: + return 'Não declarada'; + } +}; + diff --git a/src/libs/convert/modalityShiftSuperior.js b/src/libs/convert/modalityShiftSuperior.js new file mode 100644 index 0000000000000000000000000000000000000000..64595063dbb1c50ff95e10ebf60fce5f217cc342 --- /dev/null +++ b/src/libs/convert/modalityShiftSuperior.js @@ -0,0 +1,30 @@ +/* +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 shift(id) { + switch(id) { + case 1: + return 'Diurno'; + case 2: + return 'Noturno'; + default: + return 'Não especificado'; + } +} \ No newline at end of file diff --git a/src/libs/middlewares/aggregateData.js b/src/libs/middlewares/aggregateData.js index 8dbf01d7bbae35fbd18821f850c26ba17c93cbd7..8b35d6e9f4cb3d0302b03d50db7f8d371d86cad5 100644 --- a/src/libs/middlewares/aggregateData.js +++ b/src/libs/middlewares/aggregateData.js @@ -36,6 +36,9 @@ const convert = { total_doc: "totalDoc", education_degree_entity: "educationDegreeEntity", government_agreement: "governmentAgreement", + school_type: "schoolType", + age_range_cescu: "ageRangeCescu", + modality_shift_superior: "modalityShiftSuperior", despesas_alunos: "expenses", receita_potencial: "potentialRevenue", receitas: "revenue", @@ -67,6 +70,9 @@ function aggregateData(req, res, next) { 'post_graduation_entity', 'contract_type_entity', 'education_degree_entity', + 'age_range_cescu', + 'modality_shift_superior', + 'school_type', 'despesas_alunos', 'receitas', 'receita_potencial', diff --git a/src/libs/middlewares/id2str.js b/src/libs/middlewares/id2str.js index f7ccbcc66c9d6fded2cf82d72f172b4d2236946a..db78835c6a92c7694085a2a6d0f427feb2383961 100644 --- a/src/libs/middlewares/id2str.js +++ b/src/libs/middlewares/id2str.js @@ -26,6 +26,7 @@ const period = require(`${libs}/convert/period`); const schoolYear = require(`${libs}/convert/schoolYear`); const admDependency = require(`${libs}/convert/admDependency`); const admDependencyPriv = require(`${libs}/convert/admDependencyPriv`); +const admDependencyCursos = require(`${libs}/convert/admDependencyCursos`) const location = require(`${libs}/convert/location`); const ruralLocation = require(`${libs}/convert/ruralLocation`); const ethnicGroup = require(`${libs}/convert/ethnicGroup`); @@ -45,6 +46,7 @@ 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 ageRangeCescu = require(`${libs}/convert/ageRangeCescu`); const ageStudentCode = require(`${libs}/convert/ageStudentCode`); const fullAgeRange = require(`${libs}/convert/fullAgeRange`); const genderPnad = require(`${libs}/convert/genderPnad`); @@ -128,6 +130,7 @@ const ageRangeEntity = require(`${libs}/convert/ageRangeEntity`); const postGraduationEntity = require(`${libs}/convert/postGraduationEntity`); const totalDoc = require(`${libs}/convert/totalDoc`); const educationDegreeEntity = require(`${libs}/convert/educationDegreeEntity`); +const modalityShiftSuperior = require(`${libs}/convert/modalityShiftSuperior`); const expenses = require(`${libs}/convert/expenses.js`) const potentialRevenue = require(`${libs}/convert/potentialRevenue.js`) const revenue = require(`${libs}/convert/revenue`); @@ -147,6 +150,7 @@ const ids = { adm_dependency_id: admDependency, adm_dependency_detailed_id: admDependencyPriv, adm_dependency_public_id: admDependencyPub, + adm_dependency_cursos_id: admDependencyCursos, location_id: location, rural_location_id: ruralLocation, location_detailed_id: ruralLocation, @@ -172,6 +176,7 @@ const ids = { age_range_all_id: ageRangeAll, age_range_aggregate_id: ageRangeAggregate, full_age_range_id: fullAgeRange, + age_range_cescu_id: ageRangeCescu, gender_pnad_id: genderPnad, fifth_household_income_id: fifthHouseholdIncome, extremes_household_income_id: extremesHouseholdIncome, @@ -253,6 +258,7 @@ const ids = { special_education_entity: specialEducationEntity, total_doc: totalDoc, education_degree_entity: educationDegreeEntity, + modality_shift_superior_id: modalityShiftSuperior, despesas_id: expenses, receita_potencial_id: potentialRevenue, receitas_id: revenue, @@ -311,6 +317,7 @@ module.exports = { educationLevelSchoolYear, admDependency, admDependencyPriv, + admDependencyCursos, location, ruralLocation, ethnicGroup, @@ -326,6 +333,7 @@ module.exports = { ageRange, ageRangeAggregate, ageRangeAll, + ageRangeCescu, ageStudentCode, fullAgeRange, genderPnad, @@ -401,6 +409,7 @@ module.exports = { specialEducationEntity, totalDoc, educationDegreeEntity, + modalityShiftSuperior, expenses, potentialRevenue, revenue, diff --git a/src/libs/routes_v1/api.js b/src/libs/routes_v1/api.js index d49ecac0f15898ed35e7c4ab309d478840023489..ee5b7696457ed290f3cb5503f588dfecc01dcba9 100644 --- a/src/libs/routes_v1/api.js +++ b/src/libs/routes_v1/api.js @@ -181,6 +181,8 @@ const adjustedLiquidFrequency = require(`${libs}/routes_v1/adjustedLiquidFrequen const iliteracyRate = require(`${libs}/routes_v1/iliteracyRate`); +const superiorEnrollmentAggregate = require(`${libs}/routes_v1/superiorEnrollmentAggregate`); + const studentRevenue = require(`${libs}/routes_v1/studentRevenue`); const studentRevenueParser = require(`${libs}/middlewares/studentRevenueParser`); @@ -265,6 +267,7 @@ api.use('/superior_education_conclusion_tax', superiorEducationConclusionTax) api.use('/basic_education_conclusion', basicEducationConclusion); api.use('/adjusted_liquid_frequency', adjustedLiquidFrequency); api.use('/iliteracy_rate', iliteracyRate); +api.use('/superior_enrollment_aggregate', superiorEnrollmentAggregate); api.use('/student_revenue', studentRevenueParser, studentRevenue); api.use('/student_cost', studentRevenueParser, studentCost); api.use('/pop_out_school', populationOutOfSchool); diff --git a/src/libs/routes_v1/superiorEnrollmentAggregate.js b/src/libs/routes_v1/superiorEnrollmentAggregate.js new file mode 100644 index 0000000000000000000000000000000000000000..16b3ef4b6a28effccad15e56eb1f489117d94f71 --- /dev/null +++ b/src/libs/routes_v1/superiorEnrollmentAggregate.js @@ -0,0 +1,454 @@ +/* +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 superiorEnrollmentAggregateApp = express.Router(); + +const libs = `${process.cwd()}/libs`; + +const log = require(`${libs}/log`)(module); + +const squel = require('squel'); + +const multiQuery = require(`${libs}/middlewares/multiQuery`); + +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; + +superiorEnrollmentAggregateApp.use(cache('15 day')); + +let rqf = new ReqQueryFields(); + +superiorEnrollmentAggregateApp.get('/years', (req, res, next) => { + req.sql.from('curso_superior_agregado') + .field('DISTINCT curso_superior_agregado.ano_censo', 'year') + .where('curso_superior_agregado.ano_censo >= 2020') + next(); +}, query, response('years')); + +superiorEnrollmentAggregateApp.get('/universityLocalOffer', (req, res, next) => { + req.sql.from('curso_superior_agregado') + .from('ies_ens_superior') + .field('DISTINCT curso_superior_agregado.cod_ies', 'id') + .field('ies_ens_superior.nome_ies', 'name') + .where('ies_ens_superior.cod_ies = curso_superior_agregado.cod_ies') + .where('curso_superior_agregado.ano_censo >= 2020') + next(); +}, query, response('universityLocalOffer')); + +superiorEnrollmentAggregateApp.get('/state', (req, res, next) => { + req.sql.from('curso_superior_agregado') + .field('DISTINCT curso_superior_agregado.cod_uf', 'id') + .field('curso_superior_agregado.nome_uf', 'name') + .where('curso_superior_agregado.ano_censo >= 2020') + .where('curso_superior_agregado.nome_uf IS NOT NULL') + next(); +}, query, response('state')); + +superiorEnrollmentAggregateApp.get('/city', (req, res, next) => { + req.sql.from('curso_superior_agregado') + .field('DISTINCT curso_superior_agregado.cod_mun', 'id') + .field('curso_superior_agregado.nome_mun', 'name') + .where('curso_superior_agregado.ano_censo >= 2020') + .order('curso_superior_agregado.cod_mun') + next(); +}, query, response('city')); + +superiorEnrollmentAggregateApp.get('/adm_dependency_cursos', (req, res, next) => { + req.result = [] + + for (let i = 1; i <= 5; ++i) { + req.result.push({ + id: i, name: id2str.admDependencyCursos(i) + }); + } + + req.result.push({ + id: 7, name: id2str.admDependencyCursos(7) + }) + next(); +}, response('adm_dependency_cursos')); + +superiorEnrollmentAggregateApp.get('/cine_global', (req, res, next) => { + req.result = []; + for(let i = 0; i <= 10; ++i) { + req.result.push({ + id: i, + name: id2str.cineGeral(i) + }); + }; + next(); +}, response('cine_global')); + +superiorEnrollmentAggregateApp.get('/cine_specific', (req, res, next) => { + req.result = []; + const defaultCase = null; + for(let i = 0; i <= 104; ++i) { + let obj = { + id: i, + name: id2str.cineSpecific(i) + }; + if (obj.name !== id2str.cineSpecific(defaultCase)){ + req.result.push(obj); + } + }; + req.result.push({ + id: defaultCase, + name: id2str.cineSpecific(defaultCase) + }); + next(); +}, response('cine_specific')); + +superiorEnrollmentAggregateApp.get('/cine_detailed', (req, res, next) => { + req.result = []; + const defaultCase = null; + for(let i = 11; i <= 1041; ++i) { + let obj = { + id: i, + name: id2str.cineDetailed(i) + }; + if (obj.name !== id2str.cineDetailed(defaultCase)){ + req.result.push(obj); + } + }; + req.result.push({ + id: defaultCase, + name: id2str.cineDetailed(defaultCase) + }); + next(); +}, response('cine_detailed')); + +superiorEnrollmentAggregateApp.get('/academic_level', (req, res, next) => { + req.result = []; + const defaultCase = null; + for (let i = 0; i <= 3; ++i) { + let obj = { + id: i, + name: id2str.academicLevel(i) + }; + if (obj.name !== id2str.academicLevel(defaultCase)){ + req.result.push(obj); + } + } + req.result.push({ + id: defaultCase, + name: id2str.academicLevel(defaultCase) + }); + next(); +}, response('academic_level')); + +superiorEnrollmentAggregateApp.get('/modality', (req, res, next) => { + req.result = []; + for (let i = 1; i <= 2; ++i) { + req.result.push({ + id: i, + name: id2str.modalityShiftSuperior(i) + }) + } + next(); +}, response('modality')); + +superiorEnrollmentAggregateApp.get('/academic_organization', (req, res, next) => { + req.result = []; + for (let i = 1; i <= 5; ++i) { + req.result.push({ + id: i, + name: id2str.academicOrganization(i) + }) + } + next(); +}, response('academic_organization')); + +superiorEnrollmentAggregateApp.get('/region', (req, res, next) => { + req.result = []; + for (let i = 1; i <= 5; ++i) { + req.result.push({ + id: i, + name: id2str.regionCode(i) + }) + } + next(); +}, response('region')); + +rqf.addField({ + name: 'filter', + field: false, + where: true +}).addField({ + name: 'dims', + field: true, + where: false +}).addValue({ + name: 'min_year', + table: 'curso_superior_agregado', + tableField: 'ano_censo', + resultField: 'year', + where: { + relation: '>=', + type: 'integer', + field: 'ano_censo' + } +}).addValue({ + name: 'max_year', + table: 'curso_superior_agregado', + tableField: 'ano_censo', + resultField: 'year', + where: { + relation: '<=', + type: 'integer', + field: 'ano_censo' + } +}).addValue({ + name: 'adm_dependency_cursos', + table: 'curso_superior_agregado', + tableField: 'tp_categ_adm', + resultField: 'adm_dependency_cursos_id', + where: { + relation: '=', + type: 'integer', + field: 'tp_categ_adm' + } +}).addValue({ + name: 'cine_global', + table: 'curso_superior_agregado', + tableField: ['nome_cine_area_geral', 'cod_cine_area_geral'], + resultField: ['cine_global_name', 'cine_global_id'], + where: { + relation: '=', + type: 'integer', + field: 'cod_cine_area_geral', + }, +}).addValue({ + name: 'cine_specific', + table: 'curso_superior_agregado', + tableField: ['nome_cine_area_esp', 'cod_cine_area_esp'], + resultField: ['cine_specific_name', 'cine_specific_id'], + where: { + relation: '=', + type: 'integer', + field: 'cod_cine_area_esp' + } +}).addValue({ + name: 'cine_detailed', + table: 'curso_superior_agregado', + tableField: ['nome_cine_area_detalhada', 'cod_cine_area_detalhada'], + resultField: ['cine_detailed_name', 'cine_detailed_id'], + where: { + relation: '=', + type: 'integer', + field: 'cod_cine_area_detalhada' + } +}).addValue({ + name: 'graduates', + table: 'curso_superior_agregado', + tableField: 'qtd_concluintes', + resultField: 'graduates_id', + where: { + relation: '=', + type: 'integer', + field: 'qtd_concluintes' + } +}).addValue({ + name: 'disabled_students', + table: 'curso_superior_agregado', + tableField: 'qtd_aluno_deficiente', + resultField: 'disabled_students_id', + where: { + relation: '=', + type: 'integer', + field: 'qtd_aluno_deficiente' + } +}).addValue({ + name: 'academic_level', + table: 'curso_superior_agregado', + tableField: 'tp_grau_acad', + resultField: 'academic_level_id', + where: { + relation: '=', + type: 'integer', + field: 'tp_grau_acad' + } +}).addValue({ + name: 'universityLocalOffer', + table: 'ies_ens_superior', + tableField: ['nome_ies'], + resultField: ['universityLocalOffer_name'], + where: { + relation: '=', + type: 'integer', + field: 'cod_ies' + }, + join: { + primary: ['cod_ies', 'ano_censo'], + foreign: ['cod_ies', 'ano_censo'], + foreignTable: 'curso_superior_agregado' + } +}).addValue({ + name: 'modality', + table: 'curso_superior_agregado', + tableField: 'tp_modal_ens', + resultField: 'modality_id', + where: { + relation: '=', + type: 'integer', + field: 'tp_modal_ens' + } +}).addValue({ + name: 'academic_organization', + table: 'curso_superior_agregado', + tableField: 'tp_org_acad', + resultField: 'academic_organization_id', + where: { + relation: '=', + type: 'integer', + field: 'tp_org_acad' + } +}).addValue({ + name: 'region', + table: 'curso_superior_agregado', + tableField: ['nome_reg', 'cod_reg'], + resultField: ['region_name', 'region_id'], + where: { + relation: '=', + type: 'integer', + field: 'cod_reg' + } +}).addValue({ + name: 'state', + table: 'curso_superior_agregado', + tableField: ['cod_uf'], + resultField: ['state_id'], + where: { + relation: '=', + type: 'integer', + field: 'cod_uf' + } +}).addValue({ + name: 'city', + table: 'curso_superior_agregado', + tableField: ['nome_mun', 'cod_mun'], + resultField: ['city_name', 'city_id'], + where: { + relation: '=', + type: 'integer', + field: 'cod_mun' + } +}) + +function whereCondition(req) { + let where = ""; + const dims = req.query.dims; + + if (dims && dims.includes("city")){ + where += `curso_superior_agregado.nome_mun is not null` + } + + if (dims && dims.includes("region")){ + where += `curso_superior_agregado.nome_reg is not null` + } + + if (dims && dims.includes("state")){ + where += `curso_superior_agregado.cod_uf <> 99` + } + + return where; +} + + +superiorEnrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => { + let where = whereCondition(req); + + req.sql.field('curso_superior_agregado.ano_censo', 'year'); + + if (req.query.dims && req.query.dims.includes("ethnic_group")){ + req.sql.field('sum(qtd_mat_branca)', 'total_branca') + .field('sum(qtd_mat_preta)', 'total_preta') + .field('sum(qtd_mat_parda)', 'total_parda') + .field('sum(qtd_mat_amarela)', 'total_amarela') + .field('sum(qtd_mat_indigena)', 'total_indigena') + .field('sum(qtd_mat_cor_nao_declarada)', 'total_nd'); + } + else if (req.query.dims && req.query.dims.includes("school_type")){ + req.sql.field('sum(qtd_mat_proces_publica)', 'total_publica') + .field('sum(qtd_mat_proces_privada)', 'total_privada') + .field('sum(qtd_mat_proces_nao_informada)', 'total_nao_informada'); + } + else if (req.query.dims && req.query.dims.includes("age_range_cescu")){ + req.sql.field('sum(qtd_mat_0_17)', 'total_0_17') + .field('sum(qtd_mat_18_24)', 'total_18_24') + .field('sum(qtd_mat_25_29)', 'total_25_29') + .field('sum(qtd_mat_30_34)', 'total_30_34') + .field('sum(qtd_mat_35_39)', 'total_35_39') + .field('sum(qtd_mat_40_49)', 'total_40_49') + .field('sum(qtd_mat_50_59)', 'total_50_59') + .field('sum(qtd_mat_60_mais)', 'total_60_mais'); + } + else if (req.query.dims && req.query.dims.includes("gender")){ + req.sql.field('sum(qtd_mat_masc)', 'total_masc') + .field('sum(qtd_mat_fem)', 'total_fem'); + } + else if (req.query.dims && req.query.dims.includes("modality_shift_superior")){ + req.sql.field('sum(qtd_mat_diurno)', 'total_diurno') + .field('sum(qtd_mat_noturno)', 'total_noturno'); + } + else if (req.query.dims && req.query.dims.includes("qtd_graduates_agg")){ + req.sql.field('SUM(curso_superior_agregado.qtd_concluintes)', 'total'); + } + else if (req.query.dims && req.query.dims.includes("disabled_students_agg")){ + req.sql.field('SUM(curso_superior_agregado.qtd_aluno_deficiente)', 'total') + } + else if (req.query.dims && req.query.dims.includes("school_type")){ + req.sql.field('SUM(curso_superior_agregado.qtd_mat_proces_publica)', 'total_publica') + .field('SUM(curso_superior_agregado.qtd_mat_proces_privada)', 'total_privada') + .field('SUM(curso_superior_agregado.qtd_mat_proces_nao_informada)', 'total_nao_informada'); + } + else { + req.sql.field('SUM(qtd_matriculas)', 'total'); + } + + req.sql.from('curso_superior_agregado') + .where('tp_nivel_acad = 1') + .where(`${where}`) + .group('curso_superior_agregado.ano_censo') + .order('curso_superior_agregado.ano_censo'); + + + console.log(req.sql.toString()); + + next(); +}, multiQuery, query, aggregateData, id2str.transform(false), response('superior_enrollment_aggregate')); + +module.exports = superiorEnrollmentAggregateApp;