module.exports = Self => { Self.remoteMethod('clone', { description: 'Clone zone and all its properties including geolocations', accessType: 'WRITE', accepts: { arg: 'id', type: 'number', required: true, description: 'Zone id', http: {source: 'path'} }, returns: { root: true, type: 'Object' }, http: { path: '/:id/clone', verb: 'POST' } }); Self.clone = async id => { const models = Self.app.models; const transaction = await Self.beginTransaction({}); const options = {transaction}; // Find original zone const zone = await models.Zone.findOne({ fields: [ 'name', 'hour', 'warehouseFk', 'agencyModeFk', 'travelingDays', 'price', 'bonus', 'isVolumetric'], where: {id} }, options); const hour = zone.hour; const offset = hour.getTimezoneOffset() * 60000; hour.setTime(hour.getTime() + offset); // Find all original included geolocations const includedGeo = await models.ZoneIncluded.find({ fields: ['geoFk', 'isIncluded'], where: {zoneFk: id} }, options); // Find all original selected days const calendarDays = await models.ZoneCalendar.find({ where: {zoneFk: id} }, options); try { const newZone = await Self.create(zone, options); const newIncludedGeo = includedGeo.map(included => { included.zoneFk = newZone.id; return included; }); const newCalendayDays = calendarDays.map(day => { day.zoneFk = newZone.id; return day; }); await models.ZoneIncluded.create(newIncludedGeo, options); await models.ZoneCalendar.create(newCalendayDays, options); await transaction.commit(); return newZone; } catch (e) { await transaction.rollback(); throw e; } }; };