From b3d333368bdd40777e43159cdbe8b1511ff1e4bf Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 23 Mar 2021 16:19:45 +0100 Subject: [PATCH] #2819 - Notify worker assignment --- loopback/locale/es.json | 4 +- modules/client/back/models/client.js | 109 +++++++++++++----- .../client/back/models/specs/client.spec.js | 58 ++++++++++ 3 files changed, 142 insertions(+), 29 deletions(-) create mode 100644 modules/client/back/models/specs/client.spec.js diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 96858eb4a..b325b9176 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -176,5 +176,7 @@ "Invalid account": "Cuenta inválida", "Compensation account is empty": "La cuenta para compensar está vacia", "This genus already exist": "Este genus ya existe", - "This specie already exist": "Esta especie ya existe" + "This specie already exist": "Esta especie ya existe", + "Client assignment has changed": "He cambiado el comercial ~*\"<{{previousWorkerName}}>\"*~ por *\"<{{currentWorkerName}}>\"* del cliente [{{clientName}} ({{clientId}})]({{{url}}})", + "None": "Ninguno" } \ No newline at end of file diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js index 1e535a5d7..c30270f6f 100644 --- a/modules/client/back/models/client.js +++ b/modules/client/back/models/client.js @@ -226,36 +226,10 @@ module.exports = Self => { }; await Self.app.models.ClientCredit.create(newCredit); } - }); - const app = require('vn-loopback/server/server'); - app.on('started', function() { - let account = app.models.Account; - account.observe('before save', async ctx => { - if (ctx.isNewInstance) return; - ctx.hookState.oldInstance = JSON.parse(JSON.stringify(ctx.currentInstance)); - }); - - account.observe('after save', async ctx => { - let changes = ctx.data || ctx.instance; - if (!ctx.isNewInstance && changes) { - let oldData = ctx.hookState.oldInstance; - let hasChanges = oldData.name != changes.name || oldData.active != changes.active; - if (!hasChanges) return; - - let userId = ctx.options.accessToken.userId; - let logRecord = { - originFk: oldData.id, - userFk: userId, - action: 'update', - changedModel: 'Account', - oldInstance: {name: oldData.name, active: oldData.active}, - newInstance: {name: changes.name, active: changes.active} - }; - await Self.app.models.ClientLog.create(logRecord); - } - }); + ctx.hookState.oldInstance = Object.assign({}, orgData.__data); + ctx.hookState.newInstance = Object.assign({}, finalState); }); Self.observe('after save', async ctx => { @@ -303,8 +277,57 @@ module.exports = Self => { query: params }); } + + const workerIdBefore = oldInstance.salesPersonFk; + const workerIdAfter = newInstance.salesPersonFk; + const assignmentChanged = workerIdBefore != workerIdAfter; + if (assignmentChanged) + await notifyAssignment(instance, workerIdBefore, workerIdAfter); }); + // Send notification on client worker assignment + async function notifyAssignment(client, previousWorkerId, currentWorkerId) { + const loopBackContext = LoopBackContext.getCurrentContext(); + const httpCtx = {req: loopBackContext.active}; + const httpRequest = httpCtx.req.http.req; + const $t = httpRequest.__; + const headers = httpRequest.headers; + const origin = headers.origin; + const models = Self.app.models; + + let previousWorkerName = $t('None'); + let currentWorkerName = $t('None'); + if (previousWorkerId) { + const worker = await models.Worker.findById(previousWorkerId, { + include: {relation: 'user'} + }); + previousWorkerName = worker && worker.user().nickname; + } + + if (currentWorkerId) { + const worker = await models.Worker.findById(currentWorkerId, { + include: {relation: 'user'} + }); + currentWorkerName = worker && worker.user().nickname; + } + + const fullUrl = `${origin}/#!/client/${client.id}/basic-data`; + const message = $t('Client assignment has changed', { + clientId: client.id, + clientName: client.name, + url: fullUrl, + previousWorkerName: previousWorkerName, + currentWorkerName: currentWorkerName + }); + + + if (previousWorkerName) // change to worker userName + await models.Chat.send(httpCtx, '@joan', message); + + if (currentWorkerName) + await models.Chat.send(httpCtx, '@joan', message); + } + async function validateCreditChange(ctx, finalState) { let models = Self.app.models; let userId = ctx.options.accessToken.userId; @@ -341,4 +364,34 @@ module.exports = Self => { if (count <= 0) throw new UserError('The role cannot set this credit amount'); } + + const app = require('vn-loopback/server/server'); + app.on('started', function() { + let account = app.models.Account; + + account.observe('before save', async ctx => { + if (ctx.isNewInstance) return; + ctx.hookState.oldInstance = JSON.parse(JSON.stringify(ctx.currentInstance)); + }); + + account.observe('after save', async ctx => { + let changes = ctx.data || ctx.instance; + if (!ctx.isNewInstance && changes) { + let oldData = ctx.hookState.oldInstance; + let hasChanges = oldData.name != changes.name || oldData.active != changes.active; + if (!hasChanges) return; + + let userId = ctx.options.accessToken.userId; + let logRecord = { + originFk: oldData.id, + userFk: userId, + action: 'update', + changedModel: 'Account', + oldInstance: {name: oldData.name, active: oldData.active}, + newInstance: {name: changes.name, active: changes.active} + }; + await Self.app.models.ClientLog.create(logRecord); + } + }); + }); }; diff --git a/modules/client/back/models/specs/client.spec.js b/modules/client/back/models/specs/client.spec.js new file mode 100644 index 000000000..685acc80d --- /dev/null +++ b/modules/client/back/models/specs/client.spec.js @@ -0,0 +1,58 @@ +const app = require('vn-loopback/server/server'); + +describe('loopback model address', () => { + let createdAddressId; + const clientId = 101; + + afterAll(async done => { + let client = await app.models.Client.findById(clientId); + + await app.models.Address.destroyById(createdAddressId); + await client.updateAttribute('isEqualizated', false); + + done(); + }); + + describe('observe()', () => { + it('should throw an error when deactivating a consignee if its the default address', async() => { + let error; + let address = await app.models.Address.findById(1); + + await address.updateAttribute('isActive', false) + .catch(e => { + error = e; + + expect(error.message).toEqual('The default consignee can not be unchecked'); + }); + + expect(error).toBeDefined(); + }); + + it('should set isEqualizated to true of a given Client to trigger any new address to have it', async() => { + let client = await app.models.Client.findById(clientId); + + expect(client.isEqualizated).toBeFalsy(); + + await client.updateAttribute('isEqualizated', true); + + let newAddress = await app.models.Address.create({ + clientFk: clientId, + agencyModeFk: 5, + city: 'here', + isActive: true, + mobile: '555555555', + nickname: 'Test address', + phone: '555555555', + postalCode: '46000', + provinceFk: 1, + street: 'Test address', + incotermsFk: 'FAS', + customsAgentFk: 1 + }); + + expect(newAddress.isEqualizated).toBeTruthy(); + + createdAddressId = newAddress.id; + }); + }); +});