From fde854f5c2e078f4a277ad0ea649f6f01a744604 Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 22 Mar 2023 10:21:15 +0100 Subject: [PATCH 01/14] refs #5250 campo de notes --- db/changes/231201/00-workerNotes.sql | 10 +++++ e2e/helpers/selectors.js | 6 +++ e2e/paths/03-worker/08_add_notes.spec.js | 42 +++++++++++++++++++ modules/worker/front/index.js | 3 ++ modules/worker/front/locale/es.yml | 2 + modules/worker/front/note/create/index.html | 30 +++++++++++++ modules/worker/front/note/create/index.js | 21 ++++++++++ .../worker/front/note/create/index.spec.js | 22 ++++++++++ .../worker/front/note/create/locale/es.yml | 2 + modules/worker/front/note/index/index.html | 31 ++++++++++++++ modules/worker/front/note/index/index.js | 22 ++++++++++ modules/worker/front/note/index/style.scss | 5 +++ modules/worker/front/routes.json | 19 +++++++++ 13 files changed, 215 insertions(+) create mode 100644 db/changes/231201/00-workerNotes.sql create mode 100644 e2e/paths/03-worker/08_add_notes.spec.js create mode 100644 modules/worker/front/note/create/index.html create mode 100644 modules/worker/front/note/create/index.js create mode 100644 modules/worker/front/note/create/index.spec.js create mode 100644 modules/worker/front/note/create/locale/es.yml create mode 100644 modules/worker/front/note/index/index.html create mode 100644 modules/worker/front/note/index/index.js create mode 100644 modules/worker/front/note/index/style.scss diff --git a/db/changes/231201/00-workerNotes.sql b/db/changes/231201/00-workerNotes.sql new file mode 100644 index 000000000..602ea3296 --- /dev/null +++ b/db/changes/231201/00-workerNotes.sql @@ -0,0 +1,10 @@ +CREATE TABLE `vn`.`workerObservation` ( + `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, + `workerFk` int(10) unsigned DEFAULT NULL, + `userFk` int(10) unsigned DEFAULT NULL, + `text` text COLLATE utf8mb3_unicode_ci NOT NULL, + `created` timestamp NOT NULL DEFAULT current_timestamp(), + PRIMARY KEY (`id`), + CONSTRAINT `workerFk_workerObservation_FK` FOREIGN KEY (`workerFk`) REFERENCES `vn`.`worker` (`id`) ON UPDATE CASCADE, + CONSTRAINT `userFk_workerObservation_FK` FOREIGN KEY (`userFk`) REFERENCES `account`.`user`(`id`) ON UPDATE CASCADE +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Todas las observaciones referentes a un trabajador'; \ No newline at end of file diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index f20d75310..ad5ff2692 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -988,6 +988,12 @@ export default { locker: 'vn-worker-basic-data vn-input-number[ng-model="$ctrl.worker.locker"]', saveButton: 'vn-worker-basic-data button[type=submit]' }, + workerNotes: { + addNoteFloatButton: 'vn-float-button', + note: 'vn-textarea[ng-model="$ctrl.note.text"]', + saveButton: 'button[type=submit]', + firstNoteText: 'vn-worker-note .text' + }, workerPbx: { extension: 'vn-worker-pbx vn-textfield[ng-model="$ctrl.worker.sip.extension"]', saveButton: 'vn-worker-pbx button[type=submit]' diff --git a/e2e/paths/03-worker/08_add_notes.spec.js b/e2e/paths/03-worker/08_add_notes.spec.js new file mode 100644 index 000000000..eb2e4c041 --- /dev/null +++ b/e2e/paths/03-worker/08_add_notes.spec.js @@ -0,0 +1,42 @@ +import selectors from '../../helpers/selectors'; +import getBrowser from '../../helpers/puppeteer'; + +describe('Worker Add notes path', () => { + let browser; + let page; + beforeAll(async() => { + browser = await getBrowser(); + page = browser.page; + await page.loginAndModule('employee', 'worker'); + await page.accessToSearchResult('Bruce Banner'); + await page.accessToSection('worker.card.note.index'); + }); + + afterAll(async() => { + await browser.close(); + }); + + it(`should reach the notes index`, async() => { + await page.waitForState('worker.card.note.index'); + }); + + it(`should click on the add note button`, async() => { + await page.waitToClick(selectors.workerNotes.addNoteFloatButton); + await page.waitForState('worker.card.note.create'); + }); + + it(`should create a note`, async() => { + await page.waitForSelector(selectors.workerNotes.note); + await page.type(`${selectors.workerNotes.note} textarea`, 'Meeting with Black Widow 21st 9am'); + await page.waitToClick(selectors.workerNotes.saveButton); + const message = await page.waitForSnackbar(); + + expect(message.text).toContain('Data saved!'); + }); + + it('should confirm the note was created', async() => { + const result = await page.waitToGetProperty(selectors.workerNotes.firstNoteText, 'innerText'); + + expect(result).toEqual('Meeting with Black Widow 21st 9am'); + }); +}); diff --git a/modules/worker/front/index.js b/modules/worker/front/index.js index 657f6a8c6..8fad2c0df 100644 --- a/modules/worker/front/index.js +++ b/modules/worker/front/index.js @@ -18,3 +18,6 @@ import './log'; import './dms/index'; import './dms/create'; import './dms/edit'; +import './note/index'; +import './note/create'; + diff --git a/modules/worker/front/locale/es.yml b/modules/worker/front/locale/es.yml index b5bcfefa4..a25377122 100644 --- a/modules/worker/front/locale/es.yml +++ b/modules/worker/front/locale/es.yml @@ -31,3 +31,5 @@ Deallocate PDA: Desasignar PDA PDA deallocated: PDA desasignada PDA allocated: PDA asignada New PDA: Nueva PDA +Notes: Notas +New note: Nueva nota diff --git a/modules/worker/front/note/create/index.html b/modules/worker/front/note/create/index.html new file mode 100644 index 000000000..d09fc2da5 --- /dev/null +++ b/modules/worker/front/note/create/index.html @@ -0,0 +1,30 @@ + + +
+ + + + + + + + + + + + +
\ No newline at end of file diff --git a/modules/worker/front/note/create/index.js b/modules/worker/front/note/create/index.js new file mode 100644 index 000000000..81ee247db --- /dev/null +++ b/modules/worker/front/note/create/index.js @@ -0,0 +1,21 @@ +import ngModule from '../../module'; +import Section from 'salix/components/section'; + +export default class Controller extends Section { + constructor($element, $) { + super($element, $); + this.note = { + workerFk: parseInt(this.$params.id), + text: null + }; + } + + cancel() { + this.$state.go('worker.card.note.index', {id: this.$params.id}); + } +} + +ngModule.vnComponent('vnNoteWorkerCreate', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/worker/front/note/create/index.spec.js b/modules/worker/front/note/create/index.spec.js new file mode 100644 index 000000000..d900c8ee0 --- /dev/null +++ b/modules/worker/front/note/create/index.spec.js @@ -0,0 +1,22 @@ +import './index'; + +describe('Worker', () => { + describe('Component vnNoteWorkerCreate', () => { + let $state; + let controller; + + beforeEach(ngModule('worker')); + + beforeEach(inject(($componentController, _$state_) => { + $state = _$state_; + $state.params.id = '1234'; + const $element = angular.element(''); + controller = $componentController('vnNoteWorkerCreate', {$element, $state}); + })); + + it('should define workerFk using $state.params.id', () => { + expect(controller.note.workerFk).toBe(1234); + expect(controller.note.worker).toBe(undefined); + }); + }); +}); diff --git a/modules/worker/front/note/create/locale/es.yml b/modules/worker/front/note/create/locale/es.yml new file mode 100644 index 000000000..bfe773f48 --- /dev/null +++ b/modules/worker/front/note/create/locale/es.yml @@ -0,0 +1,2 @@ +New note: Nueva nota +Note: Nota \ No newline at end of file diff --git a/modules/worker/front/note/index/index.html b/modules/worker/front/note/index/index.html new file mode 100644 index 000000000..4b72d60ab --- /dev/null +++ b/modules/worker/front/note/index/index.html @@ -0,0 +1,31 @@ + + + + +
+ + {{::note.worker.user.nickname}} + {{::note.created | date:'dd/MM/yyyy HH:mm'}} + + + {{::note.text}} + +
+
+
+ + + diff --git a/modules/worker/front/note/index/index.js b/modules/worker/front/note/index/index.js new file mode 100644 index 000000000..d20971413 --- /dev/null +++ b/modules/worker/front/note/index/index.js @@ -0,0 +1,22 @@ +import ngModule from '../../module'; +import Section from 'salix/components/section'; +import './style.scss'; + +export default class Controller extends Section { + constructor($element, $) { + super($element, $); + this.filter = { + order: 'created DESC', + }; + } +} + +Controller.$inject = ['$element', '$scope']; + +ngModule.vnComponent('vnWorkerNote', { + template: require('./index.html'), + controller: Controller, + bindings: { + worker: '<' + } +}); diff --git a/modules/worker/front/note/index/style.scss b/modules/worker/front/note/index/style.scss new file mode 100644 index 000000000..5ff6baf4f --- /dev/null +++ b/modules/worker/front/note/index/style.scss @@ -0,0 +1,5 @@ +vn-worker-note { + .note:last-child { + margin-bottom: 0; + } +} \ No newline at end of file diff --git a/modules/worker/front/routes.json b/modules/worker/front/routes.json index 64b98bfca..64cb186d6 100644 --- a/modules/worker/front/routes.json +++ b/modules/worker/front/routes.json @@ -11,6 +11,7 @@ ], "card": [ {"state": "worker.card.basicData", "icon": "settings"}, + {"state": "worker.card.note.index", "icon": "insert_drive_file"}, {"state": "worker.card.timeControl", "icon": "access_time"}, {"state": "worker.card.calendar", "icon": "icon-calendar"}, {"state": "worker.card.pda", "icon": "phone_android"}, @@ -72,6 +73,24 @@ "component": "vn-worker-log", "description": "Log", "acl": ["salesAssistant"] + }, { + "url": "/note", + "state": "worker.card.note", + "component": "ui-view", + "abstract": true + }, { + "url": "/index", + "state": "worker.card.note.index", + "component": "vn-worker-note", + "description": "Notes", + "params": { + "worker": "$ctrl.worker" + } + }, { + "url": "/create", + "state": "worker.card.note.create", + "component": "vn-note-worker-create", + "description": "New note" }, { "url": "/pbx", "state": "worker.card.pbx", From c68c78cc5b80fb7f935e86862e52d0c5479a344f Mon Sep 17 00:00:00 2001 From: carlossa Date: Fri, 24 Mar 2023 12:11:42 +0100 Subject: [PATCH 02/14] refs #5250 solucion error WorkerObserv --- db/changes/231201/00-workerNotes.sql | 6 ++- modules/worker/back/model-config.json | 3 ++ .../worker/back/models/worker-observation.js | 13 +++++++ .../back/models/worker-observation.json | 39 +++++++++++++++++++ modules/worker/front/note/index/index.html | 5 ++- 5 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 modules/worker/back/models/worker-observation.js create mode 100644 modules/worker/back/models/worker-observation.json diff --git a/db/changes/231201/00-workerNotes.sql b/db/changes/231201/00-workerNotes.sql index 602ea3296..0d9eaae7e 100644 --- a/db/changes/231201/00-workerNotes.sql +++ b/db/changes/231201/00-workerNotes.sql @@ -7,4 +7,8 @@ CREATE TABLE `vn`.`workerObservation` ( PRIMARY KEY (`id`), CONSTRAINT `workerFk_workerObservation_FK` FOREIGN KEY (`workerFk`) REFERENCES `vn`.`worker` (`id`) ON UPDATE CASCADE, CONSTRAINT `userFk_workerObservation_FK` FOREIGN KEY (`userFk`) REFERENCES `account`.`user`(`id`) ON UPDATE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Todas las observaciones referentes a un trabajador'; \ No newline at end of file +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Todas las observaciones referentes a un trabajador'; + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('WorkerObservation', '*', '*', 'ALLOW', 'ROLE', 'hr'); diff --git a/modules/worker/back/model-config.json b/modules/worker/back/model-config.json index 63fc65827..145934700 100644 --- a/modules/worker/back/model-config.json +++ b/modules/worker/back/model-config.json @@ -53,6 +53,9 @@ "Worker": { "dataSource": "vn" }, + "WorkerObservation": { + "dataSource": "vn" + }, "WorkerConfig": { "dataSource": "vn" }, diff --git a/modules/worker/back/models/worker-observation.js b/modules/worker/back/models/worker-observation.js new file mode 100644 index 000000000..3a4480265 --- /dev/null +++ b/modules/worker/back/models/worker-observation.js @@ -0,0 +1,13 @@ +module.exports = function(Self) { + Self.validate('text', isEnabled, {message: 'Description cannot be blank'}); + function isEnabled(err) { + if (!this.text) err(); + } + + Self.observe('before save', async function(ctx) { + ctx.instance.created = new Date(); + let token = ctx.options.accessToken; + let userId = token && token.userId; + ctx.instance.userFk = userId; + }); +}; diff --git a/modules/worker/back/models/worker-observation.json b/modules/worker/back/models/worker-observation.json new file mode 100644 index 000000000..90eb35837 --- /dev/null +++ b/modules/worker/back/models/worker-observation.json @@ -0,0 +1,39 @@ +{ + "name": "WorkerObservation", + "base": "VnModel", + "options": { + "mysql": { + "table": "workerObservation" + } + }, + "properties": { + "id": { + "id": true, + "type": "number" + }, + "workerFk": { + "type": "number" + }, + "userFk": { + "type": "number" + }, + "text": { + "type": "string" + }, + "created": { + "type": "date" + } + }, + "relations": { + "worker": { + "type": "belongsTo", + "model": "Worker", + "foreignKey": "workerFk" + }, + "user":{ + "type": "belongsTo", + "model": "Account", + "foreignKey": "userFk" + } + } +} diff --git a/modules/worker/front/note/index/index.html b/modules/worker/front/note/index/index.html index 4b72d60ab..9f5c27008 100644 --- a/modules/worker/front/note/index/index.html +++ b/modules/worker/front/note/index/index.html @@ -1,8 +1,9 @@ @@ -14,7 +15,7 @@ ng-repeat="note in notes" class="note vn-pa-sm border-solid border-radius vn-mb-md"> - {{::note.worker.user.nickname}} + {{::note.user.nickname}} {{::note.created | date:'dd/MM/yyyy HH:mm'}} From 564165dc0ff5a150bbf1462a4a4fce01b5c3dcbe Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 28 Mar 2023 10:07:14 +0200 Subject: [PATCH 03/14] refs #5250 Self.validatesPresenceOf --- modules/worker/back/models/worker-observation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/worker/back/models/worker-observation.js b/modules/worker/back/models/worker-observation.js index 3a4480265..413d9a2ba 100644 --- a/modules/worker/back/models/worker-observation.js +++ b/modules/worker/back/models/worker-observation.js @@ -1,5 +1,5 @@ module.exports = function(Self) { - Self.validate('text', isEnabled, {message: 'Description cannot be blank'}); + Self.validatesPresenceOf('text', isEnabled, {message: 'Description cannot be blank'}); function isEnabled(err) { if (!this.text) err(); } From d066c4ea0be719ff48948c5b3349b9f104862108 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 29 Mar 2023 11:27:48 +0200 Subject: [PATCH 04/14] refs #4856 feat: se envia el registro a todos los teletrabajadores. Tmb se pone estado 'SENDED' cuando se da a 'Reenviar' --- .../back/methods/worker-time-control/sendMail.js | 14 ++------------ modules/worker/front/time-control/index.js | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/modules/worker/back/methods/worker-time-control/sendMail.js b/modules/worker/back/methods/worker-time-control/sendMail.js index 579a83112..7aff9e790 100644 --- a/modules/worker/back/methods/worker-time-control/sendMail.js +++ b/modules/worker/back/methods/worker-time-control/sendMail.js @@ -131,20 +131,10 @@ module.exports = Self => { JOIN business b ON b.id = tb.businessFk LEFT JOIN tmp.timeControlCalculate tc ON tc.userFk = tb.userFk AND tc.dated = tb.dated LEFT JOIN worker w ON w.id = u.id - JOIN (SELECT tb.userFk, - SUM(IF(tb.type IS NULL, - IF(tc.timeWorkDecimal > 0, FALSE, IF(tb.timeWorkDecimal > 0, TRUE, FALSE)), - TRUE))isTeleworkingWeek - FROM tmp.timeBusinessCalculate tb - LEFT JOIN tmp.timeControlCalculate tc ON tc.userFk = tb.userFk - AND tc.dated = tb.dated - GROUP BY tb.userFk - HAVING isTeleworkingWeek > 0 - )sub ON sub.userFk = u.id - WHERE d.hasToRefill - AND IFNULL(?, u.id) = u.id + WHERE IFNULL(?, u.id) = u.id AND b.companyCodeFk = 'VNL' AND w.businessFk + AND d.isTeleworking ORDER BY u.id, tb.dated `, [args.workerId]); const index = stmts.push(stmt) - 1; diff --git a/modules/worker/front/time-control/index.js b/modules/worker/front/time-control/index.js index 9ed454d31..3e4aeaa5c 100644 --- a/modules/worker/front/time-control/index.js +++ b/modules/worker/front/time-control/index.js @@ -379,6 +379,20 @@ class Controller extends Section { }); } + isSended() { + const params = { + workerId: this.worker.id, + year: this.date.getFullYear(), + week: this.weekNumber, + state: 'SENDED' + }; + const query = `WorkerTimeControls/updateWorkerTimeControlMail`; + this.$http.post(query, params).then(() => { + this.getMailStates(this.date); + this.getWeekData(); + }); + } + changeState(state, reason) { this.state = state; this.reason = reason; @@ -412,6 +426,7 @@ class Controller extends Section { }; this.$http.post(`WorkerTimeControls/weekly-hour-hecord-email`, params) .then(() => { + this.isSended(); this.vnApp.showSuccess(this.$t('Email sended')); }); } From 5a67f473054fbf1ad2bec943b45366fd3e4217bd Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 30 Mar 2023 08:14:17 +0200 Subject: [PATCH 05/14] refs #4856 fix: actualizar estado a 'SENDED' movido al back --- .../updateWorkerTimeControlMail.js | 6 +++++ .../weeklyHourRecordEmail.js | 24 +++++++++++-------- .../back/models/worker-time-control-mail.json | 3 +++ modules/worker/front/time-control/index.html | 2 +- modules/worker/front/time-control/index.js | 18 +++----------- 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js b/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js index 642ff90d2..3c44bda40 100644 --- a/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js +++ b/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js @@ -69,6 +69,12 @@ module.exports = Self => { reason: args.reason || null }, myOptions); + if (args.state == 'SENDED') { + await workerTimeControlMail.updateAttributes({ + sendedCounter: workerTimeControlMail.sendedCounter + 1 + }, myOptions); + } + const logRecord = { originFk: args.workerId, userFk: userId, diff --git a/modules/worker/back/methods/worker-time-control/weeklyHourRecordEmail.js b/modules/worker/back/methods/worker-time-control/weeklyHourRecordEmail.js index 6feadb936..8e9b325a6 100644 --- a/modules/worker/back/methods/worker-time-control/weeklyHourRecordEmail.js +++ b/modules/worker/back/methods/worker-time-control/weeklyHourRecordEmail.js @@ -25,6 +25,16 @@ module.exports = Self => { arg: 'url', type: 'string', required: true + }, + { + arg: 'workerId', + type: 'number', + required: true + }, + { + arg: 'state', + type: 'string', + required: true } ], returns: { @@ -37,17 +47,11 @@ module.exports = Self => { } }); - Self.weeklyHourRecordEmail = async(ctx, recipient, week, year, url) => { - const params = { - recipient: recipient, - lang: ctx.req.getLocale(), - week: week, - year: year, - url: url - }; + Self.weeklyHourRecordEmail = async ctx => { + const models = Self.app.models; - const email = new Email('weekly-hour-record', params); + Self.sendTemplate(ctx, 'weekly-hour-record'); - return email.send(); + return models.WorkerTimeControl.updateWorkerTimeControlMail(ctx); }; }; diff --git a/modules/worker/back/models/worker-time-control-mail.json b/modules/worker/back/models/worker-time-control-mail.json index 78b99881d..87eae9217 100644 --- a/modules/worker/back/models/worker-time-control-mail.json +++ b/modules/worker/back/models/worker-time-control-mail.json @@ -28,6 +28,9 @@ }, "reason": { "type": "string" + }, + "sendedCounter": { + "type": "number" } }, "acls": [ diff --git a/modules/worker/front/time-control/index.html b/modules/worker/front/time-control/index.html index bd7e68b89..044ea4038 100644 --- a/modules/worker/front/time-control/index.html +++ b/modules/worker/front/time-control/index.html @@ -204,7 +204,7 @@ vn-id="sendEmailConfirmation" on-accept="$ctrl.resendEmail()" message="Send time control email"> - + Are you sure you want to send it? diff --git a/modules/worker/front/time-control/index.js b/modules/worker/front/time-control/index.js index 3e4aeaa5c..ebfc8b444 100644 --- a/modules/worker/front/time-control/index.js +++ b/modules/worker/front/time-control/index.js @@ -379,20 +379,6 @@ class Controller extends Section { }); } - isSended() { - const params = { - workerId: this.worker.id, - year: this.date.getFullYear(), - week: this.weekNumber, - state: 'SENDED' - }; - const query = `WorkerTimeControls/updateWorkerTimeControlMail`; - this.$http.post(query, params).then(() => { - this.getMailStates(this.date); - this.getWeekData(); - }); - } - changeState(state, reason) { this.state = state; this.reason = reason; @@ -423,10 +409,12 @@ class Controller extends Section { week: this.weekNumber, year: this.date.getFullYear(), url: url, + workerId: this.worker.id, + state: 'SENDED' }; this.$http.post(`WorkerTimeControls/weekly-hour-hecord-email`, params) .then(() => { - this.isSended(); + this.getMailStates(this.date); this.vnApp.showSuccess(this.$t('Email sended')); }); } From 4edb2463b8c9f4a97eabaf35a234e7ade33d5e66 Mon Sep 17 00:00:00 2001 From: carlossa Date: Thu, 30 Mar 2023 08:23:53 +0200 Subject: [PATCH 06/14] refs #5250 eliminacion isEnabled --- modules/worker/back/models/worker-observation.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/worker/back/models/worker-observation.js b/modules/worker/back/models/worker-observation.js index 413d9a2ba..cccc2cfbd 100644 --- a/modules/worker/back/models/worker-observation.js +++ b/modules/worker/back/models/worker-observation.js @@ -1,8 +1,7 @@ module.exports = function(Self) { - Self.validatesPresenceOf('text', isEnabled, {message: 'Description cannot be blank'}); - function isEnabled(err) { - if (!this.text) err(); - } + Self.validatesPresenceOf('text', { + message: 'Description cannot be blank' + }); Self.observe('before save', async function(ctx) { ctx.instance.created = new Date(); From e1bfdc3f3cb5d4b57e8c0b05cefecb1a399f09f1 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 30 Mar 2023 11:13:40 +0200 Subject: [PATCH 07/14] eliminada variable que no se usa --- .../back/methods/worker-time-control/weeklyHourRecordEmail.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/worker/back/methods/worker-time-control/weeklyHourRecordEmail.js b/modules/worker/back/methods/worker-time-control/weeklyHourRecordEmail.js index 8e9b325a6..4c6f647cb 100644 --- a/modules/worker/back/methods/worker-time-control/weeklyHourRecordEmail.js +++ b/modules/worker/back/methods/worker-time-control/weeklyHourRecordEmail.js @@ -1,5 +1,3 @@ -const {Email} = require('vn-print'); - module.exports = Self => { Self.remoteMethodCtx('weeklyHourRecordEmail', { description: 'Sends the weekly hour record', From 862101c4b018cfc217b1fffc8432551f60d258e0 Mon Sep 17 00:00:00 2001 From: vicent Date: Mon, 3 Apr 2023 21:29:02 +0200 Subject: [PATCH 08/14] refs #4856 feat: si se modifica una fichada actualiza el estado a 'SENDED' y notifica al trabajador --- .../worker-time-control/addTimeEntry.js | 2 + .../worker-time-control/deleteTimeEntry.js | 6 +- .../resendWeeklyHourEmail.js | 68 +++++++++++++++++++ .../methods/worker-time-control/sendMail.js | 21 +++--- .../worker-time-control/updateTimeEntry.js | 6 +- .../weeklyHourRecordEmail.js | 46 +++++++++++-- .../worker/back/models/worker-time-control.js | 1 + modules/worker/front/time-control/index.js | 12 ++-- 8 files changed, 139 insertions(+), 23 deletions(-) create mode 100644 modules/worker/back/methods/worker-time-control/resendWeeklyHourEmail.js diff --git a/modules/worker/back/methods/worker-time-control/addTimeEntry.js b/modules/worker/back/methods/worker-time-control/addTimeEntry.js index fef3cf223..c8c08d9b1 100644 --- a/modules/worker/back/methods/worker-time-control/addTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/addTimeEntry.js @@ -51,6 +51,8 @@ module.exports = Self => { if (response[0] && response[0].error) throw new UserError(response[0].error); + await models.WorkerTimeControl.resendWeeklyHourEmail(ctx, workerId, args.timed, myOptions); + return response; }; }; diff --git a/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js b/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js index c80dcab81..e33d6b790 100644 --- a/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js @@ -38,7 +38,11 @@ module.exports = Self => { if (isSubordinate === false || (isSubordinate && isHimself && !isTeamBoss)) throw new UserError(`You don't have enough privileges`); - return Self.rawSql('CALL vn.workerTimeControl_remove(?, ?)', [ + const response = await Self.rawSql('CALL vn.workerTimeControl_remove(?, ?)', [ targetTimeEntry.userFk, targetTimeEntry.timed], myOptions); + + await models.WorkerTimeControl.resendWeeklyHourEmail(ctx, targetTimeEntry.userFk, targetTimeEntry.timed, myOptions); + + return response; }; }; diff --git a/modules/worker/back/methods/worker-time-control/resendWeeklyHourEmail.js b/modules/worker/back/methods/worker-time-control/resendWeeklyHourEmail.js new file mode 100644 index 000000000..5fae6988c --- /dev/null +++ b/modules/worker/back/methods/worker-time-control/resendWeeklyHourEmail.js @@ -0,0 +1,68 @@ +module.exports = Self => { + Self.remoteMethodCtx('resendWeeklyHourEmail', { + description: 'Adds a new hour registry', + accessType: 'WRITE', + accepts: [{ + arg: 'id', + type: 'number', + description: 'The worker id', + http: {source: 'path'} + }, + { + arg: 'dated', + type: 'date', + required: true + }], + returns: [{ + type: 'Object', + root: true + }], + http: { + path: `/:id/resendWeeklyHourEmail`, + verb: 'POST' + } + }); + + Self.resendWeeklyHourEmail = async(ctx, workerId, dated, options) => { + const models = Self.app.models; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const yearNumber = dated.getFullYear(); + const weekNumber = getWeekNumber(dated); + const workerTimeControlMail = await models.WorkerTimeControlMail.findOne({ + where: { + workerFk: workerId, + year: yearNumber, + week: weekNumber + } + }, myOptions); + + if (workerTimeControlMail && workerTimeControlMail.state != 'SENDED') { + const worker = await models.EmailUser.findById(workerId); + ctx.args = { + recipient: worker.email, + year: yearNumber, + week: weekNumber, + workerId: workerId, + state: 'SENDED' + }; + return models.WorkerTimeControl.weeklyHourRecordEmail(ctx, myOptions); + } + + return false; + }; + + function getWeekNumber(date) { + const tempDate = new Date(date); + let dayOfWeek = tempDate.getDay(); + dayOfWeek = (dayOfWeek === 0) ? 7 : dayOfWeek; + const firstDayOfWeek = new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() - (dayOfWeek - 1)); + const firstDayOfYear = new Date(tempDate.getFullYear(), 0, 1); + const differenceInMilliseconds = firstDayOfWeek.getTime() - firstDayOfYear.getTime(); + const weekNumber = Math.floor(differenceInMilliseconds / (1000 * 60 * 60 * 24 * 7)) + 1; + return weekNumber; + } +}; diff --git a/modules/worker/back/methods/worker-time-control/sendMail.js b/modules/worker/back/methods/worker-time-control/sendMail.js index 7aff9e790..9d17265e8 100644 --- a/modules/worker/back/methods/worker-time-control/sendMail.js +++ b/modules/worker/back/methods/worker-time-control/sendMail.js @@ -322,17 +322,20 @@ module.exports = Self => { const lastDay = days[index][days[index].length - 1]; if (day.workerFk != previousWorkerFk || day == lastDay) { - const salix = await models.Url.findOne({ - where: { - appName: 'salix', - environment: process.env.NODE_ENV || 'dev' - } + await models.WorkerTimeControlMail.create({ + workerFk: previousWorkerFk, + year: args.year, + week: args.week }, myOptions); - const timestamp = started.getTime() / 1000; - const url = `${salix.url}worker/${previousWorkerFk}/time-control?timestamp=${timestamp}`; - - await models.WorkerTimeControl.weeklyHourRecordEmail(ctx, previousReceiver, args.week, args.year, url); + ctx.args = { + recipient: previousReceiver, + year: args.year, + week: args.week, + workerId: previousWorkerFk, + state: 'SENDED' + }; + await models.WorkerTimeControl.weeklyHourRecordEmail(ctx, myOptions); previousWorkerFk = day.workerFk; previousReceiver = day.receiver; diff --git a/modules/worker/back/methods/worker-time-control/updateTimeEntry.js b/modules/worker/back/methods/worker-time-control/updateTimeEntry.js index a99a61770..83349ea63 100644 --- a/modules/worker/back/methods/worker-time-control/updateTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/updateTimeEntry.js @@ -46,8 +46,12 @@ module.exports = Self => { if (notAllowed) throw new UserError(`You don't have enough privileges`); - return targetTimeEntry.updateAttributes({ + const timeEntryUpdated = await targetTimeEntry.updateAttributes({ direction: args.direction }, myOptions); + + await models.WorkerTimeControl.resendWeeklyHourEmail(ctx, targetTimeEntry.userFk, targetTimeEntry.timed, myOptions); + + return timeEntryUpdated; }; }; diff --git a/modules/worker/back/methods/worker-time-control/weeklyHourRecordEmail.js b/modules/worker/back/methods/worker-time-control/weeklyHourRecordEmail.js index 4c6f647cb..f44080559 100644 --- a/modules/worker/back/methods/worker-time-control/weeklyHourRecordEmail.js +++ b/modules/worker/back/methods/worker-time-control/weeklyHourRecordEmail.js @@ -19,11 +19,6 @@ module.exports = Self => { type: 'number', required: true }, - { - arg: 'url', - type: 'string', - required: true - }, { arg: 'workerId', type: 'number', @@ -45,11 +40,48 @@ module.exports = Self => { } }); - Self.weeklyHourRecordEmail = async ctx => { + Self.weeklyHourRecordEmail = async(ctx, options) => { const models = Self.app.models; + const args = ctx.args; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const salix = await models.Url.findOne({ + where: { + appName: 'salix', + environment: process.env.NODE_ENV || 'dev' + } + }, myOptions); + + const dated = getMondayDateFromYearWeek(args.year, args.week); + const timestamp = dated.getTime() / 1000; + + const url = `${salix.url}worker/${args.workerId}/time-control?timestamp=${timestamp}`; + ctx.args.url = url; Self.sendTemplate(ctx, 'weekly-hour-record'); - return models.WorkerTimeControl.updateWorkerTimeControlMail(ctx); + return models.WorkerTimeControl.updateWorkerTimeControlMail(ctx, myOptions); }; + + function getMondayDateFromYearWeek(yearNumber, weekNumber) { + const yearStart = new Date(yearNumber, 0, 1); + const firstMonday = new Date(yearStart.getTime() + ((7 - yearStart.getDay() + 1) % 7) * 86400000); + const firstMondayWeekNumber = getWeekNumber(firstMonday); + + if (firstMondayWeekNumber > 1) + firstMonday.setDate(firstMonday.getDate() + 7); + + firstMonday.setDate(firstMonday.getDate() + (weekNumber - 1) * 7); + + return firstMonday; + } + + function getWeekNumber(date) { + const firstDayOfYear = new Date(date.getFullYear(), 0, 1); + const daysPassed = (date - firstDayOfYear) / 86400000; + return Math.ceil((daysPassed + firstDayOfYear.getDay() + 1) / 7); + } }; diff --git a/modules/worker/back/models/worker-time-control.js b/modules/worker/back/models/worker-time-control.js index 5b13e17f2..d5da680cf 100644 --- a/modules/worker/back/models/worker-time-control.js +++ b/modules/worker/back/models/worker-time-control.js @@ -9,6 +9,7 @@ module.exports = Self => { require('../methods/worker-time-control/updateWorkerTimeControlMail')(Self); require('../methods/worker-time-control/weeklyHourRecordEmail')(Self); require('../methods/worker-time-control/getMailStates')(Self); + require('../methods/worker-time-control/resendWeeklyHourEmail')(Self); Self.rewriteDbError(function(err) { if (err.code === 'ER_DUP_ENTRY') diff --git a/modules/worker/front/time-control/index.js b/modules/worker/front/time-control/index.js index ebfc8b444..85ddcedfe 100644 --- a/modules/worker/front/time-control/index.js +++ b/modules/worker/front/time-control/index.js @@ -303,7 +303,10 @@ class Controller extends Section { const query = `WorkerTimeControls/${this.worker.id}/addTimeEntry`; this.$http.post(query, entry) - .then(() => this.fetchHours()); + .then(() => { + this.fetchHours(); + this.getMailStates(this.date); + }); } catch (e) { this.vnApp.showError(this.$t(e.message)); return false; @@ -324,6 +327,7 @@ class Controller extends Section { this.$http.post(`WorkerTimeControls/${entryId}/deleteTimeEntry`).then(() => { this.fetchHours(); + this.getMailStates(this.date); this.vnApp.showSuccess(this.$t('Entry removed')); }); } @@ -395,20 +399,18 @@ class Controller extends Section { this.$http.post(query, {direction: entry.direction}) .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))) .then(() => this.$.editEntry.hide()) - .then(() => this.fetchHours()); + .then(() => this.fetchHours()) + .then(() => this.getMailStates(this.date)); } catch (e) { this.vnApp.showError(this.$t(e.message)); } } resendEmail() { - const timestamp = this.date.getTime() / 1000; - const url = `${window.location.origin}/#!/worker/${this.worker.id}/time-control?timestamp=${timestamp}`; const params = { recipient: this.worker.user.emailUser.email, week: this.weekNumber, year: this.date.getFullYear(), - url: url, workerId: this.worker.id, state: 'SENDED' }; From 21b7050cfd6b95fa32a9cb8241911ad1690bdb1f Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 4 Apr 2023 09:29:40 +0200 Subject: [PATCH 09/14] refs #4856 otros usuarios pueden actualizar el estado --- .../worker-time-control/updateWorkerTimeControlMail.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js b/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js index 3c44bda40..6f794511f 100644 --- a/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js +++ b/modules/worker/back/methods/worker-time-control/updateWorkerTimeControlMail.js @@ -47,10 +47,6 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); - const isHimself = userId == args.workerId; - if (!isHimself) - throw new UserError(`You don't have enough privileges`); - const workerTimeControlMail = await models.WorkerTimeControlMail.findOne({ where: { workerFk: args.workerId, From 0db3bc5e26c53e33bf4c1858cebd13a38aeef42e Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 4 Apr 2023 09:29:51 +0200 Subject: [PATCH 10/14] refs #4856 fix test --- .../specs/sendMail.spec.js | 120 ------------------ .../worker/front/time-control/index.spec.js | 9 ++ 2 files changed, 9 insertions(+), 120 deletions(-) delete mode 100644 modules/worker/back/methods/worker-time-control/specs/sendMail.spec.js diff --git a/modules/worker/back/methods/worker-time-control/specs/sendMail.spec.js b/modules/worker/back/methods/worker-time-control/specs/sendMail.spec.js deleted file mode 100644 index 24bfd6904..000000000 --- a/modules/worker/back/methods/worker-time-control/specs/sendMail.spec.js +++ /dev/null @@ -1,120 +0,0 @@ -const models = require('vn-loopback/server/server').models; - -describe('workerTimeControl sendMail()', () => { - const workerId = 18; - const activeCtx = { - getLocale: () => { - return 'en'; - } - }; - const ctx = {req: activeCtx, args: {}}; - - it('should fill time control of a worker without records in Journey and with rest', async() => { - const tx = await models.WorkerTimeControl.beginTransaction({}); - - try { - const options = {transaction: tx}; - - await models.WorkerTimeControl.sendMail(ctx, options); - - const workerTimeControl = await models.WorkerTimeControl.find({ - where: {userFk: workerId} - }, options); - - expect(workerTimeControl[0].timed.getHours()).toEqual(8); - expect(workerTimeControl[1].timed.getHours()).toEqual(9); - expect(`${workerTimeControl[2].timed.getHours()}:${workerTimeControl[2].timed.getMinutes()}`).toEqual('9:20'); - expect(workerTimeControl[3].timed.getHours()).toEqual(16); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should fill time control of a worker without records in Journey and without rest', async() => { - const workdayOf20Hours = 3; - const tx = await models.WorkerTimeControl.beginTransaction({}); - - try { - const options = {transaction: tx}; - query = `UPDATE business b - SET b.calendarTypeFk = ? - WHERE b.workerFk = ?; `; - await models.WorkerTimeControl.rawSql(query, [workdayOf20Hours, workerId], options); - - await models.WorkerTimeControl.sendMail(ctx, options); - - const workerTimeControl = await models.WorkerTimeControl.find({ - where: {userFk: workerId} - }, options); - - expect(workerTimeControl[0].timed.getHours()).toEqual(8); - expect(workerTimeControl[1].timed.getHours()).toEqual(12); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should fill time control of a worker with records in Journey and with rest', async() => { - const tx = await models.WorkerTimeControl.beginTransaction({}); - - try { - const options = {transaction: tx}; - query = `INSERT INTO postgresql.journey(journey_id, day_id, start, end, business_id) - VALUES - (1, 1, '09:00:00', '13:00:00', ?), - (2, 1, '14:00:00', '19:00:00', ?);`; - await models.WorkerTimeControl.rawSql(query, [workerId, workerId, workerId], options); - - await models.WorkerTimeControl.sendMail(ctx, options); - - const workerTimeControl = await models.WorkerTimeControl.find({ - where: {userFk: workerId} - }, options); - - expect(workerTimeControl[0].timed.getHours()).toEqual(9); - expect(workerTimeControl[2].timed.getHours()).toEqual(10); - expect(`${workerTimeControl[3].timed.getHours()}:${workerTimeControl[3].timed.getMinutes()}`).toEqual('10:20'); - expect(workerTimeControl[1].timed.getHours()).toEqual(13); - expect(workerTimeControl[4].timed.getHours()).toEqual(14); - expect(workerTimeControl[5].timed.getHours()).toEqual(19); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); - - it('should fill time control of a worker with records in Journey and without rest', async() => { - const tx = await models.WorkerTimeControl.beginTransaction({}); - - try { - const options = {transaction: tx}; - query = `INSERT INTO postgresql.journey(journey_id, day_id, start, end, business_id) - VALUES - (1, 1, '12:30:00', '14:00:00', ?);`; - await models.WorkerTimeControl.rawSql(query, [workerId, workerId, workerId], options); - - await models.WorkerTimeControl.sendMail(ctx, options); - - const workerTimeControl = await models.WorkerTimeControl.find({ - where: {userFk: workerId} - }, options); - - expect(`${workerTimeControl[0].timed.getHours()}:${workerTimeControl[0].timed.getMinutes()}`).toEqual('12:30'); - expect(workerTimeControl[1].timed.getHours()).toEqual(14); - - await tx.rollback(); - } catch (e) { - await tx.rollback(); - throw e; - } - }); -}); - diff --git a/modules/worker/front/time-control/index.spec.js b/modules/worker/front/time-control/index.spec.js index 0f9b48f6b..94f9d3d48 100644 --- a/modules/worker/front/time-control/index.spec.js +++ b/modules/worker/front/time-control/index.spec.js @@ -120,6 +120,13 @@ describe('Component vnWorkerTimeControl', () => { describe('save() ', () => { it(`should make a query an then call to the fetchHours() method`, () => { + const today = Date.vnNew(); + + jest.spyOn(controller, 'getWeekData').mockReturnThis(); + jest.spyOn(controller, 'getMailStates').mockReturnThis(); + + controller.$.model = {applyFilter: jest.fn().mockReturnValue(Promise.resolve())}; + controller.date = today; controller.fetchHours = jest.fn(); controller.selectedRow = {id: 1, timed: Date.vnNew(), direction: 'in'}; controller.$.editEntry = { @@ -240,7 +247,9 @@ describe('Component vnWorkerTimeControl', () => { describe('resendEmail() ', () => { it(`should make a query an then call showSuccess method`, () => { const today = Date.vnNew(); + jest.spyOn(controller, 'getWeekData').mockReturnThis(); + jest.spyOn(controller, 'getMailStates').mockReturnThis(); jest.spyOn(controller.vnApp, 'showSuccess'); controller.$.model = {applyFilter: jest.fn().mockReturnValue(Promise.resolve())}; From a44a640d155ee5b271860217e8bd1beedc73fb18 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 5 Apr 2023 15:14:42 +0200 Subject: [PATCH 11/14] refs #4856 manejo errores --- .../methods/worker-time-control/sendMail.js | 60 ++++++++++++++----- 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/modules/worker/back/methods/worker-time-control/sendMail.js b/modules/worker/back/methods/worker-time-control/sendMail.js index 9d17265e8..17893e6ad 100644 --- a/modules/worker/back/methods/worker-time-control/sendMail.js +++ b/modules/worker/back/methods/worker-time-control/sendMail.js @@ -82,14 +82,9 @@ module.exports = Self => { updated: Date.vnNew(), state: 'SENDED' }, myOptions); - stmt = new ParameterizedSQL( - `CALL vn.timeControl_calculateByUser(?, ?, ?) - `, [args.workerId, started, ended]); + stmt = new ParameterizedSQL('DROP TEMPORARY TABLE IF EXISTS tmp.`user`'); stmts.push(stmt); - - stmt = new ParameterizedSQL( - `CALL vn.timeBusiness_calculateByUser(?, ?, ?) - `, [args.workerId, started, ended]); + stmt = new ParameterizedSQL('CREATE TEMPORARY TABLE tmp.`user` SELECT id userFk FROM account.user WHERE id = vUserFk', [args.workerId]); stmts.push(stmt); } else { await models.WorkerTimeControl.destroyAll({ @@ -105,13 +100,27 @@ module.exports = Self => { updated: Date.vnNew(), state: 'SENDED' }, myOptions); - stmt = new ParameterizedSQL(`CALL vn.timeControl_calculateAll(?, ?)`, [started, ended]); + stmt = new ParameterizedSQL('DROP TEMPORARY TABLE IF EXISTS tmp.`user`'); stmts.push(stmt); - - stmt = new ParameterizedSQL(`CALL vn.timeBusiness_calculateAll(?, ?)`, [started, ended]); + stmt = new ParameterizedSQL('CREATE TEMPORARY TABLE IF NOT EXISTS tmp.`user` SELECT userFk FROM vn.worker w JOIN account.`user` u ON u.id = w.userFk WHERE userFk IS NOT NULL'); stmts.push(stmt); } + stmt = new ParameterizedSQL( + `CALL vn.timeControl_calculate(?, ?) + `, [started, ended]); + stmts.push(stmt); + + stmt = new ParameterizedSQL( + `CALL vn.timeControl_getError(?, ?) + `, [started, ended]); + stmts.push(stmt); + + stmt = new ParameterizedSQL( + `CALL vn.timeBusiness_calculate(?, ?) + `, [started, ended]); + stmts.push(stmt); + stmt = new ParameterizedSQL(` SELECT CONCAT(u.name, '@verdnatura.es') receiver, u.id workerFk, @@ -131,7 +140,13 @@ module.exports = Self => { JOIN business b ON b.id = tb.businessFk LEFT JOIN tmp.timeControlCalculate tc ON tc.userFk = tb.userFk AND tc.dated = tb.dated LEFT JOIN worker w ON w.id = u.id - WHERE IFNULL(?, u.id) = u.id + LEFT JOIN ( + SELECT DISTINCT wtc.userFk + FROM tmp.timeControlError tce + JOIN vn.workerTimeControl wtc ON wtc.id = tce.id + )sub ON sub.userFk = tb.userFk + WHERE sub.userFK IS NULL + AND IFNULL(?, u.id) = u.id AND b.companyCodeFk = 'VNL' AND w.businessFk AND d.isTeleworking @@ -322,11 +337,9 @@ module.exports = Self => { const lastDay = days[index][days[index].length - 1]; if (day.workerFk != previousWorkerFk || day == lastDay) { - await models.WorkerTimeControlMail.create({ - workerFk: previousWorkerFk, - year: args.year, - week: args.week - }, myOptions); + const query = `INSERT IGNORE INTO workerTimeControlMail (workerFk, year, week) + VALUES(?, ?, ?);`; + await Self.rawSql(query, [previousWorkerFk, args.year, args.week]); ctx.args = { recipient: previousReceiver, @@ -351,6 +364,21 @@ module.exports = Self => { } } + // await Self.rawSql('DROP TEMPORARY TABLE IF EXISTS tmp.`user`'); + await Self.rawSql('CREATE TEMPORARY TABLE IF NOT EXISTS tmp.`user` SELECT userFk FROM vn.worker w JOIN account.`user` u ON u.id = w.userFk WHERE userFk IS NOT NULL'); + + await Self.rawSql(`CALL vn.timeControl_getError(?, ?);`, [started, ended]); + const query = `INSERT INTO mail (receiver, replyTo, subject, body) + SELECT CONCAT(u.name, '@verdnatura.es'), + CONCAT('Error registro de horas semana ', vWeek, ' año ', vYear) , + CONCAT('No se ha podido enviar el registro de horas al empleado/s: ', GROUP_CONCAT(DISTINCT CONCAT('
', w.id, ' ', w.firstName, ' ', w.lastName))) + FROM tmp.timeControlError tce + JOIN vn.workerTimeControl wtc ON wtc.id = tce.id + JOIN worker w ON w.id = wtc.userFK + JOIN account.user u ON u.id = w.bossFk + GROUP BY w.bossFk;`; + await Self.rawSql(query, [previousWorkerFk, args.year, args.week]); + return true; }; From 041590e541965af477e6a373d6867d8428b131ed Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 6 Apr 2023 08:54:12 +0200 Subject: [PATCH 12/14] refs #4856 maneja errores y notifica a los jefes --- .../methods/worker-time-control/sendMail.js | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/modules/worker/back/methods/worker-time-control/sendMail.js b/modules/worker/back/methods/worker-time-control/sendMail.js index 17893e6ad..2c827e320 100644 --- a/modules/worker/back/methods/worker-time-control/sendMail.js +++ b/modules/worker/back/methods/worker-time-control/sendMail.js @@ -84,7 +84,7 @@ module.exports = Self => { stmt = new ParameterizedSQL('DROP TEMPORARY TABLE IF EXISTS tmp.`user`'); stmts.push(stmt); - stmt = new ParameterizedSQL('CREATE TEMPORARY TABLE tmp.`user` SELECT id userFk FROM account.user WHERE id = vUserFk', [args.workerId]); + stmt = new ParameterizedSQL('CREATE TEMPORARY TABLE tmp.`user` SELECT id userFk FROM account.user WHERE id = ?', [args.workerId]); stmts.push(stmt); } else { await models.WorkerTimeControl.destroyAll({ @@ -112,15 +112,26 @@ module.exports = Self => { stmts.push(stmt); stmt = new ParameterizedSQL( - `CALL vn.timeControl_getError(?, ?) + `CALL vn.timeBusiness_calculate(?, ?) `, [started, ended]); stmts.push(stmt); stmt = new ParameterizedSQL( - `CALL vn.timeBusiness_calculate(?, ?) + `CALL vn.timeControl_getError(?, ?) `, [started, ended]); stmts.push(stmt); + stmt = new ParameterizedSQL(`INSERT INTO mail (receiver, subject, body) + SELECT CONCAT(u.name, '@verdnatura.es'), + CONCAT('Error registro de horas semana ', ?, ' año ', ?) , + CONCAT('No se ha podido enviar el registro de horas al empleado/s: ', GROUP_CONCAT(DISTINCT CONCAT('
', w.id, ' ', w.firstName, ' ', w.lastName))) + FROM tmp.timeControlError tce + JOIN vn.workerTimeControl wtc ON wtc.id = tce.id + JOIN worker w ON w.id = wtc.userFK + JOIN account.user u ON u.id = w.bossFk + GROUP BY w.bossFk`, [args.week, args.year]); + stmts.push(stmt); + stmt = new ParameterizedSQL(` SELECT CONCAT(u.name, '@verdnatura.es') receiver, u.id workerFk, @@ -364,21 +375,6 @@ module.exports = Self => { } } - // await Self.rawSql('DROP TEMPORARY TABLE IF EXISTS tmp.`user`'); - await Self.rawSql('CREATE TEMPORARY TABLE IF NOT EXISTS tmp.`user` SELECT userFk FROM vn.worker w JOIN account.`user` u ON u.id = w.userFk WHERE userFk IS NOT NULL'); - - await Self.rawSql(`CALL vn.timeControl_getError(?, ?);`, [started, ended]); - const query = `INSERT INTO mail (receiver, replyTo, subject, body) - SELECT CONCAT(u.name, '@verdnatura.es'), - CONCAT('Error registro de horas semana ', vWeek, ' año ', vYear) , - CONCAT('No se ha podido enviar el registro de horas al empleado/s: ', GROUP_CONCAT(DISTINCT CONCAT('
', w.id, ' ', w.firstName, ' ', w.lastName))) - FROM tmp.timeControlError tce - JOIN vn.workerTimeControl wtc ON wtc.id = tce.id - JOIN worker w ON w.id = wtc.userFK - JOIN account.user u ON u.id = w.bossFk - GROUP BY w.bossFk;`; - await Self.rawSql(query, [previousWorkerFk, args.year, args.week]); - return true; }; From f307f79dc2fe478b1f64cf612c8b598fbb200356 Mon Sep 17 00:00:00 2001 From: carlossa Date: Thu, 6 Apr 2023 09:34:46 +0200 Subject: [PATCH 13/14] refs #5250 cambio a ult version de changes --- db/changes/{231201 => 231401}/00-workerNotes.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/changes/{231201 => 231401}/00-workerNotes.sql (100%) diff --git a/db/changes/231201/00-workerNotes.sql b/db/changes/231401/00-workerNotes.sql similarity index 100% rename from db/changes/231201/00-workerNotes.sql rename to db/changes/231401/00-workerNotes.sql From 8a297469d6dbd1a899ff398fb05bc1089025def3 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 6 Apr 2023 10:06:29 +0200 Subject: [PATCH 14/14] =?UTF-8?q?refs=20#4856=20a=C3=B1adido=20myOptions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../back/methods/worker-time-control/resendWeeklyHourEmail.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/worker/back/methods/worker-time-control/resendWeeklyHourEmail.js b/modules/worker/back/methods/worker-time-control/resendWeeklyHourEmail.js index 5fae6988c..2452a29f9 100644 --- a/modules/worker/back/methods/worker-time-control/resendWeeklyHourEmail.js +++ b/modules/worker/back/methods/worker-time-control/resendWeeklyHourEmail.js @@ -41,7 +41,7 @@ module.exports = Self => { }, myOptions); if (workerTimeControlMail && workerTimeControlMail.state != 'SENDED') { - const worker = await models.EmailUser.findById(workerId); + const worker = await models.EmailUser.findById(workerId, null, myOptions); ctx.args = { recipient: worker.email, year: yearNumber,