const pick = require('object.pick'); const LoopBackContext = require('loopback-context'); module.exports = function(Self) { Self.setup = function() { Self.super_.setup.call(this); }; /* Self.observe('after save', async function(ctx) { const loopBackContext = LoopBackContext.getCurrentContext(); await logInModel(ctx, loopBackContext); }); Self.observe('before save', async function(ctx) { let oldInstance; let oldInstanceFk; let newInstance; if (ctx.data) { oldInstanceFk = pick(ctx.currentInstance, Object.keys(ctx.data)); newInstance = await fkToValue(ctx.data, ctx); oldInstance = await fkToValue(oldInstanceFk, ctx); } if (ctx.isNewInstance) { newInstance = await fkToValue(ctx.instance.__data, ctx); } ctx.hookState.oldInstance = oldInstance; ctx.hookState.newInstance = newInstance; }); Self.observe('before delete', async function(ctx) { let oldInstance; // console.log(ctx.where); if (ctx.where) { let affectedModel = ctx.Model.definition.name; // console.log(affectedModel); let deletedInstances = await Self.modelBuilder.models[affectedModel].find({where: ctx.where}); // console.log(deletedInstances); let arrangedDeletedInstances = []; deletedInstances.forEach(async element => { console.log(element); arrangedDeletedInstances.push(await fkToValue(element, ctx)); }); console.log(arrangedDeletedInstances); // let deletedIntancesData = await fkToValue(deletedInstances, ctx); // console.log(deletedIntancesData); // oldInstanceFk = pick(ctx.currentInstance, Object.keys(ctx.data)); // oldInstance = await fkToValue(oldInstanceFk, ctx); } ctx.hookState.oldInstance = oldInstance; }); Self.observe('after delete', async function(ctx) { const loopBackContext = LoopBackContext.getCurrentContext(); await logInModel(ctx, loopBackContext); }); */ async function fkToValue(instance, ctx) { let result = {}; for (let key in instance) { if (key == 'id') continue; let val = instance[key]; console.log(val); if (val === undefined || val === null) continue; for (let key1 in ctx.Model.relations) { let val1 = ctx.Model.relations[key1]; if (val1.keyFrom == key) { let recordSet = await val1.modelTo.findById(val); val = recordSet.name; // FIXME preparar todos los modelos con campo name console.log(val); break; } } result[key] = val; } // console.log(result); return result; } async function logInModel(ctx, loopBackContext) { let definition = ctx.Model.definition; let primaryKey; for (let property in definition.properties) { if (definition.properties[property].id) { primaryKey = property; break; } } if (!primaryKey) throw new Error('Primary key not found'); let originId; // RELATIONS LOG let changedModelId; if (ctx.instance && !definition.settings.log.relation) { originId = ctx.instance.id; changedModelId = ctx.instance.id; } else if (definition.settings.log.relation) { primaryKey = ctx.Model.relations[definition.settings.log.relation].keyFrom; if (ctx.where && ctx.where[primaryKey]) originId = ctx.where[primaryKey]; else { originId = ctx.instance[primaryKey]; changedModelId = ctx.instance.id; } } else { originId = ctx.currentInstance.id; changedModelId = ctx.currentInstance.id; } // console.log(ctx.instance, ctx.where, ctx.currentInstance); // Sets the changedModelValue to save and the instances changed in case its an updateAll let changedModelValue = definition.settings.log.changedModelValue; if (changedModelValue && (!ctx.instance || !ctx.instance[changedModelValue])) { var where = []; changedModelId = []; let changedInstances = await Self.modelBuilder.models[definition.name].find({where: ctx.where, fields: ['id', changedModelValue]}); changedInstances.forEach(element => { where.push(element[changedModelValue]); changedModelId.push(element.id); }); } else if (ctx.hookState.oldInstance) { where = ctx.instance[changedModelValue]; } // console.log(where); // Set oldInstance, newInstance, userFk and action let oldInstance = {}; if (ctx.hookState.oldInstance) { Object.assign(oldInstance, ctx.hookState.oldInstance); } let newInstance = {}; if (ctx.hookState.newInstance) { Object.assign(newInstance, ctx.hookState.newInstance); } let userFk; if (loopBackContext) userFk = loopBackContext.active.accessToken.userId; let action = setActionType(ctx); let logRecord = { originFk: originId, userFk: userFk, action: action, changedModel: ctx.Model.definition.name, changedModelId: changedModelId, changedModelValue: where, oldInstance: oldInstance, newInstance: newInstance }; let logsToSave = setLogsToSave(where, changedModelId, logRecord); let logModel = definition.settings.log.model; let transaction = {}; if (ctx.options && ctx.options.transaction) { transaction = ctx.options.transaction; } // console.log(logsToSave); await Self.modelBuilder.models[logModel].create(logsToSave, transaction); } // this function retuns all the instances changed in case this is an updateAll function setLogsToSave(changedInstances, changedInstancesIds, logRecord) { let promises = []; if (changedInstances && typeof changedInstances == "object") { for (let i = 0; i < changedInstances.length; i++) { logRecord.changedModelId = changedInstancesIds[i]; logRecord.changedModelValue = changedInstances[i]; promises.push(JSON.parse(JSON.stringify(logRecord))); } } else { return logRecord; } return promises; } function setActionType(ctx) { let oldInstance = ctx.hookState.oldInstance; let newInstance = ctx.hookState.newInstance; if (oldInstance && newInstance) { return 'update'; } else if (!oldInstance && newInstance) { return 'insert'; } return 'delete'; } };