diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 5af9b9eeb..7b5a5960b 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1828,7 +1828,12 @@ INSERT INTO vn.claimRma (`id`, `code`, `created`, `workerFk`) (4, '02676A049183', DEFAULT, 1107), (5, '01837B023653', DEFAULT, 1106); - +INSERT INTO `vn`.`claimLog` (`originFk`, userFk, `action`, changedModel, oldInstance, newInstance, changedModelId, `description`) + VALUES + (1, 18, 'update', 'Claim', '{"hasToPickUp":false}', '{"hasToPickUp":true}', 1, NULL), + (1, 18, 'update', 'ClaimObservation', '{}', '{"claimFk":1,"text":"Waiting for customer"}', 1, NULL), + (1, 18, 'insert', 'ClaimBeginning', '{}', '{"claimFk":1,"saleFk":1,"quantity":10}', 1, NULL), + (1, 18, 'insert', 'ClaimDms', '{}', '{"claimFk":1,"dmsFk":1}', 1, NULL); INSERT INTO `hedera`.`tpvMerchant`(`id`, `description`, `companyFk`, `bankFk`, `secretKey`) VALUES @@ -2760,7 +2765,6 @@ INSERT INTO `vn`.`ticketLog` (`originFk`, userFk, `action`, changedModel, oldIns (7, 18, 'update', 'Sale', '{"price":3}', '{"price":5}', 1, NULL), (7, 18, 'update', NULL, NULL, NULL, NULL, "Cambio cantidad Melee weapon heavy shield 1x0.5m de '5' a '10'"); - INSERT INTO `vn`.`osTicketConfig` (`id`, `host`, `user`, `password`, `oldStatus`, `newStatusId`, `day`, `comment`, `hostDb`, `userDb`, `passwordDb`, `portDb`, `responseType`, `fromEmailId`, `replyTo`) VALUES (0, 'http://localhost:56596/scp', 'ostadmin', 'Admin1', '1,6', 3, 60, 'Este CAU se ha cerrado automáticamente. Si el problema persiste responda a este mensaje.', 'localhost', 'osticket', 'osticket', 40003, 'reply', 1, 'all'); diff --git a/modules/claim/back/methods/claim/logs.js b/modules/claim/back/methods/claim/logs.js new file mode 100644 index 000000000..c7e69680b --- /dev/null +++ b/modules/claim/back/methods/claim/logs.js @@ -0,0 +1,134 @@ + +const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; +const buildFilter = require('vn-loopback/util/filter').buildFilter; +const {mergeFilters, mergeWhere} = require('vn-loopback/util/filter'); + +module.exports = Self => { + Self.remoteMethodCtx('logs', { + description: 'Find all claim logs of the claim entity matched by a filter', + accessType: 'READ', + accepts: [ + { + arg: 'id', + type: 'Number', + description: 'The claim id', + http: {source: 'path'} + }, + { + arg: 'filter', + type: 'object', + http: {source: 'query'} + }, + { + arg: 'search', + type: 'string', + http: {source: 'query'} + }, + { + arg: 'userFk', + type: 'number', + http: {source: 'query'} + }, + { + arg: 'created', + type: 'date', + http: {source: 'query'} + }, + ], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/:id/logs`, + verb: 'GET' + } + }); + + Self.logs = async(ctx, id, filter, options) => { + const conn = Self.dataSource.connector; + const args = ctx.args; + const myOptions = {}; + let to; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + let where = buildFilter(args, (param, value) => { + switch (param) { + case 'search': + return { + or: [ + {changedModel: {like: `%${value}%`}}, + {oldInstance: {like: `%${value}%`}} + ] + }; + case 'userFk': + return {'cl.userFk': value}; + case 'created': + value.setHours(0, 0, 0, 0); + to = new Date(value); + to.setHours(23, 59, 59, 999); + + return {creationDate: {between: [value, to]}}; + } + }); + where = mergeWhere(where, {['cl.originFk']: id}); + filter = mergeFilters(args.filter, {where}); + + const stmts = []; + + const stmt = new ParameterizedSQL( + `SELECT + cl.id, + cl.userFk, + u.name AS userName, + cl.oldInstance, + cl.newInstance, + cl.changedModel, + cl.action, + cl.creationDate AS created + FROM claimLog cl + JOIN account.user u ON u.id = cl.userFk + ` + ); + + stmt.merge(conn.makeSuffix(filter)); + stmts.push(stmt); + + const sql = ParameterizedSQL.join(stmts, ';'); + const result = await conn.executeStmt(sql, myOptions); + + const logs = []; + for (const row of result) { + const changes = []; + const oldInstance = JSON.parse(row.oldInstance); + const newInstance = JSON.parse(row.newInstance); + const mergedProperties = [...Object.keys(oldInstance), ...Object.keys(newInstance)]; + const properties = new Set(mergedProperties); + for (const property of properties) { + let oldValue = oldInstance[property]; + let newValue = newInstance[property]; + + const change = { + property: property, + before: oldValue, + after: newValue, + }; + + changes.push(change); + } + + logs.push({ + model: row.changedModel, + action: row.action, + created: row.created, + userFk: row.userFk, + userName: row.userName, + changes: changes, + }); + } + + return logs; + }; +}; diff --git a/modules/claim/back/methods/claim/specs/log.spec.js b/modules/claim/back/methods/claim/specs/log.spec.js new file mode 100644 index 000000000..0ae534f1e --- /dev/null +++ b/modules/claim/back/methods/claim/specs/log.spec.js @@ -0,0 +1,23 @@ +const app = require('vn-loopback/server/server'); + +describe('claim log()', () => { + const claimId = 1; + const salesPersonId = 18; + + it('should return results filtering by user id', async() => { + const result = await app.models.Claim.logs({args: {userFk: salesPersonId}}, claimId); + + const expectedObject = { + model: 'Claim', + action: 'update', + changes: [ + {property: 'hasToPickUp', before: false, after: true} + ] + }; + + const firstRow = result[0]; + + expect(result.length).toBeGreaterThan(0); + expect(firstRow).toEqual(jasmine.objectContaining(expectedObject)); + }); +}); diff --git a/modules/claim/back/models/claim.js b/modules/claim/back/models/claim.js index c9d7ee7d4..12fcaa326 100644 --- a/modules/claim/back/models/claim.js +++ b/modules/claim/back/models/claim.js @@ -11,4 +11,5 @@ module.exports = Self => { require('../methods/claim/downloadFile')(Self); require('../methods/claim/claimPickupPdf')(Self); require('../methods/claim/claimPickupEmail')(Self); + require('../methods/claim/logs')(Self); };