diff --git a/loopback/common/models/loggable.js b/loopback/common/models/loggable.js index c26e66dad..557aad66a 100644 --- a/loopback/common/models/loggable.js +++ b/loopback/common/models/loggable.js @@ -1,5 +1,5 @@ +const pick = require('object.pick'); const LoopBackContext = require('loopback-context'); -const log = require('vn-loopback/util/log'); module.exports = function(Self) { Self.setup = function() { @@ -14,8 +14,6 @@ module.exports = function(Self) { Self.observe('before save', async function(ctx) { const appModels = ctx.Model.app.models; const definition = ctx.Model.definition; - const modelName = definition.name; - const model = appModels[modelName]; const options = {}; // Check for transactions @@ -26,12 +24,13 @@ module.exports = function(Self) { let newInstance; if (ctx.data) { - const changes = log.getChanges(ctx.currentInstance, ctx.data); - oldInstance = await log.translateValues(model, changes.old, options); - newInstance = await log.translateValues(model, changes.new, options); + const changes = pick(ctx.currentInstance, Object.keys(ctx.data)); + newInstance = await fkToValue(ctx.data, ctx); + oldInstance = await fkToValue(changes, ctx); if (ctx.where && !ctx.currentInstance) { const fields = Object.keys(ctx.data); + const modelName = definition.name; ctx.oldInstances = await appModels[modelName].find({ where: ctx.where, @@ -42,42 +41,40 @@ module.exports = function(Self) { // Get changes from created instance if (ctx.isNewInstance) - newInstance = await log.translateValues(model, ctx.instance.__data, options); + newInstance = await fkToValue(ctx.instance.__data, ctx); ctx.hookState.oldInstance = oldInstance; ctx.hookState.newInstance = newInstance; }); Self.observe('before delete', async function(ctx) { - const models = ctx.Model.app.models; + const appModels = ctx.Model.app.models; const definition = ctx.Model.definition; const relations = ctx.Model.relations; - const options = {}; + let options = {}; if (ctx.options && ctx.options.transaction) options.transaction = ctx.options.transaction; if (ctx.where) { - const modelName = definition.name; - const model = models[modelName]; - const deletedRows = await model.find({ + let affectedModel = definition.name; + let deletedInstances = await appModels[affectedModel].find({ where: ctx.where }, options); - const relation = definition.settings.log.relation; + let relation = definition.settings.log.relation; if (relation) { - const primaryKey = relations[relation].keyFrom; + let primaryKey = relations[relation].keyFrom; - const instances = []; - for (let instance of deletedRows) { - const translatedValues = await log.translateValues(model, instance, options); + let arrangedDeletedInstances = []; + for (let i = 0; i < deletedInstances.length; i++) { if (primaryKey) - translatedValues.originFk = instance[primaryKey]; - instances.push(translatedValues); + deletedInstances[i].originFk = deletedInstances[i][primaryKey]; + let arrangedInstance = await fkToValue(deletedInstances[i], ctx); + arrangedDeletedInstances[i] = arrangedInstance; } - - ctx.hookState.oldInstance = instances; + ctx.hookState.oldInstance = arrangedDeletedInstances; } } }); @@ -119,6 +116,74 @@ module.exports = function(Self) { }); } + // Get log values from a foreign key + async function fkToValue(instance, ctx) { + const appModels = ctx.Model.app.models; + const relations = ctx.Model.relations; + let options = {}; + + // Check for transactions + if (ctx.options && ctx.options.transaction) + options.transaction = ctx.options.transaction; + + const instanceCopy = JSON.parse(JSON.stringify(instance)); + const result = {}; + for (const key in instanceCopy) { + let value = instanceCopy[key]; + + if (value instanceof Object) + continue; + + if (value === undefined) continue; + + if (value) { + for (let relationName in relations) { + const relation = relations[relationName]; + if (relation.keyFrom == key && key != 'id') { + const model = relation.modelTo; + const modelName = relation.modelTo.modelName; + const properties = model && model.definition.properties; + const settings = model && model.definition.settings; + + const recordSet = await appModels[modelName].findById(value, null, options); + + const hasShowField = settings.log && settings.log.showField; + let showField = hasShowField && recordSet + && recordSet[settings.log.showField]; + + if (!showField) { + const showFieldNames = [ + 'name', + 'description', + 'code', + 'nickname' + ]; + for (field of showFieldNames) { + const propField = properties && properties[field]; + const recordField = recordSet && recordSet[field]; + + if (propField && recordField) { + showField = field; + break; + } + } + } + + if (showField && recordSet && recordSet[showField]) { + value = recordSet[showField]; + break; + } + + value = recordSet && recordSet.id || value; + break; + } + } + } + result[key] = value; + } + return result; + } + async function logInModel(ctx, loopBackContext) { const appModels = ctx.Model.app.models; const definition = ctx.Model.definition; @@ -262,8 +327,8 @@ module.exports = function(Self) { } function setActionType(ctx) { - const oldInstance = ctx.hookState.oldInstance; - const newInstance = ctx.hookState.newInstance; + let oldInstance = ctx.hookState.oldInstance; + let newInstance = ctx.hookState.newInstance; if (oldInstance && newInstance) return 'update'; diff --git a/loopback/util/log.js b/loopback/util/log.js index 067e458ec..9832a018a 100644 --- a/loopback/util/log.js +++ b/loopback/util/log.js @@ -47,9 +47,10 @@ exports.translateValues = async(instance, changes, options = {}) => { const relation = getRelation(instance, property); const value = properties[property]; + const hasValue = value != null && value != undefined; let finalValue = value; - if (relation) { + if (relation && hasValue) { let fieldsToShow = ['nickname', 'name', 'code', 'description']; const modelName = relation.model; const model = models[modelName]; @@ -58,9 +59,6 @@ exports.translateValues = async(instance, changes, options = {}) => { if (log && log.showField) fieldsToShow = [log.showField]; - console.log('Falla aqui? ', value); - console.log('property: ', property); - console.log('changes: ', changes); const row = await model.findById(value, { fields: fieldsToShow }, options); @@ -86,10 +84,13 @@ exports.translateValues = async(instance, changes, options = {}) => { exports.getChanges = (original, changes) => { const oldChanges = {}; const newChanges = {}; + for (let property in changes) { const firstChar = property.substring(0, 1); const isPrivate = firstChar == '$'; - if (changes[property] != original[property] && !isPrivate) { + if (isPrivate) return; + + if (changes[property] != original[property]) { newChanges[property] = changes[property]; if (original[property] != undefined) diff --git a/modules/ticket/back/methods/ticket-tracking/specs/setDelivered.spec.js b/modules/ticket/back/methods/ticket-tracking/specs/setDelivered.spec.js index 0d443fd80..694cbf8c6 100644 --- a/modules/ticket/back/methods/ticket-tracking/specs/setDelivered.spec.js +++ b/modules/ticket/back/methods/ticket-tracking/specs/setDelivered.spec.js @@ -1,7 +1,7 @@ const app = require('vn-loopback/server/server'); const LoopBackContext = require('loopback-context'); -fdescribe('ticket setDelivered()', () => { +describe('ticket setDelivered()', () => { const userId = 50; const activeCtx = { accessToken: {userId: userId}, @@ -23,8 +23,6 @@ fdescribe('ticket setDelivered()', () => { ticketOne = await app.models.Ticket.create(originalTicketOne); ticketTwo = await app.models.Ticket.create(originalTicketTwo); - console.log(ticketOne); - console.log(ticketTwo); } catch (error) { console.error(error); } @@ -34,10 +32,8 @@ fdescribe('ticket setDelivered()', () => { afterAll(async done => { try { - console.log(ticketOne); - console.log(ticketTwo); - // await app.models.Ticket.destroyById(ticketOne.id); - // await app.models.Ticket.destroyById(ticketTwo.id); + await app.models.Ticket.destroyById(ticketOne.id); + await app.models.Ticket.destroyById(ticketTwo.id); } catch (error) { console.error(error); }