tududi/backend/modules/tasks/operations/parent-child.js

154 lines
4.2 KiB
JavaScript

const { Task } = require('../../../models');
const { Op } = require('sequelize');
const taskRepository = require('../repository');
const { logError } = require('../../../services/logService');
async function checkAndUpdateParentTaskCompletion(parentTaskId, userId) {
try {
const subtasks = await taskRepository.findChildren(
parentTaskId,
userId
);
const allSubtasksDone =
subtasks.length > 0 &&
subtasks.every(
(subtask) =>
subtask.status === Task.STATUS.DONE ||
subtask.status === 'done'
);
if (allSubtasksDone) {
const parentTask = await taskRepository.findByIdAndUser(
parentTaskId,
userId
);
if (
parentTask &&
parentTask.status !== Task.STATUS.DONE &&
parentTask.status !== 'done'
) {
await taskRepository.update(parentTaskId, userId, {
status: Task.STATUS.DONE,
completed_at: new Date(),
});
return true;
}
}
return false;
} catch (error) {
logError('Error checking parent task completion:', error);
return false;
}
}
async function undoneParentTaskIfNeeded(parentTaskId, userId) {
try {
const parentTask = await taskRepository.findByIdAndUser(
parentTaskId,
userId
);
if (
parentTask &&
(parentTask.status === Task.STATUS.DONE ||
parentTask.status === 'done')
) {
await taskRepository.update(parentTaskId, userId, {
status: Task.STATUS.NOT_STARTED,
completed_at: null,
});
return true;
}
return false;
} catch (error) {
logError('Error undoing parent task:', error);
return false;
}
}
async function completeAllSubtasks(parentTaskId, userId) {
try {
const result = await taskRepository.updateChildren(
parentTaskId,
userId,
{
status: Task.STATUS.DONE,
completed_at: new Date(),
}
);
return result[0] > 0;
} catch (error) {
logError('Error completing all subtasks:', error);
return false;
}
}
async function undoneAllSubtasks(parentTaskId, userId) {
try {
const result = await taskRepository.updateChildrenWithConditions(
parentTaskId,
userId,
{
status: Task.STATUS.NOT_STARTED,
completed_at: null,
},
{
status: {
[Op.in]: [Task.STATUS.DONE, 'done'],
},
}
);
return result[0] > 0;
} catch (error) {
logError('Error undoing all subtasks:', error);
return false;
}
}
async function handleParentChildOnStatusChange(
task,
oldStatus,
newStatus,
userId
) {
let parentChildLogicExecuted = false;
const directSubtasksQuery = await taskRepository.findChildren(
task.id,
userId,
{ attributes: ['id', 'name', 'status', 'parent_task_id'] }
);
if (
directSubtasksQuery.length > 0 &&
(!task.Subtasks || task.Subtasks.length === 0)
) {
task.Subtasks = directSubtasksQuery;
}
if (task.Subtasks && task.Subtasks.length > 0) {
if (newStatus === Task.STATUS.DONE) {
const subtasksUpdated = await completeAllSubtasks(task.id, userId);
if (subtasksUpdated) {
parentChildLogicExecuted = true;
}
} else if (oldStatus === Task.STATUS.DONE || oldStatus === 'done') {
const subtasksUpdated = await undoneAllSubtasks(task.id, userId);
if (subtasksUpdated) {
parentChildLogicExecuted = true;
}
}
}
return parentChildLogicExecuted;
}
module.exports = {
checkAndUpdateParentTaskCompletion,
undoneParentTaskIfNeeded,
completeAllSubtasks,
undoneAllSubtasks,
handleParentChildOnStatusChange,
};