* finish task #2346 2347 2348.

This commit is contained in:
wangyidong
2015-10-28 14:33:06 +08:00
parent 7960c73e1b
commit e1d907628c
13 changed files with 120 additions and 74 deletions
+1
View File
@@ -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`');
+5
View File
@@ -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
);
+1 -1
View File
@@ -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;
}
+4 -5
View File
@@ -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);
+1 -5
View File
@@ -12,11 +12,7 @@ function loadBranches(productID)
{
$('#product').closest('.input-group').append(data);
$('#branch').css('width', '100px');
for(i in productGroups[productID]['branches'])
{
$('#branch').val(i);
break;
}
$('#branch').val(productGroups[productID]['branch']);
}
});
}
+1 -1
View File
@@ -28,7 +28,7 @@
<?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') echo html::select('branch', $branches, $product->branch, "class='form-control' style='width:100px'");?>
</div>
<?php endif;?>
</td>
+1 -1
View File
@@ -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);
+5 -29
View File
@@ -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;
}
}
+2 -2
View File
@@ -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>';
}
?>
+3 -1
View File
@@ -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');
+5 -3
View File
@@ -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();
}
}
/**
+79 -25
View File
@@ -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;
}
@@ -1136,7 +1177,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 +1236,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 +1247,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;
}
+12 -1
View File
@@ -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>