Tarea #1562 ticket.line isEditable
gitea/salix/dev There was a failure building this commit Details

This commit is contained in:
Bernat 2019-07-22 13:14:00 +02:00
parent 85049c126b
commit 6a23a5429c
19 changed files with 113 additions and 60 deletions

View File

@ -27,12 +27,12 @@ module.exports = Self => {
let newTicketData = {};
let receiverTicket = params.receiverTicket;
let isCurrentTicketEditable = await models.Ticket.isEditable(params.currentTicket.currentTicketId);
let isCurrentTicketEditable = await models.Ticket.isEditable(ctx, params.currentTicket.currentTicketId);
if (!isCurrentTicketEditable)
throw new UserError(`The sales of the current ticket can't be modified`);
if (params.receiverTicket.id) {
let isReceiverTicketEditable = await models.Ticket.isEditable(params.receiverTicket.id);
let isReceiverTicketEditable = await models.Ticket.isEditable(ctx, params.receiverTicket.id);
if (!isReceiverTicketEditable)
throw new UserError(`The sales of the receiver ticket can't be modified`);
}

View File

@ -1,7 +1,7 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethod('priceDifference', {
Self.remoteMethodCtx('priceDifference', {
description: 'Returns sales with price difference if the ticket is editable',
accessType: 'READ',
accepts: [{
@ -27,8 +27,8 @@ module.exports = Self => {
}
});
Self.priceDifference = async(ticketFk, data) => {
let thisTicketIsEditable = await Self.app.models.Ticket.isEditable(ticketFk);
Self.priceDifference = async(ctx, ticketFk, data) => {
let thisTicketIsEditable = await Self.app.models.Ticket.isEditable(ctx, ticketFk);
if (!thisTicketIsEditable)
throw new UserError(`The sales of this ticket can't be modified`);

View File

@ -1,7 +1,7 @@
let UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethod('removes', {
Self.remoteMethodCtx('removes', {
description: 'Change the state of a ticket',
accessType: 'WRITE',
accepts: [{
@ -21,8 +21,8 @@ module.exports = Self => {
}
});
Self.removes = async params => {
let thisTicketIsEditable = await Self.app.models.Ticket.isEditable(params.actualTicketFk);
Self.removes = async(ctx, params) => {
let thisTicketIsEditable = await Self.app.models.Ticket.isEditable(ctx, params.actualTicketFk);
if (!thisTicketIsEditable)
throw new UserError(`The sales of this ticket can't be modified`);

View File

@ -2,7 +2,7 @@
let UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethod('reserve', {
Self.remoteMethodCtx('reserve', {
description: 'Change the state of a ticket',
accessType: 'WRITE',
accepts: [{
@ -22,8 +22,8 @@ module.exports = Self => {
}
});
Self.reserve = async params => {
let thisTicketIsEditable = await Self.app.models.Ticket.isEditable(params.ticketFk);
Self.reserve = async(ctx, params) => {
let thisTicketIsEditable = await Self.app.models.Ticket.isEditable(ctx, params.ticketFk);
if (!thisTicketIsEditable)
throw new UserError(`The sales of this ticket can't be modified`);

View File

@ -3,6 +3,7 @@ let UserError = require('vn-loopback/util/user-error');
describe('sale priceDifference()', () => {
it('should return ticket price differences', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
let data = {
@ -11,7 +12,7 @@ describe('sale priceDifference()', () => {
agencyModeFk: 7,
warehouseFk: 1
};
let result = await app.models.Sale.priceDifference(16, data);
let result = await app.models.Sale.priceDifference(ctx, 16, data);
expect(result.totalUnitPrice).toEqual(215.77);
expect(result.totalNewPrice).toEqual(215.77);
@ -19,6 +20,7 @@ describe('sale priceDifference()', () => {
});
it('should return an error if the ticket is not editable', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let error;
let data = {
landed: new Date(),
@ -26,7 +28,7 @@ describe('sale priceDifference()', () => {
agencyModeFk: 1,
warehouseFk: 1
};
await app.models.Sale.priceDifference(1, data)
await app.models.Sale.priceDifference(ctx, 1, data)
.catch(e => {
error = e;
});

View File

@ -13,6 +13,7 @@ describe('sale removes()', () => {
});
it('should throw an error if the ticket of the given sales is not editable', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let error;
let params = {
@ -21,7 +22,7 @@ describe('sale removes()', () => {
};
try {
await app.models.Sale.removes(params);
await app.models.Sale.removes(ctx, params);
} catch (e) {
error = e;
}
@ -30,12 +31,13 @@ describe('sale removes()', () => {
});
it('should delete the sales', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let params = {
sales: [{id: newsale.id, instance: 0}],
actualTicketFk: 16
};
let res = await app.models.Sale.removes(params);
let res = await app.models.Sale.removes(ctx, params);
expect(res).toEqual([{count: 1}]);
});

View File

@ -2,6 +2,7 @@ const app = require('vn-loopback/server/server');
describe('sale reserve()', () => {
afterAll(async done => {
let ctx = {req: {accessToken: {userId: 9}}};
let params = {
sales: [
{id: 7},
@ -10,18 +11,19 @@ describe('sale reserve()', () => {
reserved: false
};
await app.models.Sale.reserve(params);
await app.models.Sale.reserve(ctx, params);
done();
});
it('should throw an error if the ticket can not be modified', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let error;
let params = {ticketFk: 2,
sales: [{id: 5}],
reserved: false};
await app.models.Sale.reserve(params)
await app.models.Sale.reserve(ctx, params)
.catch(response => {
expect(response).toEqual(new Error(`The sales of this ticket can't be modified`));
error = response;
@ -36,6 +38,7 @@ describe('sale reserve()', () => {
expect(originalTicketSales[0].reserved).toEqual(0);
expect(originalTicketSales[1].reserved).toEqual(0);
let ctx = {req: {accessToken: {userId: 9}}};
let params = {
sales: [
{id: 7},
@ -44,7 +47,7 @@ describe('sale reserve()', () => {
reserved: true
};
await app.models.Sale.reserve(params);
await app.models.Sale.reserve(ctx, params);
let reservedTicketSales = await app.models.Ticket.getSales(11);

View File

@ -26,10 +26,11 @@ describe('sale updatePrice()', () => {
it('should throw an error if the ticket is not editable', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let immutableSaleId = 1;
let price = 5;
await app.models.Sale.updatePrice(immutableSaleId, price)
await app.models.Sale.updatePrice(ctx, immutableSaleId, price)
.catch(response => {
expect(response).toEqual(new Error(`The sales of this ticket can't be modified`));
error = response;
@ -39,27 +40,30 @@ describe('sale updatePrice()', () => {
});
it('should return 0 if the price is an empty string', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let price = '';
await app.models.Sale.updatePrice(saleId, price);
await app.models.Sale.updatePrice(ctx, saleId, price);
let saleUpdated = await app.models.Sale.findById(saleId);
expect(saleUpdated.price).toEqual(0);
});
it('should now set price as a decimal number in a string', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let price = '8';
await app.models.Sale.updatePrice(saleId, price);
await app.models.Sale.updatePrice(ctx, saleId, price);
let saleUpdated = await app.models.Sale.findById(saleId);
expect(saleUpdated.price).toEqual(8);
});
it('should set price as a decimal number and check the sale has the mana component', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let price = 5.3;
await app.models.Sale.updatePrice(saleId, price);
await app.models.Sale.updatePrice(ctx, saleId, price);
let saleUpdated = await app.models.Sale.findById(saleId);
createdSaleComponent = await app.models.SaleComponent.findOne({where: {saleFk: saleId, componentFk: manaComponentId}});

View File

@ -1,7 +1,7 @@
let UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethod('updatePrice', {
Self.remoteMethodCtx('updatePrice', {
description: 'Changes the price of a sale',
accessType: 'WRITE',
accepts: [
@ -28,7 +28,7 @@ module.exports = Self => {
}
});
Self.updatePrice = async(id, newPrice) => {
Self.updatePrice = async(ctx, id, newPrice) => {
let models = Self.app.models;
let tx = await Self.beginTransaction({});
@ -51,7 +51,7 @@ module.exports = Self => {
};
let sale = await models.Sale.findById(id, filter, options);
let isEditable = await models.Ticket.isEditable(sale.ticketFk);
let isEditable = await models.Ticket.isEditable(ctx, sale.ticketFk);
if (!isEditable)
throw new UserError(`The sales of this ticket can't be modified`);

View File

@ -2,7 +2,7 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethod('addSale', {
Self.remoteMethodCtx('addSale', {
description: 'Inserts a new sale for the current ticket',
accessType: 'WRITE',
accepts: [{
@ -32,10 +32,10 @@ module.exports = Self => {
}
});
Self.addSale = async(id, itemId, quantity) => {
Self.addSale = async(ctx, id, itemId, quantity) => {
const models = Self.app.models;
const isEditable = await models.Ticket.isEditable(id);
const isEditable = await models.Ticket.isEditable(ctx, id);
if (!isEditable)
throw new UserError(`The sales of this ticket can't be modified`);

View File

@ -1,5 +1,5 @@
module.exports = Self => {
Self.remoteMethod('isEditable', {
Self.remoteMethodCtx('isEditable', {
description: 'Check if a ticket is editable',
accessType: 'READ',
accepts: [{
@ -19,10 +19,13 @@ module.exports = Self => {
}
});
Self.isEditable = async ticketFk => {
Self.isEditable = async(ctx, ticketFk) => {
const accessToken = ctx.active && ctx.active.accessToken || ctx.req && ctx.req.accessToken;
const userId = accessToken.userId;
let state = await Self.app.models.TicketState.findOne({
where: {ticketFk: ticketFk}
});
let isProductionBoss = await Self.app.models.Account.hasRole(userId, 'productionBoss');
let alertLevel = state ? state.alertLevel : null;
let ticket = await Self.app.models.Ticket.findById(ticketFk, {
fields: ['isDeleted', 'clientFk', 'refFk'],
@ -41,7 +44,7 @@ module.exports = Self => {
const isNotNormalClient = ticket && ticket.client().type().code == 'normal';
const isInvoiced = ticket && ticket.refFk;
if (!ticket || ((isDeleted || isOnDelivery) && isNotNormalClient) || isInvoiced)
if (!ticket || (isOnDelivery && isNotNormalClient && !isProductionBoss) || isInvoiced || isDeleted)
return false;
return true;

View File

@ -12,19 +12,21 @@ describe('ticket addSale()', () => {
});
it('should create a new sale for the ticket with id 13', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
const itemId = 4;
const quantity = 10;
newSale = await app.models.Ticket.addSale(ticketId, itemId, quantity);
newSale = await app.models.Ticket.addSale(ctx, ticketId, itemId, quantity);
expect(newSale.itemFk).toEqual(4);
});
it('should not be able to add a sale if the item quantity is not available', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
const itemId = 11;
const quantity = 10;
let error;
await app.models.Ticket.addSale(ticketId, itemId, quantity).catch(e => {
await app.models.Ticket.addSale(ctx, ticketId, itemId, quantity).catch(e => {
error = e;
}).finally(() => {
expect(error.message).toEqual(`This item is not available`);
@ -34,11 +36,12 @@ describe('ticket addSale()', () => {
});
it('should not be able to add a sale if the ticket is not editable', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
const notEditableTicketId = 1;
const itemId = 4;
const quantity = 10;
let error;
await app.models.Ticket.addSale(notEditableTicketId, itemId, quantity).catch(e => {
await app.models.Ticket.addSale(ctx, notEditableTicketId, itemId, quantity).catch(e => {
error = e;
}).finally(() => {
expect(error.message).toEqual(`The sales of this ticket can't be modified`);

View File

@ -2,26 +2,44 @@ const app = require('vn-loopback/server/server');
describe('ticket isEditable()', () => {
it('should return false if the given ticket is not editable', async() => {
let result = await app.models.Ticket.isEditable(2);
let ctx = {req: {accessToken: {userId: 9}}};
let result = await app.models.Ticket.isEditable(ctx, 2);
expect(result).toEqual(false);
});
it('should return false if the given ticket does not exist', async() => {
let result = await app.models.Ticket.isEditable(99999);
let ctx = {req: {accessToken: {userId: 9}}};
let result = await app.models.Ticket.isEditable(ctx, 99999);
expect(result).toEqual(false);
});
it('should return false if the given ticket isDeleted', async() => {
let result = await app.models.Ticket.isEditable(19);
let ctx = {req: {accessToken: {userId: 9}}};
let result = await app.models.Ticket.isEditable(ctx, 19);
expect(result).toEqual(false);
});
it('should return true if the given ticket is editable', async() => {
let result = await app.models.Ticket.isEditable(16);
let ctx = {req: {accessToken: {userId: 9}}};
let result = await app.models.Ticket.isEditable(ctx, 16);
expect(result).toEqual(true);
});
it('should be able to edit a not deleted or invoiced ticket if the role is productionBoss', async() => {
let ctx = {req: {accessToken: {userId: 50}}};
let result = await app.models.Ticket.isEditable(ctx, 8);
expect(result).toEqual(true);
});
it('should not be able to edit a not deleted or invoiced ticket if the role is salesPerson', async() => {
let ctx = {req: {accessToken: {userId: 18}}};
let result = await app.models.Ticket.isEditable(ctx, 8);
expect(result).toEqual(false);
});
});

View File

@ -28,13 +28,14 @@ describe('sale updateDiscount()', () => {
it('should throw an error if no sales were selected', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let error;
const ticketId = 11;
const sales = [];
const newDiscount = 10;
try {
await app.models.Ticket.updateDiscount(ticketId, sales, newDiscount);
await app.models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount);
} catch (err) {
error = err;
}
@ -43,13 +44,14 @@ describe('sale updateDiscount()', () => {
});
it('should throw an error if no sales belong to different tickets', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let error;
const ticketId = 11;
const sales = [1, 14];
const newDiscount = 10;
try {
await app.models.Ticket.updateDiscount(ticketId, sales, newDiscount);
await app.models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount);
} catch (err) {
error = err;
}
@ -58,13 +60,14 @@ describe('sale updateDiscount()', () => {
});
it('should throw an error if the ticket is invoiced already', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let error;
const ticketId = 1;
const sales = [1];
const newDiscount = 100;
try {
await app.models.Ticket.updateDiscount(ticketId, sales, newDiscount);
await app.models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount);
} catch (err) {
error = err;
}
@ -73,11 +76,12 @@ describe('sale updateDiscount()', () => {
});
it('should update the discount if the salesPerson has mana', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
const ticketId = 11;
const sales = [originalSaleId];
const newDiscount = 100;
await app.models.Ticket.updateDiscount(ticketId, sales, newDiscount);
await app.models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount);
let updatedSale = await app.models.Sale.findById(originalSaleId);
let createdSaleComponent = await app.models.SaleComponent.findOne({

View File

@ -7,14 +7,17 @@ describe('ticket updateEditableTicket()', () => {
const originalData = {addressFk: 123};
afterAll(async done => {
await app.models.Ticket.updateEditableTicket(validTicketId, originalData);
let ctx = {req: {accessToken: {userId: 9}}};
await app.models.Ticket.updateEditableTicket(ctx, validTicketId, originalData);
done();
});
it('should throw an error if the ticket is not editable', async() => {
let error;
await app.models.Ticket.updateEditableTicket(invalidTicketId, data).catch(e => {
let ctx = {req: {accessToken: {userId: 9}}};
await app.models.Ticket.updateEditableTicket(ctx, invalidTicketId, data).catch(e => {
error = e;
}).finally(() => {
expect(error.message).toEqual('This ticket can not be modified');
@ -25,7 +28,9 @@ describe('ticket updateEditableTicket()', () => {
it('should edit the ticket address', async() => {
await app.models.Ticket.updateEditableTicket(validTicketId, data);
let ctx = {req: {accessToken: {userId: 9}}};
await app.models.Ticket.updateEditableTicket(ctx, validTicketId, data);
let updatedTicket = await app.models.Ticket.findById(validTicketId);

View File

@ -1,7 +1,7 @@
let UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethod('updateDiscount', {
Self.remoteMethodCtx('updateDiscount', {
description: 'Changes the discount of a sale',
accessType: 'WRITE',
accepts: [
@ -34,7 +34,7 @@ module.exports = Self => {
}
});
Self.updateDiscount = async(id, salesIds, newDiscount) => {
Self.updateDiscount = async(ctx, id, salesIds, newDiscount) => {
const models = Self.app.models;
const tx = await Self.beginTransaction({});
@ -69,7 +69,7 @@ module.exports = Self => {
if (!allFromSameTicket)
throw new UserError('All sales must belong to the same ticket');
const isEditable = await models.Ticket.isEditable(id);
const isEditable = await models.Ticket.isEditable(ctx, id);
if (!isEditable)
throw new UserError(`The sales of this ticket can't be modified`);

View File

@ -1,7 +1,7 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethod('updateEditableTicket', {
Self.remoteMethodCtx('updateEditableTicket', {
description: 'Change data of a ticket',
accessType: 'WRITE',
accepts: [
@ -30,8 +30,8 @@ module.exports = Self => {
}
});
Self.updateEditableTicket = async(id, data) => {
let ticketIsEditable = await Self.app.models.Ticket.isEditable(id);
Self.updateEditableTicket = async(ctx, id, data) => {
let ticketIsEditable = await Self.app.models.Ticket.isEditable(ctx, id);
if (!ticketIsEditable)
throw new UserError('This ticket can not be modified');

View File

@ -1,20 +1,23 @@
const UserError = require('vn-loopback/util/user-error');
const LoopBackContext = require('loopback-context');
module.exports = Self => {
Self.observe('before save', async ctx => {
const loopBackContext = LoopBackContext.getCurrentContext();
let changes = ctx.currentInstance || ctx.instance;
if (changes) {
let ticketId = changes.ticketFk;
let isEditable = await Self.app.models.Ticket.isEditable(ticketId);
let isEditable = await Self.app.models.Ticket.isEditable(loopBackContext, ticketId);
if (!isEditable)
throw new UserError(`The current ticket can't be modified`);
}
});
Self.observe('before delete', async ctx => {
const loopBackContext = LoopBackContext.getCurrentContext();
const models = Self.app.models;
const service = await models.TicketService.findById(ctx.where.id);
const isEditable = await Self.app.models.Ticket.isEditable(service.ticketFk);
const isEditable = await Self.app.models.Ticket.isEditable(loopBackContext, service.ticketFk);
if (!isEditable)
throw new UserError(`The current ticket can't be modified`);

View File

@ -21,6 +21,15 @@ class Controller {
this.imagesPath = '//verdnatura.es/vn-image-data/catalog';
}
get ticket() {
return this._ticket;
}
set ticket(value) {
this._ticket = value;
this.isEditable();
}
get sales() {
return this._sales;
}
@ -85,14 +94,11 @@ class Controller {
callback.call(this);
}
get isEditable() {
try {
return !this.ticket.state.state.alertLevel;
} catch (e) {}
return true;
isEditable() {
this.$http.get(`/api/Tickets/${this.$state.params.id}/isEditable`).then(res => {
this.isEditable = res.data;
});
}
get isChecked() {
if (this.sales) {
for (let instance of this.sales)