diff --git a/src/libs/convert/period.js b/src/libs/convert/period.js index d4b97b245fc740333f9e97eb19079648d9665dac..06dbcf588e58ea2739b2e556ceac8a23ba8939d5 100644 --- a/src/libs/convert/period.js +++ b/src/libs/convert/period.js @@ -1,11 +1,11 @@ module.exports = function period(id) { switch(id) { case 1: - return 'Diurno'; + return 'Matutino'; case 2: - return 'Noturno'; + return 'Vespertino'; case 3: - return 'Integral'; + return 'Noturno'; default: return 'Indefinido'; } diff --git a/src/libs/middlewares/reqQueryFields.js b/src/libs/middlewares/reqQueryFields.js index b85e3f0036ff2084cc6efc56e4be7faf5528a60c..8dcf018b0cd7285312dca6e2f257aa8b03375f5b 100644 --- a/src/libs/middlewares/reqQueryFields.js +++ b/src/libs/middlewares/reqQueryFields.js @@ -4,6 +4,26 @@ const log = require(`${libs}/log`)(module); const _ = require('lodash'); +function parseWhereValue(type, value) { + if(type === 'integer') return parseInt(value, 10); + if(type === 'double') return parseFloat(value); + if(type === 'string') return '%'+value+'%'; + if(type === 'boolean') { + if(value === null || typeof value === 'boolean') { + return value; + } + if(typeof value === 'string') { + if(value.toLowerCase() === 'true' || value.toLowerCase() === '1') { + return true; + } + if(value.toLowerCase() === 'null') { + return null; + } + } + return false; + } +} + class ReqQueryFields { constructor(fields = {}, fieldValues = {}) { // Exemplo de requisição: `/api/v1/enrollments?dims=state,region,location` @@ -128,7 +148,8 @@ class ReqQueryFields { if (req.query[queryField]) { // Se há mais de um parametro no campo, eles estão separados por vÃrgula. // Fazemos o split então para separar os valores - const params = req.query[queryField].split(','); + const regex = /,(?=[a-z])/; // Pega as vÃrgulas que não estão nos atributos multivalorados + const params = req.query[queryField].split(regex); // Objeto temporário para guardar os parametros e seus valores. const obj = {}; for (const param of params) { @@ -136,7 +157,15 @@ class ReqQueryFields { // Fazemos o split e temos um array `['state', 41]` const kv = param.split(':'); // Checa se há um valor. Se não tem, definimos como true. - obj[kv[0]] = (typeof kv[1] === 'undefined') ? true : kv[1]; + if ( (typeof kv[1] === 'undefined')) { + obj[kv[0]] = true; + } else { + try { + obj[kv[0]] = JSON.parse(kv[1]); + } catch(err) { + obj[kv[0]] = kv[1]; + } + } // `obj` é agora `{kv[0]: kv[1]}` ou `{kv[0]: true}`. // No exemplo `{'state': 41}` } @@ -177,8 +206,6 @@ class ReqQueryFields { log.debug(field); // `param` aqui é o atributo no objeto `req` (dims, filter, search, ...) let param = req[field.name]; - // log.debug('param'); - // log.debug(param); // Fazemos um foreach nos parametros dentro do atributo Object.keys(param).forEach((k) => { let values = _.merge(this.fieldValues, field.values); @@ -217,6 +244,7 @@ class ReqQueryFields { }) }else{ req.sql.field(value.table+'.'+value.tableField, value.resultField || value.tableField) + .order(value.table+'.'+value.tableField) .group(value.table+'.'+value.tableField); } } @@ -226,19 +254,10 @@ class ReqQueryFields { // Valor do where let whereValue = param[k]; - // Valor sempre vem como string, necessário fazer parse para o banco - if(value.where.type === 'integer') whereValue = parseInt(whereValue, 10); - if(value.where.type === 'double') whereValue = parseFloat(whereValue); - if(value.where.type === 'string') whereValue = '%'+whereValue+'%'; - if(value.where.type === 'boolean') { - if (whereValue.toLowerCase() === 'null') { - whereValue = null; - console.log('Fazendo uma consulta Null'); - } else { - whereValue = (whereValue.toLowerCase() === 'true' || parseInt(whereValue, 10) === 1); - console.log('Fazendo uma consulta True'); - } - } + log.debug('whereValue'); + log.debug(whereValue); + log.debug(`Where value é array? ${Array.isArray(whereValue)}`); + let tbl = value.where.table || value.table; // multiple where, only tested for boolean filds if (Array.isArray(value.tableField)) { @@ -246,18 +265,46 @@ class ReqQueryFields { let whereField = ''; let whereValues = []; value.where.field.forEach((f, i, arr) => { - whereValues.push(whereValue); whereField += (value.where.type === 'string') ? 'LOWER(' + tbl + '.' + value.where.field[i] + ')' : tbl + '.' + value.where.field[i]; whereField += ' ' + value.where.relation + ' ?'; if (i < arr.length - 1) { whereField += ' ' + value.where.condition + ' '; } + + if (Array.isArray(whereValue)) { + let whereString = '('; + for(let i = 0; i < whereValue.length; ++i) { + whereString += whereField; + whereValues.push(parseWhereValue(value.where.type, whereValue[i])); + if(i < whereValue.length-1) { + whereString += ' OR '; + } + } + whereString += ')'; + } else { + whereValues.push(parseWhereValue(value.where.type, whereValue)); + } }); + req.sql.where(whereField, ...whereValues); } else { let whereField = (value.where.type === 'string') ? 'LOWER(' + tbl + '.' + value.where.field + ')' : tbl + '.' + value.where.field; let lower = (value.where.type === 'string') ? ' LOWER(?) ' : ' ? '; - req.sql.where(whereField + ' ' + value.where.relation + lower, whereValue); + if(Array.isArray(whereValue)) { + let whereString = '('; + let arrayWhereValues = []; + for(let i = 0; i < whereValue.length; ++i) { + whereString += whereField + ' ' + value.where.relation + lower; + arrayWhereValues.push(parseWhereValue(value.where.type, whereValue[i])); + if(i < whereValue.length-1) { + whereString += ' OR '; + } + } + whereString += ')'; + req.sql.where(whereString, ...arrayWhereValues); + } else { + req.sql.where(whereField + ' ' + value.where.relation + lower, parseWhereValue(value.where.type, whereValue)); + } } } } diff --git a/src/libs/routes/enrollment.js b/src/libs/routes/enrollment.js index ad14b9b741ea3eb1234fc0e979a46f7b117827fa..c4d13a9820d137e5f101dfc40a1a8220a04d72e2 100644 --- a/src/libs/routes/enrollment.js +++ b/src/libs/routes/enrollment.js @@ -99,6 +99,17 @@ enrollmentApp.get('/period', (req, res, next) => { next(); }, query, response('period')); +// Returns integral-time avaible +enrollmentApp.get('/integral_time', (req, res, next) => { + req.result = [ + {id: null, name: 'Não DisponÃvel'}, + {id: 0, name: 'Não'}, + {id: 1, name: 'Sim'} + ]; + next(); +}, response('integral_time')); + + rqf.addField({ name: 'filter', field: false, @@ -264,7 +275,8 @@ rqf.addField({ resultField: 'ethnic_group_id', where: { relation: '=', - type: 'integer' + type: 'integer', + field: 'cor_raca_id' } }).addValue({ name: 'period', @@ -276,6 +288,16 @@ rqf.addField({ type: 'integer', field: 'turma_turno_id' } +}).addValue({ + name:'integral_time', + table: 'matricula', + tableField: 'tempo_integral', + resultField: 'integral_time_id', + where: { + relation: '=', + type: 'boolean', + field: 'tempo_integral' + } }); enrollmentApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => { diff --git a/src/libs/routes/teacher.js b/src/libs/routes/teacher.js index 5a70c8350b1ee1bc42336eb6f70c409757ad93d4..130bd9fa3b30d793922b5795f2e519062fbd2689 100644 --- a/src/libs/routes/teacher.js +++ b/src/libs/routes/teacher.js @@ -238,7 +238,8 @@ rqf.addField({ resultField: 'ethnic_group_id', where: { relation: '=', - type: 'integer' + type: 'integer', + field: 'cor_raca_id' } }); diff --git a/src/test/enrollment.js b/src/test/enrollment.js index 7d9572ff708165ed7e519be6347c6e3d46feb034..ca4bf0314fc8335147d7b35b20d510e49e772b20 100644 --- a/src/test/enrollment.js +++ b/src/test/enrollment.js @@ -164,6 +164,20 @@ describe('request enrollments', () => { }); }); + it('should list the integral time', (done) => { + chai.request(server) + .get('/api/v1/enrollment/integral_time') + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('result'); + res.body.result.should.be.a('array'); + res.body.result[0].should.have.property('id'); + res.body.result[0].should.have.property('name'); + done(); + }); + }); + it('should list enrollments', (done) => { chai.request(server) .get('/api/v1/enrollment') @@ -237,6 +251,20 @@ describe('request enrollments', () => { }); }); + it('should list enrollments with multivalue filter and single value filter', (done) => { + chai.request(server) + .get('/api/v1/enrollment?filter=region:[1,2],min_year:2015') + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('result'); + res.body.result.should.be.a('array'); + res.body.result[0].should.have.property('name'); + res.body.result[0].should.have.property('total'); + done(); + }); + }); + it('should list enrollments with valid dimensions and filters', (done) => { chai.request(server) .get('/api/v1/enrollment?dims=region,state,school_year,school,gender,period&filter=min_year:2015,max_year:2015,city:4106902') @@ -381,6 +409,20 @@ describe('request enrollments', () => { }); }); + it('should list enrollment with dimension integral_time', (done) => { + chai.request(server) + .get('/api/v1/enrollment?dims=integral_time') + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('result'); + res.body.result.should.be.a('array'); + res.body.result[0].should.have.property('integral_time_name'); + res.body.result[0].should.not.have.property('integral_time_id'); + done(); + }); + }); + it('should list enrollments offer projection', (done) => { chai.request(server) .get('/api/v1/enrollment/offer_projection') diff --git a/src/test/id2str.js b/src/test/id2str.js index abb4bc56fe5210feb97198d091ed4f62081730a2..448de14de859e2e601e14accc737b0d05e25a0f3 100644 --- a/src/test/id2str.js +++ b/src/test/id2str.js @@ -39,7 +39,7 @@ describe('id2str middleware', () => { }); it('should transform a period id', (done) => { - expect(id2str.period(1)).to.deep.equal('Diurno'); + expect(id2str.period(1)).to.deep.equal('Matutino'); done(); }); @@ -56,7 +56,7 @@ describe('id2str middleware', () => { if (error) { throw new Error('Expected not to receive an error'); } req.should.have.property('result'); req.result.should.not.be.undefined; - req.result.should.be.deep.equal([{gender_id: 2, period_id: 3, school_year_id: 11, gender_name: 'Feminino', period_name: 'Integral', school_year_name: 'Creche - Menor de 1 ano'}]); + req.result.should.be.deep.equal([{gender_id: 2, period_id: 3, school_year_id: 11, gender_name: 'Feminino', period_name: 'Noturno', school_year_name: 'Creche - Menor de 1 ano'}]); done(); }); }); @@ -69,7 +69,7 @@ describe('id2str middleware', () => { if (error) { throw new Error('Expected not to receive an error'); } req.should.have.property('result'); req.result.should.not.be.undefined; - req.result.should.be.deep.equal([{gender_name: 'Feminino', period_name: 'Integral', school_year_name: 'Creche - Menor de 1 ano'}]); + req.result.should.be.deep.equal([{gender_name: 'Feminino', period_name: 'Noturno', school_year_name: 'Creche - Menor de 1 ano'}]); done(); }); });