diff --git a/config.json.example b/config.json.example index 20ed3f1c68e5a017dd80e4047a52ff4172e36e5b..1fa157c1e562f3843ef2f44bf60e1793fbf9c1e7 100644 --- a/config.json.example +++ b/config.json.example @@ -34,10 +34,16 @@ } }, "email": { - "port": 25, - "host": "mx.c3sl.ufpr.br", - "secure": false, - "ignoreTLS": true, + "host": "SMTP.office365.com", + "port": 587, + "secureConnection": false, + "auth": { + "user": "dadoseducacionais@ufpr.br", + "pass": "COLOCAR_A_SENHA_AQUI" + }, + "tls": { + "ciphers": "SSLv3" + }, "from": "\"Laboratório de Dados Educacionais\" <dadoseducacionais@ufpr.br>" }, "security": { @@ -80,10 +86,16 @@ } }, "email": { - "port": 25, - "host": "mx.c3sl.ufpr.br", - "secure": false, - "ignoreTLS": true, + "host": "SMTP.office365.com", + "port": 587, + "secureConnection": false, + "auth": { + "user": "dadoseducacionais@ufpr.br", + "pass": "COLOCAR_A_SENHA_AQUI" + }, + "tls": { + "ciphers": "SSLv3" + }, "from": "\"Laboratório de Dados Educacionais\" <dadoseducacionais@ufpr.br>" }, "security": { @@ -126,10 +138,16 @@ } }, "email": { - "port": 25, - "host": "mx.c3sl.ufpr.br", - "secure": false, - "ignoreTLS": true, + "host": "SMTP.office365.com", + "port": 587, + "secureConnection": false, + "auth": { + "user": "dadoseducacionais@ufpr.br", + "pass": "COLOCAR_A_SENHA_AQUI" + }, + "tls": { + "ciphers": "SSLv3" + }, "from": "\"Laboratório de Dados Educacionais\" <dadoseducacionais@ufpr.br>" }, "security": { diff --git a/src/libs/middlewares/email.js b/src/libs/middlewares/email.js index 2065dacb9f63ec248b38382e87ae806589ed8856..4d1d51711566a586fc5d29c0bf8ba7953f7da0f1 100644 --- a/src/libs/middlewares/email.js +++ b/src/libs/middlewares/email.js @@ -7,8 +7,9 @@ const htmlToText = require('nodemailer-html-to-text').htmlToText; let transporter = nodemailer.createTransport({ host: config.email.host, port: config.email.port, - secure: config.email.secure, - ignoreTLS: config.email.ignoreTLS + secureConnection: config.email.secureConnection, + auth: config.email.auth, + tls: config.email.tls, }); transporter.use('compile', htmlToText()); diff --git a/src/libs/routes/classroomCount.js b/src/libs/routes/classroomCount.js index 15a0f7eef1b7c12775d1011daa20dac763f78bc8..458117dbb59a9e10fdedd39dbd86b83dfd1bda70 100644 --- a/src/libs/routes/classroomCount.js +++ b/src/libs/routes/classroomCount.js @@ -515,6 +515,8 @@ classroomCountApp.post('/', rqf.parse(), (req, res, next) => { obj.school_id = classroom.school_id, obj.school_name = classroom.school_name } + if (req.teacherCalc) + obj.percentage_teacher_career = []; obj.locations = [] // Inserimos a localidade no array de locations da sala @@ -530,6 +532,7 @@ classroomCountApp.post('/', rqf.parse(), (req, res, next) => { let currentClassroomObj = null; if( !hashSet.has(hash) ) { // Nunca passou por esse municÃpio/escola if (result[result.length - 1] !== undefined) { // Após mudar de cidade, passamos pela cidade anterior e juntamos o valor to_be_built de localizações com o mesmo id + let last_city = result[result.length - 1] let last_locations = result[result.length - 1].locations for (let i = 0; i < last_locations.length - 1; i++) { if (last_locations[i].location_id === last_locations[i+1].location_id) { @@ -542,7 +545,7 @@ classroomCountApp.post('/', rqf.parse(), (req, res, next) => { last_locations[i].total_classroom_be_built = (last_locations[i].total_classroom_be_built < 0) ? 0 : last_locations[i].total_classroom_be_built; } - if (req.teacherCalc) executeTeacherCalc(last_locations, ti); + if (req.teacherCalc) executeTeacherCalc(last_city, ti); } hashSet.add(hash); result.push(obj); @@ -777,6 +780,7 @@ classroomCountApp.post('/', rqf.parse(), (req, res, next) => { // Tratamento do último resultado, para remover double location, tirar negativo do to_be_built. if (result[result.length - 1] !== undefined) { // Após mudar de cidade, passamos pela cidade anterior e juntamos o valor to_be_built de localizações com o mesmo id + let last_city = result[result.length - 1] let last_locations = result[result.length - 1].locations for (let i = 0; i < last_locations.length - 1; i++) { if (last_locations[i].location_id === last_locations[i+1].location_id) { @@ -789,7 +793,7 @@ classroomCountApp.post('/', rqf.parse(), (req, res, next) => { last_locations[i].total_classroom_be_built = (last_locations[i].total_classroom_be_built < 0) ? 0 : last_locations[i].total_classroom_be_built; } - if (req.teacherCalc) executeTeacherCalc(last_locations, ti); + if (req.teacherCalc) executeTeacherCalc(last_city, ti); } } @@ -804,16 +808,17 @@ classroomCountApp.post('/', rqf.parse(), (req, res, next) => { let city = result[i]; let obj = { year: city.year, - name: city.name + name: city.name, + count: 1 } if(req.dims.state) { obj.state_id = city.state_id; obj.state_name = city.state_name; } - + obj.percentage_teacher_career = [] obj.locations = []; - + let hash = '' + city.year; if(req.dims.state) hash += '' + city.state_id; @@ -824,6 +829,16 @@ classroomCountApp.post('/', rqf.parse(), (req, res, next) => { currentObj = obj; } else { // Está ordenado, podemos pegar o último currentObj = reduction[reduction.length - 1]; + currentObj.count++; + } + + if (currentObj.count == 1) + currentObj.percentage_teacher_career = city.percentage_teacher_career + else { + // Incrementa valores percentuais de cada nivel de carreira no objeto atual + currentObj.percentage_teacher_career.forEach((item, ind, thisArr) => { + thisArr[ind].percentage += city.percentage_teacher_career[ind].percentage + }) } // Fazer "merge" do array locations da cidade com o da agregação @@ -958,6 +973,7 @@ classroomCountApp.post('/', rqf.parse(), (req, res, next) => { ++l; } } + // Reinicia vetor percentage_teacher_career e calcula porcentagens pelos totais currentLocation.total_classroom += cityLocation.total_classroom; currentLocation.total_classroom_be_built += cityLocation.total_classroom_be_built; @@ -969,6 +985,10 @@ classroomCountApp.post('/', rqf.parse(), (req, res, next) => { ++i; } for (let state of reduction){ + state.percentage_teacher_career.forEach((item, ind, thisArr) => { + thisArr[ind].percentage = Number((thisArr[ind].percentage / state.count).toFixed(2)) + }) + delete state.count for (let location of state.locations){ for (let educationLevel of location.education_level){ let total = educationLevel.enrollment.integral_time_total; @@ -982,7 +1002,8 @@ classroomCountApp.post('/', rqf.parse(), (req, res, next) => { req.result = reduction || result; - function executeTeacherCalc(lastLocations, index) { + function executeTeacherCalc(lastCity, index) { + let lastLocations = lastCity.locations let teacherByFormation = []; // Vetor com a porcentagem de professores por formação. let teacherTotal = req.teacher[index].total; @@ -1002,13 +1023,26 @@ classroomCountApp.post('/', rqf.parse(), (req, res, next) => { for (let value of teacherByFormation) { sum += value; } + teacherByFormation[1] += teacherByFormation[0] + teacherByFormation[0] = 0 + let diff = 1 - sum; - // Se for menor/maior que 100 soma/subtrai na P2 + + // Se soma de porcentagens for menor/maior que 100, faz correção if (Math.abs(diff) > 0.0001) { - teacherByFormation[1] += diff; + // Garante que a porcentagem corrigida não ficará negativa + let indDiff = 1; + while (teacherByFormation[indDiff] + diff < 0) indDiff++; + teacherByFormation[indDiff] += diff; } - teacherByFormation[1] += teacherByFormation[0] - teacherByFormation[0] = 0 + + // Cria vetor de porcentagens de carreira dos professores + req.teacherFormation.forEach((formation, i) => { + lastCity.percentage_teacher_career.push({ + formation_level_id: formation.idFormationLevel, + percentage: Number((teacherByFormation[i]*100).toFixed(2)), + }) + }); lastLocations.forEach((location) => { location.education_level.forEach((educationLevel) => { diff --git a/src/libs/routes/disciplines.js b/src/libs/routes/disciplines.js index d43d8d319c5539afd635879e3604deced5bbe112..0d491d79b358589e14c975060a88234d1ed36431 100644 --- a/src/libs/routes/disciplines.js +++ b/src/libs/routes/disciplines.js @@ -460,6 +460,7 @@ disciplinesApp.get('/', rqf.parse(), (req, res, next) => { if ('discipline' in req.dims) { // delete req.filter.discipline; delete req.dims.discipline; + req.tmp_discipline = true; req.sql.field('SUM(n_disc)', 'total') .field('SUM(n_disc_adequada)', 'total_suitable') @@ -630,23 +631,40 @@ disciplinesApp.get('/', rqf.parse(), (req, res, next) => { let disciplinesSuitable = []; req.result.forEach((r) => { - let objNotSuitable = { + + let obj = { + sum_total: 0, + sum_suitable: 0 + } + + Object.keys(r).forEach(k => { + if (k !== 'total' && k !== 'total_suitable') + obj[k] = r[k]; + }) + + if (req.tmp_discipline){ + Object.keys(r).forEach(k => { + if (/^total_suitable/.test(k)) // if k starts with total_suitable + obj.sum_suitable += parseInt(r[k]); + else if (/^total_/.test(k)) + obj.sum_total += parseInt(r[k]); + }) + } else { + delete obj.sum_total; + delete obj.sum_suitable; + } + + let objNotSuitable = Object.assign({}, { total: parseInt(r.total) - parseInt(r.total_suitable), suitable: 0, - discipline_name: 'Formação não adequada' - } + discipline_name: 'Formação não adequada', + }, obj) - let objSuitable = { + let objSuitable = Object.assign({}, { total: parseInt(r.total_suitable), suitable: 1, - discipline_name: 'Formação adequada' - } - Object.keys(r).forEach(k => { - if (k !== 'total' && k !== 'total_suitable') { - objNotSuitable[k] = r[k]; - objSuitable[k] = r[k]; - } - }) + discipline_name: 'Formação adequada', + }, obj) disciplinesNotSuitable.push(objNotSuitable) disciplinesSuitable.push(objSuitable) @@ -658,3 +676,4 @@ disciplinesApp.get('/', rqf.parse(), (req, res, next) => { module.exports = disciplinesApp; +