diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js index be86d04106e232beb341a1385a408754cb3f2a89..e774e090192dd6c122bf3f2c28ba5b155823d1f5 100644 --- a/src/libs/routes/api.js +++ b/src/libs/routes/api.js @@ -60,7 +60,11 @@ const distributionFactor = require(`${libs}/routes/distributionFactor`); const siope = require(`${libs}/routes/siope`); +<<<<<<< HEAD const outOfSchool = require(`${libs}/routes/outOfSchool`); +======= +const classroomCount = require(`${libs}/routes/classroomCount`); +>>>>>>> classroom_count api.get('/', (req, res) => { res.json({ msg: 'SimCAQ API is running' }); @@ -95,5 +99,6 @@ api.use('/infrastructure', infrastructure); api.use('/distribution_factor', distributionFactor); api.use('/siope', siope); api.use('/out_of_school', outOfSchool); +api.use('/classroom_count', classroomCount); module.exports = api; diff --git a/src/libs/routes/classroom.js b/src/libs/routes/classroom.js index 246e3d9bc7ae1a54c54a3afcc1104e0190107a13..2a8ee3913344bd78c5ac43545c5ac7597be7a1ec 100644 --- a/src/libs/routes/classroom.js +++ b/src/libs/routes/classroom.js @@ -1,4 +1,4 @@ - const express = require('express'); +const express = require('express'); const classroomApp = express.Router(); diff --git a/src/libs/routes/classroomCount.js b/src/libs/routes/classroomCount.js new file mode 100644 index 0000000000000000000000000000000000000000..ba1b3ccd9662913b65861558f59e94a0ae366165 --- /dev/null +++ b/src/libs/routes/classroomCount.js @@ -0,0 +1,328 @@ +const express = require('express'); + +const classroomCountApp = 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', + resultField: 'city_name', + where: { + relation: '=', + type: 'integer', + field: 'municipio_id', + table: '@' + }, + join: { + primary: 'id', + foreign: 'municipio_id', + foreignTable: '@' + } +}, '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: '@' + } +}, 'dims').addValueToField({ + name: 'state', + table: 'estado', + tableField: 'nome', + resultField: 'state_name', + where: { + relation: '=', + type: 'integer', + field: 'estado_id', + table: '@' + }, + join: { + primary: 'id', + foreign: 'estado_id', + foreignTable: '@' + } +}, 'filter').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: '@' + } +}, 'dims').addValue({ + name: 'region', + table: 'regiao', + tableField: 'nome', + resultField: 'region_name', + where: { + relation: '=', + type: 'integer', + field: 'id' + }, + join: { + primary: 'id', + foreign: 'regiao_id', + foreignTable: '@' + } +}).addValue({ + name: 'min_year', + table: '@', + tableField: 'ano_censo', + resultField: 'year', + where: { + relation: '>=', + type: 'integer', + field: 'ano_censo' + } +}).addValue({ + name: 'max_year', + table: '@', + tableField: 'ano_censo', + resultField: 'year', + where: { + relation: '<=', + type: 'integer', + field: 'ano_censo' + } +}).addValue({ + name: 'period', + table: '@', + tableField: 'turma_turno_id', + resultField: 'period_id', + where: { + relation: '=', + type: 'integer', + field: 'turma_turno_id' + } +}).addValue({ + name: 'school_year', + table: '@', + tableField: 'serie_ano_id', + resultField: 'school_year_id', + where: { + relation: '=', + type: 'integer', + field: 'serie_ano_id' + } +}).addValue({ + name: 'location', + table: '@', + tableField: 'localizacao_id', + resultField: 'location_id', + where: { + relation: '=', + type: 'integer', + field: 'localizacao_id' + } +}).addValue({ + name: 'education_level_short', + table: '@', + tableField: 'etapa_resumida', + resultField: 'education_level_short_id', + where: { + relation: '=', + type: 'integer', + field: 'etapa_resumida' + } +}); + +classroomCountApp.post('/', rqf.parse(), (req, res, next) => { + req.dims.state = true; + req.dims.city = true; + req.dims.period = true; + req.dims.education_level_short = true; + req.dims.location = true; + + req.sql.field('COUNT(*)', 'total') + .field("'Brasil'", 'name') + .field('matricula.ano_censo', 'year') + .from('matricula') + .group('matricula.ano_censo') + .order('matricula.ano_censo') + .where('matricula.tipo<=3'); + + next(); +}, rqf.build(), query, id2str.transform(), (req, res, next) => { + req.enrollment = req.result; + req.resetSql(); + next(); +}, rqf.parse(), (req, res, next) => { + + req.dims.state = true; + req.dims.city = true; + req.dims.location = true; + + req.sql.field('SUM(escola.num_salas)', 'total') + .field("'Brasil'", 'name') + .field('escola.ano_censo', 'year') + .from('escola') + .group('escola.ano_censo') + .order('escola.ano_censo') + .where('escola.situacao_de_funcionamento = 1 AND escola.local_func_predio_escolar = 1'); + + next(); +}, rqf.build(), query, id2str.transform(), (req, res, next) => { + let classSize = JSON.parse(req.body.class_size) || null; + let integralTime = JSON.parse(req.body.integral_time) || null; + + // console.log(classSize, integralTime); + + req.classroom = req.result; + let classroom = []; + + req.classroom.forEach((c) => { + let cityObjects = req.classroom.filter((value) => { + return (c.city_id == value.city_id && c.year == value.year); + }); + + let obj = { + state_id: c.state_id, + state_name: c.state_name, + city_id: c.city_id, + city_name: c.city_name, + year: c.year, + locations: [] + }; + + cityObjects.forEach((co) => { + obj.locations.push({ + location_id: co.location_id, + location_name: co.location_name, + total_classroom: co.total + }); + }); + + if(classroom.findIndex((el) => {return (el.city_id === obj.city_id && el.year === obj.year)}) === -1) { + classroom.push(obj); + } + }); + + let result = []; + // Para cada resultado + classroom.forEach((c) => { + let r = c; + // Para cada localização + c.locations.forEach((location, index) => { + function filterEnrollment(e) { + return (e.city_id == c.city_id && e.year == c.year && e.location_id == location.location_id); + } + + let fEnrollments = req.enrollment.filter(filterEnrollment); + let educationLevels = []; + fEnrollments.forEach((fe) => { + let obj = {education_level_short_id: fe.education_level_short_id, education_level_short_name: fe.education_level_short_name}; + + if(educationLevels.findIndex((el) => {return el.education_level_short_id === obj.education_level_short_id}) === -1 ) { + educationLevels.push(obj); + } + }); + + let education_level = []; + // Para cada etapa de ensino + educationLevels.forEach((eduLevel) => { + function filterEducationLevel(e) { + return (e.city_id == c.city_id && e.year == c.year && e.location_id == location.location_id && e.education_level_short_id == eduLevel.education_level_short_id); + } + + let fEducationLevel = fEnrollments.filter(filterEducationLevel); + + let dayEnrollments = 0; + let nightEnrollments = 0; + // Para cada matrÃcula na etapa de ensino + fEducationLevel.forEach((fEduLevel) => { + if(fEduLevel.period_id < 3) dayEnrollments+= fEduLevel.total; + else if(fEduLevel.period_id === 3) nightEnrollments+= fEduLevel.total; + }); + + let size = classSize.find((el) => { + return el.id === eduLevel.education_level_short_id; + }); + let fullPeriodTime = integralTime.find((el) => { + return el.id === eduLevel.education_level_short_id; + }); + + if(typeof size === 'undefined' || typeof fullPeriodTime === 'undefined') return; + size = size.numberStudentClass; + fullPeriodTime = fullPeriodTime.offerGoal; + + let fullPeriodClasses = Math.ceil((dayEnrollments * (fullPeriodTime / 100))/size); + let dayClasses = Math.ceil((dayEnrollments/size) - fullPeriodClasses); + let nightClasses = Math.ceil(nightEnrollments/size); + let totalClassroomsNeeded = fullPeriodClasses + dayClasses; + + if(nightClasses > dayClasses) totalClassroomsNeeded+= (nightClasses - dayClasses); + + let obj = { + total_enrollment_day : dayEnrollments, + total_enrollment_night: nightEnrollments, + full_period_classes: fullPeriodClasses, + day_classes: dayClasses, + night_classes: nightClasses, + total_classrooms_needed: totalClassroomsNeeded + }; + + let educationLevelIndex = education_level.findIndex((el) => {return el.education_level_short_id === eduLevel.education_level_short_id}); + + if(educationLevelIndex === -1) { + educationLevelIndex = education_level.length; + education_level.push(eduLevel); + } + + education_level[educationLevelIndex].enrollment = obj; + // education_level[educationLevelIndex].enrollments = fEducationLevel; + }); + + r.locations[index].education_level = education_level; + }); + + result.push(r); + }); + // console.log('FEITO'); + req.result = result; + next(); +}, response('classroom_count')); + +module.exports = classroomCountApp; \ No newline at end of file