From f64a566447f251edc02b7c8d6d27a4ff8f7600a8 Mon Sep 17 00:00:00 2001 From: bernat Date: Fri, 20 Nov 2020 12:12:06 +0100 Subject: [PATCH 1/2] route.ticket drag and drop validation --- .../methods/route/specs/ticketToRoute.spec.js | 52 +++++++++++++++++++ .../route/back/methods/route/ticketToRoute.js | 51 ++++++++++++++++++ modules/route/back/models/route.js | 5 +- modules/route/front/tickets/index.js | 6 ++- modules/route/front/tickets/index.spec.js | 4 +- modules/route/front/tickets/locale/es.yml | 3 +- .../methods/zone/specs/deleteZone.spec.js | 5 ++ 7 files changed, 118 insertions(+), 8 deletions(-) create mode 100644 modules/route/back/methods/route/specs/ticketToRoute.spec.js create mode 100644 modules/route/back/methods/route/ticketToRoute.js diff --git a/modules/route/back/methods/route/specs/ticketToRoute.spec.js b/modules/route/back/methods/route/specs/ticketToRoute.spec.js new file mode 100644 index 000000000..86206ab42 --- /dev/null +++ b/modules/route/back/methods/route/specs/ticketToRoute.spec.js @@ -0,0 +1,52 @@ +const app = require('vn-loopback/server/server'); +const LoopBackContext = require('loopback-context'); + +describe('route ticketToRoute()', () => { + const deliveryId = 56; + let originalTicket; + const routeId = 2; + const activeCtx = { + accessToken: {userId: deliveryId}, + }; + + beforeAll(async done => { + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + + done(); + }); + + afterAll(async done => { + try { + await originalTicket.updateAttribute('routeFk', null); + } catch (error) { + console.error(error); + } + done(); + }); + + it('should add the ticket in a route', async() => { + originalTicket = await app.models.Ticket.findById(14); + + const ticketId = 14; + const result = await app.models.Route.ticketToRoute(ticketId, routeId); + + expect(result.routeFk).toEqual(2); + }); + + it('should throw and error if the ticket is not suitable for the route', async() => { + const ticketId = 23; + let error; + + try { + await app.models.Route.ticketToRoute(ticketId, routeId); + } catch (e) { + error = e.message; + } + + expect(error).toBeDefined(); + expect(error).toEqual('The selected ticket is not suitable for this route'); + }); +}); + diff --git a/modules/route/back/methods/route/ticketToRoute.js b/modules/route/back/methods/route/ticketToRoute.js new file mode 100644 index 000000000..93b270015 --- /dev/null +++ b/modules/route/back/methods/route/ticketToRoute.js @@ -0,0 +1,51 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethod('ticketToRoute', { + description: 'Check if the ticket can be insert into the route and insert it', + accessType: 'READ', + accepts: [{ + arg: 'ticketId', + type: 'number', + required: true, + description: 'ticketId ', + http: {source: 'path'} + }, + { + arg: 'routeId', + type: 'number', + required: true + }], + returns: { + type: 'object', + root: true + }, + http: { + path: `/:ticketId/ticketToRoute`, + verb: 'PATCH' + } + }); + + Self.ticketToRoute = async(ticketId, routeId) => { + const models = Self.app.models; + + const route = await models.Route.findById(routeId); + const minDate = new Date(route.finished); + minDate.setHours(0, 0, 0, 0); + + const maxDate = new Date(route.finished); + maxDate.setHours(23, 59, 59, 59); + const ticket = await models.Ticket.findOne({ + where: { + id: ticketId, + zoneFk: route.zoneFk, + routeFk: null, + landed: {between: [minDate, maxDate]}, + } + }); + if (!ticket) + throw new UserError('The selected ticket is not suitable for this route'); + + return await ticket.updateAttribute('routeFk', route.id); + }; +}; diff --git a/modules/route/back/models/route.js b/modules/route/back/models/route.js index 6d93cfe40..cdb51c609 100644 --- a/modules/route/back/models/route.js +++ b/modules/route/back/models/route.js @@ -5,6 +5,7 @@ module.exports = Self => { require('../methods/route/guessPriority')(Self); require('../methods/route/updateVolume')(Self); require('../methods/route/getDeliveryPoint')(Self); + require('../methods/route/ticketToRoute')(Self); Self.validate('kmStart', validateDistance, { message: 'Distance must be lesser than 1000' @@ -17,9 +18,7 @@ module.exports = Self => { function validateDistance(err) { const routeTotalKm = this.kmEnd - this.kmStart; const routeMaxKm = 1000; - if ( routeTotalKm > routeMaxKm || this.kmStart > this.kmEnd) + if (routeTotalKm > routeMaxKm || this.kmStart > this.kmEnd) err(); } }; - - diff --git a/modules/route/front/tickets/index.js b/modules/route/front/tickets/index.js index a811d6d88..49ca8d60f 100644 --- a/modules/route/front/tickets/index.js +++ b/modules/route/front/tickets/index.js @@ -162,8 +162,10 @@ class Controller extends Section { } insert(id) { - const params = {routeFk: this.route.id}; - this.$http.patch(`Tickets/${id}`, params).then(() => { + const params = {routeId: this.route.id}; + const query = `Routes/${id}/ticketToRoute`; + + return this.$http.patch(query, params).then(() => { this.vnApp.showSuccess(this.$t('Data saved!')); this.$.model.refresh(); this.card.reload(); diff --git a/modules/route/front/tickets/index.spec.js b/modules/route/front/tickets/index.spec.js index a32b368ba..a1b9229b7 100644 --- a/modules/route/front/tickets/index.spec.js +++ b/modules/route/front/tickets/index.spec.js @@ -309,8 +309,8 @@ describe('Route', () => { jest.spyOn(controller.vnApp, 'showSuccess'); const ticketId = 11; - - $httpBackend.expect('PATCH', `Tickets/11`).respond({id: 11}); + const data = {routeId: 1}; + $httpBackend.expect('PATCH', `Routes/11/ticketToRoute`, data).respond(); controller.insert(ticketId); $httpBackend.flush(); diff --git a/modules/route/front/tickets/locale/es.yml b/modules/route/front/tickets/locale/es.yml index b9892a299..836dfe595 100644 --- a/modules/route/front/tickets/locale/es.yml +++ b/modules/route/front/tickets/locale/es.yml @@ -6,4 +6,5 @@ Delete ticket from route?: ¿Quitar el ticket de la ruta? Sort routes: Ordenar rutas Add ticket: Añadir ticket Tickets to add: Tickets a añadir -Ticket not found: No se ha encontrado el ticket \ No newline at end of file +Ticket not found: No se ha encontrado el ticket +The selected ticket is not suitable for this route: El ticket seleccionado no es apto para esta ruta \ No newline at end of file diff --git a/modules/zone/back/methods/zone/specs/deleteZone.spec.js b/modules/zone/back/methods/zone/specs/deleteZone.spec.js index 8722837af..79d672f38 100644 --- a/modules/zone/back/methods/zone/specs/deleteZone.spec.js +++ b/modules/zone/back/methods/zone/specs/deleteZone.spec.js @@ -14,6 +14,7 @@ describe('zone deletezone()', () => { let ticketIDs; let originalZoneIncluded; let originalTicketStates; + let originalRoutes; beforeAll(async done => { spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ @@ -27,6 +28,7 @@ describe('zone deletezone()', () => { zoneFk: zoneId } }); + originalRoutes = await app.models.Route.find({where: {zoneFk: zoneId}}); ticketIDs = originalTickets.map(ticket => ticket.id); originalZoneIncluded = await app.models.ZoneIncluded.find({where: {zoneFk: zoneId}}); originalTicketStates = await app.models.TicketState.find({where: { @@ -44,6 +46,9 @@ describe('zone deletezone()', () => { await originalZone.save(); await app.models.ZoneWarehouse.create(originalZoneWarehouses); + for (route of originalRoutes) + await route.updateAttributes({zoneFk: zoneId}); + for (ticket of originalTickets) await ticket.updateAttributes({zoneFk: zoneId}); From 37ac312bd5ac190c74c4d32165f2af6713da3810 Mon Sep 17 00:00:00 2001 From: bernat Date: Mon, 23 Nov 2020 13:05:24 +0100 Subject: [PATCH 2/2] pr changes --- modules/route/back/methods/route/specs/ticketToRoute.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/route/back/methods/route/specs/ticketToRoute.spec.js b/modules/route/back/methods/route/specs/ticketToRoute.spec.js index 86206ab42..83c1d5080 100644 --- a/modules/route/back/methods/route/specs/ticketToRoute.spec.js +++ b/modules/route/back/methods/route/specs/ticketToRoute.spec.js @@ -26,7 +26,7 @@ describe('route ticketToRoute()', () => { done(); }); - it('should add the ticket in a route', async() => { + it('should add the ticket to a route', async() => { originalTicket = await app.models.Ticket.findById(14); const ticketId = 14;