diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js b/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js index fd6f64e..8a15406 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js +++ b/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js @@ -46,8 +46,9 @@ const doClockOut = async (context) => { if (userId) { SlackClient.sendMessageToUser(userId, CLOCK_OUT_MESSAGE_MIDNIGHT.replace('%user_name%', userName)); } - timeEntryAsJson.end_date = timeEntry.getTimeToClockOut(); + timeEntryAsJson.end_date = timeEntry.getTimeToClockOutMidnight(); await container.item(timeEntryAsJson.id, timeEntryAsJson.tenant_id).replace(timeEntryAsJson); + totalClockOutsExecuted++; } }) ); @@ -62,8 +63,8 @@ const findUserData = (users, id) => { return user ? { userName: user.displayName.split(" ")[0], userEmail: _.first(user.otherMails) } : {}; }; -const findSlackUserId = (users, email) => { - const user = users.find((user) => user.email === email); +const findSlackUserId = (slackUsers, email) => { + const user = slackUsers.find((slackUser) => slackUser.email === email); return user ? user.id : null; }; diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/constants.js b/nodejs-functions/src/handlers/automatic-clock-outs/constants.js index 1a104c1..0d0b60c 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/constants.js +++ b/nodejs-functions/src/handlers/automatic-clock-outs/constants.js @@ -1,6 +1,6 @@ const constants = { - CLOCK_OUT_MESSAGE : 'OMG %user_name%!, you have been working more than 12 hours in a row. \nPlease take a break and visit https://timetracker.ioet.com/ to set the right end time for your entries, we just did a clock out for you :wink:', - CLOCK_OUT_MESSAGE_MIDNIGHT : 'Hey %user_name%, the day has finished. Are you still working? :cara_con_monĂ³culo: \nBTW, we just did a clock-out for you; If you want to continue working, please do a new clock-in the Time Tracker app https://timetracker.ioet.com/' + CLOCK_OUT_MESSAGE : 'OMG %user_name%!, you have been working more than 12 hours in a row. \nPlease take a break and visit :ioet: to set the right end time for your entries, we just did a clock out for you :wink:', + CLOCK_OUT_MESSAGE_MIDNIGHT : 'Hey %user_name%, the day has finished. Are you still working? :face_with_monocle: \nBTW, we just did a clock-out for you. If you want to continue working, please use :ioet: to clock back in.' }; module.exports = constants; diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/package-lock.json b/nodejs-functions/src/handlers/automatic-clock-outs/package-lock.json index 2241937..c57e496 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/package-lock.json +++ b/nodejs-functions/src/handlers/automatic-clock-outs/package-lock.json @@ -12,8 +12,8 @@ "@azure/cosmos": "3.5.2", "@azure/msal-node": "^1.0.0-alpha.5", "@slack/web-api": "^6.0.0", - "axios": "^0.20.0", - "dotenv": "^8.2.0", + "axios": "^0.21.2", + "dotenv": "^16.0.0", "moment": "^2.27.0", "msal": "^1.4.0" }, @@ -288,14 +288,6 @@ "npm": ">= 6.12.0" } }, - "node_modules/@slack/web-api/node_modules/axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", - "dependencies": { - "follow-redirects": "^1.10.0" - } - }, "node_modules/@szmarczak/http-timer": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", @@ -619,12 +611,11 @@ } }, "node_modules/axios": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz", - "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==", - "deprecated": "Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410", + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.2.tgz", + "integrity": "sha512-87otirqUw3e8CzHTMO+/9kh/FSgXt/eVDvipijwDtEuwbkySWZ9SBm6VEubmJ/kLKEoLQV/POhxXFb66bfekfg==", "dependencies": { - "follow-redirects": "^1.10.0" + "follow-redirects": "^1.14.0" } }, "node_modules/balanced-match": { @@ -1240,11 +1231,11 @@ } }, "node_modules/dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.0.tgz", + "integrity": "sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==", "engines": { - "node": ">=8" + "node": ">=12" } }, "node_modules/duplexer3": { @@ -1445,9 +1436,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", - "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==", + "version": "1.14.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", + "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==", "funding": [ { "type": "individual", @@ -1456,6 +1447,11 @@ ], "engines": { "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, "node_modules/form-data": { @@ -3907,16 +3903,6 @@ "is-stream": "^1.1.0", "p-queue": "^6.6.1", "p-retry": "^4.0.0" - }, - "dependencies": { - "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", - "requires": { - "follow-redirects": "^1.10.0" - } - } } }, "@szmarczak/http-timer": { @@ -4184,11 +4170,11 @@ } }, "axios": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz", - "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==", + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.2.tgz", + "integrity": "sha512-87otirqUw3e8CzHTMO+/9kh/FSgXt/eVDvipijwDtEuwbkySWZ9SBm6VEubmJ/kLKEoLQV/POhxXFb66bfekfg==", "requires": { - "follow-redirects": "^1.10.0" + "follow-redirects": "^1.14.0" } }, "balanced-match": { @@ -4674,9 +4660,9 @@ } }, "dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.0.tgz", + "integrity": "sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==" }, "duplexer3": { "version": "0.1.4", @@ -4833,9 +4819,9 @@ } }, "follow-redirects": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", - "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==" + "version": "1.14.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", + "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==" }, "form-data": { "version": "2.5.1", diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/package.json b/nodejs-functions/src/handlers/automatic-clock-outs/package.json index ceb28ad..550bfab 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/package.json +++ b/nodejs-functions/src/handlers/automatic-clock-outs/package.json @@ -9,10 +9,10 @@ "dependencies": { "@azure/cosmos": "3.5.2", "@azure/msal-node": "^1.0.0-alpha.5", - "axios": "^0.20.0", - "dotenv": "^8.2.0", - "moment": "^2.27.0", "@slack/web-api": "^6.0.0", + "axios": "^0.21.2", + "dotenv": "^16.0.0", + "moment": "^2.27.0", "msal": "^1.4.0" }, "author": "", diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/time_entry.js b/nodejs-functions/src/handlers/automatic-clock-outs/time_entry.js index eade4bb..d3f88ff 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/time_entry.js +++ b/nodejs-functions/src/handlers/automatic-clock-outs/time_entry.js @@ -15,24 +15,27 @@ class TimeEntry { } getMidnightInTimeEntryZone(){ - return moment(this.timeEntry.start_date).utc() - .subtract(this.timeEntry.timezone_offset, 'minutes').endOf('day') + return moment(this.timeEntry.start_date).utcOffset(this.timeEntry.timezone_offset * -1).endOf('day'); + } + + getTimeToClockOutMidnight(){ + return moment(this.timeEntry.start_date).utcOffset(this.timeEntry.timezone_offset * -1).endOf('day').toISOString(); } getCurrentTimeInTimeEntryZone(){ - return moment().utc().subtract(this.timeEntry.timezone_offset, 'minutes') + return moment().utc().subtract(this.timeEntry.timezone_offset, 'minutes'); } needsToBeClockedOut() { - const currentTimeInUTC = moment().utc() - const minutesRunning = moment.duration(currentTimeInUTC.diff(this.getStartTimeInUTC())).asMinutes() + const currentTimeInUTC = moment().utc(); + const minutesRunning = moment.duration(currentTimeInUTC.diff(this.getStartTimeInUTC())).asMinutes(); return minutesRunning > 720; } needsToBeClockedOutMidnight(){ - return this.getMidnightInTimeEntryZone().isBefore(this.getCurrentTimeInTimeEntryZone()) + return this.getMidnightInTimeEntryZone().isBefore(this.getCurrentTimeInTimeEntryZone()); } } -module.exports = TimeEntry +module.exports = TimeEntry;