salix/modules/ticket/back/methods/ticket/componentUpdate.js

295 lines
10 KiB
JavaScript

const loggable = require('vn-loopback/util/log');
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('componentUpdate', {
description: 'Save ticket sale components',
accessType: 'WRITE',
accepts: [
{
arg: 'id',
type: 'number',
required: true,
description: 'The ticket id',
http: {source: 'path'}
},
{
arg: 'clientFk',
type: 'number',
description: 'The client id',
required: true
},
{
arg: 'nickname',
type: 'string',
description: 'The client nickname'
},
{
arg: 'agencyModeFk',
type: 'number',
description: 'The agencyMode id',
required: true
},
{
arg: 'addressFk',
type: 'number',
description: 'The address id',
required: true
},
{
arg: 'zoneFk',
type: 'number',
description: 'The zone id',
required: true
},
{
arg: 'warehouseFk',
type: 'number',
description: 'The warehouse id',
required: true
},
{
arg: 'companyFk',
type: 'number',
description: 'The company id',
required: true
},
{
arg: 'shipped',
type: 'date',
description: 'The shipped date',
required: true
},
{
arg: 'landed',
type: 'date',
description: 'The landing date',
required: true
},
{
arg: 'isDeleted',
type: 'boolean',
description: 'Ticket is deleted',
required: true
},
{
arg: 'option',
type: 'string',
description: 'Action code'
},
{
arg: 'isWithoutNegatives',
type: 'boolean',
description: 'Is whithout negatives',
required: true
},
{
arg: 'withWarningAccept',
type: 'boolean',
description: 'Has pressed in confirm message',
},
{
arg: 'newTicket',
type: 'number',
description: 'Ticket id you want to move the lines to, if applicable',
},
{
arg: 'keepPrice',
type: 'boolean',
description: 'If prices should be maintained',
}
],
returns: {
type: ['object'],
root: true
},
http: {
path: `/:id/componentUpdate`,
verb: 'post'
}
});
Self.componentUpdate = async(ctx, options) => {
const args = ctx.args;
const myOptions = {userId: ctx.req.accessToken.userId};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
const models = Self.app.models;
const $t = ctx.req.__; // $translate
await models.Ticket.isEditableOrThrow(ctx, args.id, myOptions);
const editZone = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'editZone', 'WRITE');
if (!editZone) {
const zoneShipped = await models.Agency.getShipped(
ctx,
args.landed,
args.addressFk,
args.agencyModeFk,
args.warehouseFk,
myOptions);
if (!zoneShipped || zoneShipped.zoneFk != args.zoneFk)
throw new UserError(`You don't have privileges to change the zone`);
}
if (args.isWithoutNegatives) {
const query = `CALL ticket_getMovable(?,?,?)`;
const params = [args.id, args.shipped, args.warehouseFk];
const [salesMovable] = await Self.rawSql(query, params, myOptions);
const sales = await models.Sale.find({where: {ticketFk: args.id}}, myOptions);
const salesNewTicket = salesMovable.filter(sale => (sale.movable ? sale.movable : 0) >= sale.quantity);
const salesNewTicketLength = salesNewTicket.length;
if (salesNewTicketLength && (args.newTicket || sales.length != salesNewTicketLength)) {
const newTicket = await models.Ticket.transferSales(
ctx,
args.id,
args.newTicket,
salesNewTicket,
myOptions
);
args.id = newTicket.id;
}
}
const ticketToChange = await models.Ticket.findOne({
where: {id: args.id},
fields: [
'id',
'clientFk',
'agencyModeFk',
'addressFk',
'zoneFk',
'warehouseFk',
'companyFk',
'shipped',
'landed',
'isDeleted',
'routeFk',
'nickname'
],
include: [
{
relation: 'client',
scope: {
fields: 'salesPersonFk'
},
include: [
{
relation: 'address',
scope: {
fields: 'nickname'
}
}
]
},
]
}, myOptions);
const originalTicket = JSON.parse(JSON.stringify(ticketToChange));
const ticketChanges = {
clientFk: args.clientFk,
nickname: args.nickname,
agencyModeFk: args.agencyModeFk,
addressFk: args.addressFk,
zoneFk: args.zoneFk,
warehouseFk: args.warehouseFk,
companyFk: args.companyFk,
shipped: args.shipped,
landed: args.landed,
isDeleted: args.isDeleted
};
let response;
if (args.keepPrice) {
ticketChanges.routeFk = null;
response = await ticketToChange.updateAttributes(ticketChanges, myOptions);
} else {
const hasToBeUnrouted = true;
response = await Self.rawSql(
'CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
[args.id].concat(Object.values(ticketChanges), [hasToBeUnrouted, args.option]),
myOptions
);
}
if (args.isWithoutNegatives === false) delete args.isWithoutNegatives;
const updatedTicket = Object.assign({}, args);
delete updatedTicket.ctx;
delete updatedTicket.option;
if (ticketToChange.addressFk != updatedTicket.addressFk && args.id) {
await models.TicketObservation.destroyAll({
ticketFk: args.id
}, myOptions);
const address = await models.Address.findOne({
where: {id: args.addressFk},
include: {
relation: 'observations'
}
}, myOptions);
const observations = address.observations();
if (observations.length) {
const clonedObservations = observations.map(observation => {
observation.ticketFk = args.id;
observation.id = undefined;
return observation;
});
await models.TicketObservation.create(clonedObservations, myOptions);
}
}
const changes = loggable.getChanges(originalTicket, updatedTicket);
const hasChanges = Object.keys(changes.old).length > 0 || Object.keys(changes.new).length > 0;
if (hasChanges) {
delete changes.old.client;
delete changes.old.address;
delete changes.new.client;
delete changes.new.address;
const oldProperties = await loggable.translateValues(Self, changes.old);
const newProperties = await loggable.translateValues(Self, changes.new);
const salesPersonId = ticketToChange.client().salesPersonFk;
if (salesPersonId) {
const url = await Self.app.models.Url.getUrl();
let changesMade = '';
for (let change in newProperties) {
let value = newProperties[change];
let oldValue = oldProperties[change];
changesMade += `\r\n~${$t(change)}: ${oldValue}~ ➔ *${$t(change)}: ${value}*`;
}
const message = $t('Changed this data from the ticket', {
ticketId: args.id,
ticketUrl: `${url}ticket/${args.id}/sale`,
changes: changesMade
});
await models.Chat.sendCheckingPresence(ctx, salesPersonId, message);
}
}
response.id = args.id;
if (tx) await tx.commit();
return response;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
};
};