2023-10-13 13:14:48 +00:00
|
|
|
const UserError = require('vn-loopback/util/user-error');
|
2023-10-16 08:10:57 +00:00
|
|
|
const LoopBackContext = require('loopback-context');
|
2023-10-13 13:14:48 +00:00
|
|
|
|
2018-05-04 09:46:03 +00:00
|
|
|
module.exports = Self => {
|
2018-08-30 09:02:50 +00:00
|
|
|
require('../methods/sale/getClaimableFromTicket')(Self);
|
2018-07-03 13:00:16 +00:00
|
|
|
require('../methods/sale/reserve')(Self);
|
2020-07-01 12:28:05 +00:00
|
|
|
require('../methods/sale/deleteSales')(Self);
|
2018-06-28 13:21:04 +00:00
|
|
|
require('../methods/sale/updatePrice')(Self);
|
|
|
|
require('../methods/sale/updateQuantity')(Self);
|
2019-09-06 09:43:15 +00:00
|
|
|
require('../methods/sale/updateConcept')(Self);
|
2019-11-21 11:00:56 +00:00
|
|
|
require('../methods/sale/recalculatePrice')(Self);
|
2022-04-04 11:26:53 +00:00
|
|
|
require('../methods/sale/refund')(Self);
|
2021-05-26 07:14:18 +00:00
|
|
|
require('../methods/sale/canEdit')(Self);
|
2022-10-20 13:05:46 +00:00
|
|
|
require('../methods/sale/usesMana')(Self);
|
2019-07-02 10:12:15 +00:00
|
|
|
|
|
|
|
Self.validatesPresenceOf('concept', {
|
|
|
|
message: `Concept cannot be blank`
|
|
|
|
});
|
2023-10-13 13:14:48 +00:00
|
|
|
|
|
|
|
Self.observe('before save', async ctx => {
|
|
|
|
const models = Self.app.models;
|
|
|
|
const changes = ctx.data || ctx.instance;
|
|
|
|
const instance = ctx.currentInstance;
|
2023-10-16 08:10:57 +00:00
|
|
|
|
2023-10-13 13:14:48 +00:00
|
|
|
const newQuantity = changes?.quantity;
|
2023-10-16 08:10:57 +00:00
|
|
|
if (newQuantity == null) return;
|
2023-10-13 13:14:48 +00:00
|
|
|
|
2023-10-16 08:10:57 +00:00
|
|
|
const loopBackContext = LoopBackContext.getCurrentContext();
|
|
|
|
ctx.req = loopBackContext.active;
|
2023-10-16 13:27:10 +00:00
|
|
|
if (await models.ACL.checkAccessAcl(ctx, 'Sale', 'canForceQuantity', 'WRITE')) return;
|
2023-10-13 13:14:48 +00:00
|
|
|
|
|
|
|
const ticketId = changes?.ticketFk || instance?.ticketFk;
|
|
|
|
const itemId = changes?.itemFk || instance?.itemFk;
|
2023-10-19 11:03:11 +00:00
|
|
|
const oldQuantity = instance?.quantity ?? null;
|
|
|
|
const quantityAdded = newQuantity - oldQuantity;
|
2023-10-13 13:14:48 +00:00
|
|
|
|
2023-10-16 08:10:57 +00:00
|
|
|
const ticket = await models.Ticket.findById(
|
|
|
|
ticketId,
|
|
|
|
{
|
2023-10-18 13:19:26 +00:00
|
|
|
fields: ['id', 'clientFk', 'warehouseFk', 'addressFk', 'agencyModeFk', 'shipped', 'landed'],
|
2023-10-16 08:10:57 +00:00
|
|
|
include: {
|
|
|
|
relation: 'client',
|
|
|
|
scope: {
|
|
|
|
fields: ['id', 'clientTypeFk'],
|
|
|
|
include: {
|
|
|
|
relation: 'type',
|
|
|
|
scope: {
|
|
|
|
fields: ['code', 'description']
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
ctx.options);
|
2023-10-16 13:27:10 +00:00
|
|
|
if (ticket?.client()?.type()?.code === 'loses') return;
|
2023-10-16 08:10:57 +00:00
|
|
|
|
2023-10-16 13:27:10 +00:00
|
|
|
const isRefund = await models.TicketRefund.findOne({
|
|
|
|
fields: ['id'],
|
|
|
|
where: {refundTicketFk: ticketId}
|
|
|
|
}, ctx.options);
|
|
|
|
if (isRefund) return;
|
2023-10-13 13:14:48 +00:00
|
|
|
|
2023-10-16 13:27:10 +00:00
|
|
|
if (newQuantity < 0)
|
2023-10-16 08:10:57 +00:00
|
|
|
throw new UserError('You can only add negative amounts in refund tickets');
|
|
|
|
|
2023-10-13 13:14:48 +00:00
|
|
|
const item = await models.Item.findOne({
|
2023-10-16 13:27:10 +00:00
|
|
|
fields: ['family', 'minQuantity'],
|
2023-10-13 13:14:48 +00:00
|
|
|
where: {id: itemId},
|
2023-10-16 13:27:10 +00:00
|
|
|
}, ctx.options);
|
|
|
|
if (item.family == 'EMB') return;
|
|
|
|
|
2023-10-20 10:37:44 +00:00
|
|
|
if (await models.ACL.checkAccessAcl(ctx, 'Sale', 'isInPreparing', '*')) return;
|
|
|
|
|
2023-10-19 11:03:11 +00:00
|
|
|
await models.Sale.rawSql(`CALL catalog_calcFromItem(?,?,?,?)`, [
|
2023-10-18 13:19:26 +00:00
|
|
|
ticket.landed,
|
|
|
|
ticket.addressFk,
|
|
|
|
ticket.agencyModeFk,
|
|
|
|
itemId
|
|
|
|
],
|
|
|
|
ctx.options);
|
|
|
|
|
2023-10-19 11:03:11 +00:00
|
|
|
const [itemInfo] = await models.Sale.rawSql(`SELECT available FROM tmp.ticketCalculateItem`, null, ctx.options);
|
|
|
|
|
|
|
|
if (!itemInfo?.available || itemInfo.available < quantityAdded)
|
2023-10-18 13:19:26 +00:00
|
|
|
throw new UserError(`This item is not available`);
|
2023-10-13 13:14:48 +00:00
|
|
|
|
2023-10-19 11:03:11 +00:00
|
|
|
if (await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*')) return;
|
|
|
|
|
|
|
|
if (newQuantity < item.minQuantity && newQuantity != itemInfo?.available)
|
|
|
|
throw new UserError('The amount cannot be less than the minimum');
|
|
|
|
|
|
|
|
if (ctx.isNewInstance || newQuantity <= oldQuantity) return;
|
|
|
|
|
|
|
|
const [saleGrouping] = await models.Sale.rawSql(`
|
2023-10-19 13:12:06 +00:00
|
|
|
SELECT t.price newPrice
|
2023-10-18 13:19:26 +00:00
|
|
|
FROM tmp.ticketComponentPrice t
|
2023-10-19 13:12:06 +00:00
|
|
|
ORDER BY (t.grouping <= ?) DESC, t.grouping ASC
|
|
|
|
LIMIT 1`,
|
2023-10-18 13:19:26 +00:00
|
|
|
[quantityAdded],
|
|
|
|
ctx.options);
|
|
|
|
|
2023-10-19 11:03:11 +00:00
|
|
|
await models.Sale.rawSql(`
|
|
|
|
DROP TEMPORARY TABLE IF EXISTS
|
2023-10-18 13:19:26 +00:00
|
|
|
tmp.ticketCalculateItem,
|
|
|
|
tmp.ticketComponentPrice,
|
|
|
|
tmp.ticketComponent,
|
|
|
|
tmp.ticketLot,
|
|
|
|
tmp.zoneGetShipped;
|
|
|
|
`, null, ctx.options);
|
|
|
|
|
2023-10-20 07:26:56 +00:00
|
|
|
if (!saleGrouping?.newPrice || saleGrouping.newPrice > instance.price)
|
2023-10-18 13:19:26 +00:00
|
|
|
throw new UserError('The price of the item changed');
|
2023-10-13 13:14:48 +00:00
|
|
|
});
|
2018-04-10 05:48:04 +00:00
|
|
|
};
|
2023-10-13 13:14:48 +00:00
|
|
|
|