-
+
@@ -49,8 +53,8 @@
recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
- '>
- testtask->product);?>
+ '>
+ '>testtask->product);?>
@@ -74,7 +78,7 @@
>
-
+ '>
diff --git a/module/group/model.php b/module/group/model.php
index f6affcba9e..0489768256 100644
--- a/module/group/model.php
+++ b/module/group/model.php
@@ -469,6 +469,23 @@ class groupModel extends model
{
$actions = $this->post->actions;
$oldGroup = $this->getByID($groupID);
+ $projects = isset($actions['projects']) ? $actions['projects'] : array();
+ $sprints = isset($actions['sprints']) ? $actions['sprints'] : array();
+
+ /* Add shadow productID when select noProduct project or execution. */
+ if($projects or $sprints)
+ {
+ /* Get all noProduct projects and executions . */
+ $noProductList = $this->loadModel('project')->getNoProductList();
+ $shadowProductIDList = $this->dao->select('id')->from(TABLE_PRODUCT)->where('shadow')->eq(1)->fetchPairs();
+ $noProductObjects = array_merge($projects, $sprints);
+
+ foreach($noProductObjects as $objectID)
+ {
+ if(isset($noProductList[$objectID])) $actions['products'][] = $noProductList[$objectID]->product;
+ }
+ }
+
if(isset($_POST['allchecker']))$actions['views'] = array();
if(!isset($actions['actions']))$actions['actions'] = array();
diff --git a/module/kanban/control.php b/module/kanban/control.php
index ceefd81560..2f28ee92ab 100644
--- a/module/kanban/control.php
+++ b/module/kanban/control.php
@@ -1195,9 +1195,22 @@ class kanban extends control
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
- $productPairs = $this->product->getPairs();
+ $productPairs = $this->product->getPairs('', 0, '', 'all');
$selectedProductID = empty($selectedProductID) ? key($productPairs) : $selectedProductID;
+ /* Waterfall project has no plan. */
+ $waterfallProducts = $this->dao->select('t1.product')->from(TABLE_PROJECTPRODUCT)->alias('t1')
+ ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
+ ->where('t2.type')->eq('project')
+ ->andWhere('t2.model')->eq('waterfall')
+ ->andWhere('t2.hasProduct')->eq('0')
+ ->fetchPairs();
+
+ foreach($productPairs as $id => $name)
+ {
+ if(isset($waterfallProducts[$id])) unset($productPairs[$id]);
+ }
+
$this->view->products = $productPairs;
$this->view->selectedProductID = $selectedProductID;
$this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID);
@@ -1247,7 +1260,7 @@ class kanban extends control
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
- $this->view->products = array($this->lang->kanban->allProducts) + $this->product->getPairs();
+ $this->view->products = array($this->lang->kanban->allProducts) + $this->product->getPairs('', 0, '', 'all');
$this->view->selectedProductID = $selectedProductID;
$this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID);
$this->view->releases2Imported = $this->release->getList($selectedProductID, 'all', 'all', 't1.date_desc', $pager);
diff --git a/module/port/control.php b/module/port/control.php
index 9daa51ee2b..e5bf7d6739 100755
--- a/module/port/control.php
+++ b/module/port/control.php
@@ -169,6 +169,7 @@ class port extends control
{
$product = $this->loadModel('product')->getByID($this->session->bugPortParams['productID']);
if($product->type == 'normal') unset($fields['branch']);
+ if($product->shadow and ($this->app->tab == 'execution' or $this->app->tab == 'project')) unset($fields['product']);
}
if($model == 'task') $datas = $this->task->processDatas4Task($datas);
$html = $this->port->buildNextList($datas->datas, $lastID, $fields, $pagerID, $model);
diff --git a/module/product/model.php b/module/product/model.php
index c2fb013e12..395687495c 100644
--- a/module/product/model.php
+++ b/module/product/model.php
@@ -1406,7 +1406,7 @@ class productModel extends model
public function getAllExecutionPairsByProduct($productID, $branch = 0, $projectID = 0)
{
if(empty($productID)) return array();
- $executions = $this->dao->select('t2.id,t2.project,t2.name,t2.grade,t2.parent,t2.hasProduct')->from(TABLE_PROJECTPRODUCT)->alias('t1')
+ $executions = $this->dao->select('t2.id,t2.project,t2.name,t2.grade,t2.parent')->from(TABLE_PROJECTPRODUCT)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
->where('t1.product')->eq($productID)
->andWhere('t2.type')->in('stage,sprint,kanban')
@@ -1426,7 +1426,7 @@ class productModel extends model
{
if($execution->grade == 2 && isset($executions[$execution->parent]))
{
- $execution->name = ($execution->hasProduct ? $projectPairs[$execution->project] . '/' : '') . $executions[$execution->parent]->name . '/' . $execution->name;
+ $execution->name = $projectPairs[$execution->project] . '/' . $executions[$execution->parent]->name . '/' . $execution->name;
$executions[$execution->parent]->children[$id] = $execution->name;
unset($executions[$id]);
}
@@ -1439,7 +1439,7 @@ class productModel extends model
$executionPairs = $executionPairs + $execution->children;
continue;
}
- if($this->config->systemMode == 'new' and isset($projectPairs[$execution->project])) $executionPairs[$execution->id] = ($execution->hasProduct ? $projectPairs[$execution->project] . '/' : '') . $execution->name;
+ if($this->config->systemMode == 'new' and isset($projectPairs[$execution->project])) $executionPairs[$execution->id] = $projectPairs[$execution->project] . '/' . $execution->name;
if($this->config->systemMode == 'classic') $executionPairs[$execution->id] = $execution->name;
}
diff --git a/module/program/model.php b/module/program/model.php
index 5c3c36218c..90c0ddf67f 100644
--- a/module/program/model.php
+++ b/module/program/model.php
@@ -66,10 +66,11 @@ class programModel extends model
* @param string $mode all|assign
* @param string $status all|noclosed
* @param string|array $append
+ * @param string|int $shadow all | 0 | 1
* @access public
* @return array
*/
- public function getProductPairs($programID = 0, $mode = 'assign', $status = 'all', $append = '')
+ public function getProductPairs($programID = 0, $mode = 'assign', $status = 'all', $append = '', $shadow = 0)
{
/* Get the top programID. */
if($programID)
@@ -86,8 +87,8 @@ class programModel extends model
$views = empty($append) ? $this->app->user->view->products : $this->app->user->view->products . ",$append";
$products = $this->dao->select('*')->from(TABLE_PRODUCT)
->where('deleted')->eq(0)
- ->andWhere('shadow')->eq(0)
->andWhere('vision')->eq($this->config->vision)
+ ->beginIF($shadow !== 'all')->andWhere('shadow')->eq((int)$shadow)->fi()
->beginIF($mode == 'assign')->andWhere('program')->eq($programID)->fi()
->beginIF(strpos($status, 'noclosed') !== false)->andWhere('status')->ne('closed')->fi()
->beginIF(!$this->app->user->admin)->andWhere('id')->in($views)->fi()
diff --git a/module/project/control.php b/module/project/control.php
index df020ebd52..d3ca2e1896 100644
--- a/module/project/control.php
+++ b/module/project/control.php
@@ -529,6 +529,7 @@ class project extends control
$products = array();
$productPlans = array();
+ $shadow = 0;
$parentProgram = $this->loadModel('program')->getByID($programID);
if($copyProjectID)
@@ -543,8 +544,9 @@ class project extends control
$programID = $copyProject->parent;
$model = $copyProject->model;
$hasProduct = $copyProject->hasProduct;
+ $products = $this->product->getProducts($copyProjectID);
- $products = $this->product->getProducts($copyProjectID);
+ if(!$copyProject->hasProduct) $shadow = 1;
foreach($products as $product)
{
foreach($product->branches as $branch)
@@ -573,7 +575,7 @@ class project extends control
$this->view->users = $this->user->getPairs('noclosed|nodeleted');
$this->view->copyProjects = $this->project->getPairsByModel($model);
$this->view->products = $products;
- $this->view->allProducts = array('0' => '') + $this->program->getProductPairs($programID, 'assign', 'noclosed');
+ $this->view->allProducts = array('0' => '') + $this->program->getProductPairs($programID, 'assign', 'noclosed', '', $shadow);
$this->view->productPlans = array('0' => '') + $productPlans;
$this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products), 'noclosed');
$this->view->programID = $programID;
@@ -1107,9 +1109,13 @@ class project extends control
$queryID = ($type == 'bysearch') ? (int)$param : 0;
$products = $this->product->getProducts($projectID);
+ if(!$project->hasProduct) unset($this->config->bug->search['fields']['product']);
+
$productPairs = array('0' => $this->lang->product->all);
foreach($products as $productData) $productPairs[$productData->id] = $productData->name;
- $this->lang->modulePageNav = $this->product->select($productPairs, $productID, 'project', 'bug', $projectID, $branchID);
+
+ $hasProduct = $this->dao->findByID($projectID)->from(TABLE_PROJECT)->fetch('hasProduct');
+ if($hasProduct) $this->lang->modulePageNav = $this->product->select($productPairs, $productID, 'project', 'bug', $projectID, $branchID);
/* Header and position. */
$title = $project->name . $this->lang->colon . $this->lang->bug->common;
@@ -1247,7 +1253,9 @@ class project extends control
$products = array('0' => $this->lang->product->all) + $this->product->getProducts($projectID, 'all', '', false);
$extra = "$projectID,$browseType";
- $this->lang->modulePageNav = $this->product->select($products, $productID, 'project', 'testcase', $extra, $branch);
+
+ $hasProduct = $this->dao->findByID($projectID)->from(TABLE_PROJECT)->fetch('hasProduct');
+ if($hasProduct) $this->lang->modulePageNav = $this->product->select($products, $productID, 'project', 'testcase', $extra, $branch);
echo $this->fetch('testcase', 'browse', "productID=$productID&branch=$branch&browseType=$browseType¶m=$param&orderBy=$orderBy&recTotal=$orderBy&recPerPage=$recPerPage&pageID=$pageID&projectID=$projectID");
}
diff --git a/module/project/css/testtask.css b/module/project/css/testtask.css
index 7d167eb581..36c6fbf838 100644
--- a/module/project/css/testtask.css
+++ b/module/project/css/testtask.css
@@ -1,7 +1,7 @@
.table-group-btns {width: 200px;}
.table-footer,
.table-grouped {box-shadow: none !important;}
-.table-footer {margin-left: 205px; margin-top: 10px;}
+.table-footer {margin-top: 10px;}
.table-grouped > thead>tr>th.c-id,
.table-grouped > tbody>tr>td.c-id {padding-left: 15px;}
.table-grouped > tbody>tr>td {overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
diff --git a/module/project/model.php b/module/project/model.php
index 078b6989ab..10f8fd2a70 100644
--- a/module/project/model.php
+++ b/module/project/model.php
@@ -173,6 +173,23 @@ class projectModel extends model
return $project;
}
+ /**
+ * Get a project by its shadow product.
+ *
+ * @param int $product
+ * @access public
+ * @return object
+ */
+ public function getByShadowProduct($product)
+ {
+ return $this->dao->select('t2.*')->from(TABLE_PROJECTPRODUCT)->alias('t1')
+ ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project=t2.id')
+ ->where('t1.product')->eq($product)
+ ->andWhere('t2.type')->eq('project')
+ ->limit(1)
+ ->fetch();
+ }
+
/**
* Get project info.
*
diff --git a/module/project/view/testtask.html.php b/module/project/view/testtask.html.php
index bae7bc849e..ffae1bd462 100644
--- a/module/project/view/testtask.html.php
+++ b/module/project/view/testtask.html.php
@@ -12,9 +12,12 @@
?>
testtask->confirmDelete)?>
+hasProduct):?>
+
+
testtask->allTasks;?>
-
+ hasProduct):?>
@@ -49,8 +52,8 @@
recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
- '>
- testtask->product);?>
+ '>
+ '>testtask->product);?>
idAB);?>
@@ -69,7 +72,7 @@
>
-
+ '>
diff --git a/module/story/control.php b/module/story/control.php
index 73b27b5193..9d3f7f9975 100755
--- a/module/story/control.php
+++ b/module/story/control.php
@@ -864,19 +864,14 @@ class story extends control
$this->view->hiddenURS = false;
$this->view->teamUsers = array();
- if($this->app->tab === 'project' || $this->app->tab === 'execution')
+ if($product->shadow)
{
- $project = $this->dao->findById((int)$objectID)->from(TABLE_PROJECT)->fetch();
- if(!empty($project->project)) $project = $this->dao->findById((int)$project->project)->from(TABLE_PROJECT)->fetch();
+ $project = $this->project->getByShadowProduct($product->id);
+ $this->view->teamUsers = $this->project->getTeamMemberPairs($project->id);
+ $this->view->hiddenProduct = true;
- if(empty($project->hasProduct))
- {
- $this->view->teamUsers = $this->project->getTeamMemberPairs($project->id);
- $this->view->hiddenProduct = true;
-
- if($project->model !== 'scrum') $this->view->hiddenPlan = true;
- if($project->model === 'kanban') $this->view->hiddenURS = true;
- }
+ if($project->model !== 'scrum') $this->view->hiddenPlan = true;
+ if($project->model === 'kanban') $this->view->hiddenURS = true;
}
/* Display status of branch. */
diff --git a/module/testcase/control.php b/module/testcase/control.php
index 911e6d6b78..1a23a638f8 100644
--- a/module/testcase/control.php
+++ b/module/testcase/control.php
@@ -118,6 +118,8 @@ class testcase extends control
$linkedProducts = $this->product->getProducts($projectID, 'all', '', false);
$this->products = count($linkedProducts) > 1 ? array('0' => $this->lang->product->all) + $linkedProducts : $linkedProducts;
$productID = count($linkedProducts) > 1 ? $productID : key($linkedProducts);
+ $hasProduct = $this->dao->findById($projectID)->from(TABLE_PROJECT)->fetch('hasProduct');
+ if(!$hasProduct) unset($this->config->testcase->search['fields']['product']);
$this->loadModel('project')->setMenu($projectID);
}
@@ -1596,6 +1598,8 @@ class testcase extends control
$product = $this->loadModel('product')->getById($productID);
$products = $this->loadModel('product')->getPairs('', 0, '', 'all');
if($product->type != 'normal') $this->lang->testcase->branch = $this->lang->product->branchName[$product->type];
+ if($product->shadow and $this->app->tab == 'project') $this->config->testcase->exportFields = str_replace('product,', '', $this->config->testcase->exportFields);
+
if($_POST)
{
$this->loadModel('file');
testtask->allTasks;?>