167 lines
6.0 KiB
JavaScript
167 lines
6.0 KiB
JavaScript
const UserError = require('vn-loopback/util/user-error');
|
|
|
|
module.exports = Self => {
|
|
Self.remoteMethodCtx('saveSign', {
|
|
description: 'Save sign',
|
|
accessType: 'WRITE',
|
|
accepts:
|
|
[
|
|
{
|
|
arg: 'tickets',
|
|
type: ['number'],
|
|
required: true,
|
|
description: 'The tickets'
|
|
},
|
|
{
|
|
arg: 'location',
|
|
type: 'object',
|
|
description: 'The employee location the moment the sign is saved'
|
|
},
|
|
{
|
|
arg: 'signedTime',
|
|
type: 'date',
|
|
description: 'The signed time'
|
|
}
|
|
],
|
|
http: {
|
|
path: `/saveSign`,
|
|
verb: 'POST'
|
|
}
|
|
});
|
|
|
|
Self.saveSign = async(ctx, tickets, location, signedTime, options) => {
|
|
const models = Self.app.models;
|
|
const myOptions = {userId: ctx.req.accessToken.userId};
|
|
let tx;
|
|
let ticket;
|
|
let dms;
|
|
let isSignUploaded;
|
|
let externalTickets = [];
|
|
|
|
if (typeof options == 'object')
|
|
Object.assign(myOptions, options);
|
|
|
|
if (!myOptions.transaction) {
|
|
tx = await Self.beginTransaction({});
|
|
myOptions.transaction = tx;
|
|
}
|
|
|
|
const dmsTypeTicket = await models.DmsType.findOne({
|
|
where: {code: 'ticket'},
|
|
fields: ['id']
|
|
});
|
|
|
|
async function setLocation() {
|
|
await models.Delivery.create({
|
|
ticketFk: ticket.id,
|
|
longitude: location.Longitude,
|
|
latitude: location.Latitude,
|
|
dated: signedTime || new Date()
|
|
}, myOptions);
|
|
}
|
|
|
|
async function hasSignDms() {
|
|
const hasTicketDms = await Self.rawSql(`
|
|
SELECT d.id
|
|
FROM ticketDms td
|
|
JOIN dms d ON d.id = td.dmsFk
|
|
WHERE td.ticketFk = ?
|
|
AND d.dmsTypeFk = ?
|
|
`, [ticket.id, dmsTypeTicket.id], myOptions);
|
|
|
|
if (hasTicketDms.length) return true;
|
|
}
|
|
|
|
async function createGestDoc() {
|
|
const ctxUploadFile = Object.assign({}, ctx);
|
|
ctxUploadFile.args = {
|
|
warehouseId: ticket.warehouseFk,
|
|
companyId: ticket.companyFk,
|
|
dmsTypeId: dmsTypeTicket.id,
|
|
reference: ticket.id,
|
|
description: `Firma del cliente - Ruta ${ticket.route().id}`,
|
|
hasFile: false
|
|
};
|
|
dms = await models.Dms.uploadFile(ctxUploadFile, myOptions);
|
|
// Si se ha subido ya la firma, no se vuelve a subir, ya que si no
|
|
// da un error de deadlock en la db
|
|
isSignUploaded = true;
|
|
}
|
|
|
|
try {
|
|
for (const ticketId of tickets) {
|
|
ticket = await models.Ticket.findById(ticketId, {
|
|
include: [{
|
|
relation: 'address',
|
|
scope: {
|
|
include: {
|
|
relation: 'province',
|
|
scope: {
|
|
include: {
|
|
relation: 'country',
|
|
scope: {
|
|
fields: ['code']
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
relation: 'route',
|
|
scope: {
|
|
fields: ['id']
|
|
}
|
|
}]
|
|
}, myOptions);
|
|
|
|
const ticketState = await models.TicketState.findOne({
|
|
where: {ticketFk: ticketId},
|
|
fields: ['alertLevel']
|
|
}, myOptions);
|
|
|
|
const packedAlertLevel = await models.AlertLevel.findOne({
|
|
where: {code: 'PACKED'},
|
|
fields: ['id']
|
|
}, myOptions);
|
|
|
|
if (!ticketState)
|
|
throw new UserError('Ticket does not exist');
|
|
if (!ticket.route())
|
|
throw new UserError('Ticket without route');
|
|
if (ticketState.alertLevel < packedAlertLevel.id)
|
|
throw new UserError('This ticket cannot be signed because it has not been boxed');
|
|
if (await ticket.isSigned)
|
|
throw new UserError('Ticket is already signed');
|
|
|
|
if (location) await setLocation();
|
|
if (!await hasSignDms() && !isSignUploaded)
|
|
await createGestDoc();
|
|
if (isSignUploaded)
|
|
await models.TicketDms.create({ticketFk: ticket.id, dmsFk: dms[0].id}, myOptions);
|
|
await ticket.updateAttribute('isSigned', true, myOptions);
|
|
|
|
const [{stateCode}] = await Self.rawSql(`
|
|
SELECT
|
|
IF((SUM(CASE WHEN est.code = 'DELIVERED' THEN 1 ELSE 0 END) = COUNT(*)),
|
|
'DELIVERED','PARTIAL_DELIVERED') stateCode
|
|
FROM vn.expedition e
|
|
JOIN vn.expeditionStateType est ON est.id = e.stateTypeFk
|
|
WHERE e.ticketFk = ?;
|
|
`, [ticketId], myOptions);
|
|
|
|
await Self.rawSql(`CALL vn.ticket_setState(?, ?)`, [ticketId, stateCode], myOptions);
|
|
|
|
if (ticket?.address()?.province()?.country()?.code != 'ES' && ticket.$cmrFk) {
|
|
await models.Ticket.saveCmr(ctx, [ticketId], myOptions);
|
|
externalTickets.push(ticketId);
|
|
}
|
|
}
|
|
if (tx) await tx.commit();
|
|
} catch (e) {
|
|
if (tx) await tx.rollback();
|
|
throw e;
|
|
}
|
|
await models.Ticket.sendCmrEmail(ctx, externalTickets);
|
|
};
|
|
};
|