diff --git a/website/common/script/cron.js b/website/common/script/cron.js index ba632b8c81..b3171976c7 100644 --- a/website/common/script/cron.js +++ b/website/common/script/cron.js @@ -122,7 +122,7 @@ export function shouldDo (day, dailyTask, options = {}) { let schedule = moment(startDate).recur() .every(dailyTask.everyX).days(); - if (options.nextDue) return schedule.next(3, 'L'); + if (options.nextDue) return schedule.fromDate(startOfDayWithCDSTime).next(3); return schedule.matches(startOfDayWithCDSTime); } else if (dailyTask.frequency === 'weekly') { @@ -134,7 +134,7 @@ export function shouldDo (day, dailyTask, options = {}) { schedule = schedule.every(daysOfTheWeek).daysOfWeek(); - if (options.nextDue) return schedule.next(3, 'L'); + if (options.nextDue) return schedule.fromDate(startOfDayWithCDSTime).next(3); return schedule.matches(startOfDayWithCDSTime); } else if (dailyTask.frequency === 'monthly') { @@ -150,7 +150,7 @@ export function shouldDo (day, dailyTask, options = {}) { schedule = schedule.every(dailyTask.daysOfMonth).daysOfMonth(); } - if (options.nextDue) return schedule.next(3, 'L'); + if (options.nextDue) return schedule.fromDate(startOfDayWithCDSTime).next(3); return schedule.matches(startOfDayWithCDSTime) && matchEveryX; } else if (dailyTask.frequency === 'yearly') { @@ -158,7 +158,7 @@ export function shouldDo (day, dailyTask, options = {}) { schedule = schedule.every(dailyTask.everyX).years(); - if (options.nextDue) return schedule.next(3, 'L'); + if (options.nextDue) return schedule.fromDate(startOfDayWithCDSTime).next(3); return schedule.matches(startOfDayWithCDSTime); } diff --git a/website/server/controllers/api-v3/tasks.js b/website/server/controllers/api-v3/tasks.js index f150f14b8d..c3d921b757 100644 --- a/website/server/controllers/api-v3/tasks.js +++ b/website/server/controllers/api-v3/tasks.js @@ -17,11 +17,11 @@ import { createTasks, getTasks, moveTask, + setNextDue, } from '../../libs/taskManager'; import common from '../../../common'; import Bluebird from 'bluebird'; import _ from 'lodash'; -import cloneDeep from 'lodash/cloneDeep'; import logger from '../../libs/logger'; const MAX_SCORE_NOTES_LENGTH = 256; @@ -457,15 +457,7 @@ api.updateTask = { task.group.approval.required = true; } - if (sanitizedObj.type === 'daily') { - let optionsForShouldDo = cloneDeep(user.preferences.toObject()); - task.isDue = common.shouldDo(Date.now(), sanitizedObj, optionsForShouldDo); - optionsForShouldDo.nextDue = true; - let nextDue = common.shouldDo(Date.now(), sanitizedObj, optionsForShouldDo); - if (nextDue && nextDue.length > 0) { - task.nextDue = nextDue; - } - } + setNextDue(task, user); let savedTask = await task.save(); @@ -596,15 +588,7 @@ api.scoreTask = { } } - if (task.type === 'daily') { - let optionsForShouldDo = cloneDeep(user.preferences.toObject()); - task.isDue = common.shouldDo(Date.now(), task, optionsForShouldDo); - optionsForShouldDo.nextDue = true; - let nextDue = common.shouldDo(Date.now(), task, optionsForShouldDo); - if (nextDue && nextDue.length > 0) { - task.nextDue = nextDue; - } - } + setNextDue(task, user); let results = await Bluebird.all([ user.save(), diff --git a/website/server/libs/taskManager.js b/website/server/libs/taskManager.js index 8676b001b9..47d2811f58 100644 --- a/website/server/libs/taskManager.js +++ b/website/server/libs/taskManager.js @@ -23,6 +23,19 @@ async function _validateTaskAlias (tasks, res) { }); } +export function setNextDue (task, user) { + if (task.type !== 'daily') return; + + let optionsForShouldDo = cloneDeep(user.preferences.toObject()); + task.isDue = shared.shouldDo(Date.now(), task, optionsForShouldDo); + optionsForShouldDo.nextDue = true; + let nextDue = shared.shouldDo(Date.now(), task, optionsForShouldDo); + if (nextDue && nextDue.length > 0) { + task.nextDue = nextDue.map((dueDate) => { + return dueDate.toISOString(); + }); + } +} /** * Creates tasks for a user, challenge or group. @@ -65,15 +78,7 @@ export async function createTasks (req, res, options = {}) { newTask.userId = user._id; } - if (newTask.type === 'daily') { - let optionsForShouldDo = cloneDeep(user.preferences.toObject()); - newTask.isDue = shared.shouldDo(Date.now(), newTask, optionsForShouldDo); - optionsForShouldDo.nextDue = true; - let nextDue = shared.shouldDo(Date.now(), newTask, optionsForShouldDo); - if (nextDue && nextDue.length > 0) { - newTask.nextDue = nextDue; - } - } + setNextDue(newTask, user); // Validate that the task is valid and throw if it isn't // otherwise since we're saving user/challenge/group and task in parallel it could save the user/challenge/group with a tasksOrder that doens't match reality diff --git a/website/server/models/task.js b/website/server/models/task.js index c032293dc2..ee09612d46 100644 --- a/website/server/models/task.js +++ b/website/server/models/task.js @@ -92,7 +92,7 @@ export let TaskSchema = new Schema({ }, discriminatorOptions)); TaskSchema.plugin(baseModel, { - noSet: ['challenge', 'userId', 'completed', 'history', 'dateCompleted', '_legacyId', 'group', 'isDue'], + noSet: ['challenge', 'userId', 'completed', 'history', 'dateCompleted', '_legacyId', 'group', 'isDue', 'nextDue'], sanitizeTransform (taskObj) { if (taskObj.type && taskObj.type !== 'reward') { // value should be settable directly only for rewards delete taskObj.value;