From d4eedc69e1be1d8e325e35dae590961f363ac9aa Mon Sep 17 00:00:00 2001 From: carlosjr Date: Tue, 11 May 2021 12:53:08 +0200 Subject: [PATCH 01/13] indentation on route filter --- modules/route/back/methods/route/filter.js | 49 +++++++++++++--------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/modules/route/back/methods/route/filter.js b/modules/route/back/methods/route/filter.js index c96f856f0..fdec84d4d 100644 --- a/modules/route/back/methods/route/filter.js +++ b/modules/route/back/methods/route/filter.js @@ -10,58 +10,67 @@ 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: 'Searchs the route by id', http: {source: 'query'} - }, { + }, + { arg: 'workerFk', - type: 'Integer', + type: 'integer', description: 'The worker id', http: {source: 'query'} - }, { + }, + { arg: 'agencyModeFk', - type: 'Integer', + type: 'integer', description: 'The agencyMode id', http: {source: 'query'} - }, { + }, + { arg: 'to', - type: 'Date', + type: 'date', description: 'The to date filter', http: {source: 'query'} - }, { + }, + { arg: 'from', - type: 'Date', + type: 'date', description: 'The to date filter', http: {source: 'query'} - }, { + }, + { arg: 'vehicleFk', - type: 'Integer', + type: 'integer', description: 'The vehicle id', http: {source: 'query'} - }, { + }, + { arg: 'm3', - type: 'Number', + type: 'number', description: 'The m3 filter', http: {source: 'query'} - }, { + }, + { arg: 'warehouseFk', - type: 'Number', + type: 'number', description: 'The warehouse filter', http: {source: 'query'} - }, { + }, + { arg: 'description', - type: 'String', + type: 'string', description: 'The description filter', http: {source: 'query'} } ], returns: { - type: ['Object'], + type: ['object'], root: true }, http: { -- 2.40.1 From 457d23dc161200e6de645bd682270b4e2e9926aa Mon Sep 17 00:00:00 2001 From: carlosjr Date: Wed, 12 May 2021 09:51:32 +0200 Subject: [PATCH 02/13] reoute tickets order columns + endpoint refactor --- db/dump/fixtures.sql | 23 +-- .../route/back/methods/route/getTickets.js | 132 +++++++----------- .../methods/route/specs/getTickets.spec.js | 3 +- modules/route/back/methods/route/summary.js | 2 +- modules/route/front/summary/index.html | 6 +- modules/route/front/tickets/index.html | 29 ++-- 6 files changed, 85 insertions(+), 110 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index f386ad780..db9f561b0 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -410,11 +410,12 @@ INSERT INTO `vn`.`clientObservation`(`id`, `clientFk`, `workerFk`, `text`, `crea INSERT INTO `vn`.`observationType`(`id`,`description`, `code`) VALUES - (1, 'observation one', 'observation one'), - (2, 'observation two', 'observation two'), - (3, 'observation three', 'observation three'), - (4, 'comercial', 'salesPerson'), - (5, 'delivery', 'delivery'); + (1, 'Sacador', 'itemPicker'), + (2, 'Encajador', 'packager'), + (3, 'Repartidor', 'delivery'), + (4, 'Comercial', 'salesPerson'), + (5, 'Administración', 'administrative'), + (6, 'Peso Aduana', 'weight'); INSERT INTO `vn`.`addressObservation`(`id`,`addressFk`,`observationTypeFk`,`description`) VALUES @@ -607,16 +608,16 @@ INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `des VALUES (1, 11, 1, 'ready'), (2, 2, 2, 'do it fast please'), - (3, 3, 3, 'Faster faster fasteeeeeer!!!'), - (4, 4, 3, 'Deliver before 8am'), - (5, 13, 3, 'You can run from the disappointments you are trying to forget. But its only when you embrace your past that you truly move forward. Maybe I never get to go home again, but I found my way there. And I am glad I did.'), - (6, 14, 3, 'Careful, armed warhead'), + (3, 3, 5, 'Faster faster fasteeeeeer!!!'), + (4, 4, 5, 'Deliver before 8am'), + (5, 13, 5, 'You can run from the disappointments you are trying to forget. But its only when you embrace your past that you truly move forward. Maybe I never get to go home again, but I found my way there. And I am glad I did.'), + (6, 14, 5, 'Careful, armed warhead'), (7, 23, 1, 'under the floor'), (8, 23, 2, 'wears leather and goes out at night'), - (9, 23, 3, 'care with the dog'), + (9, 23, 5, 'care with the dog'), (10, 23, 4, 'Reclama ticket: 8'), (11, 24, 4, 'Reclama ticket: 7'), - (12, 11, 5, 'Delivery after 10am'); + (12, 11, 3, 'Delivery after 10am'); -- FIX for state hours on local, inter_afterInsert UPDATE vncontrol.inter SET odbc_date = DATE_ADD(CURDATE(), INTERVAL -10 SECOND); diff --git a/modules/route/back/methods/route/getTickets.js b/modules/route/back/methods/route/getTickets.js index 211a2e7bb..7d9f3f254 100644 --- a/modules/route/back/methods/route/getTickets.js +++ b/modules/route/back/methods/route/getTickets.js @@ -1,101 +1,73 @@ + +const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; + module.exports = Self => { Self.remoteMethod('getTickets', { description: 'Return the tickets information displayed on the route module', accessType: 'READ', - accepts: [{ - arg: 'id', - type: 'number', - required: true, - description: 'The route id', - http: {source: 'path'} - }], + accepts: [ + { + arg: 'filter', + type: 'object', + description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string', + http: {source: 'query'} + } + ], returns: { type: 'object', root: true }, http: { - path: `/:id/getTickets`, + path: `/getTickets`, verb: 'GET' } }); - Self.getTickets = async id => { - let filter = { - where: {id: id}, - include: [ - {relation: 'ticket', - scope: { - fields: ['id', 'packages', 'warehouseFk', 'nickname', 'clientFk', 'priority', 'addressFk'], - order: 'priority', - include: [ - { - relation: 'ticketState', - scope: { - fields: ['id', 'stateFk'], - include: [{relation: 'state'}] - } - }, - { - relation: 'warehouse', - scope: { - fields: ['id', 'name'] - } - }, - { - relation: 'notes', - scope: { - where: {observationTypeFk: 3} - } - }, - { - relation: 'address', - scope: { - fields: ['id', 'street', 'postalCode', 'city'], - } - }, + Self.getTickets = async(filter, options) => { + const conn = Self.dataSource.connector; - ] - } - }, { - relation: 'agencyMode', - scope: { - fields: ['id', 'name'] - } - }, { - relation: 'worker', - scope: { - fields: ['id', 'userFk'], - include: [ - { - relation: 'user', - scope: { - fields: ['id', 'nickname'] - } - } - ] - } - }, { - relation: 'vehicle', - scope: { - fields: ['id', 'm3', 'numberPlate'] - } - } - ], - }; + const stmt = new ParameterizedSQL( + `SELECT + t.id, + t.packages, + t.warehouseFk, + t.nickname, + t.clientFk, + t.priority, + t.addressFk, + st.code AS ticketStateCode, + st.name AS ticketStateName, + wh.name AS warehouseName, + tob.description AS ticketObservation, + a.street, + a.postalCode, + a.city, + am.name AS agencyModeName, + u.nickname AS userNickname, + vn.ticketTotalVolume(t.id) AS volume + FROM route r + LEFT JOIN ticket t ON t.routeFk = r.id + LEFT JOIN ticketState ts ON ts.ticketFk = t.id + LEFT JOIN state st ON st.id = ts.stateFk + LEFT JOIN warehouse wh ON wh.id = t.warehouseFk + LEFT JOIN ticketObservation tob ON tob.ticketFk = t.id + LEFT JOIN observationType ot ON tob.observationTypeFk = ot.id + AND ot.code = 'delivery' + LEFT JOIN address a ON a.id = t.addressFk + LEFT JOIN agencyMode am ON am.id = t.agencyModeFk + LEFT JOIN account.user u ON u.id = r.workerFk + LEFT JOIN vehicle v ON v.id = r.vehicleFk` + ); - route = await Self.app.models.Route.findOne(filter); + if (!filter.where) filter.where = {}; - for (let i = 0; i < route.ticket().length; i++) { - let ticket = route.ticket()[i]; - let query = ` - SELECT vn.ticketTotalVolume(?) AS m3`; + const where = filter.where; + where['r.id'] = filter.id; - let options = [ticket.id]; - let [volume] = await Self.rawSql(query, options); + stmt.merge(conn.makeSuffix(filter)); - ticket.volume = volume.m3; - } + const tickets = await conn.executeStmt(stmt, options); - return route.ticket(); + return tickets; }; }; diff --git a/modules/route/back/methods/route/specs/getTickets.spec.js b/modules/route/back/methods/route/specs/getTickets.spec.js index 15028309f..687547e45 100644 --- a/modules/route/back/methods/route/specs/getTickets.spec.js +++ b/modules/route/back/methods/route/specs/getTickets.spec.js @@ -2,7 +2,8 @@ const app = require('vn-loopback/server/server'); describe('route getTickets()', () => { it('should return the tickets for a given route', async() => { - let result = await app.models.Route.getTickets(2); + const filter = {id: 2}; + let result = await app.models.Route.getTickets(filter); expect(result.length).toEqual(1); }); diff --git a/modules/route/back/methods/route/summary.js b/modules/route/back/methods/route/summary.js index 52927d974..ad65edb4a 100644 --- a/modules/route/back/methods/route/summary.js +++ b/modules/route/back/methods/route/summary.js @@ -53,7 +53,7 @@ module.exports = Self => { }; summary.route = await Self.app.models.Route.findOne(filter); - summary.tickets = await Self.app.models.Route.getTickets(id); + summary.tickets = await Self.app.models.Route.getTickets({id: id}); return summary; }; diff --git a/modules/route/front/summary/index.html b/modules/route/front/summary/index.html index b284851a0..86f558634 100644 --- a/modules/route/front/summary/index.html +++ b/modules/route/front/summary/index.html @@ -106,9 +106,9 @@ {{ticket.packages}} {{ticket.volume}} - {{ticket.warehouse.name}} - {{ticket.address.postalCode}} - {{ticket.address.street}} + {{ticket.warehouseName}} + {{ticket.postalCode}} + {{ticket.street}} @@ -34,14 +35,14 @@ model="model"> - Order - Street - City - PC - Client - Packages - - Ticket + Order + Street + City + PC + Client + Packages + + Ticket @@ -62,9 +63,9 @@ display-controls=true> - {{ticket.address.street}} - {{ticket.address.city}} - {{ticket.address.postalCode}} + {{::ticket.street}} + {{::ticket.city}} + {{::ticket.postalCode}} - {{ticket.packages}} + {{::ticket.packages}} {{::ticket.volume | number:1}} - {{ticket.id}} + {{::ticket.id}} -- 2.40.1 From 83d65813498ee351f784ebc534c74ebc71622660 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Wed, 12 May 2021 09:52:04 +0200 Subject: [PATCH 03/13] indentation correction --- modules/zone/back/methods/agency/getShipped.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/zone/back/methods/agency/getShipped.js b/modules/zone/back/methods/agency/getShipped.js index 1e6051696..529d7478e 100644 --- a/modules/zone/back/methods/agency/getShipped.js +++ b/modules/zone/back/methods/agency/getShipped.js @@ -34,7 +34,7 @@ module.exports = Self => { } }); - Self.getShipped = async(landed, addressFk, agencyModeFk, warehouseFk)=> { + Self.getShipped = async(landed, addressFk, agencyModeFk, warehouseFk) => { let stmts = []; stmts.push(new ParameterizedSQL( `CALL vn.zone_getShippedWarehouse(?, ?, ?)`, [ -- 2.40.1 From 61fb997717451c0f710d9d8fc72f4c6a4b7b3831 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Fri, 14 May 2021 19:17:37 +0200 Subject: [PATCH 04/13] removed transaction from procedure to use backend's --- .../00-ticket_componentMakeUpdate.sql | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 db/changes/10320-monitors/00-ticket_componentMakeUpdate.sql diff --git a/db/changes/10320-monitors/00-ticket_componentMakeUpdate.sql b/db/changes/10320-monitors/00-ticket_componentMakeUpdate.sql new file mode 100644 index 000000000..d21a0ed09 --- /dev/null +++ b/db/changes/10320-monitors/00-ticket_componentMakeUpdate.sql @@ -0,0 +1,100 @@ +DROP PROCEDURE `vn`.`ticket_componentMakeUpdate`; + +DELIMITER $$ +$$ +CREATE + DEFINER = root@`%` PROCEDURE `vn`.`ticket_componentMakeUpdate`(IN vTicketFk INT, IN vClientFk INT, IN vAgencyModeFk INT, + IN vAddressFk INT, IN vZoneFk INT, IN vWarehouseFk TINYINT, + IN vCompanyFk SMALLINT, IN vShipped DATETIME, + IN vLanded DATE, IN vIsDeleted TINYINT(1), + IN vHasToBeUnrouted TINYINT(1), IN vOption INT) +BEGIN +/** + * Modifica en el ticket los campos que se le pasan por parámetro + * y cambia sus componentes. + * Este procedimiento es transacionado en Salix + * + * @param vTicketFk Id del ticket a modificar + * @param vClientFk nuevo cliente + * @param vAgencyModeFk nueva agencia + * @param vAddressFk nuevo consignatario + * @param vZoneFk nueva zona + * @param vWarehouseFk nuevo almacen + * @param vCompanyFk nueva empresa + * @param vShipped nueva fecha del envio de mercancia + * @param vLanded nueva fecha de recepcion de mercancia + * @param vIsDeleted si se borra el ticket + * @param vHasToBeUnrouted si se le elimina la ruta al ticket + * @param vOption opcion para el case del proc ticketComponentUpdateSale + */ + DECLARE vPrice DECIMAL(10,2); + DECLARE vBonus DECIMAL(10,2); +# DECLARE EXIT HANDLER FOR SQLEXCEPTION +# BEGIN +# ROLLBACK; +# RESIGNAL; +# END; + + CALL ticket_componentPreview (vTicketFk, vLanded, vAddressFk, vZoneFk, vWarehouseFk); + +# START TRANSACTION; + + IF (SELECT addressFk FROM ticket WHERE id = vTicketFk) <> vAddressFk THEN + + UPDATE ticket t + JOIN address a ON a.id = vAddressFk + SET t.nickname = a.nickname + WHERE t.id = vTicketFk; + + END IF; + + CALL zone_getShippedWarehouse(vlanded, vAddressFk, vAgencyModeFk); + + SELECT zoneFk, price, bonus INTO vZoneFk, vPrice, vBonus + FROM tmp.zoneGetShipped + WHERE shipped BETWEEN DATE(vShipped) AND util.dayEnd(vShipped) AND warehouseFk = vWarehouseFk LIMIT 1; + + UPDATE ticket t + SET + t.clientFk = vClientFk, + t.agencyModeFk = vAgencyModeFk, + t.addressFk = vAddressFk, + t.zoneFk = vZoneFk, + t.zonePrice = vPrice, + t.zoneBonus = vBonus, + t.warehouseFk = vWarehouseFk, + t.companyFk = vCompanyFk, + t.landed = vLanded, + t.shipped = vShipped, + t.isDeleted = vIsDeleted + WHERE + t.id = vTicketFk; + + IF vHasToBeUnrouted THEN + UPDATE ticket t SET t.routeFk = NULL + WHERE t.id = vTicketFk; + END IF; + + IF vOption <> 8 THEN + DROP TEMPORARY TABLE IF EXISTS tmp.sale; + CREATE TEMPORARY TABLE tmp.sale + (PRIMARY KEY (saleFk)) + ENGINE = MEMORY + SELECT id AS saleFk, vWarehouseFk warehouseFk + FROM sale s WHERE s.ticketFk = vTicketFk; + + DROP TEMPORARY TABLE IF EXISTS tmp.ticketComponent; + CREATE TEMPORARY TABLE tmp.ticketComponent + SELECT * FROM tmp.ticketComponentPreview; + + CALL ticketComponentUpdateSale (vOption); + + DROP TEMPORARY TABLE tmp.sale; + DROP TEMPORARY TABLE IF EXISTS tmp.ticketComponent; + END IF; +# COMMIT; + + DROP TEMPORARY TABLE tmp.zoneGetShipped, tmp.ticketComponentPreview; +END;;$$ +DELIMITER ; + -- 2.40.1 From 1e8ab4d348729e878d0426836bbae0f289894321 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Fri, 14 May 2021 19:21:04 +0200 Subject: [PATCH 05/13] added transactions to several endpoints --- back/methods/chat/sendCheckingPresence.js | 13 +- .../route/back/methods/route/getTickets.js | 8 +- modules/route/front/tickets/index.html | 2 +- modules/route/front/tickets/index.js | 5 +- .../back/methods/ticket-request/filter.js | 49 ++- .../back/methods/ticket/componentUpdate.js | 369 ++++++++++-------- .../ticket/back/methods/ticket/isEditable.js | 16 +- .../ticket/back/methods/ticket/isLocked.js | 9 +- .../ticket/specs/componentUpdate.spec.js | 234 +++++------ .../methods/ticket/specs/isEditable.spec.js | 121 +++++- .../zone/back/methods/agency/getShipped.js | 13 +- .../methods/agency/specs/getShipped.spec.js | 48 ++- 12 files changed, 522 insertions(+), 365 deletions(-) diff --git a/back/methods/chat/sendCheckingPresence.js b/back/methods/chat/sendCheckingPresence.js index 16fa01dc9..c1bc565eb 100644 --- a/back/methods/chat/sendCheckingPresence.js +++ b/back/methods/chat/sendCheckingPresence.js @@ -24,11 +24,16 @@ module.exports = Self => { } }); - Self.sendCheckingPresence = async(ctx, recipientId, message) => { + Self.sendCheckingPresence = async(ctx, recipientId, message, options) => { if (!recipientId) return false; + let myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + const models = Self.app.models; - const account = await models.Account.findById(recipientId); + const account = await models.Account.findById(recipientId, null, myOptions); const userId = ctx.req.accessToken.userId; if (recipientId == userId) return false; @@ -37,14 +42,14 @@ module.exports = Self => { throw new Error(`Could not send message "${message}" to worker id ${recipientId} from user ${userId}`); const query = `SELECT worker_isWorking(?) isWorking`; - const [result] = await Self.rawSql(query, [recipientId]); + const [result] = await Self.rawSql(query, [recipientId], myOptions); if (!result.isWorking) { const workerDepartment = await models.WorkerDepartment.findById(recipientId, { include: { relation: 'department' } - }); + }, myOptions); const department = workerDepartment && workerDepartment.department(); const channelName = department && department.chatName; diff --git a/modules/route/back/methods/route/getTickets.js b/modules/route/back/methods/route/getTickets.js index 7d9f3f254..3dfc5d73a 100644 --- a/modules/route/back/methods/route/getTickets.js +++ b/modules/route/back/methods/route/getTickets.js @@ -26,6 +26,10 @@ module.exports = Self => { Self.getTickets = async(filter, options) => { const conn = Self.dataSource.connector; + let myOptions = {}; + if (typeof options == 'object') + Object.assign(myOptions, options); + const stmt = new ParameterizedSQL( `SELECT t.id, @@ -66,7 +70,9 @@ module.exports = Self => { stmt.merge(conn.makeSuffix(filter)); - const tickets = await conn.executeStmt(stmt, options); + const tickets = await conn.executeStmt(stmt, myOptions); + + if (tickets.length === 1 && !tickets[0].id) return; return tickets; }; diff --git a/modules/route/front/tickets/index.html b/modules/route/front/tickets/index.html index 621a9b3c5..6a5a4ce7c 100644 --- a/modules/route/front/tickets/index.html +++ b/modules/route/front/tickets/index.html @@ -113,7 +113,7 @@ + on-accept="$ctrl.removeTicketFromRoute($index)"> { - addresses = addresses + '+to:' + line.address.postalCode + ' ' + line.address.city + ' ' + line.address.street; + addresses = addresses + '+to:' + line.postalCode + ' ' + line.city + ' ' + line.street; }); window.open(url + addresses, '_blank'); @@ -78,10 +78,11 @@ class Controller extends Section { this.$.confirm.show(); } - removeTicketFromRoute() { + removeTicketFromRoute($index) { let params = {routeFk: null}; let query = `Tickets/${this.selectedTicket}/`; this.$http.patch(query, params).then(() => { + this.$.model.remove($index); this.vnApp.showSuccess(this.$t('Ticket removed from route')); this.updateVolume(); }); diff --git a/modules/ticket/back/methods/ticket-request/filter.js b/modules/ticket/back/methods/ticket-request/filter.js index 5778b1db2..9b864f632 100644 --- a/modules/ticket/back/methods/ticket-request/filter.js +++ b/modules/ticket/back/methods/ticket-request/filter.js @@ -9,48 +9,57 @@ module.exports = Self => { accepts: [ { arg: 'ctx', - type: 'Object', + type: 'object', http: {source: 'context'} - }, { + }, + { arg: 'filter', - type: 'Object', + type: 'object', description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string` - }, { + }, + { arg: 'search', - type: 'String', + type: 'string', description: `If it's and integer searchs by id, otherwise it searchs by nickname` - }, { + }, + { arg: 'ticketFk', - type: 'Number', + type: 'number', description: `Searchs by ticketFk` - }, { + }, + { arg: 'warehouseFk', - type: 'Number', + type: 'number', description: `Search by warehouse` - }, { + }, + { arg: 'attenderFk', - type: 'Number', + type: 'number', description: `Search requests attended by a given worker id` - }, { + }, + { arg: 'mine', - type: 'Boolean', + type: 'boolean', description: `Search requests attended by the current user` - }, { + }, + { arg: 'from', - type: 'Date', + type: 'date', description: `Date from` - }, { + }, + { arg: 'to', - type: 'Date', + type: 'date', description: `Date to` - }, { + }, + { arg: 'state', - type: 'String', + type: 'string', description: `Search request by request state` } ], returns: { - type: ['Object'], + type: ['object'], root: true }, http: { diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index fe395e562..c4d1baed1 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -5,65 +5,76 @@ module.exports = Self => { Self.remoteMethodCtx('componentUpdate', { description: 'Save ticket sale components', accessType: 'WRITE', - accepts: [{ - arg: 'id', - type: 'Number', - required: true, - description: 'The ticket id', - http: {source: 'path'} - }, { - arg: 'clientFk', - type: 'Number', - description: 'The client id', - required: true - }, { - arg: 'agencyModeFk', - type: 'Number', - description: 'The agencyMode id', - required: true - }, { - arg: 'addressFk', - type: 'Number', - description: 'The address id', - required: true - }, { - arg: 'zoneFk', - type: 'Number', - description: 'The zone id', - required: true - }, { - arg: 'warehouseFk', - type: 'Number', - description: 'The warehouse id', - required: true - }, { - arg: 'companyFk', - type: 'Number', - description: 'The company id', - required: true - }, { - arg: 'shipped', - type: 'Date', - description: 'The shipped date', - required: true - }, { - arg: 'landed', - type: 'Date', - description: 'The landing date', - required: true - }, { - arg: 'isDeleted', - type: 'Boolean', - description: 'Ticket is deleted', - required: true - }, { - arg: 'option', - type: 'Number', - description: 'Action id', - required: true - }], + accepts: [ + { + arg: 'id', + type: 'number', + required: true, + description: 'The ticket id', + http: {source: 'path'} + }, + { + arg: 'clientFk', + type: 'number', + description: 'The client id', + required: true + }, + { + arg: 'agencyModeFk', + type: 'number', + description: 'The agencyMode id', + required: true + }, + { + arg: 'addressFk', + type: 'number', + description: 'The address id', + required: true + }, + { + arg: 'zoneFk', + type: 'number', + description: 'The zone id', + required: true + }, + { + arg: 'warehouseFk', + type: 'number', + description: 'The warehouse id', + required: true + }, + { + arg: 'companyFk', + type: 'number', + description: 'The company id', + required: true + }, + { + arg: 'shipped', + type: 'date', + description: 'The shipped date', + required: true + }, + { + arg: 'landed', + type: 'date', + description: 'The landing date', + required: true + }, + { + arg: 'isDeleted', + type: 'boolean', + description: 'Ticket is deleted', + required: true + }, + { + arg: 'option', + type: 'number', + description: 'Action id', + required: true + }], returns: { - type: ['Object'], + type: ['object'], root: true }, http: { @@ -72,128 +83,156 @@ module.exports = Self => { } }); - Self.componentUpdate = async(ctx, id, clientFk, agencyModeFk, addressFk, zoneFk, warehouseFk, - companyFk, shipped, landed, isDeleted, option) => { - const userId = ctx.req.accessToken.userId; - const models = Self.app.models; - const $t = ctx.req.__; // $translate - const isEditable = await models.Ticket.isEditable(ctx, id); + Self.componentUpdate = async(ctx, options) => { + const args = ctx.args; + let tx; + let myOptions = {}; - if (!isEditable) - throw new UserError(`The sales of this ticket can't be modified`); + if (typeof options == 'object') + Object.assign(myOptions, options); - const isProductionBoss = await models.Account.hasRole(userId, 'productionBoss'); - if (!isProductionBoss) { - const zoneShipped = await models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk); - - if (!zoneShipped || zoneShipped.zoneFk != zoneFk) - throw new UserError(`You don't have privileges to change the zone`); + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; } - const observationTypeDelivery = await models.ObservationType.findOne({ - where: {code: 'delivery'} - }); - const originalTicket = await models.Ticket.findOne({ - where: {id: id}, - fields: ['id', 'clientFk', 'agencyModeFk', 'addressFk', 'zoneFk', - 'warehouseFk', 'companyFk', 'shipped', 'landed', 'isDeleted'], - include: [ - { - relation: 'client', - scope: { - fields: 'salesPersonFk' - } - }] - }); - const updatedTicket = Object.assign({}, ctx.args); - delete updatedTicket.ctx; - delete updatedTicket.option; + try { + const userId = ctx.req.accessToken.userId; + const models = Self.app.models; + const $t = ctx.req.__; // $translate + const isEditable = await models.Ticket.isEditable(ctx, args.id, myOptions); - // Force to unroute ticket - const hasToBeUnrouted = true; - const query = 'CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; - const res = await Self.rawSql(query, [ - id, - clientFk, - agencyModeFk, - addressFk, - zoneFk, - warehouseFk, - companyFk, - shipped, - landed, - isDeleted, - hasToBeUnrouted, - option - ]); + if (!isEditable) + throw new UserError(`The sales of this ticket can't be modified`); - if (originalTicket.addressFk != updatedTicket.addressFk) { - const ticketObservation = await models.TicketObservation.findOne({ - where: { - ticketFk: id, - observationTypeFk: observationTypeDelivery.id} - }); + const isProductionBoss = await models.Account.hasRole(userId, 'productionBoss', myOptions); + if (!isProductionBoss) { + const zoneShipped = await models.Agency.getShipped(args.landed, args.addressFk, args.agencyModeFk, args.warehouseFk, myOptions); - if (ticketObservation) - await ticketObservation.destroy(); + if (!zoneShipped || zoneShipped.zoneFk != args.zoneFk) + throw new UserError(`You don't have privileges to change the zone`); + } + const observationTypeDelivery = await models.ObservationType.findOne({ + where: {code: 'delivery'} + }, myOptions); - const address = await models.Address.findOne({ - where: {id: addressFk}, - include: { - relation: 'observations', - scope: { - where: {observationTypeFk: observationTypeDelivery.id}, - include: { - relation: 'observationType' + const originalTicket = await models.Ticket.findOne({ + where: {id: args.id}, + fields: [ + 'id', + 'clientFk', + 'agencyModeFk', + 'addressFk', + 'zoneFk', + 'warehouseFk', + 'companyFk', + 'shipped', + 'landed', + 'isDeleted' + ], + include: [ + { + relation: 'client', + scope: { + fields: 'salesPersonFk' + } + }] + }, myOptions); + const updatedTicket = Object.assign({}, args); + delete updatedTicket.ctx; + delete updatedTicket.option; + + // Force to unroute ticket + const hasToBeUnrouted = true; + const query = 'CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; + const res = await Self.rawSql(query, [ + args.id, + args.clientFk, + args.agencyModeFk, + args.addressFk, + args.zoneFk, + args.warehouseFk, + args.companyFk, + args.shipped, + args.landed, + args.isDeleted, + hasToBeUnrouted, + args.option + ], myOptions); + + if (originalTicket.addressFk != updatedTicket.addressFk) { + const ticketObservation = await models.TicketObservation.findOne({ + where: { + ticketFk: args.id, + observationTypeFk: observationTypeDelivery.id} + }, myOptions); + + if (ticketObservation) + await ticketObservation.destroy(myOptions); + + const address = await models.Address.findOne({ + where: {id: args.addressFk}, + include: { + relation: 'observations', + scope: { + where: {observationTypeFk: observationTypeDelivery.id}, + include: { + relation: 'observationType' + } } } + }, myOptions); + const [observation] = address.observations(); + if (observation) { + await models.TicketObservation.create({ + ticketFk: args.id, + observationTypeFk: observation.observationTypeFk, + description: observation.description + }, myOptions); } - }); - const [observation] = address.observations(); - if (observation) { - await models.TicketObservation.create({ - ticketFk: id, - observationTypeFk: observation.observationTypeFk, - description: observation.description + } + + const changes = loggable.getChanges(originalTicket, updatedTicket); + const oldProperties = await loggable.translateValues(Self, changes.old); + const newProperties = await loggable.translateValues(Self, changes.new); + + await models.TicketLog.create({ + originFk: args.id, + userFk: userId, + action: 'update', + changedModel: 'Ticket', + changedModelId: args.id, + oldInstance: oldProperties, + newInstance: newProperties + }, myOptions); + + const salesPersonId = originalTicket.client().salesPersonFk; + if (salesPersonId) { + const origin = ctx.req.headers.origin; + + let changesMade = ''; + for (let change in newProperties) { + let value = newProperties[change]; + let oldValue = oldProperties[change]; + + changesMade += `\r\n~${$t(change)}: ${oldValue}~ ➔ *${$t(change)}: ${value}*`; + } + + const message = $t('Changed this data from the ticket', { + ticketId: args.id, + ticketUrl: `${origin}/#!/ticket/${args.id}/summary`, + changes: changesMade }); - } - } - - const changes = loggable.getChanges(originalTicket, updatedTicket); - const oldProperties = await loggable.translateValues(Self, changes.old); - const newProperties = await loggable.translateValues(Self, changes.new); - - await models.TicketLog.create({ - originFk: id, - userFk: userId, - action: 'update', - changedModel: 'Ticket', - changedModelId: id, - oldInstance: oldProperties, - newInstance: newProperties - }); - - const salesPersonId = originalTicket.client().salesPersonFk; - if (salesPersonId) { - const origin = ctx.req.headers.origin; - - let changesMade = ''; - for (let change in newProperties) { - let value = newProperties[change]; - let oldValue = oldProperties[change]; - - changesMade += `\r\n~${$t(change)}: ${oldValue}~ ➔ *${$t(change)}: ${value}*`; + await models.Chat.sendCheckingPresence(ctx, salesPersonId, message, myOptions); } - const message = $t('Changed this data from the ticket', { - ticketId: id, - ticketUrl: `${origin}/#!/ticket/${id}/summary`, - changes: changesMade - }); - await models.Chat.sendCheckingPresence(ctx, salesPersonId, message); - } + if (tx) await tx.commit(); - return res; + return res; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } }; }; diff --git a/modules/ticket/back/methods/ticket/isEditable.js b/modules/ticket/back/methods/ticket/isEditable.js index 317cfac96..1cdca9f11 100644 --- a/modules/ticket/back/methods/ticket/isEditable.js +++ b/modules/ticket/back/methods/ticket/isEditable.js @@ -19,15 +19,19 @@ module.exports = Self => { } }); - Self.isEditable = async(ctx, id) => { + Self.isEditable = async(ctx, id, options) => { const userId = ctx.req.accessToken.userId; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); let state = await Self.app.models.TicketState.findOne({ where: {ticketFk: id} - }); + }, myOptions); - const isSalesAssistant = await Self.app.models.Account.hasRole(userId, 'salesAssistant'); - const isProductionBoss = await Self.app.models.Account.hasRole(userId, 'productionBoss'); + const isSalesAssistant = await Self.app.models.Account.hasRole(userId, 'salesAssistant', myOptions); + const isProductionBoss = await Self.app.models.Account.hasRole(userId, 'productionBoss', myOptions); const isValidRole = isSalesAssistant || isProductionBoss; let alertLevel = state ? state.alertLevel : null; @@ -41,8 +45,8 @@ module.exports = Self => { } } }] - }); - const isLocked = await Self.app.models.Ticket.isLocked(id); + }, myOptions); + const isLocked = await Self.app.models.Ticket.isLocked(id, myOptions); const alertLevelGreaterThanZero = (alertLevel && alertLevel > 0); const isNormalClient = ticket && ticket.client().type().code == 'normal'; diff --git a/modules/ticket/back/methods/ticket/isLocked.js b/modules/ticket/back/methods/ticket/isLocked.js index 7cf7b807e..a6c3cc036 100644 --- a/modules/ticket/back/methods/ticket/isLocked.js +++ b/modules/ticket/back/methods/ticket/isLocked.js @@ -19,10 +19,15 @@ module.exports = Self => { } }); - Self.isLocked = async id => { + Self.isLocked = async(id, options) => { + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + const ticket = await Self.app.models.Ticket.findById(id, { fields: ['isDeleted', 'refFk'] - }); + }, myOptions); const isDeleted = ticket && ticket.isDeleted; const isInvoiced = ticket && ticket.refFk; diff --git a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js index 76733f2c6..1347af888 100644 --- a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js +++ b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js @@ -13,147 +13,125 @@ describe('ticket componentUpdate()', () => { let secondvalueBeforeChange; let componentOfSaleSeven; let componentOfSaleEight; + let componentValue; + + beforeAll(async() => { + const deliveryComponenet = await app.models.Component.findOne({where: {code: 'delivery'}}); + deliveryComponentId = deliveryComponenet.id; + componentOfSaleSeven = `SELECT value FROM vn.saleComponent WHERE saleFk = 7 AND componentFk = ${deliveryComponentId}`; + componentOfSaleEight = `SELECT value FROM vn.saleComponent WHERE saleFk = 8 AND componentFk = ${deliveryComponentId}`; + + [componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleSeven); + firstvalueBeforeChange = componentValue.value; + + [componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleEight); + secondvalueBeforeChange = componentValue.value; + }); + + it('should change the agencyMode to modify the sale components value', async() => { + const tx = await app.models.SaleComponent.beginTransaction({}); - beforeAll(async done => { try { - let deliveryComponenet = await app.models.Component.findOne({where: {code: 'delivery'}}); - deliveryComponentId = deliveryComponenet.id; - componentOfSaleSeven = `SELECT value FROM vn.saleComponent WHERE saleFk = 7 AND componentFk = ${deliveryComponentId}`; - componentOfSaleEight = `SELECT value FROM vn.saleComponent WHERE saleFk = 8 AND componentFk = ${deliveryComponentId}`; + const options = {transaction: tx}; - [componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleSeven); - firstvalueBeforeChange = componentValue.value; + const args = { + id: ticketID, + clientFk: 102, + agencyModeFk: 8, + addressFk: 122, + zoneFk: 5, + warehouseFk: 1, + companyFk: 442, + shipped: today, + landed: tomorrow, + isDeleted: false, + option: 1 + }; - [componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleEight); - secondvalueBeforeChange = componentValue.value; - } catch (error) { - console.error(error); + let ctx = { + args: args, + req: { + accessToken: {userId: userID}, + headers: {origin: 'http://localhost'}, + __: value => { + return value; + } + } + }; + + await app.models.Ticket.componentUpdate(ctx, options); + + [componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleSeven, null, options); + let firstvalueAfterChange = componentValue.value; + + [componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleEight, null, options); + let secondvalueAfterChange = componentValue.value; + + expect(firstvalueBeforeChange).not.toEqual(firstvalueAfterChange); + expect(secondvalueBeforeChange).not.toEqual(secondvalueAfterChange); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; } - - done(); }); - it('should change the agencyMode to modify the sale components value and then undo the changes', async() => { - const clientID = 102; - const addressID = 122; - const agencyModeID = 8; - const warehouseID = 1; - const zoneID = 5; - const shipped = today; - const companyID = 442; - const isDeleted = false; - const landed = tomorrow; - const option = 1; + it('should change the addressFk and check that delivery observations have been changed', async() => { + const tx = await app.models.SaleComponent.beginTransaction({}); - let ctx = { - args: {clientFk: clientID, - agencyModeFk: agencyModeID}, - req: { - accessToken: {userId: userID}, - headers: {origin: 'http://localhost'}, - __: value => { - return value; + try { + const options = {transaction: tx}; + + const args = { + id: ticketID, + clientFk: 102, + agencyModeFk: 8, + addressFk: 2, + zoneFk: 5, + warehouseFk: 1, + companyFk: 442, + shipped: today, + landed: tomorrow, + isDeleted: false, + option: 1 + }; + + const ctx = { + args: args, + req: { + accessToken: {userId: userID}, + headers: {origin: 'http://localhost'}, + __: value => { + return value; + } } - } - }; + }; + const observationTypeDelivery = await app.models.ObservationType.findOne({ + where: {code: 'delivery'} + }, options); + const originalTicketObservation = await app.models.TicketObservation.findOne({ + where: { + ticketFk: args.id, + observationTypeFk: observationTypeDelivery.id} + }, options); - await app.models.Ticket.componentUpdate(ctx, ticketID, clientID, agencyModeID, addressID, - zoneID, warehouseID, companyID, shipped, landed, isDeleted, option); + expect(originalTicketObservation).toBeDefined(); - [componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleSeven); - let firstvalueAfterChange = componentValue.value; + await app.models.Ticket.componentUpdate(ctx, options); - [componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleEight); - let secondvalueAfterChange = componentValue.value; + const removedTicketObservation = await app.models.TicketObservation.findOne({ + where: { + ticketFk: ticketID, + observationTypeFk: observationTypeDelivery.id} + }, options); - expect(firstvalueBeforeChange).not.toEqual(firstvalueAfterChange); - expect(secondvalueBeforeChange).not.toEqual(secondvalueAfterChange); + expect(removedTicketObservation).toBeNull(); - // restores - const restores = { - clientID: 102, - addressID: 122, - agencyModeID: 7, - warehouseID: 1, - zoneID: 3, - shipped: today, - companyID: 442, - isDeleted: false, - landed: tomorrow, - option: 1, - }; - - ctx.clientFk = restores.clientID; - ctx.agencyModeFk = restores.agencyModeID; - - await app.models.Ticket.componentUpdate(ctx, ticketID, restores.clientID, restores.agencyModeID, restores.addressID, - restores.zoneID, restores.warehouseID, restores.companyID, restores.shipped, restores.landed, restores.isDeleted, restores.option); - - [componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleSeven); - firstvalueAfterChange = componentValue.value; - - [componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleEight); - secondvalueAfterChange = componentValue.value; - - expect(firstvalueBeforeChange).toEqual(firstvalueAfterChange); - expect(secondvalueBeforeChange).toEqual(secondvalueAfterChange); - }); - - it('should change the addressFk and check that delivery observations have been changed and then undo the changes', async() => { - const clientID = 102; - const addressID = 122; - const newAddressID = 2; - const agencyModeID = 8; - const warehouseID = 1; - const zoneID = 5; - const shipped = today; - const companyID = 442; - const isDeleted = false; - const landed = tomorrow; - const option = 1; - const ctx = { - args: {clientFk: clientID, - agencyModeFk: agencyModeID}, - req: { - accessToken: {userId: userID}, - headers: {origin: 'http://localhost'}, - __: value => { - return value; - } - } - }; - const observationTypeDelivery = await app.models.ObservationType.findOne({ - where: {code: 'delivery'} - }); - const originalTicketObservation = await app.models.TicketObservation.findOne({ - where: { - ticketFk: ticketID, - observationTypeFk: observationTypeDelivery.id} - }); - - expect(originalTicketObservation).toBeDefined(); - - await app.models.Ticket.componentUpdate(ctx, ticketID, clientID, agencyModeID, newAddressID, - zoneID, warehouseID, companyID, shipped, landed, isDeleted, option); - - const removedTicketObservation = await app.models.TicketObservation.findOne({ - where: { - ticketFk: ticketID, - observationTypeFk: observationTypeDelivery.id} - }); - - expect(removedTicketObservation).toBeNull(); - - // restores - await app.models.Ticket.componentUpdate(ctx, ticketID, clientID, agencyModeID, addressID, - zoneID, warehouseID, companyID, shipped, landed, isDeleted, option); - - const restoredTicketObservation = await app.models.TicketObservation.findOne({ - where: { - ticketFk: ticketID, - observationTypeFk: observationTypeDelivery.id} - }); - - expect(restoredTicketObservation.description).toEqual(originalTicketObservation.description); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/ticket/back/methods/ticket/specs/isEditable.spec.js b/modules/ticket/back/methods/ticket/specs/isEditable.spec.js index 276aeacf1..5a6bf7d19 100644 --- a/modules/ticket/back/methods/ticket/specs/isEditable.spec.js +++ b/modules/ticket/back/methods/ticket/specs/isEditable.spec.js @@ -2,52 +2,135 @@ const app = require('vn-loopback/server/server'); describe('ticket isEditable()', () => { it('should return false if the given ticket does not exist', async() => { - let ctx = {req: {accessToken: {userId: 9}}}; - let result = await app.models.Ticket.isEditable(ctx, 99999); + const tx = await app.models.Ticket.beginTransaction({}); + let result; + + try { + const options = {transaction: tx}; + const ctx = { + req: {accessToken: {userId: 9}} + }; + + result = await app.models.Ticket.isEditable(ctx, 9999, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } expect(result).toEqual(false); }); it(`should return false if the given ticket isn't invoiced but isDeleted`, async() => { - let ctx = {req: {accessToken: {userId: 9}}}; - let deletedTicket = await app.models.Ticket.findOne({ - where: { - invoiceOut: null, - isDeleted: true - }, - fields: ['id'] - }); + const tx = await app.models.Ticket.beginTransaction({}); + let result; - let result = await app.models.Ticket.isEditable(ctx, deletedTicket.id); + try { + const options = {transaction: tx}; + const deletedTicket = await app.models.Ticket.findOne({ + where: { + invoiceOut: null, + isDeleted: true + }, + fields: ['id'] + }); + + const ctx = { + req: {accessToken: {userId: 9}} + }; + + result = await app.models.Ticket.isEditable(ctx, deletedTicket.id, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } expect(result).toEqual(false); }); it('should return true if the given ticket is editable', async() => { - let ctx = {req: {accessToken: {userId: 9}}}; + const tx = await app.models.Ticket.beginTransaction({}); + let result; - let result = await app.models.Ticket.isEditable(ctx, 16); + try { + const options = {transaction: tx}; + const ctx = { + req: {accessToken: {userId: 9}} + }; + + result = await app.models.Ticket.isEditable(ctx, 16, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } expect(result).toEqual(true); }); it('should not be able to edit a deleted or invoiced ticket even for salesAssistant', async() => { - let ctx = {req: {accessToken: {userId: 21}}}; - let result = await app.models.Ticket.isEditable(ctx, 19); + const tx = await app.models.Ticket.beginTransaction({}); + let result; + + try { + const options = {transaction: tx}; + const ctx = { + req: {accessToken: {userId: 21}} + }; + + result = await app.models.Ticket.isEditable(ctx, 19, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } expect(result).toEqual(false); }); it('should not be able to edit a deleted or invoiced ticket even for productionBoss', async() => { - let ctx = {req: {accessToken: {userId: 50}}}; - let result = await app.models.Ticket.isEditable(ctx, 19); + const tx = await app.models.Ticket.beginTransaction({}); + let result; + + try { + const options = {transaction: tx}; + const ctx = { + req: {accessToken: {userId: 50}} + }; + + result = await app.models.Ticket.isEditable(ctx, 19, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } expect(result).toEqual(false); }); it('should not be able to edit a deleted or invoiced ticket even for salesPerson', async() => { - let ctx = {req: {accessToken: {userId: 18}}}; - let result = await app.models.Ticket.isEditable(ctx, 19); + const tx = await app.models.Ticket.beginTransaction({}); + let result; + + try { + const options = {transaction: tx}; + const ctx = { + req: {accessToken: {userId: 18}} + }; + + result = await app.models.Ticket.isEditable(ctx, 19, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } expect(result).toEqual(false); }); diff --git a/modules/zone/back/methods/agency/getShipped.js b/modules/zone/back/methods/agency/getShipped.js index 529d7478e..b54056a5f 100644 --- a/modules/zone/back/methods/agency/getShipped.js +++ b/modules/zone/back/methods/agency/getShipped.js @@ -34,7 +34,12 @@ module.exports = Self => { } }); - Self.getShipped = async(landed, addressFk, agencyModeFk, warehouseFk) => { + Self.getShipped = async(landed, addressFk, agencyModeFk, warehouseFk, options) => { + let myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + let stmts = []; stmts.push(new ParameterizedSQL( `CALL vn.zone_getShippedWarehouse(?, ?, ?)`, [ @@ -44,14 +49,14 @@ module.exports = Self => { ] )); - let rsIndex = stmts.push(new ParameterizedSQL( + const rsIndex = stmts.push(new ParameterizedSQL( `SELECT * FROM tmp.zoneGetShipped WHERE warehouseFk = ?`, [ warehouseFk ] )) - 1; - let sql = ParameterizedSQL.join(stmts, ';'); - let shipped = await Self.rawStmt(sql); + const sql = ParameterizedSQL.join(stmts, ';'); + const shipped = await Self.rawStmt(sql, myOptions); return shipped[rsIndex][0]; }; diff --git a/modules/zone/back/methods/agency/specs/getShipped.spec.js b/modules/zone/back/methods/agency/specs/getShipped.spec.js index 8f79dab3b..2d65c8bc0 100644 --- a/modules/zone/back/methods/agency/specs/getShipped.spec.js +++ b/modules/zone/back/methods/agency/specs/getShipped.spec.js @@ -2,27 +2,49 @@ const app = require('vn-loopback/server/server'); describe('agency getShipped()', () => { it('should return a shipment date', async() => { - const landed = new Date(); - landed.setDate(landed.getDate() + 1); - const addressFk = 121; - const agencyModeFk = 7; - const warehouseFk = 1; + const tx = await app.models.Agency.beginTransaction({}); + let result; - let result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk); + try { + const options = {transaction: tx}; + + const landed = new Date(); + landed.setDate(landed.getDate() + 1); + const addressFk = 121; + const agencyModeFk = 7; + const warehouseFk = 1; + + result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } expect(result).toBeDefined(); }); it('should not return a shipment date', async() => { - let newDate = new Date(); - newDate.setMonth(newDate.getMonth() - 1); + const tx = await app.models.Agency.beginTransaction({}); + let result; - const landed = newDate; - const addressFk = 121; - const agencyModeFk = 7; - const warehouseFk = 1; + try { + const options = {transaction: tx}; + let newDate = new Date(); + newDate.setMonth(newDate.getMonth() - 1); + const landed = newDate; + const addressFk = 121; + const agencyModeFk = 7; + const warehouseFk = 1; - let result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk); + result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk, options); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } expect(result).toBeUndefined(); }); -- 2.40.1 From d83d3b67655e350039daafee5c4a4c87b635db97 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Fri, 14 May 2021 19:21:31 +0200 Subject: [PATCH 06/13] documented the missing argument --- loopback/util/log.js | 1 + 1 file changed, 1 insertion(+) diff --git a/loopback/util/log.js b/loopback/util/log.js index 9832a018a..e26022c35 100644 --- a/loopback/util/log.js +++ b/loopback/util/log.js @@ -2,6 +2,7 @@ * Translates to a readable values * @param {Object} instance - The model or context instance * @param {Object} changes - Object containing changes + * @param {Object} options - Object containing transaction */ exports.translateValues = async(instance, changes, options = {}) => { const models = instance.app.models; -- 2.40.1 From 799a3c6c36a8d3092de6244dbd5bb9fe6e40122e Mon Sep 17 00:00:00 2001 From: carlosjr Date: Fri, 14 May 2021 19:22:04 +0200 Subject: [PATCH 07/13] e2e paths updated to endpoints refactors --- e2e/paths/02-client/06_add_address_notes.spec.js | 2 +- e2e/paths/05-ticket/01_observations.spec.js | 4 ++-- e2e/paths/05-ticket/17_log.spec.js | 2 +- e2e/paths/12-entry/03_latestBuys.spec.js | 1 - e2e/paths/12-entry/06_observations.spec.js | 7 +++---- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/e2e/paths/02-client/06_add_address_notes.spec.js b/e2e/paths/02-client/06_add_address_notes.spec.js index 770d7d788..8c1f93749 100644 --- a/e2e/paths/02-client/06_add_address_notes.spec.js +++ b/e2e/paths/02-client/06_add_address_notes.spec.js @@ -43,7 +43,7 @@ describe('Client add address notes path', () => { it('should create two new observations', async() => { await page.write(selectors.clientAddresses.firstObservationDescription, 'first description'); await page.waitToClick(selectors.clientAddresses.addObservationButton); - await page.autocompleteSearch(selectors.clientAddresses.secondObservationType, 'observation one'); + await page.autocompleteSearch(selectors.clientAddresses.secondObservationType, 'Sacador'); await page.write(selectors.clientAddresses.secondObservationDescription, 'second description'); await page.waitToClick(selectors.clientAddresses.saveButton); const message = await page.waitForSnackbar(); diff --git a/e2e/paths/05-ticket/01_observations.spec.js b/e2e/paths/05-ticket/01_observations.spec.js index eccf9cbfd..ec00a7122 100644 --- a/e2e/paths/05-ticket/01_observations.spec.js +++ b/e2e/paths/05-ticket/01_observations.spec.js @@ -19,7 +19,7 @@ describe('Ticket Create notes path', () => { it('should create a new note', async() => { await page.waitToClick(selectors.ticketNotes.addNoteButton); - await page.autocompleteSearch(selectors.ticketNotes.firstNoteType, 'observation one'); + await page.autocompleteSearch(selectors.ticketNotes.firstNoteType, 'sacador'); await page.write(selectors.ticketNotes.firstDescription, 'description'); await page.waitToClick(selectors.ticketNotes.submitNotesButton); const message = await page.waitForSnackbar(); @@ -32,7 +32,7 @@ describe('Ticket Create notes path', () => { const result = await page .waitToGetProperty(selectors.ticketNotes.firstNoteType, 'value'); - expect(result).toEqual('observation one'); + expect(result).toEqual('Sacador'); const firstDescription = await page .waitToGetProperty(selectors.ticketNotes.firstDescription, 'value'); diff --git a/e2e/paths/05-ticket/17_log.spec.js b/e2e/paths/05-ticket/17_log.spec.js index 1b21886d5..a37a3f307 100644 --- a/e2e/paths/05-ticket/17_log.spec.js +++ b/e2e/paths/05-ticket/17_log.spec.js @@ -24,7 +24,7 @@ describe('Ticket log path', () => { it('should create a new note for the test', async() => { await page.waitToClick(selectors.ticketNotes.addNoteButton); - await page.autocompleteSearch(selectors.ticketNotes.firstNoteType, 'observation one'); + await page.autocompleteSearch(selectors.ticketNotes.firstNoteType, 'Sacador'); await page.write(selectors.ticketNotes.firstDescription, 'description'); await page.waitToClick(selectors.ticketNotes.submitNotesButton); const message = await page.waitForSnackbar(); diff --git a/e2e/paths/12-entry/03_latestBuys.spec.js b/e2e/paths/12-entry/03_latestBuys.spec.js index 4b1050abc..f7dc07ca9 100644 --- a/e2e/paths/12-entry/03_latestBuys.spec.js +++ b/e2e/paths/12-entry/03_latestBuys.spec.js @@ -17,7 +17,6 @@ describe('Entry lastest buys path', () => { it('should access the latest buys seccion and search not seeing the edit buys button yet', async() => { await page.waitToClick(selectors.entryLatestBuys.latestBuysSectionButton); - await page.waitToClick(selectors.globalItems.searchButton); await page.waitForSelector(selectors.entryLatestBuys.editBuysButton, {visible: false}); }); diff --git a/e2e/paths/12-entry/06_observations.spec.js b/e2e/paths/12-entry/06_observations.spec.js index 107c2e0b6..f2dd93a03 100644 --- a/e2e/paths/12-entry/06_observations.spec.js +++ b/e2e/paths/12-entry/06_observations.spec.js @@ -8,7 +8,6 @@ describe('Entry observations path', () => { beforeAll(async() => { browser = await getBrowser(); page = browser.page; - // await page.loginAndModule('buyer', 'entry'); // access denied, awaiting role confirmation await page.loginAndModule('developer', 'entry'); await page.accessToSearchResult('2'); await page.accessToSection('entry.card.observation'); @@ -32,7 +31,7 @@ describe('Entry observations path', () => { }); it('should set the 2nd observation of a different one and successfully save both', async() => { - await page.autocompleteSearch(selectors.entryObservations.secondObservationType, 'delivery'); + await page.autocompleteSearch(selectors.entryObservations.secondObservationType, 'repartidor'); await page.waitToClick(selectors.entryObservations.saveObservationsButton); const message = await page.waitForSnackbar(); @@ -43,7 +42,7 @@ describe('Entry observations path', () => { await page.reloadSection('entry.card.observation'); const result = await page.waitToGetProperty(selectors.entryObservations.firstObservationType, 'value'); - expect(result).toEqual('comercial'); + expect(result).toEqual('Comercial'); }); it('should make sure the first observation description was saved correctly', async() => { @@ -55,7 +54,7 @@ describe('Entry observations path', () => { it('should make sure the second observation type was saved correctly', async() => { const result = await page.waitToGetProperty(selectors.entryObservations.secondObservationType, 'value'); - expect(result).toEqual('delivery'); + expect(result).toEqual('Repartidor'); }); it('should make sure the second observation description was saved correctly', async() => { -- 2.40.1 From b902a4dd4a180d7a55403e991c7ebf8608ec7948 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Fri, 14 May 2021 19:56:54 +0200 Subject: [PATCH 08/13] front unit test fix --- modules/route/back/methods/route/getTickets.js | 2 +- modules/route/front/tickets/index.spec.js | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/modules/route/back/methods/route/getTickets.js b/modules/route/back/methods/route/getTickets.js index 3dfc5d73a..50227b810 100644 --- a/modules/route/back/methods/route/getTickets.js +++ b/modules/route/back/methods/route/getTickets.js @@ -72,7 +72,7 @@ module.exports = Self => { const tickets = await conn.executeStmt(stmt, myOptions); - if (tickets.length === 1 && !tickets[0].id) return; + if (tickets.length === 1 && !tickets[0].id) return []; return tickets; }; diff --git a/modules/route/front/tickets/index.spec.js b/modules/route/front/tickets/index.spec.js index 77618e2e7..1fcf92448 100644 --- a/modules/route/front/tickets/index.spec.js +++ b/modules/route/front/tickets/index.spec.js @@ -13,7 +13,10 @@ describe('Route', () => { const $element = angular.element(''); controller = $componentController('vnRouteTickets', {$element, $scope}); controller.route = {id: 1}; - controller.$.model = {refresh: () => {}}; + controller.$.model = { + refresh: () => {}, + remove: () => {} + }; controller.card = {reload: () => {}}; })); @@ -98,11 +101,9 @@ describe('Route', () => { { id: 1, checked: true, - address: { - street: 'my street', - postalCode: 'n19', - city: 'London' - } + street: 'my street', + postalCode: 'n19', + city: 'London' }, ]; @@ -130,6 +131,8 @@ describe('Route', () => { it('should perform a patch query then call showSuccess and updateVolume methods', () => { jest.spyOn(controller, 'updateVolume').mockReturnThis(); jest.spyOn(controller.vnApp, 'showSuccess'); + jest.spyOn(controller.$.model, 'remove'); + let ticketId = 1; controller.selectedTicket = ticketId; -- 2.40.1 From e848b94859fc8b2ddd9640cb89d39c710254d8ae Mon Sep 17 00:00:00 2001 From: carlosjr Date: Mon, 17 May 2021 09:42:48 +0200 Subject: [PATCH 09/13] removed LEFT from join --- modules/route/back/methods/route/getTickets.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/route/back/methods/route/getTickets.js b/modules/route/back/methods/route/getTickets.js index 50227b810..5705d8905 100644 --- a/modules/route/back/methods/route/getTickets.js +++ b/modules/route/back/methods/route/getTickets.js @@ -50,7 +50,7 @@ module.exports = Self => { u.nickname AS userNickname, vn.ticketTotalVolume(t.id) AS volume FROM route r - LEFT JOIN ticket t ON t.routeFk = r.id + JOIN ticket t ON t.routeFk = r.id LEFT JOIN ticketState ts ON ts.ticketFk = t.id LEFT JOIN state st ON st.id = ts.stateFk LEFT JOIN warehouse wh ON wh.id = t.warehouseFk @@ -72,8 +72,6 @@ module.exports = Self => { const tickets = await conn.executeStmt(stmt, myOptions); - if (tickets.length === 1 && !tickets[0].id) return []; - return tickets; }; }; -- 2.40.1 From bdcd05ee14dc5ecb27e36c3c525960017422fd8e Mon Sep 17 00:00:00 2001 From: carlosjr Date: Mon, 17 May 2021 10:30:39 +0200 Subject: [PATCH 10/13] removed commented code and the keep file --- db/changes/10320-monitors/.keep | 1 - .../10320-monitors/00-ticket_componentMakeUpdate.sql | 8 -------- 2 files changed, 9 deletions(-) delete mode 100644 db/changes/10320-monitors/.keep diff --git a/db/changes/10320-monitors/.keep b/db/changes/10320-monitors/.keep deleted file mode 100644 index 3a94d75a8..000000000 --- a/db/changes/10320-monitors/.keep +++ /dev/null @@ -1 +0,0 @@ -Delete me \ No newline at end of file diff --git a/db/changes/10320-monitors/00-ticket_componentMakeUpdate.sql b/db/changes/10320-monitors/00-ticket_componentMakeUpdate.sql index d21a0ed09..242b09d34 100644 --- a/db/changes/10320-monitors/00-ticket_componentMakeUpdate.sql +++ b/db/changes/10320-monitors/00-ticket_componentMakeUpdate.sql @@ -29,16 +29,9 @@ BEGIN */ DECLARE vPrice DECIMAL(10,2); DECLARE vBonus DECIMAL(10,2); -# DECLARE EXIT HANDLER FOR SQLEXCEPTION -# BEGIN -# ROLLBACK; -# RESIGNAL; -# END; CALL ticket_componentPreview (vTicketFk, vLanded, vAddressFk, vZoneFk, vWarehouseFk); -# START TRANSACTION; - IF (SELECT addressFk FROM ticket WHERE id = vTicketFk) <> vAddressFk THEN UPDATE ticket t @@ -92,7 +85,6 @@ BEGIN DROP TEMPORARY TABLE tmp.sale; DROP TEMPORARY TABLE IF EXISTS tmp.ticketComponent; END IF; -# COMMIT; DROP TEMPORARY TABLE tmp.zoneGetShipped, tmp.ticketComponentPreview; END;;$$ -- 2.40.1 From f0fbb13af8b0cbc839fea66cc05f0c8af0c421bf Mon Sep 17 00:00:00 2001 From: carlosjr Date: Mon, 17 May 2021 10:38:53 +0200 Subject: [PATCH 11/13] fixtures to english changes + e2e amends --- db/dump/fixtures.sql | 12 ++++++------ e2e/paths/02-client/06_add_address_notes.spec.js | 2 +- e2e/paths/05-ticket/01_observations.spec.js | 4 ++-- e2e/paths/05-ticket/17_log.spec.js | 2 +- e2e/paths/12-entry/06_observations.spec.js | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 7239fb3b7..55d962330 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -410,12 +410,12 @@ INSERT INTO `vn`.`clientObservation`(`id`, `clientFk`, `workerFk`, `text`, `crea INSERT INTO `vn`.`observationType`(`id`,`description`, `code`) VALUES - (1, 'Sacador', 'itemPicker'), - (2, 'Encajador', 'packager'), - (3, 'Repartidor', 'delivery'), - (4, 'Comercial', 'salesPerson'), - (5, 'Administración', 'administrative'), - (6, 'Peso Aduana', 'weight'); + (1, 'ItemPicker', 'itemPicker'), + (2, 'Packager', 'packager'), + (3, 'Delivery', 'delivery'), + (4, 'SalesPerson', 'salesPerson'), + (5, 'Administrative', 'administrative'), + (6, 'Weight', 'weight'); INSERT INTO `vn`.`addressObservation`(`id`,`addressFk`,`observationTypeFk`,`description`) VALUES diff --git a/e2e/paths/02-client/06_add_address_notes.spec.js b/e2e/paths/02-client/06_add_address_notes.spec.js index 8c1f93749..8ed9a0f28 100644 --- a/e2e/paths/02-client/06_add_address_notes.spec.js +++ b/e2e/paths/02-client/06_add_address_notes.spec.js @@ -43,7 +43,7 @@ describe('Client add address notes path', () => { it('should create two new observations', async() => { await page.write(selectors.clientAddresses.firstObservationDescription, 'first description'); await page.waitToClick(selectors.clientAddresses.addObservationButton); - await page.autocompleteSearch(selectors.clientAddresses.secondObservationType, 'Sacador'); + await page.autocompleteSearch(selectors.clientAddresses.secondObservationType, 'ItemPicker'); await page.write(selectors.clientAddresses.secondObservationDescription, 'second description'); await page.waitToClick(selectors.clientAddresses.saveButton); const message = await page.waitForSnackbar(); diff --git a/e2e/paths/05-ticket/01_observations.spec.js b/e2e/paths/05-ticket/01_observations.spec.js index ec00a7122..45b4ebb3e 100644 --- a/e2e/paths/05-ticket/01_observations.spec.js +++ b/e2e/paths/05-ticket/01_observations.spec.js @@ -19,7 +19,7 @@ describe('Ticket Create notes path', () => { it('should create a new note', async() => { await page.waitToClick(selectors.ticketNotes.addNoteButton); - await page.autocompleteSearch(selectors.ticketNotes.firstNoteType, 'sacador'); + await page.autocompleteSearch(selectors.ticketNotes.firstNoteType, 'ItemPicker'); await page.write(selectors.ticketNotes.firstDescription, 'description'); await page.waitToClick(selectors.ticketNotes.submitNotesButton); const message = await page.waitForSnackbar(); @@ -32,7 +32,7 @@ describe('Ticket Create notes path', () => { const result = await page .waitToGetProperty(selectors.ticketNotes.firstNoteType, 'value'); - expect(result).toEqual('Sacador'); + expect(result).toEqual('ItemPicker'); const firstDescription = await page .waitToGetProperty(selectors.ticketNotes.firstDescription, 'value'); diff --git a/e2e/paths/05-ticket/17_log.spec.js b/e2e/paths/05-ticket/17_log.spec.js index a37a3f307..399eb647b 100644 --- a/e2e/paths/05-ticket/17_log.spec.js +++ b/e2e/paths/05-ticket/17_log.spec.js @@ -24,7 +24,7 @@ describe('Ticket log path', () => { it('should create a new note for the test', async() => { await page.waitToClick(selectors.ticketNotes.addNoteButton); - await page.autocompleteSearch(selectors.ticketNotes.firstNoteType, 'Sacador'); + await page.autocompleteSearch(selectors.ticketNotes.firstNoteType, 'ItemPicker'); await page.write(selectors.ticketNotes.firstDescription, 'description'); await page.waitToClick(selectors.ticketNotes.submitNotesButton); const message = await page.waitForSnackbar(); diff --git a/e2e/paths/12-entry/06_observations.spec.js b/e2e/paths/12-entry/06_observations.spec.js index f2dd93a03..b1a9f268a 100644 --- a/e2e/paths/12-entry/06_observations.spec.js +++ b/e2e/paths/12-entry/06_observations.spec.js @@ -31,7 +31,7 @@ describe('Entry observations path', () => { }); it('should set the 2nd observation of a different one and successfully save both', async() => { - await page.autocompleteSearch(selectors.entryObservations.secondObservationType, 'repartidor'); + await page.autocompleteSearch(selectors.entryObservations.secondObservationType, 'Delivery'); await page.waitToClick(selectors.entryObservations.saveObservationsButton); const message = await page.waitForSnackbar(); @@ -54,7 +54,7 @@ describe('Entry observations path', () => { it('should make sure the second observation type was saved correctly', async() => { const result = await page.waitToGetProperty(selectors.entryObservations.secondObservationType, 'value'); - expect(result).toEqual('Repartidor'); + expect(result).toEqual('Delivery'); }); it('should make sure the second observation description was saved correctly', async() => { -- 2.40.1 From 54d75e0e54f982c321445524f09ca7674c26e663 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Mon, 17 May 2021 11:08:00 +0200 Subject: [PATCH 12/13] e2e amends for salesPerson --- e2e/paths/02-client/06_add_address_notes.spec.js | 2 +- e2e/paths/12-entry/06_observations.spec.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/e2e/paths/02-client/06_add_address_notes.spec.js b/e2e/paths/02-client/06_add_address_notes.spec.js index 8ed9a0f28..c6837cc38 100644 --- a/e2e/paths/02-client/06_add_address_notes.spec.js +++ b/e2e/paths/02-client/06_add_address_notes.spec.js @@ -33,7 +33,7 @@ describe('Client add address notes path', () => { it('should not save an observation type without description', async() => { await page.clearInput(selectors.clientAddresses.firstObservationDescription); - await page.autocompleteSearch(selectors.clientAddresses.firstObservationType, 'comercial'); + await page.autocompleteSearch(selectors.clientAddresses.firstObservationType, 'SalesPerson'); await page.waitToClick(selectors.clientAddresses.saveButton); const message = await page.waitForSnackbar(); diff --git a/e2e/paths/12-entry/06_observations.spec.js b/e2e/paths/12-entry/06_observations.spec.js index b1a9f268a..c686d999a 100644 --- a/e2e/paths/12-entry/06_observations.spec.js +++ b/e2e/paths/12-entry/06_observations.spec.js @@ -20,8 +20,8 @@ describe('Entry observations path', () => { it(`should add two new observations of the same type then fail to save as they can't be repeated`, async() => { await page.waitToClick(selectors.entryObservations.addNewObservation); await page.waitToClick(selectors.entryObservations.addNewObservation); - await page.autocompleteSearch(selectors.entryObservations.firstObservationType, 'comercial'); - await page.autocompleteSearch(selectors.entryObservations.secondObservationType, 'comercial'); + await page.autocompleteSearch(selectors.entryObservations.firstObservationType, 'SalesPerson'); + await page.autocompleteSearch(selectors.entryObservations.secondObservationType, 'SalesPerson'); await page.write(selectors.entryObservations.firstObservationDescription, 'first observation'); await page.write(selectors.entryObservations.secondObservationDescription, 'second observation'); await page.waitToClick(selectors.entryObservations.saveObservationsButton); @@ -42,7 +42,7 @@ describe('Entry observations path', () => { await page.reloadSection('entry.card.observation'); const result = await page.waitToGetProperty(selectors.entryObservations.firstObservationType, 'value'); - expect(result).toEqual('Comercial'); + expect(result).toEqual('SalesPerson'); }); it('should make sure the first observation description was saved correctly', async() => { -- 2.40.1 From 5843140cf5bc907f329959142f0e4fa30537c6d5 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Mon, 17 May 2021 12:27:26 +0200 Subject: [PATCH 13/13] minor refactor for code usage instead of description --- .../back/methods/claim-beginning/importToNewRefundTicket.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/claim/back/methods/claim-beginning/importToNewRefundTicket.js b/modules/claim/back/methods/claim-beginning/importToNewRefundTicket.js index 293aae012..0e358678e 100644 --- a/modules/claim/back/methods/claim-beginning/importToNewRefundTicket.js +++ b/modules/claim/back/methods/claim-beginning/importToNewRefundTicket.js @@ -79,7 +79,7 @@ module.exports = Self => { }, myOptions); const obsevationType = await models.ObservationType.findOne({ - where: {description: 'comercial'} + where: {code: 'salesPerson'} }, myOptions); const agencyMode = await models.AgencyMode.findOne({ -- 2.40.1