From b24b825f9603992e0743a2c753ffca8d9d477025 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 25 Aug 2023 13:42:50 +0800 Subject: [PATCH] * Change the function order. --- module/task/tao.php | 808 ++++++++++++++++++++++---------------------- 1 file changed, 404 insertions(+), 404 deletions(-) diff --git a/module/task/tao.php b/module/task/tao.php index cbc93b1630..78713ad0c7 100644 --- a/module/task/tao.php +++ b/module/task/tao.php @@ -33,59 +33,6 @@ class taskTao extends taskModel return $tasks; } - /** - * 将任务的层级改为父子结构。 - * Change the hierarchy of tasks to a parent-child structure. - * - * @param object[] $tasks - * @param object[] $parentTasks - * @access protected - * @return object[] - */ - protected function buildTaskTree(array $tasks, array $parentTasks): array - { - foreach($tasks as $task) - { - /* 如果不是父任务则跳过。*/ - if($task->parent <= 0) continue; - - if(isset($tasks[$task->parent])) - { - /* 如果任务列表里有这个任务的父任务,则将子任务放到父任务里,并删除子任务。*/ - if(!isset($tasks[$task->parent]->children)) $tasks[$task->parent]->children = array(); - $tasks[$task->parent]->children[$task->id] = $task; - unset($tasks[$task->id]); - } - else - { - /* 如果任务列表里没有这个任务的父任务,则从父任务列表获取到父任务名称并附加到子任务上。*/ - $parent = $parentTasks[$task->parent]; - $task->parentName = $parent->name; - } - } - return $tasks; - } - - /** - * 构造日志数据,加上任务ID、记录人字段。 - * Add fields to workhour. - * - * @param int $taskID - * @param array $workhour - * @access protected - * @return array - */ - protected function buildWorkhour(int $taskID, array $workhour): array - { - foreach($workhour as $record) - { - $record->task = $taskID; - $record->account = $this->app->user->account; - } - - return $workhour; - } - /** * 根据填写的日志,记录历史记录、改变任务的状态、消耗工时等信息并返回。 * According to the effort, record the history, change the status of the task, consumed hours and other information and return. @@ -187,6 +134,107 @@ class taskTao extends taskModel return $data; } + /** + * 将任务的层级改为父子结构。 + * Change the hierarchy of tasks to a parent-child structure. + * + * @param object[] $tasks + * @param object[] $parentTasks + * @access protected + * @return object[] + */ + protected function buildTaskTree(array $tasks, array $parentTasks): array + { + foreach($tasks as $task) + { + /* 如果不是父任务则跳过。*/ + if($task->parent <= 0) continue; + + if(isset($tasks[$task->parent])) + { + /* 如果任务列表里有这个任务的父任务,则将子任务放到父任务里,并删除子任务。*/ + if(!isset($tasks[$task->parent]->children)) $tasks[$task->parent]->children = array(); + $tasks[$task->parent]->children[$task->id] = $task; + unset($tasks[$task->id]); + } + else + { + /* 如果任务列表里没有这个任务的父任务,则从父任务列表获取到父任务名称并附加到子任务上。*/ + $parent = $parentTasks[$task->parent]; + $task->parentName = $parent->name; + } + } + return $tasks; + } + + /** + * 构造日志数据,加上任务ID、记录人字段。 + * Add fields to workhour. + * + * @param int $taskID + * @param array $workhour + * @access protected + * @return array + */ + protected function buildWorkhour(int $taskID, array $workhour): array + { + foreach($workhour as $record) + { + $record->task = $taskID; + $record->account = $this->app->user->account; + } + + return $workhour; + } + + /** + * 取消父任务更新子任务。 + * Update a child task when cancel its parent task. + * + * @param object $task + * @access protected + * @return void + */ + protected function cancelParentTask(object $task): void + { + $taskID = $task->id; + unset($task->assignedTo); + unset($task->id); + + $oldChildrenTasks = $this->dao->select('*')->from(TABLE_TASK)->where('parent')->eq($taskID)->fetchAll('id'); + $this->dao->update(TABLE_TASK)->data($task)->autoCheck()->where('parent')->eq((int)$taskID)->exec(); + $this->dao->update(TABLE_TASK)->set('assignedTo=openedBy')->where('parent')->eq((int)$taskID)->exec(); + + if(!dao::isError() && count($oldChildrenTasks) > 0) + { + $this->loadModel('action'); + foreach($oldChildrenTasks as $oldChildrenTask) + { + $actionID = $this->action->create('task', $oldChildrenTask->id, 'Canceled', $this->post->comment); + $this->action->logHistory($actionID, common::createChanges($oldChildrenTask, $task)); + } + } + } + + /** + * 编辑日志时,检查输入是否合法。 + * When editing a effort, check that the input is legal. + * + * @param object $effort + * @access protected + * @return bool + */ + protected function checkEffort(object $effort): bool + { + $today = helper::today(); + if(helper::isZeroDate($effort->date)) dao::$errors[] = $this->lang->task->error->dateEmpty; + if($effort->date > $today) dao::$errors[] = $this->lang->task->error->date; + if($effort->consumed <= 0) dao::$errors[] = sprintf($this->lang->error->gt, $this->lang->task->record, '0'); + if($effort->left < 0) dao::$errors[] = sprintf($this->lang->error->ge, $this->lang->task->left, '0'); + + return !dao::isError(); + } + /** * 检查一个任务是否有子任务。 * Check if a task has children. @@ -257,146 +305,6 @@ class taskTao extends taskModel return true; } - /** - * Get left workhour of task after deleting a workhour of task. - * - * @param object $effort - * @param object $task - * @return float - */ - protected function getLeftAfterDeleteWorkhour(object $effort, object $task): float - { - $left = $task->left; - if($effort->isLast) - { - $lastTwoEfforts = $this->dao->select('*')->from(TABLE_EFFORT) - ->where('objectID')->eq($effort->objectID) - ->andWhere('objectType')->eq('task') - ->andWhere('deleted')->eq('0') - ->orderBy('date desc,id desc')->limit(2)->fetchAll(); - $lastTwoEfforts = isset($lastTwoEfforts[1]) ? $lastTwoEfforts[1] : ''; - if($lastTwoEfforts) $left = $lastTwoEfforts->left; - if(empty($lastTwoEfforts) && $left == 0) $left = $task->estimate; - } - - /* 如果该任务是多人团队任务则做一些额外的处理。*/ - if(empty($task->team)) return $left; - - /* 获取要删除的工时的团队,如果要删除的工时的用户不是团队成员则不做任何处理。*/ - $currentTeam = $this->getTeamByAccount($task->team, $effort->account, array('effortID' => $effort->id, 'order' => $effort->order)); - if(!$currentTeam) return $left; - - $left = $currentTeam->left; - if($task->mode == 'multi') /* 如果任务是多人并行任务。注:多人串行任务的mode是linear。*/ - { - /* 获取要删除的工时对应的用户的工时信息列表。*/ - $accountEfforts = $this->getTaskEfforts($currentTeam->task, $effort->account, $effort->id); - $lastEffort = array_pop($accountEfforts); - if($lastEffort->id == $effort->id) - { - $lastTwoEfforts = array_pop($accountEfforts); - if($lastTwoEfforts) $left = $lastTwoEfforts->left; - } - } - - /* 更新要删除的工时对应的用户的任务信息。*/ - $newTeamInfo = new stdclass(); - $newTeamInfo->consumed = $currentTeam->consumed - $effort->consumed; - if($currentTeam->status != 'done') $newTeamInfo->left = $left; - if($currentTeam->status == 'done' && $left > 0 && $task->mode == 'multi') - { - $newTeamInfo->status = 'doing'; - $newTeamInfo->left = $left; - } - - if($currentTeam->status != 'done' && $newTeamInfo->consumed > 0 && $left == 0) $newTeamInfo->status = 'done'; - if($task->mode == 'multi' && $currentTeam->status == 'done' && ($newTeamInfo->consumed == 0 && $left == 0)) - { - $newTeamInfo->status = 'doing'; - $newTeamInfo->left = $currentTeam->estimate; - } - $this->dao->update(TABLE_TASKTEAM)->data($newTeamInfo)->where('id')->eq($currentTeam->id)->exec(); - return $left; - } - - /** - * Get a new task after deleting a workhour of task. - * - * @param object $effort - * @param object $task - * @return object - */ - protected function getTaskAfterDeleteWorkhour(object $effort, object $task) - { - /* Compute the left and consumed workhour of the task. */ - $consumed = $task->consumed - $effort->consumed; - $left = $this->getLeftAfterDeleteWorkhour($effort, $task); - - /* Define and prepare one new task object to update the task. */ - $data = new stdclass(); - $data->consumed = $consumed; - $data->left = $left; - $data->status = ($left == 0 && $consumed != 0) ? 'done' : $task->status; - if($effort->isLast && $consumed == 0 && $task->status != 'wait') - { - $data->status = 'wait'; - $data->left = $task->estimate; - $data->finishedBy = ''; - $data->canceledBy = ''; - $data->closedBy = ''; - $data->closedReason = ''; - $data->finishedDate = null; - $data->canceledDate = null; - $data->closedDate = null; - if($task->assignedTo == 'closed') $data->assignedTo = $this->app->user->account; - } - elseif($effort->isLast && $left != 0 && strpos('done,pause,cancel,closed', $task->status) !== false) - { - $data->status = 'doing'; - $data->finishedBy = ''; - $data->canceledBy = ''; - $data->closedBy = ''; - $data->closedReason = ''; - $data->finishedDate = null; - $data->canceledDate = null; - $data->closedDate = null; - } - elseif($consumed != 0 && $left == 0 && strpos('done,pause,cancel,closed', $task->status) === false) - { - $now = helper::now(); - $data->status = 'done'; - $data->assignedTo = $task->openedBy; - $data->assignedDate = $now; - $data->finishedBy = $this->app->user->account; - $data->finishedDate = $now; - } - else - { - $data->status = $task->status; - } - - return $data; - } - - /** - * 编辑日志时,检查输入是否合法。 - * When editing a effort, check that the input is legal. - * - * @param object $effort - * @access protected - * @return bool - */ - protected function checkEffort(object $effort): bool - { - $today = helper::today(); - if(helper::isZeroDate($effort->date)) dao::$errors[] = $this->lang->task->error->dateEmpty; - if($effort->date > $today) dao::$errors[] = $this->lang->task->error->date; - if($effort->consumed <= 0) dao::$errors[] = sprintf($this->lang->error->gt, $this->lang->task->record, '0'); - if($effort->left < 0) dao::$errors[] = sprintf($this->lang->error->ge, $this->lang->task->left, '0'); - - return !dao::isError(); - } - /** * 获取任务的进度,通过任务的消耗和剩余工时计算,结果以百分比的数字部分显示。 * Compute progress of a task. @@ -517,35 +425,6 @@ class taskTao extends taskModel return $teamInfo; } - /** - * 取消父任务更新子任务。 - * Update a child task when cancel its parent task. - * - * @param object $task - * @access protected - * @return void - */ - protected function cancelParentTask(object $task): void - { - $taskID = $task->id; - unset($task->assignedTo); - unset($task->id); - - $oldChildrenTasks = $this->dao->select('*')->from(TABLE_TASK)->where('parent')->eq($taskID)->fetchAll('id'); - $this->dao->update(TABLE_TASK)->data($task)->autoCheck()->where('parent')->eq((int)$taskID)->exec(); - $this->dao->update(TABLE_TASK)->set('assignedTo=openedBy')->where('parent')->eq((int)$taskID)->exec(); - - if(!dao::isError() && count($oldChildrenTasks) > 0) - { - $this->loadModel('action'); - foreach($oldChildrenTasks as $oldChildrenTask) - { - $actionID = $this->action->create('task', $oldChildrenTask->id, 'Canceled', $this->post->comment); - $this->action->logHistory($actionID, common::createChanges($oldChildrenTask, $task)); - } - } - } - /** * 复制任务数据。 * Copy the task data and update the effort to the new task. @@ -602,6 +481,42 @@ class taskTao extends taskModel return array($oldTask, $task); } + /** + * 更新父任务状态时记录修改日志。 + * Create action record when update parent task. + * + * @param object $oldParentTask + * @access protected + * @return void + */ + protected function createUpdateParentTaskAction(object $oldParentTask) :void + { + $newParentTask = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq($oldParentTask->id)->fetch(); + + unset($oldParentTask->subStatus); + unset($newParentTask->subStatus); + + $status = $newParentTask->status; + $changes = common::createChanges($oldParentTask, $newParentTask); + $action = ''; + + if($status == 'done' && $oldParentTask->status != 'done') $action = 'Finished'; + if($status == 'closed' && $oldParentTask->status != 'closed') $action = 'Closed'; + if($status == 'pause' && $oldParentTask->status != 'paused') $action = 'Paused'; + if($status == 'cancel' && $oldParentTask->status != 'cancel') $action = 'Canceled'; + if($status == 'doing' && $oldParentTask->status == 'wait') $action = 'Started'; + if($status == 'doing' && $oldParentTask->status == 'pause') $action = 'Restarted'; + + if($status == 'doing' && $oldParentTask->status != 'wait' && $oldParentTask->status != 'pause') $action = 'Activated'; + + if($status == 'wait' && $oldParentTask->status != 'wait') $action = 'Adjusttasktowait'; + + if(!$action) return; + + $actionID = $this->loadModel('action')->create('task', $oldParentTask->id, $action, '', '', '', false); + $this->action->logHistory($actionID, $changes); + } + /** * 更新一个任务。 * Update a task. @@ -673,23 +588,6 @@ class taskTao extends taskModel return (string)$value; } - /** - * Format the task with valid datetime that set the zero date or datetime to null. - * - * @param object $task - * @return object - */ - protected function formatDatetime(object $task): object - { - if(empty($task)) return $task; - foreach($task as $key => $value) - { - if(!in_array($key, array('deadline', 'openedDate', 'assignedDate', 'estStarted', 'realStarted', 'finishedDate', 'canceledDate', 'closedDate', 'lastEditedDate', 'activatedDate'))) continue; - if(!empty($value) && is_string($value) && helper::isZeroDate($value)) $task->$key = null; - } - return $task; - } - /** * 获取执行下的任务。 * Fetch tasks under execution by executionID(Todo). @@ -796,6 +694,23 @@ class taskTao extends taskModel ->fetchAll('id'); } + /** + * Format the task with valid datetime that set the zero date or datetime to null. + * + * @param object $task + * @return object + */ + protected function formatDatetime(object $task): object + { + if(empty($task)) return $task; + foreach($task as $key => $value) + { + if(!in_array($key, array('deadline', 'openedDate', 'assignedDate', 'estStarted', 'realStarted', 'finishedDate', 'canceledDate', 'closedDate', 'lastEditedDate', 'activatedDate'))) continue; + if(!empty($value) && is_string($value) && helper::isZeroDate($value)) $task->$key = null; + } + return $task; + } + /** * 获取多人任务的完成者。 * Get the users who finished the multiple task. @@ -814,6 +729,68 @@ class taskTao extends taskModel ->fetchPairs('id', 'account'); } + /** + * Get left workhour of task after deleting a workhour of task. + * + * @param object $effort + * @param object $task + * @return float + */ + protected function getLeftAfterDeleteWorkhour(object $effort, object $task): float + { + $left = $task->left; + if($effort->isLast) + { + $lastTwoEfforts = $this->dao->select('*')->from(TABLE_EFFORT) + ->where('objectID')->eq($effort->objectID) + ->andWhere('objectType')->eq('task') + ->andWhere('deleted')->eq('0') + ->orderBy('date desc,id desc')->limit(2)->fetchAll(); + $lastTwoEfforts = isset($lastTwoEfforts[1]) ? $lastTwoEfforts[1] : ''; + if($lastTwoEfforts) $left = $lastTwoEfforts->left; + if(empty($lastTwoEfforts) && $left == 0) $left = $task->estimate; + } + + /* 如果该任务是多人团队任务则做一些额外的处理。*/ + if(empty($task->team)) return $left; + + /* 获取要删除的工时的团队,如果要删除的工时的用户不是团队成员则不做任何处理。*/ + $currentTeam = $this->getTeamByAccount($task->team, $effort->account, array('effortID' => $effort->id, 'order' => $effort->order)); + if(!$currentTeam) return $left; + + $left = $currentTeam->left; + if($task->mode == 'multi') /* 如果任务是多人并行任务。注:多人串行任务的mode是linear。*/ + { + /* 获取要删除的工时对应的用户的工时信息列表。*/ + $accountEfforts = $this->getTaskEfforts($currentTeam->task, $effort->account, $effort->id); + $lastEffort = array_pop($accountEfforts); + if($lastEffort->id == $effort->id) + { + $lastTwoEfforts = array_pop($accountEfforts); + if($lastTwoEfforts) $left = $lastTwoEfforts->left; + } + } + + /* 更新要删除的工时对应的用户的任务信息。*/ + $newTeamInfo = new stdclass(); + $newTeamInfo->consumed = $currentTeam->consumed - $effort->consumed; + if($currentTeam->status != 'done') $newTeamInfo->left = $left; + if($currentTeam->status == 'done' && $left > 0 && $task->mode == 'multi') + { + $newTeamInfo->status = 'doing'; + $newTeamInfo->left = $left; + } + + if($currentTeam->status != 'done' && $newTeamInfo->consumed > 0 && $left == 0) $newTeamInfo->status = 'done'; + if($task->mode == 'multi' && $currentTeam->status == 'done' && ($newTeamInfo->consumed == 0 && $left == 0)) + { + $newTeamInfo->status = 'doing'; + $newTeamInfo->left = $currentTeam->estimate; + } + $this->dao->update(TABLE_TASKTEAM)->data($newTeamInfo)->where('id')->eq($currentTeam->id)->exec(); + return $left; + } + /** * 根据报表条件查询任务. * Get task list by report. @@ -830,6 +807,66 @@ class taskTao extends taskModel ->fetchAll('id'); } + /** + * 查询当前任务作为父任务时的状态。 + * Get the status of the taskID as a parent task. + * + * @param int $taskID + * @access protected + * @return string + */ + protected function getParentStatusById(int $taskID) :string + { + $children = $this->dao->select('id,status,closedReason,parent')->from(TABLE_TASK)->where('parent')->eq($taskID)->andWhere('deleted')->eq('0')->fetchAll(); + + if(empty($children)) return ''; + + $childrenStatus = $childrenClosedReason = array(); + + foreach($children as $task) + { + $childrenStatus[$task->status] = $task->status; + $childrenClosedReason[$task->closedReason] = $task->closedReason; + } + + if(count($childrenStatus) == 1) return current($childrenStatus); + + if(isset($childrenStatus['doing']) || isset($childrenStatus['pause'])) return 'doing'; + + if((isset($childrenStatus['done']) || isset($childrenClosedReason['done'])) && isset($childrenStatus['wait'])) return 'doing'; + + if(isset($childrenStatus['wait'])) return 'wait'; + if(isset($childrenStatus['done'])) return 'done'; + if(isset($childrenStatus['closed'])) return 'closed'; + if(isset($childrenStatus['cancel'])) return 'cancel'; + + return ''; + } + + /** + * 如果任务是从Bug转来的,并且已经完成了,则获取提醒bug的链接。 + * Get a link to locate the bug if the task was transferred from the bug and it has already been finished. + * + * @param object $task + * @param array $changes + * @access protected + * @return array + */ + protected function getRemindBugLink(object $task, array $changes): array + { + foreach($changes as $change) + { + if($change['field'] == 'status' && $change['new'] == 'done') + { + $confirmURL = helper::createLink('bug', 'view', "id={$task->fromBug}"); + $cancelURL = helper::createLink('task', 'view', "taskID={$task->id}"); + return array('result' => 'success', 'load' => array('confirm' => sprintf($this->lang->task->remindBug, $task->fromBug), 'confirmed' => $confirmURL, 'canceled' => $cancelURL)); + } + } + + return array(); + } + /** * 获取edit方法的必填项。 * Get required fields for edit method. @@ -861,40 +898,17 @@ class taskTao extends taskModel } /** - * 如果任务是从Bug转来的,并且已经完成了,则获取提醒bug的链接。 - * Get a link to locate the bug if the task was transferred from the bug and it has already been finished. + * 通过任务ID获取任务团队信息。 + * Get the task team information through the task ID. * - * @param object $task - * @param array $changes + * @param int $taskID + * @param string $orderBy * @access protected - * @return array + * @return object[] */ - protected function getRemindBugLink(object $task, array $changes): array + protected function getTeamByTask(int $taskID, string $orderBy = 'order_asc'): array { - foreach($changes as $change) - { - if($change['field'] == 'status' && $change['new'] == 'done') - { - $confirmURL = helper::createLink('bug', 'view', "id={$task->fromBug}"); - $cancelURL = helper::createLink('task', 'view', "taskID={$task->id}"); - return array('result' => 'success', 'load' => array('confirm' => sprintf($this->lang->task->remindBug, $task->fromBug), 'confirmed' => $confirmURL, 'canceled' => $cancelURL)); - } - } - - return array(); - } - - /** - * 通过任务ID列表查询任务团队信息。 - * Get task team by id list. - * - * @param array $taskIdList - * @access protected - * @return array[] - */ - protected function getTeamMembersByIdList(array $taskIdList): array - { - return $this->dao->select('*')->from(TABLE_TASKTEAM)->where('task')->in($taskIdList)->fetchGroup('task'); + return $this->dao->select('*')->from(TABLE_TASKTEAM)->where('task')->eq($taskID)->orderBy($orderBy)->fetchAll('id'); } /** @@ -929,20 +943,6 @@ class taskTao extends taskModel return $teamInfoList; } - /** - * 通过任务ID获取任务团队信息。 - * Get the task team information through the task ID. - * - * @param int $taskID - * @param string $orderBy - * @access protected - * @return object[] - */ - protected function getTeamByTask(int $taskID, string $orderBy = 'order_asc'): array - { - return $this->dao->select('*')->from(TABLE_TASKTEAM)->where('task')->eq($taskID)->orderBy($orderBy)->fetchAll('id'); - } - /** * 维护团队成员信息。 * Maintain team member information. @@ -972,6 +972,78 @@ class taskTao extends taskModel return !dao::isError(); } + /** + * 通过任务ID列表查询任务团队信息。 + * Get task team by id list. + * + * @param array $taskIdList + * @access protected + * @return array[] + */ + protected function getTeamMembersByIdList(array $taskIdList): array + { + return $this->dao->select('*')->from(TABLE_TASKTEAM)->where('task')->in($taskIdList)->fetchGroup('task'); + } + + /** + * Get a new task after deleting a workhour of task. + * + * @param object $effort + * @param object $task + * @return object + */ + protected function getTaskAfterDeleteWorkhour(object $effort, object $task) + { + /* Compute the left and consumed workhour of the task. */ + $consumed = $task->consumed - $effort->consumed; + $left = $this->getLeftAfterDeleteWorkhour($effort, $task); + + /* Define and prepare one new task object to update the task. */ + $data = new stdclass(); + $data->consumed = $consumed; + $data->left = $left; + $data->status = ($left == 0 && $consumed != 0) ? 'done' : $task->status; + if($effort->isLast && $consumed == 0 && $task->status != 'wait') + { + $data->status = 'wait'; + $data->left = $task->estimate; + $data->finishedBy = ''; + $data->canceledBy = ''; + $data->closedBy = ''; + $data->closedReason = ''; + $data->finishedDate = null; + $data->canceledDate = null; + $data->closedDate = null; + if($task->assignedTo == 'closed') $data->assignedTo = $this->app->user->account; + } + elseif($effort->isLast && $left != 0 && strpos('done,pause,cancel,closed', $task->status) !== false) + { + $data->status = 'doing'; + $data->finishedBy = ''; + $data->canceledBy = ''; + $data->closedBy = ''; + $data->closedReason = ''; + $data->finishedDate = null; + $data->canceledDate = null; + $data->closedDate = null; + } + elseif($consumed != 0 && $left == 0 && strpos('done,pause,cancel,closed', $task->status) === false) + { + $now = helper::now(); + $data->status = 'done'; + $data->assignedTo = $task->openedBy; + $data->assignedDate = $now; + $data->finishedBy = $this->app->user->account; + $data->finishedDate = $now; + } + else + { + $data->status = $task->status; + } + + return $data; + } + /** * 记录任务的版本。 * Record task version. @@ -1018,41 +1090,6 @@ class taskTao extends taskModel return !dao::isError(); } - /** - * 通过拖动甘特图修改任务的预计开始日期和截止日期。 - * Update task estimate date and deadline through gantt. - * - * @param object $postData - * @access protected - * @return bool - */ - protected function updateTaskEsDateByGantt(object $postData): bool - { - $task = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq($postData->id)->fetch(); - $isChildTask = $task->parent > 0; - - if($isChildTask) $parentTask = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq($task->parent)->fetch(); - $stage = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($task->execution)->andWhere('project')->eq($task->project)->fetch(); - - $start = $isChildTask ? $parentTask->estStarted : $stage->begin; - $end = $isChildTask ? $parentTask->deadline : $stage->end; - $typeLang = $isChildTask ? $this->lang->task->parent : $this->lang->project->stage; - - if(helper::diffDate($start, $postData->startDate) > 0) dao::$errors[] = sprintf($this->lang->task->overEsStartDate, $typeLang, $typeLang); - if(helper::diffDate($end, $postData->endDate) < 0) dao::$errors[] = sprintf($this->lang->task->overEsEndDate, $typeLang, $typeLang); - if(dao::isError()) return false; - - /* Update estimate started and deadline of a task. */ - $this->dao->update(TABLE_TASK) - ->set('estStarted')->eq($postData->startDate) - ->set('deadline')->eq($postData->endDate) - ->set('lastEditedBy')->eq($this->app->user->account) - ->where('id')->eq($postData->id) - ->exec(); - - return !dao::isError(); - } - /** * 通过父任务更新子任务。 * Update children task by parent task. @@ -1081,65 +1118,6 @@ class taskTao extends taskModel } } - /** - * 通过填写的日志更新多人任务的团队表,计算多人任务的工时。 - * Update team of multi-task by effort. - * - * @param int $effortID - * @param object $record - * @param object $currentTeam - * @param object $task - * @access protected - * @return void - */ - protected function updateTeamByEffort(int $effortID, object $record, object $currentTeam, object $task) - { - $this->dao->update(TABLE_TASKTEAM) - ->set('left')->eq($record->left) - ->set("consumed = consumed + {$record->consumed}") - ->set('status')->eq($currentTeam->status) - ->where('id')->eq($currentTeam->id) - ->exec(); - - if($task->mode == 'linear' && empty($record->order)) $this->updateEffortOrder($effortID, $currentTeam->order); - } - - /** - * 查询当前任务作为父任务时的状态。 - * Get the status of the taskID as a parent task. - * - * @param int $taskID - * @access protected - * @return string - */ - protected function getParentStatusById(int $taskID) :string - { - $children = $this->dao->select('id,status,closedReason,parent')->from(TABLE_TASK)->where('parent')->eq($taskID)->andWhere('deleted')->eq('0')->fetchAll(); - - if(empty($children)) return ''; - - $childrenStatus = $childrenClosedReason = array(); - - foreach($children as $task) - { - $childrenStatus[$task->status] = $task->status; - $childrenClosedReason[$task->closedReason] = $task->closedReason; - } - - if(count($childrenStatus) == 1) return current($childrenStatus); - - if(isset($childrenStatus['doing']) || isset($childrenStatus['pause'])) return 'doing'; - - if((isset($childrenStatus['done']) || isset($childrenClosedReason['done'])) && isset($childrenStatus['wait'])) return 'doing'; - - if(isset($childrenStatus['wait'])) return 'wait'; - if(isset($childrenStatus['done'])) return 'done'; - if(isset($childrenStatus['closed'])) return 'closed'; - if(isset($childrenStatus['cancel'])) return 'cancel'; - - return ''; - } - /** * 根据子任务以及父任务的状态更新父任务。 * Update parent task status by child and parent status. @@ -1206,38 +1184,60 @@ class taskTao extends taskModel } /** - * 更新父任务状态时记录修改日志。 - * Create action record when update parent task. + * 通过拖动甘特图修改任务的预计开始日期和截止日期。 + * Update task estimate date and deadline through gantt. * - * @param object $oldParentTask + * @param object $postData + * @access protected + * @return bool + */ + protected function updateTaskEsDateByGantt(object $postData): bool + { + $task = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq($postData->id)->fetch(); + $isChildTask = $task->parent > 0; + + if($isChildTask) $parentTask = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq($task->parent)->fetch(); + $stage = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($task->execution)->andWhere('project')->eq($task->project)->fetch(); + + $start = $isChildTask ? $parentTask->estStarted : $stage->begin; + $end = $isChildTask ? $parentTask->deadline : $stage->end; + $typeLang = $isChildTask ? $this->lang->task->parent : $this->lang->project->stage; + + if(helper::diffDate($start, $postData->startDate) > 0) dao::$errors[] = sprintf($this->lang->task->overEsStartDate, $typeLang, $typeLang); + if(helper::diffDate($end, $postData->endDate) < 0) dao::$errors[] = sprintf($this->lang->task->overEsEndDate, $typeLang, $typeLang); + if(dao::isError()) return false; + + /* Update estimate started and deadline of a task. */ + $this->dao->update(TABLE_TASK) + ->set('estStarted')->eq($postData->startDate) + ->set('deadline')->eq($postData->endDate) + ->set('lastEditedBy')->eq($this->app->user->account) + ->where('id')->eq($postData->id) + ->exec(); + + return !dao::isError(); + } + + /** + * 通过填写的日志更新多人任务的团队表,计算多人任务的工时。 + * Update team of multi-task by effort. + * + * @param int $effortID + * @param object $record + * @param object $currentTeam + * @param object $task * @access protected * @return void */ - protected function createUpdateParentTaskAction(object $oldParentTask) :void + protected function updateTeamByEffort(int $effortID, object $record, object $currentTeam, object $task) { - $newParentTask = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq($oldParentTask->id)->fetch(); + $this->dao->update(TABLE_TASKTEAM) + ->set('left')->eq($record->left) + ->set("consumed = consumed + {$record->consumed}") + ->set('status')->eq($currentTeam->status) + ->where('id')->eq($currentTeam->id) + ->exec(); - unset($oldParentTask->subStatus); - unset($newParentTask->subStatus); - - $status = $newParentTask->status; - $changes = common::createChanges($oldParentTask, $newParentTask); - $action = ''; - - if($status == 'done' && $oldParentTask->status != 'done') $action = 'Finished'; - if($status == 'closed' && $oldParentTask->status != 'closed') $action = 'Closed'; - if($status == 'pause' && $oldParentTask->status != 'paused') $action = 'Paused'; - if($status == 'cancel' && $oldParentTask->status != 'cancel') $action = 'Canceled'; - if($status == 'doing' && $oldParentTask->status == 'wait') $action = 'Started'; - if($status == 'doing' && $oldParentTask->status == 'pause') $action = 'Restarted'; - - if($status == 'doing' && $oldParentTask->status != 'wait' && $oldParentTask->status != 'pause') $action = 'Activated'; - - if($status == 'wait' && $oldParentTask->status != 'wait') $action = 'Adjusttasktowait'; - - if(!$action) return; - - $actionID = $this->loadModel('action')->create('task', $oldParentTask->id, $action, '', '', '', false); - $this->action->logHistory($actionID, $changes); + if($task->mode == 'linear' && empty($record->order)) $this->updateEffortOrder($effortID, $currentTeam->order); } }