8062-testToMaster_2 #3059
|
@ -0,0 +1,9 @@
|
||||||
|
-- Place your SQL code here
|
||||||
|
INSERT INTO salix.ACL
|
||||||
|
SET model = 'Ticket',
|
||||||
|
property = 'setWeight',
|
||||||
|
accessType = 'WRITE',
|
||||||
|
permission = 'ALLOW',
|
||||||
|
principalType = 'ROLE',
|
||||||
|
principalId = 'salesPerson';
|
||||||
|
|
|
@ -372,5 +372,7 @@
|
||||||
"The entry not have stickers": "La entrada no tiene etiquetas",
|
"The entry not have stickers": "La entrada no tiene etiquetas",
|
||||||
"Too many records": "Demasiados registros",
|
"Too many records": "Demasiados registros",
|
||||||
"Original invoice not found": "Factura original no encontrada",
|
"Original invoice not found": "Factura original no encontrada",
|
||||||
"The entry has no lines or does not exist": "La entrada no tiene lineas o no existe"
|
"The entry has no lines or does not exist": "La entrada no tiene lineas o no existe",
|
||||||
|
"Weight already set": "El peso ya está establecido",
|
||||||
|
"This ticket is not allocated to your department": "Este ticket no está asignado a tu departamento"
|
||||||
}
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('setWeight', {
|
||||||
|
description: 'Sets weight of a ticket',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The ticket id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
}, {
|
||||||
|
arg: 'weight',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The weight value',
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: 'Array',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/:id/setWeight`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.setWeight = async(ctx, ticketId, weight, options) => {
|
||||||
|
const models = Self.app.models;
|
||||||
|
const userId = ctx.req.accessToken.userId;
|
||||||
|
const myOptions = {userId};
|
||||||
|
let tx;
|
||||||
|
|
||||||
|
if (typeof options == 'object') Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const ticket = await Self.findById(ticketId, null, myOptions);
|
||||||
|
if (ticket.weight) throw new UserError('Weight already set');
|
||||||
|
|
||||||
|
const canEdit = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'updateAttributes');
|
||||||
|
const client = await models.Client.findById(ticket.clientFk, {
|
||||||
|
include: {relation: 'salesPersonUser'}},
|
||||||
|
myOptions);
|
||||||
|
|
||||||
|
if (!canEdit) {
|
||||||
|
const salesPersonUser = client.salesPersonUser();
|
||||||
|
const workerDepartments = await models.WorkerDepartment.find({
|
||||||
|
include: {relation: 'department'},
|
||||||
|
where: {workerFk: {inq: [userId, salesPersonUser.id]}}
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
if (
|
||||||
|
workerDepartments.length == 2 &&
|
||||||
|
workerDepartments[0].departmentFk != workerDepartments[1].departmentFk
|
||||||
|
)
|
||||||
|
throw new UserError('This ticket is not allocated to your department');
|
||||||
|
}
|
||||||
|
|
||||||
|
await ticket.updateAttribute('weight', weight, myOptions);
|
||||||
|
|
||||||
|
const packedState = await models.State.findOne({where: {code: 'PACKED'}}, myOptions);
|
||||||
|
const ticketState = await models.TicketState.findOne({where: {ticketFk: ticketId}}, myOptions);
|
||||||
|
|
||||||
|
const [{taxArea}] = await Self.rawSql('SELECT clientTaxArea(?,?) taxArea',
|
||||||
|
[ticket.clientFk, ticket.warehouseFk], myOptions);
|
||||||
|
|
||||||
|
const isInvoiceable = ticketState.alertLevel >= packedState.alertLevel &&
|
||||||
|
taxArea == 'WORLD' && client.hasDailyInvoice;
|
||||||
|
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
let invoiceIds = [];
|
||||||
|
if (isInvoiceable) invoiceIds = [...await Self.invoiceTicketsAndPdf(ctx, [ticketId])];
|
||||||
|
|
||||||
|
return invoiceIds;
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,70 @@
|
||||||
|
const {models} = require('vn-loopback/server/server');
|
||||||
|
|
||||||
|
describe('ticket setWeight()', () => {
|
||||||
|
const ctx = beforeAll.getCtx();
|
||||||
|
beforeAll.mockLoopBackContext();
|
||||||
|
let opts;
|
||||||
|
let tx;
|
||||||
|
const employeeId = 1;
|
||||||
|
const administrativeId = 5;
|
||||||
|
|
||||||
|
beforeEach(async() => {
|
||||||
|
opts = {transaction: tx};
|
||||||
|
tx = await models.Ticket.beginTransaction({});
|
||||||
|
opts.transaction = tx;
|
||||||
|
ctx.req.accessToken.userId = administrativeId;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async() => await tx.rollback());
|
||||||
|
|
||||||
|
it('should throw an error if the weight is already set', async() => {
|
||||||
|
try {
|
||||||
|
const ticketId = 1;
|
||||||
|
const weight = 10;
|
||||||
|
|
||||||
|
await models.Ticket.setWeight(ctx, ticketId, weight, opts);
|
||||||
|
} catch (e) {
|
||||||
|
expect(e.message).toEqual('Weight already set');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set the weight of a ticket', async() => {
|
||||||
|
const ticketId = 31;
|
||||||
|
const weight = 15;
|
||||||
|
|
||||||
|
await models.Ticket.setWeight(ctx, ticketId, weight, opts);
|
||||||
|
|
||||||
|
const ticket = await models.Ticket.findById(ticketId, null, opts);
|
||||||
|
|
||||||
|
expect(ticket.weight).toEqual(weight);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if the user is not allocated to the same department', async() => {
|
||||||
|
ctx.req.accessToken.userId = employeeId;
|
||||||
|
try {
|
||||||
|
const ticketId = 10;
|
||||||
|
const weight = 20;
|
||||||
|
|
||||||
|
await models.Ticket.setWeight(ctx, ticketId, weight, opts);
|
||||||
|
} catch (e) {
|
||||||
|
expect(e.message).toEqual('This ticket is not allocated to your department');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call invoiceTicketsAndPdf if the ticket is invoiceable', async() => {
|
||||||
|
const ticketId = 10;
|
||||||
|
const weight = 25;
|
||||||
|
|
||||||
|
spyOn(models.Client, 'findById').and.returnValue({
|
||||||
|
hasDailyInvoice: true,
|
||||||
|
salesPersonUser: () => ({id: 1})
|
||||||
|
});
|
||||||
|
spyOn(models.TicketState, 'findOne').and.returnValue({alertLevel: 3});
|
||||||
|
spyOn(models.Ticket, 'rawSql').and.returnValue([{taxArea: 'WORLD'}]);
|
||||||
|
spyOn(models.Ticket, 'invoiceTicketsAndPdf').and.returnValue([10]);
|
||||||
|
|
||||||
|
const invoiceIds = await models.Ticket.setWeight(ctx, ticketId, weight, opts);
|
||||||
|
|
||||||
|
expect(invoiceIds.length).toBeGreaterThan(0);
|
||||||
|
});
|
||||||
|
});
|
|
@ -46,4 +46,5 @@ module.exports = function(Self) {
|
||||||
require('../methods/ticket/invoiceTicketsAndPdf')(Self);
|
require('../methods/ticket/invoiceTicketsAndPdf')(Self);
|
||||||
require('../methods/ticket/docuwareDownload')(Self);
|
require('../methods/ticket/docuwareDownload')(Self);
|
||||||
require('../methods/ticket/myLastModified')(Self);
|
require('../methods/ticket/myLastModified')(Self);
|
||||||
|
require('../methods/ticket/setWeight')(Self);
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,4 +3,5 @@ Address mobile: Móv. consignatario
|
||||||
Client phone: Tel. cliente
|
Client phone: Tel. cliente
|
||||||
Client mobile: Móv. cliente
|
Client mobile: Móv. cliente
|
||||||
Go to the ticket: Ir al ticket
|
Go to the ticket: Ir al ticket
|
||||||
Change state: Cambiar estado
|
Change state: Cambiar estado
|
||||||
|
Weight: Peso
|
Loading…
Reference in New Issue