From cb7d1b24e85838af2f2bd74f54af74958902e9b1 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Thu, 7 Oct 2021 09:57:07 +0200 Subject: [PATCH] refactor(ticket): all ticket endpoints are using transactions now --- .../ticket/back/methods/expedition/filter.js | 13 +- .../methods/expedition/specs/filter.spec.js | 21 +++ .../back/methods/packaging/listPackaging.js | 18 +- .../packaging/specs/listPackaging.spec.js | 20 +- .../methods/sale-tracking/listSaleTracking.js | 27 +-- .../specs/listSaleTracking.spec.js | 36 +++- .../back/methods/state/editableStates.js | 21 ++- .../methods/state/specs/editableState.spec.js | 75 ++++++-- .../back/methods/ticket-dms/removeFile.js | 38 +++- .../ticket-dms/specs/removeFile.spec.js | 25 ++- .../back/methods/ticket-request/confirm.js | 64 ++++--- .../back/methods/ticket-request/deny.js | 42 +++-- .../back/methods/ticket-request/filter.js | 18 +- .../ticket-request/specs/confirm.spec.js | 107 ++++++----- .../methods/ticket-request/specs/deny.spec.js | 29 ++- .../ticket-request/specs/filter.spec.js | 171 ++++++++++++++---- .../methods/ticket-tracking/setDelivered.js | 63 ++++--- .../specs/setDelivered.spec.js | 61 +++---- .../back/methods/ticket-weekly/filter.js | 27 +-- .../ticket-weekly/specs/filter.spec.js | 92 +++++++--- 20 files changed, 653 insertions(+), 315 deletions(-) create mode 100644 modules/ticket/back/methods/expedition/specs/filter.spec.js diff --git a/modules/ticket/back/methods/expedition/filter.js b/modules/ticket/back/methods/expedition/filter.js index 817630eec..5eb7510b7 100644 --- a/modules/ticket/back/methods/expedition/filter.js +++ b/modules/ticket/back/methods/expedition/filter.js @@ -7,13 +7,13 @@ module.exports = Self => { accepts: [ { arg: 'filter', - type: 'Object', + type: 'object', description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string', http: {source: 'query'}, }, ], returns: { - type: ['Object'], + type: ['object'], root: true, }, http: { @@ -22,7 +22,12 @@ module.exports = Self => { }, }); - Self.filter = async filter => { + Self.filter = async(filter, options) => { + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + const stmt = new ParameterizedSQL( `SELECT e.id, @@ -55,6 +60,6 @@ module.exports = Self => { `); stmt.merge(Self.buildSuffix(filter, 'e')); - return await Self.rawStmt(stmt); + return Self.rawStmt(stmt, myOptions); }; }; diff --git a/modules/ticket/back/methods/expedition/specs/filter.spec.js b/modules/ticket/back/methods/expedition/specs/filter.spec.js new file mode 100644 index 000000000..85e98da4a --- /dev/null +++ b/modules/ticket/back/methods/expedition/specs/filter.spec.js @@ -0,0 +1,21 @@ +const models = require('vn-loopback/server/server').models; + +describe('expedition filter()', () => { + it('should return the expeditions matching the filter', async() => { + const tx = await models.Expedition.beginTransaction({}); + + try { + const options = {transaction: tx}; + + const filter = {where: {packagingFk: 1}}; + const response = await models.Expedition.filter(filter, options); + + expect(response.length).toEqual(10); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/modules/ticket/back/methods/packaging/listPackaging.js b/modules/ticket/back/methods/packaging/listPackaging.js index 174630f29..c26bdbda6 100644 --- a/modules/ticket/back/methods/packaging/listPackaging.js +++ b/modules/ticket/back/methods/packaging/listPackaging.js @@ -7,13 +7,13 @@ module.exports = Self => { accessType: 'READ', accepts: [{ arg: 'filter', - type: 'Object', + type: 'object', required: false, description: 'Filter defining where and paginated data', http: {source: 'query'} }], returns: { - type: ['Object'], + type: ['object'], root: true }, http: { @@ -22,9 +22,14 @@ module.exports = Self => { } }); - Self.listPackaging = async filter => { - let conn = Self.dataSource.connector; - let stmt = new ParameterizedSQL( + Self.listPackaging = async(filter, options) => { + const conn = Self.dataSource.connector; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const stmt = new ParameterizedSQL( `SELECT name, itemFk, packagingFk FROM (SELECT i.name, i.id itemFk, p.id packagingFk FROM item i @@ -33,6 +38,7 @@ module.exports = Self => { ); stmt.merge(conn.makeSuffix(filter)); - return conn.executeStmt(stmt); + + return conn.executeStmt(stmt, myOptions); }; }; diff --git a/modules/ticket/back/methods/packaging/specs/listPackaging.spec.js b/modules/ticket/back/methods/packaging/specs/listPackaging.spec.js index 9633093f1..3d07b90f9 100644 --- a/modules/ticket/back/methods/packaging/specs/listPackaging.spec.js +++ b/modules/ticket/back/methods/packaging/specs/listPackaging.spec.js @@ -1,12 +1,22 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('ticket listPackaging()', () => { it('should return the packaging', async() => { - let filter = {where: {packagingFk: 1}}; - let response = await app.models.Packaging.listPackaging(filter); + const tx = await models.Packaging.beginTransaction({}); - expect(response[0].name).toBeDefined(); - expect(response[0].name).toEqual('Container ammo box 1m'); + try { + const options = {transaction: tx}; + + const filter = {where: {packagingFk: 1}}; + const response = await models.Packaging.listPackaging(filter, options); + + expect(response[0].name).toEqual('Container ammo box 1m'); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/ticket/back/methods/sale-tracking/listSaleTracking.js b/modules/ticket/back/methods/sale-tracking/listSaleTracking.js index 0bcb94c03..c0d63ef62 100644 --- a/modules/ticket/back/methods/sale-tracking/listSaleTracking.js +++ b/modules/ticket/back/methods/sale-tracking/listSaleTracking.js @@ -7,11 +7,11 @@ module.exports = Self => { accessType: 'READ', accepts: [{ arg: 'filter', - type: 'Object', + type: 'object', description: 'Filter defining where and paginated data' }], returns: { - type: ['Object'], + type: ['object'], root: true }, http: { @@ -20,8 +20,13 @@ module.exports = Self => { } }); - Self.listSaleTracking = async filter => { - let stmt = new ParameterizedSQL(` + Self.listSaleTracking = async(filter, options) => { + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const stmt = new ParameterizedSQL(` SELECT st.id, s.ticketFk, @@ -41,9 +46,9 @@ module.exports = Self => { stmt.merge(Self.makeSuffix(filter)); - let trackings = await Self.rawStmt(stmt); + const trackings = await Self.rawStmt(stmt, myOptions); - let salesFilter = { + const salesFilter = { include: [ { relation: 'item' @@ -52,14 +57,14 @@ module.exports = Self => { where: {ticketFk: filter.where.ticketFk} }; - let sales = await Self.app.models.Sale.find(salesFilter); + const sales = await Self.app.models.Sale.find(salesFilter, myOptions); - trackings.forEach(tracking => { - sales.forEach(sale => { + for (const tracking of trackings) { + for (const sale of sales) { if (tracking.itemFk == sale.itemFk) tracking.item = sale.item(); - }); - }); + } + } return trackings; }; diff --git a/modules/ticket/back/methods/sale-tracking/specs/listSaleTracking.spec.js b/modules/ticket/back/methods/sale-tracking/specs/listSaleTracking.spec.js index 7b19f45bb..d51c56874 100644 --- a/modules/ticket/back/methods/sale-tracking/specs/listSaleTracking.spec.js +++ b/modules/ticket/back/methods/sale-tracking/specs/listSaleTracking.spec.js @@ -1,17 +1,39 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('ticket listSaleTracking()', () => { it('should call the listSaleTracking method and return the response', async() => { - let filter = {where: {ticketFk: 1}}; - let result = await app.models.SaleTracking.listSaleTracking(filter); + const tx = await models.SaleTracking.beginTransaction({}); - expect(result.length).toEqual(4); + try { + const options = {transaction: tx}; + + const filter = {where: {ticketFk: 1}}; + const result = await models.SaleTracking.listSaleTracking(filter, options); + + expect(result.length).toEqual(4); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it(`should call the listSaleTracking method and return zero if doesn't have lines`, async() => { - let filter = {where: {ticketFk: 2}}; - let result = await app.models.SaleTracking.listSaleTracking(filter); + const tx = await models.SaleTracking.beginTransaction({}); - expect(result.length).toEqual(0); + try { + const options = {transaction: tx}; + + const filter = {where: {ticketFk: 2}}; + const result = await models.SaleTracking.listSaleTracking(filter, options); + + expect(result.length).toEqual(0); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/ticket/back/methods/state/editableStates.js b/modules/ticket/back/methods/state/editableStates.js index c1cbda799..2c90ac43b 100644 --- a/modules/ticket/back/methods/state/editableStates.js +++ b/modules/ticket/back/methods/state/editableStates.js @@ -1,4 +1,3 @@ - module.exports = Self => { Self.remoteMethodCtx('editableStates', { description: 'Gets the editable states according the user role ', @@ -8,7 +7,7 @@ module.exports = Self => { type: 'object' }, returns: { - type: ['Object'], + type: ['object'], root: true }, http: { @@ -17,14 +16,18 @@ module.exports = Self => { } }); - Self.editableStates = async(ctx, filter) => { - let userId = ctx.req.accessToken.userId; - let models = Self.app.models; - let statesList = await models.State.find({where: filter.where}); + Self.editableStates = async(ctx, filter, options) => { + const models = Self.app.models; + const userId = ctx.req.accessToken.userId; + const myOptions = {}; - let isProduction = await models.Account.hasRole(userId, 'production'); - let isSalesPerson = await models.Account.hasRole(userId, 'salesPerson'); - let isAdministrative = await models.Account.hasRole(userId, 'administrative'); + if (typeof options == 'object') + Object.assign(myOptions, options); + + let statesList = await models.State.find({where: filter.where}, myOptions); + const isProduction = await models.Account.hasRole(userId, 'production', myOptions); + const isSalesPerson = await models.Account.hasRole(userId, 'salesPerson', myOptions); + const isAdministrative = await models.Account.hasRole(userId, 'administrative', myOptions); if (isProduction || isAdministrative) return statesList; diff --git a/modules/ticket/back/methods/state/specs/editableState.spec.js b/modules/ticket/back/methods/state/specs/editableState.spec.js index fc0b80494..c75242be0 100644 --- a/modules/ticket/back/methods/state/specs/editableState.spec.js +++ b/modules/ticket/back/methods/state/specs/editableState.spec.js @@ -1,34 +1,73 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('ticket editableStates()', () => { const filter = {where: {name: {like: '%%'}}}; it('should return the expected state for the given role', async() => { - const productionRole = 49; - const ctx = {req: {accessToken: {userId: productionRole}}}; + const tx = await models.State.beginTransaction({}); - let result = await app.models.State.editableStates(ctx, filter); - let deliveredState = result.some(state => state.code == 'DELIVERED'); + try { + const options = {transaction: tx}; - expect(deliveredState).toBeTruthy(); + const productionRole = 49; + const ctx = {req: {accessToken: {userId: productionRole}}}; + + const editableStates = await models.State.editableStates(ctx, filter, options); + + const deliveredState = editableStates.some(state => state.code == 'DELIVERED'); + + expect(deliveredState).toBeTruthy(); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it(`should return the expected states by a specific role`, async() => { - const productionRole = 18; - const ctx = {req: {accessToken: {userId: productionRole}}}; - let result = await app.models.State.editableStates(ctx, filter); - let deliveredState = result.some(state => state.code == 'DELIVERED'); - let pickerDesignedState = result.some(state => state.code == 'PICKER_DESIGNED'); + const tx = await models.State.beginTransaction({}); - expect(deliveredState).toBeFalsy(); - expect(pickerDesignedState).toBeTruthy(); + try { + const options = {transaction: tx}; + + const productionRole = 18; + const ctx = {req: {accessToken: {userId: productionRole}}}; + + const editableStates = await models.State.editableStates(ctx, filter, options); + + const deliveredState = editableStates.some(state => state.code == 'DELIVERED'); + + const pickerDesignedState = editableStates.some(state => state.code == 'PICKER_DESIGNED'); + + expect(deliveredState).toBeFalsy(); + expect(pickerDesignedState).toBeTruthy(); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it(`should return again the expected state by a specific role`, async() => { - const employeeRole = 1; - const ctx = {req: {accessToken: {userId: employeeRole}}}; - let result = await app.models.State.editableStates(ctx, filter); - let pickerDesignedState = result.some(state => state.code == 'PICKER_DESIGNED'); + const tx = await models.State.beginTransaction({}); - expect(pickerDesignedState).toBeTruthy(); + try { + const options = {transaction: tx}; + + const employeeRole = 1; + const ctx = {req: {accessToken: {userId: employeeRole}}}; + + const editableStates = await models.State.editableStates(ctx, filter, options); + + const pickerDesignedState = editableStates.some(state => state.code == 'PICKER_DESIGNED'); + + expect(pickerDesignedState).toBeTruthy(); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/ticket/back/methods/ticket-dms/removeFile.js b/modules/ticket/back/methods/ticket-dms/removeFile.js index 52a0c524f..f48dc7fef 100644 --- a/modules/ticket/back/methods/ticket-dms/removeFile.js +++ b/modules/ticket/back/methods/ticket-dms/removeFile.js @@ -4,12 +4,12 @@ module.exports = Self => { accessType: 'WRITE', accepts: { arg: 'id', - type: 'Number', + type: 'number', description: 'The document id', http: {source: 'path'} }, returns: { - type: 'Object', + type: 'object', root: true }, http: { @@ -18,16 +18,36 @@ module.exports = Self => { } }); - Self.removeFile = async(ctx, id) => { + Self.removeFile = async(ctx, id, options) => { const models = Self.app.models; - const targetTicketDms = await models.TicketDms.findById(id); - const targetDms = await models.Dms.findById(targetTicketDms.dmsFk); - const trashDmsType = await models.DmsType.findOne({where: {code: 'trash'}}); + const myOptions = {}; + let tx; - await models.Dms.removeFile(ctx, targetTicketDms.dmsFk); - await targetTicketDms.destroy(); + if (typeof options == 'object') + Object.assign(myOptions, options); - return targetDms.updateAttribute('dmsTypeFk', trashDmsType.id); + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const targetTicketDms = await models.TicketDms.findById(id, null, myOptions); + const targetDms = await models.Dms.findById(targetTicketDms.dmsFk, null, myOptions); + const trashDmsType = await models.DmsType.findOne({where: {code: 'trash'}}, myOptions); + + await models.Dms.removeFile(ctx, targetTicketDms.dmsFk, myOptions); + await targetTicketDms.destroy(myOptions); + + await targetDms.updateAttribute('dmsTypeFk', trashDmsType.id, myOptions); + + if (tx) await tx.commit(); + + return targetDms; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } }; }; diff --git a/modules/ticket/back/methods/ticket-dms/specs/removeFile.spec.js b/modules/ticket/back/methods/ticket-dms/specs/removeFile.spec.js index 1cd3b16cb..9296984c3 100644 --- a/modules/ticket/back/methods/ticket-dms/specs/removeFile.spec.js +++ b/modules/ticket/back/methods/ticket-dms/specs/removeFile.spec.js @@ -1,18 +1,25 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('TicketDms removeFile()', () => { const ticketDmsId = 1; it(`should return an error for a user without enough privileges`, async() => { - let clientId = 1101; - let ctx = {req: {accessToken: {userId: clientId}}}; + const tx = await models.TicketDms.beginTransaction({}); let error; - await app.models.TicketDms.removeFile(ctx, ticketDmsId).catch(e => { - error = e; - }).finally(() => { - expect(error.message).toEqual(`You don't have enough privileges`); - }); + try { + const options = {transaction: tx}; - expect(error).toBeDefined(); + const clientId = 1101; + const ctx = {req: {accessToken: {userId: clientId}}}; + + await models.TicketDms.removeFile(ctx, ticketDmsId, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toEqual(`You don't have enough privileges`); }); }); diff --git a/modules/ticket/back/methods/ticket-request/confirm.js b/modules/ticket/back/methods/ticket-request/confirm.js index ce4bfdccb..f7f7fbc2a 100644 --- a/modules/ticket/back/methods/ticket-request/confirm.js +++ b/modules/ticket/back/methods/ticket-request/confirm.js @@ -6,22 +6,22 @@ module.exports = Self => { accessType: 'WRITE', accepts: [{ arg: 'id', - type: 'Integer', + type: 'number', required: true, description: 'The request ID', }, { arg: 'itemFk', - type: 'Integer', + type: 'number', required: true, description: 'The requested item ID', }, { arg: 'quantity', - type: 'Integer', + type: 'number', required: true, description: 'The requested item quantity', }], returns: { - type: 'Object', + type: 'object', root: true }, http: { @@ -30,25 +30,37 @@ module.exports = Self => { } }); - Self.confirm = async ctx => { + Self.confirm = async(ctx, options) => { const userId = ctx.req.accessToken.userId; const models = Self.app.models; - const tx = await Self.beginTransaction({}); const $t = ctx.req.__; // $translate - let sale; + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } try { - let options = {transaction: tx}; - - let item = await models.Item.findById(ctx.args.itemFk, null, options); + const item = await models.Item.findById(ctx.args.itemFk, null, myOptions); if (!item) throw new UserError(`That item doesn't exists`); - let request = await models.TicketRequest.findById(ctx.args.id, { + const request = await models.TicketRequest.findById(ctx.args.id, { include: {relation: 'ticket'} - }, options); + }, myOptions); + + const itemStock = await models.Item.getVisibleAvailable( + ctx.args.itemFk, + request.ticket().warehouseFk, + request.ticket().shipped, + myOptions + ); - const itemStock = await models.Item.getVisibleAvailable(ctx.args.itemFk, request.ticket().warehouseFk, request.ticket().shipped); const isAvailable = itemStock.available > 0; if (!isAvailable) @@ -57,23 +69,24 @@ module.exports = Self => { if (request.saleFk) throw new UserError(`This request already contains a sale`); - sale = await models.Sale.create({ + const sale = await models.Sale.create({ ticketFk: request.ticketFk, itemFk: ctx.args.itemFk, quantity: ctx.args.quantity, concept: item.name - }, options); + }, myOptions); await request.updateAttributes({ saleFk: sale.id, itemFk: sale.itemFk, isOk: true - }, options); + }, myOptions); - query = `CALL vn.sale_calculateComponent(?, NULL)`; - await Self.rawSql(query, [sale.id], options); + const query = `CALL vn.sale_calculateComponent(?, NULL)`; + await Self.rawSql(query, [sale.id], myOptions); const origin = ctx.req.headers.origin; const requesterId = request.requesterFk; + const message = $t('Bought units from buy request', { quantity: sale.quantity, concept: sale.concept, @@ -82,10 +95,9 @@ module.exports = Self => { url: `${origin}/#!/ticket/${sale.ticketFk}/summary`, urlItem: `${origin}/#!/item/${sale.itemFk}/summary` }); - await models.Chat.sendCheckingPresence(ctx, requesterId, message); + await models.Chat.sendCheckingPresence(ctx, requesterId, message, myOptions); - // log - let logRecord = { + const logRecord = { originFk: sale.ticketFk, userFk: userId, action: 'update', @@ -99,14 +111,14 @@ module.exports = Self => { } }; - await Self.app.models.TicketLog.create(logRecord); + await Self.app.models.TicketLog.create(logRecord, myOptions); - await tx.commit(); + if (tx) await tx.commit(); return sale; - } catch (error) { - await tx.rollback(); - throw error; + } catch (e) { + if (tx) await tx.rollback(); + throw e; } }; }; diff --git a/modules/ticket/back/methods/ticket-request/deny.js b/modules/ticket/back/methods/ticket-request/deny.js index e663ef1bc..5b79a57cb 100644 --- a/modules/ticket/back/methods/ticket-request/deny.js +++ b/modules/ticket/back/methods/ticket-request/deny.js @@ -4,7 +4,7 @@ module.exports = Self => { accessType: 'WRITE', accepts: [{ arg: 'id', - type: 'Integer', + type: 'number', required: true, description: 'The request ID', }, { @@ -23,17 +23,37 @@ module.exports = Self => { } }); - Self.deny = async ctx => { - let userId = ctx.req.accessToken.userId; - let worker = await Self.app.models.Worker.findOne({where: {userFk: userId}}); + Self.deny = async(ctx, options) => { + const myOptions = {}; + let tx; - let params = { - isOk: false, - attenderFk: worker.id, - response: ctx.args.observation, - }; + if (typeof options == 'object') + Object.assign(myOptions, options); - let request = await Self.app.models.TicketRequest.findById(ctx.args.id); - return request.updateAttributes(params); + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const userId = ctx.req.accessToken.userId; + const worker = await Self.app.models.Worker.findOne({where: {userFk: userId}}, myOptions); + + const params = { + isOk: false, + attenderFk: worker.id, + response: ctx.args.observation, + }; + + const request = await Self.app.models.TicketRequest.findById(ctx.args.id, null, myOptions); + await request.updateAttributes(params, myOptions); + + if (tx) await tx.commit(); + + return request; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } }; }; diff --git a/modules/ticket/back/methods/ticket-request/filter.js b/modules/ticket/back/methods/ticket-request/filter.js index 9b864f632..62c58ea95 100644 --- a/modules/ticket/back/methods/ticket-request/filter.js +++ b/modules/ticket/back/methods/ticket-request/filter.js @@ -68,9 +68,13 @@ module.exports = Self => { } }); - Self.filter = async(ctx, filter) => { - let conn = Self.dataSource.connector; - let userId = ctx.req.accessToken.userId; + Self.filter = async(ctx, filter, options) => { + const conn = Self.dataSource.connector; + const userId = ctx.req.accessToken.userId; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); if (ctx.args.mine) ctx.args.attenderFk = userId; @@ -111,9 +115,7 @@ module.exports = Self => { filter = mergeFilters(filter, {where}); - let stmt; - - stmt = new ParameterizedSQL( + const stmt = new ParameterizedSQL( `SELECT tr.id, tr.ticketFk, @@ -149,8 +151,6 @@ module.exports = Self => { LEFT JOIN account.user ua ON ua.id = wka.userFk`); stmt.merge(conn.makeSuffix(filter)); - let result = await conn.executeStmt(stmt); - - return result; + return conn.executeStmt(stmt, myOptions); }; }; diff --git a/modules/ticket/back/methods/ticket-request/specs/confirm.spec.js b/modules/ticket/back/methods/ticket-request/specs/confirm.spec.js index 2068fdfdd..49413cf44 100644 --- a/modules/ticket/back/methods/ticket-request/specs/confirm.spec.js +++ b/modules/ticket/back/methods/ticket-request/specs/confirm.spec.js @@ -1,4 +1,4 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('ticket-request confirm()', () => { let ctx = { @@ -12,74 +12,89 @@ describe('ticket-request confirm()', () => { }; it(`should throw an error if the item doesn't exist`, async() => { - ctx.args = {itemFk: 999}; + const tx = await models.TicketRequest.beginTransaction({}); let error; try { - await app.models.TicketRequest.confirm(ctx); - } catch (err) { - error = err; + const options = {transaction: tx}; + + ctx.args = {itemFk: 999}; + await models.TicketRequest.confirm(ctx, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; } expect(error.message).toEqual(`That item doesn't exists`); }); it('should throw an error if the item is not available', async() => { - const requestId = 5; - const itemId = 4; - const quantity = 99999; - - ctx.args = { - itemFk: itemId, - id: requestId, - quantity: quantity - }; + const tx = await models.TicketRequest.beginTransaction({}); let error; - try { - await app.models.TicketRequest.confirm(ctx); - } catch (err) { - error = err; + const options = {transaction: tx}; + + const requestId = 5; + const itemId = 4; + const quantity = 99999; + + ctx.args = { + itemFk: itemId, + id: requestId, + quantity: quantity + }; + + await models.TicketRequest.confirm(ctx, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; } expect(error.message).toEqual(`This item is not available`); }); it(`should throw if there's a sale id`, async() => { - const requestId = 4; - const itemId = 1; - const quantity = 10; - - ctx.args = { - itemFk: itemId, - id: requestId, - quantity: quantity - }; - - const request = await app.models.TicketRequest.findById(requestId); - - expect(request.saleFk).toBeNull(); - - await request.updateAttributes({saleFk: 2}); - - ctx.args = { - itemFk: itemId, - id: requestId, - quantity: quantity - }; + const tx = await models.TicketRequest.beginTransaction({}); let error; - try { - await app.models.TicketRequest.confirm(ctx); - } catch (err) { - error = err; + const options = {transaction: tx}; + + const requestId = 4; + const itemId = 1; + const quantity = 10; + + ctx.args = { + itemFk: itemId, + id: requestId, + quantity: quantity + }; + + const request = await models.TicketRequest.findById(requestId, null, options); + + expect(request.saleFk).toBeNull(); + + await request.updateAttributes({saleFk: 2}, options); + + ctx.args = { + itemFk: itemId, + id: requestId, + quantity: quantity + }; + + await models.TicketRequest.confirm(ctx, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; } expect(error.message).toEqual(`This request already contains a sale`); - - // restores - await request.updateAttributes({saleFk: null}); }); }); diff --git a/modules/ticket/back/methods/ticket-request/specs/deny.spec.js b/modules/ticket/back/methods/ticket-request/specs/deny.spec.js index 04152fa21..523c5f065 100644 --- a/modules/ticket/back/methods/ticket-request/specs/deny.spec.js +++ b/modules/ticket/back/methods/ticket-request/specs/deny.spec.js @@ -1,25 +1,22 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('ticket-request deny()', () => { - let request; - afterAll(async done => { - let params = { - isOk: null, - attenderFk: request.attenderFk, - response: null, - }; + it('should return the dinied ticket request', async() => { + const tx = await models.TicketRequest.beginTransaction({}); - await request.updateAttributes(params); - done(); - }); + try { + const options = {transaction: tx}; - it('should return all ticket requests', async() => { - let ctx = {req: {accessToken: {userId: 9}}, args: {id: 4, observation: 'my observation'}}; + const ctx = {req: {accessToken: {userId: 9}}, args: {id: 4, observation: 'my observation'}}; - request = await app.models.TicketRequest.findById(ctx.args.id); + const result = await models.TicketRequest.deny(ctx, options); - let result = await app.models.TicketRequest.deny(ctx); + expect(result.id).toEqual(4); - expect(result.id).toEqual(4); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/ticket/back/methods/ticket-request/specs/filter.spec.js b/modules/ticket/back/methods/ticket-request/specs/filter.spec.js index 82bdfbd38..ae004a024 100644 --- a/modules/ticket/back/methods/ticket-request/specs/filter.spec.js +++ b/modules/ticket/back/methods/ticket-request/specs/filter.spec.js @@ -1,85 +1,184 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('ticket-request filter()', () => { const userId = 9; let ctx = {req: {accessToken: {userId: userId}}}; it('should now return all ticket requests', async() => { - ctx.args = {}; + const tx = await models.TicketRequest.beginTransaction({}); - const result = await app.models.TicketRequest.filter(ctx); + try { + const options = {transaction: tx}; - expect(result.length).toEqual(3); + ctx.args = {}; + + const result = await models.TicketRequest.filter(ctx, options); + + expect(result.length).toEqual(3); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the ticket request matching a generic search value which is the ticket ID', async() => { - ctx.args = {search: 11}; + const tx = await models.TicketRequest.beginTransaction({}); - const result = await app.models.TicketRequest.filter(ctx); - const requestId = result[0].id; + try { + const options = {transaction: tx}; - expect(requestId).toEqual(4); + ctx.args = {search: 11}; + + const result = await models.TicketRequest.filter(ctx, options); + const requestId = result[0].id; + + expect(requestId).toEqual(4); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the ticket request matching a generic search value which is the client address alias', async() => { - ctx.args = {search: 'NY roofs'}; + const tx = await models.TicketRequest.beginTransaction({}); - const result = await app.models.TicketRequest.filter(ctx); - const requestId = result[0].id; + try { + const options = {transaction: tx}; - expect(requestId).toEqual(4); + ctx.args = {search: 'NY roofs'}; + + const result = await models.TicketRequest.filter(ctx, options); + const requestId = result[0].id; + + expect(requestId).toEqual(4); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the ticket request matching the ticket ID', async() => { - ctx.args = {ticketFk: 11}; - const result = await app.models.TicketRequest.filter(ctx); - const requestId = result[0].id; + const tx = await models.TicketRequest.beginTransaction({}); - expect(requestId).toEqual(4); + try { + const options = {transaction: tx}; + + ctx.args = {ticketFk: 11}; + const result = await models.TicketRequest.filter(ctx, options); + const requestId = result[0].id; + + expect(requestId).toEqual(4); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the ticket request matching the atender ID', async() => { - ctx.args = {attenderFk: 35}; + const tx = await models.TicketRequest.beginTransaction({}); - const result = await app.models.TicketRequest.filter(ctx); - const requestId = result[0].id; + try { + const options = {transaction: tx}; - expect(requestId).toEqual(3); + ctx.args = {attenderFk: 35}; + + const result = await models.TicketRequest.filter(ctx, options); + const requestId = result[0].id; + + expect(requestId).toEqual(3); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the ticket request matching the isOk triple-state', async() => { - ctx.args = {isOk: null}; + const tx = await models.TicketRequest.beginTransaction({}); - const result = await app.models.TicketRequest.filter(ctx); - const requestId = result[0].id; + try { + const options = {transaction: tx}; - expect(requestId).toEqual(3); + ctx.args = {isOk: null}; + + const result = await models.TicketRequest.filter(ctx, options); + const requestId = result[0].id; + + expect(requestId).toEqual(3); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the ticket request matching the client ID', async() => { - ctx.args = {clientFk: 1102}; + const tx = await models.TicketRequest.beginTransaction({}); - const result = await app.models.TicketRequest.filter(ctx); - const requestId = result[0].id; + try { + const options = {transaction: tx}; - expect(requestId).toEqual(4); + ctx.args = {clientFk: 1102}; + + const result = await models.TicketRequest.filter(ctx, options); + const requestId = result[0].id; + + expect(requestId).toEqual(4); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the ticket request matching the warehouse ID', async() => { - ctx.args = {warehouse: 1}; + const tx = await models.TicketRequest.beginTransaction({}); - const result = await app.models.TicketRequest.filter(ctx, {order: 'id'}); - const requestId = result[0].id; + try { + const options = {transaction: tx}; - expect(requestId).toEqual(3); + ctx.args = {warehouse: 1}; + + const result = await models.TicketRequest.filter(ctx, {order: 'id'}, options); + const requestId = result[0].id; + + expect(requestId).toEqual(3); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the ticket request matching the salesPerson ID', async() => { - ctx.args = {salesPersonFk: 18}; + const tx = await models.TicketRequest.beginTransaction({}); - const result = await app.models.TicketRequest.filter(ctx); - const requestId = result[0].id; + try { + const options = {transaction: tx}; - expect(requestId).toEqual(3); + ctx.args = {salesPersonFk: 18}; + + const result = await models.TicketRequest.filter(ctx, options); + const requestId = result[0].id; + + expect(requestId).toEqual(3); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/ticket/back/methods/ticket-tracking/setDelivered.js b/modules/ticket/back/methods/ticket-tracking/setDelivered.js index 509f5b446..bd6e32dcf 100644 --- a/modules/ticket/back/methods/ticket-tracking/setDelivered.js +++ b/modules/ticket/back/methods/ticket-tracking/setDelivered.js @@ -6,13 +6,13 @@ module.exports = Self => { { arg: 'ticketIds', description: 'the array of ticket ids to set as delivered', - type: ['Number'], + type: ['number'], required: true, http: {source: 'body'} } ], returns: { - type: 'Object', + type: 'object', root: true }, http: { @@ -21,30 +21,47 @@ module.exports = Self => { } }); - Self.setDelivered = async(ctx, ticketIds) => { - let userId = ctx.req.accessToken.userId; - let models = Self.app.models; + Self.setDelivered = async(ctx, ticketIds, options) => { + const userId = ctx.req.accessToken.userId; + const models = Self.app.models; + const myOptions = {}; + let tx; - let state = await models.State.findOne({ - where: { - code: 'delivered' - }, - fields: ['id', 'name', 'alertLevel', 'code'] - }); + if (typeof options == 'object') + Object.assign(myOptions, options); - let worker = await models.Worker.findOne({where: {userFk: userId}}); - - let promises = []; - for (let id of ticketIds) { - let promise = models.TicketTracking.changeState(ctx, { - stateFk: state.id, - workerFk: worker.id, - ticketFk: id - }); - promises.push(promise); + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; } - await Promise.all(promises); - return state; + try { + const state = await models.State.findOne({ + where: { + code: 'delivered' + }, + fields: ['id', 'name', 'alertLevel', 'code'] + }, myOptions); + + const worker = await models.Worker.findOne({where: {userFk: userId}}, myOptions); + + const promises = []; + for (const id of ticketIds) { + const promise = models.TicketTracking.changeState(ctx, { + stateFk: state.id, + workerFk: worker.id, + ticketFk: id + }, myOptions); + promises.push(promise); + } + await Promise.all(promises); + + if (tx) await tx.commit(); + + return state; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } }; }; diff --git a/modules/ticket/back/methods/ticket-tracking/specs/setDelivered.spec.js b/modules/ticket/back/methods/ticket-tracking/specs/setDelivered.spec.js index 042ae0a1f..80c6055e5 100644 --- a/modules/ticket/back/methods/ticket-tracking/specs/setDelivered.spec.js +++ b/modules/ticket/back/methods/ticket-tracking/specs/setDelivered.spec.js @@ -1,4 +1,4 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); describe('ticket setDelivered()', () => { @@ -7,50 +7,41 @@ describe('ticket setDelivered()', () => { accessToken: {userId: userId}, }; - let ticketOne; - let ticketTwo; - beforeAll(async done => { spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ active: activeCtx }); - try { - let originalTicketOne = await app.models.Ticket.findById(8); - let originalTicketTwo = await app.models.Ticket.findById(10); - - originalTicketOne.id = null; - originalTicketTwo.id = null; - - ticketOne = await app.models.Ticket.create(originalTicketOne); - ticketTwo = await app.models.Ticket.create(originalTicketTwo); - } catch (error) { - console.error(error); - } - - done(); - }); - - afterAll(async done => { - try { - await app.models.Ticket.destroyById(ticketOne.id); - await app.models.Ticket.destroyById(ticketTwo.id); - } catch (error) { - console.error(error); - } - done(); }); it('should return the state which has been applied to the given tickets', async() => { - let ctx = {req: {accessToken: {userId: 49}}}; - let delivered = await app.models.State.findOne({where: {code: 'delivered'}, fields: ['id']}); + const tx = await models.TicketTracking.beginTransaction({}); - let params = [ticketOne.id, ticketTwo.id]; - let state = await app.models.TicketTracking.setDelivered(ctx, params); + try { + const options = {transaction: tx}; - expect(state.id).toEqual(delivered.id); + const ctx = {req: {accessToken: {userId: 49}}}; - // restores - await app.models.TicketTracking.destroyById(state.id); + const originalTicketOne = await models.Ticket.findById(8, null, options); + const originalTicketTwo = await models.Ticket.findById(10, null, options); + + originalTicketOne.id = null; + originalTicketTwo.id = null; + + const ticketOne = await models.Ticket.create(originalTicketOne, options); + const ticketTwo = await models.Ticket.create(originalTicketTwo, options); + + const delivered = await models.State.findOne({where: {code: 'delivered'}, fields: ['id']}, options); + + const params = [ticketOne.id, ticketTwo.id]; + const state = await models.TicketTracking.setDelivered(ctx, params, options); + + expect(state.id).toEqual(delivered.id); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/ticket/back/methods/ticket-weekly/filter.js b/modules/ticket/back/methods/ticket-weekly/filter.js index ef00aff9b..0bf92d542 100644 --- a/modules/ticket/back/methods/ticket-weekly/filter.js +++ b/modules/ticket/back/methods/ticket-weekly/filter.js @@ -10,18 +10,18 @@ module.exports = Self => { accepts: [ { arg: 'filter', - type: 'Object', + type: 'object', description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string', http: {source: 'query'} }, { arg: 'search', - type: 'String', + type: 'string', description: `If it's and integer searchs by id, otherwise it searchs by client id`, http: {source: 'query'} } ], returns: { - type: ['Object'], + type: ['object'], root: true }, http: { @@ -30,10 +30,14 @@ module.exports = Self => { } }); - Self.filter = async(ctx, filter) => { - let conn = Self.dataSource.connector; + Self.filter = async(ctx, filter, options) => { + const conn = Self.dataSource.connector; + const myOptions = {}; - let where = buildFilter(ctx.args, (param, value) => { + if (typeof options == 'object') + Object.assign(myOptions, options); + + const where = buildFilter(ctx.args, (param, value) => { switch (param) { case 'search': return {or: [ @@ -46,10 +50,9 @@ module.exports = Self => { filter = mergeFilters(ctx.args.filter, {where}); - let stmts = []; - let stmt; + const stmts = []; - stmt = new ParameterizedSQL( + const stmt = new ParameterizedSQL( `SELECT t.id AS ticketFk, c.id AS clientFk, c.name AS clientName, tw.weekDay, wh.name AS warehouseName, u.id AS workerFk, u.name AS userName, u.nickName, tw.agencyModeFk FROM ticketWeekly tw @@ -60,10 +63,10 @@ module.exports = Self => { ); stmt.merge(conn.makeSuffix(filter)); - let itemsIndex = stmts.push(stmt) - 1; + const itemsIndex = stmts.push(stmt) - 1; - let sql = ParameterizedSQL.join(stmts, ';'); - let result = await conn.executeStmt(sql); + const sql = ParameterizedSQL.join(stmts, ';'); + const result = await conn.executeStmt(sql, myOptions); return itemsIndex === 0 ? result : result[itemsIndex]; }; }; diff --git a/modules/ticket/back/methods/ticket-weekly/specs/filter.spec.js b/modules/ticket/back/methods/ticket-weekly/specs/filter.spec.js index 690fa669b..411bbe014 100644 --- a/modules/ticket/back/methods/ticket-weekly/specs/filter.spec.js +++ b/modules/ticket/back/methods/ticket-weekly/specs/filter.spec.js @@ -1,43 +1,89 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; describe('ticket-weekly filter()', () => { const authUserId = 9; it('should all return the tickets matching the filter', async() => { - const filter = {order: 't.id ASC'}; - const ctx = {req: {accessToken: {userId: authUserId}}, args: {filter: filter}}; - const result = await app.models.TicketWeekly.filter(ctx); + const tx = await models.TicketWeekly.beginTransaction({}); - const firstRow = result[0]; + try { + const options = {transaction: tx}; - expect(firstRow.ticketFk).toEqual(1); - expect(result.length).toEqual(5); + const filter = {order: 't.id ASC'}; + + const ctx = {req: {accessToken: {userId: authUserId}}, args: {filter: filter}}; + + const result = await models.TicketWeekly.filter(ctx, null, options); + + const firstRow = result[0]; + + expect(firstRow.ticketFk).toEqual(1); + expect(result.length).toEqual(5); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the ticket with id one', async() => { - const ctx = {req: {accessToken: {userId: authUserId}}, args: {search: 2}}; - const filter = {}; - const result = await app.models.TicketWeekly.filter(ctx, filter); - const firstRow = result[0]; + const tx = await models.TicketWeekly.beginTransaction({}); - expect(firstRow.ticketFk).toEqual(2); + try { + const options = {transaction: tx}; + + const ctx = {req: {accessToken: {userId: authUserId}}, args: {search: 2}}; + + const result = await models.TicketWeekly.filter(ctx, null, options); + const firstRow = result[0]; + + expect(firstRow.ticketFk).toEqual(2); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the ticket matching the client name', async() => { - const ctx = {req: {accessToken: {userId: authUserId}}, args: {search: 'bruce'}}; - const filter = {}; - const result = await app.models.TicketWeekly.filter(ctx, filter); - const firstRow = result[0]; + const tx = await models.TicketWeekly.beginTransaction({}); - expect(firstRow.clientName).toEqual('Bruce Wayne'); + try { + const options = {transaction: tx}; + + const ctx = {req: {accessToken: {userId: authUserId}}, args: {search: 'bruce'}}; + + const result = await models.TicketWeekly.filter(ctx, null, options); + const firstRow = result[0]; + + expect(firstRow.clientName).toEqual('Bruce Wayne'); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); it('should return the ticket matching the client id', async() => { - const ctx = {req: {accessToken: {userId: authUserId}}, args: {search: 1101}}; - const filter = {}; - const result = await app.models.TicketWeekly.filter(ctx, filter); - const firstRow = result[0]; + const tx = await models.TicketWeekly.beginTransaction({}); - expect(firstRow.clientFk).toEqual(1101); - expect(firstRow.clientName).toEqual('Bruce Wayne'); + try { + const options = {transaction: tx}; + + const ctx = {req: {accessToken: {userId: authUserId}}, args: {search: 1101}}; + + const result = await models.TicketWeekly.filter(ctx, null, options); + const firstRow = result[0]; + + expect(firstRow.clientFk).toEqual(1101); + expect(firstRow.clientName).toEqual('Bruce Wayne'); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); });