diff --git a/website/client/src/components/tasks/task.vue b/website/client/src/components/tasks/task.vue
index 59426dcc1c..becdd85e9f 100644
--- a/website/client/src/components/tasks/task.vue
+++ b/website/client/src/components/tasks/task.vue
@@ -9,11 +9,6 @@
]"
@click="castEnd($event, task)"
>
-
{ i.completed = false; });
}
}
-
- if (task.group && task.group.approval && task.group.approval.approved) {
- task.group.approval.approved = false;
- task.group.approval.dateApproved = null;
- task.group.approval.requested = false;
- task.group.approval.requestedDate = null;
- }
});
resetHabitCounters(user, tasksByType, now, daysMissed);
@@ -464,12 +457,6 @@ export async function cron (options = {}) {
if (task.up === false || task.down === false) {
task.value = Math.abs(task.value) < 0.1 ? 0 : task.value /= 2;
}
- if (task.group && task.group.approval && task.group.approval.approved) {
- task.group.approval.approved = false;
- task.group.approval.dateApproved = null;
- task.group.approval.requested = false;
- task.group.approval.requestedDate = null;
- }
});
// Finished tallying
diff --git a/website/server/libs/groupTasks.js b/website/server/libs/groupTasks.js
index baad36e57d..f5604d3488 100644
--- a/website/server/libs/groupTasks.js
+++ b/website/server/libs/groupTasks.js
@@ -6,11 +6,6 @@ const SHARED_COMPLETION = {
every: 'allAssignedCompletion',
};
-async function _completeMasterTask (masterTask) {
- masterTask.completed = true;
- await masterTask.save();
-}
-
async function _deleteUnfinishedTasks (groupMemberTask) {
await Tasks.Task.deleteMany({
'group.taskId': groupMemberTask.group.taskId,
@@ -21,33 +16,11 @@ async function _deleteUnfinishedTasks (groupMemberTask) {
}).exec();
}
-async function _evaluateAllAssignedCompletion (masterTask) {
- let completions;
- if (masterTask.group.approval && masterTask.group.approval.required) {
- completions = await Tasks.Task.countDocuments({
- 'group.taskId': masterTask._id,
- 'group.approval.approved': true,
- }).exec();
- } else {
- completions = await Tasks.Task.countDocuments({
- 'group.taskId': masterTask._id,
- completed: true,
- }).exec();
- }
- if (completions >= masterTask.group.assignedUsers.length) {
- await _completeMasterTask(masterTask);
- }
-}
-
async function handleSharedCompletion (masterTask, groupMemberTask) {
- if (masterTask.type !== 'todo') return;
-
- if (masterTask.group.sharedCompletion === SHARED_COMPLETION.single) {
- await _deleteUnfinishedTasks(groupMemberTask);
- await _completeMasterTask(masterTask);
- } else if (masterTask.group.sharedCompletion === SHARED_COMPLETION.every) {
- await _evaluateAllAssignedCompletion(masterTask);
- }
+ if (masterTask.type === 'reward') return;
+ if (masterTask.type === 'todo') await _deleteUnfinishedTasks(groupMemberTask);
+ masterTask.completed = groupMemberTask.completed;
+ await masterTask.save();
}
export {
diff --git a/website/server/libs/tasks/index.js b/website/server/libs/tasks/index.js
index 2e33d1da9a..0c8b8f472a 100644
--- a/website/server/libs/tasks/index.js
+++ b/website/server/libs/tasks/index.js
@@ -8,7 +8,6 @@ import {
} from './utils';
import { model as Challenge } from '../../models/challenge';
import { model as Group } from '../../models/group';
-import { model as User } from '../../models/user';
import * as Tasks from '../../models/task';
import apiError from '../apiError';
import {
@@ -336,69 +335,18 @@ async function scoreTask (user, task, direction, req, res) {
}
}
- if (task.group.approval.required && !task.group.approval.approved) {
- const fields = requiredGroupFields.concat(' managers');
- const group = await Group.getGroup({ user, groupId: task.group.id, fields });
+ let localTask;
- const managerIds = Object.keys(group.managers);
- managerIds.push(group.leader);
-
- if (managerIds.indexOf(user._id) !== -1) {
- task.group.approval.approved = true;
- task.group.approval.requested = true;
- task.group.approval.requestedDate = new Date();
- } else {
- if (task.group.approval.requested) {
- return {
- task,
- requiresApproval: true,
- message: res.t('taskRequiresApproval'),
- };
- }
-
- task.group.approval.requested = true;
- task.group.approval.requestedDate = new Date();
-
- const managers = await User.find({ _id: managerIds }, 'notifications preferences').exec(); // Use this method so we can get access to notifications
-
- // @TODO: we can use the User.pushNotification function because
- // we need to ensure notifications are translated
- const managerPromises = [];
- managers.forEach(manager => {
- manager.addNotification('GROUP_TASK_APPROVAL', {
- message: res.t('userHasRequestedTaskApproval', {
- user: user.profile.name,
- taskName: task.text,
- }, manager.preferences.language),
- groupId: group._id,
- // user task id, used to match the notification when the task is approved
- taskId: task._id,
- userId: user._id,
- groupTaskId: task.group.taskId, // the original task id
- direction,
- });
- managerPromises.push(manager.save());
- });
-
- managerPromises.push(task.save());
- await Promise.all(managerPromises);
-
- return {
- task,
- requiresApproval: true,
- message: res.t('taskApprovalHasBeenRequested'),
- };
+ if (task.group.id && !task.userId && task.group.assignedUsers.length > 0) {
+ // Task is being scored from team board, and a user copy should exist
+ if (!task.group.assignedUsers.includes(user._id)) {
+ throw new BadRequest('Task has not been assigned to this user.');
}
- }
- if (task.group.approval.required && task.group.approval.approved) {
- const notificationIndex = user.notifications.findIndex(notification => notification
- && notification.data && notification.data.task
- && notification.data.task._id === task._id && notification.type === 'GROUP_TASK_APPROVED');
-
- if (notificationIndex !== -1) {
- user.notifications.splice(notificationIndex, 1);
- }
+ localTask = await Tasks.Task.findOne(
+ { userId: user._id, 'group.taskId': task._id },
+ ).exec();
+ if (!localTask) throw new NotFound('Task not found.');
}
const wasCompleted = task.completed;
@@ -411,26 +359,30 @@ async function scoreTask (user, task, direction, req, res) {
// If a todo was completed or uncompleted move it in or out of the user.tasksOrder.todos list
// TODO move to common code?
- let pullTask = false;
- let pushTask = false;
+ let pullTask;
+ let pushTask;
if (task.type === 'todo') {
if (!wasCompleted && task.completed) {
// @TODO: mongoose's push and pull should be atomic and help with
// our concurrency issues. If not, we need to use this update $pull and $push
- pullTask = true;
- // user.tasksOrder.todos.pull(task._id);
+ pullTask = localTask ? localTask._id : task._id;
} else if (
wasCompleted
&& !task.completed
&& user.tasksOrder.todos.indexOf(task._id) === -1
) {
- pushTask = true;
- // user.tasksOrder.todos.push(task._id);
+ pushTask = localTask ? localTask._id : task._id;
}
}
setNextDue(task, user);
+ if (localTask) {
+ localTask.completed = task.completed;
+ localTask.value = task.value + delta;
+ await localTask.save();
+ }
+
taskScoredWebhook.send(user, {
task,
direction,
@@ -514,8 +466,8 @@ export async function scoreTasks (user, taskScorings, req, res) {
const pushIDs = [];
returnDatas.forEach(returnData => {
- if (returnData.pushTask === true) pushIDs.push(returnData.task._id);
- if (returnData.pullTask === true) pullIDs.push(returnData.task._id);
+ if (returnData.pushTask) pushIDs.push(returnData.pushTask);
+ if (returnData.pullTask) pullIDs.push(returnData.pullTask);
});
const moveUpdateObject = {};
@@ -532,13 +484,6 @@ export async function scoreTasks (user, taskScorings, req, res) {
handleChallengeTask(data.task, data.delta, data.direction);
handleGroupTask(data.task, data.delta, data.direction);
- // Handle group tasks that require approval
- if (data.requiresApproval === true) {
- return {
- id: data.task._id, message: data.message, requiresApproval: true,
- };
- }
-
return { id: data.task._id, delta: data.delta, _tmp: data._tmp };
});
}