* Fix sv_in_waterfall.
This commit is contained in:
@@ -20,29 +20,61 @@
|
||||
*/
|
||||
class sv_in_waterfall extends baseCalc
|
||||
{
|
||||
public $dataset = 'getWaterfallTasks';
|
||||
|
||||
public $fieldList = array('t1.id as project', 't2.estimate', 't2.consumed', 't2.left');
|
||||
|
||||
public $result = array();
|
||||
|
||||
public function calculate($row)
|
||||
public $reuse = true;
|
||||
|
||||
public $reuseMetrics = array('pv' => 'pv_of_task_in_waterfall', 'ev' => 'ev_of_finished_task_in_waterfall');
|
||||
|
||||
public $reuseRule = '({ev} - {pv}) / {pv}';
|
||||
|
||||
public function calculate($metrics)
|
||||
{
|
||||
$project = $row->project;
|
||||
$estimate = (float)$row->estimate;
|
||||
$consumed = (float)$row->consumed;
|
||||
$left = (float)$row->left;
|
||||
$total = $consumed + $left;
|
||||
$pvs = $metrics['pv'];
|
||||
$evs = $metrics['ev'];
|
||||
if(empty($pvs) || empty($evs)) return false;
|
||||
|
||||
$ev = $total == 0 ? 0 : round($consumed / $total * $estimate, 2);
|
||||
$sv = $estimate == 0 ? 0 : round(($ev - $estimate) / $estimate, 4);
|
||||
$all = array_merge($pvs, $evs);
|
||||
|
||||
if(!isset($this->result[$project])) $this->result[$project] = $sv;
|
||||
$projects = array_column($all, 'project', 'project');
|
||||
$years = array_column($all, 'year', 'year');
|
||||
$weeks = array_column($all, 'week', 'week');
|
||||
|
||||
$pvs = $this->generateUniqueKey($pvs);
|
||||
$evs = $this->generateUniqueKey($evs);
|
||||
|
||||
foreach($projects as $project)
|
||||
{
|
||||
foreach($years as $year)
|
||||
{
|
||||
foreach($weeks as $week)
|
||||
{
|
||||
$key = "{$project}_{$year}_{$week}";
|
||||
$pv = isset($pvs[$key]) ? $pvs[$key] : 0;
|
||||
$ev = isset($evs[$key]) ? $evs[$key] : 0;
|
||||
|
||||
if($pv == 0) continue;
|
||||
$this->result[$project] = array($year => array($week => round(($ev - $pv) / $pv, 4)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getResult($options = array())
|
||||
{
|
||||
$records = $this->getRecords(array('project', 'value'));
|
||||
$records = $this->getRecords(array('project', 'year', 'week', 'value'));
|
||||
return $this->filterByOptions($records, $options);
|
||||
}
|
||||
|
||||
public function generateUniqueKey($records)
|
||||
{
|
||||
$uniqueKeyRecords = array();
|
||||
foreach($records as $record)
|
||||
{
|
||||
$key = "{$record['project']}_{$record['year']}_{$record['week']}";
|
||||
$uniqueKeyRecords[$key] = $record['value'];
|
||||
}
|
||||
|
||||
return $uniqueKeyRecords;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,16 +283,32 @@ class metricTest
|
||||
include_once $this->objectModel->getCalcRoot() . $scope . DS . $purpose . DS . $code . '.php';
|
||||
|
||||
$calc = new $code;
|
||||
$rows = $this->prepareDataset($calc)->fetchAll();
|
||||
|
||||
foreach($rows as $row)
|
||||
if(!$calc->reuse)
|
||||
{
|
||||
$calc->calculate((object)$row);
|
||||
$rows = $this->prepareDataset($calc)->fetchAll();
|
||||
|
||||
foreach($rows as $row)
|
||||
{
|
||||
$calc->calculate((object)$row);
|
||||
}
|
||||
}
|
||||
|
||||
return $calc;
|
||||
}
|
||||
|
||||
public function getReuseCalcResult($calc, $options = array())
|
||||
{
|
||||
$reuseMetrics = array();
|
||||
foreach($calc->reuseMetrics as $key => $reuseMetric)
|
||||
{
|
||||
$reuseMetrics[$key] = $this->objectModel->getResultByCode($reuseMetric, $options);
|
||||
}
|
||||
|
||||
$calc->calculate($reuseMetrics);
|
||||
|
||||
return $calc->getResult($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* 准备计算度量项所需要的数据源。
|
||||
* Prepare dataset object for calc.
|
||||
|
||||
@@ -7,8 +7,8 @@ title=sv_in_waterfall
|
||||
timeout=0
|
||||
cid=1
|
||||
|
||||
- 测试分组数。 @5
|
||||
- 测试项目7。第0条的value属性 @-0.3492
|
||||
- 测试分组数。 @1
|
||||
- 测试项目7。第0条的value属性 @1.0905
|
||||
|
||||
*/
|
||||
include dirname(__FILE__, 7) . '/test/lib/init.php';
|
||||
@@ -21,6 +21,6 @@ zdTable('task')->config('task_waterfall', true, 4)->gen(1000);
|
||||
$metric = new metricTest();
|
||||
$calc = $metric->calcMetric(__FILE__);
|
||||
|
||||
r(count($calc->getResult())) && p('') && e('5'); // 测试分组数。
|
||||
r(count($metric->getReuseCalcResult($calc))) && p('') && e('1'); // 测试分组数。
|
||||
|
||||
r($calc->getResult(array('project' => '7'))) && p('0:value') && e('-0.3492'); // 测试项目7。
|
||||
r($metric->getReuseCalcResult($calc, array('project' => '1', 'year' => '2024', 'week' => '05'))) && p('0:value') && e('1.0905'); // 测试项目7。
|
||||
Reference in New Issue
Block a user