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

165 lines
5.2 KiB
JavaScript

const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('priceDifference', {
description: 'Returns sales with price difference if the ticket is editable',
accessType: 'READ',
accepts: [{
arg: 'id',
type: 'number',
required: true,
description: 'The ticket id',
http: {source: 'path'}
},
{
arg: 'landed',
type: 'date',
description: 'The landing date',
required: true
},
{
arg: 'addressId',
type: 'number',
description: 'The address id',
required: true
},
{
arg: 'agencyModeId',
type: 'number',
description: 'The agencyMode id',
required: true
},
{
arg: 'zoneId',
type: 'number',
description: 'The zone id',
required: true
},
{
arg: 'warehouseId',
type: 'number',
description: 'The warehouse id',
required: true
},
{
arg: 'shipped',
type: 'date',
description: 'shipped',
required: true
}],
returns: {
type: ['object'],
root: true
},
http: {
path: `/:id/priceDifference`,
verb: 'POST'
}
});
Self.priceDifference = async(ctx, options) => {
const args = ctx.args;
const models = Self.app.models;
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 {
await Self.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.addressId,
args.agencyModeId,
args.warehouseId,
myOptions);
if (!zoneShipped || zoneShipped.zoneFk != args.zoneId) {
const error = `You don't have privileges to change the zone`;
throw new UserError(error);
}
}
const items = await models.Sale.find({
where: {
ticketFk: args.id
},
order: 'concept ASC',
include: 'item'
}, myOptions);
const salesObj = {
items: items,
totalUnitPrice: 0.00,
totalNewPrice: 0.00,
totalDifference: 0.00,
};
// Get items movable
const ticketOrigin = await models.Ticket.findById(args.id, null, myOptions);
const differenceShipped = ticketOrigin.shipped.getTime() > args.shipped.getTime();
const differenceWarehouse = ticketOrigin.warehouseFk != args.warehouseId;
salesObj.haveDifferences = differenceShipped || differenceWarehouse;
let query = `CALL ticket_getMovable(?,?,?)`;
let params = [args.id, args.shipped, args.warehouseId];
const [salesMovable] = await Self.rawSql(query, params, myOptions);
const itemMovable = new Map();
for (let sale of salesMovable) {
const saleMovable = sale.movable ? sale.movable : 0;
itemMovable.set(sale.id, saleMovable);
}
// Sale price component, one per sale
query = `CALL vn.ticket_priceDifference(?, ?, ?, ?, ?)`;
params = [args.id, args.landed, args.addressId, args.zoneId, args.warehouseId];
const [difComponents] = await Self.rawSql(query, params, myOptions);
const map = new Map();
for (let difComponent of difComponents)
map.set(difComponent.saleFk, difComponent);
for (sale of salesObj.items) {
const difComponent = map.get(sale.id);
if (difComponent) {
sale.component = difComponent;
salesObj.totalDifference += difComponent.difference;
salesObj.totalDifference = round(salesObj.totalDifference);
salesObj.totalNewPrice += difComponent.newPrice;
salesObj.totalNewPrice = round(salesObj.totalNewPrice);
}
salesObj.totalUnitPrice += sale.price;
salesObj.totalUnitPrice = round(salesObj.totalUnitPrice);
sale.movable = itemMovable.get(sale.id);
}
if (tx) await tx.commit();
return salesObj;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
};
function round(value) {
return Math.round(value * 100) / 100;
}
};