+ Add consumed and teamCount of projects for performance optimization.
This commit is contained in:
@@ -2,4 +2,5 @@ ALTER TABLE `zt_project`
|
||||
ADD `progress` decimal(5,2) NOT NULL DEFAULT '0' AFTER `realDuration`,
|
||||
ADD `estimate` float NOT NULL DEFAULT '0' AFTER `progress`,
|
||||
ADD `left` float NOT NULL DEFAULT '0' AFTER `estimate`,
|
||||
ADD `consumed` float NOT NULL DEFAULT '0' AFTER `left`;
|
||||
ADD `consumed` float NOT NULL DEFAULT '0' AFTER `left`,
|
||||
ADD `teamCount` int NOT NULL DEFAULT '0' AFTER `consumed`;
|
||||
|
||||
@@ -364,7 +364,7 @@ class block extends control
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager(0, 30, 1);
|
||||
|
||||
$this->view->actions = $this->loadModel('action')->getDynamic('all', 'today', 'date_desc', $pager);
|
||||
$this->view->actions = $this->loadModel('action')->getDynamic('all', 'today', 'id_desc', $pager);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('nodeleted|noletter|all');
|
||||
|
||||
$this->display();
|
||||
@@ -1542,7 +1542,7 @@ class block extends control
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager(0, 30, 1);
|
||||
|
||||
$this->view->actions = $this->loadModel('action')->getDynamic('all', 'all', 'date_desc', $pager, 'all', $projectID);
|
||||
$this->view->actions = $this->loadModel('action')->getDynamic('all', 'all', 'id_desc', $pager, 'all', $projectID);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
}
|
||||
|
||||
|
||||
@@ -3060,7 +3060,6 @@ class bugModel extends model
|
||||
$bugs = $this->dao->select("*, IF(`pri` = 0, {$this->config->maxPriValue}, `pri`) as priOrder, IF(`severity` = 0, {$this->config->maxPriValue}, `severity`) as severityOrder")->from(TABLE_BUG)->where($bugQuery)
|
||||
->beginIF(!$this->app->user->admin)->andWhere('execution')->in('0,' . $this->app->user->view->sprints)->fi()
|
||||
->beginIF($excludeBugs)->andWhere('id')->notIN($excludeBugs)->fi()
|
||||
|
||||
->beginIF($projectID)
|
||||
->andWhere('project', true)->eq($projectID)
|
||||
->orWhere('project')->eq(0)
|
||||
|
||||
@@ -1369,50 +1369,6 @@ class productModel extends model
|
||||
|
||||
$projectKeys = array_keys($projects);
|
||||
$stats = array();
|
||||
$hours = array();
|
||||
$emptyHour = array('totalEstimate' => 0, 'totalConsumed' => 0, 'totalLeft' => 0, 'progress' => 0);
|
||||
|
||||
/* Get all tasks and compute totalEstimate, totalConsumed, totalLeft, progress according to them. */
|
||||
$tasks = $this->dao->select('id, project, estimate, consumed, `left`, status, closedReason')
|
||||
->from(TABLE_TASK)
|
||||
->where('project')->in($projectKeys)
|
||||
->andWhere('parent')->lt(1)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetchGroup('project', 'id');
|
||||
|
||||
/* Compute totalEstimate, totalConsumed, totalLeft. */
|
||||
foreach($tasks as $projectID => $projectTasks)
|
||||
{
|
||||
$hour = (object)$emptyHour;
|
||||
foreach($projectTasks as $task)
|
||||
{
|
||||
if($task->status != 'cancel')
|
||||
{
|
||||
$hour->totalEstimate += $task->estimate;
|
||||
$hour->totalConsumed += $task->consumed;
|
||||
}
|
||||
if($task->status != 'cancel' and $task->status != 'closed') $hour->totalLeft += $task->left;
|
||||
}
|
||||
$hours[$projectID] = $hour;
|
||||
}
|
||||
|
||||
/* Compute totalReal and progress. */
|
||||
$progressList = $this->loadModel('project')->getWaterfallProgress(array_keys($hours));
|
||||
foreach($hours as $projectID => $hour)
|
||||
{
|
||||
$hour->totalEstimate = round($hour->totalEstimate, 1) ;
|
||||
$hour->totalConsumed = round($hour->totalConsumed, 1);
|
||||
$hour->totalLeft = round($hour->totalLeft, 1);
|
||||
$hour->totalReal = $hour->totalConsumed + $hour->totalLeft;
|
||||
$hour->progress = $projects[$projectID]->model == 'waterfall' ? $progressList[$projectID] : ($hour->totalReal ? round($hour->totalConsumed / $hour->totalReal, 2) * 100 : 0);
|
||||
}
|
||||
|
||||
/* Get the number of project teams. */
|
||||
$teams = $this->dao->select('root,count(*) as teams')->from(TABLE_TEAM)
|
||||
->where('root')->in($projectKeys)
|
||||
->andWhere('type')->eq('project')
|
||||
->groupBy('root')
|
||||
->fetchAll('root');
|
||||
|
||||
/* Process projects. */
|
||||
foreach($projects as $key => $project)
|
||||
@@ -1426,10 +1382,6 @@ class productModel extends model
|
||||
if($delay > 0) $project->delay = $delay;
|
||||
}
|
||||
|
||||
/* Process the hours. */
|
||||
$project->hours = isset($hours[$project->id]) ? $hours[$project->id] : (object)$emptyHour;
|
||||
|
||||
$project->teamCount = isset($teams[$project->id]) ? $teams[$project->id]->teams : 0;
|
||||
$stats[] = $project;
|
||||
}
|
||||
return $stats;
|
||||
|
||||
@@ -92,11 +92,11 @@
|
||||
<td title='<?php echo $budgetTitle;?>' class="text-ellipsis text-right"><?php echo $budgetTitle;?></td>
|
||||
<td class='padding-right text-left'><?php echo $project->begin;?></td>
|
||||
<td class='padding-right text-left'><?php echo $project->end;?></td>
|
||||
<td class="text-right" title="<?php echo $project->hours->totalEstimate . ' ' . $lang->execution->workHour;?>"><?php echo $project->hours->totalEstimate . $lang->execution->workHourUnit;?></td>
|
||||
<td class="text-right" title="<?php echo $project->hours->totalConsumed . ' ' . $lang->execution->workHour;?>"><?php echo $project->hours->totalConsumed . $lang->execution->workHourUnit;?></td>
|
||||
<td class="text-right" title="<?php echo $project->estimate . ' ' . $lang->execution->workHour;?>"><?php echo $project->estimate . $lang->execution->workHourUnit;?></td>
|
||||
<td class="text-right" title="<?php echo $project->consumed . ' ' . $lang->execution->workHour;?>"><?php echo $project->consumed . $lang->execution->workHourUnit;?></td>
|
||||
<td>
|
||||
<div class='progress-pie' data-doughnut-size='90' data-color='#3CB371' data-value='<?php echo round($project->hours->progress);?>' data-width='24' data-height='24' data-back-color='#e8edf3'>
|
||||
<div class='progress-info'><?php echo round($project->hours->progress);?></div>
|
||||
<div class='progress-pie' data-doughnut-size='90' data-color='#3CB371' data-value='<?php echo round($project->progress);?>' data-width='24' data-height='24' data-back-color='#e8edf3'>
|
||||
<div class='progress-info'><?php echo round($project->progress);?></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -1370,13 +1370,21 @@ class programModel extends model
|
||||
if(empty($projects)) return;
|
||||
}
|
||||
|
||||
/* 1. Get executions to be refreshed. */
|
||||
/* 1. Get summary and members of executions to be refreshed. */
|
||||
$summary = $this->dao->select('execution, SUM(estimate) AS totalEstimate, SUM(consumed) AS totalConsumed, SUM(`left`) AS totalLeft')->from(TABLE_TASK)
|
||||
->where('deleted')->eq(0)
|
||||
->beginIF(!empty($projects))->andWhere('project')->in($projects)->fi()
|
||||
->groupBy('execution')
|
||||
->fetchAll();
|
||||
if(empty($summary)) return;
|
||||
|
||||
$teamMembers = $this->dao->select('t1.root, COUNT(1) AS members')->from(TABLE_TEAM)->alias('t1')
|
||||
->leftJoin(TABLE_USER)->alias('t2')->on('t1.account=t2.account')
|
||||
->where('t1.type')->eq('project')
|
||||
->beginIF(!empty($projects))->andWhere('t1.root')->in($projects)->fi()
|
||||
->andWhere('t2.deleted')->eq(0)
|
||||
->groupBy('t1.root')
|
||||
->fetchPairs('root');
|
||||
|
||||
|
||||
/* 2. Get all parents to be refreshed. */
|
||||
$executions = array();
|
||||
@@ -1392,13 +1400,19 @@ class programModel extends model
|
||||
$executionID = $execution->execution;
|
||||
foreach($executionPaths[$executionID] as $nodeID)
|
||||
{
|
||||
if(!isset($stats[$nodeID])) $stats[$nodeID] = array('totalEstimate' => 0, 'totalConsumed' => 0, 'totalLeft' => 0);
|
||||
if(!isset($stats[$nodeID])) $stats[$nodeID] = array('totalEstimate' => 0, 'totalConsumed' => 0, 'totalLeft' => 0, 'teamCount' => 0);
|
||||
$stats[$nodeID]['totalEstimate'] += $execution->totalEstimate;
|
||||
$stats[$nodeID]['totalConsumed'] += $execution->totalConsumed;
|
||||
$stats[$nodeID]['totalLeft'] += $execution->totalLeft;
|
||||
}
|
||||
}
|
||||
|
||||
foreach($teamMembers as $projectID => $teamCount)
|
||||
{
|
||||
if(!isset($stats[$projectID])) $stats[$projectID] = array('totalEstimate' => 0, 'totalConsumed' => 0, 'totalLeft' => 0, 'teamCount' => 0);
|
||||
$stats[$projectID]['teamCount'] = $teamCount;
|
||||
}
|
||||
|
||||
/* 4. Refresh stats to db. */
|
||||
foreach($stats as $projectID => $project)
|
||||
{
|
||||
@@ -1406,6 +1420,7 @@ class programModel extends model
|
||||
$progress = $totalReal ? round($project['totalConsumed'] / $totalReal, 2) * 100 : 0;
|
||||
$this->dao->update(TABLE_PROJECT)
|
||||
->set('progress')->eq($progress)
|
||||
->set('teamCount')->eq($project['teamCount'])
|
||||
->set('estimate')->eq($project['totalEstimate'])
|
||||
->set('consumed')->eq($project['totalConsumed'])
|
||||
->set('left')->eq($project['totalLeft'])
|
||||
@@ -1461,7 +1476,6 @@ class programModel extends model
|
||||
if($delay > 0) $project->delay = $delay;
|
||||
}
|
||||
|
||||
$project->teamCount = isset($teamMembers[$project->id]) ? count($teamMembers[$project->id]) : 0;
|
||||
$project->teamMembers = isset($teamMembers[$project->id]) ? array_keys($teamMembers[$project->id]) : array();
|
||||
|
||||
/* Convert predefined HTML entities to characters. */
|
||||
@@ -1469,6 +1483,7 @@ class programModel extends model
|
||||
|
||||
$stats[$key] = $project;
|
||||
}
|
||||
|
||||
return $stats;
|
||||
}
|
||||
|
||||
|
||||
@@ -297,7 +297,7 @@ class projectModel extends model
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getOverviewList($queryType = 'byStatus', $param = 'all', $orderBy = 'id_desc', $limit = 15, $excludedModel = '')
|
||||
public function getOverviewList($queryType = 'byStatus', $param = 'all', $orderBy = 'id_desc', $limit = 10, $excludedModel = '')
|
||||
{
|
||||
$queryType = strtolower($queryType);
|
||||
$projects = $this->dao->select('*')->from(TABLE_PROJECT)
|
||||
@@ -316,31 +316,12 @@ class projectModel extends model
|
||||
if(empty($projects)) return array();
|
||||
$projectIdList = array_keys($projects);
|
||||
|
||||
$teams = $this->dao->select('t1.root, count(t1.id) as teams')->from(TABLE_TEAM)->alias('t1')
|
||||
->leftJoin(TABLE_USER)->alias('t2')->on('t1.account=t2.account')
|
||||
->where('t1.root')->in($projectIdList)
|
||||
->andWhere('t1.type')->eq('project')
|
||||
->andWhere('t2.deleted')->eq(0)
|
||||
->groupBy('root')->fetchPairs();
|
||||
|
||||
$hours = $this->dao->select('t2.project, ROUND(SUM(t1.consumed), 1) AS consumed, ROUND(SUM(t1.estimate), 1) AS estimate')->from(TABLE_TASK)->alias('t1')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.execution = t2.id')
|
||||
->where('t2.project')->in($projectIdList)
|
||||
->andWhere('t2.deleted')->eq(0)
|
||||
->andWhere('t1.deleted')->eq(0)
|
||||
->andWhere('t1.parent')->lt(1)
|
||||
->groupBy('t2.project')
|
||||
->fetchAll('project');
|
||||
|
||||
$storySummary = $this->getTotalStoriesByProject($projectIdList);
|
||||
$taskSummary = $this->getTotalTaskByProject($projectIdList);
|
||||
$bugSummary = $this->getTotalBugByProject($projectIdList);
|
||||
|
||||
foreach($projects as $projectID => $project)
|
||||
{
|
||||
$project->consumed = isset($hours[$projectID]) ? (float)$hours[$projectID]->consumed : 0;
|
||||
$project->estimate = isset($hours[$projectID]) ? (float)$hours[$projectID]->estimate : 0;
|
||||
$project->teamCount = isset($teams[$projectID]) ? $teams[$projectID] : 0;
|
||||
$project->leftBugs = isset($bugSummary[$projectID]) ? $bugSummary[$projectID]->leftBugs : 0;
|
||||
$project->allBugs = isset($bugSummary[$projectID]) ? $bugSummary[$projectID]->allBugs : 0;
|
||||
$project->doneBugs = isset($bugSummary[$projectID]) ? $bugSummary[$projectID]->doneBugs : 0;
|
||||
|
||||
Reference in New Issue
Block a user