#1475 no borrar servicios de tickets no editables
This commit is contained in:
parent
2c012b084a
commit
40654f94c4
|
@ -117,7 +117,7 @@ describe('Client balance path', () => {
|
||||||
let result = await nightmare
|
let result = await nightmare
|
||||||
.waitToGetProperty(selectors.clientBalance.firstBalanceLine, 'innerText');
|
.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() => {
|
it('should now click on the Clients button of the top bar menu', async() => {
|
||||||
|
|
|
@ -3,13 +3,13 @@ import createNightmare from '../../helpers/nightmare';
|
||||||
|
|
||||||
describe('Ticket services path', () => {
|
describe('Ticket services path', () => {
|
||||||
const nightmare = createNightmare();
|
const nightmare = createNightmare();
|
||||||
const invoiceTicketId = 10;
|
const invoicedTicketId = 10;
|
||||||
|
|
||||||
describe('as employee', () => {
|
describe('as employee', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
nightmare
|
nightmare
|
||||||
.loginAndModule('employee', 'ticket')
|
.loginAndModule('employee', 'ticket')
|
||||||
.accessToSearchResult(invoiceTicketId)
|
.accessToSearchResult(invoicedTicketId)
|
||||||
.accessToSection('ticket.card.service');
|
.accessToSection('ticket.card.service');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -31,15 +31,16 @@ describe('Ticket services path', () => {
|
||||||
.waitToClick(selectors.ticketService.saveServiceButton)
|
.waitToClick(selectors.ticketService.saveServiceButton)
|
||||||
.waitForLastSnackbar();
|
.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', () => {
|
describe('as administrative', () => {
|
||||||
|
let editableTicketId = 13;
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
nightmare
|
nightmare
|
||||||
.loginAndModule('administrative', 'ticket')
|
.loginAndModule('administrative', 'ticket')
|
||||||
.accessToSearchResult(13)
|
.accessToSearchResult(editableTicketId)
|
||||||
.accessToSection('ticket.card.service');
|
.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() => {
|
it('should create a new description then add price then create the service', async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.waitToClick(selectors.ticketService.firstAddDescriptionButton)
|
|
||||||
.write(selectors.ticketService.newDescriptionInput, 'accurate description')
|
.write(selectors.ticketService.newDescriptionInput, 'accurate description')
|
||||||
.waitToClick(selectors.ticketService.saveDescriptionButton)
|
.waitToClick(selectors.ticketService.saveDescriptionButton)
|
||||||
.write(selectors.ticketService.firstPriceInput, 999)
|
.write(selectors.ticketService.firstPriceInput, 999)
|
||||||
|
@ -127,7 +127,7 @@ describe('Ticket services path', () => {
|
||||||
expect(result).toEqual('Data saved!');
|
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
|
const result = await nightmare
|
||||||
.reloadSection('ticket.card.service')
|
.reloadSection('ticket.card.service')
|
||||||
.waitForNumberOfElements(selectors.ticketService.serviceLine, 0)
|
.waitForNumberOfElements(selectors.ticketService.serviceLine, 0)
|
||||||
|
|
|
@ -44,5 +44,5 @@
|
||||||
"Invalid TIN": "Invalid Tax number",
|
"Invalid TIN": "Invalid Tax number",
|
||||||
"This ticket can't be invoiced": "This ticket can't be invoiced",
|
"This ticket can't be invoiced": "This ticket can't be invoiced",
|
||||||
"The value should be a number": "The value should be a number",
|
"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"
|
||||||
}
|
}
|
|
@ -85,5 +85,6 @@
|
||||||
"INFINITE_LOOP": "Existe una dependencia entre dos Jefes",
|
"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 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",
|
"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"
|
||||||
}
|
}
|
|
@ -41,7 +41,7 @@ export default class Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
onPassChange(response) {
|
onPassChange(response) {
|
||||||
if (response == 'ACCEPT')
|
if (response == 'ACCEPT') {
|
||||||
try {
|
try {
|
||||||
if (!this.newPassword)
|
if (!this.newPassword)
|
||||||
throw new Error(`Passwords can't be empty`);
|
throw new Error(`Passwords can't be empty`);
|
||||||
|
@ -56,6 +56,7 @@ export default class Controller {
|
||||||
this.vnApp.showError(this.$translate.instant(e.message));
|
this.vnApp.showError(this.$translate.instant(e.message));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,9 +24,8 @@ module.exports = Self => {
|
||||||
where: {ticketFk: ticketFk}
|
where: {ticketFk: ticketFk}
|
||||||
});
|
});
|
||||||
let alertLevel = state ? state.alertLevel : null;
|
let alertLevel = state ? state.alertLevel : null;
|
||||||
let exists = await Self.app.models.Ticket.findOne({
|
let ticket = await Self.app.models.Ticket.findById(ticketFk, {
|
||||||
where: {id: ticketFk},
|
fields: ['isDeleted', 'clientFk', 'refFk'],
|
||||||
fields: ['isDeleted', 'clientFk'],
|
|
||||||
include: [{
|
include: [{
|
||||||
relation: 'client',
|
relation: 'client',
|
||||||
scope: {
|
scope: {
|
||||||
|
@ -37,10 +36,12 @@ module.exports = Self => {
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exists && exists.client().type().code !== 'normal')
|
const isDeleted = ticket && ticket.isDeleted;
|
||||||
return true;
|
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 false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -5,9 +5,18 @@ module.exports = Self => {
|
||||||
let changes = ctx.currentInstance || ctx.instance;
|
let changes = ctx.currentInstance || ctx.instance;
|
||||||
if (changes) {
|
if (changes) {
|
||||||
let ticketId = changes.ticketFk;
|
let ticketId = changes.ticketFk;
|
||||||
let ticket = await Self.app.models.Ticket.findById(ticketId);
|
let isEditable = await Self.app.models.Ticket.isEditable(ticketId);
|
||||||
if (ticket.refFk)
|
if (!isEditable)
|
||||||
throw new UserError('You cannot add or modify services to an invoiced ticket');
|
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`);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,8 +7,7 @@
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<vn-watcher
|
<vn-watcher
|
||||||
vn-id="watcher"
|
vn-id="watcher"
|
||||||
data="$ctrl.services"
|
data="$ctrl.services">
|
||||||
form="form">
|
|
||||||
</vn-watcher>
|
</vn-watcher>
|
||||||
<form name="form" ng-submit="$ctrl.onSubmit()" compact>
|
<form name="form" ng-submit="$ctrl.onSubmit()" compact>
|
||||||
<vn-card pad-large>
|
<vn-card pad-large>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import ngModule from '../module';
|
import ngModule from '../module';
|
||||||
|
import UserError from 'core/lib/user-error';
|
||||||
|
|
||||||
class Controller {
|
class Controller {
|
||||||
constructor($http, $scope, $stateParams, vnApp, $translate, $element) {
|
constructor($http, $scope, $stateParams, vnApp, $translate, $element) {
|
||||||
|
@ -53,22 +54,18 @@ class Controller {
|
||||||
|
|
||||||
onNewServiceTypeResponse(response) {
|
onNewServiceTypeResponse(response) {
|
||||||
if (response == 'ACCEPT') {
|
if (response == 'ACCEPT') {
|
||||||
try {
|
if (!this.newServiceType.name)
|
||||||
if (!this.newServiceType.name)
|
throw new UserError(`Name can't be empty`);
|
||||||
throw new Error(`Name can't be empty`);
|
|
||||||
|
|
||||||
this.$http.post(`/api/TicketServiceTypes`, this.newServiceType).then(response => {
|
this.$http.post(`/api/TicketServiceTypes`, this.newServiceType).then(response => {
|
||||||
this.services[this.currentServiceIndex].description = response.data.name;
|
this.services[this.currentServiceIndex].description = response.data.name;
|
||||||
});
|
});
|
||||||
} catch (err) {
|
|
||||||
this.vnApp.showError(this.$translate.instant(err.message));
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
this.$scope.watcher.check();
|
this.$scope.watcher.check();
|
||||||
|
|
||||||
this.$scope.model.save().then(() => {
|
this.$scope.model.save().then(() => {
|
||||||
this.$scope.watcher.notifySaved();
|
this.$scope.watcher.notifySaved();
|
||||||
this.$scope.model.refresh();
|
this.$scope.model.refresh();
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import './index.js';
|
import './index.js';
|
||||||
|
import UserError from 'core/lib/user-error';
|
||||||
|
|
||||||
describe('Ticket component vnTicketService', () => {
|
describe('Ticket component vnTicketService', () => {
|
||||||
let controller;
|
let controller;
|
||||||
|
@ -38,11 +39,17 @@ describe('Ticket component vnTicketService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('onNewServiceTypeResponse', () => {
|
describe('onNewServiceTypeResponse', () => {
|
||||||
it(`should throw an error`, () => {
|
it(`should throw an error if the new service description is empty`, () => {
|
||||||
controller.newServiceType = {name: undefined};
|
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', () => {
|
it('should set the description of the selected service upon service type creation', () => {
|
||||||
|
|
Loading…
Reference in New Issue