* Performance for product list.
This commit is contained in:
@@ -1 +1,16 @@
|
||||
INSERT INTO `zt_cron` (`m`, `h`, `dom`, `mon`, `dow`, `command`, `remark`, `type`, `buildin`, `status`) VALUES ('0','*','*','*','*','moduleName=misc&methodName=cleanCache', '清理缓存文件','zentao', 1, 'normal');
|
||||
|
||||
ALTER TABLE `zt_product`
|
||||
ADD `draftStories` mediumint(8) NOT NULL DEFAULT '0' AFTER `reviewer`,
|
||||
ADD `activeStories` mediumint(8) NOT NULL DEFAULT '0' AFTER `draftStories`,
|
||||
ADD `changingStories` mediumint(8) NOT NULL DEFAULT '0' AFTER `activeStories`,
|
||||
ADD `reviewingStories` mediumint(8) NOT NULL DEFAULT '0' AFTER `changingStories`,
|
||||
ADD `finishedStories` mediumint NOT NULL DEFAULT '0' AFTER `reviewingStories`,
|
||||
ADD `closedStories` mediumint(8) NOT NULL DEFAULT '0' AFTER `reviewingStories`,
|
||||
ADD `totalStories` mediumint(8) NOT NULL DEFAULT '0' AFTER `closedStories`,
|
||||
ADD `unresolvedBugs` mediumint(8) NOT NULL DEFAULT '0' AFTER `totalStories`,
|
||||
ADD `closedBugs` mediumint(8) NOT NULL DEFAULT '0' AFTER `unresolvedBugs`,
|
||||
ADD `fixedBugs` mediumint(8) NOT NULL DEFAULT '0' AFTER `closedBugs`,
|
||||
ADD `totalBugs` mediumint(8) NOT NULL DEFAULT '0' AFTER `fixedBugs`,
|
||||
ADD `plans` mediumint(8) NOT NULL DEFAULT '0' AFTER `totalBugs`,
|
||||
ADD `releases` mediumint(8) NOT NULL DEFAULT '0' AFTER `plans`;
|
||||
|
||||
@@ -156,8 +156,8 @@ $config->product->report->planLabels = array();
|
||||
$config->product->report->planLabels[] = '';
|
||||
|
||||
$config->product->statisticFields = array();
|
||||
$config->product->statisticFields['stories'] = array('draftStories', 'activeStories', 'changingStories', 'reviewingStories', 'closedStories', 'finishClosedStories', 'unclosedStories');
|
||||
$config->product->statisticFields['bugs'] = array('unResolvedBugs', 'closedBugs', 'fixedBugs');
|
||||
$config->product->statisticFields['stories'] = array('draftStories', 'activeStories', 'changingStories', 'reviewingStories', 'closedStories', 'finishedStories', 'totalStories');
|
||||
$config->product->statisticFields['bugs'] = array('unresolvedBugs', 'closedBugs', 'fixedBugs');
|
||||
$config->product->statisticFields['plans'] = array('plans');
|
||||
$config->product->statisticFields['releases'] = array('releases');
|
||||
|
||||
|
||||
@@ -1295,6 +1295,8 @@ class product extends control
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$this->product->refreshStats(); // Refresh stats fields of products.
|
||||
|
||||
/* Process product structure. */
|
||||
if($this->config->systemMode == 'light' and $orderBy == 'program_asc') $orderBy = 'order_asc';
|
||||
$productStats = $this->product->getStats($orderBy, $pager, $browseType, '', 'story', '', $queryID);
|
||||
|
||||
+127
-163
@@ -1769,6 +1769,131 @@ class productModel extends model
|
||||
return $product;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh stats info of products.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function refreshStats()
|
||||
{
|
||||
$updateTime = zget($this->app->config->global, 'productStatsTime', '');
|
||||
$now = helper::now();
|
||||
|
||||
/*
|
||||
* If productStatsTime is before two weeks ago, refresh all products directly.
|
||||
* Else only refresh the latest products in action table.
|
||||
*/
|
||||
$productActions = array();
|
||||
if($updateTime > date('Y-m-d', strtotime('-14 days')))
|
||||
{
|
||||
$productActions = $this->dao->select('distinct product')->from(TABLE_ACTION)
|
||||
->where('date')->ge($updateTime)
|
||||
->andWhere('product')->notin(array(',0,', ',,'))
|
||||
->fetchPairs('product');
|
||||
if(empty($productActions)) return;
|
||||
}
|
||||
|
||||
$products = array();
|
||||
foreach($productActions as $productAction)
|
||||
{
|
||||
foreach(explode(',', trim($productAction, ',')) as $product)
|
||||
{
|
||||
$products[$product] = $product;
|
||||
}
|
||||
}
|
||||
|
||||
/* 1. Get summary and members of products to be refreshed. */
|
||||
$stories = $this->dao->select('product, status, `closedReason`, count(id) AS c')
|
||||
->from(TABLE_STORY)
|
||||
->where('deleted')->eq(0)
|
||||
->beginIF(!empty($products))->andWhere('product')->in($products)->fi()
|
||||
->andWhere('type')->eq('story')
|
||||
->groupBy('product, status, `closedReason`')
|
||||
->fetchAll();
|
||||
$productStories = array();
|
||||
foreach($stories as $story)
|
||||
{
|
||||
if(!isset($productStories[$story->product])) $productStories[$story->product] = array('draft' => 0, 'active' => 0, 'changing' => 0, 'reviewing' => 0, 'finished' => 0, 'closed' => 0, 'total' => 0);
|
||||
if($story->status == 'draft') $productStories[$story->product]['draft'] += $story->c;
|
||||
if($story->status == 'active') $productStories[$story->product]['active'] += $story->c;
|
||||
if($story->status == 'changing') $productStories[$story->product]['changing'] += $story->c;
|
||||
if($story->status == 'reviewing') $productStories[$story->product]['reviewing'] += $story->c;
|
||||
if($story->status == 'closed') $productStories[$story->product]['closed'] += $story->c;
|
||||
$productStories[$story->product]['total'] += $story->c;
|
||||
|
||||
if($story->status == 'closed' && $story->closedReason == 'done') $productStories[$story->product]['finished'] += $story->c;
|
||||
}
|
||||
|
||||
$bugs = $this->dao->select('product,status,resolution, count(id) AS c')
|
||||
->from(TABLE_BUG)
|
||||
->where('deleted')->eq(0)
|
||||
->beginIF(!empty($products))->andWhere('product')->in($products)->fi()
|
||||
->groupBy('product')
|
||||
->fetchAll();
|
||||
$productBugs = array();
|
||||
foreach($bugs as $bug)
|
||||
{
|
||||
if(!isset($productBugs[$bug->product])) $productBugs[$bug->product] = array('unresolved' => 0, 'fixed' => 0, 'closed' => 0, 'total' => 0);
|
||||
if($bug->status == 'active' or $bug->resolution == 'postponed') $productBugs[$bug->product]['unresolved'] += $bug->c;
|
||||
if($bug->status == 'closed' and $bug->resolution == 'fixed') $productBugs[$bug->product]['fixed'] += $bug->c;
|
||||
if($bug->status == 'closed') $productBugs[$bug->product]['closed'] += $bug->c;
|
||||
$productBugs[$bug->product]['total'] += $bug->c;
|
||||
}
|
||||
|
||||
$plans = $this->dao->select('product, count(id) AS c')
|
||||
->from(TABLE_PRODUCTPLAN)
|
||||
->where('deleted')->eq(0)
|
||||
->beginIF(!empty($products))->andWhere('product')->in($products)->fi()
|
||||
->andWhere('end')->gt(helper::now())
|
||||
->groupBy('product')
|
||||
->fetchPairs();
|
||||
|
||||
$releases = $this->dao->select('product, count(id) AS c')
|
||||
->from(TABLE_RELEASE)
|
||||
->where('deleted')->eq(0)
|
||||
->beginIF(!empty($products))->andWhere('product')->in($products)->fi()
|
||||
->groupBy('product')
|
||||
->fetchPairs();
|
||||
|
||||
/* If products is empty, get all products. */
|
||||
if(empty($products)) $products = $this->dao->select('id')->from(TABLE_PRODUCT)->where('deleted')->eq(0)->fetchPairs();
|
||||
|
||||
$stats = array();
|
||||
foreach($products as $productID)
|
||||
{
|
||||
$product = new stdclass();
|
||||
|
||||
$product->draftStories = isset($productStories[$productID]) ? $productStories[$productID]['draft'] : 0;
|
||||
$product->activeStories = isset($productStories[$productID]) ? $productStories[$productID]['active'] : 0;
|
||||
$product->changingStories = isset($productStories[$productID]) ? $productStories[$productID]['changing'] : 0;
|
||||
$product->reviewingStories = isset($productStories[$productID]) ? $productStories[$productID]['reviewing'] : 0;
|
||||
$product->closedStories = isset($productStories[$productID]) ? $productStories[$productID]['closed'] : 0;
|
||||
$product->finishedStories = isset($productStories[$productID]) ? $productStories[$productID]['finished'] : 0;
|
||||
$product->totalStories = isset($productStories[$productID]) ? $productStories[$productID]['total'] : 0;
|
||||
|
||||
$product->unresolvedBugs = isset($productBugs[$productID]) ? $productBugs[$productID]['unresolved'] : 0;
|
||||
$product->closedBugs = isset($productBugs[$productID]) ? $productBugs[$productID]['closed'] : 0;
|
||||
$product->fixedBugs = isset($productBugs[$productID]) ? $productBugs[$productID]['fixed'] : 0;
|
||||
$product->totalBugs = isset($productBugs[$productID]) ? $productBugs[$productID]['total'] : 0;
|
||||
|
||||
$product->plans = isset($plans[$productID]) ? $plans[$productID] : 0;
|
||||
$product->releases = isset($releases[$productID]) ? $releases[$productID] : 0;
|
||||
|
||||
$stats[$productID] = $product;
|
||||
}
|
||||
|
||||
/* 2. Refresh stats to db. */
|
||||
foreach($stats as $productID=> $product)
|
||||
{
|
||||
$this->dao->update(TABLE_PRODUCT)->data($product)->where('id')->eq($productID)->exec();
|
||||
}
|
||||
|
||||
/* 3. Update projectStatsTime in config. */
|
||||
$this->loadModel('setting')->setItem('system.common.global.productStatsTime', $now);
|
||||
$this->app->config->global->productStatsTime = $now;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get product stats.
|
||||
*
|
||||
@@ -1831,134 +1956,7 @@ class productModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
$stories = $this->dao->select('product, status, count(id) AS count')
|
||||
->from(TABLE_STORY)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('type')->eq('story')
|
||||
->andWhere('product')->in($productKeys)
|
||||
->groupBy('product, status')
|
||||
->fetchGroup('product', 'status');
|
||||
|
||||
/* Padding the stories to sure all products have records. */
|
||||
foreach($productKeys as $productID) if(!isset($stories[$productID])) $stories[$productID] = array();
|
||||
|
||||
/* Padding the stories to sure all status have records. */
|
||||
foreach($stories as $key => $story)
|
||||
{
|
||||
foreach(array_keys($this->lang->story->statusList) as $status)
|
||||
{
|
||||
$story[$status] = isset($story[$status]) ? $story[$status]->count : 0;
|
||||
}
|
||||
$stories[$key] = $story;
|
||||
}
|
||||
|
||||
$finishClosedStory = $this->dao->select('product, count(id) as finish')->from(TABLE_STORY)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('status')->eq('closed')
|
||||
->andWhere('type')->eq('story')
|
||||
->andWhere('closedReason')->eq('done')
|
||||
->groupBy('product')
|
||||
->fetchPairs();
|
||||
|
||||
$unclosedStory = $this->dao->select('product, count(id) as unclosed')->from(TABLE_STORY)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('type')->eq('story')
|
||||
->andWhere('status')->ne('closed')
|
||||
->groupBy('product')
|
||||
->fetchPairs();
|
||||
|
||||
$plans = $this->dao->select('product, count(id) AS count')
|
||||
->from(TABLE_PRODUCTPLAN)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('product')->in($productKeys)
|
||||
->andWhere('end')->gt(helper::now())
|
||||
->groupBy('product')
|
||||
->fetchPairs();
|
||||
|
||||
$releases = $this->dao->select('product, count(id) AS count')
|
||||
->from(TABLE_RELEASE)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('product')->in($productKeys)
|
||||
->groupBy('product')
|
||||
->fetchPairs();
|
||||
|
||||
$bugs = $this->dao->select('product,count(id) AS conut')
|
||||
->from(TABLE_BUG)
|
||||
->where('product')->in($productKeys)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->groupBy('product')
|
||||
->fetchPairs();
|
||||
|
||||
$unResolved = $this->dao->select('product,count(id) AS count')
|
||||
->from(TABLE_BUG)
|
||||
->where('status')->eq('active')
|
||||
->orWhere('resolution')->eq('postponed')
|
||||
->andWhere('product')->in($productKeys)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->groupBy('product')
|
||||
->fetchPairs();
|
||||
|
||||
$fixedBugs = $this->dao->select('product,count(id) AS count')
|
||||
->from(TABLE_BUG)
|
||||
->where('status')->eq('closed')
|
||||
->andWhere('product')->in($productKeys)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('resolution')->eq('fixed')
|
||||
->groupBy('product')
|
||||
->fetchPairs();
|
||||
|
||||
$closedBugs = $this->dao->select('product,count(id) AS count')
|
||||
->from(TABLE_BUG)
|
||||
->where('status')->eq('closed')
|
||||
->andWhere('product')->in($productKeys)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->groupBy('product')
|
||||
->fetchPairs();
|
||||
|
||||
$this->app->loadClass('date', true);
|
||||
$weekDate = date::getThisWeek();
|
||||
$thisWeekBugs = $this->dao->select('product,count(id) AS count')
|
||||
->from(TABLE_BUG)
|
||||
->where('openedDate')->between($weekDate['begin'], $weekDate['end'])
|
||||
->andWhere('product')->in($productKeys)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->groupBy('product')
|
||||
->fetchPairs();
|
||||
|
||||
$assignToNull = $this->dao->select('product,count(id) AS count')
|
||||
->from(TABLE_BUG)
|
||||
->where('assignedTo')->eq('')
|
||||
->andWhere('product')->in($productKeys)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->groupBy('product')
|
||||
->fetchPairs();
|
||||
|
||||
$stats = array();
|
||||
foreach($products as $key => $product)
|
||||
{
|
||||
$product->stories = $stories[$product->id];
|
||||
$product->stories['finishClosed'] = isset($finishClosedStory[$product->id]) ? $finishClosedStory[$product->id] : 0;
|
||||
$product->stories['unclosed'] = isset($unclosedStory[$product->id]) ? $unclosedStory[$product->id] : 0;
|
||||
$product->stories['totalStories'] = $product->stories['unclosed'] + $product->stories['closed'];
|
||||
|
||||
$product->plans = isset($plans[$product->id]) ? $plans[$product->id] : 0;
|
||||
$product->releases = isset($releases[$product->id]) ? $releases[$product->id] : 0;
|
||||
|
||||
$product->bugs = isset($bugs[$product->id]) ? $bugs[$product->id] : 0;
|
||||
$product->unResolved = isset($unResolved[$product->id]) ? $unResolved[$product->id] : 0;
|
||||
$product->closedBugs = isset($closedBugs[$product->id]) ? $closedBugs[$product->id] : 0;
|
||||
$product->fixedBugs = isset($fixedBugs[$product->id]) ? $fixedBugs[$product->id] : 0;
|
||||
$product->thisWeekBugs = isset($thisWeekBugs[$product->id]) ? $thisWeekBugs[$product->id] : 0;
|
||||
$product->assignToNull = isset($assignToNull[$product->id]) ? $assignToNull[$product->id] : 0;
|
||||
|
||||
$closedTotal = $product->stories['closed'];
|
||||
$allTotal = array_sum($product->stories);
|
||||
$product->progress = empty($closedTotal) ? 0 : round($closedTotal / $allTotal * 100, 1);
|
||||
|
||||
$stats[$key] = $product;
|
||||
}
|
||||
|
||||
return $stats;
|
||||
return $products;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2194,44 +2192,10 @@ class productModel extends model
|
||||
$data = $type == 'program' ? $productStructure[$product->program] : $productStructure[$product->program][$product->line];
|
||||
foreach($this->config->product->statisticFields as $key => $fields)
|
||||
{
|
||||
/* Get the total number of requirements and stories. */
|
||||
if(strpos('stories|requirements', $key) !== false)
|
||||
{
|
||||
$totalObjects = 0;
|
||||
foreach($product->$key as $status => $number)
|
||||
{
|
||||
if(isset($this->lang->story->statusList[$status])) $totalObjects += $number;
|
||||
}
|
||||
|
||||
$fieldType = $key == 'stories' ? 'Stories' : 'Requirements';
|
||||
if(!isset($data['total' . $fieldType])) $data['total' . $fieldType] = 0;
|
||||
$data['total' . $fieldType] += $totalObjects;
|
||||
}
|
||||
elseif($key == 'bugs')
|
||||
{
|
||||
$fieldType = 'Bugs';
|
||||
}
|
||||
|
||||
foreach($fields as $field)
|
||||
{
|
||||
if(!isset($data[$field])) $data[$field] = 0;
|
||||
|
||||
$status = $field;
|
||||
if(strpos($field, 'Requirements') !== false or strpos($field, 'Stories') !== false or $field == 'unResolvedBugs')
|
||||
{
|
||||
$length = strpos($field, $fieldType);
|
||||
$status = substr($field, 0, $length);
|
||||
}
|
||||
|
||||
if(strpos('requirements|stories', $key) !== false)
|
||||
{
|
||||
$objects = $product->$key;
|
||||
$data[$field] += $objects[$status];
|
||||
}
|
||||
else
|
||||
{
|
||||
$data[$field] += $product->$status;
|
||||
}
|
||||
$data[$field] += $product->$field;
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
|
||||
@@ -129,9 +129,9 @@
|
||||
<td><?php echo $program['changingStories'];?></td>
|
||||
<td><?php echo $program['reviewingStories'];?></td>
|
||||
<?php $totalStories = $program['totalStories'];?>
|
||||
<td><?php echo $totalStories == 0 ? 0 : round($program['finishClosedStories'] / $totalStories, 3) * 100;?>%</td>
|
||||
<td><?php echo $program['unResolvedBugs'];?></td>
|
||||
<td><?php echo ($program['unResolvedBugs'] + $program['fixedBugs']) == 0 ? 0 : round($program['fixedBugs'] / ($program['unResolvedBugs'] + $program['fixedBugs']), 3) * 100;?>%</td>
|
||||
<td><?php echo $totalStories == 0 ? 0 : round($program['finishedStories'] / $totalStories, 3) * 100;?>%</td>
|
||||
<td><?php echo $program['unresolvedBugs'];?></td>
|
||||
<td><?php echo ($program['unresolvedBugs'] + $program['fixedBugs']) == 0 ? 0 : round($program['fixedBugs'] / ($program['unresolvedBugs'] + $program['fixedBugs']), 3) * 100;?>%</td>
|
||||
<td><?php echo $program['plans'];?></td>
|
||||
<td><?php echo $program['releases'];?></td>
|
||||
<?php foreach($extendFields as $extendField) echo "<td></td>";?>
|
||||
@@ -170,9 +170,9 @@
|
||||
<td><?php echo isset($line['changingStories']) ? $line['changingStories'] : 0;?></td>
|
||||
<td><?php echo isset($line['reviewingStories']) ? $line['reviewingStories'] : 0;?></td>
|
||||
<?php $totalStories = (isset($line['totalStories']) ? $line['totalStories'] : 0)?>
|
||||
<td><?php echo $totalStories == 0 ? 0 : round((isset($line['finishClosedStories']) ? $line['finishClosedStories'] : 0) / $totalStories, 3) * 100;?>%</td>
|
||||
<td><?php echo isset($line['unResolvedBugs']) ? $line['unResolvedBugs'] : 0;?></td>
|
||||
<td><?php echo (isset($line['fixedBugs']) and ($line['unResolvedBugs'] + $line['fixedBugs'] != 0)) ? round($line['fixedBugs'] / ($line['unResolvedBugs'] + $line['fixedBugs']), 3) * 100 : 0;?>%</td>
|
||||
<td><?php echo $totalStories == 0 ? 0 : round((isset($line['finishedStories']) ? $line['finishedStories'] : 0) / $totalStories, 3) * 100;?>%</td>
|
||||
<td><?php echo isset($line['unresolvedBugs']) ? $line['unresolvedBugs'] : 0;?></td>
|
||||
<td><?php echo (isset($line['fixedBugs']) and ($line['unresolvedBugs'] + $line['fixedBugs'] != 0)) ? round($line['fixedBugs'] / ($line['unresolvedBugs'] + $line['fixedBugs']), 3) * 100 : 0;?>%</td>
|
||||
<td><?php echo isset($line['plans']) ? $line['plans'] : 0;?></td>
|
||||
<td><?php echo isset($line['releases']) ? $line['releases'] : 0;?></td>
|
||||
<?php foreach($extendFields as $extendField) echo "<td></td>";?>
|
||||
@@ -184,7 +184,7 @@
|
||||
<?php if(isset($line['products']) and is_array($line['products'])):?>
|
||||
<?php foreach($line['products'] as $productID => $product):?>
|
||||
<?php
|
||||
$totalStories = $product->stories['totalStories'];
|
||||
$totalStories = $product->totalStories;
|
||||
|
||||
$trClass = '';
|
||||
if($product->line and $this->config->systemMode == 'ALM')
|
||||
@@ -229,13 +229,13 @@
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td><?php echo $product->stories['draft'];?></td>
|
||||
<td><?php echo $product->stories['active'];?></td>
|
||||
<td><?php echo $product->stories['changing'];?></td>
|
||||
<td><?php echo $product->stories['reviewing'];?></td>
|
||||
<td><?php echo $totalStories == 0 ? 0 : round($product->stories['finishClosed'] / $totalStories, 3) * 100;?>%</td>
|
||||
<td><?php echo $product->unResolved;?></td>
|
||||
<td><?php echo ($product->unResolved + $product->fixedBugs) == 0 ? 0 : round($product->fixedBugs / ($product->unResolved + $product->fixedBugs), 3) * 100;?>%</td>
|
||||
<td><?php echo $product->draftStories;?></td>
|
||||
<td><?php echo $product->activeStories;?></td>
|
||||
<td><?php echo $product->changingStories;?></td>
|
||||
<td><?php echo $product->reviewingStories;?></td>
|
||||
<td><?php echo $totalStories == 0 ? 0 : round($product->finishedStories / $totalStories, 3) * 100;?>%</td>
|
||||
<td><?php echo $product->unresolvedBugs;?></td>
|
||||
<td><?php echo ($product->unresolvedBugs + $product->fixedBugs) == 0 ? 0 : round($product->fixedBugs / ($product->unresolvedBugs + $product->fixedBugs), 3) * 100;?>%</td>
|
||||
<td><?php echo $product->plans;?></td>
|
||||
<td><?php echo $product->releases;?></td>
|
||||
<?php foreach($extendFields as $extendField) echo "<td>" . $this->loadModel('flow')->getFieldValue($extendField, $product) . "</td>";?>
|
||||
|
||||
@@ -629,55 +629,6 @@ class programModel extends model
|
||||
->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get program and project progress list.
|
||||
*
|
||||
* @param array $programIdList
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getProgressList($programIdList = array())
|
||||
{
|
||||
$programPairs = $this->getPairs();
|
||||
$existProgramIdList = array_intersect($programIdList, array_keys($programPairs));
|
||||
$projectStats = $this->getProjectStats(0, 'all', 0, 'id_desc', null, 0, 0, true);
|
||||
|
||||
$totalProgress = array();
|
||||
$projectCount = array();
|
||||
$userPRJCount = array();
|
||||
$progressList = array();
|
||||
|
||||
foreach($existProgramIdList as $programID)
|
||||
{
|
||||
$totalProgress[$programID] = 0;
|
||||
$projectCount[$programID] = 0;
|
||||
$userPRJCount[$programID] = 0;
|
||||
$progressList[$programID] = 0;
|
||||
|
||||
foreach($projectStats as $projectID => $project)
|
||||
{
|
||||
if(strpos($projectStats[$projectID]->path, ",{$programID},") === false) continue;
|
||||
|
||||
/* The number of projects under this program that the user can view. */
|
||||
if(strpos(",{$this->app->user->view->projects},", ",{$projectID},") !== false) $userPRJCount[$programID] ++;
|
||||
|
||||
$totalProgress[$programID] += $projectStats[$projectID]->progress;
|
||||
$projectCount[$programID] ++;
|
||||
}
|
||||
|
||||
if(empty($projectCount[$programID])) continue;
|
||||
|
||||
$progressList[$programID] = round($totalProgress[$programID] / $projectCount[$programID]);
|
||||
}
|
||||
|
||||
/* Add project progress. */
|
||||
/* First calculate the overall progress of the program, and then filter the unqualified projects. */
|
||||
$existProjectIdList = array_intersect($programIdList, array_keys($projectStats));
|
||||
foreach($existProjectIdList as $projectID) $progressList[$projectID] = $projectStats[$projectID]->progress;
|
||||
|
||||
return $progressList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a program.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user