From 307cffcb5855024bc994c86aa23a7e0c972cb351 Mon Sep 17 00:00:00 2001 From: Joan Sanchez Date: Wed, 15 May 2019 12:57:46 +0200 Subject: [PATCH] fixed item clone #1429 --- modules/item/back/methods/item/clone.js | 150 ++++++++++-------- .../back/methods/item/specs/clone.spec.js | 4 +- 2 files changed, 90 insertions(+), 64 deletions(-) diff --git a/modules/item/back/methods/item/clone.js b/modules/item/back/methods/item/clone.js index b8c1727cd..fc1682912 100644 --- a/modules/item/back/methods/item/clone.js +++ b/modules/item/back/methods/item/clone.js @@ -1,3 +1,5 @@ +let UserError = require('vn-loopback/util/user-error'); + module.exports = Self => { Self.remoteMethod('clone', { description: 'clone item', @@ -10,8 +12,9 @@ module.exports = Self => { http: {source: 'path'} }], returns: { - arg: 'id', - description: 'new cloned itemId' + type: 'Object', + description: 'new cloned itemId', + root: true, }, http: { path: `/:id/clone`, @@ -20,76 +23,99 @@ module.exports = Self => { }); Self.clone = async itemId => { - let $ = Self.app.models; let transaction = await Self.beginTransaction({}); - let filter = { - where: { - id: itemId - }, - include: [ - {relation: 'tags', scope: {order: 'priority ASC', include: {relation: 'tag'}}} - ] - }; + let options = {transaction}; try { - let origin = await Self.findOne(filter); - let copy = JSON.parse(JSON.stringify(origin)); + const origin = await Self.findById(itemId, options); + if (!origin) + throw new UserError(`That item doesn't exists`); - delete copy.id; - delete copy.itemTag; - delete copy.description; - delete copy.image; - delete copy.comment; + const newItem = await Self.create(origin, options); + let promises = []; - let newItem = await Self.create(copy); - - let botanical = await $.ItemBotanical.findOne({ - where: {itemFk: origin.id}, - fields: ['botanical', 'genusFk', 'specieFk'] - }, {options: transaction}); - - if (botanical) { - botanical.itemFk = newItem.id; - await $.ItemBotanical.create(botanical); - } - - - let copyTags = await $.ItemTag.find({ - where: { - itemFk: origin.id - }, - fields: ['tagFk', 'value', 'priority'] - }, {options: transaction}); - - for (let i = 0; i < copyTags.length; i++) { - copyTags[i].itemFk = newItem.id; - await $.ItemTag.upsert(copyTags[i], {options: transaction}); - } - - let copyTaxes = await Self.app.models.ItemTaxCountry.find({ - where: {itemFk: origin.id}, - fields: ['botanical', 'countryFk', 'taxClassFk'] - }, {options: transaction}); - - for (let i = 0; i < copyTaxes.length; i++) { - let tax = copyTaxes[i]; - tax.itemFk = newItem.id; - await Self.app.models.ItemTaxCountry.upsertWithWhere( - { - itemFk: tax.itemFk, - countryFk: tax.countryFk, - taxClassFk: tax.taxClassFk, - }, - tax, - {options: transaction} - ); - } + await cloneTaxes(origin.id, newItem.id, promises, options); + await cloneBotanical(origin.id, newItem.id, promises, options); + await cloneTags(origin.id, newItem.id, promises, options); + await Promise.all(promises); await transaction.commit(); - return newItem.id; + + return newItem; } catch (e) { await transaction.rollback(); throw e; } }; + + /** + * Clone original taxes to new item + * @param {Integer} originalId - Original item id + * @param {Integer} newId - New item id + * @param {Array} promises - Array of promises + * @param {Object} options - Transaction options + */ + async function cloneTaxes(originalId, newId, promises, options) { + const models = Self.app.models; + const originalTaxes = await models.ItemTaxCountry.find({ + where: {itemFk: originalId}, + fields: ['botanical', 'countryFk', 'taxClassFk'] + }, options); + + originalTaxes.forEach(tax => { + tax.itemFk = newId; + + const newItemTax = models.ItemTaxCountry.upsertWithWhere({ + itemFk: newId, + countryFk: tax.countryFk, + }, tax, options); + + promises.push(newItemTax); + }); + } + + /** + * Clone original botanical to new item + * @param {Integer} originalId - Original item id + * @param {Integer} newId - New item id + * @param {Array} promises - Array of promises + * @param {Object} options - Transaction options + */ + async function cloneBotanical(originalId, newId, promises, options) { + const models = Self.app.models; + const botanical = await models.ItemBotanical.findOne({ + where: {itemFk: originalId}, + fields: ['botanical', 'genusFk', 'specieFk'] + }, options); + + if (botanical) { + botanical.itemFk = newId; + const newBotanical = models.ItemBotanical.create(botanical, options); + promises.push(newBotanical); + } + } + + /** + * Clone original item tags to new item + * @param {Integer} originalId - Original item id + * @param {Integer} newId - New item id + * @param {Array} promises - Array of promises + * @param {Object} options - Transaction options + */ + async function cloneTags(originalId, newId, promises, options) { + const models = Self.app.models; + const originalTags = await models.ItemTag.find({ + where: { + itemFk: originalId + }, + fields: ['tagFk', 'value', 'priority'] + }, options); + + originalTags.forEach(tag => { + tag.itemFk = newId; + + const newTag = models.ItemTag.create(tag, options); + promises.push(newTag); + }); + } }; diff --git a/modules/item/back/methods/item/specs/clone.spec.js b/modules/item/back/methods/item/specs/clone.spec.js index 8bae14133..859a3167f 100644 --- a/modules/item/back/methods/item/specs/clone.spec.js +++ b/modules/item/back/methods/item/specs/clone.spec.js @@ -16,7 +16,7 @@ describe('item clone()', () => { let itemFk = 1; let result = await app.models.Item.clone(itemFk); - expect(result).toEqual(nextItemId); + expect(result.id).toEqual(nextItemId); }); it('should attempt to clone the given item but give an error as it doesnt exist', async() => { @@ -24,7 +24,7 @@ describe('item clone()', () => { let itemFk = 999; await app.models.Item.clone(itemFk) .catch(e => { - expect(e.message).toContain('Cannot convert undefined or null to object'); + expect(e.message).toContain(`That item doesn't exists`); error = e; });