const UserError = require('vn-loopback/util/user-error'); const LoopBackContext = require('loopback-context'); module.exports = Self => { require('../methods/sale/getClaimableFromTicket')(Self); require('../methods/sale/reserve')(Self); require('../methods/sale/deleteSales')(Self); require('../methods/sale/updatePrice')(Self); require('../methods/sale/updateQuantity')(Self); require('../methods/sale/updateConcept')(Self); require('../methods/sale/recalculatePrice')(Self); require('../methods/sale/refund')(Self); require('../methods/sale/canEdit')(Self); require('../methods/sale/usesMana')(Self); Self.validatesPresenceOf('concept', { message: `Concept cannot be blank` }); Self.observe('before save', async ctx => { const models = Self.app.models; const changes = ctx.data || ctx.instance; const instance = ctx.currentInstance; const newQuantity = changes?.quantity; if (newQuantity == null) return; const loopBackContext = LoopBackContext.getCurrentContext(); ctx.req = loopBackContext.active; if (await models.ACL.checkAccessAcl(ctx, 'Sale', 'canForceQuantity', 'WRITE')) return; const ticketId = changes?.ticketFk || instance?.ticketFk; const itemId = changes?.itemFk || instance?.itemFk; const ticket = await models.Ticket.findById( ticketId, { fields: ['id', 'clientFk', 'warehouseFk', 'addressFk', 'agencyModeFk', 'shipped', 'landed'], include: { relation: 'client', scope: { fields: ['id', 'clientTypeFk'], include: { relation: 'type', scope: { fields: ['code', 'description'] } } } } }, ctx.options); if (ticket?.client()?.type()?.code === 'loses') return; const isRefund = await models.TicketRefund.findOne({ fields: ['id'], where: {refundTicketFk: ticketId} }, ctx.options); if (isRefund) return; if (newQuantity < 0) throw new UserError('You can only add negative amounts in refund tickets'); const item = await models.Item.findOne({ fields: ['family', 'minQuantity'], where: {id: itemId}, }, ctx.options); if (item.family == 'EMB') return; if (newQuantity < item.minQuantity) throw new UserError('The amount cannot be less than the minimum'); const oldQuantity = instance?.quantity ?? null; const quantityAdded = newQuantity - oldQuantity; if (await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*')) return; if (ctx.isNewInstance || newQuantity <= oldQuantity) return; await Self.rawSql(`CALL catalog_calcFromItem(?,?,?,?)`, [ ticket.landed, ticket.addressFk, ticket.agencyModeFk, itemId ], ctx.options); const [itemInfo] = await Self.rawSql(`SELECT available FROM tmp.ticketCalculateItem`, null, ctx.options); if (itemInfo?.available < quantityAdded) throw new UserError(`This item is not available`); const [saleGrouping] = await Self.rawSql(` SELECT MAX(t.grouping), t.price newPrice FROM tmp.ticketComponentPrice t WHERE t.grouping <= ?`, [quantityAdded], ctx.options); await Self.rawSql(` DROP TEMPORARY TABLE tmp.ticketCalculateItem, tmp.ticketComponentPrice, tmp.ticketComponent, tmp.ticketLot, tmp.zoneGetShipped; `, null, ctx.options); if (!saleGrouping?.newPrice || instance.price < saleGrouping.newPrice) throw new UserError('The price of the item changed'); }); };