let UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethod('clone', { description: 'clone item', accessType: 'WRITE', accepts: [{ arg: 'id', type: 'number', required: true, description: 'origin itemId', http: {source: 'path'} }], returns: { type: 'object', description: 'new cloned itemId', root: true, }, http: { path: `/:id/clone`, verb: 'post' } }); Self.clone = async(itemId, options) => { let tx; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); if (!myOptions.transaction) { tx = await Self.beginTransaction({}); myOptions.transaction = tx; } try { const origin = await Self.findById(itemId, null, myOptions); if (!origin) throw new UserError(`This item doesn't exists`); origin.itemTag = undefined; origin.description = undefined; origin.comment = undefined; origin.size = undefined; const newItem = await Self.create(origin, myOptions); await cloneTaxes(origin.id, newItem.id, myOptions); await cloneBotanical(origin.id, newItem.id, myOptions); await cloneTags(origin.id, newItem.id, myOptions); if (tx) await tx.commit(); return newItem; } catch (e) { if (tx) await tx.rollback(); throw e; } }; /** * Clone original taxes to new item * @param {Integer} originalId - Original item id * @param {Integer} newId - New item id * @param {Object} options - Transaction options */ async function cloneTaxes(originalId, newId, options) { const models = Self.app.models; const originalTaxes = await models.ItemTaxCountry.find({ where: {itemFk: originalId}, fields: ['countryFk', 'taxClassFk'] }, options); const promises = []; for (tax of originalTaxes) { tax.itemFk = newId; const newTax = models.ItemTaxCountry.upsertWithWhere({ itemFk: newId, countryFk: tax.countryFk, }, tax, options); promises.push(newTax); } await Promise.all(promises); } /** * Clone original botanical to new item * @param {Integer} originalId - Original item id * @param {Integer} newId - New item id * @param {Object} options - Transaction options */ async function cloneBotanical(originalId, newId, options) { const models = Self.app.models; const botanical = await models.ItemBotanical.findOne({ where: {itemFk: originalId}, fields: ['genusFk', 'specieFk'] }, options); if (botanical) { botanical.itemFk = newId; await models.ItemBotanical.create(botanical, options); } } /** * Clone original item tags to new item * @param {Integer} originalId - Original item id * @param {Integer} newId - New item id * @param {Object} options - Transaction options */ async function cloneTags(originalId, newId, options) { const models = Self.app.models; const originalTags = await models.ItemTag.find({ where: { itemFk: originalId }, fields: ['tagFk', 'value', 'priority'] }, options); const promises = []; for (tag of originalTags) { tag.itemFk = newId; const newItemTag = models.ItemTag.create(tag, options); promises.push(newItemTag); } await Promise.all(promises); } };