private function getResolvedIssues($teamid, $userid = 0, $projects = NULL) { $team = TeamCache::getInstance()->getTeam($teamid); if (is_null($projects)) { $projects = $team->getProjects(false, false, false); $formattedProjects = implode(',', array_keys($projects)); } else { $formattedProjects = implode(',', array_values($projects)); } $formattedUsers = 0 != $userid ? $userid : implode(',', array_keys($team->getActiveMembers())); $query = "SELECT id FROM `mantis_bug_table` " . "WHERE project_id IN ({$formattedProjects}) " . "AND handler_id IN ({$formattedUsers}) " . "AND status >= get_project_resolved_status_threshold(project_id) "; $result = SqlWrapper::getInstance()->sql_query($query); echo "query = {$query}<br>"; if (!$result) { echo "<span style='color:red'>ERROR: Query FAILED</span>"; exit; } $isel = new IssueSelection('resolvedIssues'); while ($row = SqlWrapper::getInstance()->sql_fetch_object($result)) { $isel->addIssue($row->id); } echo implode(',', array_keys($isel->getIssueList())); return $isel; }
/** * * @param IssueSelection $iSel * @param type $projectid * @param type $odtTemplate * @return string filepath complete path to generated ODT file */ private function generateODT(IssueSelection $iSel, $projectid, $odtTemplate) { self::$logger->debug("genProjectODT(): project {$projectid} template {$odtTemplate}"); $project = ProjectCache::getInstance()->getProject($projectid); $odf = new odf($odtTemplate); try { $odf->setVars('today', date('Y-m-d')); } catch (Exception $e) { } try { $odf->setVars('selectionName', $project->getName()); } catch (Exception $e) { } try { $session_user = UserCache::getInstance()->getUser($this->session_userid); $odf->setVars('sessionUser', $session_user->getRealname()); } catch (Exception $e) { } $issueList = $iSel->getIssueList(); if (self::$logger->isDebugEnabled()) { self::$logger->debug("nb issues = " . count($issueList)); } $q_id = 0; try { $issueSegment = $odf->setSegment('issueSelection'); } catch (Exception $e) { self::$logger->error("generateODT: TAG 'issueSelection'"); self::$logger->error("generateODT: " + $e->getMessage()); return "FAILED: error on segment 'issueSelection'."; } if (self::$logger->isDebugEnabled()) { self::$logger->debug('XML=' . $issueSegment->getXml()); } foreach ($issueList as $issue) { $q_id += 1; if (0 == $issue->getHandlerId()) { $userName = T_('unknown'); } else { $user = UserCache::getInstance()->getUser($issue->getHandlerId()); $userName = utf8_decode($user->getRealname()); if (empty($userName)) { $userName = "******" . $issue->getHandlerId(); } } if (self::$logger->isDebugEnabled()) { self::$logger->debug("issue " . $issue->getId() . ": handlerName = " . $userName); } if (0 == $issue->getReporterId()) { $reporterName = T_('unknown'); } else { $reporter = UserCache::getInstance()->getUser($issue->getReporterId()); $reporterName = utf8_decode($reporter->getRealname()); if (empty($reporterName)) { $reporterName = "user_" . $issue->getReporterId(); } } if (self::$logger->isDebugEnabled()) { self::$logger->debug("issue " . $issue->getId() . ": reporterName = " . $reporterName); } // add issue try { $issueSegment->setVars('q_id', $q_id); } catch (Exception $e) { } try { $issueSegment->setVars('bugId', $issue->getId()); } catch (Exception $e) { $this->logException($e); } try { $issueSegment->setVars('summary', utf8_decode($issue->getSummary())); } catch (Exception $e) { $this->logException($e); } try { $issueSegment->setVars('dateSubmission', date('d/m/Y', $issue->getDateSubmission())); } catch (Exception $e) { } try { $timestamp = $issue->getLatestStatusOccurrence($issue->getBugResolvedStatusThreshold()); if (is_null($timestamp)) { $issueSegment->setVars('dateResolved', ''); } else { $issueSegment->setVars('dateResolved', date('d/m/Y', $timestamp)); } } catch (Exception $e) { } try { $timestamp = $issue->getDeadLine(); $deadline = 0 == $timestamp ? '' : date('d/m/Y', $issue->getDeadLine()); $issueSegment->setVars('deadline', $deadline); } catch (Exception $e) { $this->logException($e); } try { $issueSegment->setVars('currentStatus', Constants::$statusNames[$issue->getCurrentStatus()]); } catch (Exception $e) { } try { $issueSegment->setVars('handlerId', $userName); } catch (Exception $e) { } try { $issueSegment->setVars('reporterId', $reporterName); } catch (Exception $e) { } try { $issueSegment->setVars('reporterName', $reporterName); } catch (Exception $e) { } try { $issueSegment->setVars('description', utf8_decode($issue->getDescription())); } catch (Exception $e) { } #try { $issueSegment->setVars('description', utf8_decode(Tools::convertToUTF8($issue->getDescription()))); } catch (Exception $e) { }; try { $issueSegment->setVars('category', $issue->getCategoryName()); } catch (Exception $e) { } try { $issueSegment->setVars('severity', $issue->getSeverityName()); } catch (Exception $e) { } try { $issueSegment->setVars('status', Constants::$statusNames[$issue->getStatus()]); } catch (Exception $e) { } try { $issueSegment->setVars('extId', $issue->getTcId()); } catch (Exception $e) { } // add issueNotes $issueNotes = $issue->getIssueNoteList(); $noteId = 0; foreach ($issueNotes as $id => $issueNote) { $noteId += 1; if (self::$logger->isDebugEnabled()) { self::$logger->debug("issue " . $issue->getId() . ": note {$id} = " . $issueNote->getNote()); } $noteReporter = UserCache::getInstance()->getUser($issueNote->getReporterId()); try { $noteReporterName = utf8_decode($noteReporter->getRealname()); } catch (Exception $e) { } try { $issueSegment->bugnotes->noteId($noteId); } catch (Exception $e) { } try { $issueSegment->bugnotes->noteReporter($noteReporterName); } catch (Exception $e) { } try { $issueSegment->bugnotes->noteDateSubmission(date('d/m/Y', $issueNote->getDateSubmitted())); } catch (Exception $e) { } try { $issueSegment->bugnotes->note(utf8_decode($issueNote->getNote())); } catch (Exception $e) { } try { $issueSegment->bugnotes->merge(); } catch (Exception $e) { } } $issueSegment->merge(); } $odf->mergeSegment($issueSegment); // INFO: the following line is MANDATORY and fixes the following error: // "wrong .odt file encoding" #ob_end_clean(); #$odf->exportAsAttachedFile(); // 2nd solution : show link in page $odtFilename = basename($odtTemplate, ".odt") . '_' . $project->getName() . '_' . date('Ymd') . '.odt'; $filepath = Constants::$codevOutputDir . '/reports/' . $odtFilename; if (self::$logger->isDebugEnabled()) { self::$logger->debug("save odt file " . $filepath); } $odf->saveToDisk($filepath); return $filepath; }
/** * @param IssueSelection $inputIssueSel * @param int[] $timestampList */ private function getStatusData(IssueSelection $inputIssueSel, array $timestampList) { $this->statusData = array(); $historyStatusNew = array(); // timestamp => nbIssues $historyStatusFeedback = array(); // timestamp => nbIssues $historyStatusOngoing = array(); // timestamp => nbIssues $historyStatusResolved = array(); // timestamp => nbIssues $historyStatusTotal = array(); // timestamp => nbIssues // get a snapshot of the Status at each timestamp $issues = $inputIssueSel->getIssueList(); foreach ($timestampList as $timestamp) { $midnight_timestamp = mktime(0, 0, 0, date('m', $timestamp), date('d', $timestamp), date('Y', $timestamp)); // all timestamps must be defined, even if empty $historyStatusNew["{$midnight_timestamp}"] = 0; $historyStatusFeedback["{$midnight_timestamp}"] = 0; $historyStatusOngoing["{$midnight_timestamp}"] = 0; $historyStatusResolved["{$midnight_timestamp}"] = 0; $historyStatusTotal["{$midnight_timestamp}"] = 0; foreach ($issues as $issue) { $issueStatus = $issue->getStatus($timestamp); // if issue exists at this date if (-1 != $issueStatus) { if ($issueStatus >= $issue->getBugResolvedStatusThreshold()) { $historyStatusResolved["{$midnight_timestamp}"] += 1; } else { if ($issueStatus == Constants::$status_feedback) { $historyStatusFeedback["{$midnight_timestamp}"] += 1; } else { if ($issueStatus == Constants::$status_new) { $historyStatusNew["{$midnight_timestamp}"] += 1; } else { $historyStatusOngoing["{$midnight_timestamp}"] += 1; } } } $historyStatusTotal["{$midnight_timestamp}"] += 1; #echo date('Y-m-d', $timestamp)." issue ".$issue->getId()." status ".$issueStatus."<br>"; } } if (self::$logger->isDebugEnabled()) { self::$logger->debug('Y-m-d', $midnight_timestamp) . ' new ' . $historyStatusNew["{$midnight_timestamp}"] . 'feedback ' . $historyStatusFeedback["{$midnight_timestamp}"] . 'ongoing ' . $historyStatusOngoing["{$midnight_timestamp}"] . 'resolved ' . $historyStatusResolved["{$midnight_timestamp}"] . 'total ' . $historyStatusTotal["{$midnight_timestamp}"]; } } $statusData = array('new' => $historyStatusNew, 'feedback' => $historyStatusFeedback, 'ongoing' => $historyStatusOngoing, 'resolved' => $historyStatusResolved, 'total' => $historyStatusTotal); return $statusData; }
/** * * Deux courbes: * * RAF Theorique = charge initiale - cumul consomé * * RAF Reel = cumul consomé / (cumul consomé + RAF) * * */ public function execute() { $startTimestamp = mktime(23, 59, 59, date('m', $this->startTimestamp), date('d', $this->startTimestamp), date('Y', $this->startTimestamp)); $endTimestamp = mktime(23, 59, 59, date('m', $this->endTimestamp), date('d', $this->endTimestamp), date('Y', $this->endTimestamp)); #echo "Backlog start ".date('Y-m-d H:i:s', $startTimestamp)." end ".date('Y-m-d H:i:s', $endTimestamp)." interval ".$this->interval."<br>"; $timestampList = Tools::createTimestampList($startTimestamp, $endTimestamp, $this->interval); // -------- elapsed in the period $startTimestamp = mktime(0, 0, 0, date('m', $startTimestamp), date('d', $startTimestamp), date('Y', $startTimestamp)); $endTimestamp = mktime(23, 59, 59, date('m', $endTimestamp), date('d', $endTimestamp), date('Y', $endTimestamp)); //echo "Elapsed start ".date('Y-m-d H:i:s', $startTimestamp)." end ".date('Y-m-d H:i:s', $endTimestamp)." interval ".$this->interval."<br>"; $timestampList2 = Tools::createTimestampList($startTimestamp, $endTimestamp, $this->interval); $this->getBacklogData($this->inputIssueSel, $timestampList); $this->getElapsedData($this->inputIssueSel, $timestampList2); // ------ compute $theoBacklog = array(); $realBacklog = array(); $iselMaxEE = max(array($this->inputIssueSel->mgrEffortEstim, $this->inputIssueSel->effortEstim + $this->inputIssueSel->effortAdd)); $sumElapsed = 0; $nbZeroDivErrors1 = 0; $nbZeroDivErrors2 = 0; foreach ($timestampList as $timestamp) { $midnight_timestamp = mktime(0, 0, 0, date('m', $timestamp), date('d', $timestamp), date('Y', $timestamp)); // ========= RAF theorique // Indicateur = charge initiale - cumul consomé if (array_key_exists($midnight_timestamp, $this->elapsedData)) { #echo "sumElapsed += ".$this->elapsedData[$midnight_timestamp]." from ".date('Y-m-d H:i:s', $midnight_timestamp)."<br>"; $sumElapsed += $this->elapsedData[$midnight_timestamp]; } if (0 != $iselMaxEE) { $val1 = $sumElapsed / $iselMaxEE; } else { // TODO $val1 = 0; $nbZeroDivErrors1 += 1; //self::$logger->error("Division by zero ! (mgrEffortEstim)"); } if ($val1 > 1) { $val1 = 1; } $theoBacklog[Tools::formatDate("%Y-%m-%d", $midnight_timestamp)] = round($val1 * 100, 2); // ========= RAF reel // Indicateur = Conso. Cumulé / (Conso. Cumulé + RAF) $tmp = $sumElapsed + $this->backlogData[$midnight_timestamp]; if (0 != $tmp) { $val2 = $sumElapsed / $tmp; } else { // TODO $val2 = 0; $nbZeroDivErrors2 += 1; //self::$logger->error("Division by zero ! (elapsed + realBacklog)"); } $realBacklog[Tools::formatDate("%Y-%m-%d", $midnight_timestamp)] = round($val2 * 100, 2); #echo "(".date('Y-m-d', $midnight_timestamp).") sumElapsed = $sumElapsed BacklogData = ".$this->backlogData[$midnight_timestamp]." MaxEE = ".$iselMaxEE.'<br>'; #echo "(".date('Y-m-d', $midnight_timestamp).") theoBacklog = ".$theoBacklog[Tools::formatDate("%Y-%m-%d", $midnight_timestamp)]." realBacklog = ".$realBacklog[Tools::formatDate("%Y-%m-%d", $midnight_timestamp)].'<br>'; } // foreach timestamp if (count($this->inputIssueSel->getIssueList()) > 0) { // PERF logging is slow, factorize errors if ($nbZeroDivErrors1 > 0) { self::$logger->error("{$nbZeroDivErrors1} Division by zero ! (mgrEffortEstim)"); } if ($nbZeroDivErrors2 > 0) { self::$logger->error("{$nbZeroDivErrors2} Division by zero ! (elapsed + realBacklog)"); } } $this->execData = array(); $this->execData['theo'] = $theoBacklog; $this->execData['real'] = $realBacklog; }
/** * * returns an array of [user][activity] * activity in (elapsed, sidetask, other, external, leave) * */ public function execute() { $team = TeamCache::getInstance()->getTeam($this->teamid); $members = $team->getActiveMembers(null, null, true); $issueList = $this->inputIssueSel->getIssueList(); // --- $userList = array(); $formattedTaskListPerUser = array(); $iSelPerUser = array(); $iSelOpenTasks = new IssueSelection('nonResolved'); /* @var $issue Issue */ foreach ($issueList as $issue) { try { // for each issue that is not resolved, add reestimated to handler. if (!$issue->isResolved()) { $userId = $issue->getHandlerId(); if (0 != $userId) { $user = UserCache::getInstance()->getUser($userId); $userList[$userId] = $user->getRealname(); } else { $userList[0] = '(unknown 0)'; } if (!$this->isExtRef) { $displayedTaskId = NULL; } else { $displayedTaskId = NULL != $issue->getTcId() && false != trim($issue->getTcId()) ? $issue->getTcId() : 'm-' . $issue->getId(); } $tooltipAttr = $issue->getTooltipItems($this->teamid, $this->sessionUserid, $this->isManager); // add task summary in front $tooltipAttr = array(T_('Summary') => $issue->getSummary()) + $tooltipAttr; $formattedTaskListPerUser[$userId][] = Tools::issueInfoURL($issue->getId(), $tooltipAttr, FALSE, $displayedTaskId); if (!array_key_exists($userId, $iSelPerUser)) { $iSelPerUser[$userId] = new IssueSelection('user_' . $userId); } $iSelPerUser[$userId]->addIssue($issue->getId()); $iSelOpenTasks->addIssue($issue->getId()); } } catch (Exception $e) { self::$logger->error("BacklogPerUserIndicator: " . $e->getMessage()); } } // sort by name, keep key-val association asort($userList); asort($members); // team members $usersActivity = array(); foreach ($members as $userId => $userName) { if (array_key_exists($userId, $iSelPerUser)) { $isel = $iSelPerUser[$userId]; $progress = round($isel->getProgress() * 100); $backlog = $isel->duration; $taskList = implode(', ', $formattedTaskListPerUser[$userId]); $nbTasks = count($formattedTaskListPerUser[$userId]); } else { $progress = 0; $backlog = ''; $taskList = ''; $nbTasks = ''; } $usersActivity[$userId] = array('handlerName' => $userName, 'backlog' => $backlog, 'nbTasks' => $nbTasks, 'progress' => $progress, 'taskList' => $taskList); } // users not in team foreach ($userList as $userId => $userName) { if (!array_key_exists($userId, $members) && 0 != $userId) { $isel = $iSelPerUser[$userId]; $usersActivity[$userId] = array('handlerName' => '<span class="warn_font">' . $userName . '</span>', 'backlog' => $isel->duration, 'nbTasks' => count($formattedTaskListPerUser[$userId]), 'progress' => round($isel->getProgress() * 100), 'taskList' => implode(', ', $formattedTaskListPerUser[$userId])); } } // unassigned tasks if (array_key_exists(0, $userList)) { $isel = $iSelPerUser[0]; $usersActivity[0] = array('handlerName' => '<span class="error_font">' . T_('(unknown 0)') . '</span>', 'backlog' => $isel->duration, 'nbTasks' => count($formattedTaskListPerUser[0]), 'progress' => round($isel->getProgress() * 100), 'taskList' => implode(', ', $formattedTaskListPerUser[0])); } // Total $totalArray = array('handlerName' => T_('TOTAL'), 'backlog' => $iSelOpenTasks->duration, 'nbTasks' => count($iSelOpenTasks->getIssueList()), 'progress' => round($iSelOpenTasks->getProgress() * 100), 'taskList' => ''); #var_dump($usersActivity); $this->execData = array(); $this->execData['userArray'] = $usersActivity; $this->execData['totalArray'] = $totalArray; }
/** * get issues attributes * @param IssueSelection $issueSelection * @return mixed[] */ public static function getIssueListInfo(IssueSelection $issueSelection) { $issueArray = array(); $issues = $issueSelection->getIssueList(); foreach ($issues as $id => $issue) { $driftMgr = $issue->getDriftMgr(); $driftMgrColor = $issue->getDriftColor($driftMgr); $issueArray[$id] = array("bugid" => Tools::issueInfoURL(sprintf("%07d\n", $issue->getId())), "project" => $issue->getProjectName(), "target" => $issue->getTargetVersion(), "effortEstim" => $issue->getMgrEffortEstim(), "elapsed" => $issue->getElapsed(), "summary" => $issue->getSummary(), "category" => $issue->getCategoryName()); } return $issueArray; }