Tarea #600 loggable
This commit is contained in:
parent
98d035a961
commit
43cbdefa22
|
@ -0,0 +1,50 @@
|
||||||
|
{
|
||||||
|
"name": "ClientLog",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "clientLog"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"id": true,
|
||||||
|
"type": "Number",
|
||||||
|
"forceId": false
|
||||||
|
},
|
||||||
|
"originFk": {
|
||||||
|
"type": "Number",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"userFk": {
|
||||||
|
"type": "Number",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"action": {
|
||||||
|
"type": "String",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"type": "String",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"oldInstance": {
|
||||||
|
"type": "Object",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"newInstance": {
|
||||||
|
"type": "Object",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"creationDate": {
|
||||||
|
"type": "Date"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"user": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Account",
|
||||||
|
"foreignKey": "userFk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,9 @@
|
||||||
{
|
{
|
||||||
"name": "Client",
|
"name": "Client",
|
||||||
"base": "VnModel",
|
"base": "Loggable",
|
||||||
|
"log": {
|
||||||
|
"model":"ClientLog"
|
||||||
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "client"
|
"table": "client"
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
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, next) {
|
||||||
|
let oldInstance;
|
||||||
|
if (ctx.instance) {
|
||||||
|
oldInstance = await fkToValue(ctx.data, ctx);
|
||||||
|
}
|
||||||
|
await logInModel(ctx);
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.observe('after delete', async function(ctx, next) {
|
||||||
|
let oldInstance;
|
||||||
|
if (ctx.instance) {
|
||||||
|
oldInstance = await fkToValue(ctx.data, ctx);
|
||||||
|
}
|
||||||
|
await logInModel(ctx);
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
async function fkToValue(instance, ctx) {
|
||||||
|
let result = {};
|
||||||
|
for (let key in instance) {
|
||||||
|
if (key == 'id') continue;
|
||||||
|
let val = instance[key];
|
||||||
|
if (val === undefined) 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
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result[key] = val;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (definition.settings.log.relation) {
|
||||||
|
// RELATIONS LOG
|
||||||
|
primaryKey = ctx.Model.relations[definition.settings.log.relation].keyFrom;
|
||||||
|
|
||||||
|
if(ctx.where && ctx.where[primaryKey])
|
||||||
|
originId = ctx.where[primaryKey]
|
||||||
|
else
|
||||||
|
originId = ctx.instance[primaryKey];
|
||||||
|
} else {
|
||||||
|
if (ctx.instance) {
|
||||||
|
originId = ctx.instance.id;
|
||||||
|
} else {
|
||||||
|
originId = ctx.currentInstance.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This adds the originDescription field if it doesnt exists in the instances
|
||||||
|
|
||||||
|
let originDescription = definition.settings.log.originDescription;
|
||||||
|
|
||||||
|
if (originDescription && (!ctx.instance || !ctx.instance[originDescription]))
|
||||||
|
await Self.modelBuilder.models[definition.name].findById()
|
||||||
|
|
||||||
|
if (ctx.hookState.oldInstance && !ctx.hookState.oldInstance[originDescription]){
|
||||||
|
ctx.hookState.oldInstance[originDescription] = ctx.instance[originDescription];
|
||||||
|
ctx.hookState.newInstance[originDescription] = ctx.instance[originDescription];
|
||||||
|
}
|
||||||
|
|
||||||
|
// This put some order in the intances putting the originDescription in first place
|
||||||
|
|
||||||
|
let oldInstance = {};
|
||||||
|
if (ctx.hookState.oldInstance) {
|
||||||
|
oldInstance[originDescription] = ctx.hookState.oldInstance[originDescription];
|
||||||
|
delete ctx.hookState.oldInstance[originDescription];
|
||||||
|
Object.assign(oldInstance, ctx.hookState.oldInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
let newInstance = {};
|
||||||
|
if (ctx.hookState.newInstance) {
|
||||||
|
newInstance[originDescription] = ctx.hookState.newInstance[originDescription];
|
||||||
|
delete ctx.hookState.newInstance[originDescription];
|
||||||
|
Object.assign(newInstance, ctx.hookState.newInstance)
|
||||||
|
}
|
||||||
|
|
||||||
|
let action = setActionType(ctx);
|
||||||
|
let userFk = loopBackContext.active.accessToken.userId;
|
||||||
|
|
||||||
|
let logRecord = {
|
||||||
|
originFk: originId,
|
||||||
|
userFk: userFk,
|
||||||
|
model: ctx.Model.definition.name,
|
||||||
|
action: action,
|
||||||
|
oldInstance: oldInstance,
|
||||||
|
newInstance: newInstance
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
let logModel = definition.settings.log.model
|
||||||
|
await Self.modelBuilder.models[logModel].create(logRecord);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setActionType(ctx) {
|
||||||
|
let oldInstance = ctx.hookState.oldInstance;
|
||||||
|
let newInstance = ctx.hookState.newInstance;
|
||||||
|
|
||||||
|
if (oldInstance && newInstance) {
|
||||||
|
return 'update';
|
||||||
|
} else if (!oldInstance && newInstance) {
|
||||||
|
return 'insert';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"name": "Loggable",
|
||||||
|
"base": "VnModel",
|
||||||
|
"validateUpsert": true
|
||||||
|
}
|
|
@ -45,6 +45,9 @@
|
||||||
"Client": {
|
"Client": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"ClientLog": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"ClientCreditLimit": {
|
"ClientCreditLimit": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue