Merge pull request 'fixes #5546 Actualizar código de registro de histórico de los modelos' (!1436) from 5546-codigo-registro into dev
gitea/salix/pipeline/head There was a failure building this commit Details

Reviewed-on: #1436
Reviewed-by: Juan Ferrer <juan@verdnatura.es>
This commit is contained in:
Alexandre Riera 2023-04-14 05:32:11 +00:00
commit ecac5fffd4
76 changed files with 313 additions and 597 deletions

View File

@ -28,22 +28,4 @@ describe('Client log path', () => {
it('should navigate to the log section', async() => { it('should navigate to the log section', async() => {
await page.accessToSection('client.card.log'); await page.accessToSection('client.card.log');
}); });
it('should check the previous value of the last logged change', async() => {
let lastModificationPreviousValue = await page
.waitToGetProperty(selectors.clientLog.lastModificationPreviousValue, 'innerText');
expect(lastModificationPreviousValue).toContain('DavidCharlesHaller');
});
it('should check the current value of the last logged change', async() => {
let lastModificationPreviousValue = await page
.waitToGetProperty(selectors.clientLog.lastModificationPreviousValue, 'innerText');
let lastModificationCurrentValue = await page.
waitToGetProperty(selectors.clientLog.lastModificationCurrentValue, 'innerText');
expect(lastModificationPreviousValue).toEqual('DavidCharlesHaller');
expect(lastModificationCurrentValue).toEqual('this is a test');
});
}); });

View File

@ -42,23 +42,4 @@ describe('Item log path', () => {
await page.waitForSelector(selectors.itemsIndex.createItemButton); await page.waitForSelector(selectors.itemsIndex.createItemButton);
await page.waitForState('item.index'); await page.waitForState('item.index');
}); });
it(`should search for the created item and navigate to it's log section`, async() => {
await page.accessToSearchResult('Knowledge artifact');
await page.accessToSection('item.card.log');
});
it(`should confirm the log is showing 4 entries`, async() => {
await page.waitForSelector(selectors.itemLog.anyLineCreated);
const anyLineCreatedCount = await page.countElement(selectors.itemLog.anyLineCreated);
expect(anyLineCreatedCount).toEqual(4);
});
xit(`should confirm the log is showing the intrastat for the created item`, async() => {
const fifthLineCreatedProperty = await page
.waitToGetProperty(selectors.itemLog.fifthLineCreatedProperty, 'innerText');
expect(fifthLineCreatedProperty).toEqual('05080000');
});
}); });

View File

@ -29,20 +29,4 @@ describe('Ticket expeditions and log path', () => {
expect(result).toEqual(3); expect(result).toEqual(3);
}); });
it(`should confirm the expedition deleted is shown now in the ticket log`, async() => {
await page.accessToSection('ticket.card.log');
const user = await page
.waitToGetProperty(selectors.ticketLog.user, 'innerText');
const action = await page
.waitToGetProperty(selectors.ticketLog.action, 'innerText');
const id = await page
.waitToGetProperty(selectors.ticketLog.id, 'innerText');
expect(user).toContain('production');
expect(action).toContain('Deletes');
expect(id).toEqual('2');
});
}); });

View File

@ -31,30 +31,4 @@ describe('Ticket log path', () => {
expect(message.text).toContain('Data saved!'); expect(message.text).toContain('Data saved!');
}); });
it('should navigate to the log section', async() => {
await page.accessToSection('ticket.card.log');
});
it('should set the viewport width to 1920 to see the table full width', async() => {
await page.setViewport({
width: 1920,
height: 0,
});
const result = await page.waitToGetProperty(selectors.ticketLog.firstTD, 'innerText');
expect(result.length).not.toBeGreaterThan('20');
});
it('should set the viewport width to 800 to see the table shrink and move data to the 1st column', async() => {
await page.setViewport({
width: 800,
height: 0,
});
const result = await page.waitToGetProperty(selectors.ticketLog.firstTD, 'innerText');
expect(result.length).toBeGreaterThan('15');
});
}); });

View File

@ -29,14 +29,4 @@ describe('Zone descriptor path', () => {
expect(count).toEqual(0); expect(count).toEqual(0);
}); });
it('should check the ticket whom lost the zone and see evidence on the logs', async() => {
await page.waitToClick(selectors.globalItems.homeButton);
await page.selectModule('ticket');
await page.accessToSearchResult('20');
await page.accessToSection('ticket.card.log');
const lastChanges = await page.waitToGetProperty(selectors.ticketLog.changes, 'innerText');
expect(lastChanges).toContain('1');
});
}); });

View File

@ -64,14 +64,4 @@ describe('Supplier basic data path', () => {
expect(result).toEqual('Some notes'); expect(result).toEqual('Some notes');
}); });
it('should navigate to the log section', async() => {
await page.accessToSection('supplier.card.log');
});
it('should check the changes have been recorded', async() => {
const result = await page.waitToGetProperty('vn-tr table tr:nth-child(3) td.after', 'innerText');
expect(result).toEqual('Some notes');
});
}); });

View File

@ -1,6 +1,20 @@
const app = require('vn-loopback/server/server'); const app = require('vn-loopback/server/server');
const LoopBackContext = require('loopback-context');
describe('Model crud()', () => { describe('Model crud()', () => {
beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
let insertId; let insertId;
const barcodeModel = app.models.ItemBarcode; const barcodeModel = app.models.ItemBarcode;

View File

@ -1,6 +1,21 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('Model rewriteDbError()', () => { describe('Model rewriteDbError()', () => {
beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
it('should extend rewriteDbError properties to any model passed', () => { it('should extend rewriteDbError properties to any model passed', () => {
const exampleModel = models.ItemTag; const exampleModel = models.ItemTag;

View File

@ -1,41 +1,9 @@
const mysql = require('mysql'); const mysql = require('mysql');
const MySQL = require('loopback-connector-mysql').MySQL; const MySQL = require('loopback-connector-mysql').MySQL;
const EnumFactory = require('loopback-connector-mysql').EnumFactory; const EnumFactory = require('loopback-connector-mysql').EnumFactory;
const { Transaction, SQLConnector, ParameterizedSQL } = require('loopback-connector'); const {Transaction, SQLConnector, ParameterizedSQL} = require('loopback-connector');
const fs = require('fs'); const fs = require('fs');
const limitSet = new Set([
'save',
'updateOrCreate',
'replaceOrCreate',
'replaceById',
'update'
]);
const opOpts = {
update: [
'update',
'replaceById',
// |insert
'save',
'updateOrCreate',
'replaceOrCreate'
],
delete: [
'destroy',
'destroyAll'
],
insert: [
'create'
]
};
const opMap = new Map();
for (const op in opOpts) {
for (const met of opOpts[op])
opMap.set(met, op);
}
class VnMySQL extends MySQL { class VnMySQL extends MySQL {
/** /**
* Promisified version of execute(). * Promisified version of execute().
@ -253,49 +221,49 @@ class VnMySQL extends MySQL {
} }
create(model, data, opts, cb) { create(model, data, opts, cb) {
const ctx = { data }; const ctx = {data};
this.invokeMethod('create', this.invokeMethod('create',
arguments, model, ctx, opts, cb); arguments, model, ctx, opts, cb);
} }
createAll(model, data, opts, cb) { createAll(model, data, opts, cb) {
const ctx = { data }; const ctx = {data};
this.invokeMethod('createAll', this.invokeMethod('createAll',
arguments, model, ctx, opts, cb); arguments, model, ctx, opts, cb);
} }
save(model, data, opts, cb) { save(model, data, opts, cb) {
const ctx = { data }; const ctx = {data};
this.invokeMethod('save', this.invokeMethod('save',
arguments, model, ctx, opts, cb); arguments, model, ctx, opts, cb);
} }
updateOrCreate(model, data, opts, cb) { updateOrCreate(model, data, opts, cb) {
const ctx = { data }; const ctx = {data};
this.invokeMethod('updateOrCreate', this.invokeMethod('updateOrCreate',
arguments, model, ctx, opts, cb); arguments, model, ctx, opts, cb);
} }
replaceOrCreate(model, data, opts, cb) { replaceOrCreate(model, data, opts, cb) {
const ctx = { data }; const ctx = {data};
this.invokeMethod('replaceOrCreate', this.invokeMethod('replaceOrCreate',
arguments, model, ctx, opts, cb); arguments, model, ctx, opts, cb);
} }
destroyAll(model, where, opts, cb) { destroyAll(model, where, opts, cb) {
const ctx = { where }; const ctx = {where};
this.invokeMethod('destroyAll', this.invokeMethod('destroyAll',
arguments, model, ctx, opts, cb); arguments, model, ctx, opts, cb);
} }
update(model, where, data, opts, cb) { update(model, where, data, opts, cb) {
const ctx = { where, data }; const ctx = {where, data};
this.invokeMethod('update', this.invokeMethod('update',
arguments, model, ctx, opts, cb); arguments, model, ctx, opts, cb);
} }
replaceById(model, id, data, opts, cb) { replaceById(model, id, data, opts, cb) {
const ctx = { id, data }; const ctx = {id, data};
this.invokeMethod('replaceById', this.invokeMethod('replaceById',
arguments, model, ctx, opts, cb); arguments, model, ctx, opts, cb);
} }
@ -316,45 +284,17 @@ class VnMySQL extends MySQL {
async invokeMethodP(method, args, model, ctx, opts) { async invokeMethodP(method, args, model, ctx, opts) {
const Model = this.getModelDefinition(model).model; const Model = this.getModelDefinition(model).model;
const settings = Model.definition.settings;
let tx; let tx;
if (!opts.transaction) { if (!opts.transaction) {
tx = await Transaction.begin(this, {}); tx = await Transaction.begin(this, {});
opts = Object.assign({ transaction: tx, httpCtx: opts.httpCtx }, opts); opts = Object.assign({transaction: tx, httpCtx: opts.httpCtx}, opts);
} }
try { try {
// Fetch old values (update|delete) or login const userId = opts.httpCtx && opts.httpCtx.active.accessToken.userId;
let where, id, data, idName, limit, op, oldInstances, newInstances; if (userId) {
const hasGrabUser = settings.log && settings.log.grabUser; const user = await Model.app.models.Account.findById(userId, {fields: ['name']}, opts);
if (hasGrabUser) {
const userId = opts.httpCtx && opts.httpCtx.active.accessToken.userId;
const user = await Model.app.models.Account.findById(userId, { fields: ['name'] }, opts);
await this.executeP(`CALL account.myUser_loginWithName(?)`, [user.name], opts); await this.executeP(`CALL account.myUser_loginWithName(?)`, [user.name], opts);
} else {
where = ctx.where;
id = ctx.id;
data = ctx.data;
idName = this.idName(model);
limit = limitSet.has(method);
op = opMap.get(method);
if (!where) {
if (id) where = { [idName]: id };
else where = { [idName]: data[idName] };
}
// Fetch old values
switch (op) {
case 'update':
case 'delete':
// Single entity operation
const stmt = this.buildSelectStmt(op, data, idName, model, where, limit);
stmt.merge(`FOR UPDATE`);
oldInstances = await this.executeStmt(stmt, opts);
}
} }
const res = await new Promise((resolve, reject) => { const res = await new Promise((resolve, reject) => {
@ -366,38 +306,7 @@ class VnMySQL extends MySQL {
super[method].apply(this, fnArgs); super[method].apply(this, fnArgs);
}); });
if (hasGrabUser) if (userId) await this.executeP(`CALL account.myUser_logout()`, null, opts);
await this.executeP(`CALL account.myUser_logout()`, null, opts);
else {
// Fetch new values
const ids = [];
switch (op) {
case 'insert':
case 'update': {
switch (method) {
case 'createAll':
for (const row of res[0])
ids.push(row[idName]);
break;
case 'create':
ids.push(res[0]);
break;
case 'update':
if (data[idName] != null)
ids.push(data[idName]);
break;
}
const newWhere = ids.length ? {[idName]: {inq: ids}} : where;
const stmt = this.buildSelectStmt(op, data, idName, model, newWhere, limit);
newInstances = await this.executeStmt(stmt, opts);
}
}
await this.createLogRecord(oldInstances, newInstances, model, opts);
}
if (tx) await tx.commit(); if (tx) await tx.commit();
return res; return res;
} catch (err) { } catch (err) {
@ -405,125 +314,6 @@ class VnMySQL extends MySQL {
throw err; throw err;
} }
} }
buildSelectStmt(op, data, idName, model, where, limit) {
const Model = this.getModelDefinition(model).model;
const properties = Object.keys(Model.definition.properties);
const fields = data ? Object.keys(data) : [];
if (op == 'delete')
properties.forEach(property => fields.push(property));
else {
const log = Model.definition.settings.log;
fields.push(idName);
if (log.relation) fields.push(Model.relations[log.relation].keyFrom);
if (log.showField) fields.push(log.showField);
else {
const showFieldNames = ['name', 'description', 'code', 'nickname'];
for (const field of showFieldNames) {
if (properties.includes(field)) {
log.showField = field;
fields.push(field);
break;
}
}
}
}
const stmt = new ParameterizedSQL(
'SELECT ' +
this.buildColumnNames(model, { fields }) +
' FROM ' +
this.tableEscaped(model)
);
stmt.merge(this.buildWhere(model, where));
if (limit) stmt.merge(`LIMIT 1`);
return stmt;
}
async createLogRecord(oldInstances, newInstances, model, opts) {
function setActionType() {
if (oldInstances && newInstances)
return 'update';
else if (!oldInstances && newInstances)
return 'insert';
return 'delete';
}
const action = setActionType();
if (!newInstances && action != 'delete') return;
const Model = this.getModelDefinition(model).model;
const models = Model.app.models;
const definition = Model.definition;
const log = definition.settings.log;
const primaryKey = this.idName(model);
const originRelation = log.relation;
const originFkField = originRelation
? Model.relations[originRelation].keyFrom
: primaryKey;
// Prevent adding logs when deleting a principal entity (Client, Zone...)
if (action == 'delete' && !originRelation) return;
function map(instances) {
const map = new Map();
if (!instances) return;
for (const instance of instances)
map.set(instance[primaryKey], instance);
return map;
}
const changedModel = definition.name;
const userFk = opts.httpCtx && opts.httpCtx.active.accessToken.userId;
const oldMap = map(oldInstances);
const newMap = map(newInstances);
const ids = (oldMap || newMap).keys();
const logEntries = [];
function insertValuesLogEntry(logEntry, instance) {
logEntry.originFk = instance[originFkField];
logEntry.changedModelId = instance[primaryKey];
if (log.showField) logEntry.changedModelValue = instance[log.showField];
}
for (const id of ids) {
const oldI = oldMap && oldMap.get(id);
const newI = newMap && newMap.get(id);
const logEntry = {
action,
userFk,
changedModel,
};
if (newI) {
insertValuesLogEntry(logEntry, newI);
// Delete unchanged properties
if (oldI) {
Object.keys(oldI).forEach(prop => {
const hasChanges = oldI[prop] instanceof Date ?
oldI[prop]?.getTime() != newI[prop]?.getTime() :
oldI[prop] != newI[prop];
if (!hasChanges) {
delete oldI[prop];
delete newI[prop];
}
});
}
} else
insertValuesLogEntry(logEntry, oldI);
logEntry.oldInstance = oldI;
logEntry.newInstance = newI;
logEntries.push(logEntry);
}
await models[log.model].create(logEntries, opts);
}
} }
exports.VnMySQL = VnMySQL; exports.VnMySQL = VnMySQL;
@ -544,7 +334,7 @@ exports.initialize = function initialize(dataSource, callback) {
if (callback) { if (callback) {
if (dataSource.settings.lazyConnect) { if (dataSource.settings.lazyConnect) {
process.nextTick(function () { process.nextTick(function() {
callback(); callback();
}); });
} else } else
@ -552,13 +342,13 @@ exports.initialize = function initialize(dataSource, callback) {
} }
}; };
MySQL.prototype.connect = function (callback) { MySQL.prototype.connect = function(callback) {
const self = this; const self = this;
const options = generateOptions(this.settings); const options = generateOptions(this.settings);
if (this.client) { if (this.client) {
if (callback) { if (callback) {
process.nextTick(function () { process.nextTick(function() {
callback(null, self.client); callback(null, self.client);
}); });
} }
@ -567,7 +357,7 @@ MySQL.prototype.connect = function (callback) {
function connectionHandler(options, callback) { function connectionHandler(options, callback) {
const client = mysql.createPool(options); const client = mysql.createPool(options);
client.getConnection(function (err, connection) { client.getConnection(function(err, connection) {
const conn = connection; const conn = connection;
if (!err) { if (!err) {
if (self.debug) if (self.debug)
@ -647,30 +437,27 @@ function generateOptions(settings) {
return options; return options;
} }
SQLConnector.prototype.all = function find(model, filter, options, cb) { SQLConnector.prototype.all = function find(model, filter, options, cb) {
const self = this; const self = this;
// Order by id if no order is specified // Order by id if no order is specified
filter = filter || {}; filter = filter || {};
const stmt = this.buildSelect(model, filter, options); const stmt = this.buildSelect(model, filter, options);
this.execute(stmt.sql, stmt.params, options, function (err, data) { this.execute(stmt.sql, stmt.params, options, function(err, data) {
if (err) { if (err)
return cb(err, []); return cb(err, []);
}
try { try {
const objs = data.map(function (obj) { const objs = data.map(function(obj) {
return self.fromRow(model, obj); return self.fromRow(model, obj);
}); });
if (filter && filter.include) { if (filter && filter.include) {
self.getModelDefinition(model).model.include( self.getModelDefinition(model).model.include(
objs, filter.include, options, cb, objs, filter.include, options, cb,
); );
} else { } else
cb(null, objs); cb(null, objs);
}
} catch (error) { } catch (error) {
cb(error, []) cb(error, []);
} }
}); });
}; };

View File

@ -1,6 +1,20 @@
const app = require('vn-loopback/server/server'); const app = require('vn-loopback/server/server');
const LoopBackContext = require('loopback-context');
describe('Update Claim', () => { describe('Update Claim', () => {
beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
const newDate = Date.vnNew(); const newDate = Date.vnNew();
const originalData = { const originalData = {
ticketFk: 3, ticketFk: 3,

View File

@ -1,6 +1,20 @@
const app = require('vn-loopback/server/server'); const app = require('vn-loopback/server/server');
const LoopBackContext = require('loopback-context');
describe('Update Claim', () => { describe('Update Claim', () => {
beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
const newDate = Date.vnNew(); const newDate = Date.vnNew();
const original = { const original = {
ticketFk: 3, ticketFk: 3,

View File

@ -1,11 +1,6 @@
{ {
"name": "ClaimBeginning", "name": "ClaimBeginning",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ClaimLog",
"relation": "claim",
"showField": "quantity"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "claimBeginning" "table": "claimBeginning"

View File

@ -1,10 +1,6 @@
{ {
"name": "ClaimDevelopment", "name": "ClaimDevelopment",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ClaimLog",
"relation": "claim"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "claimDevelopment" "table": "claimDevelopment"

View File

@ -1,10 +1,6 @@
{ {
"name": "ClaimDms", "name": "ClaimDms",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ClaimLog",
"relation": "claim"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "claimDms" "table": "claimDms"

View File

@ -1,10 +1,6 @@
{ {
"name": "ClaimEnd", "name": "ClaimEnd",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ClaimLog",
"relation": "claim"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "claimEnd" "table": "claimEnd"

View File

@ -1,10 +1,6 @@
{ {
"name": "ClaimObservation", "name": "ClaimObservation",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ClaimLog",
"relation": "claim"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "claimObservation" "table": "claimObservation"

View File

@ -1,11 +1,6 @@
{ {
"name": "ClaimState", "name": "ClaimState",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ClaimLog",
"relation": "claim",
"showField": "description"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "claimState" "table": "claimState"

View File

@ -1,10 +1,6 @@
{ {
"name": "Claim", "name": "Claim",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ClaimLog",
"showField": "id"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "claim" "table": "claim"

View File

@ -2,11 +2,6 @@
"name": "Address", "name": "Address",
"description": "Client addresses", "description": "Client addresses",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ClientLog",
"relation": "client",
"showField": "nickname"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "address" "table": "address"

View File

@ -2,11 +2,6 @@
"name": "ClientContact", "name": "ClientContact",
"description": "Client phone contacts", "description": "Client phone contacts",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ClientLog",
"relation": "client",
"showField": "name"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "clientContact" "table": "clientContact"

View File

@ -1,11 +1,6 @@
{ {
"name": "ClientDms", "name": "ClientDms",
"base": "Loggable", "base": "Loggable",
"log": {
"model":"ClientLog",
"relation": "client",
"showField": "dmsFk"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "clientDms" "table": "clientDms"

View File

@ -2,10 +2,6 @@
"name": "ClientObservation", "name": "ClientObservation",
"description": "Client notes", "description": "Client notes",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ClientLog",
"relation": "client"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "clientObservation" "table": "clientObservation"

View File

@ -1,11 +1,6 @@
{ {
"name": "ClientSample", "name": "ClientSample",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ClientLog",
"relation": "client",
"showField": "type"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "clientSample" "table": "clientSample"

View File

@ -1,10 +1,6 @@
{ {
"name": "Client", "name": "Client",
"base": "Loggable", "base": "Loggable",
"log": {
"model":"ClientLog",
"showField": "id"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "client" "table": "client"

View File

@ -1,11 +1,6 @@
{ {
"name": "Greuge", "name": "Greuge",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ClientLog",
"relation": "client",
"showField": "description"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "greuge" "table": "greuge"

View File

@ -1,10 +1,6 @@
{ {
"name": "Recovery", "name": "Recovery",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ClientLog",
"relation": "client"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "recovery" "table": "recovery"

View File

@ -1,11 +1,6 @@
{ {
"name": "Buy", "name": "Buy",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "EntryLog",
"relation": "entry",
"grabUser": true
},
"options": { "options": {
"mysql": { "mysql": {
"table": "buy" "table": "buy"

View File

@ -1,10 +1,6 @@
{ {
"name": "EntryObservation", "name": "EntryObservation",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "EntryLog",
"relation": "entry"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "entryObservation" "table": "entryObservation"

View File

@ -1,10 +1,6 @@
{ {
"name": "Entry", "name": "Entry",
"base": "Loggable", "base": "Loggable",
"log": {
"model":"EntryLog",
"grabUser": true
},
"options": { "options": {
"mysql": { "mysql": {
"table": "entry" "table": "entry"

View File

@ -1,6 +1,21 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('invoiceIn clone()', () => { describe('invoiceIn clone()', () => {
beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
it('should return the cloned invoiceIn and also clone invoiceInDueDays and invoiceInTaxes if there are any referencing the invoiceIn', async() => { it('should return the cloned invoiceIn and also clone invoiceInDueDays and invoiceInTaxes if there are any referencing the invoiceIn', async() => {
const userId = 1; const userId = 1;
const ctx = { const ctx = {

View File

@ -1,10 +1,6 @@
{ {
"name": "InvoiceInTax", "name": "InvoiceInTax",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "InvoiceInLog",
"relation": "invoiceIn"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "invoiceInTax" "table": "invoiceInTax"

View File

@ -1,9 +1,6 @@
{ {
"name": "InvoiceIn", "name": "InvoiceIn",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "InvoiceInLog"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "invoiceIn" "table": "invoiceIn"

View File

@ -1,6 +1,21 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('item updateTaxes()', () => { describe('item updateTaxes()', () => {
beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
it('should throw an error if the taxClassFk is blank', async() => { it('should throw an error if the taxClassFk is blank', async() => {
const tx = await models.Item.beginTransaction({}); const tx = await models.Item.beginTransaction({});
const options = {transaction: tx}; const options = {transaction: tx};

View File

@ -1,6 +1,21 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('tag onSubmit()', () => { describe('tag onSubmit()', () => {
beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
it('should delete a tag', async() => { it('should delete a tag', async() => {
const tx = await models.Item.beginTransaction({}); const tx = await models.Item.beginTransaction({});
const options = {transaction: tx}; const options = {transaction: tx};

View File

@ -1,11 +1,6 @@
{ {
"name": "ItemBarcode", "name": "ItemBarcode",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ItemLog",
"relation": "item",
"showField": "code"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "itemBarcode" "table": "itemBarcode"

View File

@ -1,10 +1,6 @@
{ {
"name": "ItemBotanical", "name": "ItemBotanical",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ItemLog",
"relation": "item"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "itemBotanical" "table": "itemBotanical"

View File

@ -1,11 +1,6 @@
{ {
"name": "ItemTag", "name": "ItemTag",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ItemLog",
"relation": "item",
"showField": "value"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "itemTag" "table": "itemTag"

View File

@ -1,11 +1,6 @@
{ {
"name": "ItemTaxCountry", "name": "ItemTaxCountry",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ItemLog",
"relation": "item",
"showField": "countryFk"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "itemTaxCountry" "table": "itemTaxCountry"

View File

@ -1,11 +1,6 @@
{ {
"name": "Item", "name": "Item",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ItemLog",
"showField": "id",
"grabUser": true
},
"options": { "options": {
"mysql": { "mysql": {
"table": "item" "table": "item"

View File

@ -1,6 +1,20 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('AgencyTerm createInvoiceIn()', () => { describe('AgencyTerm createInvoiceIn()', () => {
beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
const rows = [ const rows = [
{ {
routeFk: 2, routeFk: 2,

View File

@ -1,10 +1,6 @@
{ {
"name": "Route", "name": "Route",
"base": "Loggable", "base": "Loggable",
"log": {
"model":"RouteLog",
"grabUser": true
},
"options": { "options": {
"mysql": { "mysql": {
"table": "route" "table": "route"

View File

@ -1,10 +1,6 @@
{ {
"name": "Shelving", "name": "Shelving",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ShelvingLog",
"showField": "id"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "shelving" "table": "shelving"

View File

@ -1,10 +1,6 @@
{ {
"name": "SupplierAccount", "name": "SupplierAccount",
"base": "Loggable", "base": "Loggable",
"log": {
"model":"SupplierLog",
"relation": "supplier"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "supplierAccount" "table": "supplierAccount"

View File

@ -2,11 +2,6 @@
"name": "SupplierAddress", "name": "SupplierAddress",
"description": "Supplier addresses", "description": "Supplier addresses",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "SupplierLog",
"relation": "supplier",
"showField": "name"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "supplierAddress" "table": "supplierAddress"

View File

@ -1,10 +1,6 @@
{ {
"name": "SupplierContact", "name": "SupplierContact",
"base": "Loggable", "base": "Loggable",
"log": {
"model":"SupplierLog",
"relation": "supplier"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "supplierContact" "table": "supplierContact"

View File

@ -1,9 +1,6 @@
{ {
"name": "Supplier", "name": "Supplier",
"base": "Loggable", "base": "Loggable",
"log": {
"model":"SupplierLog"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "supplier" "table": "supplier"

View File

@ -1,6 +1,21 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('ticket deleteExpeditions()', () => { describe('ticket deleteExpeditions()', () => {
beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
it('should delete the selected expeditions', async() => { it('should delete the selected expeditions', async() => {
const tx = await models.Expedition.beginTransaction({}); const tx = await models.Expedition.beginTransaction({});

View File

@ -1,6 +1,21 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('ticket moveExpeditions()', () => { describe('ticket moveExpeditions()', () => {
beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
it('should move the selected expeditions to new ticket', async() => { it('should move the selected expeditions to new ticket', async() => {
const tx = await models.Expedition.beginTransaction({}); const tx = await models.Expedition.beginTransaction({});
const ctx = { const ctx = {

View File

@ -1,6 +1,20 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('ticket-request confirm()', () => { describe('ticket-request confirm()', () => {
beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
let ctx = { let ctx = {
req: { req: {
accessToken: {userId: 9}, accessToken: {userId: 9},

View File

@ -1,6 +1,21 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('ticket-request deny()', () => { describe('ticket-request deny()', () => {
beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
it('should return the denied ticket request', async() => { it('should return the denied ticket request', async() => {
const tx = await models.TicketRequest.beginTransaction({}); const tx = await models.TicketRequest.beginTransaction({});

View File

@ -17,6 +17,17 @@ describe('ticket componentUpdate()', () => {
let componentValue; let componentValue;
beforeAll(async() => { beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
const deliveryComponenet = await models.Component.findOne({where: {code: 'delivery'}}); const deliveryComponenet = await models.Component.findOne({where: {code: 'delivery'}});
deliveryComponentId = deliveryComponenet.id; deliveryComponentId = deliveryComponenet.id;
componentOfSaleSeven = `SELECT value componentOfSaleSeven = `SELECT value
@ -180,9 +191,6 @@ describe('ticket componentUpdate()', () => {
} }
}; };
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: ctx.req
});
const oldTicket = await models.Ticket.findById(ticketID, null, options); const oldTicket = await models.Ticket.findById(ticketID, null, options);
await models.Ticket.componentUpdate(ctx, options); await models.Ticket.componentUpdate(ctx, options);

View File

@ -1,10 +1,6 @@
{ {
"name": "Expedition", "name": "Expedition",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "TicketLog",
"relation": "ticket"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "expedition" "table": "expedition"
@ -59,4 +55,3 @@
} }
} }
} }

View File

@ -1,12 +1,6 @@
{ {
"name": "Sale", "name": "Sale",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "TicketLog",
"relation": "ticket",
"showField": "concept",
"grabUser": true
},
"options": { "options": {
"mysql": { "mysql": {
"table": "sale" "table": "sale"

View File

@ -1,6 +1,20 @@
const app = require('vn-loopback/server/server'); const app = require('vn-loopback/server/server');
const LoopBackContext = require('loopback-context');
describe('ticket model TicketTracking', () => { describe('ticket model TicketTracking', () => {
beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
let ticketTrackingId; let ticketTrackingId;
afterAll(async() => { afterAll(async() => {

View File

@ -1,10 +1,6 @@
{ {
"name": "TicketDms", "name": "TicketDms",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "TicketLog",
"relation": "ticket"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "ticketDms" "table": "ticketDms"

View File

@ -1,10 +1,6 @@
{ {
"name": "TicketObservation", "name": "TicketObservation",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "TicketLog",
"relation": "ticket"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "ticketObservation" "table": "ticketObservation"

View File

@ -1,10 +1,6 @@
{ {
"name": "TicketPackaging", "name": "TicketPackaging",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "TicketLog",
"relation": "ticket"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "ticketPackaging" "table": "ticketPackaging"

View File

@ -6,10 +6,6 @@
"table": "ticketRefund" "table": "ticketRefund"
} }
}, },
"log": {
"model": "TicketLog",
"relation": "originalTicket"
},
"properties": { "properties": {
"id": { "id": {
"id": true, "id": true,

View File

@ -1,10 +1,6 @@
{ {
"name": "TicketRequest", "name": "TicketRequest",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "TicketLog",
"relation": "ticket"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "ticketRequest" "table": "ticketRequest"

View File

@ -1,11 +1,6 @@
{ {
"name": "TicketService", "name": "TicketService",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "TicketLog",
"relation": "ticket",
"showField": "description"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "ticketService" "table": "ticketService"

View File

@ -1,16 +1,11 @@
{ {
"name": "TicketTracking", "name": "TicketTracking",
"base": "Loggable", "base": "Loggable",
"log": { "options": {
"model": "TicketLog", "mysql": {
"relation": "ticket", "table": "ticketTracking"
"showField": "stateFk" }
}, },
"options": {
"mysql": {
"table": "ticketTracking"
}
},
"properties": { "properties": {
"id": { "id": {
"id": true, "id": true,
@ -48,4 +43,3 @@
} }
} }
} }

View File

@ -1,11 +1,6 @@
{ {
"name": "TicketWeekly", "name": "TicketWeekly",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "TicketLog",
"relation": "ticket",
"showField": "ticketFk"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "ticketWeekly" "table": "ticketWeekly"

View File

@ -1,11 +1,6 @@
{ {
"name": "Ticket", "name": "Ticket",
"base": "Loggable", "base": "Loggable",
"log": {
"model":"TicketLog",
"showField": "id",
"grabUser": true
},
"options": { "options": {
"mysql": { "mysql": {
"table": "ticket" "table": "ticket"

View File

@ -1,6 +1,20 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('Travel createThermograph()', () => { describe('Travel createThermograph()', () => {
beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
const travelId = 3; const travelId = 3;
const currentUserId = 1102; const currentUserId = 1102;
const thermographId = '138350-0'; const thermographId = '138350-0';

View File

@ -1,14 +1,9 @@
{ {
"name": "TravelThermograph", "name": "TravelThermograph",
"base": "Loggable", "base": "Loggable",
"log": {
"model":"TravelLog",
"relation": "travel",
"showField": "ref"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "travelThermograph" "table": "travelThermograph"
} }
}, },
"properties": { "properties": {

View File

@ -1,11 +1,6 @@
{ {
"name": "Travel", "name": "Travel",
"base": "Loggable", "base": "Loggable",
"log": {
"model":"TravelLog",
"showField": "ref",
"grabUser": true
},
"options": { "options": {
"mysql": { "mysql": {
"table": "travel" "table": "travel"

View File

@ -1,11 +1,6 @@
{ {
"name": "WorkerDms", "name": "WorkerDms",
"base": "Loggable", "base": "Loggable",
"log": {
"model":"ClientLog",
"relation": "worker",
"showField": "dmsFk"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "workerDocument" "table": "workerDocument"

View File

@ -2,10 +2,6 @@
"name": "Worker", "name": "Worker",
"description": "Company employees", "description": "Company employees",
"base": "Loggable", "base": "Loggable",
"log": {
"model":"WorkerLog",
"showField": "firstName"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "worker" "table": "worker"

View File

@ -1,6 +1,21 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('agency clone()', () => { describe('agency clone()', () => {
beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
it('should clone a zone', async() => { it('should clone a zone', async() => {
const tx = await models.Zone.beginTransaction({}); const tx = await models.Zone.beginTransaction({});

View File

@ -1,6 +1,20 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('zone exclusionGeo()', () => { describe('zone exclusionGeo()', () => {
beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
const zoneId = 1; const zoneId = 1;
const today = Date.vnNew(); const today = Date.vnNew();

View File

@ -1,6 +1,21 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('zone toggleIsIncluded()', () => { describe('zone toggleIsIncluded()', () => {
beforeAll(async() => {
const activeCtx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
it('should return the created location with isIncluded true', async() => { it('should return the created location with isIncluded true', async() => {
const tx = await models.Zone.beginTransaction({}); const tx = await models.Zone.beginTransaction({});

View File

@ -1,10 +1,6 @@
{ {
"name": "ZoneEvent", "name": "ZoneEvent",
"base": "Loggable", "base": "Loggable",
"log": {
"model":"ZoneLog",
"relation": "zone"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "zoneEvent" "table": "zoneEvent"

View File

@ -1,10 +1,6 @@
{ {
"name": "ZoneExclusion", "name": "ZoneExclusion",
"base": "Loggable", "base": "Loggable",
"log": {
"model":"ZoneLog",
"relation": "zone"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "zoneExclusion" "table": "zoneExclusion"

View File

@ -1,11 +1,6 @@
{ {
"name": "ZoneIncluded", "name": "ZoneIncluded",
"base": "Loggable", "base": "Loggable",
"log": {
"model": "ZoneLog",
"relation": "zone",
"showField": "isIncluded"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "zoneIncluded" "table": "zoneIncluded"

View File

@ -1,10 +1,6 @@
{ {
"name": "ZoneWarehouse", "name": "ZoneWarehouse",
"base": "Loggable", "base": "Loggable",
"log": {
"model":"ZoneLog",
"relation": "zone"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "zoneWarehouse" "table": "zoneWarehouse"

View File

@ -1,10 +1,6 @@
{ {
"name": "Zone", "name": "Zone",
"base": "Loggable", "base": "Loggable",
"log": {
"model":"ZoneLog",
"showField": "name"
},
"options": { "options": {
"mysql": { "mysql": {
"table": "zone" "table": "zone"