let UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethodCtx('confirm', { description: '', accessType: 'WRITE', accepts: [{ arg: 'id', type: 'Integer', required: true, description: 'The request ID', }, { arg: 'itemFk', type: 'Integer', required: true, description: 'The requested item ID', }, { arg: 'quantity', type: 'Integer', required: true, description: 'The requested item quantity', }], returns: { type: 'Object', root: true }, http: { path: `/:id/confirm`, verb: 'post' } }); Self.confirm = async ctx => { const models = Self.app.models; let sale; let tx = await Self.beginTransaction({}); try { let options = {transaction: tx}; let item = await models.Item.findById(ctx.args.itemFk); if (!item) throw new UserError(`That item doesn't exists`); let request = await models.TicketRequest.findById(ctx.args.id, { include: {relation: 'ticket'} }); let [[stock]] = await Self.rawSql(`CALL vn.getItemVisibleAvailable(?,?,?,?)`, [ ctx.args.itemFk, request.ticket().shipped, request.ticket().warehouseFk, false ]); if (stock.available < ctx.args.quantity) throw new UserError(`This item is not available`); if (request.saleFk) { sale = await models.Sale.findById(request.saleFk); sale.updateAttributes({ itemFk: ctx.args.itemFk, quantity: ctx.args.quantity, concept: item.name, }, options); } else { sale = await models.Sale.create({ ticketFk: request.ticketFk, itemFk: ctx.args.itemFk, quantity: ctx.args.quantity, concept: item.name }, options); request.updateAttributes({saleFk: sale.id, itemFk: sale.itemFk, isOk: true}, options); } query = `CALL vn.ticketCalculateSale(?)`; await Self.rawSql(query, [sale.id], options); const message = `Se ha comprado ${sale.quantity} unidades de "${sale.concept}" (#${sale.itemFk}) ` + `para el ticket #${sale.ticketFk}`; await models.Message.send(ctx, { recipientFk: request.requesterFk, message: message }, options); await tx.commit(); } catch (error) { await tx.rollback(); throw error; } }; };