* finish for task #2899.

This commit is contained in:
wangyidong
2017-03-09 17:21:09 +08:00
parent 5e4bae3022
commit 752a96a5eb
25 changed files with 1230 additions and 17 deletions
+2
View File
@@ -172,6 +172,7 @@ define('TABLE_BLOCK', '`' . $config->db->prefix . 'block`');
define('TABLE_DOCCONTENT', '`' . $config->db->prefix . 'doccontent`');
define('TABLE_TESTSUITE', '`' . $config->db->prefix . 'testsuite`');
define('TABLE_SUITECASE', '`' . $config->db->prefix . 'suitecase`');
define('TABLE_TESTREPORT', '`' . $config->db->prefix . 'testreport`');
if(!defined('TABLE_LANG')) define('TABLE_LANG', '`' . $config->db->prefix . 'lang`');
$config->objectTables['product'] = TABLE_PRODUCT;
@@ -186,6 +187,7 @@ $config->objectTables['case'] = TABLE_CASE;
$config->objectTables['testcase'] = TABLE_CASE;
$config->objectTables['testtask'] = TABLE_TESTTASK;
$config->objectTables['testsuite'] = TABLE_TESTSUITE;
$config->objectTables['testreport'] = TABLE_TESTREPORT;
$config->objectTables['user'] = TABLE_USER;
$config->objectTables['doc'] = TABLE_DOC;
$config->objectTables['doclib'] = TABLE_DOCLIB;
+1
View File
@@ -18,5 +18,6 @@ $config->action->objectNameFields['branch'] = 'name';
$config->action->objectNameFields['module'] = 'name';
$config->action->objectNameFields['testsuite'] = 'name';
$config->action->objectNameFields['testlib'] = 'name';
$config->action->objectNameFields['testreport'] = 'title';
$config->action->commonImgSize = 870;
+1
View File
@@ -63,6 +63,7 @@ $lang->action->objectTypes['branch'] = '分支';
$lang->action->objectTypes['module'] = '模块';
$lang->action->objectTypes['testsuite'] = '套件';
$lang->action->objectTypes['testlib'] = '公共库';
$lang->action->objectTypes['testreport'] = '总结报告';
/* 用来描述操作历史记录。*/
$lang->action->desc = new stdclass();
+12
View File
@@ -36,6 +36,18 @@ class buildModel extends model
return $build;
}
/**
* Get by ID list.
*
* @param array $idList
* @access public
* @return array
*/
public function getByList($idList)
{
return $this->dao->select('*')->from(TABLE_BUILD)->where('id')->in($idList)->fetchAll('id');
}
/**
* Get builds of a project.
*
+1 -1
View File
@@ -214,7 +214,7 @@ $lang->project->menu->story = array('link' => 'Story|project|story|projectID
$lang->project->menu->bug = 'Bug|project|bug|projectID=%s';
$lang->project->menu->dynamic = 'Dynamic|project|dynamic|projectID=%s';
$lang->project->menu->build = array('link' => 'Build|project|build|projectID=%s', 'subModule' => 'build');
$lang->project->menu->testtask = 'Test Task|project|testtask|projectID=%s';
$lang->project->menu->testtask = array('link' => 'Test Task|project|testtask|projectID=%s');
$lang->project->menu->team = array('link' => 'Team|project|team|projectID=%s', 'alias' => 'managemembers');
$lang->project->menu->doc = array('link' => 'Document|doc|objectLibs|type=project&objectID=%s&from=project', 'subModule' => 'doc');
$lang->project->menu->product = $lang->productCommon . '|project|manageproducts|projectID=%s';
+12 -10
View File
@@ -66,16 +66,18 @@ $lang->task->menuOrder = $lang->project->menuOrder;
$lang->build->menuOrder = $lang->project->menuOrder;
/* qa menu order. */
$lang->qa->menuOrder[5] = 'product';
$lang->qa->menuOrder[10] = 'index';
$lang->qa->menuOrder[15] = 'bug';
$lang->qa->menuOrder[20] = 'testcase';
$lang->qa->menuOrder[25] = 'testtask';
$lang->qa->menuOrder[30] = 'testsuite';
$lang->bug->menuOrder = $lang->qa->menuOrder;
$lang->testcase->menuOrder = $lang->bug->menuOrder;
$lang->testtask->menuOrder = $lang->testcase->menuOrder;
$lang->testsuite->menuOrder = $lang->testcase->menuOrder;
$lang->qa->menuOrder[5] = 'product';
$lang->qa->menuOrder[10] = 'index';
$lang->qa->menuOrder[15] = 'bug';
$lang->qa->menuOrder[20] = 'testcase';
$lang->qa->menuOrder[25] = 'testtask';
$lang->qa->menuOrder[30] = 'testsuite';
$lang->qa->menuOrder[35] = 'testreport';
$lang->bug->menuOrder = $lang->qa->menuOrder;
$lang->testcase->menuOrder = $lang->bug->menuOrder;
$lang->testtask->menuOrder = $lang->testcase->menuOrder;
$lang->testsuite->menuOrder = $lang->testcase->menuOrder;
$lang->testreport->menuOrder = $lang->testcase->menuOrder;
/* doc menu order. */
$lang->doc->menuOrder[5] = 'list';
+7 -1
View File
@@ -214,7 +214,7 @@ $lang->project->menu->story = array('link' => '需求|project|story|projectI
$lang->project->menu->bug = 'Bug|project|bug|projectID=%s';
$lang->project->menu->dynamic = '动态|project|dynamic|projectID=%s';
$lang->project->menu->build = array('link' => '版本|project|build|projectID=%s', 'subModule' => 'build');
$lang->project->menu->testtask = '测试|project|testtask|projectID=%s';
$lang->project->menu->testtask = array('link' => '测试|project|testtask|projectID=%s');
$lang->project->menu->team = array('link' => '团队|project|team|projectID=%s', 'alias' => 'managemembers');
$lang->project->menu->doc = array('link' => '文档|doc|objectLibs|type=project&objectID=%s&from=project', 'subModule' => 'doc');
$lang->project->menu->product = $lang->productCommon . '|project|manageproducts|projectID=%s';
@@ -237,6 +237,7 @@ $lang->qa->menu->bug = array('link' => 'Bug|bug|browse|productID=%s');
$lang->qa->menu->testcase = array('link' => '用例|testcase|browse|productID=%s');
$lang->qa->menu->testtask = array('link' => '版本|testtask|browse|productID=%s');
$lang->qa->menu->testsuite = array('link' => '套件|testsuite|browse|productID=%s');
$lang->qa->menu->report = array('link' => '总结报告|testreport|browse|productID=%s');
$lang->qa->menu->testlib = array('link' => '公共库|testsuite|library');
$lang->qa->menu->index = array('link' => "<i class='icon-home'></i>测试主页|qa|index|locate=no&productID=%s", 'float' => 'right');
@@ -248,6 +249,7 @@ $lang->bug->menu->bug = array('link' => 'Bug|bug|browse|productID=%s', 'al
$lang->bug->menu->testcase = array('link' => '用例|testcase|browse|productID=%s');
$lang->bug->menu->testtask = array('link' => '版本|testtask|browse|productID=%s');
$lang->bug->menu->testsuite = array('link' => '套件|testsuite|browse|productID=%s');
$lang->bug->menu->report = array('link' => '总结报告|testreport|browse|productID=%s');
$lang->bug->menu->testlib = array('link' => '公共库|testsuite|library');
$lang->bug->menu->index = array('link' => "<i class='icon-home'></i>测试主页|qa|index|locate=no&productID=%s", 'float' => 'right');
@@ -259,6 +261,7 @@ $lang->testcase->menu->bug = array('link' => 'Bug|bug|browse|productID=%s'
$lang->testcase->menu->testcase = array('link' => '用例|testcase|browse|productID=%s', 'alias' => 'view,create,batchcreate,edit,batchedit,showimport,groupcase,importlib,report', 'subModule' => 'tree');
$lang->testcase->menu->testtask = array('link' => '版本|testtask|browse|productID=%s', 'alias' => 'view,create,edit,linkcase,cases,start,close,batchrun,groupcase');
$lang->testcase->menu->testsuite = array('link' => '套件|testsuite|browse|productID=%s', 'alias' => 'view,create,edit,linkcase');
$lang->testcase->menu->report = array('link' => '总结报告|testreport|browse|productID=%s', 'alias' => 'view,create');
$lang->testcase->menu->testlib = array('link' => '公共库|testsuite|library');
$lang->testcase->menu->index = array('link' => "<i class='icon-home'></i>测试主页|qa|index|locate=no&productID=%s", 'float' => 'right');
@@ -266,6 +269,8 @@ $lang->testtask = new stdclass();
$lang->testtask->menu = $lang->testcase->menu;
$lang->testsuite = new stdclass();
$lang->testsuite->menu = $lang->testcase->menu;
$lang->testreport = new stdclass();
$lang->testreport->menu = $lang->testcase->menu;
$lang->testlib = new stdclass();
$lang->testlib->menu = new stdclass();
@@ -372,6 +377,7 @@ $lang->menugroup->bug = 'qa';
$lang->menugroup->testcase = 'qa';
$lang->menugroup->testtask = 'qa';
$lang->menugroup->testsuite = 'qa';
$lang->menugroup->testreport = 'qa';
$lang->menugroup->people = 'company';
$lang->menugroup->dept = 'company';
$lang->menugroup->todo = 'my';
+6 -2
View File
@@ -18,7 +18,10 @@
<?php echo html::icon($lang->icons['test']);?> <?php echo $lang->testtask->browse;?>
</div>
<div class='actions'>
<?php common::printIcon('testtask', 'create', "product=0&project=$projectID");?>
<?php
common::printIcon('testreport', 'create', "objectID=$projectID&objectType=project", '', 'button','flag');
common::printIcon('testtask', 'create', "product=0&project=$projectID");
?>
</div>
</div>
@@ -32,7 +35,7 @@
<th class='w-100px'><?php echo $lang->testtask->begin;?></th>
<th class='w-100px'><?php echo $lang->testtask->end;?></th>
<th class='w-80px'><?php echo $lang->statusAB;?></th>
<th class='w-100px {sorter:false}'><?php echo $lang->actions;?></th>
<th class='w-120px'><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
@@ -50,6 +53,7 @@
common::printIcon('testtask', 'cases', "taskID=$task->id", '', 'list', 'sitemap');
common::printIcon('testtask', 'linkCase', "taskID=$task->id", '', 'list', 'link');
common::printIcon('testtask', 'edit', "taskID=$task->id", '', 'list');
common::printIcon('testreport', 'create', "objectID=$task->id&objectType=testtask", '', 'list','flag');
if(common::hasPriv('testtask', 'delete'))
{
+2 -2
View File
@@ -476,14 +476,14 @@ class storyModel extends model
{
$this->dao->update(TABLE_PROJECTSTORY)->set('product')->eq($story->product)->where('story')->eq($storyID)->exec();
$storyProjects = $this->dao->select('project')->from(TABLE_PROJECTSTORY)->where('story')->eq($storyID)->orderBy('project')->fetchPairs('project', 'project');
$linkedProjects = $this->dao->select('project')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($storyProjects)->andWhere('product')->eq($story->product)->orderBy('project')->fetchPairs('project','project');
$linkedProjects = $this->dao->select('project')->from(TABLE_PROJECTPRODUCT)->where('project')->in($storyProjects)->andWhere('product')->eq($story->product)->orderBy('project')->fetchPairs('project','project');
$unlinkedProjects = array_diff($storyProjects, $linkedProjects);
foreach($unlinkedProjects as $projectID)
{
$data = new stdclass();
$data->project = $projectID;
$data->product = $story->product;
$this->dao->insert(TABLE_PROJECTPRODUCT)->data($data)->exec();
$this->dao->replace(TABLE_PROJECTPRODUCT)->data($data)->exec();
}
}
return common::createChanges($oldStory, $story);
+6
View File
@@ -0,0 +1,6 @@
<?php
$config->testreport->create = new stdclass();
$config->testreport->create->requiredFields = 'title,owner';
$config->testreport->editor = new stdclass();
$config->testreport->editor->create = array('id' => 'report', 'tools' => 'simpleTools');
+370
View File
@@ -0,0 +1,370 @@
<?php
/**
* The control file of testreport of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package testreport
* @version $Id$
* @link http://www.zentao.net
*/
class testreport extends control
{
/**
* Construct
*
* @param string $moduleName
* @param string $methodName
* @access public
* @return void
*/
public function __construct($moduleName = '', $methodName = '')
{
parent::__construct($moduleName, $methodName);
$this->loadModel('project');
$this->loadModel('product');
$this->loadModel('story');
$this->loadModel('build');
$this->loadModel('bug');
$this->loadModel('tree');
$this->loadModel('testcase');
$this->loadModel('testtask');
$this->loadModel('user');
}
/**
* Browse report.
*
* @param int $objectID
* @param string $objectType
* @param string $extra
* @param string $orderBy
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @access public
* @return void
*/
public function browse($objectID, $objectType = 'product', $extra = '', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
if($objectType != 'product' and $objectType != 'project') die('Type Error!');
if($objectID != $this->commonAction($objectID, $objectType)) die(js::reload());
$this->session->set('reportList', $this->app->getURI(true));
$object = $this->$objectType->getById($objectID);
if($extra) $task = $this->testtask->getById($extra);
$name = $extra ? $task->name : $object->name;
/* Load pager. */
$this->app->loadClass('pager', $static = true);
if($this->app->getViewType() == 'mhtml') $recPerPage = 10;
$pager = pager::init($recTotal, $recPerPage, $pageID);
$reports = $this->testreport->getList($objectID, $objectType, $extra, $orderBy, $pager);
$projects = array();
$tasks = array();
foreach($reports as $report)
{
if($report->objectType == 'project') $projects[$report->objectID] = $report->objectID;
if($report->objectType == 'testtask') $tasks[$report->objectID] = $report->objectID;
}
if($projects) $projects = $this->dao->select('id,name')->from(TABLE_PROJECT)->where('id')->in($projects)->fetchPairs('id', 'name');
if($tasks) $tasks = $this->dao->select('id,name')->from(TABLE_TESTTASK)->where('id')->in($tasks)->fetchPairs('id', 'name');
$this->view->title = $name . $this->lang->colon . $this->lang->testreport->common;
$this->view->position[] = html::a(inlink('browse', "objectID=$objectID&objectType=$objectType&extra=$extra"), $extra ? $task->name : $object->name);
$this->view->position[] = $this->lang->testreport->browse;
$this->view->reports = $reports;
$this->view->orderBy = $orderBy;
$this->view->objectID = $objectID;
$this->view->objectType = $objectType;
$this->view->extra = $extra;
$this->view->pager = $pager;
$this->view->users = $this->user->getPairs('noletter|nodeleted|noclosed');
$this->view->tasks = $tasks;
$this->view->projects = $projects;
$this->display();
}
/**
* Create report.
*
* @param int $objectID
* @param string $objectType
* @access public
* @return void
*/
public function create($objectID, $objectType = 'testtask')
{
if($_POST)
{
$reportID = $this->testreport->create();
if(dao::isError()) die(js::error(dao::getError()));
die(js::locate(inlink('view', "reportID=$reportID"), 'parent'));
}
if($objectType == 'testtask')
{
$task = $this->testtask->getById($objectID);
$productID = $this->commonAction($task->product, 'product');
if($productID != $task->product) die('deny access');
$productIdList[$productID] = $productID;
$begin = $task->begin;
$end = $task->end;
$project = $this->project->getById($task->project);
$builds = array();
if($task->build == 'trunk')
{
$stories = $this->story->getProjectStories($project->id);
$bugs = $this->testreport->getBugs4Test('trunk', $productID, $begin, $end);
}
else
{
$build = $this->build->getById($task->build);
$stories = $this->story->getByList($build->stories);
$builds[$build->id] = $build;
$bugs = $this->testreport->getBugs4Test($builds, $productID, $begin, $end);
}
$tasks = array($task->id => $task);
$owner = $task->owner;
$this->view->title = $task->name . $this->lang->testreport->create;
$this->view->position[] = html::a(inlink('browse', "objectID=$productID&objectType=product&extra={$task->id}"), $task->name);
$this->view->position[] = $this->lang->testreport->create;
$this->view->reportTitle = date('Y-m-d') . " TESTTASK#{$task->id} {$task->name} {$this->lang->testreport->common}";
}
elseif($objectType == 'project')
{
$projectID = $this->commonAction($objectID, 'project');
if($projectID != $objectID) die('deny access');
$project = $this->project->getById($projectID);
$tasks = $this->testtask->getByProject($projectID);
$productIdList = array();
foreach($tasks as $task)
{
$owners[$task->owner] = $task->owner;
$productIdList[$task->product] = $task->product;
}
$stories = $this->story->getProjectStories($project->id);
$builds = $this->build->getProjectBuilds($project->id);
$begin = $project->begin;
$end = $project->end;
$owner = current($owners);
$bugs = $this->testreport->getBugs4Test($builds, $productIdList, $begin, $end, 'project');
$this->view->title = $project->name . $this->lang->testreport->create;
$this->view->position[] = html::a(inlink('browse', "objectID=$projectID&objectType=project"), $project->name);
$this->view->position[] = $this->lang->testreport->create;
$this->view->reportTitle = date('Y-m-d') . " PROJECT#{$project->id} {$project->name} {$this->lang->testreport->common}";
}
$cases = $this->testreport->getTaskCases($tasks);
$bugInfo = $this->testreport->getBugInfo($tasks, $productIdList, $begin, $end, $builds);
$modules = array();
foreach($productIdList as $productID) $modules += $this->tree->getOptionMenu($productID, $viewType = 'bug');
$this->view->begin = $begin;
$this->view->end = $end;
$this->view->members = $this->dao->select('lastRunner')->from(TABLE_TESTRESULT)->where('run')->in(array_keys($tasks))->fetchPairs('lastRunner', 'lastRunner');
$this->view->owner = $owner;
$this->view->stories = $stories;
$this->view->bugs = $bugs;
$this->view->project = $project;
$this->view->productIdList = join(',', array_keys($productIdList));
$this->view->tasks = join(',', array_keys($tasks));
$this->view->storySummary = $this->product->summary($stories);
$this->view->builds = $builds;
$this->view->users = $this->user->getPairs('noletter|nodeleted|noclosed');
$this->view->modules = $modules;
$this->view->cases = $cases;
$this->view->caseSummary = $this->testreport->getResultSummary($tasks, $cases);
$this->view->legacyBugs = $bugInfo['legacyBugs'];
$this->view->bugSeverityGroups = $bugInfo['bugSeverityGroups'];
$this->view->bugStatusGroups = $bugInfo['bugStatusGroups'];
$this->view->bugOpenedByGroups = $bugInfo['bugOpenedByGroups'];
$this->view->bugResolvedByGroups = $bugInfo['bugResolvedByGroups'];
$this->view->bugResolutionGroups = $bugInfo['bugResolutionGroups'];
$this->view->bugModuleGroups = $bugInfo['bugModuleGroups'];
$this->view->bugConfirmedRate = $bugInfo['bugConfirmedRate'];
$this->view->bugCreateByCaseRate = $bugInfo['bugCreateByCaseRate'];
$this->view->objectID = $objectID;
$this->view->objectType = $objectType;
$this->display();
}
/**
* View report.
*
* @param int $reportID
* @access public
* @return void
*/
public function view($reportID)
{
$report = $this->testreport->getById($reportID);
$project = $this->project->getById($report->project);
if($report->objectType == 'testtask')
{
$task = $this->testtask->getById($report->objectID);
$productID = $this->commonAction($task->product, 'product');
if($productID != $task->product) die('deny access');
$browseLink = inlink('browse', "objectID=$productID&objectType=product&extra={$report->objectID}");
$this->view->position[] = html::a($browseLink, $task->name);
}
elseif($report->objectType == 'project')
{
$projectID = $this->commonAction($report->objectID, 'project');
if($projectID != $report->objectID) die('deny access');
$browseLink = inlink('browse', "objectID=$projectID&objectType=project");
$this->view->position[] = html::a($browseLink, $project->name);
}
$stories = $report->stories ? $this->story->getByList($report->stories) : array();
$results = $this->dao->select('*')->from(TABLE_TESTRESULT)->where('run')->in($report->tasks)->andWhere('`case`')->in($report->cases)->fetchAll();
$failResults = array();
$runCasesNum = array();
foreach($results as $result)
{
$runCasesNum[$result->case] = $result->case;
if($result->caseResult == 'fail') $failResults[$result->case] = $result->case;
}
$tasks = $report->tasks ? $this->testtask->getByList($report->tasks) : array();;
$builds = $report->builds ? $this->build->getByList($report->builds) : array();
$cases = $this->testreport->getTaskCases($tasks, $report->cases);
$bugInfo = $this->testreport->getBugInfo($tasks, $report->product, $report->begin, $report->end, $builds);
$modules = array();
foreach(explode(',', $report->product) as $productID) $modules += $this->tree->getOptionMenu($productID, $viewType = 'bug');
$this->view->title = $report->title;
$this->view->browseLink = $browseLink;
$this->view->position[] = $report->title;
$this->view->report = $report;
$this->view->project = $project;
$this->view->stories = $stories;
$this->view->bugs = $report->bugs ? $this->bug->getByList($report->bugs) : array();
$this->view->builds = $builds;
$this->view->cases = $cases;
$this->view->users = $this->user->getPairs('noletter|nodeleted|noclosed');
$this->view->modules = $modules;
$this->view->storySummary = $this->product->summary($stories);
$this->view->caseSummary = $this->testreport->getResultSummary($tasks, $cases);
$this->view->legacyBugs = $bugInfo['legacyBugs'];
$this->view->bugSeverityGroups = $bugInfo['bugSeverityGroups'];
$this->view->bugStatusGroups = $bugInfo['bugStatusGroups'];
$this->view->bugOpenedByGroups = $bugInfo['bugOpenedByGroups'];
$this->view->bugResolvedByGroups = $bugInfo['bugResolvedByGroups'];
$this->view->bugResolutionGroups = $bugInfo['bugResolutionGroups'];
$this->view->bugModuleGroups = $bugInfo['bugModuleGroups'];
$this->view->bugConfirmedRate = $bugInfo['bugConfirmedRate'];
$this->view->bugCreateByCaseRate = $bugInfo['bugCreateByCaseRate'];
$this->display();
}
/**
* Delete report.
*
* @param int $reportID
* @param string $confirm
* @access public
* @return void
*/
public function delete($reportID, $confirm = 'no')
{
if($confirm == 'no')
{
die(js::confirm($this->lang->testreport->confirmDelete, inlink('delete', "reportID=$reportID&confirm=yes")));
}
else
{
$this->testreport->delete(TABLE_TESTREPORT, $reportID);
die(js::locate($this->session->reportList, 'parent'));
}
}
/**
* Export report.
*
* @param int $reportID
* @access public
* @return void
*/
public function export($reportID)
{
if($_POST)
{
$report = $this->testreport->getById($reportID);
$data = fixer::input('post')->get();
$this->session->set('notHead', true);
$output = $this->fetch('testreport', 'view', array('reportID' =>$reportID));
$this->session->set('notHead', false);
$style = <<<EOD
<style>
body{font-size:14px}h1{font-size:16px}
.w-100px{width:100px}.w-p50{width:50%}.w-id{width:70px}.w-pri{width:40px}.w-user{width:80px}.w-80px{width:80px}.w-70px{width:70px}.w-hour[width:57px].w-status{width:60px}.w-130px{width:130px;}.w-type{width:80px}.w-150px{width:150px;}
.text-center{text-align:center}.text-top{vertical-align:top;}.text-left{text-align:left}.text-right{text-align:right;}
.table{width:100%;margin-bottom:5px;border:1px solid #ddd;border-collapse:collapse;border-spacing:0;}
.table caption{padding:8px 20px;border:1px solid #DDD;border-bottom:0;background:#fafafa;}.table td, .table th{border-bottom:1px solid #ddd;padding:5px;}
.table-form{border: none;}.table-form>tbody>tr>th,.table-form>tbody>tr>td{border-bottom:none;}.table-form>tbody>tr>th{text-align:right;}
.input-group{width:100%;}.input-group{position:relative;display:table;border-collapse:separate;}
.input-group-addon:first-child {border-right:0;}
.input-group-addon{background-color:#f5f5f5;padding:6px 12px;font-size:13px;font-weight:400;line-height:1;color:#222;text-align:center;background-color:#e5e5e5;border:1px solid #ccc;border-radius:0;display:table-cell;}
.input-group-addon:first-child{border-top-right-radius:0;border-bottom-right-radius:0;}
</style>
EOD;
$content = "<!DOCTYPE html>\n<html lang='zh-cn'>\n<head>\n<meta charset='utf-8'>\n<title>{$report->title}</title>\n$style</head>\n<body>\n<h1>{$report->title}</h1>\n$output</body></html>";
$this->fetch('file', 'sendDownHeader', array('fileName' => $data->fileName, 'fileType' => $data->fileType, 'content' =>$content));
}
$this->view->customExport = false;
$this->display();
}
/**
* Common action.
*
* @param int $objectID
* @param string $objectType
* @access public
* @return int
*/
public function commonAction($objectID, $objectType = 'product')
{
if($objectType == 'product')
{
$this->products = $this->product->getPairs('nocode');
$productID = $this->product->saveState($objectID, $this->products);
$this->testreport->setMenu($this->products, $productID);
return $productID;
}
elseif($objectType == 'project')
{
$this->projects = $this->project->getPairs('nocode');
$projectID = $this->project->saveState($objectID, $this->projects);
$this->project->setMenu($this->projects, $projectID);
$this->lang->testreport->menu = $this->lang->project->menu;
$this->lang->testreport->menu->testtask['subModule'] = 'testreport';
$this->lang->menugroup->testreport = 'project';
return $projectID;
}
}
}
+38
View File
@@ -0,0 +1,38 @@
<?php
$lang->testreport->common = '测试报告';
$lang->testreport->browse = '报告列表';
$lang->testreport->create = '创建报告';
$lang->testreport->view = '报告详情';
$lang->testreport->recreate = '重新生成报告';
$lang->testreport->title = '标题';
$lang->testreport->startEnd = '起止时间';
$lang->testreport->owner = '负责人';
$lang->testreport->member = '参与人员';
$lang->testreport->stories = '测试的需求';
$lang->testreport->bugs = '测试的Bug';
$lang->testreport->builds = '版本信息';
$lang->testreport->goal = '项目目标';
$lang->testreport->coverage = '需求覆盖率';
$lang->testreport->cases = '用例';
$lang->testreport->bugInfo = '缺陷信息';
$lang->testreport->report = '总结';
$lang->testreport->legacyBugs = '遗留的Bug';
$lang->testreport->createdDate = '创建时间';
$lang->testreport->objectID = '所属对象';
$lang->testreport->value = '值';
$lang->testreport->none = '无';
$lang->testreport->all = '所有报告';
$lang->testreport->bugSeverityGroups = '严重级别分布';
$lang->testreport->bugStatusGroups = '状态分布';
$lang->testreport->bugOpenedByGroups = '创建者分布';
$lang->testreport->bugResolvedByGroups = '解决者分布';
$lang->testreport->bugResolutionGroups = '解决方案分布';
$lang->testreport->bugModuleGroups = '模块分布';
$lang->testreport->legacyBugs = '遗留的Bug';
$lang->testreport->bugConfirmedRate = '有效Bug率';
$lang->testreport->bugCreateByCaseRate = '用例发现Bug率';
$lang->testreport->caseSummary = '共有%s个用例,共执行%s个用例,产生了%s个结果,失败的用例有%s个';
$lang->testreport->confirmDelete = '是否删除该报告?';
+221
View File
@@ -0,0 +1,221 @@
<?php
/**
* The model file of testreport module of ZenTaoCMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package testreport
* @version $Id$
* @link http://www.zentao.net
*/
class testreportModel extends model
{
/**
* Set menu.
*
* @param array $products
* @param int $productID
* @param int $branch
* @access public
* @return void
*/
public function setMenu($products, $productID, $branch = 0)
{
$this->loadModel('product')->setMenu($products, $productID, $branch);
$selectHtml = $this->product->select($products, $productID, 'testreport', 'browse', '', $branch);
foreach($this->lang->testtask->menu as $key => $value)
{
$replace = ($key == 'product') ? $selectHtml : $productID;
common::setMenuVars($this->lang->testreport->menu, $key, $replace);
}
}
/**
* Create report.
*
* @access public
* @return int
*/
public function create()
{
$data = fixer::input('post')
->stripTags($this->config->testreport->editor->create['id'], $this->config->allowedTags)
->add('createdBy', $this->app->user->account)
->add('createdDate', helper::now())
->join('stories', ',')
->join('builds', ',')
->join('bugs', ',')
->join('cases', ',')
->join('members', ',')
->remove('files,labels,uid')
->get();
$this->dao->insert(TABLE_TESTREPORT)->data($data)->autocheck()
->batchCheck($this->config->testreport->create->requiredFields, 'notempty')
->batchCheck('start,end', 'notempty')
->check('end', 'ge', $data->start)
->exec();
if(dao::isError()) return false;
$reportID = $this->dao->lastInsertID();
$this->loadModel('file')->updateObjectID($this->post->uid, $reportID, 'testreport');
$this->file->saveUpload('testreport', $reportID);
return $reportID;
}
/**
* Get report by id.
*
* @param int $reportID
* @access public
* @return object
*/
public function getById($reportID)
{
$report = $this->dao->select('*')->from(TABLE_TESTREPORT)->where('id')->eq($reportID)->fetch();
$report->files = $this->loadModel('file')->getByObject('testreport', $reportID);
return $report;
}
/**
* Get report list.
*
* @param int $objectID
* @param string $objectType
* @param string $extra
* @param string $orderBy
* @param object $pager
* @access public
* @return array
*/
public function getList($objectID, $objectType, $extra = '', $orderBy = 'id_desc', $pager = null)
{
$objectID = (int)$objectID;
return $this->dao->select('*')->from(TABLE_TESTREPORT)->where('deleted')->eq(0)
->beginIF($objectType == 'project')->andWhere('objectID')->eq($objectID)->andWhere('objectType')->eq('project')->fi()
->beginIF($objectType == 'product' and $extra)->andWhere('objectID')->eq((int)$extra)->andWhere('objectType')->eq('testtask')->fi()
->beginIF($objectType == 'product' and empty($extra))->andWhere("CONCAT(',', product, ',') like '%,$objectID,%'")->fi()
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
}
/**
* Get bug info.
*
* @param array $tasks
* @param array $productIdList
* @param string $begin
* @param string $end
* @param array $builds
* @access public
* @return array
*/
public function getBugInfo($tasks, $productIdList, $begin, $end, $builds)
{
$bugsByTask = $this->dao->select('*')->from(TABLE_BUG)->where('testtask')->in(array_keys($tasks))->andWhere('deleted')->eq(0)->fetchAll();
$severityGroups = $statusGroups = $openedByGroups = $resolvedByGroups = $resolutionGroups = $moduleGroups = array();
$confirmedNum = 0;
foreach($bugsByTask as $bug)
{
$severityGroups[$bug->severity] = isset($severityGroups[$bug->severity]) ? $severityGroups[$bug->severity] + 1 : 1;
$statusGroups[$bug->status] = isset($statusGroups[$bug->status]) ? $statusGroups[$bug->status] + 1 : 1;
$openedByGroups[$bug->openedBy] = isset($openedByGroups[$bug->openedBy]) ? $openedByGroups[$bug->openedBy] + 1 : 1;
$moduleGroups[$bug->module] = isset($moduleGroups[$bug->module]) ? $moduleGroups[$bug->module] + 1 : 1;
if($bug->resolvedBy)$resolvedByGroups[$bug->resolvedBy] = isset($resolvedByGroups[$bug->resolvedBy]) ? $resolvedByGroups[$bug->resolvedBy] + 1 : 1;
if($bug->resolution)$resolutionGroups[$bug->resolution] = isset($resolutionGroups[$bug->resolution]) ? $resolutionGroups[$bug->resolution] + 1 : 1;
if($bug->confirmed) $confirmedNum ++;
}
$newBugs = $this->dao->select('*')->from(TABLE_BUG)
->where('product')->in($productIdList)
->andWhere('openedDate')->ge($begin)
->andWhere('openedDate')->le("$end 23:59:59")
->andWhere('deleted')->eq(0)
->fetchAll();
$legacyBugs = array();
$byCaseNum = 0;
$buildIdList = array_keys($builds) + array('trunk' => 'trunk');
foreach($newBugs as $bug)
{
if(!array_diff(explode(',', $bug->openedBuild), $buildIdList) and ($bug->status == 'active' OR $bug->resolvedDate > "$end 23:59:59")) $legacyBugs[$bug->id] = $bug;
if($bug->case) $byCaseNum ++;
}
$bugInfo['legacyBugs'] = $legacyBugs;
$bugInfo['bugSeverityGroups'] = $severityGroups;
$bugInfo['bugStatusGroups'] = $statusGroups;
$bugInfo['bugOpenedByGroups'] = $openedByGroups;
$bugInfo['bugResolvedByGroups'] = $resolvedByGroups;
$bugInfo['bugResolutionGroups'] = $resolutionGroups;
$bugInfo['bugModuleGroups'] = $moduleGroups;
$bugInfo['bugConfirmedRate'] = round($confirmedNum / count($bugsByTask) * 100, 2);
$bugInfo['bugCreateByCaseRate'] = empty($byCaseNum) ? 0 : round($byCaseNum / count($newBugs) * 100, 2);
return $bugInfo;
}
/**
* Get task cases.
*
* @param array $tasks
* @param string $idList
* @access public
* @return array
*/
public function getTaskCases($tasks, $idList = '')
{
return $this->dao->select('t2.*,t1.assignedTo,t1.lastRunner,t1.lastRunDate,t1.lastRunResult,t1.status')->from(TABLE_TESTRUN)->alias('t1')
->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case=t2.id')
->where('t1.task')->in(array_keys($tasks))
->beginIF($idList)->andWhere('t2.id')->in($idList)->fi()
->andWhere('t2.deleted')->eq(0)
->fetchAll('id');
}
/**
* Get result summary.
*
* @param array $tasks
* @param array $cases
* @access public
* @return string
*/
public function getResultSummary($tasks, $cases)
{
$results = $this->dao->select('*')->from(TABLE_TESTRESULT)->where('run')->in(array_keys($tasks))->andWhere('`case`')->in(array_keys($cases))->fetchAll();
$failResults = array();
$runCasesNum = array();
foreach($results as $result)
{
$runCases[$result->case] = $result->case;
if($result->caseResult == 'fail') $failResults[$result->case] = $result->case;
}
return sprintf($this->lang->testreport->caseSummary, count($cases), count($results), count($runCasesNum), count($failResults));
}
/**
* Get bugs for test
*
* @param array $builds
* @param array $product
* @param string $begin
* @param string $end
* @param string $type
* @access public
* @return void
*/
public function getBugs4Test($builds, $product, $begin, $end, $type = 'build')
{
$bugIdList = '';
if(is_array($builds))
{
foreach($builds as $build) $bugIdList .= $build->bugs . ',';
}
return $this->dao->select('*')->from(TABLE_BUG)->where('deleted')->eq(0)
->andWhere('product')->in($product)
->andWhere('openedDate')->lt($begin)
->beginIF(is_array($builds) and $type == 'build')->andWhere('id')->in(trim($bugIdList, ','))->fi()
->beginIF(!is_array($builds) and $type == 'build')->andWhere("(resolvedBuild = 'trunk' and resolvedDate >= '$begin' and resolvedDate <= '$end 23:59:59')")->fi()
->beginIF($type == 'project')->andWhere("(id " . helper::dbIN(trim($bugIdList, ',')) . " OR (resolvedBuild = 'trunk' and resolvedDate >= '$begin' and resolvedDate <= '$end 23:59:59'))")
->fetchAll('id');
}
}
@@ -0,0 +1,110 @@
<tr>
<th rowspan='4' class='text-top'><?php echo $lang->testreport->bugInfo?></th>
<td class='text-top'>
<div class='input-group' id='bugConfirmedRate'>
<span class='input-group-addon'><?php echo $lang->testreport->bugConfirmedRate?></span>
<span class='input-group-addon'><?php echo $bugConfirmedRate . '%'?></span>
<span class='input-group-addon'><?php echo $lang->testreport->bugCreateByCaseRate?></span>
<span class='input-group-addon'><?php echo $bugCreateByCaseRate . '%'?></span>
</div>
</td>
<td></td>
</tr>
<tr>
<td class='text-top'>
<table class='table' id='bugSeverityGroups'>
<caption><?php echo $lang->testreport->bugSeverityGroups?></caption>
<tr>
<th class='text-right w-100px'><?php echo $lang->bug->severity?></th>
<th><?php echo $lang->testreport->value?></th>
</tr>
<?php foreach($lang->bug->severityList as $severityKey => $severityValue):?>
<tr>
<td class='text-right'><?php echo $severityValue === '' ? 'null' : $severityValue?></td>
<td><?php echo zget($bugSeverityGroups, $severityKey, 0);?></td>
</tr>
<?php endforeach?>
</table>
</td>
<td class='text-top'>
<table class='table' id='bugStatusGroups'>
<caption><?php echo $lang->testreport->bugStatusGroups?></caption>
<tr>
<th class='text-right w-100px'><?php echo $lang->bug->status?></th>
<th><?php echo $lang->testreport->value?></th>
</tr>
<?php foreach($lang->bug->statusList as $statusKey => $statusValue):?>
<?php if(!isset($bugStatusGroups['']) and $statusValue === '') continue;?>
<tr>
<td class='text-right'><?php echo $statusValue === '' ? 'null' : $statusValue?></td>
<td><?php echo zget($bugStatusGroups, $statusKey, 0);?></td>
</tr>
<?php endforeach?>
</table>
</td>
</tr>
<tr>
<td class='text-top'>
<table class='table' id='bugOpenedByGroups'>
<caption><?php echo $lang->testreport->bugOpenedByGroups?></caption>
<tr>
<th class='text-right w-100px'><?php echo $lang->bug->openedBy?></th>
<th><?php echo $lang->testreport->value?></th>
</tr>
<?php foreach($bugOpenedByGroups as $account => $num):?>
<tr>
<td class='text-right'><?php echo zget($users, $account)?></td>
<td><?php echo $num;?></td>
</tr>
<?php endforeach?>
</table>
</td>
<td class='text-top'>
<table class='table' id='bugResolvedByGroups'>
<caption><?php echo $lang->testreport->bugResolvedByGroups?></caption>
<tr>
<th class='text-right w-100px'><?php echo $lang->bug->resolvedBy?></th>
<th><?php echo $lang->testreport->value?></th>
</tr>
<?php foreach($bugResolvedByGroups as $account => $num):?>
<tr>
<td class='text-right'><?php echo zget($users, $account)?></td>
<td><?php echo $num;?></td>
</tr>
<?php endforeach?>
</table>
</td>
</tr>
<tr>
<td class='text-top'>
<table class='table' id='bugResolutionGroups'>
<caption><?php echo $lang->testreport->bugResolutionGroups?></caption>
<tr>
<th class='text-right w-100px'><?php echo $lang->bug->resolution?></th>
<th><?php echo $lang->testreport->value?></th>
</tr>
<?php foreach($lang->bug->resolutionList as $resolutionKey => $resolutionValue):?>
<tr>
<td class='text-right'><?php echo $resolutionValue === '' ? 'null' : $resolutionValue?></td>
<td><?php echo zget($bugResolutionGroups, $resolutionKey, 0);?></td>
</tr>
<?php endforeach?>
</table>
</td>
<td class='text-top'>
<table class='table' id='bugModuleGroups'>
<caption><?php echo $lang->testreport->bugModuleGroups?></caption>
<tr>
<th class='text-right w-100px'><?php echo $lang->bug->module?></th>
<th><?php echo $lang->testreport->value?></th>
</tr>
<?php ksort($bugModuleGroups)?>
<?php foreach($bugModuleGroups as $moduleKey => $num):?>
<tr>
<td class='text-right'><?php echo zget($modules, $moduleKey);?></td>
<td><?php echo $num;?></td>
</tr>
<?php endforeach?>
</table>
</td>
</tr>
+33
View File
@@ -0,0 +1,33 @@
<tr>
<th class='text-top'><?php echo $lang->testreport->bugs?></th>
<td colspan='2'>
<?php if($bugs):?>
<table class='table' id='bugs'>
<thead>
<tr>
<th class='w-id'> <?php echo $lang->idAB;?></th>
<th class='w-pri'> <?php echo $lang->priAB;?></th>
<th> <?php echo $lang->bug->title;?></th>
<th class='w-user'> <?php echo $lang->openedByAB;?></th>
<th class='w-150px'><?php echo $lang->bug->resolvedBy;?></th>
<th class='w-80px'> <?php echo $lang->statusAB;?></th>
</tr>
</thead>
<tbody class='text-center'>
<?php foreach($bugs as $bug):?>
<tr>
<td><?php echo $bug->id . html::hidden('bugs[]', $bug->id)?></td>
<td><span class='pri<?php echo $bug->pri?>'><?php echo zget($lang->bug->priList, $bug->pri);?></span></td>
<td class='text-left' title='<?php echo $bug->title?>'><?php echo $bug->title?></td>
<td><?php echo zget($users, $bug->openedBy);?></td>
<td><?php echo zget($users, $bug->resolvedBy);?></td>
<td><?php echo zget($lang->bug->statusList, $bug->status);?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<?php else:?>
<?php echo $lang->testreport->none;?>
<?php endif?>
</td>
</tr>
@@ -0,0 +1,29 @@
<tr>
<th class='text-top'><?php echo $lang->testreport->builds?></th>
<td colspan='2'>
<?php if($builds):?>
<table class='table' id='builds'>
<thead>
<tr>
<th class='w-id'> <?php echo $lang->build->id;?></th>
<th> <?php echo $lang->build->name;?></th>
<th class='w-user'><?php echo $lang->build->builder;?></th>
<th class='w-date'><?php echo $lang->build->date;?></th>
</tr>
</thead>
<tbody class='text-center'>
<?php foreach($builds as $build):?>
<tr>
<td><?php echo $build->id . html::hidden('builds[]', $build->id)?></td>
<td class='text-left' title='<?php echo $build->name?>'><?php echo $build->name?></td>
<td><?php echo zget($users, $build->builder);?></td>
<td><?php echo $build->date;?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<?php else:?>
<?php echo 'Trunk'?>
<?php endif;?>
</td>
</tr>
@@ -0,0 +1,40 @@
<tr>
<th class='text-top'><?php echo $lang->testreport->cases?></th>
<td colspan='2'>
<?php if($cases):?>
<table class='table' id='cases'>
<thead>
<tr>
<th class='w-id'> <?php echo $lang->idAB;?></th>
<th class='w-pri'> <?php echo $lang->priAB;?></th>
<th> <?php echo $lang->testcase->title;?></th>
<th class='w-type'> <?php echo $lang->testcase->type;?></th>
<th class='w-user'> <?php echo $lang->testtask->assignedTo;?></th>
<th class='w-user'> <?php echo $lang->testtask->lastRunAccount;?></th>
<th class='w-130px'> <?php echo $lang->testtask->lastRunTime;?></th>
<th class='w-80px'> <?php echo $lang->testtask->lastRunResult;?></th>
<th class='w-status'><?php echo $lang->statusAB;?></th>
</tr>
</thead>
<tbody class='text-center'>
<?php foreach($cases as $case):?>
<tr>
<td><?php echo $case->id . html::hidden('cases[]', $case->id)?></td>
<td><span class='pri<?php echo $case->pri?>'><?php echo zget($lang->testcase->priList, $case->pri);?></span></td>
<td class='text-left' title='<?php echo $case->title?>'><?php echo $case->title?></td>
<td><?php echo zget($lang->testcase->typeList, $case->type);?></td>
<td><?php echo zget($users, $case->assignedTo);?></td>
<td><?php echo zget($users, $case->lastRunner);?></td>
<td><?php echo substr($case->lastRunDate, 2);?></td>
<td><?php echo zget($lang->testcase->resultList, $case->lastRunResult);?></td>
<td><?php echo zget($lang->testtask->statusList, $case->status);?></td>
</tr>
<?php endforeach;?>
</tbody>
<tfoot><tr><td colspan='9'><?php echo $caseSummary;?></td></tr></tfoot>
</table>
<?php else:?>
<?php echo $lang->testreport->none;?>
<?php endif;?>
</td>
</tr>
@@ -0,0 +1,33 @@
<tr>
<th class='text-top'><?php echo $lang->testreport->legacyBugs?></th>
<td colspan='2'>
<?php if($legacyBugs):?>
<table class='table' id='bugs'>
<thead>
<tr>
<th class='w-id'> <?php echo $lang->idAB;?></th>
<th class='w-pri'> <?php echo $lang->priAB;?></th>
<th> <?php echo $lang->bug->title;?></th>
<th class='w-user'> <?php echo $lang->openedByAB;?></th>
<th class='w-150px'><?php echo $lang->bug->resolvedBy;?></th>
<th class='w-80px'> <?php echo $lang->statusAB;?></th>
</tr>
</thead>
<tbody class='text-center'>
<?php foreach($legacyBugs as $bug):?>
<tr>
<td><?php echo $bug->id?></td>
<td><span class='pri<?php echo $bug->pri?>'><?php echo zget($lang->bug->priList, $bug->pri);?></span></td>
<td class='text-left' title='<?php echo $bug->title?>'><?php echo $bug->title?></td>
<td><?php echo zget($users, $bug->openedBy);?></td>
<td><?php echo zget($users, $bug->resolvedBy);?></td>
<td><?php echo zget($lang->bug->statusList, $bug->status);?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<?php else:?>
<?php echo $lang->testreport->none;?>
<?php endif?>
</td>
</tr>
@@ -0,0 +1,38 @@
<tr>
<th class='text-top'><?php echo $lang->testreport->stories?></th>
<td colspan='2'>
<?php if($stories):?>
<table class='table' id='stories'>
<thead>
<tr>
<th class='w-id'> <?php echo $lang->idAB;?></th>
<th class='w-pri'> <?php echo $lang->priAB;?></th>
<th> <?php echo $lang->story->title;?></th>
<th class='w-user'><?php echo $lang->openedByAB;?></th>
<th class='w-80px'><?php echo $lang->assignedToAB;?></th>
<th class='w-hour'><?php echo $lang->story->estimateAB;?></th>
<th class='w-hour'><?php echo $lang->statusAB;?></th>
<th class='w-70px'><?php echo $lang->story->stageAB;?></th>
</tr>
</thead>
<tbody class='text-center'>
<?php foreach($stories as $story):?>
<tr>
<td><?php echo $story->id . html::hidden('stories[]', $story->id)?></td>
<td><span class='pri<?php echo $story->pri?>'><?php echo zget($lang->story->priList, $story->pri);?></span></td>
<td class='text-left' title='<?php echo $story->title?>'><?php echo $story->title?></td>
<td><?php echo zget($users, $story->openedBy);?></td>
<td><?php echo zget($users, $story->assignedTo);?></td>
<td><?php echo $story->estimate?></td>
<td><?php echo zget($lang->story->statusList, $story->status);?></td>
<td><?php echo zget($lang->story->stageList, $story->stage);?></td>
</tr>
<?php endforeach;?>
</tbody>
<tfoot><tr><td colspan='8'><?php echo $storySummary?></td></tr></tfoot>
</table>
<?php else:?>
<?php echo $lang->testreport->none;?>
<?php endif?>
</td>
</tr>
+54
View File
@@ -0,0 +1,54 @@
<?php
/**
* The browse view file of testreport module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package testreport
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<div class='container mw-1400px'>
<div id='titlebar'>
<div class='heading'>
<strong><?php echo $lang->testreport->browse;?></strong>
</div>
</div>
<table class='table table-condensed table-hover table-striped tablesorter table-fixed table-selectable' id='reportList'>
<?php $vars = "objectID=$objectID&objectType=$objectType&extra=$extra&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";?>
<thead>
<tr>
<th class='w-id'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th> <?php common::printOrderLink('title', $orderBy, $vars, $lang->testreport->title);?></th>
<th class='w-user'> <?php common::printOrderLink('createdBy', $orderBy, $vars, $lang->openedByAB);?></th>
<th class='w-120px'><?php common::printOrderLink('createdDate', $orderBy, $vars, $lang->testreport->createdDate);?></th>
<th class='w-250px'><?php common::printOrderLink('objectID', $orderBy, $vars, $lang->testreport->objectID);?></th>
<th class='w-50px'> <?php echo $lang->actions;?></th>
</tr>
</thead>
<?php if($reports):?>
<tbody class='text-center'>
<?php foreach($reports as $report):?>
<tr>
<td><?php echo $report->id?></td>
<td class='text-left' title='<?php $report->title?>'><?php echo html::a(inlink('view', "reportID=$report->id"), $report->title)?></td>
<td><?php echo zget($users, $report->createdBy);?></td>
<td><?php echo substr($report->createdDate, 2);?></td>
<?php
$objectName = '';
if($report->objectType == 'testtask' and isset($tasks[$report->objectID])) $objectName = 'TESTTAST #' . $report->objectID . $tasks[$report->objectID];
if($report->objectType == 'project' and isset($projects[$report->objectID])) $objectName = 'PROJECT #' . $report->objectID . $projects[$report->objectID];
?>
<td class='text-left' title='<?php echo $objectName?>'><?php echo $objectName;?></td>
<td><?php common::printIcon('testreport', 'delete', "id=$report->id", '', 'list', 'remove', 'hiddenwin');?></td>
</tr>
<?php endforeach;?>
</tbody>
<?php endif;?>
<tfoot><tr><td colspan='6'><?php $pager->show();?></td></tr></tfoot>
</table>
</div>
<?php include '../../common/view/footer.html.php';?>
+89
View File
@@ -0,0 +1,89 @@
<?php
/**
* The create view file of testreport module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package testreport
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/datepicker.html.php';?>
<?php include '../../common/view/kindeditor.html.php';?>
<div class='container mw-1400px'>
<div id='titlebar'>
<div class='heading'>
<strong><small class='text-muted'><?php echo html::icon($lang->icons['create']);?></small> <?php echo $lang->testreport->create;?></strong>
</div>
<div class='actions'>
<?php
if(common::hasPriv('testreport', 'browse'))
{
$param = '';
if($objectType == 'project') $param = "objectID=$objectID&objectType=$objectType";
if($objectType == 'testtask') $param = "objectID=$productIdList&objectType=product&extra=$objectID";
echo html::a(inlink('browse', $param), $lang->testreport->all, '', "class='btn'");
}
echo html::backButton();
?>
</div>
</div>
<form class='form-condensed' method='post' enctype='multipart/form-data' target='hiddenwin'>
<table class='table table-form'>
<tr>
<th class='w-80px'><?php echo $lang->testreport->startEnd?></th>
<td class='w-p50'>
<div class='input-group'>
<?php echo html::input('begin', $begin, "class='form-control form-date'")?>
<span class='input-group-addon'> ~ </span>
<?php echo html::input('end', $end, "class='form-control form-date'")?>
<?php
echo html::hidden('product', $productIdList) . html::hidden('project', $project->id) . html::hidden('tasks', $tasks);
echo html::hidden('objectID', $objectID) . html::hidden('objectType', $objectType);
?>
</div>
</td>
<td>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->testreport->owner?></span>
<?php echo html::select('owner', $users, $owner, "class='form-control chosen'")?>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->testreport->member?></th>
<td colspan='2'><?php echo html::select('members', $users, $members, "class='form-control chosen' multiple")?></td>
</tr>
<tr>
<th><?php echo $lang->testreport->title?></th>
<td colspan='2'><?php echo html::input('title', $reportTitle, "class='form-control'")?></td>
</tr>
<tr>
<th><?php echo $lang->testreport->goal?></th>
<td colspan='2'><?php echo $project->desc?></td>
</tr>
<?php include './blockstories.html.php'?>
<?php include './blockbugs.html.php'?>
<?php include './blockbuilds.html.php'?>
<?php include './blockcases.html.php'?>
<?php include './blocklegacybugs.html.php'?>
<?php include './blockbuginfo.html.php'?>
<tr>
<th><?php echo $lang->testreport->report?></th>
<td colspan='2'><?php echo html::textarea('report', '', "class='form-control'")?></td>
</tr>
<tr>
<th><?php echo $lang->files?></th>
<td colspan='2'><?php echo $this->fetch('file', 'buildform');?></td>
</tr>
<tr>
<th></th>
<td colspan='2'><?php echo html::submitButton() . html::backButton();?></td>
</tr>
</table>
</form>
</div>
<?php include '../../common/view/footer.html.php';?>
+17
View File
@@ -0,0 +1,17 @@
<?php
/**
* The export view file of testreport module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package testreport
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php
unset($lang->exportFileTypeList);
$lang->exportFileTypeList['html'] = 'html';
include '../../file/view/export.html.php';
?>
+82
View File
@@ -0,0 +1,82 @@
<?php
/**
* The view view file of testreport module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package testreport
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php if(!$this->session->notHead):?>
<?php include '../../common/view/header.html.php';?>
<div class='container mw-1400px'>
<div id='titlebar'>
<div class='heading'>
<span class='prefix'><strong><?php echo $report->id;?></strong></span>
<strong><?php echo $report->title;?></strong>
</div>
<div class='actions'>
<?php
$browseLink = $this->session->reportList != false ? $app->session->reportList : $browseLink;
$actionLinks = '';
ob_start();
echo "<div class='btn-group'>";
common::printIcon('testreport', 'export', "reportID=$report->id", '', 'button', 'download-alt', '', 'iframe');
if(common::hasPriv('testreport', 'create')) echo html::a(inLink('create', "objectID=$report->objectID&objectType=$report->objectType"), "<i class='icon-refresh'></i>", '', "class='btn' title='{$lang->testreport->recreate}'");
common::printIcon('testreport', 'delete', "reportID=$report->id", '', 'button', '', 'hiddenwin');
echo '</div>';
echo "<div class='btn-group'>";
common::printRPN($browseLink);
echo '</div>';
$actionLinks = ob_get_contents();
ob_end_clean();
echo $actionLinks;
?>
</div>
</div>
<?php endif;?>
<table class='table table-form'>
<tr>
<th class='w-100px'><?php echo $lang->testreport->startEnd?></th>
<td class='w-p50'> <?php echo $report->begin . ' ~ ' . $report->end;?></td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->testreport->owner?></th>
<td><?php echo zget($users, $report->owner);?></td>
</tr>
<tr>
<th><?php echo $lang->testreport->member?></th>
<td colspan='2'><?php foreach(explode(',', $report->members) as $member)echo zget($users, $member) . ' &nbsp; ';?></td>
</tr>
<tr>
<th><?php echo $lang->testreport->goal?></th>
<td colspan='2'><?php echo $project->desc?></td>
</tr>
<?php include './blockstories.html.php'?>
<?php include './blockbugs.html.php'?>
<?php include './blockbuilds.html.php'?>
<?php include './blockcases.html.php'?>
<?php include './blocklegacybugs.html.php'?>
<?php include './blockbuginfo.html.php'?>
<tr>
<th><?php echo $lang->testreport->report?></th>
<td colspan='2'><?php echo $report->report;?></td>
</tr>
<?php if(!$this->session->notHead):?>
<tr>
<th><?php echo $lang->files?></th>
<td colspan='2'><?php echo $this->fetch('file', 'printFiles', array('files' => $report->files, 'fieldset' => 'false'));?></td>
</tr>
<?php endif;?>
</table>
<?php if(!$this->session->notHead):?>
</div>
<?php include '../../common/view/footer.html.php';?>
<?php endif;?>
+24
View File
@@ -106,6 +106,18 @@ class testtaskModel extends model
->fetchAll();
}
/**
* Get task by idList.
*
* @param array $idList
* @access public
* @return array
*/
public function getByList($idList)
{
return $this->dao->select("*")->from(TABLE_TESTTASK)->where('id')->in($idList)->fetchAll('id');
}
/**
* Get test task info by id.
*
@@ -129,6 +141,18 @@ class testtaskModel extends model
return $task;
}
/**
* Bet tasks by project.
*
* @param int $projectID
* @access public
* @return array
*/
public function getByProject($projectID)
{
return $this->dao->select('*')->from(TABLE_TESTTASK)->where('project')->eq((int)$projectID)->andWhere('deleted')->eq(0)->fetchAll('id');
}
/**
* Get taskrun by case id.
*
+2 -1
View File
@@ -32,7 +32,7 @@
<th class='w-100px text-left'><?php common::printOrderLink('begin', $orderBy, $vars, $lang->testtask->begin);?></th>
<th class='w-100px text-left'><?php common::printOrderLink('end', $orderBy, $vars, $lang->testtask->end);?></th>
<th class='w-80px text-left'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='w-120px {sorter:false} text-left'><?php echo $lang->actions;?></th>
<th class='w-130px text-left'><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
@@ -56,6 +56,7 @@
common::printIcon('testtask', 'view', "taskID=$task->id", '', 'list', 'file','','iframe',true);
common::printIcon('testtask', 'linkCase', "taskID=$task->id", '', 'list', 'link');
common::printIcon('testtask', 'edit', "taskID=$task->id", '', 'list','','','iframe',true);
common::printIcon('testreport', 'create', "objectID=$task->id&objectType=testtask", '', 'list','flag');
if(common::hasPriv('testtask', 'delete'))
{