status !== 'done' and $task->status !== 'cancel' and $task->status != 'closed') { if(!empty($task->deadline) and !helper::isZeroDate($task->deadline)) { $delay = helper::diffDate($today, $task->deadline); if($delay > 0) $task->delay = $delay; } } /* Story changed or not. */ $task->needConfirm = false; if(!empty($task->storyStatus) and $task->storyStatus == 'active' and $task->latestStoryVersion > $task->storyVersion) $task->needConfirm = true; /* Set product type for task. */ if(isset($task->product) and $task->product) { $product = $this->loadModel('product')->getById($task->product); $task->productType = $product->type; } /* Set closed realname. */ if($task->assignedTo == 'closed') $task->assignedToRealName = 'Closed'; /* Compute task progress. */ if($task->consumed == 0 and $task->left == 0) { $task->progress = 0; } elseif($task->consumed != 0 and $task->left == 0) { $task->progress = 100; } else { $task->progress = round($task->consumed / ($task->consumed + $task->left), 2) * 100; } if($task->mode == 'multi') { $teamMembers = $this->dao->select('t1.realname')->from(TABLE_USER)->alias('t1') ->leftJoin(TABLE_TASKTEAM)->alias('t2') ->on('t1.account = t2.account') ->where('t2.task')->eq($task->id) ->fetchPairs(); $task->teamMembers= join(',', array_keys($teamMembers)); } return $task; } public function printCell($col, $task, $users, $browseType, $branchGroups, $modulePairs = array(), $mode = 'datatable', $child = false, $showBranch = false) { $canBatchEdit = common::hasPriv('task', 'batchEdit', !empty($task) ? $task : null); $canBatchClose = (common::hasPriv('task', 'batchClose', !empty($task) ? $task : null) && strtolower($browseType) != 'closedBy'); $canBatchCancel = common::hasPriv('task', 'batchCancel', !empty($task) ? $task : null); $canBatchChangeModule = common::hasPriv('task', 'batchChangeModule', !empty($task) ? $task : null); $canBatchAssignTo = common::hasPriv('task', 'batchAssignTo', !empty($task) ? $task : null); $canBatchAction = $canBatchEdit or $canBatchClose or $canBatchCancel or $canBatchChangeModule or $canBatchAssignTo; $storyChanged = (!empty($task->storyStatus) and $task->storyStatus == 'active' and $task->latestStoryVersion > $task->storyVersion and !in_array($task->status, array('cancel', 'closed'))); $designChange = ($task->designName && $task->latestDesignVersion > $task->designVersion); $canView = common::hasPriv('task', 'view'); $taskLink = helper::createLink('task', 'view', "taskID=$task->id"); $account = $this->app->user->account; $id = $col->id; if($col->show) { $class = "c-{$id}"; if($id == 'status') $class .= ' task-' . $task->status; if($id == 'id') $class .= ' cell-id'; if($id == 'name') $class .= ' text-left'; if($id == 'deadline' and isset($task->delay)) $class .= ' text-center delayed'; if($id == 'assignedTo') $class .= ' has-btn text-left'; if($id == 'lane') $class .= ' text-left'; if(strpos('progress', $id) !== false) $class .= ' text-right'; $title = ''; if($id == 'name') { $title = " title='{$task->name}'"; if(!empty($task->children)) $class .= ' has-child'; } if($id == 'story') $title = " title='{$task->storyTitle}'"; if($id == 'estimate' || $id == 'consumed' || $id == 'left') { $value = round($task->$id, 1); $title = " title='{$value} {$this->lang->execution->workHour}'"; } if($id == 'lane') $title = " title='{$task->lane}'"; echo ""; if($this->config->edition != 'open') $this->loadModel('flow')->printFlowCell('task', $task, $id); switch($id) { case 'id': if($canBatchAction) { echo html::checkbox('taskIDList', array($task->id => '')) . html::a(helper::createLink('task', 'view', "taskID=$task->id"), sprintf('%03d', $task->id)); } else { printf('%03d', $task->id); } break; case 'pri': echo ""; echo zget($this->lang->task->priList, $task->pri, $task->pri); echo ""; break; case 'name': if($showBranch) $showBranch = isset($this->config->execution->task->showBranch) ? $this->config->execution->task->showBranch : 1; if($task->parent > 0 and isset($task->parentName)) $task->name = "{$task->parentName} / {$task->name}"; if(!empty($task->product) and isset($branchGroups[$task->product][$task->branch]) and $showBranch) echo "" . $branchGroups[$task->product][$task->branch] . ' '; if($task->module and isset($modulePairs[$task->module])) echo "" . $modulePairs[$task->module] . ' '; if($task->parent > 0) echo '' . $this->lang->task->childrenAB . ' '; if(!empty($task->team)) echo '' . $this->lang->task->multipleAB . ' '; echo $canView ? html::a($taskLink, $task->name, null, "style='color: $task->color' title='$task->name'") : "$task->name"; if(!empty($task->children)) echo ''; if($task->fromBug) echo html::a(helper::createLink('bug', 'view', "id=$task->fromBug"), "[BUG#$task->fromBug]", '', "class='bug'"); break; case 'type': echo $this->lang->task->typeList[$task->type]; break; case 'status': if($storyChanged) { print("{$this->lang->story->changed}"); } elseif($designChange) { print("{$this->lang->task->designChanged}"); } else { $statusLabel = $this->processStatus('task', $task); print(" " . $statusLabel . ""); } break; case 'estimate': echo round($task->estimate, 1) . ' ' . $this->lang->execution->workHourUnit; break; case 'consumed': echo round($task->consumed, 1) . ' ' . $this->lang->execution->workHourUnit; break; case 'left': echo round($task->left, 1) . ' ' . $this->lang->execution->workHourUnit; break; case 'design': echo $task->designName ? html::a(helper::createLink('design', 'view', "id=$task->design"), $task->designName) : ''; break; case 'progress': echo "{$task->progress}%"; break; case 'deadline': if(substr($task->deadline, 0, 4) > 0) echo '' . substr($task->deadline, 5, 6). ''; break; case 'openedBy': echo zget($users, $task->openedBy); break; case 'openedDate': echo substr($task->openedDate, 5, 11); break; case 'estStarted': echo helper::isZeroDate($task->estStarted) ? '' : substr($task->estStarted, 5, 11); break; case 'realStarted': echo helper::isZeroDate($task->realStarted) ? '' : substr($task->realStarted, 5, 11); break; case 'assignedTo': $this->printAssignedHtml($task, $users); break; case 'lane': echo mb_substr($task->lane, 0, 8); break; case 'assignedDate': echo helper::isZeroDate($task->assignedDate) ? '' : substr($task->assignedDate, 5, 11); break; case 'finishedBy': echo zget($users, $task->finishedBy); break; case 'finishedDate': echo helper::isZeroDate($task->finishedDate) ? '' : substr($task->finishedDate, 5, 11); break; case 'canceledBy': echo zget($users, $task->canceledBy); break; case 'canceledDate': echo helper::isZeroDate($task->canceledDate) ? '' : substr($task->canceledDate, 5, 11); break; case 'closedBy': echo zget($users, $task->closedBy); break; case 'closedDate': echo helper::isZeroDate($task->closedDate) ? '' : substr($task->closedDate, 5, 11); break; case 'closedReason': echo $this->lang->task->reasonList[$task->closedReason]; break; case 'story': if(!empty($task->storyID)) { if(common::hasPriv('story', 'view')) { echo html::a(helper::createLink('story', 'view', "storyid=$task->storyID", 'html', true), "", '', "class='iframe' title='{$task->storyTitle}'"); } else { echo ""; } } break; case 'mailto': $mailto = explode(',', $task->mailto); foreach($mailto as $account) { $account = trim($account); if(empty($account)) continue; echo zget($users, $account) . '  '; } break; case 'lastEditedBy': echo zget($users, $task->lastEditedBy); break; case 'lastEditedDate': echo helper::isZeroDate($task->lastEditedDate) ? '' : substr($task->lastEditedDate, 5, 11); break; case 'actions': echo $this->buildOperateMenu($task, 'browse'); break; } echo ''; } } /** * Build task browse action menu. * * @param object $task * @access public * @return string */ public function buildOperateBrowseMenu($task) { $menu = ''; $params = "taskID=$task->id"; $storyChanged = !empty($task->storyStatus) && $task->storyStatus == 'active' && $task->latestStoryVersion > $task->storyVersion && !in_array($task->status, array('cancel', 'closed')); $designChange = isset($task->designName) ? $task->designName && $task->latestDesignVersion > $task->designVersion : false; if($storyChanged) return $this->buildMenu('task', 'confirmStoryChange', $params, $task, 'browse', '', 'hiddenwin'); if($designChange) return $this->buildMenu('task', 'confirmDesignChange', $params, $task, 'browse', 'search', 'hiddenwin'); $canStart = ($task->status != 'pause' and common::hasPriv('task', 'start')); $canRestart = ($task->status == 'pause' and common::hasPriv('task', 'restart')); $canFinish = common::hasPriv('task', 'finish'); $canClose = common::hasPriv('task', 'close'); $canRecordEstimate = common::hasPriv('task', 'recordEstimate'); $canEdit = common::hasPriv('task', 'edit'); $canBatchCreate = ($this->config->vision == 'rnd' and common::hasPriv('task', 'batchCreate')); if($task->status != 'pause') $menu .= $this->buildMenu('task', 'start', $params, $task, 'browse', '', '', 'iframe', true); if($task->status == 'pause') $menu .= $this->buildMenu('task', 'restart', $params, $task, 'browse', '', '', 'iframe', true); $menu .= $this->buildMenu('task', 'finish', $params, $task, 'browse', '', '', 'iframe', true); $menu .= $this->buildMenu('task', 'close', $params, $task, 'browse', '', '', 'iframe', true); if(($canStart or $canRestart or $canFinish or $canClose) and ($canRecordEstimate or $canEdit or $canBatchCreate)) { $menu .= "
"; } $menu .= $this->buildMenu('task', 'recordEstimate', $params, $task, 'browse', 'time', '', 'iframe', true); $menu .= $this->buildMenu('task', 'edit', $params, $task, 'browse'); if($this->config->vision == 'rnd') { $menu .= $this->buildMenu('task', 'batchCreate', "execution=$task->execution&storyID=$task->story&moduleID=$task->module&taskID=$task->id&ifame=0", $task, 'browse', 'split', '', '', '', '', $this->lang->task->children); } return $menu; } /** * Gets the version record of the task. * * @param $taskID * @param $version * @access public * @return void */ public function getTaskSpec($taskID, $version) { return $this->dao->select('*')->from(TABLE_TASKSPEC) ->where('task')->eq($taskID) ->andWhere('version')->eq($version) ->fetch(); } public function activate($taskID, $extra = '') { $changes = parent::activate($taskID, $extra); $now = helper::now(); $this->dao->update(TABLE_TASK)->set('activatedDate')->eq($now)->where('id')->eq($taskID)->exec(); return $changes; } public function update($taskID) { $result = parent::update($taskID); /* Update planDuration. */ if($result) { $estStarted = $this->post->estStarted; $deadline = $this->post->deadline; $planDuration = $this->loadModel('holiday')->getActualWorkingDays($estStarted, $deadline); $planDuration = count($planDuration); $this->dao->update(TABLE_TASK)->set('planDuration')->eq($planDuration)->where('id')->eq($taskID)->exec(); } return $result; }