From f5f4c5936d956b7c5a4171603d40e92fd55b4bfa Mon Sep 17 00:00:00 2001 From: joan Date: Mon, 1 Feb 2021 09:29:47 +0100 Subject: [PATCH 1/3] 2763 - Notify urgen issues --- back/methods/chat/notifyIssues.js | 39 +++++++++++++++++++ back/methods/chat/spec/notifyIssue.spec.js | 28 +++++++++++++ back/methods/chat/spec/send.spec.js | 2 +- .../chat/spec/sendCheckingPresence.spec.js | 2 +- back/models/chat.js | 1 + .../10280-valentineDay/00-department.sql | 4 ++ loopback/locale/en.json | 3 +- loopback/locale/es.json | 3 +- modules/worker/back/models/department.json | 19 +++++---- 9 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 back/methods/chat/notifyIssues.js create mode 100644 back/methods/chat/spec/notifyIssue.spec.js create mode 100644 db/changes/10280-valentineDay/00-department.sql diff --git a/back/methods/chat/notifyIssues.js b/back/methods/chat/notifyIssues.js new file mode 100644 index 000000000..54eb41c89 --- /dev/null +++ b/back/methods/chat/notifyIssues.js @@ -0,0 +1,39 @@ +module.exports = Self => { + Self.remoteMethodCtx('notifyIssues', { + description: 'Notifies new urgent issues', + accessType: 'READ', + returns: { + type: 'Object', + root: true + }, + http: { + path: `/notifyIssues`, + verb: 'GET' + } + }); + + Self.notifyIssues = async ctx => { + const models = Self.app.models; + const $t = ctx.req.__; // $translate + const [urgentIssue] = await Self.rawSql(` + SELECT * FROM managedesktop.vn_workOrderInmediata LIMIT 1 + `); + + if (!urgentIssue) return; + + const message = $t(`There's a new urgent ticket`, { + title: urgentIssue.title, + issueId: urgentIssue.workOrderId + }); + + const department = await models.Department.findOne({ + where: {code: 'IT'} + }); + const channelName = department && department.chatName; + + if (channelName) + return Self.send(ctx, `#${channelName}`, `@all ➔ ${message}`); + + return; + }; +}; diff --git a/back/methods/chat/spec/notifyIssue.spec.js b/back/methods/chat/spec/notifyIssue.spec.js new file mode 100644 index 000000000..19fbbbd56 --- /dev/null +++ b/back/methods/chat/spec/notifyIssue.spec.js @@ -0,0 +1,28 @@ +const app = require('vn-loopback/server/server'); + +describe('Chat notifyIssue()', () => { + const ctx = {req: {accessToken: {userId: 1}}}; + ctx.req.__ = value => { + return value; + }; + const chatModel = app.models.Chat; + const departmentId = 31; + + it(`should call to notifyIssue() method then return a response calling the send() method`, async() => { + spyOn(chatModel, 'send').and.callThrough(); + spyOn(chatModel, 'rawSql').and.returnValue([{title: 'Issue title'}]); + + const department = await app.models.Department.findById(departmentId); + let orgChatName = department.chatName; + await department.updateAttribute('chatName', 'IT'); + + const response = await chatModel.notifyIssues(ctx); + + expect(response.statusCode).toEqual(200); + expect(response.message).toEqual('Fake notification sent'); + expect(chatModel.send).toHaveBeenCalledWith(ctx, '#IT', `@all ➔ There's a new urgent ticket`); + + // restores + await department.updateAttribute('chatName', orgChatName); + }); +}); diff --git a/back/methods/chat/spec/send.spec.js b/back/methods/chat/spec/send.spec.js index 56f2a9c27..2c23bb591 100644 --- a/back/methods/chat/spec/send.spec.js +++ b/back/methods/chat/spec/send.spec.js @@ -1,6 +1,6 @@ const app = require('vn-loopback/server/server'); -describe('chat send()', () => { +describe('Chat send()', () => { it('should return a "Fake notification sent" as response', async() => { let ctx = {req: {accessToken: {userId: 1}}}; let response = await app.models.Chat.send(ctx, '@salesPerson', 'I changed something'); diff --git a/back/methods/chat/spec/sendCheckingPresence.spec.js b/back/methods/chat/spec/sendCheckingPresence.spec.js index b3e89180c..aa4a80801 100644 --- a/back/methods/chat/spec/sendCheckingPresence.spec.js +++ b/back/methods/chat/spec/sendCheckingPresence.spec.js @@ -1,6 +1,6 @@ const app = require('vn-loopback/server/server'); -describe('chat sendCheckingPresence()', () => { +describe('Chat sendCheckingPresence()', () => { const today = new Date(); today.setHours(6, 0); const ctx = {req: {accessToken: {userId: 1}}}; diff --git a/back/models/chat.js b/back/models/chat.js index ab23ef713..5487569c1 100644 --- a/back/models/chat.js +++ b/back/models/chat.js @@ -1,4 +1,5 @@ module.exports = Self => { require('../methods/chat/send')(Self); require('../methods/chat/sendCheckingPresence')(Self); + require('../methods/chat/notifyIssues')(Self); }; diff --git a/db/changes/10280-valentineDay/00-department.sql b/db/changes/10280-valentineDay/00-department.sql new file mode 100644 index 000000000..bb3062825 --- /dev/null +++ b/db/changes/10280-valentineDay/00-department.sql @@ -0,0 +1,4 @@ +ALTER TABLE `vn`.`department` + ADD code VARCHAR(45) NULL AFTER id; + +UPDATE `vn`.`department` t SET t.code = 'IT', t.chatName = 'informatica-cau' WHERE t.id = 31; diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 0ac49d5b5..400aa5265 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -88,5 +88,6 @@ "A travel with this data already exists": "A travel with this data already exists", "The observation type can't be repeated": "The observation type can't be repeated", "New ticket request has been created with price": "New ticket request has been created '{{description}}' for day {{shipped}}, with a quantity of {{quantity}} and a price of {{price}} €", - "New ticket request has been created": "New ticket request has been created '{{description}}' for day {{shipped}}, with a quantity of {{quantity}}" + "New ticket request has been created": "New ticket request has been created '{{description}}' for day {{shipped}}, with a quantity of {{quantity}}", + "There's a new urgent ticket": "There's a new urgent ticket: [{{title}}](https://cau.verdnatura.es/WorkOrder.do?woMode=viewWO&woID={{issueId}})" } \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index aa54c6b94..48b89ec0f 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -167,5 +167,6 @@ "Sorts whole route": "Reordena ruta entera", "New ticket request has been created with price": "Se ha creado una nueva petición de compra '{{description}}' para el día {{shipped}}, con una cantidad de {{quantity}} y un precio de {{price}} €", "New ticket request has been created": "Se ha creado una nueva petición de compra '{{description}}' para el día {{shipped}}, con una cantidad de {{quantity}}", - "That item doesn't exists": "Ese artículo no existe" + "That item doesn't exists": "Ese artículo no existe", + "There's a new urgent ticket": "Hay un nuevo ticket urgente: [{{title}}](https://cau.verdnatura.es/WorkOrder.do?woMode=viewWO&woID={{issueId}})" } \ No newline at end of file diff --git a/modules/worker/back/models/department.json b/modules/worker/back/models/department.json index 31ebbb09a..7d6f7a7be 100644 --- a/modules/worker/back/models/department.json +++ b/modules/worker/back/models/department.json @@ -9,28 +9,31 @@ "properties": { "id": { "id": true, - "type": "Number" + "type": "number" + }, + "code": { + "type": "string" }, "name": { - "type": "String" + "type": "string" }, "parentFk": { - "type": "Number" + "type": "number" }, "lft": { - "type": "Number" + "type": "number" }, "rgt": { - "type": "Number" + "type": "number" }, "sons": { - "type": "Number" + "type": "number" }, "chatName": { - "type": "String" + "type": "string" }, "notificationEmail": { - "type": "String" + "type": "string" } } } From b34e5804aecc4d6aa6494a7ec6ea129cbd118c3d Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 2 Feb 2021 08:15:20 +0100 Subject: [PATCH 2/3] Updated unit test --- back/methods/chat/spec/notifyIssue.spec.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/back/methods/chat/spec/notifyIssue.spec.js b/back/methods/chat/spec/notifyIssue.spec.js index 19fbbbd56..e23c33859 100644 --- a/back/methods/chat/spec/notifyIssue.spec.js +++ b/back/methods/chat/spec/notifyIssue.spec.js @@ -8,7 +8,17 @@ describe('Chat notifyIssue()', () => { const chatModel = app.models.Chat; const departmentId = 31; - it(`should call to notifyIssue() method then return a response calling the send() method`, async() => { + it(`should not call to the send() method and neither return a response`, async() => { + spyOn(chatModel, 'send').and.callThrough(); + spyOn(chatModel, 'rawSql').and.returnValue([]); + + const response = await chatModel.notifyIssues(ctx); + + expect(chatModel.send).not.toHaveBeenCalled(); + expect(response).toBeUndefined(); + }); + + it(`should return a response calling the send() method`, async() => { spyOn(chatModel, 'send').and.callThrough(); spyOn(chatModel, 'rawSql').and.returnValue([{title: 'Issue title'}]); From 20116ac62064be0dc09ef168d5c0cacafa7237a9 Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 2 Feb 2021 09:08:11 +0100 Subject: [PATCH 3/3] 2741 - Claim detail deletion visual fix --- modules/claim/front/detail/index.js | 9 ++++----- modules/claim/front/detail/index.spec.js | 11 +++++++---- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/modules/claim/front/detail/index.js b/modules/claim/front/detail/index.js index 4e0017baa..7c3c04f44 100644 --- a/modules/claim/front/detail/index.js +++ b/modules/claim/front/detail/index.js @@ -86,16 +86,15 @@ class Controller extends Section { }); } - showDeleteConfirm(index) { - this.sale = this.salesClaimed[index]; + showDeleteConfirm($index) { + this.claimedIndex = $index; this.$.confirm.show(); } deleteClaimedSale() { - let query = `ClaimBeginnings/${this.sale.id}`; - this.$http.delete(query).then(() => { + this.$.model.remove(this.claimedIndex); + this.$.model.save().then(() => { this.vnApp.showSuccess(this.$t('Data saved!')); - this.$.model.remove(this.sale); this.calculateTotals(); }); } diff --git a/modules/claim/front/detail/index.spec.js b/modules/claim/front/detail/index.spec.js index 972d487e5..b36f3a172 100644 --- a/modules/claim/front/detail/index.spec.js +++ b/modules/claim/front/detail/index.spec.js @@ -73,13 +73,16 @@ describe('claim', () => { describe('deleteClaimedSale()', () => { it('should make a delete and call refresh and showSuccess', () => { - controller.sale = {id: 1}; + const claimedIndex = 1; + controller.claimedIndex = claimedIndex; jest.spyOn(controller.$.model, 'remove'); + jest.spyOn(controller.$.model, 'save'); jest.spyOn(controller.vnApp, 'showSuccess'); - $httpBackend.expectDELETE(`ClaimBeginnings/1`).respond('ok'); - controller.deleteClaimedSale(); - $httpBackend.flush(); + controller.deleteClaimedSale(); + + expect(controller.$.model.remove).toHaveBeenCalledWith(claimedIndex); + expect(controller.$.model.save).toHaveBeenCalledWith(); expect(controller.vnApp.showSuccess).toHaveBeenCalled(); }); });