const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; module.exports = Self => { Self.remoteMethodCtx('importBuys', { description: 'Imports the buys from a list', accessType: 'WRITE', accepts: [{ arg: 'id', type: 'number', required: true, description: 'The entry id', http: {source: 'path'} }, { arg: 'reference', type: 'string', description: 'The buyed boxes ids', }, { arg: 'invoiceNumber', type: 'string', description: 'The registered invoice number', }, { arg: 'observation', type: 'string', description: 'The observation', }, { arg: 'buys', type: ['object'], description: 'The buys', }], returns: { type: ['object'], root: true }, http: { path: `/:id/importBuys`, verb: 'POST' } }); Self.importBuys = async(ctx, id, options) => { const conn = Self.dataSource.connector; const args = ctx.args; const models = Self.app.models; let tx; const myOptions = {userId: ctx.req.accessToken.userId}; if (typeof options == 'object') Object.assign(myOptions, options); if (!myOptions.transaction) { tx = await Self.beginTransaction({}); myOptions.transaction = tx; } try { const entry = await models.Entry.findById(id, { include: [{ relation: 'travel', scope: { fields: ['warehouseInFk', 'landed'], } }] }, myOptions); await entry.updateAttributes({ observation: args.observation, reference: args.reference, invoiceNumber: args.invoiceNumber }, myOptions); const travel = entry.travel(); await Self.rawSql('CALL buyUltimate(?, ?)', [ travel.warehouseInFk, travel.landed ], myOptions); const buyUltimate = await Self.rawSql(` SELECT * FROM tmp.buyUltimate WHERE warehouseFk = ? `, [travel.warehouseInFk], myOptions); const lastItemBuys = new Map(); for (const buy of buyUltimate) lastItemBuys.set(buy.itemFk, buy); const buys = []; for (let buy of args.buys) { if (!buy.itemFk) throw new Error('The item is required'); const lastItemBuy = lastItemBuys.get(buy.itemFk); if (!lastItemBuy) continue; const lastBuy = await models.Buy.findById(lastItemBuy.buyFk, null, myOptions); const stickers = 1; const quantity = (stickers * buy.packing); buys.push({ entryFk: entry.id, itemFk: buy.itemFk, stickers: stickers, quantity: quantity, packing: buy.packing, grouping: buy.grouping, buyingValue: buy.buyingValue, packagingFk: buy.packagingFk, groupingMode: lastBuy.groupingMode, weight: lastBuy.weight }); await models.ItemMatchProperties.upsert({ itemFk: buy.itemFk, name: buy.description, producer: buy.companyName, size: buy.size }, myOptions); } if (!buys.length) return; const createdBuys = await models.Buy.create(buys, myOptions); const buyIds = createdBuys.map(buy => buy.id); const stmts = []; let stmt; stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.buyRecalc'); stmt = new ParameterizedSQL( `CREATE TEMPORARY TABLE tmp.buyRecalc (INDEX (id)) ENGINE = MEMORY SELECT ? AS id`, [buyIds]); stmts.push(stmt); stmts.push('CALL buy_recalcPrices()'); const sql = ParameterizedSQL.join(stmts, ';'); await conn.executeStmt(sql, myOptions); if (tx) await tx.commit(); } catch (e) { if (tx) await tx.rollback(); throw e; } }; };