diff --git a/api/v1/entries/reports.php b/api/v1/entries/reports.php index 7d415b25a9..75ffa215a1 100644 --- a/api/v1/entries/reports.php +++ b/api/v1/entries/reports.php @@ -66,15 +66,20 @@ class reportsEntry extends entry } elseif($field == 'output') { - $this->loadModel('report'); - $storyStat = $this->report->getYearObjectStat($accounts, $year, 'story'); - $report['output']['story'] = $this->processStatus($storyStat['statusStat'], 'story'); + $report['output'] = $this->loadModel('report')->getOutput4API($accounts, $year); } } return $this->send(200, $report); } + /** + * Get project overview by status. + * + * @param array $accounts + * @access public + * @return array + */ public function projectOverview($accounts) { $statusOverview = $this->loadModel('report')->getProjectStatusOverview(array_keys($accounts)); @@ -100,6 +105,14 @@ class reportsEntry extends entry return $projectOverview; } + /** + * Get radar data. include product, execution, qa, devel and other. + * + * @param array $accounts + * @param string $year + * @access public + * @return array + */ public function radar($accounts, $year) { $allAccounts = $this->loadModel('user')->getPairs('noletter|noclosed'); @@ -127,6 +140,12 @@ class reportsEntry extends entry return array_values($radar); } + /** + * Get project progress. + * + * @access public + * @return array + */ public function projectProgress() { $projects = $this->loadModel('program')->getProjectStats(0, 'all'); @@ -166,6 +185,12 @@ class reportsEntry extends entry return array('statusList' => $statusList, 'projects' => array_values($processedProjects)); } + /** + * Get execution progress. + * + * @access public + * @return array + */ public function executionProgress() { $executions = $this->loadModel('project')->getStats(0, 'all', 0, 0, 30, 'id_desc'); @@ -205,10 +230,17 @@ class reportsEntry extends entry return array('statusList' => $statusList, 'executions' => array_values($processedExecutions)); } + /** + * Get product progress with story. + * + * @access public + * @return array + */ public function productProgress() { $this->app->loadLang('product'); $this->app->loadLang('story'); + $storyStatusStat = $this->dao->select('t1.product,t2.name,t2.status,t1.status as storyStatus,count(*) as storyCount')->from(TABLE_STORY)->alias('t1') ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id') ->where('t2.deleted')->eq(0) @@ -240,6 +272,7 @@ class reportsEntry extends entry if(isset($productStatusList[$product->status])) $productStatusList[$product->status]['total'] += 1; } + /* Set story status statistics integrate into product. */ $storyStatusList = array('draft' => array(), 'active' => array(), 'changed' => array(), 'closed' => array()); foreach($processedProducts as $productID => $product) { @@ -268,10 +301,17 @@ class reportsEntry extends entry return array('productStatusList' => $productStatusList, 'products' => array_values($processedProducts), 'storyStatusList' => $storyStatusList); } + /** + * Get bug progress by product. + * + * @access public + * @return array + */ public function bugProgress() { $this->app->loadLang('product'); $this->app->loadLang('bug'); + $bugStatusStat = $this->dao->select('t1.product,t2.name,t2.status,t1.status as bugStatus,count(*) as bugCount')->from(TABLE_BUG)->alias('t1') ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id') ->where('t2.deleted')->eq(0) @@ -286,7 +326,7 @@ class reportsEntry extends entry $productStatusList['closed']['total'] = 0; $processedProducts = array(); - $productBugStat = array(); + $productBugStat = array(); foreach($bugStatusStat as $product) { $productBugStat[$product->product][$product->bugStatus] = $product->bugCount; @@ -303,6 +343,7 @@ class reportsEntry extends entry if(isset($productStatusList[$product->status])) $productStatusList[$product->status]['total'] += 1; } + /* Set bug status statistics integrate into product. */ $bugStatusList = array('active' => array(), 'resolved' => array(), 'closed' => array()); foreach($processedProducts as $productID => $product) { @@ -330,23 +371,4 @@ class reportsEntry extends entry return array('productStatusList' => $productStatusList, 'bugs' => array_values($processedProducts), 'bugStatusList' => $bugStatusList); } - - public function processStatus($statusStat, $objectType) - { - $this->app->loadLang($objectType); - - $processedStatus = array(); - $total = 0; - foreach($this->lang->$objectType->statusList as $status => $statusName) - { - if(empty($statusStat[$status])) continue; - - $processedStatus[$status]['code'] = $status; - $processedStatus[$status]['name'] = $statusName; - $processedStatus[$status]['total'] = $statusStat[$status]; - $total += $statusStat[$status]; - } - - return array('total' => $total, 'statusList' => array_values($processedStatus)); - } } diff --git a/module/report/config.php b/module/report/config.php index 9bd447e755..ef44d7a72f 100644 --- a/module/report/config.php +++ b/module/report/config.php @@ -54,3 +54,11 @@ $config->report->annualData['month']['story'] = array('opened' => 'create', 'act $config->report->annualData['month']['task'] = array('opened' => 'create', 'started' => 'start', 'finished' => 'finish', 'paused' => 'pause', 'activated' => 'activate', 'canceled' => 'cancel', 'closed' => 'close'); $config->report->annualData['month']['bug'] = array('opened' => 'create', 'bugconfirmed' => 'confirm', 'activated' => 'activate', 'resolved' => 'resolve', 'closed' => 'close'); $config->report->annualData['month']['case'] = array('opened' => 'create', 'run' => 'run', 'createBug' => 'createBug'); + +$config->report->outputData['story'] = array('opened' => 'create', 'changed' => 'change', 'reviewed' => 'review', 'closed' => 'close'); +$config->report->outputData['productplan'] = array('opened' => 'create'); +$config->report->outputData['release'] = array('opened' => 'create', 'stoped' => 'stop', 'activated' => 'activate'); +$config->report->outputData['execution'] = array('opened' => 'create', 'started' => 'start', 'delayed' => 'putoff', 'suspended' => 'suspend', 'closed' => 'close'); +$config->report->outputData['task'] = array('opened' => 'create', 'assigned' => 'assign', 'finished' => 'finish', 'activated' => 'activate', 'closed' => 'close'); +$config->report->outputData['bug'] = array('opened' => 'create', 'resolved' => 'resolve', 'activated' => 'activate', 'closed' => 'close'); +$config->report->outputData['case'] = array('opened' => 'create', 'run' => 'run', 'createBug' => 'createBug'); diff --git a/module/report/lang/zh-cn.php b/module/report/lang/zh-cn.php index 428efdce3a..0d84257637 100644 --- a/module/report/lang/zh-cn.php +++ b/module/report/lang/zh-cn.php @@ -193,6 +193,10 @@ $lang->report->annualData->actionList['assign'] = '指派'; $lang->report->annualData->actionList['activate'] = '激活'; $lang->report->annualData->actionList['resolve'] = '解决'; $lang->report->annualData->actionList['run'] = '执行'; +$lang->report->annualData->actionList['stop'] = '停止维护'; + +$lang->report->annualData->actionList['putoff'] = '延期'; +$lang->report->annualData->actionList['suspend'] = '挂起'; $lang->report->annualData->actionList['change'] = '变更'; $lang->report->annualData->actionList['pause'] = '暂停'; $lang->report->annualData->actionList['cancel'] = '取消'; diff --git a/module/report/model.php b/module/report/model.php index fe4d60004b..a558bbe421 100644 --- a/module/report/model.php +++ b/module/report/model.php @@ -1063,6 +1063,71 @@ class reportModel extends model return $statusOverview; } + + /** + * Get output data for API. + * + * @param array $accounts + * @param string $year + * @access public + * @return array + */ + public function getOutput4API($accounts, $year) + { + $stmt = $this->dao->select('*')->from(TABLE_ACTION) + ->where('objectType')->in(array_keys($this->config->report->outputData)) + ->andWhere('LEFT(date, 4)')->eq($year) + ->beginIF($accounts)->andWhere('actor')->in($accounts)->fi() + ->query(); + + $outputData = array(); + while($action = $stmt->fetch()) + { + if($action->objectType == 'release' and $action->action == 'changestatus') + { + if($action->extra == 'terminate') $action->action = 'stoped'; + if($action->extra == 'normal') $action->action = 'activated'; + } + + if(!isset($this->config->report->outputData[$action->objectType][$action->action])) continue; + if(!isset($outputData[$action->objectType][$action->action])) $outputData[$action->objectType][$action->action] = 0; + + $outputData[$action->objectType][$action->action] += 1; + } + + $stmt = $this->dao->select('t1.*')->from(TABLE_ACTION)->alias('t1') + ->leftJoin(TABLE_BUG)->alias('t2')->on('t1.objectID=t2.id') + ->where('t1.objectType')->eq('bug') + ->andWhere('t2.deleted')->eq(0) + ->andWhere('LEFT(t1.date, 4)')->eq($year) + ->andWhere('t1.action')->eq('opened') + ->andWhere('t2.case')->ne('0') + ->beginIF($accounts)->andWhere('t1.actor')->in($accounts)->fi() + ->query(); + while($action = $stmt->fetch()) + { + if(!isset($outputData['case']['createBug'])) $outputData['case']['createBug'] = 0; + $outputData['case']['createBug'] += 1; + } + + $processedOutput = array(); + foreach($this->config->report->outputData as $objectType => $actions) + { + $objectActions = $outputData[$objectType]; + $processedOutput[$objectType]['total'] = array_sum($objectActions); + + foreach($actions as $action => $langCode) + { + if(empty($objectActions[$action])) continue; + + $processedOutput[$objectType]['actions'][$langCode]['code'] = $langCode; + $processedOutput[$objectType]['actions'][$langCode]['name'] = $this->lang->report->annualData->actionList[$langCode]; + $processedOutput[$objectType]['actions'][$langCode]['total'] = $objectActions[$action]; + } + } + + return $processedOutput; + } } /**