Merge branch 'master' of github.com:easysoft/zentaopms
This commit is contained in:
@@ -133,6 +133,7 @@ define('TABLE_PRODUCT', '`' . $config->db->prefix . 'product`');
|
||||
define('TABLE_BRANCH', '`' . $config->db->prefix . 'branch`');
|
||||
define('TABLE_STORY', '`' . $config->db->prefix . 'story`');
|
||||
define('TABLE_STORYSPEC', '`' . $config->db->prefix . 'storyspec`');
|
||||
define('TABLE_STORYSTAGE', '`' . $config->db->prefix . 'storystage`');
|
||||
define('TABLE_PRODUCTPLAN', '`' . $config->db->prefix . 'productplan`');
|
||||
define('TABLE_RELEASE', '`' . $config->db->prefix . 'release`');
|
||||
|
||||
|
||||
@@ -18,3 +18,8 @@ CREATE TABLE `zt_branch` (
|
||||
`name` varchar(255) COLLATE 'utf8_general_ci' NOT NULL,
|
||||
`deleted` enum('0','1') COLLATE 'utf8_general_ci' NOT NULL DEFAULT '0'
|
||||
);
|
||||
CREATE TABLE `zt_storystage` (
|
||||
`story` mediumint unsigned NOT NULL,
|
||||
`branch` mediumint unsigned NOT NULL,
|
||||
`stage` varchar(50) COLLATE 'utf8_general_ci' NOT NULL
|
||||
);
|
||||
|
||||
@@ -51,15 +51,6 @@ class branch extends control
|
||||
$this->display();
|
||||
}
|
||||
|
||||
public function ajaxGetBranches($productID)
|
||||
{
|
||||
$product = $this->loadModel('product')->getById($productID);
|
||||
if(empty($product) or $product->type == 'normal') die();
|
||||
|
||||
$branches = $this->branch->getPairs($productID);
|
||||
die(html::select('branch', $branches, '', "class='form-control' onchange='loadBranch()'"));
|
||||
}
|
||||
|
||||
public function delete($branchID, $confirm = 'no')
|
||||
{
|
||||
if($confirm == 'no') die(js::confirm($this->lang->branch->confirmDelete, inlink('delete', "branchID=$branchID&confirm=yes")));
|
||||
@@ -67,5 +58,14 @@ class branch extends control
|
||||
$this->branch->delete(TABLE_BRANCH, $branchID);
|
||||
die(js::reload('parent'));
|
||||
}
|
||||
}
|
||||
|
||||
public function ajaxGetBranches($productID, $oldBranch = 0)
|
||||
{
|
||||
$product = $this->loadModel('product')->getById($productID);
|
||||
if(empty($product) or $product->type == 'normal') die();
|
||||
|
||||
$branches = $this->branch->getPairs($productID);
|
||||
if($oldBranch) $branches = array($oldBranch => $branches[$oldBranch]);
|
||||
die(html::select('branch', $branches, '', "class='form-control' onchange='loadBranch()'"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class branchModel extends model
|
||||
|
||||
public function getPairs($productID, $params = '')
|
||||
{
|
||||
$branches = $this->dao->select('*')->from(TABLE_BRANCH)->where('product')->eq($productID)->andWhere('deleted')->eq(0)->orderBy('id_desc')->fetchPairs('id', 'name');
|
||||
$branches = $this->dao->select('*')->from(TABLE_BRANCH)->where('product')->eq($productID)->andWhere('deleted')->eq(0)->orderBy('id_asc')->fetchPairs('id', 'name');
|
||||
if(strpos($params, 'noempty') === false) $branches = array('0' => $this->lang->branch->all) + $branches;
|
||||
return $branches;
|
||||
}
|
||||
|
||||
@@ -434,7 +434,7 @@ class bug extends control
|
||||
$this->view->stories = $stories;
|
||||
$this->view->builds = $builds;
|
||||
$this->view->users = $this->user->getPairs('nodeleted,devfirst');
|
||||
$this->view->projects = $this->product->getProjectPairs($productID, $params = 'nodeleted');
|
||||
$this->view->projects = $this->product->getProjectPairs($productID, $branch, $params = 'nodeleted');
|
||||
$this->view->projectID = $projectID;
|
||||
$this->view->moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0, $branch);
|
||||
$this->view->moduleID = $moduleID;
|
||||
|
||||
@@ -132,11 +132,10 @@ class build extends control
|
||||
$build = $this->build->getById((int)$buildID, true);
|
||||
if(!$build) die(js::error($this->lang->notFound) . js::locate('back'));
|
||||
|
||||
$stories = $this->dao->select('*')->from(TABLE_STORY)->where('id')->in($build->stories)->andWhere('deleted')->eq(0)->fetchAll();
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'story');
|
||||
|
||||
$bugs = $this->dao->select('*')->from(TABLE_BUG)->where('id')->in($build->bugs)->andWhere('deleted')->eq(0)->fetchAll();
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'bug');
|
||||
$stories = $this->dao->select('*')->from(TABLE_STORY)->where('id')->in($build->stories)->andWhere('deleted')->eq(0)->fetchAll('id');
|
||||
$stages = $this->dao->select('*')->from(TABLE_STORYSTAGE)->where('story')->in($build->stories)->andWhere('branch')->eq($build->branch)->fetchPairs('story', 'stage');
|
||||
foreach($stages as $storyID => $stage)$stories[$storyID]->stage = $stage;
|
||||
$bugs = $this->dao->select('*')->from(TABLE_BUG)->where('id')->in($build->bugs)->andWhere('deleted')->eq(0)->fetchAll();
|
||||
|
||||
$this->loadModel('project')->setMenu($this->project->getPairs(), $build->project);
|
||||
|
||||
|
||||
@@ -6,17 +6,12 @@ $(document).ready(function()
|
||||
function loadBranches(productID)
|
||||
{
|
||||
$('#branch').remove();
|
||||
$.get(createLink('branch', 'ajaxGetBranches', 'productID=' + productID), function(data)
|
||||
$.get(createLink('branch', 'ajaxGetBranches', 'productID=' + productID + '&oldBranch=' + productGroups[productID]['branch']), function(data)
|
||||
{
|
||||
if(data)
|
||||
{
|
||||
$('#product').closest('.input-group').append(data);
|
||||
$('#branch').css('width', '100px');
|
||||
for(i in productGroups[productID]['branches'])
|
||||
{
|
||||
$('#branch').val(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -28,7 +28,13 @@
|
||||
<?php if($products):?>
|
||||
<div class='input-group'>
|
||||
<?php echo html::select('product', $products, $product->id, "onchange='loadBranches(this.value);' class='form-control chosen'");?>
|
||||
<?php if($product->type != 'normal') echo html::select('branch', $branches, key($product->branches), "class='form-control' style='width:100px'");?>
|
||||
<?php
|
||||
if($product->type != 'normal')
|
||||
{
|
||||
if($product->branch) $branches = array($product->branch => $branches[$product->branch]);
|
||||
echo html::select('branch', $branches, $product->branch, "class='form-control' style='width:100px'");
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</td>
|
||||
|
||||
@@ -1549,7 +1549,7 @@ class project extends control
|
||||
else
|
||||
{
|
||||
$branches = array(0 => 0);
|
||||
foreach($products as $product) $branches += $product->branches;
|
||||
foreach($products as $product) $branches[$product->branch] = $product->branch;
|
||||
$allStories = $this->story->getProductStories(array_keys($products), $branches, $moduleID = '0', $status = 'active');
|
||||
}
|
||||
$prjStories = $this->story->getProjectStoryPairs($projectID);
|
||||
|
||||
@@ -793,16 +793,7 @@ class projectModel extends model
|
||||
->on('t1.product = t2.id')
|
||||
->where('t1.project')->eq((int)$projectID);
|
||||
if(!$withBranch) return $query->fetchPairs('id', 'name');
|
||||
$products = $query->fetchAll();
|
||||
$productGroups = array();
|
||||
foreach($products as $product)
|
||||
{
|
||||
if(!isset($productGroups[$product->id])) $productGroups[$product->id] = $product;
|
||||
$productGroups[$product->id]->branches[$product->branch] = $product->branch;
|
||||
unset($productGroups[$product->id]->branch);
|
||||
}
|
||||
|
||||
return $productGroups;
|
||||
return $query->fetchAll('id');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -848,29 +839,14 @@ class projectModel extends model
|
||||
foreach($products as $i => $productID)
|
||||
{
|
||||
if(empty($productID)) continue;
|
||||
if(isset($existedProducts[$productID])) continue;
|
||||
|
||||
$data = new stdclass();
|
||||
$data->project = $projectID;
|
||||
$data->product = $productID;
|
||||
|
||||
/* When manageProducts. */
|
||||
if(isset($branches[$i]) and is_array($branches[$i]))
|
||||
{
|
||||
foreach($branches[$i] as $branch)
|
||||
{
|
||||
$data->branch = $branch;
|
||||
if(isset($existedProducts[$data->product][$data->branch])) continue;
|
||||
$existedProducts[$data->product][$data->branch] = true;
|
||||
$this->dao->insert(TABLE_PROJECTPRODUCT)->data($data)->exec();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$data->branch = isset($branches[$i]) ? $branches[$i] : 0;
|
||||
if(isset($existedProducts[$data->product][$data->branch])) continue;
|
||||
$existedProducts[$data->product][$data->branch] = true;
|
||||
$this->dao->insert(TABLE_PROJECTPRODUCT)->data($data)->exec();
|
||||
}
|
||||
$data->branch = isset($branches[$i]) ? $branches[$i] : 0;
|
||||
$this->dao->insert(TABLE_PROJECTPRODUCT)->data($data)->exec();
|
||||
$existedProducts[$productID] = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<?php foreach($allProducts as $productID => $productName):?>
|
||||
<?php $checked = isset($linkedProducts[$productID]) ? 'checked' : ''; ?>
|
||||
<div class='col-sm-4 <?php echo $checked?>'>
|
||||
<?php if(isset($branchGroups[$productID])) echo "<div class='col-sm-6'>"?>
|
||||
<?php if(isset($branchGroups[$productID])) echo "<div class='col-sm-6' style='padding-left:0px'>"?>
|
||||
<label for='<?php echo 'products'. $productID?>';>
|
||||
<?php echo "<input type='checkbox' name='products[$productID]' value='$productID' $checked id='products{$productID}'> $productName";?>
|
||||
</label>
|
||||
@@ -30,7 +30,7 @@
|
||||
if(isset($branchGroups[$productID]))
|
||||
{
|
||||
echo "</div><div class='col-sm-6'>";
|
||||
echo html::select("branch[$productID][]", $branchGroups[$productID], $checked ? join(',', $linkedProducts[$productID]->branches) : '', "class='from-control chosen' multiple");
|
||||
echo html::select("branch[$productID]", $branchGroups[$productID], $checked ? $linkedProducts[$productID]->branch : '', "class='from-control chosen'");
|
||||
echo '</div>';
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -137,8 +137,10 @@ class release extends control
|
||||
$release = $this->release->getById((int)$releaseID, true);
|
||||
if(!$release) die(js::error($this->lang->notFound) . js::locate('back'));
|
||||
|
||||
$stories = $this->dao->select('*')->from(TABLE_STORY)->where('id')->in($release->stories)->andWhere('deleted')->eq(0)->fetchAll();
|
||||
$stories = $this->dao->select('*')->from(TABLE_STORY)->where('id')->in($release->stories)->andWhere('deleted')->eq(0)->fetchAll('id');
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'story');
|
||||
$stages = $this->dao->select('*')->from(TABLE_STORYSTAGE)->where('story')->in($release->stories)->andWhere('branch')->eq($release->branch)->fetchPairs('story', 'stage');
|
||||
foreach($stages as $storyID => $stage)$stories[$storyID]->stage = $stage;
|
||||
|
||||
$bugs = $this->dao->select('*')->from(TABLE_BUG)->where('id')->in($release->bugs)->andWhere('deleted')->eq(0)->fetchAll();
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'linkedBug');
|
||||
|
||||
@@ -125,7 +125,6 @@ class releaseModel extends model
|
||||
{
|
||||
$releaseID = $this->dao->lastInsertID();
|
||||
$this->loadModel('file')->saveUpload('release', $releaseID);
|
||||
if($release->stories) $this->dao->update(TABLE_STORY)->set('stage')->eq('released')->where('id')->in($release->stories)->exec();
|
||||
if(!dao::isError()) return $releaseID;
|
||||
}
|
||||
|
||||
@@ -151,7 +150,6 @@ class releaseModel extends model
|
||||
->check('name','unique', "id != $releaseID")
|
||||
->where('id')->eq((int)$releaseID)
|
||||
->exec();
|
||||
$this->dao->update(TABLE_STORY)->set('stage')->eq('released')->where('id')->in($release->stories)->exec();
|
||||
if(!dao::isError()) return common::createChanges($oldRelease, $release);
|
||||
}
|
||||
|
||||
@@ -168,7 +166,11 @@ class releaseModel extends model
|
||||
|
||||
$release->stories .= ',' . join(',', $this->post->stories);
|
||||
$this->dao->update(TABLE_RELEASE)->set('stories')->eq($release->stories)->where('id')->eq((int)$releaseID)->exec();
|
||||
if($release->stories) $this->dao->update(TABLE_STORY)->set('stage')->eq('released')->where('id')->in($release->stories)->exec();
|
||||
if($release->stories)
|
||||
{
|
||||
$this->dao->update(TABLE_STORY)->set('stage')->eq('released')->where('id')->in($release->stories)->exec();
|
||||
$this->dao->update(TABLE_STORYSTAGE)->set('stage')->eq('released')->where('story')->in($release->stories)->andWhere('branch')->eq($release->branch)->exec();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,6 +42,7 @@ class storyModel extends model
|
||||
->orderBy('t1.project DESC')
|
||||
->fetchAll('project');
|
||||
$story->tasks = $this->dao->select('id, name, assignedTo, project, status, consumed, `left`')->from(TABLE_TASK)->where('story')->eq($storyID)->andWhere('deleted')->eq(0)->orderBy('id DESC')->fetchGroup('project');
|
||||
$story->stages = $this->dao->select('*')->from(TABLE_STORYSTAGE)->where('story')->eq($storyID)->fetchPairs('branch', 'stage');
|
||||
//$story->bugCount = $this->dao->select('COUNT(*)')->alias('count')->from(TABLE_BUG)->where('story')->eq($storyID)->fetch('count');
|
||||
//$story->caseCount = $this->dao->select('COUNT(*)')->alias('count')->from(TABLE_CASE)->where('story')->eq($storyID)->fetch('count');
|
||||
if($story->toBug) $story->toBugTitle = $this->dao->findById($story->toBug)->from(TABLE_BUG)->fetch('title');
|
||||
@@ -837,6 +838,7 @@ class storyModel extends model
|
||||
*/
|
||||
public function setStage($storyID, $customStage = '')
|
||||
{
|
||||
$storyID = (int)$storyID;
|
||||
/* Custom stage defined, use it. */
|
||||
if($customStage)
|
||||
{
|
||||
@@ -845,24 +847,32 @@ class storyModel extends model
|
||||
}
|
||||
|
||||
/* Get projects which status is doing. */
|
||||
$projects = $this->dao->select('project')
|
||||
->from(TABLE_PROJECTSTORY)->alias('t1')->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
|
||||
->where('t1.story')->eq((int)$storyID)
|
||||
$this->dao->delete()->from(TABLE_STORYSTAGE)->where('story')->eq($storyID)->exec();
|
||||
$projects = $this->dao->select('t1.project,t3.branch')->from(TABLE_PROJECTSTORY)->alias('t1')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
|
||||
->leftJoin(TABLE_PROJECTPRODUCT)->alias('t3')->on('t1.project = t3.project')
|
||||
->where('t1.story')->eq($storyID)
|
||||
->andWhere('t2.status')->ne('done')
|
||||
->andWhere('t2.deleted')->eq(0)
|
||||
->fetchPairs();
|
||||
->fetchPairs('project', 'branch');
|
||||
|
||||
/* If no projects, in plan, stage is planned. No plan, wait. */
|
||||
if(!$projects)
|
||||
{
|
||||
$this->dao->update(TABLE_STORY)->set('stage')->eq('wait')->where('id')->eq((int)$storyID)->andWhere('plan')->eq(0)->exec();
|
||||
$this->dao->update(TABLE_STORY)->set('stage')->eq('planned')->where('id')->eq((int)$storyID)->andWhere('plan')->gt(0)->exec();
|
||||
$this->dao->update(TABLE_STORY)->set('stage')->eq('wait')->where('id')->eq($storyID)->andWhere('plan')->eq(0)->exec();
|
||||
$this->dao->update(TABLE_STORY)->set('stage')->eq('planned')->where('id')->eq($storyID)->andWhere('plan')->gt(0)->exec();
|
||||
return true;
|
||||
}
|
||||
|
||||
$story = $this->dao->findById($storyID)->from(TABLE_STORY)->fetch();
|
||||
$product = $this->dao->findById($story->product)->from(TABLE_PRODUCT)->fetch();
|
||||
$branches = array();
|
||||
foreach($projects as $projectID => $branch) $branches[$branch] = $branch;
|
||||
unset($branches[0]);
|
||||
|
||||
/* Search related tasks. */
|
||||
$tasks = $this->dao->select('type,status')->from(TABLE_TASK)
|
||||
->where('project')->in($projects)
|
||||
$tasks = $this->dao->select('type,project,status')->from(TABLE_TASK)
|
||||
->where('project')->in(array_keys($projects))
|
||||
->andWhere('story')->eq($storyID)
|
||||
->andWhere('type')->in('devel,test')
|
||||
->andWhere('status')->ne('cancel')
|
||||
@@ -870,19 +880,28 @@ class storyModel extends model
|
||||
->fetchGroup('type');
|
||||
|
||||
/* No tasks, then the stage is projected. */
|
||||
$hasBranch = ($product->type != 'normal' and empty($story->branch) and $branches);
|
||||
if(!$tasks)
|
||||
{
|
||||
$this->dao->update(TABLE_STORY)->set('stage')->eq('projected')->where('id')->eq((int)$storyID)->exec();
|
||||
if($hasBranch)
|
||||
{
|
||||
foreach($branches as $branch) $this->dao->insert(TABLE_STORYSTAGE)->set('story')->eq($storyID)->set('branch')->eq($branch)->set('stage')->eq('projected')->exec();
|
||||
}
|
||||
$this->dao->update(TABLE_STORY)->set('stage')->eq('projected')->where('id')->eq($storyID)->exec();
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Get current stage and set as default value. */
|
||||
$currentStage = $this->dao->findById($storyID)->from(TABLE_STORY)->fields('stage')->fetch('stage');
|
||||
$taskProjects = array();
|
||||
$currentStage = $story->stage;
|
||||
$stage = $currentStage;
|
||||
|
||||
/* Cycle all tasks, get counts of every type and every status. */
|
||||
$statusList['devel'] = array('wait' => 0, 'doing' => 0, 'done' => 0);
|
||||
$statusList['test'] = array('wait' => 0, 'doing' => 0, 'done' => 0);
|
||||
$branchStatusList = array();
|
||||
$branchDevelTasks = array();
|
||||
$branchTestTasks = array();
|
||||
$statusList['devel'] = array('wait' => 0, 'doing' => 0, 'done'=> 0);
|
||||
$statusList['test'] = array('wait' => 0, 'doing' => 0, 'done'=> 0);
|
||||
foreach($tasks as $type => $typeTasks)
|
||||
{
|
||||
foreach($typeTasks as $task)
|
||||
@@ -890,14 +909,23 @@ class storyModel extends model
|
||||
$status = $task->status ? $task->status : 'wait';
|
||||
$status = $status == 'closed' ? 'done' : $status;
|
||||
|
||||
$statusList[$task->type][$status] ++;
|
||||
$branch = $projects[$task->project];
|
||||
if(!isset($branchStatusList[$branch])) $branchStatusList[$branch] = $statusList;
|
||||
$branchStatusList[$branch][$task->type][$status] ++;
|
||||
$taskProjects[$task->project] = $task->project;
|
||||
if($type == 'devel')
|
||||
{
|
||||
if(!isset($develTasks[$branch])) $develTasks[$branch] = 0;
|
||||
$branchDevelTasks[$branch] ++;
|
||||
}
|
||||
elseif($type == 'test')
|
||||
{
|
||||
if(!isset($testTasks[$branch])) $testTasks[$branch] = 0;
|
||||
$branchTestTasks[$branch] ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get counts of every type tasks. */
|
||||
$develTasks = isset($tasks['devel']) ? count($tasks['devel']) : 0;
|
||||
$testTasks = isset($tasks['test']) ? count($tasks['test']) : 0;
|
||||
|
||||
/**
|
||||
* Judge stage according to the devel and test tasks' status.
|
||||
*
|
||||
@@ -907,13 +935,26 @@ class storyModel extends model
|
||||
* 4. all test tasks done, still some devel tasks not done(wait, doing), set stage as testing.
|
||||
* 5. all test tasks done, all devel tasks done, set stage as tested.
|
||||
*/
|
||||
if($statusList['devel']['doing'] > 0 and $statusList['test']['wait'] == $testTasks) $stage = 'developing';
|
||||
if($statusList['devel']['done'] == $develTasks and $develTasks > 0 and $statusList['test']['wait'] == $testTasks) $stage = 'developed';
|
||||
if($statusList['test']['doing'] > 0) $stage = 'testing';
|
||||
if(($statusList['devel']['wait'] > 0 or $statusList['devel']['doing'] > 0) and $statusList['test']['done'] == $testTasks and $testTasks > 0) $stage = 'testing';
|
||||
if($statusList['devel']['done'] == $develTasks and $develTasks > 0 and $statusList['test']['done'] == $testTasks and $testTasks > 0) $stage = 'tested';
|
||||
foreach($branchStatusList as $branch => $statusList)
|
||||
{
|
||||
$testTasks = isset($branchTestTasks[$branch]) ? $branchTestTasks[$branch] : 0;
|
||||
$develTasks = isset($branchDevelTasks[$branch]) ? $branchDevelTasks[$branch] : 0;
|
||||
if($statusList['devel']['doing'] > 0 and $statusList['test']['wait'] == $testTasks) $stage = 'developing';
|
||||
if($statusList['devel']['done'] == $develTasks and $develTasks > 0 and $statusList['test']['wait'] == $testTasks) $stage = 'developed';
|
||||
if($statusList['test']['doing'] > 0) $stage = 'testing';
|
||||
if(($statusList['devel']['wait'] > 0 or $statusList['devel']['doing'] > 0) and $statusList['test']['done'] == $testTasks and $testTasks > 0) $stage = 'testing';
|
||||
if($statusList['devel']['done'] == $develTasks and $develTasks > 0 and $statusList['test']['done'] == $testTasks and $testTasks > 0) $stage = 'tested';
|
||||
|
||||
if($hasBranch and $branch) $this->dao->insert(TABLE_STORYSTAGE)->set('story')->eq($storyID)->set('branch')->eq($branch)->set('stage')->eq($stage)->exec();
|
||||
$this->dao->update(TABLE_STORY)->set('stage')->eq($stage)->where('id')->eq($storyID)->exec();
|
||||
}
|
||||
|
||||
foreach($projects as $projectID => $branch)
|
||||
{
|
||||
if(isset($taskProjects[$projectID])) continue;
|
||||
$this->dao->insert(TABLE_STORYSTAGE)->set('story')->eq($storyID)->set('branch')->eq($branch)->set('stage')->eq('projected')->exec();
|
||||
}
|
||||
|
||||
$this->dao->update(TABLE_STORY)->set('stage')->eq($stage)->where('id')->eq((int)$storyID)->exec();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1080,8 +1121,7 @@ class storyModel extends model
|
||||
*/
|
||||
public function getWillClose($productID, $branch, $orderBy, $pager)
|
||||
{
|
||||
return $this->dao->select('t1.*, t2.title as planTitle')
|
||||
->from(TABLE_STORY)->alias('t1')
|
||||
$stories = $this->dao->select('t1.*, t2.title as planTitle')->from(TABLE_STORY)->alias('t1')
|
||||
->leftJoin(TABLE_PRODUCTPLAN)->alias('t2')->on('t1.plan = t2.id')
|
||||
->where('t1.product')->in($productID)
|
||||
->andWhere('t1.deleted')->eq(0)
|
||||
@@ -1089,7 +1129,10 @@ class storyModel extends model
|
||||
->andWhere('status')->ne('closed')
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll();
|
||||
->fetchAll('id');
|
||||
$stages = $this->dao->select('*')->from(TABLE_STORYSTAGE)->where('story')->in(array_keys($stories))->andWhere('stage')->notIN('released')->fetchPairs('story', 'story');
|
||||
foreach($stages as $storyID) unset($stories[$storyID]);
|
||||
return $stories;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1136,7 +1179,7 @@ class storyModel extends model
|
||||
if($projectID != '')
|
||||
{
|
||||
$branches = array(0 => 0);
|
||||
foreach($products as $product) $branches += $product->branches;
|
||||
foreach($products as $product) $branches[$product->branch] = $product->branch;
|
||||
$storyQuery .= " AND `branch`" . helper::dbIN($branches);
|
||||
$storyQuery .= " AND `status` != 'draft'";
|
||||
}
|
||||
@@ -1195,8 +1238,10 @@ class storyModel extends model
|
||||
public function getProjectStories($projectID = 0, $orderBy = 'pri_asc,id_desc', $type = 'byModule', $param = 0, $pager = null)
|
||||
{
|
||||
$modules = ($type == 'byModule' and $param) ? $this->dao->select('*')->from(TABLE_MODULE)->where('path')->like("%,$param,%")->andWhere('type')->eq('story')->fetchPairs('id', 'id') : array();
|
||||
$stories = $this->dao->select('t1.*, t2.*')->from(TABLE_PROJECTSTORY)->alias('t1')
|
||||
$stories = $this->dao->select('t1.*, t2.*,t3.branch as productBranch,t4.type as productType')->from(TABLE_PROJECTSTORY)->alias('t1')
|
||||
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id')
|
||||
->leftJoin(TABLE_PROJECTPRODUCT)->alias('t3')->on('t1.project = t3.project')
|
||||
->leftJoin(TABLE_PRODUCT)->alias('t4')->on('t2.product = t4.id')
|
||||
->where('t1.project')->eq((int)$projectID)
|
||||
->beginIF($type == 'byProduct')->andWhere('t1.product')->eq($param)->fi()
|
||||
->beginIF($type == 'byModule' and $param)->andWhere('t2.module')->in($modules)->fi()
|
||||
@@ -1204,6 +1249,17 @@ class storyModel extends model
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
|
||||
$branches = array();
|
||||
foreach($stories as $story)
|
||||
{
|
||||
if(empty($story->branch) and $story->productType != 'normal') $branches[$story->productBranch][$story->id] = $story->id;
|
||||
}
|
||||
foreach($branches as $branchID => $storyIDList)
|
||||
{
|
||||
$stages = $this->dao->select('*')->from(TABLE_STORYSTAGE)->where('story')->in($storyIDList)->andWhere('branch')->eq($branchID)->fetchPairs('story', 'stage');
|
||||
foreach($stages as $storyID => $stage) $stories[$storyID]->stage = $stage;
|
||||
}
|
||||
return $stories;
|
||||
}
|
||||
|
||||
|
||||
@@ -159,7 +159,18 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->stage;?></th>
|
||||
<td><?php echo $lang->story->stageList[$story->stage];?></td>
|
||||
<td>
|
||||
<?php
|
||||
if($story->stages)
|
||||
{
|
||||
foreach($story->stages as $branch => $stage) echo $branches[$branch] . ' : ' . $lang->story->stageList[$stage] . '<br />';
|
||||
}
|
||||
else
|
||||
{
|
||||
echo $lang->story->stageList[$story->stage];
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->pri;?></th>
|
||||
|
||||
@@ -427,7 +427,7 @@ class testcase extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function createBug($productID, $extras = '')
|
||||
public function createBug($productID, $branch = 0, $extras = '')
|
||||
{
|
||||
parse_str(str_replace(array(',', ' '), array('&', ''), $extras));
|
||||
|
||||
@@ -445,13 +445,14 @@ class testcase extends control
|
||||
}
|
||||
|
||||
if(!$case) die(js::error($this->lang->notFound) . js::locate('back', 'parent'));
|
||||
if(empty($case->steps)) die(js::locate($this->createLink('bug', 'create', "product=$productID&extras=$extras"), 'parent'));
|
||||
if(empty($case->steps)) die(js::locate($this->createLink('bug', 'create', "product=$productID&branch=$branch&extras=$extras"), 'parent'));
|
||||
|
||||
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testcase->createBug;
|
||||
$this->view->case = $case;
|
||||
$this->view->result = reset($results);
|
||||
$this->view->extras = $extras;
|
||||
$this->view->productID = $productID;
|
||||
$this->view->branch = $branch;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.lite.html.php';?>
|
||||
<form action='<?php echo $this->createLink('bug', 'create', "product=$productID&extras=$extras")?>' target='_parent' method='post'>
|
||||
<form action='<?php echo $this->createLink('bug', 'create', "product=$productID&branch=$branch&extras=$extras")?>' target='_parent' method='post'>
|
||||
<table class='table table-condensed table-hover table-striped tablesorter table-fixed'>
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
@@ -49,14 +49,14 @@ class testtask extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function browse($productID = 0, $type = 'wait', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
public function browse($productID = 0, $branch = 0, $type = 'wait', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
/* Save session. */
|
||||
$this->session->set('testtaskList', $this->app->getURI(true));
|
||||
|
||||
/* Set menu. */
|
||||
$productID = $this->product->saveState($productID, $this->products);
|
||||
$this->testtask->setMenu($this->products, $productID);
|
||||
$this->testtask->setMenu($this->products, $productID, $branch);
|
||||
|
||||
/* Load pager. */
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
@@ -71,10 +71,11 @@ class testtask extends control
|
||||
$this->view->productID = $productID;
|
||||
$this->view->productName = $this->products[$productID];
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->tasks = $this->testtask->getProductTasks($productID, $sort, $pager, $type);
|
||||
$this->view->tasks = $this->testtask->getProductTasks($productID, $branch, $sort, $pager, $type);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed|noletter');
|
||||
$this->view->pager = $pager;
|
||||
$this->view->type = $type;
|
||||
$this->view->branch = $branch;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
@@ -132,7 +133,7 @@ class testtask extends control
|
||||
/* Create testtask from testtask of test.*/
|
||||
if($projectID == 0)
|
||||
{
|
||||
$projects = $this->product->getProjectPairs($productID, $params = 'nodeleted');
|
||||
$projects = $this->product->getProjectPairs($productID, $branch = 0, $params = 'nodeleted');
|
||||
$builds = $this->loadModel('build')->getProductBuildPairs($productID);
|
||||
}
|
||||
|
||||
@@ -186,7 +187,7 @@ class testtask extends control
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'bug');
|
||||
}
|
||||
|
||||
$this->testtask->setMenu($this->products, $productID);
|
||||
$this->testtask->setMenu($this->products, $productID, $task->branch);
|
||||
|
||||
$this->view->title = "TASK #$task->id $task->name/" . $this->products[$productID];
|
||||
$this->view->position[] = html::a($this->createLink('testtask', 'browse', "productID=$productID"), $this->products[$productID]);
|
||||
@@ -237,7 +238,7 @@ class testtask extends control
|
||||
$task = $this->testtask->getById($taskID);
|
||||
if(!$task) die(js::error($this->lang->notFound) . js::locate('back'));
|
||||
$productID = $task->product;
|
||||
$this->testtask->setMenu($this->products, $productID);
|
||||
$this->testtask->setMenu($this->products, $productID, $task->branch);
|
||||
if($browseType == 'bymodule' or $browseType == 'all')
|
||||
{
|
||||
$modules = '';
|
||||
@@ -301,6 +302,15 @@ class testtask extends control
|
||||
$this->config->testcase->search['params']['product']['values']= array($productID => $this->products[$productID], 'all' => $this->lang->testcase->allProduct);
|
||||
$this->config->testcase->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($productID, $viewType = 'case');
|
||||
$this->config->testcase->search['actionURL'] = inlink('cases', "taskID=$taskID&browseType=bySearch&queryID=myQueryID");
|
||||
if($this->session->currentProductType == 'normal')
|
||||
{
|
||||
unset($this->config->testcase->search['fields']['branch']);
|
||||
unset($this->config->testcase->search['params']['branch']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->config->testcase->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty');
|
||||
}
|
||||
$this->loadModel('search')->setSearchParams($this->config->testcase->search);
|
||||
|
||||
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testtask->cases;
|
||||
@@ -312,7 +322,7 @@ class testtask extends control
|
||||
$this->view->productName = $this->products[$productID];
|
||||
$this->view->task = $task;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed,nodeleted,qafirst');
|
||||
$this->view->moduleTree = $this->loadModel('tree')->getTreeMenu($productID, $viewType = 'case', $startModuleID = 0, array('treeModel', 'createTestTaskLink'), $extra = $taskID);
|
||||
$this->view->moduleTree = $this->loadModel('tree')->getTreeMenu($productID, $viewType = 'case', $startModuleID = 0, array('treeModel', 'createTestTaskLink'), $extra = $taskID, $task->branch);
|
||||
$this->view->browseType = $browseType;
|
||||
$this->view->param = $param;
|
||||
$this->view->orderBy = $orderBy;
|
||||
@@ -335,7 +345,7 @@ class testtask extends control
|
||||
$task = $this->testtask->getById($taskID);
|
||||
if(!$task) die(js::error($this->lang->notFound) . js::locate('back'));
|
||||
$productID = $task->product;
|
||||
$this->testtask->setMenu($this->products, $productID);
|
||||
$this->testtask->setMenu($this->products, $productID, $task->branch);
|
||||
|
||||
$runs = $this->testtask->getRuns($taskID, 0, $groupBy);
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'testcase', false);
|
||||
@@ -396,7 +406,7 @@ class testtask extends control
|
||||
$productID = $this->product->saveState($task->product, $this->products);
|
||||
|
||||
/* Set menu. */
|
||||
$this->testtask->setMenu($this->products, $productID);
|
||||
$this->testtask->setMenu($this->products, $productID, $task->branch);
|
||||
|
||||
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testtask->edit;
|
||||
$this->view->position[] = html::a($this->createLink('testtask', 'browse', "productID=$productID"), $this->products[$productID]);
|
||||
@@ -442,7 +452,7 @@ class testtask extends control
|
||||
$productID = $this->product->saveState($testtask->product, $this->products);
|
||||
|
||||
/* Set menu. */
|
||||
$this->testtask->setMenu($this->products, $productID);
|
||||
$this->testtask->setMenu($this->products, $productID, $testtask->branch);
|
||||
|
||||
$this->view->testtask = $testtask;
|
||||
$this->view->title = $testtask->name . $this->lang->colon . $this->lang->testtask->start;
|
||||
@@ -483,7 +493,7 @@ class testtask extends control
|
||||
$productID = $this->product->saveState($testtask->product, $this->products);
|
||||
|
||||
/* Set menu. */
|
||||
$this->testtask->setMenu($this->products, $productID);
|
||||
$this->testtask->setMenu($this->products, $productID, $testtask->branch);
|
||||
|
||||
$this->view->testtask = $this->testtask->getById($taskID);
|
||||
$this->view->title = $testtask->name . $this->lang->colon . $this->lang->close;
|
||||
@@ -562,10 +572,19 @@ class testtask extends control
|
||||
$this->config->testcase->search['params']['product']['values']= array($productID => $this->products[$productID], 'all' => $this->lang->testcase->allProduct);
|
||||
$this->config->testcase->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($productID, $viewType = 'case');
|
||||
$this->config->testcase->search['actionURL'] = inlink('linkcase', "taskID=$taskID");
|
||||
if($this->session->currentProductType == 'normal')
|
||||
{
|
||||
unset($this->config->testcase->search['fields']['branch']);
|
||||
unset($this->config->testcase->search['params']['branch']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->config->testcase->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty');
|
||||
}
|
||||
$this->loadModel('search')->setSearchParams($this->config->testcase->search);
|
||||
|
||||
/* Save session. */
|
||||
$this->testtask->setMenu($this->products, $productID);
|
||||
$this->testtask->setMenu($this->products, $productID, $task->branch);
|
||||
|
||||
$this->view->title = $task->name . $this->lang->colon . $this->lang->testtask->linkCase;
|
||||
$this->view->position[] = html::a($this->createLink('testtask', 'browse', "productID=$productID"), $this->products[$productID]);
|
||||
@@ -581,6 +600,7 @@ class testtask extends control
|
||||
$cases = $this->dao->select('*')->from(TABLE_CASE)->where($query)
|
||||
->andWhere('product')->eq($productID)
|
||||
->andWhere('id')->notIN($linkedCases)
|
||||
->andWhere('branch')->in("0,$task->branch")
|
||||
->andWhere('deleted')->eq(0)
|
||||
->orderBy('id desc')
|
||||
->page($pager)
|
||||
|
||||
@@ -21,10 +21,10 @@ class testtaskModel extends model
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function setMenu($products, $productID)
|
||||
public function setMenu($products, $productID, $branch = 0)
|
||||
{
|
||||
$this->loadModel('product')->setMenu($products, $productID);
|
||||
$selectHtml = $this->product->select($products, $productID, 'testtask', 'browse');
|
||||
$this->loadModel('product')->setMenu($products, $productID, $branch);
|
||||
$selectHtml = $this->product->select($products, $productID, 'testtask', 'browse', '', $branch);
|
||||
foreach($this->lang->testtask->menu as $key => $value)
|
||||
{
|
||||
$replace = ($key == 'product') ? $selectHtml : $productID;
|
||||
@@ -61,17 +61,20 @@ class testtaskModel extends model
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getProductTasks($productID, $orderBy = 'id_desc', $pager = null, $type = '')
|
||||
public function getProductTasks($productID, $branch = 0, $orderBy = 'id_desc', $pager = null, $type = '')
|
||||
{
|
||||
return $this->dao->select('t1.*, t2.name AS productName, t3.name AS projectName, t4.name AS buildName')
|
||||
return $this->dao->select('t1.*, t2.name AS productName, t3.name AS projectName, t4.name AS buildName, if(t4.branch, t4.branch, t5.branch) AS branch')
|
||||
->from(TABLE_TESTTASK)->alias('t1')
|
||||
->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t3')->on('t1.project = t3.id')
|
||||
->leftJoin(TABLE_BUILD)->alias('t4')->on('t1.build = t4.id')
|
||||
->leftJoin(TABLE_PROJECTPRODUCT)->alias('t5')->on('t1.project = t5.project')
|
||||
->where('t1.product')->eq((int)$productID)
|
||||
->andWhere('t5.product = t1.product')
|
||||
->andWhere('t1.deleted')->eq(0)
|
||||
->beginIF($type == 'wait')->andWhere('t1.status')->ne('done')->fi()
|
||||
->beginIF($type == 'done')->andWhere('t1.status')->eq('done')->fi()
|
||||
->beginIF($branch)->andWhere("if(t4.branch, t4.branch, t5.branch) = '$branch'")->fi()
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll();
|
||||
@@ -108,12 +111,15 @@ class testtaskModel extends model
|
||||
*/
|
||||
public function getById($taskID, $setImgSize = false)
|
||||
{
|
||||
$task = $this->dao->select('t1.*, t2.name AS productName, t3.name AS projectName, t4.name AS buildName')
|
||||
$task = $this->dao->select('t1.*, t2.name AS productName, t2.type AS productType, t3.name AS projectName, t4.name AS buildName, if(t4.branch, t4.branch, t5.branch) AS branch')
|
||||
->from(TABLE_TESTTASK)->alias('t1')
|
||||
->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t3')->on('t1.project = t3.id')
|
||||
->leftJoin(TABLE_BUILD)->alias('t4')->on('t1.build = t4.id')
|
||||
->where('t1.id')->eq((int)$taskID)->fetch();
|
||||
->leftJoin(TABLE_PROJECTPRODUCT)->alias('t5')->on('t1.project = t5.project')
|
||||
->where('t1.id')->eq((int)$taskID)
|
||||
->andWhere('t5.product = t1.product')
|
||||
->fetch();
|
||||
if($setImgSize) $task->desc = $this->loadModel('file')->setImgSize($task->desc);
|
||||
return $task;
|
||||
}
|
||||
|
||||
@@ -14,14 +14,14 @@
|
||||
<?php js::set('confirmDelete', $lang->testtask->confirmDelete)?>
|
||||
<div id="featurebar">
|
||||
<ul class="nav">
|
||||
<li id='waitTab'><?php echo html::a(inlink('browse', "productID=$productID&type=wait"), $lang->testtask->wait);?></li>
|
||||
<li id='doneTab'><?php echo html::a(inlink('browse', "productID=$productID&type=done"), $lang->testtask->done);?></li>
|
||||
<li id='waitTab'><?php echo html::a(inlink('browse', "productID=$productID&branch=$branch&type=wait"), $lang->testtask->wait);?></li>
|
||||
<li id='doneTab'><?php echo html::a(inlink('browse', "productID=$productID&branch=$branch&type=done"), $lang->testtask->done);?></li>
|
||||
</ul>
|
||||
<div class="actions"><?php common::printIcon('testtask', 'create', "product=$productID");?></div>
|
||||
</div>
|
||||
<table class='table tablesorter table-fixed' id='taskList'>
|
||||
<thead>
|
||||
<?php $vars = "productID=$productID&type=$type&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; ?>
|
||||
<?php $vars = "productID=$productID&branch=$branch&type=$type&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; ?>
|
||||
<tr>
|
||||
<th class='w-id'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
|
||||
<th> <?php common::printOrderLink('name', $orderBy, $vars, $lang->testtask->name);?></th>
|
||||
|
||||
@@ -81,7 +81,7 @@ var moduleID = '<?php echo $moduleID;?>';
|
||||
echo html::a("javascript:ajaxDelete(\"$unlinkURL\",\"caseList\",confirmUnlink)", '<i class="icon-unlink"></i>', '', "title='{$lang->testtask->unlinkCase}' class='btn-icon'");
|
||||
}
|
||||
|
||||
common::printIcon('testcase', 'createBug', "product=$productID&extra=projectID=$task->project,buildID=$task->build,caseID=$run->case,version=$run->version,runID=$run->id,testtask=$taskID", $run, 'list', 'bug', '', 'iframe');
|
||||
common::printIcon('testcase', 'createBug', "product=$productID&branch=$task->branch&extra=projectID=$task->project,buildID=$task->build,caseID=$run->case,version=$run->version,runID=$run->id,testtask=$taskID", $run, 'list', 'bug', '', 'iframe');
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -284,8 +284,9 @@ class treeModel extends model
|
||||
$treeMenu = array();
|
||||
$stmt = $this->dbh->query($this->buildMenuQuery($rootID, $type, $startModule, $branchID));
|
||||
while($module = $stmt->fetch()) $this->buildTree($treeMenu, $module, $type, $userFunc, $extra, $branchID);
|
||||
if($type == 'case' and !empty($extra) and empty($treeMenu)) continue;
|
||||
ksort($treeMenu);
|
||||
if(!empty($branchID) and $branchID != 'null')
|
||||
if(!empty($branchID) and $branch and $branchID != 'null')
|
||||
{
|
||||
$linkHtml = $manage ? html::a(inlink('browse', "root=$rootID&viewType=$type¤tModuleID=0&branch=$branchID"), $branch) : $this->createBranchLink($type, $rootID, $branchID, $branch);
|
||||
$lastMenu .= "<li>$linkHtml<ul>" . @array_shift($treeMenu) . "</ul></li>\n";
|
||||
@@ -472,7 +473,7 @@ class treeModel extends model
|
||||
{
|
||||
$modules = $this->getAllChildID($module->id);
|
||||
$runs = $this->testtask->getRuns($extra, $modules, 'id');
|
||||
if(empty($runs)) continue;
|
||||
if(empty($runs)) return;
|
||||
}
|
||||
|
||||
$extra['branchID'] = $branch;
|
||||
|
||||
Reference in New Issue
Block a user