const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const buildFilter = require('vn-loopback/util/filter').buildFilter; const mergeFilters = require('vn-loopback/util/filter').mergeFilters; const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethodCtx('getTicketsFuture', { description: 'Find all tickets that can be moved to the future', accessType: 'READ', accepts: [ { arg: 'originDated', type: 'date', description: 'The date in question', required: true }, { arg: 'futureDated', type: 'date', description: 'The date to probe', required: true }, { arg: 'litersMax', type: 'number', description: 'Maximum volume of tickets to catapult', required: true }, { arg: 'linesMax', type: 'number', description: 'Maximum number of lines of tickets to catapult', required: true }, { arg: 'warehouseFk', type: 'number', description: 'Warehouse identifier', required: true }, { arg: 'shipped', type: 'date', description: 'Origin shipped', required: false }, { arg: 'tfShipped', type: 'date', description: 'Destination shipped', required: false }, { arg: 'ipt', type: 'string', description: 'Origin Item Packaging Type', required: false }, { arg: 'tfIpt', type: 'string', description: 'Destination Item Packaging Type', required: false }, { arg: 'id', type: 'number', description: 'Origin id', required: false }, { arg: 'tfId', type: 'number', description: 'Destination id', required: false }, { arg: 'state', type: 'string', description: 'Origin state', required: false }, { arg: 'tfState', type: 'string', description: 'Destination state', required: false }, { arg: 'problems', type: 'boolean', description: `Whether to show only tickets with problems`, required: false }, { arg: 'filter', type: 'object', description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string` } ], returns: { type: ['object'], root: true }, http: { path: `/getTicketsFuture`, verb: 'GET' } }); Self.getTicketsFuture = async (ctx, options) => { const args = ctx.args; const conn = Self.dataSource.connector; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); const where = buildFilter(ctx.args, (param, value) => { switch (param) { case 'id': return { 'f.id': value }; case 'tfId': return { 'f.ticketFuture': value }; case 'shipped': return { 'f.shipped': value }; case 'tfShipped': return { 'f.tfShipped': value }; case 'ipt': return { 'f.ipt': value }; case 'tfIpt': return { 'f.tfIpt': value }; case 'state': return { 'f.code': { like: `%${value}%` } }; case 'tfState': return { 'f.tfCode': { like: `%${value}%` } }; } }); let filter = mergeFilters(ctx.args.filter, { where }); const stmts = []; let stmt; stmt = new ParameterizedSQL( `CALL vn.ticket_canbePostponed(?,?,?,?,?)`, [args.originDated, args.futureDated, args.litersMax, args.linesMax, args.warehouseFk]); stmts.push(stmt); stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.sale_getProblems'); stmt = new ParameterizedSQL(` CREATE TEMPORARY TABLE tmp.sale_getProblems (INDEX (ticketFk)) ENGINE = MEMORY SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped FROM tmp.filter f LEFT JOIN alertLevel al ON al.id = f.alertLevel WHERE (al.code = 'FREE' OR f.alertLevel IS NULL)`); stmts.push(stmt); stmts.push('CALL ticket_getProblems(FALSE)'); stmt = new ParameterizedSQL(` SELECT f.*, tp.* FROM tmp.filter f LEFT JOIN tmp.ticket_problems tp ON tp.ticketFk = f.id`); if (args.problems != undefined && (!args.originDated && !args.futureDated)) throw new UserError('Choose a date range or days forward'); let condition; let hasProblem; let range; let hasWhere; switch (args.problems) { case true: condition = `or`; hasProblem = true; range = { neq: null }; hasWhere = true; break; case false: condition = `and`; hasProblem = null; range = null; hasWhere = true; break; } const problems = { [condition]: [ { 'tp.isFreezed': hasProblem }, { 'tp.risk': hasProblem }, { 'tp.hasTicketRequest': hasProblem }, { 'tp.itemShortage': range }, { 'tp.hasComponentLack': hasProblem }, { 'tp.isTooLittle': hasProblem } ] }; if (hasWhere) { filter = mergeFilters(filter, { where: problems }); } stmt.merge(conn.makeWhere(filter.where)); stmt.merge(conn.makeOrderBy(filter.order)); stmt.merge(conn.makeLimit(filter)); const ticketsIndex = stmts.push(stmt) - 1; stmts.push( `DROP TEMPORARY TABLE tmp.filter, tmp.ticket_problems`); const sql = ParameterizedSQL.join(stmts, ';'); const result = await conn.executeStmt(sql, myOptions); return result[ticketsIndex]; }; };