From 40654f94c416758483a17cb40cae44997e2f7b4e Mon Sep 17 00:00:00 2001 From: Carlos Jimenez Ruiz Date: Wed, 29 May 2019 13:06:42 +0200 Subject: [PATCH] #1475 no borrar servicios de tickets no editables --- e2e/paths/02-client-module/14_balance.spec.js | 2 +- e2e/paths/05-ticket-module/13_services.spec.js | 12 ++++++------ loopback/locale/en.json | 2 +- loopback/locale/es.json | 3 ++- modules/client/front/web-access/index.js | 3 ++- .../ticket/back/methods/ticket/isEditable.js | 13 +++++++------ modules/ticket/back/models/ticket-service.js | 15 ++++++++++++--- modules/ticket/front/services/index.html | 3 +-- modules/ticket/front/services/index.js | 17 +++++++---------- modules/ticket/front/services/index.spec.js | 13 ++++++++++--- 10 files changed, 49 insertions(+), 34 deletions(-) diff --git a/e2e/paths/02-client-module/14_balance.spec.js b/e2e/paths/02-client-module/14_balance.spec.js index b03f0410a..e01840fb4 100644 --- a/e2e/paths/02-client-module/14_balance.spec.js +++ b/e2e/paths/02-client-module/14_balance.spec.js @@ -117,7 +117,7 @@ describe('Client balance path', () => { let result = await nightmare .waitToGetProperty(selectors.clientBalance.firstBalanceLine, 'innerText'); - expect(result).toContain('50'); + expect(result).toEqual('€50.00'); }); it('should now click on the Clients button of the top bar menu', async() => { diff --git a/e2e/paths/05-ticket-module/13_services.spec.js b/e2e/paths/05-ticket-module/13_services.spec.js index 38c0d31da..ab98a36bb 100644 --- a/e2e/paths/05-ticket-module/13_services.spec.js +++ b/e2e/paths/05-ticket-module/13_services.spec.js @@ -3,13 +3,13 @@ import createNightmare from '../../helpers/nightmare'; describe('Ticket services path', () => { const nightmare = createNightmare(); - const invoiceTicketId = 10; + const invoicedTicketId = 10; describe('as employee', () => { beforeAll(() => { nightmare .loginAndModule('employee', 'ticket') - .accessToSearchResult(invoiceTicketId) + .accessToSearchResult(invoicedTicketId) .accessToSection('ticket.card.service'); }); @@ -31,15 +31,16 @@ describe('Ticket services path', () => { .waitToClick(selectors.ticketService.saveServiceButton) .waitForLastSnackbar(); - expect(result).toEqual('You cannot add or modify services to an invoiced ticket'); + expect(result).toEqual(`The current ticket can't be modified`); }); }); describe('as administrative', () => { + let editableTicketId = 13; beforeAll(() => { nightmare .loginAndModule('administrative', 'ticket') - .accessToSearchResult(13) + .accessToSearchResult(editableTicketId) .accessToSection('ticket.card.service'); }); @@ -78,7 +79,6 @@ describe('Ticket services path', () => { it('should create a new description then add price then create the service', async() => { const result = await nightmare - .waitToClick(selectors.ticketService.firstAddDescriptionButton) .write(selectors.ticketService.newDescriptionInput, 'accurate description') .waitToClick(selectors.ticketService.saveDescriptionButton) .write(selectors.ticketService.firstPriceInput, 999) @@ -127,7 +127,7 @@ describe('Ticket services path', () => { expect(result).toEqual('Data saved!'); }); - it('should confirm the service was sucessfully removed', async() => { + it(`should confirm the service wasn't sucessfully removed`, async() => { const result = await nightmare .reloadSection('ticket.card.service') .waitForNumberOfElements(selectors.ticketService.serviceLine, 0) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index ddb77beee..e6212f57e 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -44,5 +44,5 @@ "Invalid TIN": "Invalid Tax number", "This ticket can't be invoiced": "This ticket can't be invoiced", "The value should be a number": "The value should be a number", - "You cannot add or modify services to an invoiced ticket": "You cannot add or modify services to an invoiced ticket" + "The current ticket can't be modified": "The current ticket can't be modified" } \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index b8dec397f..58582d087 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -85,5 +85,6 @@ "INFINITE_LOOP": "Existe una dependencia entre dos Jefes", "The sales of the current ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas", "The sales of the receiver ticket can't be modified": "Las lineas del ticket al que envias no pueden ser modificadas", - "NO_AGENCY_AVAILABLE": "No hay agencias disponibles" + "NO_AGENCY_AVAILABLE": "No hay agencias disponibles", + "The current ticket can't be modified": "El ticket actual no puede ser modificado" } \ No newline at end of file diff --git a/modules/client/front/web-access/index.js b/modules/client/front/web-access/index.js index ef1ccd16c..5e7510853 100644 --- a/modules/client/front/web-access/index.js +++ b/modules/client/front/web-access/index.js @@ -41,7 +41,7 @@ export default class Controller { } onPassChange(response) { - if (response == 'ACCEPT') + if (response == 'ACCEPT') { try { if (!this.newPassword) throw new Error(`Passwords can't be empty`); @@ -56,6 +56,7 @@ export default class Controller { this.vnApp.showError(this.$translate.instant(e.message)); return false; } + } return true; } diff --git a/modules/ticket/back/methods/ticket/isEditable.js b/modules/ticket/back/methods/ticket/isEditable.js index 95805948a..b8cb9e181 100644 --- a/modules/ticket/back/methods/ticket/isEditable.js +++ b/modules/ticket/back/methods/ticket/isEditable.js @@ -24,9 +24,8 @@ module.exports = Self => { where: {ticketFk: ticketFk} }); let alertLevel = state ? state.alertLevel : null; - let exists = await Self.app.models.Ticket.findOne({ - where: {id: ticketFk}, - fields: ['isDeleted', 'clientFk'], + let ticket = await Self.app.models.Ticket.findById(ticketFk, { + fields: ['isDeleted', 'clientFk', 'refFk'], include: [{ relation: 'client', scope: { @@ -37,10 +36,12 @@ module.exports = Self => { }] }); - if (exists && exists.client().type().code !== 'normal') - return true; + const isDeleted = ticket && ticket.isDeleted; + const isOnDelivery = (alertLevel && alertLevel > 0); + const isNotNormalClient = ticket && ticket.client().type().code == 'normal'; + const isInvoiced = ticket && ticket.refFk; - if (!exists || exists.isDeleted == 1 || (alertLevel && alertLevel > 0)) + if (!ticket || ((isDeleted || isOnDelivery) && isNotNormalClient) || isInvoiced) return false; return true; diff --git a/modules/ticket/back/models/ticket-service.js b/modules/ticket/back/models/ticket-service.js index 751885116..aab6b4f34 100644 --- a/modules/ticket/back/models/ticket-service.js +++ b/modules/ticket/back/models/ticket-service.js @@ -5,9 +5,18 @@ module.exports = Self => { let changes = ctx.currentInstance || ctx.instance; if (changes) { let ticketId = changes.ticketFk; - let ticket = await Self.app.models.Ticket.findById(ticketId); - if (ticket.refFk) - throw new UserError('You cannot add or modify services to an invoiced ticket'); + let isEditable = await Self.app.models.Ticket.isEditable(ticketId); + if (!isEditable) + throw new UserError(`The current ticket can't be modified`); } }); + + Self.observe('before delete', async ctx => { + const models = Self.app.models; + const service = await models.TicketService.findById(ctx.where.id); + const isEditable = await Self.app.models.Ticket.isEditable(service.ticketFk); + + if (!isEditable) + throw new UserError(`The current ticket can't be modified`); + }); }; diff --git a/modules/ticket/front/services/index.html b/modules/ticket/front/services/index.html index 94ff67868..dc7f5b92c 100644 --- a/modules/ticket/front/services/index.html +++ b/modules/ticket/front/services/index.html @@ -7,8 +7,7 @@ + data="$ctrl.services">
diff --git a/modules/ticket/front/services/index.js b/modules/ticket/front/services/index.js index c576ccbda..8d2566948 100644 --- a/modules/ticket/front/services/index.js +++ b/modules/ticket/front/services/index.js @@ -1,4 +1,5 @@ import ngModule from '../module'; +import UserError from 'core/lib/user-error'; class Controller { constructor($http, $scope, $stateParams, vnApp, $translate, $element) { @@ -53,22 +54,18 @@ class Controller { onNewServiceTypeResponse(response) { if (response == 'ACCEPT') { - try { - if (!this.newServiceType.name) - throw new Error(`Name can't be empty`); + if (!this.newServiceType.name) + throw new UserError(`Name can't be empty`); - this.$http.post(`/api/TicketServiceTypes`, this.newServiceType).then(response => { - this.services[this.currentServiceIndex].description = response.data.name; - }); - } catch (err) { - this.vnApp.showError(this.$translate.instant(err.message)); - return err; - } + this.$http.post(`/api/TicketServiceTypes`, this.newServiceType).then(response => { + this.services[this.currentServiceIndex].description = response.data.name; + }); } } onSubmit() { this.$scope.watcher.check(); + this.$scope.model.save().then(() => { this.$scope.watcher.notifySaved(); this.$scope.model.refresh(); diff --git a/modules/ticket/front/services/index.spec.js b/modules/ticket/front/services/index.spec.js index 209459789..410b7a090 100644 --- a/modules/ticket/front/services/index.spec.js +++ b/modules/ticket/front/services/index.spec.js @@ -1,4 +1,5 @@ import './index.js'; +import UserError from 'core/lib/user-error'; describe('Ticket component vnTicketService', () => { let controller; @@ -38,11 +39,17 @@ describe('Ticket component vnTicketService', () => { }); describe('onNewServiceTypeResponse', () => { - it(`should throw an error`, () => { + it(`should throw an error if the new service description is empty`, () => { controller.newServiceType = {name: undefined}; - let error = controller.onNewServiceTypeResponse('ACCEPT'); - expect(error.message).toEqual(`Name can't be empty`); + let error; + try { + controller.onNewServiceTypeResponse('ACCEPT'); + } catch (e) { + error = e.message; + } + + expect(error).toBe(`Name can't be empty`); }); it('should set the description of the selected service upon service type creation', () => {