This commit is contained in:
Carlos Jimenez Ruiz 2019-05-15 13:07:44 +02:00
commit 41c20d977c
2 changed files with 90 additions and 64 deletions

View File

@ -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);
});
}
};

View File

@ -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;
});