sale module now has canEdit endpoint to check arrays of sales

This commit is contained in:
Carlos Jimenez Ruiz 2021-05-26 09:14:18 +02:00
parent f5ffdd6995
commit d6ef5352a2
12 changed files with 126 additions and 11 deletions

View File

@ -86,6 +86,7 @@
"The current ticket can't be modified": "El ticket actual no puede ser modificado",
"The current claim can't be modified": "La reclamación actual no puede ser modificada",
"The sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas",
"Sale(s) blocked, contact production": "Linea(s) bloqueada(s), contacte con produccion",
"Please select at least one sale": "Por favor selecciona al menos una linea",
"All sales must belong to the same ticket": "Todas las lineas deben pertenecer al mismo ticket",
"NO_ZONE_FOR_THIS_PARAMETERS": "Para este día no hay ninguna zona configurada",

View File

@ -0,0 +1,40 @@
module.exports = Self => {
Self.remoteMethodCtx('canEdit', {
description: 'Check if all the received sales are aditable',
accessType: 'READ',
accepts: [{
arg: 'sales',
type: ['object'],
required: true
}],
returns: {
type: 'boolean',
root: true
},
http: {
path: `/isEditable`,
verb: 'get'
}
});
Self.canEdit = async(ctx, sales, options) => {
const models = Self.app.models;
const userId = ctx.req.accessToken.userId;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const idsCollection = sales.map(sale => sale.id);
const saleTracking = await models.SaleTracking.find({where: {saleFk: {inq: idsCollection}}}, myOptions);
const hasSaleTracking = saleTracking.length;
const isProductionRole = await models.Account.hasRole(userId, 'production', myOptions);
const canEdit = (isProductionRole || !hasSaleTracking);
return canEdit;
};
};

View File

@ -28,10 +28,16 @@ module.exports = Self => {
Self.deleteSales = async(ctx, sales, ticketId) => {
const models = Self.app.models;
const canEditSales = await models.Sale.canEdit(ctx, sales);
const isTicketEditable = await models.Ticket.isEditable(ctx, ticketId);
if (!isTicketEditable)
throw new UserError(`The sales of this ticket can't be modified`);
if (!canEditSales)
throw new UserError(`Sale(s) blocked, please contact production`);
const promises = [];
for (let sale of sales) {
const deletedSale = models.Sale.destroyById(sale.id);

View File

@ -29,6 +29,11 @@ module.exports = Self => {
if (!isEditable)
throw new UserError(`The sales of this ticket can't be modified`);
const canEditSale = await models.Sale.canEdit(ctx, [id]);
if (!canEditSale)
throw new UserError(`Sale(s) blocked, please contact production`);
return Self.rawSql('CALL vn.sale_calculateComponent(?, null)', [id]);
};
};

View File

@ -37,6 +37,11 @@ module.exports = Self => {
if (!isTicketEditable)
throw new UserError(`The sales of this ticket can't be modified`);
const canEditSale = await models.Sale.canEdit(ctx, sales);
if (!canEditSale)
throw new UserError(`Sale(s) blocked, please contact production`);
const promises = [];
for (let sale of sales) {
const reservedSale = models.Sale.update({id: sale.id}, {reserved: reserved});

View File

@ -0,0 +1,36 @@
const app = require('vn-loopback/server/server');
describe('sale canEdit()', () => {
it('should return true if the role is production regardless of the saleTrackings', async() => {
const productionUserID = 49;
let ctx = {req: {accessToken: {userId: productionUserID}}};
const sales = [{id: 3}];
const result = await app.models.Sale.canEdit(ctx, sales);
expect(result).toEqual(true);
});
it('should return true if the role is not production and none of the sales has saleTracking', async() => {
const salesPersonUserID = 18;
let ctx = {req: {accessToken: {userId: salesPersonUserID}}};
const sales = [{id: 10}];
const result = await app.models.Sale.canEdit(ctx, sales);
expect(result).toEqual(true);
});
it('should return false if any of the sales has a saleTracking record', async() => {
const salesPersonUserID = 18;
let ctx = {req: {accessToken: {userId: salesPersonUserID}}};
const sales = [{id: 3}];
const result = await app.models.Sale.canEdit(ctx, sales);
expect(result).toEqual(false);
});
});

View File

@ -1,6 +1,7 @@
const app = require('vn-loopback/server/server');
describe('sale updateConcept()', () => {
const ctx = {req: {accessToken: {userId: 9}}};
const saleId = 1;
let originalSale;
@ -21,7 +22,7 @@ describe('sale updateConcept()', () => {
const newConcept = 'I am he new concept';
try {
await app.models.Sale.updateConcept(undefined, newConcept);
await app.models.Sale.updateConcept(ctx, undefined, newConcept);
} catch (e) {
err = e;
}
@ -32,7 +33,7 @@ describe('sale updateConcept()', () => {
it('should update the sale concept', async() => {
const newConcept = 'I am the new concept';
let response = await app.models.Sale.updateConcept(saleId, newConcept);
let response = await app.models.Sale.updateConcept(ctx, saleId, newConcept);
expect(response.concept).toEqual(newConcept);
});

View File

@ -1,10 +1,12 @@
const app = require('vn-loopback/server/server');
describe('sale updateQuantity()', () => {
const ctx = {req: {accessToken: {userId: 9}}};
it('should throw an error if the quantity is not a number', async() => {
let error;
await app.models.Sale.updateQuantity(1, 'wrong quantity!')
await app.models.Sale.updateQuantity(ctx, 1, 'wrong quantity!')
.catch(response => {
expect(response).toEqual(new Error('The value should be a number'));
error = response;
@ -16,7 +18,7 @@ describe('sale updateQuantity()', () => {
it('should throw an error if the quantity is greater than it should be', async() => {
let error;
await app.models.Sale.updateQuantity(1, 99)
await app.models.Sale.updateQuantity(ctx, 1, 99)
.catch(response => {
expect(response).toEqual(new Error('The new quantity should be smaller than the old one'));
error = response;
@ -30,7 +32,7 @@ describe('sale updateQuantity()', () => {
expect(originalLineData.quantity).toEqual(5);
await app.models.Sale.updateQuantity(1, 4);
await app.models.Sale.updateQuantity(ctx, 1, 4);
let modifiedLineData = await app.models.Sale.findOne({where: {id: 1}, fields: ['quantity']});

View File

@ -1,5 +1,5 @@
module.exports = Self => {
Self.remoteMethod('updateConcept', {
Self.remoteMethodCtx('updateConcept', {
description: 'Updates the concept of a sale',
accessType: 'WRITE',
accepts: [{
@ -24,8 +24,14 @@ module.exports = Self => {
}
});
Self.updateConcept = async(id, newConcept) => {
let currentLine = await Self.app.models.Sale.findById(id);
Self.updateConcept = async(ctx, id, newConcept) => {
const models = Self.app.models;
const currentLine = await models.Sale.findById(id);
const canEditSale = await models.Sale.canEdit(ctx, [id]);
if (!canEditSale)
throw new UserError(`Sale(s) blocked, please contact production`);
return await currentLine.updateAttributes({concept: newConcept});
};

View File

@ -55,6 +55,11 @@ module.exports = Self => {
if (!isEditable)
throw new UserError(`The sales of this ticket can't be modified`);
const canEditSale = await models.Sale.canEdit(ctx, [id]);
if (!canEditSale)
throw new UserError(`Sale(s) blocked, please contact production`);
const userId = ctx.req.accessToken.userId;
let usesMana = await models.WorkerMana.findOne({where: {workerFk: userId}, fields: 'amount'}, options);

View File

@ -1,7 +1,7 @@
let UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethod('updateQuantity', {
Self.remoteMethodCtx('updateQuantity', {
description: 'Changes the quantity of a sale',
accessType: 'WRITE',
accepts: [{
@ -26,11 +26,18 @@ module.exports = Self => {
}
});
Self.updateQuantity = async(id, quantity) => {
Self.updateQuantity = async(ctx, id, quantity) => {
const models = Self.app.models;
const canEditSale = await models.Sale.canEdit(ctx, [id]);
if (!canEditSale)
throw new UserError(`Sale(s) blocked, please contact production`);
if (isNaN(quantity))
throw new UserError(`The value should be a number`);
let currentLine = await Self.app.models.Sale.findOne({where: {id: id}});
let currentLine = await models.Sale.findOne({where: {id: id}});
if (quantity > currentLine.quantity)
throw new UserError('The new quantity should be smaller than the old one');

View File

@ -6,6 +6,7 @@ module.exports = Self => {
require('../methods/sale/updateQuantity')(Self);
require('../methods/sale/updateConcept')(Self);
require('../methods/sale/recalculatePrice')(Self);
require('../methods/sale/canEdit')(Self);
Self.validatesPresenceOf('concept', {
message: `Concept cannot be blank`