* Refactor the getStats method under the project.
This commit is contained in:
@@ -888,6 +888,7 @@ class block extends control
|
||||
/* Load models and langs. */
|
||||
$this->loadModel('project');
|
||||
$this->loadModel('weekly');
|
||||
$this->loadModel('execution');
|
||||
$this->app->loadLang('task');
|
||||
$this->app->loadLang('story');
|
||||
$this->app->loadLang('bug');
|
||||
@@ -898,7 +899,7 @@ class block extends control
|
||||
|
||||
/* Get projects. */
|
||||
$excludedModel = $this->config->edition == 'max' ? '' : 'waterfall';
|
||||
$projects = $this->loadModel('project')->getOverviewList('byStatus', $status, 'order_asc', $count, $excludedModel);
|
||||
$projects = $this->project->getOverviewList('byStatus', $status, 'order_asc', $count, $excludedModel);
|
||||
if(empty($projects))
|
||||
{
|
||||
$this->view->projects = $projects;
|
||||
@@ -924,7 +925,7 @@ class block extends control
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = pager::init(0, 3, 1);
|
||||
$project->progress = $project->allStories == 0 ? 0 : round($project->doneStories / $project->allStories, 3) * 100;
|
||||
$project->executions = $this->project->getStats($projectID, 'all', 0, 0, 30, 'id_desc', $pager);
|
||||
$project->executions = $this->execution->getStatData($projectID, 'all', 0, 0, false, '', 'id_desc', $pager);
|
||||
}
|
||||
elseif($project->model == 'waterfall')
|
||||
{
|
||||
@@ -1356,8 +1357,8 @@ class block extends control
|
||||
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = pager::init(0, $count, 1);
|
||||
$this->app->loadLang('execution');
|
||||
$this->view->executionStats = !defined('TUTORIAL') ? $this->loadModel('project')->getStats($this->session->project, $type, 0, 0, 30, 'id_desc', $pager) : array($this->loadModel('tutorial')->getExecution());
|
||||
$this->loadModel('execution');
|
||||
$this->view->executionStats = !defined('TUTORIAL') ? $this->execution->getStatData($this->session->project, $type, 0, 0, false, '', 'id_desc', $pager) : array($this->loadModel('tutorial')->getExecution());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1692,7 +1693,7 @@ class block extends control
|
||||
$count = isset($this->params->count) ? (int)$this->params->count : 0;
|
||||
$status = isset($this->params->type) ? $this->params->type : 'all';
|
||||
|
||||
$this->app->loadLang('execution');
|
||||
$this->loadModel('execution');
|
||||
$this->app->loadClass('pager', true);
|
||||
$pager = pager::init(0, $count, 1);
|
||||
|
||||
@@ -1700,17 +1701,8 @@ class block extends control
|
||||
if($this->config->systemMode == 'new') $projectPairs = $this->dao->select('id,name')->from(TABLE_PROJECT)->where('type')->eq('project')->fetchPairs('id', 'name');
|
||||
|
||||
$projectID = $this->view->block->module == 'my' ? 0 : (int)$this->session->project;
|
||||
$executions = $this->loadModel('project')->getStats($projectID, $status, 0, 0, 30, 'id_asc', $pager);
|
||||
|
||||
foreach($executions as $index => $execution)
|
||||
{
|
||||
if(empty($execution->children)) continue;
|
||||
|
||||
foreach($execution->children as $child) $executions[] = $child;
|
||||
unset($executions[$index]);
|
||||
}
|
||||
|
||||
$this->view->executionStats = $executions;
|
||||
$this->view->executionStats = $this->execution->getStatData($projectID, $status, 0, 0, false, 'skipParent', 'id_asc', $pager);
|
||||
$this->view->projectPairs = $projectPairs;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<?php
|
||||
$config->execution = new stdclass();
|
||||
$config->execution->defaultWorkhours = '7.0';
|
||||
$config->execution->orderBy = 'isDone,status,order_desc';
|
||||
$config->execution->maxBurnDay = '31';
|
||||
$config->execution->weekend = '2';
|
||||
$config->execution->ownerFields = array('PO', 'PM', 'QD', 'RD');
|
||||
$config->execution->defaultWorkhours = '7.0';
|
||||
$config->execution->orderBy = 'isDone,status,order_desc';
|
||||
$config->execution->maxBurnDay = '31';
|
||||
$config->execution->weekend = '2';
|
||||
$config->execution->ownerFields = array('PO', 'PM', 'QD', 'RD');
|
||||
$config->execution->defaultBurnPeriod = 30;
|
||||
|
||||
$config->execution->list = new stdclass();
|
||||
$config->execution->list->exportFields = 'id,name,projectName,code,PM,begin,end,status,totalEstimate,totalConsumed,totalLeft,progress';
|
||||
|
||||
@@ -2552,7 +2552,7 @@ class execution extends control
|
||||
{
|
||||
$this->loadModel('project');
|
||||
$projects = $this->project->getPairsByProgram('', 'noclosed');
|
||||
$executions = $this->project->getStats(0, 'all', 0, 0, 30, 'id_desc');
|
||||
$executions = $this->execution->getStatData(0, 'all', 0, 0, false, '', 'id_desc');
|
||||
|
||||
$teams = $this->dao->select('root,account')->from(TABLE_TEAM)
|
||||
->where('root')->in($this->app->user->view->sprints)
|
||||
@@ -3731,7 +3731,7 @@ class execution extends control
|
||||
$this->view->title = $this->lang->execution->allExecutions;
|
||||
$this->view->position[] = $this->lang->execution->allExecutions;
|
||||
|
||||
$executionStats = $this->project->getStats(0, $status, $productID, 0, 30, $orderBy, $pager, false, $queryID);
|
||||
$executionStats = $this->execution->getStatData(0, $status, $productID, 0, false, $queryID, $orderBy, $pager);
|
||||
|
||||
$parentIdList = array();
|
||||
foreach($executionStats as $execution)
|
||||
@@ -3742,7 +3742,7 @@ class execution extends control
|
||||
$parents = array();
|
||||
if($parentIdList) $parents = $this->execution->getByIdList($parentIdList);
|
||||
|
||||
$allExecutionsNum = $this->project->getStats(0, 'all');
|
||||
$allExecutionsNum = $this->execution->getStatData(0, 'all');
|
||||
$this->view->allExecutionsNum = count($allExecutionsNum);
|
||||
|
||||
$this->view->executionStats = $executionStats;
|
||||
@@ -3853,7 +3853,7 @@ class execution extends control
|
||||
}
|
||||
|
||||
$project = $this->project->getByID($projectID);
|
||||
$executionStats = $this->project->getStats($projectID, $status == 'byproduct' ? 'all' : $status, $productID, 0, 30, 'id_asc');
|
||||
$executionStats = $this->execution->getStatData($projectID, $status == 'byproduct' ? 'all' : $status, $productID, 0, false, '', 'id_asc');
|
||||
if(isset($project->model) and $project->model == 'waterfall')
|
||||
{
|
||||
$stageList = array();
|
||||
|
||||
@@ -1409,6 +1409,126 @@ class executionModel extends model
|
||||
->fetchPairs('id', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get execution stat data.
|
||||
|
||||
* @param int $projectID
|
||||
* @param string $browseType all|undone|wait|doing|suspended|closed|involved|bySearch|review
|
||||
* @param int $productID
|
||||
* @param int $branch
|
||||
* @param bool $withTasks
|
||||
* @param string|int $param skipParent
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getStatData($projectID = 0, $browseType = 'undone', $productID = 0, $branch = 0, $withTasks = false, $param = '', $orderBy = 'id_asc', $pager = null)
|
||||
{
|
||||
/* Construct the query SQL at search executions. */
|
||||
$executionQuery = '';
|
||||
if($browseType == 'bySearch')
|
||||
{
|
||||
$queryID = (int)$param;
|
||||
if($queryID)
|
||||
{
|
||||
$query = $this->loadModel('search')->getQuery($queryID);
|
||||
if($query)
|
||||
{
|
||||
$this->session->set('executionQuery', $query->sql);
|
||||
$this->session->set('executionForm', $query->form);
|
||||
}
|
||||
}
|
||||
if($this->session->executionQuery == false) $this->session->set('executionQuery', ' 1 = 1');
|
||||
|
||||
$executionQuery = $this->session->executionQuery;
|
||||
$allProject = "`project` = 'all'";
|
||||
|
||||
if(strpos($executionQuery, $allProject) !== false) $executionQuery = str_replace($allProject, '1', $executionQuery);
|
||||
$executionQuery = preg_replace('/(`\w*`)/', 't1.$1',$executionQuery);
|
||||
}
|
||||
|
||||
/* Get involved executions. */
|
||||
$myExecutionIDList = array();
|
||||
if($browseType == 'involved')
|
||||
{
|
||||
$myExecutionIDList = $this->dao->select('root')->from(TABLE_TEAM)
|
||||
->where('account')->eq($this->app->user->account)
|
||||
->andWhere('type')->eq('execution')
|
||||
->fetchPairs();
|
||||
}
|
||||
|
||||
$executions = $this->dao->select('t1.*,t2.name projectName, t2.model as projectModel')->from(TABLE_EXECUTION)->alias('t1')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
|
||||
->beginIF($productID)->leftJoin(TABLE_PROJECTPRODUCT)->alias('t3')->on('t1.id=t3.project')->fi()
|
||||
->where('t1.type')->in('sprint,stage,kanban')
|
||||
->andWhere('t1.deleted')->eq('0')
|
||||
->andWhere('t1.vision')->eq($this->config->vision)
|
||||
->beginIF(!$this->app->user->admin)->andWhere('t1.id')->in($this->app->user->view->sprints)->fi()
|
||||
->beginIF(!empty($executionQuery))->andWhere($executionQuery)->fi()
|
||||
->beginIF($productID)->andWhere('t3.product')->eq($productID)->fi()
|
||||
->beginIF($projectID)->andWhere('t1.project')->eq($projectID)->fi()
|
||||
->beginIF(!in_array($browseType, array('all', 'undone', 'involved', 'review', 'bySearch')))->andWhere('t1.status')->eq($browseType)->fi()
|
||||
->beginIF($browseType == 'undone')->andWhere('t1.status')->notIN('done,closed')->fi()
|
||||
->beginIF($browseType == 'review')
|
||||
->andWhere("FIND_IN_SET('{$this->app->user->account}', t1.reviewers)")
|
||||
->andWhere('t1.reviewStatus')->eq('doing')
|
||||
->fi()
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
|
||||
$hours = $this->computerProgress($executions);
|
||||
$burns = $this->loadModel('execution')->getBurnData($executions);
|
||||
|
||||
if($withTasks) $executionTasks = $this->execution->getTaskGroupByExecution(array_keys($executions));
|
||||
|
||||
/* Process executions. */
|
||||
$emptyHour = array('totalEstimate' => 0, 'totalConsumed' => 0, 'totalLeft' => 0, 'progress' => 0);
|
||||
foreach($executions as $key => $execution)
|
||||
{
|
||||
/* Process the end time. */
|
||||
$execution->end = date(DT_DATE1, strtotime($execution->end));
|
||||
|
||||
/* Judge whether the execution is delayed. */
|
||||
if($execution->status != 'done' and $execution->status != 'closed' and $execution->status != 'suspended')
|
||||
{
|
||||
$delay = helper::diffDate(helper::today(), $execution->end);
|
||||
if($delay > 0) $execution->delay = $delay;
|
||||
}
|
||||
|
||||
/* Process the burns. */
|
||||
$execution->burns = array();
|
||||
$burnData = isset($burns[$execution->id]) ? $burns[$execution->id] : array();
|
||||
foreach($burnData as $data) $execution->burns[] = $data->value;
|
||||
|
||||
/* Process the hours. */
|
||||
$execution->hours = isset($hours[$execution->id]) ? $hours[$execution->id] : (object)$emptyHour;
|
||||
|
||||
$this->app->loadConfig('task');
|
||||
if(isset($executionTasks) and isset($executionTasks[$execution->id]))
|
||||
{
|
||||
$tasks = array_chunk($executionTasks[$execution->id], $this->config->task->defaultLoadCount, true);
|
||||
$execution->tasks = $tasks[0];
|
||||
}
|
||||
|
||||
/* In the case of the waterfall model, calculate the sub-stage. */
|
||||
if($param == 'skipParent')
|
||||
{
|
||||
if($execution->parent < 0 and $execution->type == 'stage') unset($executions[$key]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(isset($executions[$execution->parent]) and $execution->type == 'stage')
|
||||
{
|
||||
$executions[$execution->parent]->children[$key] = $execution;
|
||||
unset($executions[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $executions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get executions by project.
|
||||
*
|
||||
@@ -1800,6 +1920,38 @@ class executionModel extends model
|
||||
return $tasks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the task data group by execution id list.
|
||||
*
|
||||
* @param array $executionIdList
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getTaskGroupByExecution($executionIdList = array())
|
||||
{
|
||||
if(empty($executionIdList)) return array();
|
||||
$executionTasks = $this->dao->select('*')->from(TABLE_TASK)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('status')->notin('closed,cancel')
|
||||
->andWhere('execution')->in($executionIdList)
|
||||
->orderBy('id_asc')
|
||||
->fetchGroup('execution', 'id');
|
||||
|
||||
foreach($executionTasks as $executionID => $tasks)
|
||||
{
|
||||
foreach($tasks as $task)
|
||||
{
|
||||
if($task->parent > 0 and isset($executionTasks[$executionID][$task->parent]))
|
||||
{
|
||||
$executionTasks[$executionID][$task->parent]->children[$task->id] = $task;
|
||||
unset($executionTasks[$executionID][$task->id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $executionTasks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the execution by ID.
|
||||
*
|
||||
@@ -3236,6 +3388,45 @@ class executionModel extends model
|
||||
return $burnData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get execution burn data.
|
||||
*
|
||||
* @param array $executions
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getBurnData($executions)
|
||||
{
|
||||
/* Get burndown charts datas. */
|
||||
$burns = $this->dao->select('execution, date AS name, `left` AS value')
|
||||
->from(TABLE_BURN)
|
||||
->where('execution')->in(array_keys($executions))
|
||||
->andWhere('task')->eq(0)
|
||||
->orderBy('date desc')
|
||||
->fetchGroup('execution', 'name');
|
||||
|
||||
foreach($burns as $executionID => $executionBurns)
|
||||
{
|
||||
/* If executionBurns > $itemCounts, split it, else call processBurnData() to pad burns. */
|
||||
$begin = $executions[$executionID]->begin;
|
||||
$end = $executions[$executionID]->end;
|
||||
if(helper::isZeroDate($begin)) $begin = $executions[$executionID]->openedDate;
|
||||
$executionBurns = $this->processBurnData($executionBurns, $this->config->execution->defaultBurnPeriod, $begin, $end);
|
||||
|
||||
/* Shorter names. */
|
||||
foreach($executionBurns as $executionBurn)
|
||||
{
|
||||
$executionBurn->name = substr($executionBurn->name, 5);
|
||||
unset($executionBurn->execution);
|
||||
}
|
||||
|
||||
ksort($executionBurns);
|
||||
$burns[$executionID] = $executionBurns;
|
||||
}
|
||||
|
||||
return $burns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process burndown datas when the sets is smaller than the itemCounts.
|
||||
*
|
||||
|
||||
@@ -1353,7 +1353,7 @@ class kanban extends control
|
||||
$this->view->projects = array($this->lang->kanban->allProjects) + $this->project->getPairsByProgram();
|
||||
$this->view->selectedProjectID = $selectedProjectID;
|
||||
$this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID);
|
||||
$this->view->executions2Imported = $this->project->getStats($selectedProjectID, 'undone', 0, 0, 30, 'id_asc', $pager);
|
||||
$this->view->executions2Imported = $this->execution->getStatData($selectedProjectID, 'undone', 0, 0, false, '', 'id_asc', $pager);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter|nodeleted');
|
||||
$this->view->pager = $pager;
|
||||
$this->view->kanbanID = $kanbanID;
|
||||
|
||||
@@ -1024,13 +1024,13 @@ class project extends control
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$allExecution = $this->project->getStats($projectID, 'all');
|
||||
$allExecution = $this->execution->getStatData($projectID, 'all');
|
||||
$this->view->allExecutionNum = empty($allExecution);
|
||||
|
||||
$this->view->title = $this->lang->execution->allExecutions;
|
||||
$this->view->position[] = $this->lang->execution->allExecutions;
|
||||
|
||||
$this->view->executionStats = $this->project->getStats($projectID, $status, $productID, 0, 30, $orderBy, $pager, $this->cookie->showTask);
|
||||
$this->view->executionStats = $this->execution->getStatData($projectID, $status, $productID, 0, $this->cookie->showTask, '', $orderBy, $pager);
|
||||
$this->view->productList = $this->loadModel('product')->getProductPairsByProject($projectID);
|
||||
$this->view->productID = $productID;
|
||||
$this->view->projectID = $projectID;
|
||||
|
||||
+2
-211
@@ -240,7 +240,7 @@ class projectModel extends model
|
||||
{
|
||||
$orderBy = $project->model == 'waterfall' ? 'id_asc' : 'id_desc';
|
||||
$pager = $project->model == 'waterfall' ? null : new pager(0, 1, 1);
|
||||
$project->executions = $this->getStats($projectID, 'undone', 0, 0, 30, $orderBy, $pager);
|
||||
$project->executions = $this->loadModel('execution')->getStatData($projectID, 'undone', 0, 0, false, '', $orderBy, $pager);
|
||||
$project->teamCount = isset($teams[$projectID]) ? $teams[$projectID]->count : 0;
|
||||
$project->estimate = isset($estimates[$projectID]) ? round($estimates[$projectID]->estimate, 2) : 0;
|
||||
$project->parentName = $this->getParentProgram($project);
|
||||
@@ -2263,215 +2263,6 @@ class projectModel extends model
|
||||
->fetchAll('account');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get project stats.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @param string $status
|
||||
* @param int $productID
|
||||
* @param int $branch
|
||||
* @param int $itemCounts
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @param bool $withTasks
|
||||
* @param int $queryID
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getStats($projectID = 0, $status = 'undone', $productID = 0, $branch = 0, $itemCounts = 30, $orderBy = 'id_asc', $pager = null, $withTasks = false, $queryID = 0)
|
||||
{
|
||||
if(empty($productID))
|
||||
{
|
||||
$myExecutionIDList = array();
|
||||
$query = '';
|
||||
if($status == 'bySearch')
|
||||
{
|
||||
$status = 'all';
|
||||
if($queryID)
|
||||
{
|
||||
$query = $this->loadModel('search')->getQuery($queryID);
|
||||
if($query)
|
||||
{
|
||||
$this->session->set('executionQuery', $query->sql);
|
||||
$this->session->set('executionForm', $query->form);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->set('executionQuery', ' 1 = 1');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->session->executionQuery == false) $this->session->set('executionQuery', ' 1 = 1');
|
||||
}
|
||||
$query = $this->session->executionQuery;
|
||||
$allProject = "`project` = 'all'";
|
||||
|
||||
if(strpos($query, $allProject) !== false) $query = str_replace($allProject, '1', $query);
|
||||
$query = preg_replace('/(`\w*`)/', 't1.$1',$query);
|
||||
}
|
||||
|
||||
if($status == 'involved')
|
||||
{
|
||||
$myExecutionIDList = $this->dao->select('root')->from(TABLE_TEAM)
|
||||
->where('account')->eq($this->app->user->account)
|
||||
->andWhere('type')->eq('execution')
|
||||
->fetchPairs();
|
||||
}
|
||||
|
||||
$executions = $this->dao->select('t1.*,t2.name projectName, t2.model as projectModel')->from(TABLE_EXECUTION)->alias('t1')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
|
||||
->where('t1.type')->in('sprint,stage,kanban')
|
||||
->beginIF(!empty($query))->andWhere($query)->fi()
|
||||
->beginIF($projectID != 0)->andWhere('t1.project')->eq($projectID)->fi()
|
||||
->beginIF($projectID == 0 and $this->config->vision)->andWhere('t1.vision')->eq($this->config->vision)->fi()
|
||||
->beginIF(!empty($myExecutionIDList))->andWhere('t1.id')->in(array_keys($myExecutionIDList))->fi()
|
||||
->beginIF($status == 'undone')->andWhere('t1.status')->notIN('done,closed')->fi()
|
||||
->beginIF(!in_array($status, array('all', 'undone', 'involved', 'review'), true))->andWhere('t1.status')->eq($status)->fi()
|
||||
->beginIF($status == 'review')
|
||||
->andWhere("FIND_IN_SET('{$this->app->user->account}', t1.reviewers)")
|
||||
->andWhere('t1.reviewStatus')->eq('doing')
|
||||
->fi()
|
||||
->beginIF(!$this->app->user->admin)->andWhere('t1.id')->in($this->app->user->view->sprints)->fi()
|
||||
->andWhere('t1.vision')->eq($this->config->vision)
|
||||
->andWhere('t1.deleted')->eq('0')
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
}
|
||||
else
|
||||
{
|
||||
$executions = $this->dao->select('t2.*,t3.name projectName, t3.model as projectModel')->from(TABLE_PROJECTPRODUCT)->alias('t1')
|
||||
->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.project=t2.id')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t3')->on('t2.project=t3.id')
|
||||
->where('t1.product')->eq($productID)
|
||||
->beginIF($projectID)->andWhere('t2.project')->eq($projectID)->fi()
|
||||
->beginIF($status == 'undone')->andWhere('t2.status')->notIN('done,closed')->fi()
|
||||
->beginIF($status != 'all' and $status != 'undone')->andWhere('t2.status')->eq($status)->fi()
|
||||
->beginIF(!$this->app->user->admin)->andWhere('t2.id')->in($this->app->user->view->sprints)->fi()
|
||||
->andWhere('t2.deleted')->eq('0')
|
||||
->andWhere('t2.vision')->eq($this->config->vision)
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
}
|
||||
|
||||
$hours = $this->computerProgress($executions);
|
||||
$emptyHour = array('totalEstimate' => 0, 'totalConsumed' => 0, 'totalLeft' => 0, 'progress' => 0);
|
||||
|
||||
/* Get burndown charts datas. */
|
||||
$burns = $this->dao->select('execution, date AS name, `left` AS value')
|
||||
->from(TABLE_BURN)
|
||||
->where('execution')->in(array_keys($executions))
|
||||
->andWhere('task')->eq(0)
|
||||
->orderBy('date desc')
|
||||
->fetchGroup('execution', 'name');
|
||||
|
||||
$this->loadModel('execution');
|
||||
foreach($burns as $executionID => $executionBurns)
|
||||
{
|
||||
/* If executionBurns > $itemCounts, split it, else call processBurnData() to pad burns. */
|
||||
$begin = $executions[$executionID]->begin;
|
||||
$end = $executions[$executionID]->end;
|
||||
if(helper::isZeroDate($begin)) $begin = $executions[$executionID]->openedDate;
|
||||
$executionBurns = $this->execution->processBurnData($executionBurns, $itemCounts, $begin, $end);
|
||||
|
||||
/* Shorter names. */
|
||||
foreach($executionBurns as $executionBurn)
|
||||
{
|
||||
$executionBurn->name = substr($executionBurn->name, 5);
|
||||
unset($executionBurn->execution);
|
||||
}
|
||||
|
||||
ksort($executionBurns);
|
||||
$burns[$executionID] = $executionBurns;
|
||||
}
|
||||
|
||||
if($withTasks)
|
||||
{
|
||||
$executionTasks = $this->dao->select('*')->from(TABLE_TASK)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('status')->notin('closed,cancel')
|
||||
->andWhere('execution')->in(array_keys($executions))
|
||||
->orderBy('id_asc')
|
||||
->fetchGroup('execution', 'id');
|
||||
|
||||
foreach($executionTasks as $executionID => $tasks)
|
||||
{
|
||||
foreach($tasks as $task)
|
||||
{
|
||||
if($task->parent > 0)
|
||||
{
|
||||
if(isset($executionTasks[$executionID][$task->parent]))
|
||||
{
|
||||
$executionTasks[$executionID][$task->parent]->children[$task->id] = $task;
|
||||
unset($executionTasks[$executionID][$task->id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Process executions. */
|
||||
$parents = array();
|
||||
$children = array();
|
||||
foreach($executions as $key => $execution)
|
||||
{
|
||||
/* Process the end time. */
|
||||
$execution->end = date(DT_DATE1, strtotime($execution->end));
|
||||
|
||||
/* Judge whether the execution is delayed. */
|
||||
if($execution->status != 'done' and $execution->status != 'closed' and $execution->status != 'suspended')
|
||||
{
|
||||
$delay = helper::diffDate(helper::today(), $execution->end);
|
||||
if($delay > 0) $execution->delay = $delay;
|
||||
}
|
||||
|
||||
/* Process the burns. */
|
||||
$execution->burns = array();
|
||||
$burnData = isset($burns[$execution->id]) ? $burns[$execution->id] : array();
|
||||
foreach($burnData as $data) $execution->burns[] = $data->value;
|
||||
|
||||
/* Process the hours. */
|
||||
$execution->hours = isset($hours[$execution->id]) ? $hours[$execution->id] : (object)$emptyHour;
|
||||
|
||||
$execution->children = array();
|
||||
$execution->grade == 1 ? $parents[$execution->id] = $execution : $children[$execution->parent][] = $execution;
|
||||
if(isset($executionTasks) and isset($executionTasks[$execution->id]))
|
||||
{
|
||||
$tasks = array_chunk($executionTasks[$execution->id], 50, true);
|
||||
$execution->tasks = $tasks[0];
|
||||
}
|
||||
}
|
||||
|
||||
/* In the case of the waterfall model, calculate the sub-stage. */
|
||||
if($projectID == 0)
|
||||
{
|
||||
foreach($executions as $key => $execution)
|
||||
{
|
||||
if($execution->type == 'stage')
|
||||
{
|
||||
$execution->children = isset($children[$execution->id]) ? $children[$execution->id] : array();
|
||||
unset($children[$execution->id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$project = $this->getByID($projectID);
|
||||
if($project and $project->model == 'waterfall')
|
||||
{
|
||||
foreach($parents as $id => $execution)
|
||||
{
|
||||
$execution->children = isset($children[$id]) ? $children[$id] : array();
|
||||
unset($children[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
$orphan = array();
|
||||
foreach($children as $child) $orphan = array_merge($child, $orphan);
|
||||
|
||||
return array_merge($parents, $orphan);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stats for project kanban.
|
||||
*
|
||||
@@ -2483,7 +2274,7 @@ class projectModel extends model
|
||||
$this->loadModel('program');
|
||||
|
||||
$projects = $this->program->getProjectStats(0, 'all', 0, 'order_asc');
|
||||
$executions = $this->getStats(0, 'doing');
|
||||
$executions = $this->loadModel('execution')->getStatData(0, 'doing');
|
||||
|
||||
$doingExecutions = array();
|
||||
$latestExecutions = array();
|
||||
|
||||
@@ -41,6 +41,7 @@ $config->task->exportFields = '
|
||||
$config->task->customCreateFields = 'story,estStarted,deadline,mailto,pri,estimate';
|
||||
$config->task->customBatchCreateFields = 'module,story,assignedTo,estimate,estStarted,deadline,desc,pri';
|
||||
$config->task->customBatchEditFields = 'module,assignedTo,status,pri,estimate,record,left,estStarted,deadline,finishedBy,canceledBy,closedBy,closedReason';
|
||||
$config->task->defaultLoadCount = 50;
|
||||
|
||||
$config->task->custom = new stdclass();
|
||||
$config->task->custom->createFields = $config->task->customCreateFields;
|
||||
|
||||
Reference in New Issue
Block a user