Skip to content
Snippets Groups Projects
Commit f233a3f1 authored by Nick Milner's avatar Nick Milner Committed by Daniel Stone
Browse files

Generate burndown chart from task status

Rather than using columns that a task was in to determine its status for
burndown charts, use the task status in Maniphest.

[daniels: Substantially rebased from previous version to remove
          intermediate patches, commit message rewritten.]

Differential Revision: https://phabricator.collabora.co.uk/D14
parent e2fc15b6
No related branches found
No related tags found
No related merge requests found
......@@ -2,16 +2,11 @@
final class SprintConstants {
const CUSTOMFIELD_TYPE_STATUS = 'core:customfield';
const PHABRICATOR_ROOT_DIR = 'vendor/phabricator/phabricator';
const LIBPHUTIL_ROOT_DIR = 'vendor/libphutil/libphutil';
const ROOT_DIR = '/srv/phab';
const POINTFIELD_INDEX = 'yERhvoZPNPtM';
const SPRINTFIELD_INDEX = 'scsOmkpB9Tqi';
const TYPE_CLOSED_STATUS_COLUMN = 'Done';
const TYPE_REVIEW_STATUS_COLUMN = 'Review';
const TYPE_DOING_STATUS_COLUMN = 'Doing';
const TYPE_BACKLOG_STATUS_COLUMN = 'Backlog';
const PANEL_BURNDOWN = 'project.sprint';
const PANEL_PHRAGILE = 'project.phragile';
......
......@@ -163,23 +163,22 @@ final class BoardDataProvider {
return $points_sum;
}
private function getProjectColumnXactions() {
private function getProjectTaskStatusXactions() {
$xactions = array();
$scope_phid = $this->project->getPHID();
$task_phids = mpull($this->tasks, 'getPHID');
$query = new ManiphestTransactionQuery();
$query->withTransactionTypes(array(PhabricatorTransactions::TYPE_COLUMNS));
$query->withTransactionTypes(array(ManiphestTransaction::TYPE_STATUS));
$query->withObjectPHIDs($task_phids);
$query->setViewer($this->viewer);
$col_xactions = $query->execute();
foreach ($col_xactions as $xaction) {
$stories = $query->execute();
// FIXME: This should _really_ have ManiphestTransactionQuery take a
// date range, rather than getting the entire list and filtering
// client-side ...
foreach ($stories as $xaction) {
$xaction_date = $xaction->getDateCreated();
if ($xaction_date >= $this->start && $xaction_date <= $this->end) {
$newval = $xaction->getNewValue();
$newArr = call_user_func_array('array_merge', $newval);
if ($newArr['boardPHID'] == $scope_phid) {
$xactions[] = $xaction;
}
$xactions[] = $xaction;
}
}
return $xactions;
......@@ -189,7 +188,8 @@ final class BoardDataProvider {
$date_array = $this->stats->buildDateArray($this->start, $this->end,
$this->timezone);
$xactions = $this->getProjectColumnXactions();
$xactions = $this->getProjectTaskStatusXactions();
$xaction_map = mpull($xactions, null, 'getPHID');
$sprint_xaction = id(new SprintColumnTransaction())
......@@ -197,7 +197,7 @@ final class BoardDataProvider {
->setTasks($this->tasks)
->setQuery($this->query)
->setProject($this->project)
->setEvents($xactions);
->setEventsTaskStatus($xactions);
$dates = $sprint_xaction->parseEvents($date_array, $xaction_map);
$this->stats->setTasks($this->tasks);
......
......@@ -90,70 +90,37 @@ final class SprintColumnTransaction {
return $dates;
}
private function setXActionEventType($old_col_name, $new_col_name) {
$old_is_closed = ($old_col_name = SprintConstants::TYPE_CLOSED_STATUS_COLUMN and $new_col_name != SprintConstants::TYPE_CLOSED_STATUS_COLUMN);
if ($old_is_closed) {
return 'reopen';
} else if ($new_col_name) {
switch ($new_col_name) {
case SprintConstants::TYPE_CLOSED_STATUS_COLUMN:
return 'close';
case SprintConstants::TYPE_REVIEW_STATUS_COLUMN:
return 'review';
case SprintConstants::TYPE_DOING_STATUS_COLUMN:
return 'doing';
case SprintConstants::TYPE_BACKLOG_STATUS_COLUMN:
return 'backlog';
default:
break;
}
private function setXActionTaskStatusEventType($was_open, $is_open) {
if ($was_open == $is_open) {
return null; // no change, ignore
}
if ($was_open && !$is_open) {
return 'close'; // task has been closed
} else {
return null;
return 'reopen'; // task was closed and has been reopened
}
}
public function setEvents($xactions) {
public function setEventsTaskStatus($xactions) {
assert_instances_of($xactions, 'ManiphestTransaction');
$old_col_name = null;
$new_col_name = null;
$events = array();
foreach ($xactions as $xaction) {
$oldval = $xaction->getOldValue();
if (!empty($oldval)) {
$newArr = call_user_func_array('array_merge', $oldval);
$old_col_phid = idx($newArr, 'columnPHID');
foreach ($old_col_phid as $phid) {
$old_col = $this->query->getColumnforPHID($phid);
foreach ($old_col as $obj) {
$old_col_name = $obj->getDisplayName();
}
}
if ($xaction->getOldValue() == null) {
continue;
}
$newval = $xaction->getNewValue();
if (!empty($newval)) {
$newArr = call_user_func_array('array_merge', $newval);
$new_col_phid = idx($newArr, 'columnPHID');
$xaction_scope_phid = idx($newArr, 'boardPHID');
$new_col = $this->query->getColumnforPHID($new_col_phid);
foreach ($new_col as $obj) {
$new_col_name = $obj->getDisplayName();
}
}
$scope_phid = $this->project->getPHID();
if ($scope_phid == $xaction_scope_phid) {
$event_type = $this->setXActionEventType($old_col_name, $new_col_name);
if ($event_type !== null) {
$events[] = array(
'transactionPHID' => $xaction->getPHID(),
'objectPHID' => $xaction->getObjectPHID(),
'created' => $xaction->getDateCreated(),
'modified' => $xaction->getDateModified(),
'key' => $xaction->getMetadataValue('customfield:key'),
'type' => $event_type,
'title' => $xaction->getTitle(),
);
}
$was_open = ManiphestTaskStatus::isOpenStatus($xaction->getOldValue());
$is_open = ManiphestTaskStatus::isOpenStatus($xaction->getNewValue());
$event_type = $this->setXActionTaskStatusEventType($was_open, $is_open);
if ($event_type !== null) {
$events[] = array(
'transactionPHID' => $xaction->getPHID(),
'objectPHID' => $xaction->getObjectPHID(),
'created' => $xaction->getDateCreated(),
'modified' => $xaction->getDateModified(),
'key' => $xaction->getMetadataValue('customfield:key'),
'type' => $event_type,
'title' => $xaction->getTitle(),
);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment