Skip to content
Snippets Groups Projects
Commit 943702db authored by Vytor Calixto's avatar Vytor Calixto :space_invader:
Browse files

Refactor classroom count code

New requirements not implemented yet
parent fc1f4277
No related branches found
No related tags found
No related merge requests found
Pipeline #
...@@ -127,16 +127,6 @@ rqf.addField({ ...@@ -127,16 +127,6 @@ rqf.addField({
type: 'integer', type: 'integer',
field: 'ano_censo' field: 'ano_censo'
} }
}).addValue({
name: 'period',
table: '@',
tableField: 'turma_turno_id',
resultField: 'period_id',
where: {
relation: '=',
type: 'integer',
field: 'turma_turno_id'
}
}).addValue({ }).addValue({
name: 'school_year', name: 'school_year',
table: '@', table: '@',
...@@ -158,22 +148,34 @@ rqf.addField({ ...@@ -158,22 +148,34 @@ rqf.addField({
field: 'localizacao_id' field: 'localizacao_id'
} }
}).addValue({ }).addValue({
name: 'education_level_short', name: 'period',
table: '@', table: '@',
tableField: 'etapa_resumida', tableField: 'turma_turno_id',
resultField: 'education_level_short_id', resultField: 'period_id',
where: { where: {
relation: '=', relation: '=',
type: 'integer', type: 'integer',
field: 'etapa_resumida' field: 'turma_turno_id'
} }
}); });
classroomCountApp.post('/', rqf.parse(), (req, res, next) => { classroomCountApp.post('/', rqf.parse(), (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);
if(classSize == null || integralTime == null) {
res.statusCode = 400;
return res.json({err: {message: "There was an error processing class_size or integral_time. Check your JSON sintax and be sure you're sending both paramenters."}});
}
req.classSize = classSize;
req.integralTime = integralTime;
req.dims.state = true; req.dims.state = true;
req.dims.city = true; req.dims.city = true;
req.dims.period = true; req.dims.period = true;
req.dims.education_level_short = true; req.dims.school_year = true;
req.dims.location = true; req.dims.location = true;
req.sql.field('COUNT(*)', 'total') req.sql.field('COUNT(*)', 'total')
...@@ -187,6 +189,28 @@ classroomCountApp.post('/', rqf.parse(), (req, res, next) => { ...@@ -187,6 +189,28 @@ classroomCountApp.post('/', rqf.parse(), (req, res, next) => {
next(); next();
}, rqf.build(), query, id2str.transform(), (req, res, next) => { }, rqf.build(), query, id2str.transform(), (req, res, next) => {
req.enrollment = req.result; req.enrollment = req.result;
// Gera a relação etapa de ensino X ano escolar
req.educationSchoolYear = {};
for(let i = 10; i < 80; ++i) {
if(id2str.schoolYear(i) !== id2str.schoolYear(99)) {
let educationLevelId = Math.floor(i/10);
let classSize = req.classSize.find((el) => {return el.id === educationLevelId});
let integralTime = req.integralTime.find((el) => {return el.id === educationLevelId});
let numberStudentClass = (typeof classSize !== 'undefined') ? classSize.numberStudentClass : null;
let offerGoal = (typeof integralTime !== 'undefined') ? integralTime.offerGoal : null;
req.educationSchoolYear[i] = {
id: educationLevelId,
name: id2str.educationLevelShort(educationLevelId),
numberStudentClass,
offerGoal
};
}
}
req.resetSql(); req.resetSql();
next(); next();
}, rqf.parse(), (req, res, next) => { }, rqf.parse(), (req, res, next) => {
...@@ -205,128 +229,173 @@ classroomCountApp.post('/', rqf.parse(), (req, res, next) => { ...@@ -205,128 +229,173 @@ classroomCountApp.post('/', rqf.parse(), (req, res, next) => {
next(); next();
}, rqf.build(), query, id2str.transform(), (req, res, 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);
if(classSize == null || integralTime == null) {
res.statusCode = 400;
return res.json({err: {message: "There was an error processing class_size or integral_time. Check your JSON sintax and be sure you're sending both paramenters."}});
}
req.classroom = req.result; req.classroom = req.result;
let classroom = []; let classroom = [];
// req.result = [{classroom: req.classroom, enrollment: req.enrollment}]; return next();
req.classroom.forEach((c) => { // Cria estrutura de resposta requisitada:
let cityObjects = req.classroom.filter((value) => { let i = 0;
return (c.city_id == value.city_id && c.year == value.year); let j = 0;
}); let result = [];
let hashSet = new Set();
while (i < req.classroom.length) {
let classroom = req.classroom[i];
// Cria hash única para cada cidade, dado um ano
let hash = '' + classroom.year + classroom.city_id;
// Estrutura do objeto do resultado final
let obj = { let obj = {
state_id: c.state_id, year: classroom.year,
state_name: c.state_name, name: classroom.name,
city_id: c.city_id, state_id: classroom.state_id,
city_name: c.city_name, state_name: classroom.state_name,
year: c.year, city_id: classroom.city_id,
city_name: classroom.city_name,
locations: [] locations: []
}; };
cityObjects.forEach((co) => { let currentClassroomObj = null;
obj.locations.push({ if( !hashSet.has(hash) ) {
location_id: co.location_id, hashSet.add(hash);
location_name: co.location_name, result.push(obj);
total_classroom: co.total currentClassroomObj = obj;
}); } else { // Se a hash já existe, já temos a cidade nos resultados. Como está ordenado, é o último valor nos resultados
}); currentClassroomObj = result[result.length - 1];
if(classroom.findIndex((el) => {return (el.city_id === obj.city_id && el.year === obj.year)}) === -1) {
classroom.push(obj);
} }
});
let result = []; // Inserimos a localidade no array de locations da sala
// Para cada resultado let location = {
classroom.forEach((c) => { location_id: classroom.location_id,
let r = c; location_name: classroom.location_name,
// Para cada localização total_classroom: parseInt(classroom.total, 10),
c.locations.forEach((location, index) => { total_classroom_be_built: 0,
function filterEnrollment(e) { education_level: []
return (e.city_id == c.city_id && e.year == c.year && e.location_id == location.location_id); };
currentClassroomObj.locations.push(location);
// Partimos para as etapas de ensino/anos escolares
let enrollmentMatch = true;
j = 0;
let educationLevelSet = new Set();
while(enrollmentMatch && j < req.enrollment.length) {
let enrollment = req.enrollment[j];
if(typeof enrollment === 'undefined') {
enrollmentMatch = false;
continue;
}
if(enrollment.city_id != classroom.city_id) { // Se as cidades não são iguais, já passamos do range
enrollmentMatch = false;
continue;
} }
let fEnrollments = req.enrollment.filter(filterEnrollment); if(enrollment.year != classroom.year || enrollment.location_id != classroom.location_id) { // Se ano ou localização são diferentes, passa para o próximo
let educationLevels = []; ++j;
fEnrollments.forEach((fe) => { continue;
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 ) { // Remove se o período é nulo (não dá pra usar no cálculo)
educationLevels.push(obj); if(enrollment.period_id == null) {
} req.enrollment.splice(j, 1);
}); continue;
}
let education_level = []; // Temos uma matrícula com cidade, ano e localidades certos
// Para cada etapa de ensino // "Consome" a matrícula (remove do vetor de matrículas)
educationLevels.forEach((eduLevel) => { req.enrollment.splice(j, 1);
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); // Cria a etapa de ensino adequada
let enrollmentEducationLevel = req.educationSchoolYear[enrollment.school_year_id];
// Se não há um número de alunos por turna para a etapa de ensino, ignoramos a entrada
if(enrollmentEducationLevel.numberStudentClass == null) continue;
let educationLevel = null;
if(!educationLevelSet.has(enrollmentEducationLevel.id)) {
educationLevelSet.add(enrollmentEducationLevel.id);
educationLevel = {
education_level_short_id: enrollmentEducationLevel.id,
education_level_short_name: enrollmentEducationLevel.name,
enrollment: {
total_enrollment_day: 0,
total_enrollment_night: 0,
full_period_classes: 0,
day_classes: 0,
night_classes: 0,
total_classrooms_needed: 0
}
};
// location.education_level.push(educationLevel);
// Para manter a orde da etapa de ensino
if (location.education_level.length == 0) {
location.education_level.push(educationLevel);
} else {
let k = location.education_level.length - 1;
let el = location.education_level[k];
while (k >= 0) {
if(educationLevel.education_level_short_id < el.education_level_short_id) {
--k;
if(k>=0) el = location.education_level[k];
} else break;
}
k++;
location.education_level.splice(k, 0, educationLevel);
} }
} else {
let k = 0;
let el = location.education_level[k];
while(k < location.education_level.length) {
if(el.education_level_short_id != enrollmentEducationLevel.id) {
++k;
if(k<location.education_level.length) el = location.education_level[k];
} else break;
}
if(k >= location.education_level.length) --k;
educationLevel = location.education_level[k];
}
let fEducationLevel = fEnrollments.filter(filterEducationLevel); // Soma os totais de matrícula da etapa de ensino
educationLevel.enrollment.total_enrollment_day += (enrollment.period_id < 3 && enrollment.period_id != null) ? enrollment.total : 0;
let dayEnrollments = 0; educationLevel.enrollment.total_enrollment_night += (enrollment.period_id == 3) ? enrollment.total : 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;
}) || undefined;
let fullPeriodTime = integralTime.find((el) => {
return el.id === eduLevel.education_level_short_id;
}) || undefined;
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}); // Calcula o número de turmas parcial
// Turmas de período integral
educationLevel.enrollment.full_period_classes = Math.ceil((educationLevel.enrollment.total_enrollment_day * (enrollmentEducationLevel.offerGoal/100)) / enrollmentEducationLevel.numberStudentClass);
if(educationLevelIndex === -1) { // Turmas diurnas
educationLevelIndex = education_level.length; educationLevel.enrollment.day_classes = Math.ceil((educationLevel.enrollment.total_enrollment_day / enrollmentEducationLevel.numberStudentClass) - educationLevel.enrollment.full_period_classes);
education_level.push(eduLevel);
}
education_level[educationLevelIndex].enrollment = obj; // Turmas noturnas
// education_level[educationLevelIndex].enrollments = fEducationLevel; educationLevel.enrollment.night_classes = Math.ceil((educationLevel.enrollment.total_enrollment_night / enrollmentEducationLevel.numberStudentClass));
});
r.locations[index].education_level = education_level; // Total de salas
}); educationLevel.enrollment.total_classrooms_needed = (educationLevel.enrollment.full_period_classes + educationLevel.enrollment.day_classes);
if(educationLevel.enrollment.night_classes > educationLevel.enrollment.day_classes) educationLevel.enrollment.total_classrooms_needed += (educationLevel.enrollment.night_classes - educationLevel.enrollment.day_classes);
}
// Calculamos o total classroom be built para o município usando reduce
location.total_classroom_be_built = location.education_level.reduce((total, atual) => {
return total + atual.enrollment.total_classrooms_needed;
}, 0) - location.total_classroom;
if(location.total_classroom_be_built < 0) location.total_classroom_be_built = 0;
++i;
}
// TODO: agregar por estado e brasil
if(req.query['state']) {
console.log('ESTADO!!!!');
} else if(!req.query['city']) {
console.log('BRASIL!!!');
}
result.push(r);
});
console.log('FEITO');
req.result = result; req.result = result;
next(); next();
}, response('classroom_count')); }, response('classroom_count'));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment