diff --git a/module/metric/calc/product/qc/count_of_released_bug_in_product.php b/module/metric/calc/product/qc/count_of_released_bug_in_product.php deleted file mode 100755 index d80c29f615..0000000000 --- a/module/metric/calc/product/qc/count_of_released_bug_in_product.php +++ /dev/null @@ -1,166 +0,0 @@ - - * @package - * @uses func - * @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html) - * @Link https://www.zentao.net - */ -class xxx_of_xxx_in_xxx extends baseCalc -{ - /** - * 通用数据源,详情见通用数据源列表。 - */ - public $dataset = null; - - /** - * 通用数据源对应使用的字段,具体字段根据使用的通用数据源来设置。 - * - * 如 public $dataset = "getProjectBugs"; - * 涉及的表有 zt_bug t1, zt_product t2, zt_project t3 - * 那么$fieldList可以使用 zt_bug表、zt_product表、zt_project表的所有字段; - * 例如 public $fieldList = array('t1.resolvedBy', 't1.resolvedDate', 't2.name as productName', 't3.name as projectName'); - */ - public $fieldList = array(); - - /** - * 度量项计算临时结果。 - * - * 如果度量项为单个值, 例如【按全局统计的bug数】, 则为int类型; - * 如果度量项为单个维度, 例如【按产品统计的bug数】, 则为array(productID => value); - * 如果度量项为多个维度 ,例如【按产品统计的每月bug数】,则为array(productID => array(year => array(month => value))); - */ - public $result = array(); - - /** - * 获取自定义数据源pdo句柄。 - * - * 如果设置了通用数据源,该函数将不会被执行; - * 可以使用this->dao进行数据库查询; - * 返回值为PDOStatement。 - */ - public function getStatement() - { - /** - * 例如【按全局统计的有效研发需求数】 - * return $this->dao->select('count(t1.id) as value')->from(TABLE_STORY)->alias('t1') - * ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id') - * ->where('t1.deleted')->eq(0) - * ->andWhere('t2.deleted')->eq(0) - * ->andWhere('t2.shadow')->eq(0) - * ->andWhere('t1.type')->eq('story') - * ->andWhere('t1.closedReason')->notin('duplicate,willnotdo,bydesign,cancel') - * ->query(); - */ - return $this->dao->XXX->query(); - } - - /** - * 计算度量项。 - * - * 对数据源查询得到的数据集进行逐行计算,该函数实现对于一行数据的计算逻辑 - * 计算完成后将数据临时记录到$this->result上 - * - * @param object $row 数据源的一行数据 - */ - public function calculate($row) - { - /** - * 例如【按全局统计的研发需求总数】 - * $this->result += 1; - * - * 例如【按全局统计的未关闭Bug数】 - * if($row->status != 'closed') $this->result += 1; - * - * 例如【按全局统计的月度修复Bug数】 - * $closedDate = $row->closedDate; - * if(empty($closedDate)) return false; - * - * $year = substr($closedDate, 0, 4); - * if($year == '0000') return false; - * $month = substr($closedDate, 5, 2); - * - * if(!isset($this->result[$year])) $this->result[$year] = array(); - * if(!isset($this->result[$year][$month])) $this->result[$year][$month] = 0; - * if($row->status == 'closed' and $row->resolution == 'fixed') $this->result[$year][$month] += 1; - */ - } - - /** - * 汇总并获取度量项计算结果。 - * - * @param array $options 筛选参数,如果不传参,则返回度量项所有数据 - * 产品id为5: array('product' => '5') - * 产品id为5,6,7: array('product' => '5,6,7') - * 产品id为5,年份为2023年:array('product' => '5', 'year' => '2023') - */ - public function getResult($options = array()) - { - /** - * $this->getRecords($keys) 将 $this->result拍平为 - * array(product => 1, year => 2023, month => 03) - * $keys为拍平后的键值数组,需要与$this->result的层级顺序保持一致。 - * - * 例如【按全局统计的bug数】 - * $this->result = 200; - * $this->getRecords(array('value')); - * 逻辑等同于 - * $records = array(array('value' => $this->result = 200)); - * - * 例如【按产品统计的bug数】 - * $this->result = array(1 => 25, 2 => 33, 5 => 21, ...); - * $this->getRecords(array('product', 'value')); - * 逻辑等同于 - * $records = array(); - * foreach($this->result as $product => $value) - * { - * $records[] = array('product' => $product, 'value' => $value); - * } - * - * 例如【按产品统计的每月bug数】 - * $this->result = array - * ( - * 1 => array - * ( - * 2023 => array(08 => 21, 12 => 44, ...), - * 2022 => array(08 => 63, 12 => 29, ...), - * ... - * ), - * 2 => array - * ( - * 2023 => array(04 => 21, 10 => 44, ...), - * 2022 => array(05 => 63, 07 => 29, ...), - * ... - * ), - * ... - * ); - * $this->getRecords(array('product', 'year', 'month', 'value')); - * 逻辑等同于 - * $records = array(); - * foreach($this->result as $product => $years) - * { - * foreach($years as $year => $months) - * { - * foreach($months as $month => $value) - * { - * $records[] = array('product' => $product, 'year' => $year, 'month' => $month, 'value' => $value); - * } - * } - * } - */ - $records = $this->getRecords(array('value')); - return $this->filterByOptions($records, $options); - } -} diff --git a/module/metric/calc/product/qc/rate_of_approved_story_in_product.php b/module/metric/calc/product/qc/rate_of_approved_story_in_product.php index 4c1d8a7a39..7165fad48e 100755 --- a/module/metric/calc/product/qc/rate_of_approved_story_in_product.php +++ b/module/metric/calc/product/qc/rate_of_approved_story_in_product.php @@ -20,35 +20,33 @@ */ class rate_of_approved_story_in_product extends baseCalc { - public $result = array(); + public $dataset = 'getDevStoriesWithReview'; - public function getStatement() - { - return $this->dao->select("COUNT(t1.result) as total, SUM(CASE WHEN result = 'pass' THEN 1 ELSE 0 END) as pass, t2.product") - ->from(TABLE_STORYREVIEW)->alias('t1') - ->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story=t2.id') - ->leftJoin(TABLE_PRODUCT)->alias('t3')->on('t2.product=t3.id') - ->where('t2.deleted')->eq(0) - ->andWhere('t3.deleted')->eq(0) - ->andWhere('t2.type')->eq('story') - ->andWhere('t3.shadow')->eq(0) - ->andWhere("t3.vision NOT LIKE '%or%'") - ->andWhere("t3.vision NOT LIKE '%lite%'") - ->groupBy('t2.product') - ->query(); - } + public $fieldList = array('t2.product', 't1.result'); + + public $result = array(); public function calculate($row) { - $total = $row->total; - $pass = $row->pass; + $result = $row->result; $product = $row->product; - $this->result[$product] = $total == 0 ? 0 : round($pass / $total, 4); + if(!isset($this->result[$product])) $this->result[$product] = array('total' => 0, 'pass' => 0); + + $this->result[$product]['total'] += 1; + if($result == 'pass') $this->result[$product]['pass'] += 1; } public function getResult($options = array()) { + foreach($this->result as $product => $rate) + { + if(!isset($rate['total']) || !isset($rate['pass'])) continue; + $pass = $rate['pass']; + $total = $rate['total']; + + $this->result[$product] = $total == 0 ? 0 : round($pass / $total, 4); + } $records = $this->getRecords(array('product', 'value')); return $this->filterByOptions($records, $options); } diff --git a/module/metric/calc/product/scale/case_coverage_of_projected_story_in_product.php b/module/metric/calc/product/scale/case_coverage_of_projected_story_in_product.php index da346fe037..d4aaefb89a 100755 --- a/module/metric/calc/product/scale/case_coverage_of_projected_story_in_product.php +++ b/module/metric/calc/product/scale/case_coverage_of_projected_story_in_product.php @@ -20,41 +20,33 @@ */ class case_coverage_of_projected_story_in_product extends baseCalc { - public $idList = array(); + public $dataset = 'getDevStories'; + + public $fieldList = array('t1.product', 't3.case_count'); public $result = array(); - public function getStatement() - { - $caseQuery = $this->dao->select('story, count(DISTINCT id) as case_count')->from(TABLE_CASE) - ->groupBy('story') - ->get(); - - return $this->dao->select('t1.product, COUNT(t1.id) as total, SUM(CASE WHEN t3.case_count > 0 THEN 1 ELSE 0 END) as hasCase')->from(TABLE_STORY)->alias('t1') - ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id') - ->leftJoin("($caseQuery)")->alias('t3')->on('t1.id=t3.story') - ->where('t1.stage')->eq('projected') - ->andWhere('t1.deleted')->eq(0) - ->andWhere('t2.deleted')->eq(0) - ->andWhere('t2.shadow')->eq(0) - ->andWhere("t1.vision NOT LIKE '%or%'") - ->andWhere("t1.vision NOT LIKE '%lite%'") - ->groupBy('t1.product') - ->query(); - } - public function calculate($row) { $product = $row->product; - $total = $row->total; - $hasCase = $row->hasCase; + $case = $row->case_count; - $rate = $total ? round($hasCase / $total, 2) : 0; - $this->result[$product] = $rate; + if(!isset($this->result[$product])) $this->result[$product] = array('total' => 0, 'hasCase' => 0); + + $this->result[$product]['total'] += 1; + $this->result[$product]['hasCase'] += $case > 0 ? 1 : 0; } public function getResult($options = array()) { + foreach($this->result as $product => $rate) + { + if(!isset($rate['total']) || !isset($rate['hasCase'])) continue; + $total = $rate['total']; + $hasCase = $rate['hasCase']; + + $this->result[$product] = $total ? round($hasCase / $total, 2) : 0; + } $records = $this->getRecords(array('product', 'value')); return $this->filterByOptions($records, $options); } diff --git a/module/metric/calc/product/scale/count_of_annual_created_productplan_in_product.php b/module/metric/calc/product/scale/count_of_annual_created_productplan_in_product.php index a370c2deda..9e894cc5a5 100755 --- a/module/metric/calc/product/scale/count_of_annual_created_productplan_in_product.php +++ b/module/metric/calc/product/scale/count_of_annual_created_productplan_in_product.php @@ -20,19 +20,11 @@ */ class count_of_annual_created_productplan_in_product extends baseCalc { - public $result = array(); + public $dataset = 'getPlans'; - public function getStatement() - { - return $this->dao->select('t1.id,t1.product,t1.createdDate')->from(TABLE_PRODUCTPLAN)->alias('t1') - ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id') - ->where('t1.deleted')->eq(0) - ->andWhere('t2.deleted')->eq(0) - ->andWhere('t2.shadow')->eq(0) - ->andWhere("t2.vision NOT LIKE '%or%'") - ->andWhere("t2.vision NOT LIKE '%lite%'") - ->query(); - } + public $fieldList = array('t1.product', 't1.createdDate'); + + public $result = array(); public function calculate($row) { diff --git a/module/metric/calc/product/scale/count_of_annual_finished_productplan_in_product.php b/module/metric/calc/product/scale/count_of_annual_finished_productplan_in_product.php index 95eb72330d..5f5efd3d1f 100755 --- a/module/metric/calc/product/scale/count_of_annual_finished_productplan_in_product.php +++ b/module/metric/calc/product/scale/count_of_annual_finished_productplan_in_product.php @@ -20,19 +20,11 @@ */ class count_of_annual_finished_productplan_in_product extends baseCalc { - public $result = array(); + public $dataset = 'getPlans'; - public function getStatement() - { - return $this->dao->select('t1.id,t1.product,t1.finishedDate')->from(TABLE_PRODUCTPLAN)->alias('t1') - ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id') - ->where('t1.deleted')->eq(0) - ->andWhere('t2.deleted')->eq(0) - ->andWhere('t2.shadow')->eq(0) - ->andWhere("t2.vision NOT LIKE '%or%'") - ->andWhere("t2.vision NOT LIKE '%lite%'") - ->query(); - } + public $fieldList = array('t1.product', 't1.finishedDate'); + + public $result = array(); public function calculate($row) { diff --git a/module/metric/calc/product/scale/count_of_delivered_story_in_product.php b/module/metric/calc/product/scale/count_of_delivered_story_in_product.php index 545906cbcf..690defa7b1 100755 --- a/module/metric/calc/product/scale/count_of_delivered_story_in_product.php +++ b/module/metric/calc/product/scale/count_of_delivered_story_in_product.php @@ -20,32 +20,27 @@ */ class count_of_delivered_story_in_product extends baseCalc { - public $result = array(); + public $dataset = 'getDevStories'; - public function getStatement() - { - return $this->dao->select('t1.product,count(t1.id) as value')->from(TABLE_STORY)->alias('t1') - ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id') - ->where('t1.deleted')->eq(0) - ->andWhere('t2.deleted')->eq(0) - ->andWhere('t2.shadow')->eq(0) - ->andWhere("t1.vision NOT LIKE '%or%'") - ->andWhere("t1.vision NOT LIKE '%lite%'") - ->andWhere('t1.stage', true)->eq('released') - ->orWhere('t1.closedReason')->eq('done') - ->markRight(1) - ->groupBy('t1.product') - ->query(); - } + public $fieldList = array('t1.product', 't1.stage', 't1.closedReason'); + + public $result = array(); public function calculate($row) { - $this->result[] = $row; + $stage = $row->stage; + $product = $row->product; + $closedReason = $row->closedReason; + + if($stage != 'released' && $closedReason != 'done') return false; + + if(!isset($this->result[$row->product])) $this->result[$row->product] = 0; + $this->result[$row->product] += 1; } public function getResult($options = array()) { - $records = $this->result; + $records = $this->getRecords(array('product', 'value')); return $this->filterByOptions($records, $options); } } diff --git a/module/metric/calc/product/scale/count_of_developed_story_in_product.php b/module/metric/calc/product/scale/count_of_developed_story_in_product.php index bb7a52a776..81363818bb 100755 --- a/module/metric/calc/product/scale/count_of_developed_story_in_product.php +++ b/module/metric/calc/product/scale/count_of_developed_story_in_product.php @@ -20,27 +20,20 @@ */ class count_of_developed_story_in_product extends baseCalc { - public $result = array(); + public $dataset = 'getDevStories'; - public function getStatement() - { - return $this->dao->select('t1.product,count(t1.id) as value')->from(TABLE_STORY)->alias('t1') - ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id') - ->where('t1.deleted')->eq(0) - ->andWhere('t2.deleted')->eq(0) - ->andWhere('t2.shadow')->eq(0) - ->andWhere('t1.type')->eq('story') - ->andWhere("t1.vision NOT LIKE '%or%'") - ->andWhere("t1.vision NOT LIKE '%lite%'") - ->andWhere('t1.stage', true)->in('developed,testing,tested,verified,released') - ->orWhere('t1.closedReason')->eq('done') - ->markRight(1) - ->groupBy('t1.product') - ->query(); - } + public $fieldList = array('t1.product', 't1.stage', 't1.closedReason'); + + public $result = array(); public function calculate($row) { + $stage = $row->stage; + $product = $row->product; + $closedReason = $row->closedReason; + + if(!in_array($stage, array('developed', 'testing', 'tested', 'verified', 'released')) && $closedReason != 'done') return false; + if(!isset($this->result[$row->product])) $this->result[$row->product] = 0; $this->result[$row->product] += 1; } diff --git a/module/metric/calc/product/scale/count_of_invalid_story_in_product.php b/module/metric/calc/product/scale/count_of_invalid_story_in_product.php index 86cb9fcc74..10bf1a7e7c 100755 --- a/module/metric/calc/product/scale/count_of_invalid_story_in_product.php +++ b/module/metric/calc/product/scale/count_of_invalid_story_in_product.php @@ -20,31 +20,26 @@ */ class count_of_invalid_story_in_product extends baseCalc { - public $result = array(); + public $dataset = 'getDevStories'; - public function getStatement() - { - return $this->dao->select('t1.product,count(t1.id) as value')->from(TABLE_STORY)->alias('t1') - ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id') - ->where('t1.deleted')->eq(0) - ->andWhere('t2.deleted')->eq(0) - ->andWhere('t1.type')->eq('story') - ->andWhere('t2.shadow')->eq(0) - ->andWhere('t1.closedReason')->in('duplicate,willnotdo,bydesign,cancel') - ->andWhere("t1.vision NOT LIKE '%or%'") - ->andWhere("t1.vision NOT LIKE '%lite%'") - ->groupBy('t1.product') - ->query(); - } + public $fieldList = array('t1.product', 't1.closedReason'); + + public $result = array(); public function calculate($row) { - $this->result[] = $row; + $product = $row->product; + $closedReason = $row->closedReason; + + if(!in_array($closedReason, array('duplicate', 'willnotdo', 'bydesign', 'cancel'))) return false; + + if(!isset($this->result[$product])) $this->result[$product] = 0; + $this->result[$product] += 1; } public function getResult($options = array()) { - $records = $this->result; + $records = $this->getRecords(array('product', 'value')); return $this->filterByOptions($records, $options); } } diff --git a/module/metric/calc/product/scale/count_of_projected_story_in_product.php b/module/metric/calc/product/scale/count_of_projected_story_in_product.php index f7f1a8e178..9800062454 100755 --- a/module/metric/calc/product/scale/count_of_projected_story_in_product.php +++ b/module/metric/calc/product/scale/count_of_projected_story_in_product.php @@ -20,27 +20,21 @@ */ class count_of_projected_story_in_product extends baseCalc { - public $result = array(); + public $dataset = 'getDevStoriesWithProject'; - public function getStatement() - { - return $this->dao->select("COUNT(DISTINCT t1.story) as 'value', t1.product") - ->from(TABLE_PROJECTSTORY)->alias('t1') - ->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story=t2.id') - ->leftJoin(TABLE_PRODUCT)->alias('t3')->on('t1.product=t3.id') - ->where('t2.deleted')->eq('0') - ->andWhere('t3.deleted')->eq('0') - ->andWhere("t3.vision NOT LIKE '%or%'") - ->andWhere("t3.vision NOT LIKE '%lite%'") - ->groupBy('t1.product'); - } + public $fieldList = array('t2.id as product', 't3.story'); + + public $result = array(); public function calculate($row) { $product = $row->product; - $value = $row->value; + $story = $row->story; - $this->result[$product] = $value; + if(empty($story)) return false; + + if(!isset($this->result[$product])) $this->result[$product] = 0; + $this->result[$product] += 1; } public function getResult($options = array()) diff --git a/module/metric/calc/product/scale/count_of_projected_story_with_case_in_product.php b/module/metric/calc/product/scale/count_of_projected_story_with_case_in_product.php index 1962bad4c3..faa6477dfe 100755 --- a/module/metric/calc/product/scale/count_of_projected_story_with_case_in_product.php +++ b/module/metric/calc/product/scale/count_of_projected_story_with_case_in_product.php @@ -20,32 +20,28 @@ */ class count_of_projected_story_with_case_in_product extends baseCalc { - public $result = array(); + public $dataset = 'getCasesWithStory'; - public function getStatement() - { - return $this->dao->select("COUNT(DISTINCT t1.story) as 'value', t1.product") - ->from(TABLE_CASE)->alias('t0') - ->leftJoin(TABLE_PROJECTSTORY)->alias('t1')->on('t1.story=t0.story') - ->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story=t2.id') - ->leftJoin(TABLE_PRODUCT)->alias('t3')->on('t1.product=t3.id') - ->where('t2.deleted')->eq('0') - ->andWhere('t3.deleted')->eq('0') - ->andWhere("t2.vision NOT LIKE '%or%'") - ->andWhere("t2.vision NOT LIKE '%lite%'") - ->groupBy('t1.product'); - } + public $fieldList = array('t1.product', 't1.story'); + + public $result = array(); public function calculate($row) { $product = $row->product; - $value = $row->value; + $story = $row->story; - $this->result[$product] = $value; + if(!isset($this->result[$product])) $this->result[$product] = array(); + $this->result[$product][$story] = $story; } public function getResult($options = array()) { + foreach($this->result as $product => $stories) + { + if(!is_array($stories)) continue; + $this->result[$product] = count($stories); + } $records = $this->getRecords(array('product', 'value')); return $this->filterByOptions($records, $options); } diff --git a/module/metric/calc/product/scale/count_of_valid_story_in_product.php b/module/metric/calc/product/scale/count_of_valid_story_in_product.php index 63037f05c4..557c843723 100755 --- a/module/metric/calc/product/scale/count_of_valid_story_in_product.php +++ b/module/metric/calc/product/scale/count_of_valid_story_in_product.php @@ -20,24 +20,19 @@ */ class count_of_valid_story_in_product extends baseCalc { - public $result = array(); + public $dataset = 'getDevStories'; - public function getStatement() - { - return $this->dao->select('t1.product,t1.id')->from(TABLE_STORY)->alias('t1') - ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id') - ->where('t1.deleted')->eq(0) - ->andWhere('t2.deleted')->eq(0) - ->andWhere('t2.shadow')->eq(0) - ->andWhere('t1.type')->eq('story') - ->andWhere('t1.closedReason')->notin('duplicate,willnotdo,bydesign,cancel') - ->andWhere("t2.vision NOT LIKE '%or%'") - ->andWhere("t2.vision NOT LIKE '%lite%'") - ->query(); - } + public $fieldList = array('t1.product', 't1.closedReason'); + + public $result = array(); public function calculate($row) { + $closedReason = $row->closedReason; + $product = $row->product; + + if(in_array($closedReason, array('duplicate', 'willnotdo', 'bydesign', 'cancel'))) return false; + if(!isset($this->result[$row->product])) $this->result[$row->product] = 0; $this->result[$row->product] += 1; } diff --git a/module/metric/calc/project/hour/ac_of_all_in_waterfall.php b/module/metric/calc/project/hour/ac_of_all_in_waterfall.php index 3be8674fe6..e2990b08ce 100755 --- a/module/metric/calc/project/hour/ac_of_all_in_waterfall.php +++ b/module/metric/calc/project/hour/ac_of_all_in_waterfall.php @@ -20,29 +20,22 @@ */ class ac_of_all_in_waterfall extends baseCalc { - public $result = array(); + public $dataset = 'getProjectEfforts'; - public function getStatement() - { - return $this->dao->select('t3.id as project, SUM(t1.consumed) as ac') - ->from(TABLE_EFFORT)->alias('t1') - ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.execution=t2.id') - ->leftJoin(TABLE_PROJECT)->alias('t3')->on('t2.project=t3.id') - ->where('t3.deleted')->eq('0') - ->andWhere('t3.type')->eq('project') - ->andWhere('t3.model')->in('waterfall,waterfallplus') - ->andWhere("t3.vision NOT LIKE '%or%'") - ->andWhere("t3.vision NOT LIKE '%lite%'") - ->groupBy('t3.id') - ->query(); - } + public $fieldList = array('t3.id as project', 't1.consumed', 't3.model'); + + public $result = array(); public function calculate($row) { $project = $row->project; - $ac = $row->ac; + $ac = $row->consumed; + $model = $row->model; - if(!isset($this->result[$project])) $this->result[$project] = $ac; + if($model != 'waterfall' && $model != 'waterfallplus') return false; + + if(!isset($this->result[$project])) $this->result[$project] = 0; + $this->result[$project] += $ac; } public function getResult($options = array()) diff --git a/module/metric/calc/project/hour/consume_of_all_in_project.php b/module/metric/calc/project/hour/consume_of_all_in_project.php index a3f1ade0c0..afc45a53b5 100755 --- a/module/metric/calc/project/hour/consume_of_all_in_project.php +++ b/module/metric/calc/project/hour/consume_of_all_in_project.php @@ -20,28 +20,19 @@ */ class consume_of_all_in_project extends baseCalc { - public $result = array(); + public $dataset = 'getProjectEfforts'; - public function getStatement() - { - return $this->dao->select('t3.id as project, SUM(t1.consumed) as consumed') - ->from(TABLE_EFFORT)->alias('t1') - ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.execution=t2.id') - ->leftJoin(TABLE_PROJECT)->alias('t3')->on('t2.project=t3.id') - ->where('t3.deleted')->eq('0') - ->andWhere('t3.type')->eq('project') - ->andWhere("t3.vision NOT LIKE '%or%'") - ->andWhere("t3.vision NOT LIKE '%lite%'") - ->groupBy('t3.id') - ->query(); - } + public $fieldList = array('t3.id as project', 't1.consumed'); + + public $result = array(); public function calculate($row) { $project = $row->project; $consumed = $row->consumed; - if(!isset($this->result[$project])) $this->result[$project] = $consumed; + if(!isset($this->result[$project])) $this->result[$project] = 0; + $this->result[$project] += $consumed; } public function getResult($options = array()) diff --git a/module/metric/calc/project/hour/day_of_invested_in_project.php b/module/metric/calc/project/hour/day_of_invested_in_project.php index ef612f254c..6a75196fc0 100755 --- a/module/metric/calc/project/hour/day_of_invested_in_project.php +++ b/module/metric/calc/project/hour/day_of_invested_in_project.php @@ -20,40 +20,29 @@ */ class day_of_invested_in_project extends baseCalc { + public $dataset = 'getProjectEfforts'; + + public $fieldList = array('t3.id as project', 't1.consumed'); + public $result = array(); - public function getStatement() - { - $defaultHours = $this->dao->select('value') - ->from(TABLE_CONFIG) - ->where('module')->eq('execution') - ->andWhere('key')->eq('defaultWorkhours') - ->fetch('value'); - if(empty($defaultHours)) $defaultHours = 7; - - return $this->dao->select("t3.id as project, SUM(t1.consumed) as consumed, $defaultHours as defaultHours") - ->from(TABLE_EFFORT)->alias('t1') - ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.execution=t2.id') - ->leftJoin(TABLE_PROJECT)->alias('t3')->on('t2.project=t3.id') - ->where('t3.deleted')->eq('0') - ->andWhere('t3.type')->eq('project') - ->andWhere("t3.vision NOT LIKE '%or%'") - ->andWhere("t3.vision NOT LIKE '%lite%'") - ->groupBy('t3.id') - ->query(); - } - public function calculate($row) { $project = $row->project; $consumed = $row->consumed; $defaultHours = $row->defaultHours; - if(!isset($this->result[$project])) $this->result[$project] = $defaultHours ? round($consumed / $defaultHours, 2) : 0; + if(!isset($this->result[$project])) $this->result[$project] = 0; + + $this->result[$project] += $defaultHours ? $consumed / $defaultHours : 0; } public function getResult($options = array()) { + foreach($this->result as $project => $days) + { + $this->result[$project] = round($days, 2); + } $records = $this->getRecords(array('project', 'value')); return $this->filterByOptions($records, $options); } diff --git a/module/metric/calc/project/hour/ev_of_finished_task_in_waterfall.php b/module/metric/calc/project/hour/ev_of_finished_task_in_waterfall.php index f2cb583148..d812ae6b36 100755 --- a/module/metric/calc/project/hour/ev_of_finished_task_in_waterfall.php +++ b/module/metric/calc/project/hour/ev_of_finished_task_in_waterfall.php @@ -20,33 +20,12 @@ */ class ev_of_finished_task_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 getStatement() - { - $ev = $this->dao->select('project, SUM(estimate) as estimate, SUM(consumed) as consumed, SUM(`left`) as `left`') - ->from(TABLE_TASK) - ->where('deleted')->eq('0') - ->andWhere('parent')->ne('-1') - ->andWhere("vision NOT LIKE '%or%'") - ->andWhere("vision NOT LIKE '%lite%'") - ->andWhere('status', true)->in('done,closed') - ->orWhere('closedReason')->eq('done') - ->markRight(1) - ->groupBy('project') - ->get(); - - return $this->dao->select('t1.id as project, t2.estimate, t2.consumed, t2.`left`') - ->from(TABLE_PROJECT)->alias('t1') - ->leftJoin("($ev)")->alias('t2')->on('t1.id=t2.project') - ->where('t1.deleted')->eq('0') - ->andWhere('t1.type')->eq('project') - ->andWhere('t1.model')->in('waterfall,waterfallplus') - ->andWhere("t1.vision NOT LIKE '%or%'") - ->andWhere("t1.vision NOT LIKE '%lite%'") - ->query(); - } - public function calculate($row) { $project = $row->project; diff --git a/module/metric/calc/project/hour/pv_of_task_in_waterfall.php b/module/metric/calc/project/hour/pv_of_task_in_waterfall.php index 23b550e712..335ef72945 100755 --- a/module/metric/calc/project/hour/pv_of_task_in_waterfall.php +++ b/module/metric/calc/project/hour/pv_of_task_in_waterfall.php @@ -20,37 +20,16 @@ */ class pv_of_task_in_waterfall extends baseCalc { + public $dataset = 'getWaterfallTasks'; + + public $fieldList = array('t1.id as project', 't2.estimate'); + public $result = array(); - public function getStatement() - { - $pv = $this->dao->select('project, SUM(estimate) as estimate') - ->from(TABLE_TASK) - ->where('deleted')->eq('0') - ->andWhere('parent')->ne('-1') - ->andWhere("vision NOT LIKE '%or%'") - ->andWhere("vision NOT LIKE '%lite%'") - ->andWhere('status', true)->in('done,closed') - ->orWhere('closedReason')->eq('done') - ->markRight(1) - ->groupBy('project') - ->get(); - - return $this->dao->select('t1.id as project, t2.estimate as pv') - ->from(TABLE_PROJECT)->alias('t1') - ->leftJoin("($pv)")->alias('t2')->on('t1.id=t2.project') - ->where('t1.deleted')->eq('0') - ->andWhere('t1.type')->eq('project') - ->andWhere('t1.model')->in('waterfall,waterfallplus') - ->andWhere("t1.vision NOT LIKE '%or%'") - ->andWhere("t1.vision NOT LIKE '%lite%'") - ->query(); - } - public function calculate($row) { $project = $row->project; - $pv = $row->pv; + $pv = $row->estimate; if(!isset($this->result[$project])) $this->result[$project] = $pv; } diff --git a/module/metric/calc/project/rate/cv_in_waterfall.php b/module/metric/calc/project/rate/cv_in_waterfall.php index ed3d098b76..14d40e2e48 100755 --- a/module/metric/calc/project/rate/cv_in_waterfall.php +++ b/module/metric/calc/project/rate/cv_in_waterfall.php @@ -20,41 +20,12 @@ */ class cv_in_waterfall extends baseCalc { + public $dataset = 'getWaterfallTasks'; + + public $fieldList = array('t1.id as project', 't2.estimate', 't2.consumed', 't2.`left`', 't3.consumed as ac'); + public $result = array(); - public function getStatement() - { - $ev = $this->dao->select('project, SUM(estimate) as estimate, SUM(consumed) as consumed, SUM(`left`) as `left`') - ->from(TABLE_TASK) - ->where('deleted')->eq('0') - ->andWhere('parent')->ne('-1') - ->andWhere("vision NOT LIKE '%or%'") - ->andWhere("vision NOT LIKE '%lite%'") - ->andWhere('status', true)->in('done,closed') - ->orWhere('closedReason')->eq('done') - ->markRight(1) - ->groupBy('project') - ->get(); - - $ac = $this->dao->select('t3.id as project, SUM(t1.consumed) as consumed') - ->from(TABLE_EFFORT)->alias('t1') - ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.execution=t2.id') - ->leftJoin(TABLE_PROJECT)->alias('t3')->on('t2.project=t3.id') - ->where("t3.vision NOT LIKE '%or%'") - ->andWhere("t3.vision NOT LIKE '%lite%'") - ->groupBy('t3.id') - ->get(); - - return $this->dao->select('t1.id as project, t2.estimate, t2.consumed, t2.`left`, t3.consumed as ac') - ->from(TABLE_PROJECT)->alias('t1') - ->leftJoin("($ev)")->alias('t2')->on('t1.id=t2.project') - ->leftJoin("($ac)")->alias('t3')->on('t1.id=t3.project') - ->where('t1.deleted')->eq('0') - ->andWhere('t1.type')->eq('project') - ->andWhere('t1.model')->in('waterfall,waterfallplus') - ->query(); - } - public function calculate($row) { $project = $row->project; diff --git a/module/metric/calc/project/rate/sv_in_waterfall.php b/module/metric/calc/project/rate/sv_in_waterfall.php index ae65e40009..cf27aaadb6 100755 --- a/module/metric/calc/project/rate/sv_in_waterfall.php +++ b/module/metric/calc/project/rate/sv_in_waterfall.php @@ -20,33 +20,12 @@ */ 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 getStatement() - { - $task = $this->dao->select('project, SUM(estimate) as estimate, SUM(consumed) as consumed, SUM(`left`) as `left`') - ->from(TABLE_TASK) - ->where('deleted')->eq('0') - ->andWhere('parent')->ne('-1') - ->andWhere("vision NOT LIKE '%or%'") - ->andWhere("vision NOT LIKE '%lite%'") - ->andWhere('status', true)->in('done,closed') - ->orWhere('closedReason')->eq('done') - ->markRight(1) - ->groupBy('project') - ->get(); - - return $this->dao->select('t1.id as project, t2.estimate, t2.consumed, t2.`left`') - ->from(TABLE_PROJECT)->alias('t1') - ->leftJoin("($task)")->alias('t2')->on('t1.id=t2.project') - ->where('t1.deleted')->eq('0') - ->andWhere('t1.type')->eq('project') - ->andWhere('t1.model')->in('waterfall,waterfallplus') - ->andWhere("t1.vision NOT LIKE '%or%'") - ->andWhere("t1.vision NOT LIKE '%lite%'") - ->query(); - } - public function calculate($row) { $project = $row->project; diff --git a/module/metric/calc/project/scale/count_of_user_in_project.php b/module/metric/calc/project/scale/count_of_user_in_project.php index 713d4b3420..f4ab72f927 100755 --- a/module/metric/calc/project/scale/count_of_user_in_project.php +++ b/module/metric/calc/project/scale/count_of_user_in_project.php @@ -20,32 +20,28 @@ */ class count_of_user_in_project extends baseCalc { - public $result = array(); + public $dataset = 'getTeamMembers'; - public function getStatement() - { - return $this->dao->select('t3.id as project, COUNT(DISTINCT account) as value') - ->from(TABLE_TEAM)->alias('t1') - ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t2.id=t1.root') - ->leftJoin(TABLE_PROJECT)->alias('t3')->on('t3.id=t2.project') - ->where('t1.type')->eq('execution') - ->andWhere('t2.deleted')->eq(0) - ->andWhere('t3.deleted')->eq(0) - ->andWhere("t3.vision NOT LIKE '%or%'") - ->andWhere("t3.vision NOT LIKE '%lite%'") - ->groupBy('t3.id') - ->query(); - } + public $fieldList = array('t3.id as project', 't1.account'); + + public $result = array(); public function calculate($row) { $project = $row->project; - $value = $row->value; - $this->result[$project] = $value; + $account = $row->account; + + if(!isset($this->result[$project])) $this->result[$project] = array(); + $this->result[$project][$account] = $account; } public function getResult($options = array()) { + foreach($this->result as $project => $users) + { + if(!is_array($users)) continue; + $this->result[$project] = count($users); + } $records = $this->getRecords(array('project', 'value')); return $this->filterByOptions($records, $options); } diff --git a/module/metric/calc/system/hour/consume_of_annual_closed_project.php b/module/metric/calc/system/hour/consume_of_annual_closed_project.php index 6049bc2f8e..ab2b641466 100755 --- a/module/metric/calc/system/hour/consume_of_annual_closed_project.php +++ b/module/metric/calc/system/hour/consume_of_annual_closed_project.php @@ -20,41 +20,20 @@ */ class consume_of_annual_closed_project extends baseCalc { - public $dataset = null; + public $dataset = 'getProjectTasks'; - public $fieldList = array(); + public $fieldList = array('t1.closedDate', 't2.consumed', 't1.id as project', 't1.status'); public $result = array(); - public function getStatement() - { - $task = $this->dao->select('SUM(consumed) as consumed, project') - ->from(TABLE_TASK) - ->where('deleted')->eq('0') - ->andWhere('parent')->ne('-1') - ->andWhere("vision NOT LIKE '%or%'") - ->andWhere("vision NOT LIKE '%lite%'") - ->groupBy('project') - ->get(); - - return $this->dao->select('t1.id as project, t1.closedDate, t2.consumed') - ->from(TABLE_PROJECT)->alias('t1') - ->leftJoin("($task)")->alias('t2')->on('t1.id = t2.project') - ->where('t1.type')->eq('project') - ->andWhere('t1.status')->eq('closed') - ->andWhere('t1.deleted')->eq('0') - ->andWhere('t1.closedDate')->notZeroDatetime() - ->andWhere("t1.vision NOT LIKE '%or%'") - ->andWhere("t1.vision NOT LIKE '%lite%'") - ->query(); - } - public function calculate($data) { $project = $data->project; $year = substr($data->closedDate, 0, 4); $consumed = $data->consumed; + $status = $data->status; + if($status != 'closed') return false; if(empty($year) || $year == '0000') return false; if(!is_numeric($consumed) || empty($consumed)) return false; diff --git a/module/metric/calc/system/hour/consume_of_monthly_closed_project.php b/module/metric/calc/system/hour/consume_of_monthly_closed_project.php index 67b6564688..e716d9a172 100755 --- a/module/metric/calc/system/hour/consume_of_monthly_closed_project.php +++ b/module/metric/calc/system/hour/consume_of_monthly_closed_project.php @@ -20,41 +20,20 @@ */ class consume_of_monthly_closed_project extends baseCalc { - public $dataset = null; + public $dataset = 'getProjectTasks'; - public $fieldList = array(); + public $fieldList = array('t1.closedDate', 't2.consumed', 't1.id as project', 't1.status'); public $result = array(); - public function getStatement() - { - $task = $this->dao->select('SUM(consumed) as consumed, project') - ->from(TABLE_TASK) - ->where('deleted')->eq('0') - ->andWhere('parent')->ne('-1') - ->andWhere("vision NOT LIKE '%or%'") - ->andWhere("vision NOT LIKE '%lite%'") - ->groupBy('project') - ->get(); - - return $this->dao->select('t1.id as project, t1.closedDate, t2.consumed') - ->from(TABLE_PROJECT)->alias('t1') - ->leftJoin("($task)")->alias('t2')->on('t1.id = t2.project') - ->where('t1.type')->eq('project') - ->andWhere('t1.status')->eq('closed') - ->andWhere('t1.deleted')->eq('0') - ->andWhere('t1.closedDate IS NOT NULL') - ->andWhere("t1.vision NOT LIKE '%or%'") - ->andWhere("t1.vision NOT LIKE '%lite%'") - ->query(); - } - public function calculate($data) { $project = $data->project; $year = substr($data->closedDate, 0, 4); $consumed = $data->consumed; + $status = $data->status; + if($status != 'closed') return false; if(empty($year) || $year == '0000') return false; $month = substr($data->closedDate, 5, 2); diff --git a/module/metric/calc/system/hour/day_of_annual_closed_project.php b/module/metric/calc/system/hour/day_of_annual_closed_project.php index 1a72685ea1..f7a361d0d3 100755 --- a/module/metric/calc/system/hour/day_of_annual_closed_project.php +++ b/module/metric/calc/system/hour/day_of_annual_closed_project.php @@ -20,62 +20,39 @@ */ class day_of_annual_closed_project extends baseCalc { - public $dataset = null; + public $dataset = 'getProjectTasks'; - public $fieldList = array(); + public $fieldList = array('t1.closedDate', 't2.consumed', 't1.id as project', 't1.status'); public $result = array(); - public function getStatement() - { - $task = $this->dao->select('SUM(consumed) as consumed, project') - ->from(TABLE_TASK) - ->where('deleted')->eq('0') - ->andWhere('parent')->ne('-1') - ->andWhere("vision NOT LIKE '%or%'") - ->andWhere("vision NOT LIKE '%lite%'") - ->groupBy('project') - ->get(); - - return $this->dao->select('t1.id as project, t1.closedDate, t2.consumed') - ->from(TABLE_PROJECT)->alias('t1') - ->leftJoin("($task)")->alias('t2')->on('t1.id = t2.project') - ->where('t1.type')->eq('project') - ->andWhere('t1.status')->eq('closed') - ->andWhere('t1.deleted')->eq('0') - ->andWhere('t1.closedDate')->notZeroDatetime() - ->andWhere("t1.vision NOT LIKE '%or%'") - ->andWhere("t1.vision NOT LIKE '%lite%'") - ->query(); - } - public function calculate($data) { $project = $data->project; $year = substr($data->closedDate, 0, 4); $consumed = $data->consumed; + $status = $data->status; + $defaultHours = $data->defaultHours; + if($status != 'closed') return false; if(empty($year) || $year == '0000') return false; - if(!is_numeric($consumed) || empty($consumed)) return false; - if(!isset($this->result[$year])) $this->result[$year] = array(); + if(!isset($this->result[$year][$project])) $this->result[$year][$project] = 0; - $this->result[$year][$project] = round($consumed, 2); + $this->result[$year][$project] += $defaultHours ? $consumed / $defaultHours : 0; } public function getResult($options = array()) { - $defaultWorkhours = $this->dao->select('value')->from(TABLE_CONFIG)->where('`key`')->eq('defaultWorkhours')->fetch(); - $records = array(); foreach($this->result as $year => $projects) { - foreach($projects as $project => $value) + foreach($projects as $project => $days) { - $value = $defaultWorkhours ? round($value / $defaultWorkhours->value, 4) : 0; - $records[] = array('project' => $project, 'year' => $year, 'value' => $value); + $this->result[$year][$project] = round($days, 4); } } + $records = getRecords(array('year', 'project', 'value')); return $this->filterByOptions($records, $options); } } diff --git a/module/metric/calc/system/hour/day_of_annual_effort.php b/module/metric/calc/system/hour/day_of_annual_effort.php index a32f477bf4..9ecd5e6947 100755 --- a/module/metric/calc/system/hour/day_of_annual_effort.php +++ b/module/metric/calc/system/hour/day_of_annual_effort.php @@ -20,27 +20,19 @@ */ class day_of_annual_effort extends baseCalc { + public $dataset = 'getEfforts'; + + public $fieldList = array('t1.date', 't1.consumed'); + public $result = array(); - public function getStatement() - { - $defaultHours = $this->dao->select('value') - ->from(TABLE_CONFIG) - ->where('module')->eq('execution') - ->andWhere('key')->eq('defaultWorkhours') - ->fetch('value'); - if(empty($defaultHours)) $defaultHours = 7; - - return $this->dao->select("`date`, `consumed`, $defaultHours as defaultHours") - ->from(TABLE_EFFORT) - ->where('deleted')->eq('0') - ->andWhere('date')->notZeroDate() - ->query(); - } - public function calculate($row) { - $year = substr($row->date, 0, 4); + if(empty($row->date)) return false; + + $year = substr($row->date, 0, 4); + if($year == '0000') return false; + $consumed = $row->consumed; $defaultHours = $row->defaultHours; diff --git a/module/metric/calc/system/hour/day_of_daily_effort.php b/module/metric/calc/system/hour/day_of_daily_effort.php index e07a001dfa..56387fde9d 100755 --- a/module/metric/calc/system/hour/day_of_daily_effort.php +++ b/module/metric/calc/system/hour/day_of_daily_effort.php @@ -20,28 +20,20 @@ */ class day_of_daily_effort extends baseCalc { + public $dataset = 'getEfforts'; + + public $fieldList = array('t1.date', 't1.consumed'); + public $result = array(); - public function getStatement() - { - $defaultHours = $this->dao->select('value') - ->from(TABLE_CONFIG) - ->where('module')->eq('execution') - ->andWhere('key')->eq('defaultWorkhours') - ->fetch('value'); - if(empty($defaultHours)) $defaultHours = 7; - - return $this->dao->select("`date`, `consumed`, $defaultHours as defaultHours") - ->from(TABLE_EFFORT) - ->where('deleted')->eq('0') - ->andWhere('date')->notZeroDate() - ->query(); - } - public function calculate($row) { - $date = $row->date; - $year = substr($date, 0, 4); + $date = $row->date; + if(empty($date)) return false; + + $year = substr($date, 0, 4); + if($year == '0000') return false; + $month = substr($date, 5, 2); $day = substr($date, 8, 2); $consumed = $row->consumed; diff --git a/module/metric/calc/system/hour/hour_of_annual_effort.php b/module/metric/calc/system/hour/hour_of_annual_effort.php index ca65e6f407..123c8e56ba 100755 --- a/module/metric/calc/system/hour/hour_of_annual_effort.php +++ b/module/metric/calc/system/hour/hour_of_annual_effort.php @@ -20,21 +20,20 @@ */ class hour_of_annual_effort extends baseCalc { - public $result = array(); + public $dataset = 'getEfforts'; - public function getStatement() - { - return $this->dao->select("`date`, `consumed`") - ->from(TABLE_EFFORT) - ->where('deleted')->eq('0') - ->andWhere('date')->notZeroDate() - ->query(); - } + public $fieldList = array('t1.date', 't1.consumed'); + + public $result = array(); public function calculate($row) { - $year = substr($row->date, 0, 4); - $consumed = $row->consumed; + if(empty($row->date)) return false; + + $year = substr($row->date, 0, 4); + if($year == '0000') return false; + + $consumed = $row->consumed; if(!isset($this->result[$year])) $this->result[$year] = 0; $this->result[$year] += $consumed; diff --git a/module/metric/calc/system/hour/hour_of_daily_effort.php b/module/metric/calc/system/hour/hour_of_daily_effort.php index 09688a0d9e..1701b220fd 100755 --- a/module/metric/calc/system/hour/hour_of_daily_effort.php +++ b/module/metric/calc/system/hour/hour_of_daily_effort.php @@ -20,21 +20,22 @@ */ class hour_of_daily_effort extends baseCalc { - public $result = array(); + public $dataset = 'getEfforts'; - public function getStatement() - { - return $this->dao->select("`date`, `consumed`") - ->from(TABLE_EFFORT) - ->where('deleted')->eq('0') - ->andWhere('date')->notZeroDate() - ->query(); - } + public $fieldList = array('t1.date', 't1.consumed'); + + public $result = array(); public function calculate($row) { - $date = $row->date; - $year = substr($date, 0, 4); + $date = $row->date; + + if(empty($date)) return false; + + $year = substr($date, 0, 4); + + if($year == '0000') return false; + $month = substr($date, 5, 2); $day = substr($date, 8, 2); $consumed = $row->consumed; diff --git a/module/metric/calc/system/scale/count_of_daily_run_case.php b/module/metric/calc/system/scale/count_of_daily_run_case.php index e047f58410..3a35fad096 100755 --- a/module/metric/calc/system/scale/count_of_daily_run_case.php +++ b/module/metric/calc/system/scale/count_of_daily_run_case.php @@ -20,21 +20,11 @@ */ class count_of_daily_run_case extends baseCalc { - public $result = array(); + public $dataset = 'getTestResults'; - public function getStatement() - { - return $this->dao->select('t1.`date` as `date`, t1.id') - ->from(TABLE_TESTRESULT)->alias('t1') - ->leftJoin(TABLE_CASE)->alias('t2')->on('t1.`case`=t2.id') - ->leftJoin(TABLE_PRODUCT)->alias('t3')->on('t2.product=t3.id') - ->where('t2.deleted')->eq('0') - ->andWhere('t3.deleted')->eq('0') - ->andWhere('t1.date')->notZeroDatetime() - ->andWhere("t3.vision NOT LIKE '%or%'") - ->andWhere("t3.vision NOT LIKE '%lite%'") - ->query(); - } + public $fieldList = array('t1.id', 't1.`date`'); + + public $result = array(); public function calculate($row) { diff --git a/module/metric/calc/system/scale/count_of_invalid_story.php b/module/metric/calc/system/scale/count_of_invalid_story.php index 2240c69072..537e34951e 100755 --- a/module/metric/calc/system/scale/count_of_invalid_story.php +++ b/module/metric/calc/system/scale/count_of_invalid_story.php @@ -20,24 +20,18 @@ */ class count_of_invalid_story extends baseCalc { - public $result = 0; + public $dataset = 'getAllDevStories'; - public function getStatement() - { - return $this->dao->select('count(t1.id) as value')->from(TABLE_STORY)->alias('t1') - ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id') - ->where('t1.deleted')->eq(0) - ->andWhere('t2.deleted')->eq(0) - ->andWhere('t1.type')->eq('story') - ->andWhere('t1.closedReason')->in('duplicate,willnotdo,bydesign') - ->andWhere("t1.vision NOT LIKE '%or%'") - ->andWhere("t1.vision NOT LIKE '%lite%'") - ->query(); - } + public $fieldList = array('t1.id', 't1.closedReason'); + + public $result = 0; public function calculate($data) { - $this->result = $data->value; + $closedReason = $data->closedReason; + + if(!in_array($closedReason, array('duplicate', 'willnotdo', 'bydesign'))) return false; + $this->result += 1; } public function getResult($options = array()) diff --git a/module/metric/calc/system/scale/count_of_valid_story.php b/module/metric/calc/system/scale/count_of_valid_story.php index 3effec1d7b..6ce367b9ba 100755 --- a/module/metric/calc/system/scale/count_of_valid_story.php +++ b/module/metric/calc/system/scale/count_of_valid_story.php @@ -20,24 +20,19 @@ */ class count_of_valid_story extends baseCalc { - public $result = 0; + public $dataset = 'getAllDevStories'; - public function getStatement() - { - return $this->dao->select('count(t1.id) as value')->from(TABLE_STORY)->alias('t1') - ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id') - ->where('t1.deleted')->eq(0) - ->andWhere('t2.deleted')->eq(0) - ->andWhere('t1.type')->eq('story') - ->andWhere('t1.closedReason')->notin('duplicate,willnotdo,bydesign,cancel') - ->andWhere("t1.vision NOT LIKE '%or%'") - ->andWhere("t1.vision NOT LIKE '%lite%'") - ->query(); - } + public $fieldList = array('t1.id', 't1.closedReason'); + + public $result = 0; public function calculate($row) { - $this->result = $row->value; + $closedReason = $row->closedReason; + + if(in_array($closedReason, array('duplicate', 'willnotdo', 'bydesign', 'cancel'))) return false; + + $this->result += 1; } public function getResult($options = array()) diff --git a/module/metric/calc/user/scale/count_of_assigned_case_in_user.php b/module/metric/calc/user/scale/count_of_assigned_case_in_user.php index d82731915c..e437e40ac1 100755 --- a/module/metric/calc/user/scale/count_of_assigned_case_in_user.php +++ b/module/metric/calc/user/scale/count_of_assigned_case_in_user.php @@ -20,23 +20,17 @@ */ class count_of_assigned_case_in_user extends baseCalc { - public $result = array(); + public $dataset = 'getTestRuns'; - public function getStatement() - { - return $this->dao->select('t1.assignedTo')->from(TABLE_TESTRUN)->alias('t1') - ->leftJoin(TABLE_CASE)->alias('t2')->on('t1.`case` = t2.id') - ->leftJoin(TABLE_TESTTASK)->alias('t3')->on('t1.task = t3.id') - ->where('t3.deleted')->eq(0) - ->andWhere('t2.deleted')->eq(0) - ->andWhere('t3.status')->ne('done') - ->query(); - } + public $fieldList = array('t1.assignedTo', 't3.status'); + + public $result = array(); public function calculate($row) { $assignedTo = $row->assignedTo; + if($row->status == 'done') return false; if(empty($assignedTo) || $assignedTo == 'closed') return false; if(!isset($this->result[$assignedTo])) $this->result[$assignedTo] = 0; diff --git a/module/metric/calc/user/scale/count_of_reviewing_story_in_user.php b/module/metric/calc/user/scale/count_of_reviewing_story_in_user.php index c69914d139..f02b8068a1 100755 --- a/module/metric/calc/user/scale/count_of_reviewing_story_in_user.php +++ b/module/metric/calc/user/scale/count_of_reviewing_story_in_user.php @@ -20,31 +20,23 @@ */ class count_of_reviewing_story_in_user extends baseCalc { - public $result = array(); + public $dataset = 'getDevStoriesWithReview'; - public function getStatement() - { - return $this->dao->select('t3.reviewer, t3.story, t3.version') - ->from(TABLE_STORY)->alias('t1') - ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id') - ->leftJoin(TABLE_STORYREVIEW)->alias('t3')->on('t1.id=t3.story and t1.version=t3.version') - ->where('t1.deleted')->eq('0') - ->andWhere('t2.deleted')->eq('0') - ->andWhere('t1.type')->eq('story') - ->andWhere('t1.status')->in('reviewing,changing') - ->andWhere('t3.result')->eq('') - ->andWhere("t2.vision NOT LIKE '%or%'") - ->andWhere("t2.vision NOT LIKE '%lite%'") - ->query(); - } + public $fieldList = array('t1.reviewer', 't1.story', 't1.version', 't2.status', 't1.result'); + + public $result = array(); public function calculate($row) { $reviewer = $row->reviewer; $story = $row->story; $version = $row->version; + $status = $row->status; + $result = $row->result; if(empty($reviewer)) return false; + if($status != 'reviewing' and $status != 'changing') return false; + if(!empty($result)) return false; if(!isset($this->result[$story])) { diff --git a/module/metric/dataset.php b/module/metric/dataset.php index c6ec946b93..4fe945e304 100644 --- a/module/metric/dataset.php +++ b/module/metric/dataset.php @@ -172,6 +172,8 @@ class dataset ->where('t1.deleted')->eq(0) ->andWhere('t2.deleted')->eq(0) ->andWhere('t2.shadow')->eq(0) + ->andWhere("t2.vision NOT LIKE '%or%'") + ->andWhere("t2.vision NOT LIKE '%lite%'") ->query(); } @@ -352,7 +354,6 @@ class dataset ->where('t1.deleted')->eq(0) ->andWhere('t2.deleted')->eq(0) ->andWhere('t1.type')->eq('story') - ->andWhere('t2.shadow')->eq(0) ->andWhere('t4.deleted')->eq(0) ->andWhere('t4.type')->eq('project') ->andWhere("t1.vision NOT LIKE '%or%'") @@ -370,9 +371,15 @@ class dataset */ public function getDevStories($fieldList) { + $caseQuery = $this->dao->select('story, count(DISTINCT id) as case_count') + ->from(TABLE_CASE) + ->groupBy('story') + ->get(); + return $this->dao->select($fieldList) ->from(TABLE_STORY)->alias('t1') ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id') + ->leftJoin("($caseQuery)")->alias('t3')->on('t1.id=t3.story') ->where('t1.deleted')->eq(0) ->andWhere('t2.deleted')->eq(0) ->andWhere('t1.type')->eq('story') @@ -466,6 +473,28 @@ class dataset ->query(); } + /** + * 获取关联用例的研发需求数据。 + * Get story list with case. + * + * @param string $fieldList + * @access public + * @return PDOStatement + */ + public function getCasesWithStory($fieldList) + { + return $this->dao->select($fieldList) + ->from(TABLE_CASE)->alias('t0') + ->leftJoin(TABLE_PROJECTSTORY)->alias('t1')->on('t1.story=t0.story') + ->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story=t2.id') + ->leftJoin(TABLE_PRODUCT)->alias('t3')->on('t1.product=t3.id') + ->where('t2.deleted')->eq('0') + ->andWhere('t3.deleted')->eq('0') + ->andWhere("t2.vision NOT LIKE '%or%'") + ->andWhere("t2.vision NOT LIKE '%lite%'") + ->query(); + } + /** * 获取产品数据。 * Get product list. @@ -693,10 +722,10 @@ class dataset } /** - * 统计mr信息。 - * Get merge request data. + * 统计合并请求信息。 + * Get merge requests. * - * @param string $fieldList + * @param string $fieldList * @access public * @return PDOStatement */ @@ -708,4 +737,201 @@ class dataset ->andWhere('t2.deleted')->eq('0') ->query(); } + + /** + * 统计团队成员信息。 + * Get team members. + * + * @param string $fieldList + * @access public + * @return PDOStatement + */ + public function getTeamMembers($fieldList) + { + return $this->dao->select($fieldList) + ->from(TABLE_TEAM)->alias('t1') + ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t2.id=t1.root') + ->leftJoin(TABLE_PROJECT)->alias('t3')->on('t3.id=t2.project') + ->where('t1.type')->eq('execution') + ->andWhere('t2.deleted')->eq(0) + ->andWhere('t3.deleted')->eq(0) + ->andWhere("t3.vision NOT LIKE '%or%'") + ->andWhere("t3.vision NOT LIKE '%lite%'") + ->query(); + } + + /** + * 统计日志信息。 + * Get effort. + * + * @param string $fieldList + * @access public + * @return PDOStatement + */ + public function getEfforts($fieldList) + { + $defaultHours = $this->dao->select('value') + ->from(TABLE_CONFIG) + ->where('module')->eq('execution') + ->andWhere('key')->eq('defaultWorkhours') + ->fetch('value'); + if(empty($defaultHours)) $defaultHours = 7; + + return $this->dao->select("$fieldList, $defaultHours as defaultHours") + ->from(TABLE_EFFORT)->alias('t1') + ->where('t1.deleted')->eq('0') + ->query(); + } + + /** + * 统计项目日志信息。 + * Get project effort. + * + * @param string $fieldList + * @access public + * @return PDOStatement + */ + public function getProjectEfforts($fieldList) + { + $defaultHours = $this->dao->select('value') + ->from(TABLE_CONFIG) + ->where('module')->eq('execution') + ->andWhere('key')->eq('defaultWorkhours') + ->fetch('value'); + if(empty($defaultHours)) $defaultHours = 7; + + return $this->dao->select("$fieldList, $defaultHours as defaultHours") + ->from(TABLE_EFFORT)->alias('t1') + ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.execution=t2.id') + ->leftJoin(TABLE_PROJECT)->alias('t3')->on('t2.project=t3.id') + ->where('t3.deleted')->eq('0') + ->andWhere('t3.type')->eq('project') + ->andWhere("t3.vision NOT LIKE '%or%'") + ->andWhere("t3.vision NOT LIKE '%lite%'") + ->query(); + } + + /** + * 统计瀑布项目任务信息。 + * Get waterfall tasks. + * + * @param string $fieldList + * @access public + * @return PDOStatement + */ + public function getWaterfallTasks($fieldList) + { + $task = $this->dao->select('project, SUM(estimate) as estimate, SUM(consumed) as consumed, SUM(`left`) as `left`') + ->from(TABLE_TASK) + ->where('deleted')->eq('0') + ->andWhere('parent')->ne('-1') + ->andWhere("vision NOT LIKE '%or%'") + ->andWhere("vision NOT LIKE '%lite%'") + ->andWhere('status', true)->in('done,closed') + ->orWhere('closedReason')->eq('done') + ->markRight(1) + ->groupBy('project') + ->get(); + + $effort = $this->dao->select('t3.id as project, SUM(t1.consumed) as consumed') + ->from(TABLE_EFFORT)->alias('t1') + ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.execution=t2.id') + ->leftJoin(TABLE_PROJECT)->alias('t3')->on('t2.project=t3.id') + ->where("t3.vision NOT LIKE '%or%'") + ->andWhere("t3.vision NOT LIKE '%lite%'") + ->groupBy('t3.id') + ->get(); + + return $this->dao->select($fieldList) + ->from(TABLE_PROJECT)->alias('t1') + ->leftJoin("($task)")->alias('t2')->on('t1.id=t2.project') + ->leftJoin("($effort)")->alias('t3')->on('t1.id=t3.project') + ->where('t1.deleted')->eq('0') + ->andWhere('t1.type')->eq('project') + ->andWhere('t1.model')->in('waterfall,waterfallplus') + ->andWhere("t1.vision NOT LIKE '%or%'") + ->andWhere("t1.vision NOT LIKE '%lite%'") + ->query(); + } + + /** + * 统计测试用例结果信息。 + * Get test results. + * + * @param string $fieldList + * @access public + * @return PDOStatement + */ + public function getTestresults($fieldList) + { + return $this->dao->select($fieldList) + ->from(TABLE_TESTRESULT)->alias('t1') + ->leftJoin(TABLE_CASE)->alias('t2')->on('t1.`case`=t2.id') + ->leftJoin(TABLE_PRODUCT)->alias('t3')->on('t2.product=t3.id') + ->where('t2.deleted')->eq('0') + ->andWhere('t3.deleted')->eq('0') + ->andWhere("t3.vision NOT LIKE '%or%'") + ->andWhere("t3.vision NOT LIKE '%lite%'") + ->query(); + } + + /** + * 统计研发需求评审信息。 + * + * @param string $fieldList + * @access public + * @return PDOStatement + */ + public function getDevStoriesWithReview($fieldList) + { + return $this->dao->select($fieldList) + ->from(TABLE_STORYREVIEW)->alias('t1') + ->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story=t2.id') + ->leftJoin(TABLE_PRODUCT)->alias('t3')->on('t2.product=t3.id') + ->where('t2.deleted')->eq(0) + ->andWhere('t3.deleted')->eq(0) + ->andWhere('t2.type')->eq('story') + ->andWhere("t3.vision NOT LIKE '%or%'") + ->andWhere("t3.vision NOT LIKE '%lite%'") + ->query(); + } + + public function getProjectTasks($fieldList) + { + $defaultHours = $this->dao->select('value') + ->from(TABLE_CONFIG) + ->where('module')->eq('execution') + ->andWhere('key')->eq('defaultWorkhours') + ->fetch('value'); + if(empty($defaultHours)) $defaultHours = 7; + + $task = $this->dao->select('SUM(consumed) as consumed, project') + ->from(TABLE_TASK) + ->where('deleted')->eq('0') + ->andWhere('parent')->ne('-1') + ->andWhere("vision NOT LIKE '%or%'") + ->andWhere("vision NOT LIKE '%lite%'") + ->groupBy('project') + ->get(); + + return $this->dao->select("$fieldList, $defaultHours as defaultHours") + ->from(TABLE_PROJECT)->alias('t1') + ->leftJoin("($task)")->alias('t2')->on('t1.id = t2.project') + ->where('t1.type')->eq('project') + ->andWhere('t1.deleted')->eq('0') + ->andWhere("t1.vision NOT LIKE '%or%'") + ->andWhere("t1.vision NOT LIKE '%lite%'") + ->query(); + } + + public function getTestRuns($fieldList) + { + return $this->dao->select($fieldList) + ->from(TABLE_TESTRUN)->alias('t1') + ->leftJoin(TABLE_CASE)->alias('t2')->on('t1.`case` = t2.id') + ->leftJoin(TABLE_TESTTASK)->alias('t3')->on('t1.task = t3.id') + ->where('t3.deleted')->eq(0) + ->andWhere('t2.deleted')->eq(0) + ->query(); + } } diff --git a/module/metric/test/calc/product/scale/count_of_developed_story_in_product.php b/module/metric/test/calc/product/scale/count_of_developed_story_in_product.php index c877cdb04e..76f0f20202 100755 --- a/module/metric/test/calc/product/scale/count_of_developed_story_in_product.php +++ b/module/metric/test/calc/product/scale/count_of_developed_story_in_product.php @@ -8,8 +8,8 @@ timeout=0 cid=1 - 测试分组数 @5 -- 测试产品1已开发的需求数第0条的value属性 @1 -- 测试产品3已开发的需求数第0条的value属性 @1 +- 测试产品1已开发的需求数第0条的value属性 @80 +- 测试产品3已开发的需求数第0条的value属性 @80 - 测试已删除产品4已开发的需求数第0条的value属性 @0 - 测试不存在的产品下的需求数 @0 @@ -24,7 +24,7 @@ $metric = new metricTest(); $calc = $metric->calcMetric(__FILE__); r(count($calc->getResult())) && p('') && e('5'); // 测试分组数 -r($calc->getResult(array('product' => '1'))) && p('0:value') && e('1'); // 测试产品1已开发的需求数 -r($calc->getResult(array('product' => '3'))) && p('0:value') && e('1'); // 测试产品3已开发的需求数 +r($calc->getResult(array('product' => '1'))) && p('0:value') && e('80'); // 测试产品1已开发的需求数 +r($calc->getResult(array('product' => '3'))) && p('0:value') && e('80'); // 测试产品3已开发的需求数 r($calc->getResult(array('product' => '4'))) && p('0:value') && e('0'); // 测试已删除产品4已开发的需求数 r($calc->getResult(array('product' => '9999'))) && p('') && e('0'); // 测试不存在的产品下的需求数 \ No newline at end of file diff --git a/module/metric/test/calc/product/scale/count_of_projected_story_in_product.php b/module/metric/test/calc/product/scale/count_of_projected_story_in_product.php index 6f97e2255d..6d737f3906 100755 --- a/module/metric/test/calc/product/scale/count_of_projected_story_in_product.php +++ b/module/metric/test/calc/product/scale/count_of_projected_story_in_product.php @@ -14,6 +14,7 @@ include dirname(__FILE__, 7) . '/test/lib/init.php'; include dirname(__FILE__, 4) . '/calc.class.php'; zdTable('product')->config('product', true, 4)->gen(10); +zdTable('project')->config('project', true, 4)->gen(10); zdTable('story')->config('story_status_closedreason', true, 4)->gen(1000); zdTable('projectstory')->config('projectstory', true, 4)->gen(1000); diff --git a/module/metric/test/calc/user/scale/count_of_delayed_bug_in_user.php b/module/metric/test/calc/user/scale/count_of_delayed_bug_in_user.php index 5a6f21e2e2..d248c24739 100755 --- a/module/metric/test/calc/user/scale/count_of_delayed_bug_in_user.php +++ b/module/metric/test/calc/user/scale/count_of_delayed_bug_in_user.php @@ -8,7 +8,7 @@ timeout=0 cid=1 - 测试分组数。 @4 -- 测试用户dev。第0条的value属性 @18 +- 测试用户dev。第0条的value属性 @39 */ include dirname(__FILE__, 7) . '/test/lib/init.php'; @@ -22,4 +22,4 @@ $calc = $metric->calcMetric(__FILE__); r(count($calc->getResult())) && p('') && e('4'); // 测试分组数。 -r($calc->getResult(array('user' => 'dev'))) && p('0:value') && e('18'); // 测试用户dev。 \ No newline at end of file +r($calc->getResult(array('user' => 'dev'))) && p('0:value') && e('39'); // 测试用户dev。 \ No newline at end of file diff --git a/module/metric/test/model/getcalcinstancelist.php b/module/metric/test/model/getcalcinstancelist.php index 6d9f652301..a14674bd45 100755 --- a/module/metric/test/model/getcalcinstancelist.php +++ b/module/metric/test/model/getcalcinstancelist.php @@ -14,16 +14,16 @@ cid=1 - 第count_of_unclosed_story_in_project条的dataset属性 @getDevStoriesWithProject - 第count_of_unclosed_story_in_project条的id属性 @205 - 测试count_of_user_in_project的数据源和编号 - - 第count_of_user_in_project条的dataset属性 @~~ + - 第count_of_user_in_project条的dataset属性 @getTeamMembers - 第count_of_user_in_project条的id属性 @228 - 测试count_of_valid_story_in_project的数据源和编号 - 第count_of_valid_story_in_project条的dataset属性 @getDevStoriesWithProject - 第count_of_valid_story_in_project条的id属性 @208 - 测试consume_of_all_in_project的数据源和编号 - - 第consume_of_all_in_project条的dataset属性 @~~ + - 第consume_of_all_in_project条的dataset属性 @getProjectEfforts - 第consume_of_all_in_project条的id属性 @229 - 测试ac_of_all_in_waterfall的数据源和编号 - - 第ac_of_all_in_waterfall条的dataset属性 @~~ + - 第ac_of_all_in_waterfall条的dataset属性 @getProjectEfforts - 第ac_of_all_in_waterfall条的id属性 @231 - 测试count_of_pending_story_in_user的数据源和编号 - 第count_of_pending_story_in_user条的dataset属性 @getAllDevStories @@ -39,8 +39,8 @@ $metric = new metricTest(); r($metric->getCalcInstanceList()) && p('count_of_task_in_project:dataset,id') && e('getTasks,213'); // 测试count_of_task_in_project的数据源和编号 r($metric->getCalcInstanceList()) && p('count_of_unclosed_story_in_project:dataset,id') && e('getDevStoriesWithProject,205'); // 测试count_of_unclosed_story_in_project的数据源和编号 -r($metric->getCalcInstanceList()) && p('count_of_user_in_project:dataset,id') && e('~~,228'); // 测试count_of_user_in_project的数据源和编号 +r($metric->getCalcInstanceList()) && p('count_of_user_in_project:dataset,id') && e('getTeamMembers,228'); // 测试count_of_user_in_project的数据源和编号 r($metric->getCalcInstanceList()) && p('count_of_valid_story_in_project:dataset,id') && e('getDevStoriesWithProject,208'); // 测试count_of_valid_story_in_project的数据源和编号 -r($metric->getCalcInstanceList()) && p('consume_of_all_in_project:dataset,id') && e('~~,229'); // 测试consume_of_all_in_project的数据源和编号 -r($metric->getCalcInstanceList()) && p('ac_of_all_in_waterfall:dataset,id') && e('~~,231'); // 测试ac_of_all_in_waterfall的数据源和编号 +r($metric->getCalcInstanceList()) && p('consume_of_all_in_project:dataset,id') && e('getProjectEfforts,229'); // 测试consume_of_all_in_project的数据源和编号 +r($metric->getCalcInstanceList()) && p('ac_of_all_in_waterfall:dataset,id') && e('getProjectEfforts,231'); // 测试ac_of_all_in_waterfall的数据源和编号 r($metric->getCalcInstanceList()) && p('count_of_pending_story_in_user:dataset,id') && e('getAllDevStories,251'); // 测试count_of_pending_story_in_user的数据源和编号 \ No newline at end of file