387 lines
13 KiB
JavaScript
387 lines
13 KiB
JavaScript
const _ = require('lodash');
|
|
const {
|
|
HttpStatusError
|
|
} = require('./errors');
|
|
const {
|
|
parse
|
|
} = require('./parser');
|
|
const {
|
|
raw
|
|
} = require('./transforms');
|
|
const Op = require('sequelize').Op;
|
|
|
|
class ModelHandler {
|
|
constructor(model, defaults = {
|
|
limit: 50,
|
|
offset: 0
|
|
}) {
|
|
this.model = model;
|
|
this.defaults = defaults;
|
|
this.custom = null;
|
|
this.name = this.model.getTableName();
|
|
}
|
|
|
|
create() {
|
|
const handle = (req, res, next) => {
|
|
this.model
|
|
.create(req.body)
|
|
.then(respond)
|
|
.catch(next);
|
|
|
|
function respond(row) {
|
|
res.status(201);
|
|
res.send(res.transform(row));
|
|
}
|
|
};
|
|
|
|
return [
|
|
raw,
|
|
handle
|
|
];
|
|
}
|
|
|
|
get() {
|
|
const handle = (req, res, next) => {
|
|
this
|
|
.findOne(req.params, req.options)
|
|
.then(respond)
|
|
.catch(next);
|
|
|
|
function respond(row) {
|
|
if (!row) {
|
|
throw new HttpStatusError(404, 'Not Found');
|
|
}
|
|
|
|
res.send(res.transform(row));
|
|
}
|
|
};
|
|
|
|
return [
|
|
raw,
|
|
handle
|
|
];
|
|
}
|
|
|
|
query() {
|
|
|
|
const customQuery = (req) => {
|
|
return new Promise((resolve, reject) => {
|
|
// TODO: Corregir y adecuar al nuevo funcionamiento
|
|
// if (req.query.searchPro == 1 && req.query.fIni && req.query.fFin) {
|
|
// options.where.fecha = {
|
|
// $between: [new Date(req.query.fIni) || fAct, new Date(req.query.fFin) || fAct]
|
|
// };
|
|
// }
|
|
|
|
if (!req.query.filter || req.query.filter === '') return resolve();
|
|
const condiciones = [];
|
|
const options = {};
|
|
options.attributes = _.keys(this.model.rawAttributes);
|
|
|
|
return this.model.describe().then(fields => {
|
|
for (const key in fields) {
|
|
const field = fields[key];
|
|
const obj = {};
|
|
|
|
let aux;
|
|
let tipo = field.type;
|
|
let buscar = (options.attributes == null) ? true : options.attributes.indexOf(key) != -1;
|
|
console.log('Revisndo l interpretacion del searchPRO', req.query.searchPro == 1);
|
|
if (req.query.searchPro == 1 && buscar && req.query.tipoBus == 'campo') buscar = req.query.campoSel == key;
|
|
|
|
if (req.query.searchPro == 1 && req.query.tipoBus == 'documento') {
|
|
console.log('SearchPro_Ddocumento'.bgWhite.red);
|
|
buscar = false;
|
|
if (key == 'plantilla_valor') {
|
|
obj[key] = {
|
|
"$ilike": `%${req.query.filter}%`
|
|
};
|
|
// xfilter.push(obj);
|
|
}
|
|
}
|
|
if (req.query.searchPro == 1 && req.query.tipoBus == 'flujo') {
|
|
console.log('SearchPro_Ddocumento'.bgWhite.red);
|
|
|
|
buscar = false;
|
|
if (key == 'grupo') {
|
|
obj[key] = req.query.filter;
|
|
// obj[i] = { $ilike:"%"+req.query.filter+"%" };
|
|
// xfilter.push(obj);
|
|
}
|
|
}
|
|
|
|
if (tipo.indexOf('CHARACTER VARYING') > -1) tipo = 'CHARACTER VARYING';
|
|
switch (tipo) {
|
|
case 'INTEGER':
|
|
aux = parseInt(req.query.filter);
|
|
if (!isNaN(aux) && req.query.filter.indexOf("/") == -1) {
|
|
obj[key] = aux;
|
|
}
|
|
break;
|
|
case 'USER-DEFINED':
|
|
|
|
aux = req.query.filter;
|
|
for (var j in field.special) {
|
|
if (field.special[j].toLowerCase().indexOf(aux.toLowerCase()) == 0) {
|
|
obj[key] = field.special[j];
|
|
}
|
|
}
|
|
break;
|
|
case 'TIMESTAMP WITH TIME ZONE':
|
|
// Busqueda de fechas del tipo: 2016-10-20, 2016/10/20, 20-10-2016, 20/10/2016.
|
|
// TODO: No se puede buscar por el mes.
|
|
console.log('TIMESTAMP WITH TIME ZONE __________________________'.magenta.bgWhite);
|
|
console.log('Primer procesado de fecha __________________'.magenta.bgWhite, procesarFecha(req.query.filter));
|
|
var consulta = procesarFecha(req.query.filter);
|
|
if (consulta != false) {
|
|
console.log('Fecha'.cyan, procesarFecha(req.query.filter));
|
|
obj[key] = procesarFecha(req.query.filter);
|
|
// condiciones.push(obj);
|
|
}
|
|
break;
|
|
case 'CHARACTER VARYING':
|
|
obj[key] = {
|
|
"$iLike": `%${req.query.filter}%`
|
|
};
|
|
break;
|
|
case 'TEXT':
|
|
obj[key] = {
|
|
"$iLike": `%${req.query.filter}%`
|
|
};
|
|
break;
|
|
case 'ARRAY':
|
|
// obj[key] = {"$iLike":`%${req.query.filter}%`};
|
|
break;
|
|
case 'BOOLEAN':
|
|
// obj[key] = {"$iLike":`%${req.query.filter}%`};
|
|
break;
|
|
default:
|
|
console.log('DEFAULT__________________________'.magenta.bgWhite, tipo);
|
|
obj[key] = req.query.filter;
|
|
break;
|
|
}
|
|
|
|
if (obj.hasOwnProperty(key)) {
|
|
condiciones.push(obj);
|
|
}
|
|
|
|
|
|
|
|
}
|
|
})
|
|
.then(() => {
|
|
console.log('Finalizando filtrado custom'.bgCyan.black);
|
|
this.custom = condiciones;
|
|
console.log('Checking custom condition'.bgCyan.black, this.custom);
|
|
return resolve();
|
|
});
|
|
});
|
|
}
|
|
const handle = (req, res, next) => {
|
|
customQuery(req)
|
|
.then(() => {
|
|
let flag = false;
|
|
if (this.custom !== null) {
|
|
flag = true;
|
|
req.query.filter = this.custom;
|
|
this.custom = null;
|
|
}
|
|
|
|
|
|
this
|
|
.findAndCountAll(req.query, req.options, flag)
|
|
.then(respond)
|
|
.catch(next);
|
|
});
|
|
|
|
function respond({
|
|
rows,
|
|
start,
|
|
end,
|
|
count
|
|
}) {
|
|
res.set('Content-Range', `${start}-${end}/${count}`);
|
|
|
|
if (count > end) {
|
|
res.status(206);
|
|
} else {
|
|
res.status(200);
|
|
}
|
|
|
|
const response = {
|
|
total: count,
|
|
resultado: rows
|
|
}
|
|
res.send(res.transform(response));
|
|
}
|
|
};
|
|
|
|
return [
|
|
raw,
|
|
handle
|
|
];
|
|
}
|
|
|
|
remove() {
|
|
const handle = (req, res, next) => {
|
|
this
|
|
.findOne(req.params)
|
|
.then(destroy)
|
|
.then(respond)
|
|
.catch(next);
|
|
|
|
function destroy(row) {
|
|
if (!row) {
|
|
throw new HttpStatusError(404, 'Not Found');
|
|
}
|
|
|
|
return row.destroy();
|
|
}
|
|
|
|
function respond() {
|
|
res.sendStatus(204);
|
|
}
|
|
};
|
|
|
|
return [
|
|
handle
|
|
];
|
|
}
|
|
|
|
update() {
|
|
const handle = (req, res, next) => {
|
|
console.log('[update] iniciando la modificacion ', req.params, req.body);
|
|
this
|
|
.findOne(req.params)
|
|
.then(updateAttributes)
|
|
.then(respond)
|
|
.catch(next);
|
|
|
|
function updateAttributes(row) {
|
|
console.log('[update] row', row);
|
|
if (!row) {
|
|
throw new HttpStatusError(404, 'Not Found');
|
|
}
|
|
|
|
// return row.updateAttributes(req.body);
|
|
return row.update(req.body);
|
|
}
|
|
|
|
function respond(row) {
|
|
res.send(res.transform(row));
|
|
}
|
|
};
|
|
|
|
return [
|
|
raw,
|
|
handle
|
|
];
|
|
}
|
|
|
|
findOne(params, options) {
|
|
if (params.hasOwnProperty('id')) {
|
|
params[`id_${this.name}`] = params.id;
|
|
delete params.id;
|
|
}
|
|
if (options && options.hasOwnProperty('id')) {
|
|
delete options.id;
|
|
delete options.audit_usuario;
|
|
|
|
}
|
|
options = _.merge(parse(params, this.model), options);
|
|
return this.model.findOne(options);
|
|
}
|
|
|
|
findAndCountAll(params, options, custom) {
|
|
let parsed = parse(params, this.model, custom);
|
|
|
|
options = _(parsed)
|
|
.defaults(this.defaults)
|
|
.merge(options)
|
|
.value();
|
|
if (custom) options.where["$or"] = params.filter;
|
|
if (params.page) {
|
|
options.offset = (params.page === 0 ? 0 : params.page - 1) * options.limit;
|
|
}
|
|
|
|
return this.model
|
|
.findAndCountAll(options)
|
|
.then(extract);
|
|
|
|
function extract({
|
|
count,
|
|
rows
|
|
}) {
|
|
const start = options.offset;
|
|
const end = Math.min(count, options.offset + options.limit);
|
|
|
|
return {
|
|
rows,
|
|
start,
|
|
end,
|
|
count
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
Funcion que procesa una cadena, verifica si tiene el formato de una fecha.
|
|
@param {pCadena} Cadena de texto con formato de fecha.
|
|
@return Retorna:
|
|
EXITO -> un objeto de consulta con formato sequelize.
|
|
FALLO -> false.
|
|
*/
|
|
function procesarFecha(pCadena) {
|
|
|
|
var fecha = new Date(pCadena);
|
|
var anio = null,
|
|
inicio = null,
|
|
fin = null;
|
|
|
|
// Identifica el operador usando en la cadena para separar los datos.
|
|
var operador = pCadena.indexOf('-') > -1 ? '-' : pCadena.indexOf('/') > -1 ? '/' : null;
|
|
|
|
// Si existe un operador valido en la cadena.
|
|
if (operador != null) {
|
|
|
|
// Si la cadena no es valida como fecha, se la invierte.
|
|
if (fecha == 'Invalid Date') {
|
|
fecha = new Date(((pCadena.split(operador)).reverse()).join("-"));
|
|
}
|
|
// Obtine el año.
|
|
anio = fecha.getFullYear();
|
|
|
|
// Si existe el año.
|
|
if (anio != null) {
|
|
var vector = pCadena.split(operador)
|
|
|
|
// Si la longitud del vector es igual a 3.
|
|
if (vector.length == 3) {
|
|
var indice = vector.indexOf(anio.toString());
|
|
|
|
// Si el año existe dentro del vector de la cadena.
|
|
if (indice > -1) {
|
|
|
|
// Armado de la fecha inicio y fecha fin.
|
|
if (indice == 0) {
|
|
inicio = vector[0] + "-" + vector[1] + "-" + vector[2];
|
|
fin = vector[0] + "-" + vector[1] + "-" + (parseInt(vector[2]) + 1);
|
|
} else if (indice == 2) {
|
|
inicio = vector[2] + "-" + vector[1] + "-" + vector[0];
|
|
fin = vector[2] + "-" + vector[1] + "-" + (parseInt(vector[0]) + 1);
|
|
}
|
|
|
|
// Armado de la respuesta a retornar.
|
|
var respuesta = {
|
|
$gte: inicio,
|
|
$lt: fin
|
|
};
|
|
return respuesta;
|
|
} else return false; // Fin condicional indice.
|
|
} else return false; // Fin condicional longitud vector.
|
|
} else return false; // Fin condicional existencia año.
|
|
} else return false; // Fin condicional existencia operador.
|
|
}
|
|
|
|
module.exports = ModelHandler; |