@@ -43,32 +43,41 @@
idAB;?>
release->name;?>
- release->project;?>
- release->build;?>
+ release->includedBuild;?>
+ release->relatedProject;?>
release->date;?>
+
+ builds);?>
+ builds as $build):?>
-
+
+
id);?>
-
-
+
+
name;?>
+
+ name;?>
+
-
- name;?>
- projectName;?>
- buildName;?>
- date;?>
+ name;?>
+ projectName;?>
+
+ date;?>
+
+
+
@@ -83,5 +92,4 @@
noData;?>
-
diff --git a/module/message/model.php b/module/message/model.php
index 03cc3f6639..72ca92a564 100755
--- a/module/message/model.php
+++ b/module/message/model.php
@@ -66,6 +66,8 @@ class messageModel extends model
*/
public function send($objectType, $objectID, $actionType, $actionID, $actor = '', $extra = '')
{
+ if(defined('TUTORIAL')) return;
+
$objectType = strtolower($objectType);
$messageSetting = $this->config->message->setting;
if(is_string($messageSetting)) $messageSetting = json_decode($messageSetting, true);
diff --git a/module/misc/lang/de.php b/module/misc/lang/de.php
index e892681bf2..70525fda4d 100644
--- a/module/misc/lang/de.php
+++ b/module/misc/lang/de.php
@@ -47,8 +47,8 @@ $lang->misc->zentao->cowin['feedback'] = "Feedback";
$lang->misc->zentao->cowin['recommend'] = "More";
$lang->misc->zentao->service['zentaotrain'] = 'ZenTao Training';
-$lang->misc->zentao->service['idc'] = 'Zentao Cloud';
-$lang->misc->zentao->service['custom'] = 'Zentao Custom';
+$lang->misc->zentao->service['idc'] = 'ZenTao Cloud';
+$lang->misc->zentao->service['custom'] = 'ZenTao Custom';
global $config;
$lang->misc->zentao->others['chanzhi'] = " Zsite";
@@ -100,7 +100,7 @@ $lang->misc->feature->close = 'Close';
$lang->misc->feature->downloadFile = 'Download introduction';
$lang->misc->feature->tutorialDesc = 'ZenTao 15.0 has new functions, and you know how to use it through the "Tutorial ".
Click your [Avatar-Theme-Young Blue ] to set it.
';
$lang->misc->feature->themeDesc = 'ZenTao 15.0+ a new "Youth Blue" theme, the pages are more beautiful and the experience is more friendly.
Click your [Avatar-Theme-Young Blue ] to set it.
';
-$lang->misc->feature->visionsDesc = "The concept of interface has been added since 16.5. Users can deal with R & D affairs in [R&D] and daily office affairs in [Lite] .
You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.
";
+$lang->misc->feature->visionsDesc = "The concept of interface has been added since 16.5. Users can deal with R&D affairs in [Full Feature Interface] and daily office affairs in [Operation Management Interface] .
You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.
";
$lang->misc->feature->visionsImage = 'theme/default/images/main/visions_en.png';
$lang->misc->releaseDate['17.8'] = '2022-11-02';
@@ -225,7 +225,7 @@ $lang->misc->feature->all['15.0.3'][] = array('title' => 'Fix Bug', 'desc'
$lang->misc->feature->all['15.0.2'][] = array('title' => 'Fix Bug', 'desc' => '');
$lang->misc->feature->all['15.0.1'][] = array('title' => 'Fix Bug', 'desc' => '');
$lang->misc->feature->all['15.0'][] = array('title' => 'Fix Bug', 'desc' => '');
-$lang->misc->feature->all['15.0.rc3'][] = array('title' => 'Adjust details,Fix bug', 'desc' => '');
+$lang->misc->feature->all['15.0.rc3'][] = array('title' => 'Adjust details, fix bug.', 'desc' => '');
$lang->misc->feature->all['15.0.rc2'][] = array('title' => 'Fix Bug.', 'desc' => '');
$lang->misc->feature->all['15.0.rc1'][] = array('title' => 'Upgrade to 15,reframe menu, add program.', 'desc' => '');
$lang->misc->feature->all['12.5.3'][] = array('title' => 'Adjust annual data.', 'desc' => '');
diff --git a/module/misc/lang/en.php b/module/misc/lang/en.php
index b63f934519..fb0e92e185 100644
--- a/module/misc/lang/en.php
+++ b/module/misc/lang/en.php
@@ -100,7 +100,7 @@ $lang->misc->feature->close = 'Close';
$lang->misc->feature->downloadFile = 'Download introduction';
$lang->misc->feature->tutorialDesc = 'ZenTao 15.0 has new functions, and you know how to use it through the "Tutorial ".
Click your [Avatar-Theme-Young Blue ] to set it.
';
$lang->misc->feature->themeDesc = 'ZenTao 15.0+ a new "Youth Blue" theme, the pages are more beautiful and the experience is more friendly.
Click your [Avatar-Theme-Young Blue ] to set it.
';
-$lang->misc->feature->visionsDesc = "The concept of interface has been added since 16.5. Users can deal with R & D affairs in [R&D] and daily office affairs in [Lite] .
You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.
";
+$lang->misc->feature->visionsDesc = "The concept of interface has been added since 16.5. Users can deal with R&D affairs in [Full Feature Interface] and daily office affairs in [Operation Management Interface] .
You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.
";
$lang->misc->feature->visionsImage = 'theme/default/images/main/visions_en.png';
$lang->misc->releaseDate['17.8'] = '2022-11-02';
@@ -223,9 +223,9 @@ $lang->misc->feature->all['15.2'][] = array('title' => 'Optimize the new v
$lang->misc->feature->all['15.0.3'][] = array('title' => 'Fix Bug', 'desc' => '');
$lang->misc->feature->all['15.0.2'][] = array('title' => 'Fix Bug', 'desc' => '');
-$lang->misc->feature->all['15.0.1'][] = array('title' => 'Fix bug', 'desc' => '');
-$lang->misc->feature->all['15.0'][] = array('title' => 'Fix bug', 'desc' => '');
-$lang->misc->feature->all['15.0.rc3'][] = array('title' => 'Adjust details,Fix bug', 'desc' => '');
+$lang->misc->feature->all['15.0.1'][] = array('title' => 'Fix Bug', 'desc' => '');
+$lang->misc->feature->all['15.0'][] = array('title' => 'Fix Bug', 'desc' => '');
+$lang->misc->feature->all['15.0.rc3'][] = array('title' => 'Adjust details, fix bug.', 'desc' => '');
$lang->misc->feature->all['15.0.rc2'][] = array('title' => 'Fix Bug.', 'desc' => '');
$lang->misc->feature->all['15.0.rc1'][] = array('title' => 'Upgrade to 15,reframe menu, add program.', 'desc' => '');
$lang->misc->feature->all['12.5.3'][] = array('title' => 'Adjust annual data.', 'desc' => '');
diff --git a/module/misc/lang/fr.php b/module/misc/lang/fr.php
index 0bc2366d43..7b47d01dc1 100644
--- a/module/misc/lang/fr.php
+++ b/module/misc/lang/fr.php
@@ -47,8 +47,8 @@ $lang->misc->zentao->cowin['feedback'] = "Feedback";
$lang->misc->zentao->cowin['recommend'] = "Plus...";
$lang->misc->zentao->service['zentaotrain'] = 'ZenTao Training';
-$lang->misc->zentao->service['idc'] = 'Zentao Cloud';
-$lang->misc->zentao->service['custom'] = 'Zentao Custom';
+$lang->misc->zentao->service['idc'] = 'ZenTao Cloud';
+$lang->misc->zentao->service['custom'] = 'ZenTao Custom';
global $config;
$lang->misc->zentao->others['chanzhi'] = " Zsite";
@@ -100,7 +100,7 @@ $lang->misc->feature->close = 'Close';
$lang->misc->feature->downloadFile = 'Download introduction';
$lang->misc->feature->tutorialDesc = 'ZenTao 15.0 has new functions, and you know how to use it through the "Tutorial ".
Click your [Avatar-Theme-Young Blue ] to set it.
';
$lang->misc->feature->themeDesc = 'ZenTao 15.0+ a new "Youth Blue" theme, the pages are more beautiful and the experience is more friendly.
Click your [Avatar-Theme-Young Blue ] to set it.
';
-$lang->misc->feature->visionsDesc = "The concept of interface has been added since 16.5. Users can deal with R & D affairs in [R&D] and daily office affairs in [Lite] .
You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.
";
+$lang->misc->feature->visionsDesc = "The concept of interface has been added since 16.5. Users can deal with R&D affairs in [Full Feature Interface] and daily office affairs in [Operation Management Interface] .
You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.
";
$lang->misc->feature->visionsImage = 'theme/default/images/main/visions_en.png';
$lang->misc->releaseDate['17.8'] = '2022-11-02';
diff --git a/module/misc/lang/zh-cn.php b/module/misc/lang/zh-cn.php
index d5b2ef9cc6..f9dcacc66a 100644
--- a/module/misc/lang/zh-cn.php
+++ b/module/misc/lang/zh-cn.php
@@ -100,7 +100,7 @@ $lang->misc->feature->close = '关闭';
$lang->misc->feature->downloadFile = '下载新版本功能介绍文档';
$lang->misc->feature->tutorialDesc = "禅道15系列新增了多项功能,您可以通过“新手引导教程 ”快速了解禅道的基本使用方法。
通过鼠标经过 [头像-新手引导 ],点击新手引导,即可进入新手引导教程。
";
$lang->misc->feature->themeDesc = "禅道15系列上线了全新的“青春蓝”主题,页面呈现更加美观,体验更加友好。
通过鼠标经过 [头像-主题-青春蓝 ],点击青春蓝,即可设置成功。
";
-$lang->misc->feature->visionsDesc = "从16.5开始增加了界面概念,用户可以在[研发综合界面] 中处理研发事务、在[迅捷界面] 处理日常办公事务。
在头像右侧即可查看当前所处界面,点击当前界面名称可查看和切换其他的界面。
";
+$lang->misc->feature->visionsDesc = "从16.5开始增加了界面概念,用户可以在[研发综合界面] 中处理研发事务、在[运营管理界面] 处理日常办公事务。
在头像右侧即可查看当前所处界面,点击当前界面名称可查看和切换其他的界面。
";
$lang->misc->feature->visionsImage = 'theme/default/images/main/visions.png';
$lang->misc->releaseDate['17.8'] = '2022-11-02';
diff --git a/module/my/model.php b/module/my/model.php
index 926ec8e9a9..3a432a791d 100644
--- a/module/my/model.php
+++ b/module/my/model.php
@@ -1301,6 +1301,7 @@ class myModel extends model
$review->time = $action->date;
$review->result = strtolower($action->extra);
$review->status = $objectType == 'attend' ? $object->reviewStatus : $object->status;
+ if(strpos($review->result, ',') !== false) list($review->result) = explode(',', $review->result);
if($review->type == 'review') $review->type = 'project';
if($review->type == 'case') $review->type = 'testcase';
diff --git a/module/my/view/audit.html.php b/module/my/view/audit.html.php
index 3d9d3bc8a4..3a999df645 100644
--- a/module/my/view/audit.html.php
+++ b/module/my/view/audit.html.php
@@ -55,7 +55,7 @@
$type = $review->type;
if($type == 'project') $type = 'review';
- $typeName = $lang->$type->common;
+ $typeName = $lang->{$review->type}->common;
if($type == 'story') $typeName = $lang->my->auditMenu->audit->story;
$statusList = $lang->$type->statusList;
diff --git a/module/my/view/task.html.php b/module/my/view/task.html.php
index 64caf5f5e8..950103d321 100644
--- a/module/my/view/task.html.php
+++ b/module/my/view/task.html.php
@@ -104,15 +104,16 @@
' title='name?>'>
team)) echo '' . $this->lang->task->multipleAB . ' ';?>
executionMultiple) ? 'project' : 'execution';
if($task->parent > 0)
{
- echo '' . $this->lang->task->childrenAB . ' ' . html::a($this->createLink('task', 'view', "taskID=$task->id", '', '', $task->project), $task->parentName . ' / '. $task->name, '', "title='{$task->parentName} / {$task->name}'");
+ echo '' . $this->lang->task->childrenAB . ' ' . html::a($this->createLink('task', 'view', "taskID=$task->id", '', '', $task->project), $task->parentName . ' / '. $task->name, '', "title='{$task->parentName} / {$task->name}' data-app='$dataApp'");
}
else
{
$onlybody = $task->executionType == 'kanban' ? true : '';
$class = $task->executionType == 'kanban' ? 'iframe' : '';
- echo html::a($this->createLink('task', 'view', "taskID=$task->id", '', $onlybody, $task->project), $task->name, null, "class='$class' data-width='80%' style='color: $task->color'");
+ echo html::a($this->createLink('task', 'view', "taskID=$task->id", '', $onlybody, $task->project), $task->name, null, "class='$class' data-width='80%' style='color: $task->color' data-app='$dataApp'");
}
?>
children)) echo ' ';?>
@@ -189,8 +190,9 @@
id);?>
+ executionMultiple) ? 'project' : 'execution';?>
parent > 0) echo '' . $this->lang->task->childrenAB . ' ';?>
- createLink('task', 'view', "taskID=$child->id", '', '', $child->project), $child->name, null, "style='color: $child->color'");?>
+ createLink('task', 'view', "taskID=$child->id", '', '', $child->project), $child->name, null, "style='color: $child->color' data-app='$dataApp'");?>
pri;?>' title='task->priList, $child->pri);?>'>task->priList, $child->pri);?>
diff --git a/module/product/config.php b/module/product/config.php
index eca608a237..da591a9343 100644
--- a/module/product/config.php
+++ b/module/product/config.php
@@ -3,13 +3,13 @@ $config->product = new stdclass();
$config->product->orderBy = 'isClosed,program_asc,order_asc';
$config->product->showAllProjects = 0;
-$config->product->customBatchEditFields = 'line,PO,QD,RD,status,type,acl';
-if($config->systemMode == 'ALM') $config->product->customBatchEditFields = 'program,' . $config->product->customBatchEditFields;
+$config->product->customBatchEditFields = 'PO,QD,RD,status,type,acl';
+if($config->systemMode == 'ALM') $config->product->customBatchEditFields = 'program,line,' . $config->product->customBatchEditFields;
$config->product->browse = new stdclass();
$config->product->custom = new stdclass();
-$config->product->custom->batchEditFields = 'line,PO,QD,RD';
-if($config->systemMode == 'ALM') $config->product->custom->batchEditFields .= ',program';
+$config->product->custom->batchEditFields = 'PO,QD,RD';
+if($config->systemMode == 'ALM') $config->product->custom->batchEditFields .= ',program,line';
$config->product->list = new stdclass();
$config->product->list->exportFields = 'id,program,line,name,manager,draftStories,activeStories,changedStories,reviewingStories,closedStories,storyCompleteRate,bugs,unResolvedBugs,assignToNullBugs,bugFixedRate,plans,releases';
@@ -115,8 +115,11 @@ $config->product->all->search['fields']['createdBy'] = $lang->product->created
$config->product->all->search['params']['name'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
if(!isset($config->setCode) or $config->setCode == 1) $config->product->all->search['params']['code'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
$config->product->all->search['params']['id'] = array('operator' => '=', 'control' => 'input', 'values' => '');
-if($config->systemMode == 'ALM') $config->product->all->search['params']['program'] = array('operator' => '=', 'control' => 'select', 'values' => '');
-$config->product->all->search['params']['line'] = array('operator' => '=', 'control' => 'select', 'values' => '');
+if($config->systemMode == 'ALM')
+{
+ $config->product->all->search['params']['program'] = array('operator' => '=', 'control' => 'select', 'values' => '');
+ $config->product->all->search['params']['line'] = array('operator' => '=', 'control' => 'select', 'values' => '');
+}
$config->product->all->search['params']['desc'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
$config->product->all->search['params']['PO'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
$config->product->all->search['params']['QD'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
diff --git a/module/product/control.php b/module/product/control.php
index d14444e506..8f701aee51 100755
--- a/module/product/control.php
+++ b/module/product/control.php
@@ -100,7 +100,7 @@ class product extends control
$accounts = array();
$projectStats = $this->product->getProjectStatsByProduct($productID, $status, $branch, $involved, $orderBy, $pager);
$product = $this->product->getByID($productID);
- $projects = $this->project->getPairsByProgram($product->program, 'all', false, 'order_asc');
+ $projects = $this->project->getPairsByProgram($product->program, 'all', false, 'order_asc', '', '', 'product');
foreach($projectStats as $project)
{
@@ -110,8 +110,6 @@ class product extends control
$PMList = $this->user->getListByAccounts($accounts, 'account');
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->product->project;
- $this->view->position[] = $this->products[$productID];
- $this->view->position[] = $this->lang->product->project;
$this->view->projectStats = $projectStats;
$this->view->PMList = $PMList;
$this->view->productID = $productID;
diff --git a/module/product/model.php b/module/product/model.php
index 5ec816a474..3bb5714f04 100644
--- a/module/product/model.php
+++ b/module/product/model.php
@@ -1235,10 +1235,11 @@ class productModel extends model
* @param int $branch
* @param int $appendProject
* @param string $status all|closed|unclosed
+ * @param string $param multiple|
* @access public
* @return array
*/
- public function getProjectPairsByProduct($productID, $branch = 0, $appendProject = 0, $status = '')
+ public function getProjectPairsByProduct($productID, $branch = 0, $appendProject = 0, $status = '', $param = '')
{
$product = $this->getById($productID);
@@ -1246,6 +1247,7 @@ class productModel extends model
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
->where('t1.product')->eq($productID)
->beginIF($status == 'closed')->andWhere('t2.status')->ne('closed')->fi()
+ ->beginIF(strpos($param, 'multiple') !== false)->andWhere('t2.multiple')->ne('0')->fi()
->andWhere('t2.type')->eq('project')
->beginIF(!$this->app->user->admin)->andWhere('t2.id')->in($this->app->user->view->projects)->fi()
->beginIF($product->type != 'normal' and $branch !== '')->andWhere('t1.branch')->in($branch)->fi()
diff --git a/module/productplan/control.php b/module/productplan/control.php
index 7d3f57f94c..d0dd0b3263 100644
--- a/module/productplan/control.php
+++ b/module/productplan/control.php
@@ -370,7 +370,7 @@ class productplan extends control
$this->view->orderBy = $orderBy;
$this->view->plans = $this->productplan->getList($productID, $branch, $browseType, $pager, $sort, "", $queryID);
$this->view->pager = $pager;
- $this->view->projects = $this->product->getProjectPairsByProduct($productID, $branch, '', $status = 'closed');
+ $this->view->projects = $this->product->getProjectPairsByProduct($productID, $branch, '', $status = 'closed', 'multiple');
$this->view->statusList = $this->lang->productplan->featureBar['browse'];
$this->view->queryID = $queryID;
$this->display();
@@ -627,7 +627,7 @@ class productplan extends control
*/
public function ajaxGetProjects($productID, $branch = 0)
{
- $projects = $this->loadModel('product')->getProjectPairsByProduct($productID, $branch, '', $status = 'closed');
+ $projects = $this->loadModel('product')->getProjectPairsByProduct($productID, $branch, '', $status = 'closed', 'multiple');
echo html::select('project', $projects, key($projects), "class='form-control chosen'");
}
diff --git a/module/program/model.php b/module/program/model.php
index 5f2e52dc9a..fb3fb0dbc1 100644
--- a/module/program/model.php
+++ b/module/program/model.php
@@ -67,10 +67,11 @@ class programModel extends model
* @param string $status all|noclosed
* @param string|array $append
* @param string|int $shadow all | 0 | 1
+ * @param bool $withProgram
* @access public
* @return array
*/
- public function getProductPairs($programID = 0, $mode = 'assign', $status = 'all', $append = '', $shadow = 0)
+ public function getProductPairs($programID = 0, $mode = 'assign', $status = 'all', $append = '', $shadow = 0, $withProgram = false)
{
/* Get the top programID. */
if($programID)
@@ -84,72 +85,40 @@ class programModel extends model
if(!empty($append) and is_array($append)) $append = implode(',', $append);
$views = empty($append) ? $this->app->user->view->products : $this->app->user->view->products . ",$append";
- return $this->dao->select('*')->from(TABLE_PRODUCT)
+ $dao = $this->dao->select('id, name, program')->from(TABLE_PRODUCT)
->where('deleted')->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()
- ->fetchPairs('id', 'name');
- }
+ ->beginIF(!$this->app->user->admin)->andWhere('id')->in($views)->fi();
- /**
- * Get product pairs which name with program.
- *
- * @param int $programID
- * @param string $mode
- * @param string $status
- * @param string $append
- * @param int $shadow
- * @access public
- * @return array
- */
- public function getProductPairsWithProgram($programID = 0, $mode = 'assign', $status = 'all', $append = '', $shadow = 0)
- {
- /* Get the top programID. */
- if($programID)
- {
- $program = $this->getByID($programID);
- $path = array_filter(explode(',', $program->path));
- $programID = current($path);
- }
+ if(!$withProgram) return $dao->fetchPairs('id', 'name');
- /* When mode equals assign and programID equals 0, you can query the standalone product. */
- if(!empty($append) and is_array($append)) $append = implode(',', $append);
- $views = empty($append) ? $this->app->user->view->products : $this->app->user->view->products . ",$append";
-
- $products = $this->dao->select("t1.id, t1.program, CONCAT(IF(t2.name IS NOT NULL, t2.name, ''), '/', t1.name) AS name")->from(TABLE_PRODUCT)->alias('t1')
- ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.program = t2.id')
- ->where('t1.deleted')->eq('0')
- ->andWhere('t1.vision')->eq($this->config->vision)
- ->beginIF($shadow !== 'all')->andWhere('t1.shadow')->eq((int)$shadow)->fi()
- ->beginIF($mode == 'assign')->andWhere('t1.program')->eq($programID)->fi()
- ->beginIF(strpos($status, 'noclosed') !== false)->andWhere('t1.status')->ne('closed')->fi()
- ->beginIF(!$this->app->user->admin)->andWhere('t1.id')->in($views)->fi()
- ->orderBy('t1.program, t1.order_asc')
- ->fetchGroup('program');
+ $products = $dao->orderBy('program,order')->fetchGroup('program');
+ $productPrograms = $this->dao->select('id, name')->from(TABLE_PROJECT)->where('type')->eq('program')->andWhere('deleted')->eq('0')->fetchPairs();
/* Put products of current program first.*/
if($mode != 'assign' && $programID)
{
$currentProgramProducts = $products[$programID];
-
unset($products[$programID]);
-
array_unshift($products, $currentProgramProducts);
}
$productPairs = array();
foreach($products as $programProducts)
{
- foreach($programProducts as $product) $productPairs[$product->id] = $product->name;
+ foreach($programProducts as $product)
+ {
+ $programName = zget($productPrograms, $product->program, '') . '/';
+ $productPairs[$product->id] = $programName . $product->name;
+ }
}
return $productPairs;
}
-
/**
* Get program by id.
*
diff --git a/module/project/config.php b/module/project/config.php
index afbb5e6010..d3149df35e 100644
--- a/module/project/config.php
+++ b/module/project/config.php
@@ -11,7 +11,8 @@ $config->project->editor->activate = array('id' => 'comment', 'tools' => 'simple
$config->project->editor->view = array('id' => 'lastComment', 'tools' => 'simpleTools');
$config->project->list = new stdclass();
-$config->project->list->exportFields = 'id,parent,code,name,hasProduct,linkedProducts,status,begin,end,budget,PM,end,desc';
+$config->project->list->exportFields = 'id,code,name,hasProduct,linkedProducts,status,begin,end,budget,PM,end,desc';
+if($config->systemMode == 'ALM') $config->project->list->exportFields = substr_replace($config->project->list->exportFields, ',parent', 2, 0);
$config->project->create = new stdclass();
$config->project->edit = new stdclass();
diff --git a/module/project/control.php b/module/project/control.php
index 0d712bdd9a..3f5574ef39 100755
--- a/module/project/control.php
+++ b/module/project/control.php
@@ -283,7 +283,8 @@ class project extends control
if($objectType == 'program')
{
- $allProducts = array(0 => '') + $this->program->getProductPairsWithProgram($selectedProgramID, 'all', 'noclosed');
+ $withProgram = $this->config->systemMode == 'ALM' ? true : false;
+ $allProducts = array(0 => '') + $this->program->getProductPairs($selectedProgramID, 'all', 'noclosed', '', 0, $withProgram);
$data['allProducts'] = html::select("products[]", $allProducts, '', "class='form-control chosen' onchange='loadBranches(this)'");
$data['plans'] = html::select('plans[][][]', '', '', 'class=\'form-control chosen\' multiple');
}
@@ -603,13 +604,16 @@ class project extends control
$this->config->executionCommonList[$this->app->getClientLang()][0] :
$this->config->executionCommonList[$this->app->getClientLang()][1];
+ $withProgram = $this->config->systemMode == 'ALM' ? true : false;
+ $allProducts = array('0' => '') + $this->program->getProductPairs($programID, 'all', 'noclosed', '', $shadow, $withProgram);
+
$this->view->title = $this->lang->project->create;
$this->view->gobackLink = (isset($output['from']) and $output['from'] == 'global') ? $this->createLink('project', 'browse') : '';
$this->view->pmUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst');
$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->getProductPairsWithProgram(0, 'all', 'noclosed', '', $shadow);
+ $this->view->allProducts = $allProducts;
$this->view->productPlans = array('0' => '') + $productPlans;
$this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products), 'noclosed');
$this->view->programID = $programID;
@@ -713,12 +717,14 @@ class project extends control
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $locateLink));
}
+ $withProgram = $this->config->systemMode == 'ALM' ? true : false;
+
$linkedBranches = array();
$linkedBranchList = array();
$productPlans = array(0 => '');
$branches = $this->project->getBranchesByProject($projectID);
$linkedProductIdList = empty($branches) ? '' : array_keys($branches);
- $allProducts = $this->program->getProductPairsWithProgram($project->parent, 'all', 'noclosed');
+ $allProducts = $this->program->getProductPairs($project->parent, 'all', 'noclosed', '', 0, $withProgram);
$linkedProducts = $this->loadModel('product')->getProducts($projectID, 'all', '', true, $linkedProductIdList);
$parentProject = $this->program->getByID($project->parent);
$plans = $this->productplan->getGroupByProduct(array_keys($linkedProducts), 'skipParent|unexpired');
@@ -1148,7 +1154,7 @@ class project extends control
* @access public
* @return void
*/
- public function bug($projectID = 0, $productID = 0, $branchID = 0, $orderBy = 'status,id_desc', $build = 0, $type = 'all', $param = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
+ public function bug($projectID = 0, $productID = 0, $branchID = 'all', $orderBy = 'status,id_desc', $build = 0, $type = 'all', $param = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
/* Load these two models. */
$this->loadModel('bug');
@@ -1307,7 +1313,7 @@ class project extends control
* @access public
* @return void
*/
- public function testcase($projectID = 0, $productID = 0, $branch = 0, $browseType = 'all', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
+ public function testcase($projectID = 0, $productID = 0, $branch = 'all', $browseType = 'all', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
$this->loadModel('product');
$this->session->set('bugList', $this->app->getURI(true), 'project');
@@ -2228,43 +2234,48 @@ class project extends control
}
}
- $branchGroups = $this->loadModel('branch')->getByProducts(array_keys($allProducts), 'ignoreNormal|noclosed');
- $productsGroupByProgram = $this->product->getProductsGroupByProgram();
-
- $currentProducts = array();
- $otherProducts = array();
- foreach($productsGroupByProgram as $programID => $programProducts)
+ $branchGroups = $this->loadModel('branch')->getByProducts(array_keys($allProducts), 'ignoreNormal|noclosed');
+ if($this->config->systemMode == 'ALM')
{
- if($programID != $project->parent)
- {
- foreach($programProducts as $productID => $productName)
- {
- if(!empty($branchGroups[$productID]))
- {
- foreach($branchGroups[$productID] as $branchID => $branchName)
- {
- if(isset($linkedProducts[$productID]) and isset($linkedBranches[$productID][$branchID])) continue;
+ $productsGroupByProgram = $this->product->getProductsGroupByProgram();
- $otherProducts["{$productID}_{$branchID}"] = $productName . '_' . $branchName;
+ $currentProducts = array();
+ $otherProducts = array();
+ foreach($productsGroupByProgram as $programID => $programProducts)
+ {
+ if($programID != $project->parent)
+ {
+ foreach($programProducts as $productID => $productName)
+ {
+ if(!empty($branchGroups[$productID]))
+ {
+ foreach($branchGroups[$productID] as $branchID => $branchName)
+ {
+ if(isset($linkedProducts[$productID]) and isset($linkedBranches[$productID][$branchID])) continue;
+
+ $otherProducts["{$productID}_{$branchID}"] = $productName . '_' . $branchName;
+ }
+ }
+ else
+ {
+ if(isset($linkedProducts[$productID])) continue;
+ $otherProducts[$productID] = $productName;
}
}
- else
- {
- if(isset($linkedProducts[$productID])) continue;
- $otherProducts[$productID] = $productName;
- }
+ }
+ else
+ {
+ $currentProducts += $programProducts;
}
}
- else
- {
- $currentProducts += $programProducts;
- }
+
+ $this->view->currentProducts = $currentProducts;
+ $this->view->otherProducts = $otherProducts;
}
/* Assign. */
$this->view->title = $this->lang->project->manageProducts . $this->lang->colon . $project->name;
$this->view->project = $project;
- $this->view->currentProducts = $currentProducts;
$this->view->linkedProducts = $linkedProducts;
$this->view->linkedBranches = $linkedBranches;
$this->view->branches = $branches;
@@ -2275,7 +2286,6 @@ class project extends control
$this->view->branchGroups = $branchGroups;
$this->view->allBranches = $this->branch->getByProducts(array_keys($allProducts), 'ignoreNormal');
$this->view->allProducts = $allProducts;
- $this->view->otherProducts = $otherProducts;
$this->display();
}
diff --git a/module/project/css/create.css b/module/project/css/create.css
old mode 100644
new mode 100755
index 8d3216532d..65133863d7
--- a/module/project/css/create.css
+++ b/module/project/css/create.css
@@ -28,3 +28,4 @@
.futureBox {vertical-align: top !important; padding-top: 13px !important;}
#linkPlan {padding-top: 25px !important;}
#projectType {padding-top: 7px !important;}
+.division .icon-help {margin-left: 15px}
diff --git a/module/project/lang/de.php b/module/project/lang/de.php
index 93471b8c7d..2b42d47da9 100644
--- a/module/project/lang/de.php
+++ b/module/project/lang/de.php
@@ -134,7 +134,7 @@ $lang->project->realBeganAB = 'Actual Begin';
$lang->project->realEndAB = 'Actual End';
$lang->project->realBegan = 'Actual Began';
$lang->project->realEnd = 'Actual End';
-$lang->project->division = 'Create Stages by Product';
+$lang->project->division = 'Stage Type';
$lang->project->bygrid = 'Kanban';
$lang->project->bylist = 'List';
$lang->project->bycard = 'Card';
@@ -190,8 +190,8 @@ $lang->project->typeList = array();
$lang->project->typeList['my'] = 'Projects Ownedbyme';
$lang->project->typeList['other'] = 'Other Projects';
-$lang->project->divisionList['1'] = 'Enable';
-$lang->project->divisionList['0'] = 'Disable';
+$lang->project->divisionList['1'] = 'Create by project';
+$lang->project->divisionList['0'] = 'Create by product';
$lang->project->waitProjects = 'Waiting Projects';
$lang->project->doingProjects = 'Ongoing Projects';
@@ -208,7 +208,7 @@ $lang->project->changeProgram = '%s > Change project';
$lang->project->changeProgramTip = 'After modifying the project set, the products linked with the project will also modify the project set to which it belongs. Please confirm whether to modify it.';
$lang->project->linkedProjectsTip = 'Linked projects are as follows';
$lang->project->multiLinkedProductsTip = 'The following products linked to this project are also linked to other projects, please unlink before proceeding.';
-$lang->project->noticeDivsion = "The current project is associated with multiple products, you can click Confirm to open the mode by {$lang->productCommon} creation stage, click Cancel to keep the status quo.";
+$lang->project->noticeDivsion = "The current project is a single stage, click [Create by project] to change to multiple stages, each stage is only associated with one product.";
$lang->project->linkStoryByPlanTips = "This action will associate all {$lang->SRCommon} under the selected plan to this project";
$lang->project->createExecution = "There is no {$lang->executionCommon} under this project, please create {$lang->executionCommon} first";
$lang->project->unlinkExecutionMember = "The user participated in %s executions such as %s%s. Do you want to remove the user from those executions as well? (The data related to this user will not be deleted.)";
@@ -373,6 +373,7 @@ $lang->project->begigLetterExecution = 'The start date of project should be ≤
$lang->project->endGreateExecution = 'The finish date of the project should be ≥ the maximum finish date of the execution: %s.';
$lang->project->childLongTime = "If a child as long-term projects, the parent should be long-term too.";
$lang->project->confirmUnlinkMember = "Do you want to remove this user from project?";
+$lang->project->divisionTips = "Created by project as a single set of stages, and the stage is associated with all products; created by product as multiple sets of stages, each set of stages is associated with a product";
$lang->project->action = new stdclass();
$lang->project->action->managed = '$date, managed by $actor . $extra' . "\n";
diff --git a/module/project/lang/en.php b/module/project/lang/en.php
index 3417c68de8..3963595967 100644
--- a/module/project/lang/en.php
+++ b/module/project/lang/en.php
@@ -134,7 +134,7 @@ $lang->project->realBeganAB = 'Actual Begin';
$lang->project->realEndAB = 'Actual End';
$lang->project->realBegan = 'Actual Begin';
$lang->project->realEnd = 'Actual End';
-$lang->project->division = 'Create Stages by Product';
+$lang->project->division = 'Stage Type';
$lang->project->bygrid = 'Kanban';
$lang->project->bylist = 'List';
$lang->project->bycard = 'Card';
@@ -190,8 +190,8 @@ $lang->project->typeList = array();
$lang->project->typeList['my'] = 'Projects Ownedbyme';
$lang->project->typeList['other'] = 'Other Projects';
-$lang->project->divisionList['1'] = 'Enable';
-$lang->project->divisionList['0'] = 'Disable';
+$lang->project->divisionList['1'] = 'Create by project';
+$lang->project->divisionList['0'] = 'Create by product';
$lang->project->waitProjects = 'Waiting Projects';
$lang->project->doingProjects = 'Ongoing Projects';
@@ -208,7 +208,7 @@ $lang->project->changeProgram = '%s > Change project';
$lang->project->changeProgramTip = 'Once the program is edited, the product that is linked to this program will be changed. Do you want to edit it?';
$lang->project->linkedProjectsTip = 'Linked projects are as follows';
$lang->project->multiLinkedProductsTip = 'The following products linked to this project are also linked to other projects, please unlink before proceeding.';
-$lang->project->noticeDivsion = "The current project is associated with multiple products, you can click Confirm to open the mode by {$lang->productCommon} creation stage, click Cancel to keep the status quo.";
+$lang->project->noticeDivsion = "The current project is a single stage, click [Create by project] to change to multiple stages, each stage is only associated with one product.";
$lang->project->linkStoryByPlanTips = "This action will associate all {$lang->SRCommon} under the selected plan to this project";
$lang->project->createExecution = "There is no {$lang->executionCommon} under this project, please create {$lang->executionCommon} first";
$lang->project->unlinkExecutionMember = "The user participated in %s executions such as %s%s. Do you want to remove the user from those executions as well? (The data related to this user will not be deleted.)";
@@ -373,6 +373,7 @@ $lang->project->begigLetterExecution = 'The start date of project should be ≤
$lang->project->endGreateExecution = 'The finish date of the project should be ≥ the maximum finish date of the execution: %s.';
$lang->project->childLongTime = "There are long-term projects in the child project, and the parent project should also be a long-term project.";
$lang->project->confirmUnlinkMember = "Do you want to remove this user from project?";
+$lang->project->divisionTips = "Created by project as a single set of stages, and the stage is associated with all products; created by product as multiple sets of stages, each set of stages is associated with a product";
$lang->project->action = new stdclass();
$lang->project->action->managed = '$date, managed by $actor . $extra' . "\n";
diff --git a/module/project/lang/fr.php b/module/project/lang/fr.php
index 84cdd9e0bd..f480217097 100644
--- a/module/project/lang/fr.php
+++ b/module/project/lang/fr.php
@@ -134,7 +134,7 @@ $lang->project->realBeganAB = 'Actual Begin';
$lang->project->realEndAB = 'Actual End';
$lang->project->realBegan = 'Actual Began';
$lang->project->realEnd = 'Actual End';
-$lang->project->division = 'Create Stages by Product';
+$lang->project->division = 'Stage Type';
$lang->project->bygrid = 'Kanban';
$lang->project->bylist = 'List';
$lang->project->bycard = 'Card';
@@ -190,8 +190,8 @@ $lang->project->typeList = array();
$lang->project->typeList['my'] = 'Projects Ownedbyme';
$lang->project->typeList['other'] = 'Other Projects';
-$lang->project->divisionList['1'] = 'Enable';
-$lang->project->divisionList['0'] = 'Disable';
+$lang->project->divisionList['1'] = 'Create by project';
+$lang->project->divisionList['0'] = 'Create by product';
$lang->project->waitProjects = 'Waiting Projects';
$lang->project->doingProjects = 'Ongoing Projects';
@@ -208,7 +208,7 @@ $lang->project->changeProgram = '%s > Change project';
$lang->project->changeProgramTip = 'After modifying the project set, the products linked with the project will also modify the project set to which it belongs. Please confirm whether to modify it.';
$lang->project->linkedProjectsTip = 'Linked projects are as follows';
$lang->project->multiLinkedProductsTip = 'The following products linked to this project are also linked to other projects, please unlink before proceeding.';
-$lang->project->noticeDivsion = "The current project is associated with multiple products, you can click Confirm to open the mode by {$lang->productCommon} creation stage, click Cancel to keep the status quo.";
+$lang->project->noticeDivsion = "The current project is a single stage, click [Create by project] to change to multiple stages, each stage is only associated with one product.";
$lang->project->linkStoryByPlanTips = "This action will associate all {$lang->SRCommon} under the selected plan to this project";
$lang->project->createExecution = "There is no {$lang->executionCommon} under this project, please create {$lang->executionCommon} first";
$lang->project->unlinkExecutionMember = "The user participated in %s executions such as %s%s. Do you want to remove the user from those executions as well? (The data related to this user will not be deleted.)";
@@ -373,6 +373,7 @@ $lang->project->begigLetterExecution = 'La date de début du projet "%s" doit ê
$lang->project->endGreateExecution = 'La date de fin du projet "%s" doit être ≥ à la date de fin maximale d\'exécution: %s.';
$lang->project->childLongTime = "If a child as long-term projects, the parent should be long-term too.";
$lang->project->confirmUnlinkMember = "Do you want to remove this user from project?";
+$lang->project->divisionTips = "Created by project as a single set of stages, and the stage is associated with all products; created by product as multiple sets of stages, each set of stages is associated with a product";
$lang->project->action = new stdclass();
$lang->project->action->managed = '$date, managed by $actor . $extra' . "\n";
diff --git a/module/project/lang/vi.php b/module/project/lang/vi.php
index ec1120b68e..fc890c98cb 100644
--- a/module/project/lang/vi.php
+++ b/module/project/lang/vi.php
@@ -1,85 +1,140 @@
project->createGuide = 'Select Template';
-$lang->project->index = 'Dashboard';
-$lang->project->home = 'Home';
-$lang->project->create = 'Create Project';
-$lang->project->edit = 'Edit';
-$lang->project->batchEdit = 'Batch Edit Projects';
-$lang->project->view = 'Project View';
-$lang->project->batchEdit = 'Batch Edit';
-$lang->project->browse = 'Projects';
-$lang->project->all = 'All';
-$lang->project->start = 'Start';
-$lang->project->finish = 'Finish';
-$lang->project->suspend = 'Suspend';
-$lang->project->delete = 'Delete';
-$lang->project->close = 'Close';
-$lang->project->activate = 'Activate';
-$lang->project->group = 'Privilege Group';
-$lang->project->createGroup = 'Create Group';
-$lang->project->editGroup = 'Edit Group';
-$lang->project->copyGroup = 'Copy Group';
-$lang->project->manageView = 'Manage View';
-$lang->project->managePriv = 'Manage Privilege';
-$lang->project->manageMembers = 'Manage Team';
-$lang->project->export = 'Export';
-$lang->project->addProduct = 'Add Product';
-$lang->project->manageGroupMember = 'Manage Group';
-$lang->project->moduleSetting = 'List Settings';
-$lang->project->moduleOpen = 'Program Name';
-$lang->project->dynamic = 'Dynamic';
-$lang->project->execution = 'Execution';
-$lang->project->qa = 'QA';
-$lang->project->bug = 'Bug List';
-$lang->project->testcase = 'Case List';
-$lang->project->testtask = 'Test Task';
-$lang->project->build = 'Build';
-$lang->project->updateOrder = 'Order';
-$lang->project->sort = 'Order';
-$lang->project->whitelist = 'Project Whitelist';
-$lang->project->addWhitelist = 'Project Add Whitelist';
-$lang->project->unbindWhitelist = 'Project Remove Whitelist';
-$lang->project->manageProducts = 'Manage Products';
-$lang->project->copyTitle = 'Please select an project to copy';
-$lang->project->errorSameProducts = 'Project cannot be associated with multiple identical products.';
-$lang->project->errorNoProducts = 'At least one product is associated';
-$lang->project->copyNoProject = 'There are no items available to copy.';
-$lang->project->searchByName = 'Enter the project name to retrieve';
-$lang->project->linkedProducts = "Linked {$lang->productCommon}s";
-$lang->project->unlinkedProducts = "Unlinked {$lang->productCommon}s";
-$lang->project->testreport = 'Testreport';
-$lang->project->selectProgram = 'Program filtering';
-$lang->project->teamMember = 'Team Member';
-$lang->project->manageRepo = 'Manage Repo';
-$lang->project->linkedRepo = 'Link Repo';
-$lang->project->unlinkedRepo = 'Unlink Repo';
+$lang->project->createGuide = 'Select Template';
+$lang->project->index = 'Dashboard';
+$lang->project->home = 'Home';
+$lang->project->create = 'Create Project';
+$lang->project->edit = 'Edit';
+$lang->project->batchEdit = 'Batch Edit Projects';
+$lang->project->view = 'Project View';
+$lang->project->batchEdit = 'Batch Edit';
+$lang->project->browse = 'Projects';
+$lang->project->all = 'All';
+$lang->project->start = 'Start';
+$lang->project->finish = 'Finish';
+$lang->project->suspend = 'Suspend';
+$lang->project->delete = 'Delete';
+$lang->project->close = 'Close';
+$lang->project->activate = 'Activate';
+$lang->project->group = 'Privilege Group';
+$lang->project->createGroup = 'Create Group';
+$lang->project->editGroup = 'Edit Group';
+$lang->project->copyGroup = 'Copy Group';
+$lang->project->manageView = 'Manage View';
+$lang->project->managePriv = 'Manage Privilege';
+$lang->project->manageMembers = 'Manage Team';
+$lang->project->export = 'Export';
+$lang->project->addProduct = 'Add Product';
+$lang->project->manageGroupMember = 'Manage Group';
+$lang->project->moduleSetting = 'List Settings';
+$lang->project->moduleOpen = 'Program Name';
+$lang->project->dynamic = 'Dynamic';
+$lang->project->execution = 'Execution';
+$lang->project->qa = 'QA';
+$lang->project->bug = 'Bug List';
+$lang->project->testcase = 'Case List';
+$lang->project->testtask = 'Test Task';
+$lang->project->build = 'Build';
+$lang->project->updateOrder = 'Order';
+$lang->project->sort = 'Order';
+$lang->project->whitelist = 'Project Whitelist';
+$lang->project->addWhitelist = 'Project Add Whitelist';
+$lang->project->unbindWhitelist = 'Project Remove Whitelist';
+$lang->project->manageProducts = 'Manage Products';
+$lang->project->manageOtherProducts = 'Manage Other Products';
+$lang->project->copyTitle = 'Please select an project to copy';
+$lang->project->errorSameProducts = 'Project cannot be associated with multiple identical products.';
+$lang->project->errorSameBranches = 'Project cannot be associated with multiple identical branches.';
+$lang->project->errorSamePlans = 'Project cannot be associated with multiple identical plans.';
+$lang->project->errorNoProducts = 'At least one product is associated';
+$lang->project->copyNoProject = 'There are no items available to copy.';
+$lang->project->searchByName = 'Enter the project name to retrieve';
+$lang->project->deleted = 'Deleted';
+$lang->project->linkedProducts = "Linked {$lang->productCommon}s";
+$lang->project->unlinkedProducts = "Unlinked {$lang->productCommon}s";
+$lang->project->testreport = 'Test Report';
+$lang->project->selectProgram = 'Program filtering';
+$lang->project->teamMember = 'Team Member';
+$lang->project->unlinkMember = 'Remove Member';
+$lang->project->copyTeamTitle = 'Select a project team to copy';
+$lang->project->daysGreaterProject = 'Days cannot be greater than days of project『%s』';
+$lang->project->errorHours = 'Hours/Day cannot be greater than『24』';
+$lang->project->workdaysExceed = 'No more than『%s』working days';
+$lang->project->teamMembersCount = ', there are %s team members.';
+$lang->project->budgetNumber = '『Budget』must be numbers.';
+$lang->project->budgetGe0 = '『Budget』must be greater than or equal to 0.';
+$lang->project->allProjects = 'All Projects';
+$lang->project->ignore = 'Ignore';
+$lang->project->manageRepo = 'Manage Repo';
+$lang->project->linkedRepo = 'Link Repo';
+$lang->project->unlinkedRepo = 'Unlink Repo';
+$lang->project->disableExecution = 'Project of disable iteration';
+$lang->project->selectProduct = 'Select Product';
/* Fields. */
$lang->project->common = 'Project';
+$lang->project->id = 'ID';
+$lang->project->project = 'Project';
$lang->project->stage = 'Stage';
+$lang->project->model = 'Model';
$lang->project->PM = 'Manager';
+$lang->project->PO = 'Project Owner';
+$lang->project->QD = 'Test Leader';
+$lang->project->RD = 'Releaser';
$lang->project->name = 'Name';
$lang->project->category = 'Category';
$lang->project->desc = 'Description';
$lang->project->code = 'Code';
$lang->project->hasProduct = 'Has Product';
$lang->project->copy = 'Copy';
-$lang->project->begin = 'Begin';
-$lang->project->end = 'End';
+$lang->project->begin = 'Planned Begin';
+$lang->project->end = 'Planned End';
$lang->project->status = 'Status';
-$lang->project->PM = 'Manager';
+$lang->project->subStatus = 'Sub Status';
+$lang->project->type = 'Type';
+$lang->project->lifetime = 'Project Cycle';
+$lang->project->attribute = 'Stage Type';
+$lang->project->percent = 'Workload %';
+$lang->project->milestone = 'Milestone';
+$lang->project->output = 'Output';
+$lang->project->path = 'Path';
+$lang->project->grade = 'Grade';
+$lang->project->version = 'Version';
+$lang->project->parentVersion = 'Parent Version';
+$lang->project->planDuration = 'Plan Duration';
+$lang->project->realDuration = 'Real Duration';
+$lang->project->openedVersion = 'Opened Version';
+$lang->project->pri = 'Priority';
+$lang->project->openedBy = 'OpenedBy';
+$lang->project->openedDate = 'OpenedDate';
+$lang->project->lastEditedBy = 'Last EditedBy';
+$lang->project->lastEditedDate = 'Last EditedDate';
+$lang->project->closedBy = 'ClosedBy';
+$lang->project->closedDate = 'ClosedDate';
+$lang->project->canceledBy = 'CanceledBy';
+$lang->project->canceledDate = 'CanceledDate';
+$lang->project->team = 'Team';
+$lang->project->teamAction = 'Team List';
+$lang->project->order = 'Rank';
$lang->project->budget = 'Budget';
+$lang->project->budgetUnit = 'Budget Unit';
+$lang->project->suspendedDate = 'SuspendedDate';
+$lang->project->vision = 'Vision';
+$lang->project->displayCards = 'Max cards per column';
+$lang->project->fluidBoard = 'Column Width';
$lang->project->template = 'Template';
$lang->project->estimate = 'Estimates';
$lang->project->consume = 'Cost';
$lang->project->surplus = 'Left';
$lang->project->progress = 'Progress';
-$lang->project->dateRange = 'Duration';
+$lang->project->weekProgress = 'This Week Progress';
+$lang->project->dateRange = 'Plan Duration';
$lang->project->to = ' to ';
+$lang->project->realBeganAB = 'Actual Begin';
+$lang->project->realEndAB = 'Actual End';
+$lang->project->realBegan = 'Actual Begin';
$lang->project->realEnd = 'Actual End';
-$lang->project->realBegan = 'Actual Began';
-$lang->project->division = 'Create Stages by Product';
+$lang->project->division = 'Stage Type';
$lang->project->bygrid = 'Kanban';
$lang->project->bylist = 'List';
$lang->project->bycard = 'Card';
@@ -90,14 +145,12 @@ $lang->project->acl = 'ACL';
$lang->project->setPlanduration = 'Set Duration';
$lang->project->auth = 'Privileges';
$lang->project->durationEstimation = 'Estimated Workload';
-$lang->project->teamCount = 'Man';
-$lang->project->teamSumCount = '%s people in total';
$lang->project->leftStories = 'Left Stories';
$lang->project->leftTasks = 'Left Tasks';
$lang->project->leftBugs = 'Left Bugs';
$lang->project->leftHours = 'Left Hours';
$lang->project->children = 'Child Project';
-$lang->project->parent = 'Parent Project';
+$lang->project->parent = 'Parent Program';
$lang->project->allStories = 'All Stories';
$lang->project->doneStories = 'Finished Stories';
$lang->project->doneProjects = 'Finished';
@@ -108,48 +161,89 @@ $lang->project->ev = 'EV';
$lang->project->sv = 'SV%';
$lang->project->ac = 'AC';
$lang->project->cv = 'CV%';
+$lang->project->pvTitle = 'Planed Value';
+$lang->project->evTitle = 'Earn Value';
+$lang->project->svTitle = 'Schedule Variance';
+$lang->project->acTitle = 'Actual Cost';
+$lang->project->cvTitle = 'Cost Variance';
$lang->project->teamCount = 'Team';
+$lang->project->teamSumCount = '%s people in total';
$lang->project->longTime = 'Long-Term Program';
$lang->project->future = 'TBD';
$lang->project->moreProject = 'More Project';
-$lang->project->days = 'Available Days';
+$lang->project->days = 'Days';
+$lang->project->mailto = 'Mailto';
+$lang->project->etc = " , etc";
+$lang->project->product = 'Product';
+$lang->project->branch = 'Branch';
+$lang->project->plan = 'Plan';
+$lang->project->createKanban = 'Create Kanban';
+$lang->project->kanban = 'Kanban';
/* Project Kanban. */
$lang->project->projectTypeList = array();
$lang->project->projectTypeList[1] = 'Has Product';
$lang->project->projectTypeList[0] = 'No Product';
+/* Project Kanban. */
+$lang->project->typeList = array();
+$lang->project->typeList['my'] = 'Projects Ownedbyme';
+$lang->project->typeList['other'] = 'Other Projects';
+
+$lang->project->divisionList['1'] = 'Create by project';
+$lang->project->divisionList['0'] = 'Create by product';
+
+$lang->project->waitProjects = 'Waiting Projects';
+$lang->project->doingProjects = 'Ongoing Projects';
+$lang->project->doingExecutions = 'Ongoing Executions';
+$lang->project->closedProjects = 'Closed Projects(The recent two projects)';
+$lang->project->closedProject = 'Closed Projects';
+$lang->project->noProgram = 'Independent Projects';
+
+$lang->project->laneColorList = array('#32C5FF', '#006AF1', '#9D28B2', '#FF8F26', '#FFC20E', '#00A78E', '#7FBB00', '#424BAC', '#C0E9FF', '#EC2761');
+
$lang->project->productNotEmpty = 'Please link products or create products.';
$lang->project->existProductName = 'Product name already exists.';
$lang->project->changeProgram = '%s > Change project';
-$lang->project->changeProgramTip = 'After modifying the project set, the products linked with the project will also modify the project set to which it belongs. Please confirm whether to modify it.';
+$lang->project->changeProgramTip = 'Once the program is edited, the product that is linked to this program will be changed. Do you want to edit it?';
$lang->project->linkedProjectsTip = 'Linked projects are as follows';
$lang->project->multiLinkedProductsTip = 'The following products linked to this project are also linked to other projects, please unlink before proceeding.';
-$lang->project->noticeDivsion = "The current project is associated with multiple products, you can click Confirm to open the mode by {$lang->productCommon} creation stage, click Cancel to keep the status quo.";
+$lang->project->noticeDivsion = "The current project is a single stage, click [Create by project] to change to multiple stages, each stage is only associated with one product.";
$lang->project->linkStoryByPlanTips = "This action will associate all {$lang->SRCommon} under the selected plan to this project";
$lang->project->createExecution = "There is no {$lang->executionCommon} under this project, please create {$lang->executionCommon} first";
+$lang->project->unlinkExecutionMember = "The user participated in %s executions such as %s%s. Do you want to remove the user from those executions as well? (The data related to this user will not be deleted.)";
+$lang->project->unlinkExecutionMembers = "The team members you are removing are also in the execution team of this project. Do you want to remove them from the execution team too?";
+$lang->project->productTip = 'After clicking New Product, the project will not be linked to the selected product.';
$lang->project->noDevStage = 'There is no R&D stage under this project, or you do not have access permissions. The creation of builds is not supported at the moment.';
+$lang->project->budgetOverrun = "The project's budget exceeds the remaining budget of the parent program:";
+$lang->project->disabledInputTip = 'Please cancel %s first';
$lang->project->linkRepoFailed = 'Failed to link projects and code repositories.';
+$lang->project->unLinkProductTip = 'Are you sure you want to unlink %s? (Does not affect linked requirements)';
+$lang->project->summary = 'Total projects: %s .';
+$lang->project->allSummary = 'Total projects: %s , Wait: %s , Doing: %s , Suspended: %s , Closed: %s .';
+$lang->project->checkedSummary = 'Seleted: %total% .';
+$lang->project->checkedAllSummary = 'Seleted: %total% , Wait: %wait% , Doing: %doing% , Suspended: %suspended% , Closed: %closed% .';
-$lang->project->tenThousand = '';
+$lang->project->tenThousand = 'Ten Thousand';
+$lang->project->hundredMillion = 'Hundred Million';
$lang->project->unitList['CNY'] = 'RMB';
$lang->project->unitList['USD'] = 'USD';
$lang->project->unitList['HKD'] = 'HKD';
-$lang->project->unitList['NTD'] = 'New Taiwan';
-$lang->project->unitList['EUR'] = 'Euro';
-$lang->project->unitList['DEM'] = 'Deutsche Mark';
-$lang->project->unitList['CHF'] = 'Swiss Franc';
-$lang->project->unitList['FRF'] = 'French Franc';
-$lang->project->unitList['GBP'] = 'Pound';
-$lang->project->unitList['NLG'] = 'Florin';
-$lang->project->unitList['CAD'] = 'Canadian';
-$lang->project->unitList['RUR'] = 'Russian Ruble';
-$lang->project->unitList['INR'] = 'Indian';
-$lang->project->unitList['AUD'] = 'Australian';
-$lang->project->unitList['NZD'] = 'New Zealand';
-$lang->project->unitList['THB'] = 'Thai Baht';
-$lang->project->unitList['SGD'] = 'Singapore';
+$lang->project->unitList['NTD'] = 'NTD';
+$lang->project->unitList['EUR'] = 'EUR';
+$lang->project->unitList['DEM'] = 'DEM';
+$lang->project->unitList['CHF'] = 'CHF';
+$lang->project->unitList['FRF'] = 'FRF';
+$lang->project->unitList['GBP'] = 'GPR';
+$lang->project->unitList['NLG'] = 'NLG';
+$lang->project->unitList['CAD'] = 'CAD';
+$lang->project->unitList['RUR'] = 'RUB';
+$lang->project->unitList['INR'] = 'IDR';
+$lang->project->unitList['AUD'] = 'AUD';
+$lang->project->unitList['NZD'] = 'NZD';
+$lang->project->unitList['THB'] = 'THB';
+$lang->project->unitList['SGD'] = 'SGD';
$lang->project->currencySymbol['CNY'] = '¥';
$lang->project->currencySymbol['USD'] = '$';
@@ -169,34 +263,56 @@ $lang->project->currencySymbol['NZD'] = 'NZ$';
$lang->project->currencySymbol['THB'] = '฿';
$lang->project->currencySymbol['SGD'] = 'S$';
+$lang->project->modelList[''] = '';
$lang->project->modelList['scrum'] = "Scrum";
-$lang->project->modelList['waterfall'] = "CMMI";
+if(helper::hasFeature('waterfall')) $lang->project->modelList['waterfall'] = "CMMI";
+$lang->project->modelList['kanban'] = "Kanban";
$lang->project->featureBar['browse']['all'] = 'All';
-$lang->project->featureBar['browse']['doing'] = 'Doing';
+$lang->project->featureBar['browse']['undone'] = 'Unfinished';
$lang->project->featureBar['browse']['wait'] = 'Waiting';
+$lang->project->featureBar['browse']['doing'] = 'Doing';
$lang->project->featureBar['browse']['suspended'] = 'Suspended';
$lang->project->featureBar['browse']['closed'] = 'Closed';
$lang->project->featureBar['build']['all'] = 'Build List';
-$lang->project->aclList['private'] = 'Private (For team members and stakeholders only)';
+$lang->project->aclList['private'] = 'Private (For the project leader, team members and stakeholders only)';
$lang->project->aclList['open'] = "Open (accessible with project view permissions)";
+$lang->project->multipleList['1'] = 'Yes';
+$lang->project->multipleList['0'] = 'No';
+
$lang->project->acls['private'] = 'Private';
-$lang->project->acls['open'] = "Open";
+$lang->project->acls['open'] = 'Open';
$lang->project->subAclList['private'] = "Private (Only the project leader, team members and stakeholders can access)";
$lang->project->subAclList['open'] = "Open (accessible with project view permissions)";
$lang->project->subAclList['program'] = 'Open in the program (all upper-level program team leaders and stakeholders, the project leader, team members and stakeholders can access)';
+$lang->project->kanbanAclList['private'] = 'Private (For the project leader, team members only)';
+$lang->project->kanbanAclList['open'] = "Open (accessible with project view permissions)";
+
+$lang->project->kanbanSubAclList['private'] = "Private (Only the project leader, team members can access)";
+$lang->project->kanbanSubAclList['open'] = "Open (accessible with project view permissions)";
+$lang->project->kanbanSubAclList['program'] = 'Open in the program (all upper-level program team leaders and stakeholders, the project leader, team members can access)';
+
+global $config;
+if($config->systemMode == 'light')
+{
+ unset($lang->project->subAclList['program']);
+ unset($lang->project->kanbanSubAclList['program']);
+}
+
$lang->project->authList['extend'] = 'Inherit (system privilege and project privilege)';
$lang->project->authList['reset'] = 'Reset (project privilege only)';
+$lang->project->statusList[''] = '';
$lang->project->statusList['wait'] = 'Waiting';
$lang->project->statusList['doing'] = 'Doing';
$lang->project->statusList['suspended'] = 'Suspended';
$lang->project->statusList['closed'] = 'Closed';
+$lang->project->statusList['delay'] = 'Delayed';
$lang->project->endList[31] = 'One month';
$lang->project->endList[93] = 'Trimester';
@@ -204,46 +320,54 @@ $lang->project->endList[186] = 'Half year';
$lang->project->endList[365] = 'One year';
$lang->project->endList[999] = 'Longtime';
+$lang->project->scrumTitle = 'Agile Development Management';
+$lang->project->waterfallTitle = 'Waterfall Project Management';
+$lang->project->kanbanTitle = 'Kanban Project Management';
+
$lang->project->empty = 'No project.';
-$lang->project->accessDenied = 'Access denied!';
-$lang->project->chooseProgramType = 'Select the project management model';
$lang->project->nextStep = 'Next step';
$lang->project->hoursUnit = '%s hours';
$lang->project->membersUnit = '%s men';
$lang->project->lastIteration = "Recent {$lang->executionCommon}";
+$lang->project->lastKanban = 'Recent Kanban';
$lang->project->ongoingStage = 'Ongoing stage';
$lang->project->scrum = 'Scrum';
-$lang->project->waterfall = 'CMMI';
-$lang->project->waterfallTitle = 'CMMI';
+$lang->project->waterfall = 'Waterfall';
$lang->project->cannotCreateChild = 'It is not empty, so you cannot add a child. You can add a parent for it, and then create a child.';
-$lang->project->confirmDelete = "Do you want to delete [%s]?";
$lang->project->emptyPM = 'No manager';
$lang->project->cannotChangeToCat = "It is not empty, so you cannot change it to a parent.";
$lang->project->cannotCancelCat = "It has child projects, so you cannot unmark the parent.";
$lang->project->parentBeginEnd = "Parent begin&end date: %s ~ %s";
$lang->project->childLongTime = "If a child as long-term projects, the parent should be long-term too.";
$lang->project->readjustTime = 'Change the project begin&end date.';
-$lang->project->notAllowRemoveProducts = 'The story of this product is linked with the project. Unlink it before doing any action.';
+$lang->project->notAllowRemoveProducts = "Stories of this product are linked to projects or {$lang->execution->common} of this project is linked to this product. Please unlink it and try again.";
+$lang->project->ge = "『%s』should be >= actual begin『%s』.";
-$lang->project->programTitle['0'] = 'Hide';
+$lang->project->programTitle['0'] = 'Hidden';
$lang->project->programTitle['base'] = 'Base-level project only';
$lang->project->programTitle['end'] = 'End-level project only';
-$lang->project->accessDenied = 'Access denied to this project';
-$lang->project->chooseProgramType = 'Select management type';
-$lang->project->scrumTitle = 'Agile Development Management';
-$lang->project->cannotCreateChild = 'The project has contents, so you cannot add a child project. You can create a parent project for this one and then add a child project for the parent project.';
-$lang->project->hasChildren = 'This project has a child project, so it cannot be deleted.';
-$lang->project->confirmDelete = 'Do you want to delete this project?';
-$lang->project->cannotChangeToCat = "The project has contents, so you cannot it to a parent project.";
-$lang->project->cannotCancelCat = "There are child projects of this project. You cannot cancel the parent project mark.";
-$lang->project->parentBeginEnd = "The begin and end date of the parent project: %s ~ %s";
-$lang->project->parentBudget = "The budget of the parent project: ";
-$lang->project->beginLetterParent = "The begin date of the parent project: %s. It cannot be < the begin date of its parent project.";
-$lang->project->endGreaterParent = "The end date of the parent project: %s. It cannot be > the end date of its parent project.";
-$lang->project->beginGreateChild = "The minimum start date of the project set: %s. The start date of the project cannot be less than the minimum start date of the project set.";
-$lang->project->endLetterChild = "The maximum finish date for the project set: %s. The completion date of a project cannot be greater than the maximum completion date of the project set.";
-$lang->project->childLongTime = "There are long-term projects in the child project, and the parent project should also be a long-term project.";
+$lang->project->accessDenied = 'Access denied to this project';
+$lang->project->chooseProgramType = 'Select management type';
+$lang->project->cannotCreateChild = 'The project has contents, so you cannot add a child project. You can create a parent project for this one and then add a child project for the parent project.';
+$lang->project->hasChildren = 'This project has a child project, so it cannot be deleted.';
+$lang->project->confirmDelete = 'Do you want to delete \"%s\"?';
+$lang->project->cannotChangeToCat = "The project has contents, so you cannot it to a parent project.";
+$lang->project->cannotCancelCat = "There are child projects of this project. You cannot cancel the parent project mark.";
+$lang->project->parentBeginEnd = "The begin and end date of the parent project: %s ~ %s";
+$lang->project->parentBudget = "The budget of the parent program: ";
+$lang->project->beginLetterParent = "The start date of the project is < the start date of the parent program:";
+$lang->project->endGreaterParent = "The finish date of the project is > the finish date of the parent program:";
+$lang->project->dateExceedParent = "The start and finish date of the project was > the start and finish date of the parent program:";
+$lang->project->beginGreateChild = 'The start date of the project should be ≥ the start date of program: %s.';
+$lang->project->endLetterChild = 'The finish date of the project should be ≤ the finish date of program: %s.';
+$lang->project->begigLetterExecution = 'The start date of project should be ≤ the minimum start date of the execution: %s.';
+$lang->project->endGreateExecution = 'The finish date of the project should be ≥ the maximum finish date of the execution: %s.';
+$lang->project->childLongTime = "There are long-term projects in the child project, and the parent project should also be a long-term project.";
+$lang->project->confirmUnlinkMember = "Do you want to remove this user from project?";
+$lang->project->divisionTips = "Created by project as a single set of stages, and the stage is associated with all products; created by product as multiple sets of stages, each set of stages is associated with a product";
$lang->project->action = new stdclass();
$lang->project->action->managed = '$date, managed by $actor . $extra' . "\n";
+
+$lang->project->multiple = "Multi {$lang->executionCommon}";
diff --git a/module/project/lang/zh-cn.php b/module/project/lang/zh-cn.php
index 0bc3733d3c..b90355021a 100644
--- a/module/project/lang/zh-cn.php
+++ b/module/project/lang/zh-cn.php
@@ -134,7 +134,7 @@ $lang->project->realBeganAB = '实际开始';
$lang->project->realEndAB = '实际完成';
$lang->project->realBegan = '实际开始日期';
$lang->project->realEnd = '实际完成日期';
-$lang->project->division = '按产品创建阶段';
+$lang->project->division = '阶段类型';
$lang->project->bygrid = '看板';
$lang->project->bylist = '列表';
$lang->project->bycard = '卡片';
@@ -190,8 +190,8 @@ $lang->project->typeList = array();
$lang->project->typeList['my'] = '我负责的项目';
$lang->project->typeList['other'] = '其他项目';
-$lang->project->divisionList['1'] = '开启';
-$lang->project->divisionList['0'] = '关闭';
+$lang->project->divisionList['0'] = '按项目创建';
+$lang->project->divisionList['1'] = "按{$lang->productCommon}创建";
$lang->project->waitProjects = '未开始的项目';
$lang->project->doingProjects = '进行中的项目';
@@ -208,7 +208,7 @@ $lang->project->changeProgram = '%s > 修改项目集';
$lang->project->changeProgramTip = '修改项目集后,该项目关联产品的项目集也会被修改,请确认是否修改。';
$lang->project->linkedProjectsTip = '关联的项目如下';
$lang->project->multiLinkedProductsTip = '该项目关联的如下产品还关联了其他项目,请取消关联后再操作';
-$lang->project->noticeDivsion = '当前项目关联多个产品,可以点击确认开启按产品创建阶段的模式,点击关闭则保持现状。';
+$lang->project->noticeDivsion = "当前项目为单套阶段,点击[按项目创建]可以变为多套阶段,每套阶段只关联一个{$lang->productCommon}。";
$lang->project->linkStoryByPlanTips = "此操作会将所选计划下面的{$lang->SRCommon}全部关联到此项目中";
$lang->project->createExecution = "该项目下没有{$lang->executionCommon},请先创建{$lang->executionCommon}";
$lang->project->unlinkExecutionMember = "该用户参与了%s%s%s个{$lang->execution->common},是否同时将其移除?(该用户所产生的数据不会受影响。)";
@@ -373,6 +373,7 @@ $lang->project->begigLetterExecution = '项目的开始日期应小于等于执
$lang->project->endGreateExecution = '项目的完成日期应大于等于执行的最大完成日期:%s';
$lang->project->childLongTime = "子项目中有长期项目,父项目也应该是长期项目";
$lang->project->confirmUnlinkMember = "您确定从该项目中移除该用户吗?";
+$lang->project->divisionTips = "按项目创建为单套阶段,阶段关联所有{$lang->productCommon};按{$lang->productCommon}创建为多套阶段,每套阶段关联一个{$lang->productCommon}。";
$lang->project->action = new stdclass();
$lang->project->action->managed = '$date, 由 $actor 维护。$extra' . "\n";
diff --git a/module/project/model.php b/module/project/model.php
index 11c14bb5a0..472a23d353 100644
--- a/module/project/model.php
+++ b/module/project/model.php
@@ -792,11 +792,11 @@ class projectModel extends model
* @param string $orderBy
* @param string $excludedModel
* @param string $model
- * @param bool $multiple
+ * @param string $param multiple|product
* @access public
* @return object
*/
- public function getPairsByProgram($programID = '', $status = 'all', $isQueryAll = false, $orderBy = 'order_asc', $excludedModel = '', $model = '', $multiple = false)
+ public function getPairsByProgram($programID = '', $status = 'all', $isQueryAll = false, $orderBy = 'order_asc', $excludedModel = '', $model = '', $param = '')
{
if(defined('TUTORIAL')) return $this->loadModel('tutorial')->getProjectPairs();
return $this->dao->select('id, name')->from(TABLE_PROJECT)
@@ -807,7 +807,8 @@ class projectModel extends model
->beginIF($status != 'all' and $status != 'noclosed')->andWhere('status')->eq($status)->fi()
->beginIF($excludedModel)->andWhere('model')->ne($excludedModel)->fi()
->beginIF($model)->andWhere('model')->eq($model)->fi()
- ->beginIF($multiple)->andWhere('multiple')->eq(1)->fi()
+ ->beginIF(strpos($param, 'multiple') !== false)->andWhere('multiple')->eq(1)->fi()
+ ->beginIF(strpos($param, 'product') !== false)->andWhere('hasProduct')->eq(1)->fi()
->beginIF($status == 'noclosed')->andWhere('status')->ne('closed')->fi()
->beginIF(!$this->app->user->admin and !$isQueryAll)->andWhere('id')->in($this->app->user->view->projects)->fi()
->orderBy($orderBy)
@@ -2848,6 +2849,17 @@ class projectModel extends model
$this->lang->project->menuOrder = $this->lang->$navGroup->menuOrder;
$this->lang->project->dividerMenu = $this->lang->$navGroup->dividerMenu;
+ if(empty($project->hasProduct))
+ {
+ unset($this->lang->project->menu->settings['subMenu']->products);
+ }
+ else
+ {
+ unset($this->lang->project->menu->settings['subMenu']->module);
+ unset($this->lang->project->menu->settings['subMenu']->managerepo);
+ unset($this->lang->project->menu->projectplan);
+ }
+
$this->loadModel('common')->resetProjectPriv($projectID);
}
diff --git a/module/project/view/create.html.php b/module/project/view/create.html.php
index 7bcc9b33ec..f80f3bea14 100755
--- a/module/project/view/create.html.php
+++ b/module/project/view/create.html.php
@@ -199,7 +199,10 @@
project->division;?>
- project->divisionList, '0');?>
+
+ project->divisionList, '0');?>
+
+
diff --git a/module/project/view/execution.html.php b/module/project/view/execution.html.php
index a1224679ee..3c3f5d52d3 100644
--- a/module/project/view/execution.html.php
+++ b/module/project/view/execution.html.php
@@ -42,10 +42,12 @@
$lang->programplan->stageCustom->task), '', $this->cookie->showTask ? 'checked=checked' : '');?>
+ config->systemMode == 'ALM'):?>
project->manageOtherProducts; ?>
+
-
-
-
+
+ config->systemMode == 'ALM')
+ {
+ unset($currentProducts[$productID]);
+ }
+ else
+ {
+ unset($allProducts[$productID]);
+ }
+ }
+
+ if(isset($branchGroups[$productID][$branchID])) unset($branchGroups[$productID][$branchID]);
+
+ if(isset($branchGroups[$productID]) and empty($branchGroups[$productID]))
+ {
+ if($this->config->systemMode == 'ALM')
+ {
+ unset($currentProducts[$productID]);
+ }
+ else
+ {
+ unset($allProducts[$productID]);
+ }
+ }
+ ?>
@@ -57,7 +84,10 @@
project->unlinkedProducts;?>
- $productName):?>
+ config->systemMode == 'ALM' ? $currentProducts : $allProducts;
+ foreach($unlinkedProducts as $productID => $productName):
+ ?>
'>
@@ -75,6 +105,8 @@
+
+ config->systemMode == 'ALM'):?>
+
diff --git a/module/projectrelease/control.php b/module/projectrelease/control.php
index 64a5d6b9e9..f39e8cc6e2 100644
--- a/module/projectrelease/control.php
+++ b/module/projectrelease/control.php
@@ -83,15 +83,12 @@ class projectrelease extends control
$pager = new pager($recTotal, $recPerPage, $pageID);
$releases = $this->projectrelease->getList($projectID, $type, $orderBy, $pager);
- $productIdList = array();
- foreach($releases as $release) $productIdList[$release->product] = $release->product;
$this->view->title = $objectName . $this->lang->colon . $this->lang->release->browse;
$this->view->execution = $execution;
$this->view->project = $project;
$this->view->products = $this->loadModel('product')->getProducts($projectID);
$this->view->releases = $releases;
- $this->view->builds = $this->loadModel('build')->getBuildPairs($productIdList, 'all', 'notrunk,withbranch', $projectID, 'project');
$this->view->projectID = $projectID;
$this->view->executionID = $executionID;
$this->view->type = $type;
@@ -372,7 +369,7 @@ class projectrelease extends control
$builds = $this->dao->select('*')->from(TABLE_BUILD)->where('id')->in($release->build)->fetchAll('id');
foreach($builds as $build)
{
- if(empty($build->execution)) $this->build->delete(TABLE_BUILD, $build->id);
+ if(empty($build->execution) and empty($build->builds) and $build->createdDate == $release->createdDate) $this->build->delete(TABLE_BUILD, $build->id);
}
$message = $this->executeHooks($releaseID);
@@ -390,7 +387,6 @@ class projectrelease extends control
{
$response['result'] = 'success';
$response['message'] = '';
- $this->dao->update(TABLE_BUILD)->set('deleted')->eq(1)->where('id')->in($release->build)->andWhere('name')->eq($release->name)->exec();
}
return $this->send($response);
}
@@ -693,7 +689,7 @@ class projectrelease extends control
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values'];
$searchModules = array();
- $moduleGroups = $this->loadModel('tree')->getOptionMenu($release->product, 'story', 0, explode(',', $release->branch));
+ $moduleGroups = $this->loadModel('tree')->getOptionMenu($release->product, 'bug', 0, explode(',', $release->branch));
foreach($moduleGroups as $modules) $searchModules += $modules;
$this->config->bug->search['params']['module']['values'] = $searchModules;
diff --git a/module/projectrelease/model.php b/module/projectrelease/model.php
index b3c76e6c56..17bd84efef 100644
--- a/module/projectrelease/model.php
+++ b/module/projectrelease/model.php
@@ -38,7 +38,7 @@ class projectreleaseModel extends model
$this->loadModel('file');
$release = $this->file->replaceImgURL($release, 'desc');
$release->files = $this->file->getByObject('release', $releaseID);
- $release->buildInfos = $this->dao->select('id,project,product,name,scmPath,filePath')->from(TABLE_BUILD)->where('id')->in($release->build)->fetchAll('id');
+ $release->buildInfos = $this->dao->select('id,project,product,execution,name,scmPath,filePath')->from(TABLE_BUILD)->where('id')->in($release->build)->fetchAll('id');
if(empty($release->files))$release->files = $this->file->getByObject('build', $release->build);
if($setImgSize) $release->desc = $this->file->setImgSize($release->desc);
return $release;
@@ -55,7 +55,7 @@ class projectreleaseModel extends model
*/
public function getList($projectID, $type = 'all', $orderBy = 't1.date_desc', $pager = null)
{
- return $this->dao->select('t1.*, t2.name as productName')->from(TABLE_RELEASE)->alias('t1')
+ $releases = $this->dao->select('t1.*, t2.name as productName')->from(TABLE_RELEASE)->alias('t1')
->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id')
->where('t1.deleted')->eq(0)
->andWhere("FIND_IN_SET($projectID, t1.project)")
@@ -64,6 +64,26 @@ class projectreleaseModel extends model
->orderBy($orderBy)
->page($pager)
->fetchAll();
+
+ $buildIdList = array();
+ foreach($releases as $release)
+ {
+ $release->project = trim($release->project, ',');
+ $release->branch = trim($release->branch, ',');
+ $release->build = trim($release->build, ',');
+ $buildIdList = array_merge($buildIdList, explode(',', $release->build));
+ }
+
+ $builds = $this->dao->select("id,project,product,execution,name,scmPath,filePath")->from(TABLE_BUILD)->where('id')->in(array_unique($buildIdList))->fetchAll('id');
+ foreach($releases as $release)
+ {
+ foreach(explode(',', $release->build) as $buildID)
+ {
+ if(empty($buildID)) continue;
+ $release->buildInfos[$buildID] = $builds[$buildID];
+ }
+ }
+ return $releases;
}
/**
diff --git a/module/projectrelease/view/browse.html.php b/module/projectrelease/view/browse.html.php
index 9764482095..7686b8a08e 100644
--- a/module/projectrelease/view/browse.html.php
+++ b/module/projectrelease/view/browse.html.php
@@ -65,11 +65,10 @@
build, ','));
- $buildCount = count($linkedBuilds);
- foreach($linkedBuilds as $i => $buildID):
+ $i = 0;
+ $buildCount = count($release->buildInfos);
+ foreach($release->buildInfos as $buildID => $build):
?>
-
1 ? "rowspan='$buildCount'" : '';?>
@@ -83,7 +82,7 @@
hasProduct):?>
title='productName?>'>productName?>
- createLink('build', 'view', "buildID=$buildID"), $buildName, '', "data-app='project'");?>
+ createLink($build->execution ? 'build' : 'projectbuild', 'view', "buildID=$buildID"), $build->name, '', "data-app='project'");?>
processStatus('release', $release);?>
class='c-status text-center' title=''>
@@ -94,9 +93,10 @@
- createLink('build', 'view', "buildID=$buildID"), $buildName, '', "data-app='project'");?>
+ createLink($build->execution ? 'build' : 'projectbuild', 'view', "buildID=$buildID"), $build->name, '', "data-app='project'");?>
+
diff --git a/module/projectrelease/view/create.html.php b/module/projectrelease/view/create.html.php
index ea809f9afe..a17fe99ce5 100644
--- a/module/projectrelease/view/create.html.php
+++ b/module/projectrelease/view/create.html.php
@@ -38,7 +38,7 @@
id, "onchange='loadBranches(this.value)' class='form-control chosen'");?>
- type != 'normal') echo html::select('branch', $branches, $branch, "class='form-control chosen control-branch'");?>
+ type != 'normal') echo html::select('branch', $branches, $branch, "onchange='loadBuilds()' class='form-control chosen control-branch'");?>
diff --git a/module/projectrelease/view/view.html.php b/module/projectrelease/view/view.html.php
index 23b8bdf03c..4f8b471a9c 100644
--- a/module/projectrelease/view/view.html.php
+++ b/module/projectrelease/view/view.html.php
@@ -356,9 +356,9 @@
$buildHtml = array();
foreach($release->buildInfos as $buildID => $buildInfo)
{
- $buildHtml[] = html::a($this->createLink('build', 'view', "buildID=$buildID"), $buildInfo->name);
+ $buildHtml[] = html::a($this->createLink($buildInfo->execution ? 'build' : 'projectbuild', 'view', "buildID=$buildID"), $buildInfo->name, '', "data-app='project'");
}
- echo join(', ', $buildHtml);
+ echo join($lang->comma, $buildHtml);
?>
diff --git a/module/release/control.php b/module/release/control.php
index 6327b37398..c1fc6a7af6 100644
--- a/module/release/control.php
+++ b/module/release/control.php
@@ -464,7 +464,6 @@ class release extends control
$this->session->set('storyList', inlink('view', "releaseID=$releaseID&type=story&link=true¶m=" . helper::safe64Encode("&browseType=$browseType&queryID=$param")), 'product');
$release = $this->release->getById($releaseID);
- $build = $this->loadModel('build')->getByID($release->build);
$this->commonAction($release->product);
$this->loadModel('story');
$this->loadModel('tree');
@@ -475,15 +474,21 @@ class release extends control
$pager = new pager($recTotal, $recPerPage, $pageID);
/* Build search form. */
- $queryID = ($browseType == 'bySearch') ? (int)$param : 0;
unset($this->config->product->search['fields']['product']);
unset($this->config->product->search['fields']['project']);
+
+ $queryID = ($browseType == 'bySearch') ? (int)$param : 0;
$this->config->product->search['actionURL'] = $this->createLink('release', 'view', "releaseID=$releaseID&type=story&link=true¶m=" . helper::safe64Encode('&browseType=bySearch&queryID=myQueryID'));
$this->config->product->search['queryID'] = $queryID;
$this->config->product->search['style'] = 'simple';
$this->config->product->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairsForStory($release->product, $release->branch, 'skipParent|withMainPlan');
$this->config->product->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $this->lang->story->statusList);
- $this->config->product->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($release->product, 'story', 0, $release->branch);;
+
+ $searchModules = array();
+ $moduleGroups = $this->loadModel('tree')->getOptionMenu($release->product, 'story', 0, explode(',', $release->branch));;
+ foreach($moduleGroups as $modules) $searchModules += $modules;
+ $this->config->product->search['params']['module']['values'] = $searchModules;
+
if($this->session->currentProductType == 'normal')
{
unset($this->config->product->search['fields']['branch']);
@@ -491,20 +496,30 @@ class release extends control
}
else
{
- $this->config->product->search['fields']['branch'] = $this->lang->product->branch;
- $branchName = $this->loadModel('branch')->getById($release->branch);
- $branches = array('' => '', BRANCH_MAIN => $this->lang->branch->main, $release->branch => $branchName);
+ $allBranchs = $this->loadModel('branch')->getPairs($release->product);
+ $branches = array('' => '', BRANCH_MAIN => $this->lang->branch->main);
+ foreach(explode(',', trim($release->branch, ',')) as $branchID) $branches[$branchID] = zget($allBranchs, $branchID);
+
+ $this->config->product->search['fields']['branch'] = sprintf($this->lang->product->branch, $this->lang->product->branchName[$release->productType]);
$this->config->product->search['params']['branch']['values'] = $branches;
}
$this->loadModel('search')->setSearchParams($this->config->product->search);
- if($browseType == 'bySearch' or $build->execution == 0)
+ $builds = $this->loadModel('build')->getByList($release->build);
+ $executionIdList = array();
+ foreach($builds as $build)
{
- $allStories = $this->story->getBySearch($release->product, "0,{$release->branch}", $queryID, 'id', $build->execution ? $build->execution : '', 'story', $release->stories, $pager);
+ if(empty($build->execution)) continue;
+ $executionIdList[$build->execution] = $build->execution;
+ }
+
+ if($browseType == 'bySearch')
+ {
+ $allStories = $this->story->getBySearch($release->product, $release->branch, $queryID, 'id', $executionIdList, 'story', $release->stories, $pager);
}
else
{
- $allStories = $this->story->getExecutionStories($build->execution, $build->product, 0, 't1.`order`_desc', 'byBranch', $release->branch, 'story', $release->stories, $pager);
+ $allStories = $this->story->getExecutionStories($executionIdList, $build->product, 0, 't1.`order`_desc', 'byBranch', $release->branch, 'story', $release->stories, $pager);
}
$this->view->allStories = $allStories;
@@ -584,7 +599,6 @@ class release extends control
$this->session->set('bugList', inlink('view', "releaseID=$releaseID&type=$type&link=true¶m=" . helper::safe64Encode("&browseType=$browseType&queryID=$param")), 'qa');
/* Set menu. */
$release = $this->release->getByID($releaseID);
- $build = $this->loadModel('build')->getByID($release->build);
$this->commonAction($release->product);
/* Load pager. */
@@ -593,17 +607,24 @@ class release extends control
/* Build the search form. */
$this->loadModel('bug');
- $queryID = ($browseType == 'bysearch') ? (int)$param : 0;
unset($this->config->bug->search['fields']['product']);
unset($this->config->bug->search['fields']['project']);
+
+ $queryID = ($browseType == 'bysearch') ? (int)$param : 0;
$this->config->bug->search['actionURL'] = $this->createLink('release', 'view', "releaseID=$releaseID&type=$type&link=true¶m=" . helper::safe64Encode('&browseType=bySearch&queryID=myQueryID'));
$this->config->bug->search['queryID'] = $queryID;
$this->config->bug->search['style'] = 'simple';
+
$this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairsForStory($release->product, $release->branch, 'skipParent|withMainPlan');
$this->config->bug->search['params']['execution']['values'] = $this->loadModel('product')->getExecutionPairsByProduct($release->product, $release->branch);
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($release->product, $branch = 'all', $params = '');
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values'];
- $this->config->bug->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($release->product, 'bug', 0, $release->branch);
+
+ $searchModules = array();
+ $moduleGroups = $this->loadModel('tree')->getOptionMenu($release->product, 'bug', 0, explode(',', $release->branch));
+ foreach($moduleGroups as $modules) $searchModules += $modules;
+ $this->config->bug->search['params']['module']['values'] = $searchModules;
+
if($this->session->currentProductType == 'normal')
{
unset($this->config->bug->search['fields']['branch']);
@@ -611,28 +632,31 @@ class release extends control
}
else
{
- $this->config->bug->search['fields']['branch'] = $this->lang->product->branch;
- $branchName = $this->loadModel('branch')->getById($release->branch);
- $branches = array('' => '', BRANCH_MAIN => $this->lang->branch->main, $release->branch => $branchName);
+ $allBranchs = $this->loadModel('branch')->getPairs($release->product);
+ $branches = array('' => '', BRANCH_MAIN => $this->lang->branch->main);
+ foreach(explode(',', trim($release->branch, ',')) as $branchID) $branches[$branchID] = zget($allBranchs, $branchID);
+
+ $this->config->bug->search['fields']['branch'] = sprintf($this->lang->product->branch, $this->lang->product->branchName[$release->productType]);
$this->config->bug->search['params']['branch']['values'] = $branches;
}
$this->loadModel('search')->setSearchParams($this->config->bug->search);
+ $builds = $this->loadModel('build')->getByList($release->build);
$allBugs = array();
$releaseBugs = $type == 'bug' ? $release->bugs : $release->leftBugs;
- if($browseType == 'bySearch' or $build->execution == 0)
+ if($browseType == 'bySearch')
{
$allBugs = $this->bug->getBySearch($release->product, $release->branch, $queryID, 'id_desc', $releaseBugs, $pager);
}
- elseif($build->execution)
+ else
{
if($type == 'bug')
{
- $allBugs = $this->bug->getReleaseBugs($build->id, $release->product, $release->branch, $releaseBugs, $pager);
+ $allBugs = $this->bug->getReleaseBugs(array_keys($builds), $release->product, $release->branch, $releaseBugs, $pager);
}
elseif($type == 'leftBug')
{
- $allBugs = $this->bug->getProductLeftBugs($build->id, $release->product, $release->branch, $releaseBugs, $pager);
+ $allBugs = $this->bug->getProductLeftBugs(array_keys($builds), $release->product, $release->branch, $releaseBugs, $pager);
}
}
diff --git a/module/release/css/browse.css b/module/release/css/browse.css
index 8c33b9fd78..dd6d856b51 100644
--- a/module/release/css/browse.css
+++ b/module/release/css/browse.css
@@ -1,5 +1,6 @@
#releaseList {font-size: 13px;}
td {overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
+#releaseList tbody>tr:hover{background-color: unset!important;}
.main-table tbody>tr>td:first-child{padding: 2px 8px!important;}
.c-id {width: 60px}
diff --git a/module/release/lang/de.php b/module/release/lang/de.php
index 5b9df0f6a5..81723c68b5 100644
--- a/module/release/lang/de.php
+++ b/module/release/lang/de.php
@@ -38,6 +38,8 @@ $lang->release->product = $lang->productCommon;
$lang->release->branch = 'Platform/Branch';
$lang->release->project = 'Project';
$lang->release->build = 'Build';
+$lang->release->includedBuild = 'Included Build';
+$lang->release->relatedProject = 'Related Project';
$lang->release->name = 'Name';
$lang->release->marker = 'Meilensteine';
$lang->release->date = 'Datum';
diff --git a/module/release/lang/en.php b/module/release/lang/en.php
index 14f54db539..c480cbd021 100644
--- a/module/release/lang/en.php
+++ b/module/release/lang/en.php
@@ -39,6 +39,8 @@ $lang->release->product = $lang->productCommon;
$lang->release->branch = 'Platform/Branch';
$lang->release->project = 'Project';
$lang->release->build = 'Build';
+$lang->release->includedBuild = 'Included Build';
+$lang->release->relatedProject = 'Related Project';
$lang->release->name = 'Name';
$lang->release->marker = 'Milestone';
$lang->release->date = 'Release Date';
diff --git a/module/release/lang/fr.php b/module/release/lang/fr.php
index 1f5dbdf9e1..c27bfe6121 100644
--- a/module/release/lang/fr.php
+++ b/module/release/lang/fr.php
@@ -38,6 +38,8 @@ $lang->release->product = $lang->productCommon;
$lang->release->branch = 'Plateforme/Branche';
$lang->release->project = 'Project';
$lang->release->build = 'Build';
+$lang->release->includedBuild = 'Included Build';
+$lang->release->relatedProject = 'Related Project';
$lang->release->name = 'Nom';
$lang->release->marker = 'Etape Importante';
$lang->release->date = 'Date Release';
diff --git a/module/release/lang/zh-cn.php b/module/release/lang/zh-cn.php
index 6689db4489..57af6338f2 100644
--- a/module/release/lang/zh-cn.php
+++ b/module/release/lang/zh-cn.php
@@ -39,6 +39,8 @@ $lang->release->product = $lang->productCommon;
$lang->release->branch = '平台/分支';
$lang->release->project = '所属项目';
$lang->release->build = '版本';
+$lang->release->includedBuild = '包含版本';
+$lang->release->relatedProject = '对应项目';
$lang->release->name = '发布名称';
$lang->release->marker = '里程碑';
$lang->release->date = '发布日期';
diff --git a/module/release/model.php b/module/release/model.php
index 92d8aaa8d4..db12c0f417 100644
--- a/module/release/model.php
+++ b/module/release/model.php
@@ -31,7 +31,7 @@ class releaseModel extends model
->fetch();
if(!$release) return false;
- $release->builds = $this->dao->select('id, filePath, scmPath, name, project')->from(TABLE_BUILD)->where('id')->in($release->build)->fetchAll();
+ $release->builds = $this->dao->select('id, filePath, scmPath, name, execution, project')->from(TABLE_BUILD)->where('id')->in($release->build)->fetchAll();
$this->loadModel('file');
$release = $this->file->replaceImgURL($release, 'desc');
@@ -66,7 +66,7 @@ class releaseModel extends model
->page($pager)
->fetchAll();
- $builds = $this->dao->select("t1.id, t1.name, IF(t2.name IS NOT NULL, t2.name, '') AS projectName, IF(t3.name IS NOT NULL, t3.name, '{$this->lang->trunk}') AS branchName")
+ $builds = $this->dao->select("t1.id, t1.name, t1.execution, IF(t2.name IS NOT NULL, t2.name, '') AS projectName, IF(t3.name IS NOT NULL, t3.name, '{$this->lang->trunk}') AS branchName")
->from(TABLE_BUILD)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
->leftJoin(TABLE_BRANCH)->alias('t3')->on('t1.branch = t3.id')
diff --git a/module/release/view/browse.html.php b/module/release/view/browse.html.php
index 5552c7eb28..b78e2b51fc 100644
--- a/module/release/view/browse.html.php
+++ b/module/release/view/browse.html.php
@@ -51,8 +51,8 @@
release->id;?>
release->name;?>
- release->build;?>
- release->project;?>
+ release->includedBuild;?>
+ release->relatedProject;?>
release->status;?>
release->date;?>
type != 'normal'):?>
branchName;?>
- createLink('build', 'view', "buildID=$build->id"), $build->name);?>
+ createLink($build->execution ? 'build' : 'projectbuild', 'view', "buildID=$build->id"), $build->name);?>
projectName;?>
diff --git a/module/release/view/view.html.php b/module/release/view/view.html.php
index dbb2394344..3b60363ba9 100644
--- a/module/release/view/view.html.php
+++ b/module/release/view/view.html.php
@@ -357,7 +357,7 @@
foreach($release->builds as $build)
{
$buildDivision = $i == count($release->builds) ? '' : $lang->comma;
- echo (($build->project) ? html::a($this->createLink('build', 'view', "buildID=$build->id"), $build->name, '_blank') : $build->name) . $buildDivision;
+ echo (($build->project) ? html::a($this->createLink($build->execution ? 'build' : 'projectbuild', 'view', "buildID=$build->id"), $build->name) : $build->name) . $buildDivision;
$i++;
}
?>
diff --git a/module/search/model.php b/module/search/model.php
index 1c36a7a665..001fceda17 100644
--- a/module/search/model.php
+++ b/module/search/model.php
@@ -973,10 +973,11 @@ class searchModel extends model
if($this->app->user->admin) return $results;
$this->loadModel('doc');
- $products = $this->app->user->view->products;
- $programs = $this->app->user->view->programs;
- $projects = $this->app->user->view->projects;
- $executions = $this->app->user->view->sprints;
+ $products = $this->app->user->view->products;
+ $shadowProducts = $this->dao->select('id')->from(TABLE_PRODUCT)->where('shadow')->eq(1)->fetchPairs('id');
+ $programs = $this->app->user->view->programs;
+ $projects = $this->app->user->view->projects;
+ $executions = $this->app->user->view->sprints;
$objectPairs = array();
$total = count($results);
@@ -1014,6 +1015,7 @@ class searchModel extends model
foreach($objectIdList as $productID => $recordID)
{
if(strpos(",$products,", ",$productID,") === false) unset($results[$recordID]);
+ if(in_array($productID, $shadowProducts)) unset($results[$recordID]);
}
}
elseif($objectType == 'program')
diff --git a/module/story/control.php b/module/story/control.php
index 6cffa44848..ef31bfa269 100755
--- a/module/story/control.php
+++ b/module/story/control.php
@@ -396,6 +396,7 @@ class story extends control
/* Hidden some fields of projects without products. */
$this->view->hiddenProduct = false;
+ $this->view->hiddenParent = false;
$this->view->hiddenPlan = false;
$this->view->hiddenURS = false;
$this->view->teamUsers = array();
@@ -409,6 +410,7 @@ class story extends control
{
$this->view->teamUsers = $this->project->getTeamMemberPairs($project->id);
$this->view->hiddenProduct = true;
+ $this->view->hiddenParent = true;
if($project->model !== 'scrum') $this->view->hiddenPlan = true;
if(!$project->multiple) $this->view->hiddenPlan = true;
@@ -883,6 +885,7 @@ class story extends control
/* Hidden some fields of projects without products. */
$this->view->hiddenProduct = false;
+ $this->view->hiddenParent = false;
$this->view->hiddenPlan = false;
$this->view->hiddenURS = false;
$this->view->teamUsers = array();
@@ -892,6 +895,7 @@ class story extends control
$project = $this->project->getByShadowProduct($product->id);
$this->view->teamUsers = $this->project->getTeamMemberPairs($project->id);
$this->view->hiddenProduct = true;
+ $this->view->hiddenParent = true;
if($project->model !== 'scrum') $this->view->hiddenPlan = true;
if(!$project->multiple) $this->view->hiddenPlan = true;
@@ -1085,7 +1089,7 @@ class story extends control
}
/* Set ditto option for users. */
- $users = $this->loadModel('user')->getPairs('nodeleted');
+ $users = $this->loadModel('user')->getPairs('nodeleted|noclosed');
$users = array('' => '', 'ditto' => $this->lang->story->ditto) + $users;
/* Set Custom*/
@@ -2777,7 +2781,7 @@ class story extends control
$this->config->story->datatable->fieldList['plan']['dataSource'] = array('module' => 'productplan', 'method' => 'getPairs', 'params' => $productIdList);
}
- $this->post->set('rows', $this->story->getExportStorys($executionID, $orderBy));
+ $this->post->set('rows', $this->story->getExportStorys($executionID, $orderBy, $storyType));
$this->fetch('transfer', 'export', 'model=story');
}
@@ -2816,7 +2820,7 @@ class story extends control
if(isset($project->hasProduct) && !$project->hasProduct)
{
$filterFields = array('product,', 'branch,');
- if($project->model != 'scrum') $filterFields[] = 'plan';
+ if($project->model != 'scrum') $filterFields[] = 'plan,';
$this->config->story->exportFields = str_replace($filterFields, '', $this->config->story->exportFields);
}
diff --git a/module/story/js/common.js b/module/story/js/common.js
index 6a1503c104..5be7092e6e 100644
--- a/module/story/js/common.js
+++ b/module/story/js/common.js
@@ -22,7 +22,7 @@ $(function()
$('#saveButton').on('click', function()
{
- $('#saveButton').attr('disabled', true);
+ $('#saveButton').attr('type', 'submit').attr('disabled', true);
$('#saveDraftButton').attr('disabled', true);
var storyStatus = !$('#reviewer').val() || $('#needNotReview').is(':checked') ? 'active' : 'reviewing';
@@ -31,7 +31,7 @@ $(function()
setTimeout(function()
{
- $('#saveButton').removeAttr('disabled');
+ $('#saveButton').attr('type', 'button').removeAttr('disabled');
$('#saveDraftButton').removeAttr('disabled');
}, 1000);
});
@@ -39,7 +39,7 @@ $(function()
$('#saveDraftButton').on('click', function()
{
$('#saveButton').attr('disabled', true);
- $('#saveDraftButton').attr('disabled', true);
+ $('#saveDraftButton').attr('type', 'submit').attr('disabled', true);
storyStatus = 'draft';
if(typeof(page) != 'undefined' && page == 'change') storyStatus = 'changing';
@@ -50,7 +50,7 @@ $(function()
setTimeout(function()
{
$('#saveButton').removeAttr('disabled');
- $('#saveDraftButton').removeAttr('disabled');
+ $('#saveDraftButton').attr('type', 'button').removeAttr('disabled');
}, 1000);
});
})
diff --git a/module/story/model.php b/module/story/model.php
index ce627b9b37..e0f14160fc 100644
--- a/module/story/model.php
+++ b/module/story/model.php
@@ -4218,7 +4218,7 @@ class storyModel extends model
if($action == 'batchcreate' and $story->parent > 0) return false;
if($action == 'batchcreate' and $story->type == 'requirement' and $story->status != 'closed') return strpos('draft,reviewing,changing', $story->status) === false;
if($action == 'batchcreate' and $config->vision == 'lite' and ($story->status == 'active' and ($story->stage == 'wait' or $story->stage == 'projected'))) return true;
- /* Adjust code, hide split entry, fix bug #29432. */
+ /* Adjust code, hide split entry. */
if($action == 'batchcreate' and ($story->status != 'active' or (isset($shadowProducts[$story->product])) or (!isset($shadowProducts[$story->product]) && $story->stage != 'wait') or !empty($story->plan))) return false;
return true;
@@ -4489,7 +4489,7 @@ class storyModel extends model
$executionID = empty($execution) ? 0 : $execution->id;
- /* Adjust code, hide split entry, fix bug #29432. */
+ /* Adjust code, hide split entry. */
if(common::hasPriv('story', 'batchCreate') and !$execution->multiple and !$execution->hasProduct and false)
{
$isClick = $this->isClickable($story, 'batchcreate');
@@ -5878,13 +5878,16 @@ class storyModel extends model
*
* @param int $executionID
* @param string $orderBy
+ * @param string $storyType
* @access public
* @return void
*/
- public function getExportStorys($executionID, $orderBy = 'id_desc')
+ public function getExportStorys($executionID, $orderBy = 'id_desc', $storyType = 'story')
{
$this->loadModel('file');
$this->loadModel('branch');
+
+ $this->replaceURLang($storyType);
$storyLang = $this->lang->story;
$storyConfig = $this->config->story;
diff --git a/module/story/view/create.html.php b/module/story/view/create.html.php
index 5ba9b5c1a0..3f92c9a6f5 100644
--- a/module/story/view/create.html.php
+++ b/module/story/view/create.html.php
@@ -161,7 +161,7 @@ foreach(explode(',', $config->story->create->requiredFields) as $field)
story->parent : $lang->story->requirement;?>
-
+ >
-
+ >
story->parent;?>
@@ -297,8 +297,12 @@ foreach(explode(',', $config->story->create->requiredFields) as $field)
+
+
+
save, "id='saveButton'", 'btn btn-primary btn-wide');?>
story->saveDraft, "id='saveDraftButton'", 'btn btn-secondary btn-wide');?>
+
goback, '', 'class="btn btn-wide"') : html::backButton('', $source == 'bug' ? 'data-app=qa' : '');?>
diff --git a/module/story/view/edit.html.php b/module/story/view/edit.html.php
index df89e7043a..ea2bc86610 100644
--- a/module/story/view/edit.html.php
+++ b/module/story/view/edit.html.php
@@ -166,7 +166,7 @@
parent >= 0 and $story->type == 'story'):?>
-
+
story->parent;?>
parent, "class='form-control chosen'");?>
diff --git a/module/story/view/view.html.php b/module/story/view/view.html.php
index aab887a7cf..91b29a8998 100644
--- a/module/story/view/view.html.php
+++ b/module/story/view/view.html.php
@@ -53,7 +53,7 @@
app->rawModule == 'projectstory')
+ if($this->app->rawModule == 'projectstory' or $this->app->tab == 'project')
{
$otherParam = "storyID=&projectID={$this->session->project}";
$tab = 'project';
diff --git a/module/task/js/create.js b/module/task/js/create.js
index 36e63a45ff..0dcd61d073 100644
--- a/module/task/js/create.js
+++ b/module/task/js/create.js
@@ -343,7 +343,7 @@ function setStories(moduleID, executionID)
$("#story").addClass('filled').chosen();
/* If there is no story option, select will be hidden and text will be displayed; otherwise, the opposite is true */
- if($('#story option').length > 1)
+ if($('#story option').length > 1 || parseInt(hasProduct) == 0)
{
$('#story').parent().removeClass('hidden');
$('#storyBox').addClass('hidden');
diff --git a/module/task/view/create.html.php b/module/task/view/create.html.php
index f66321ccb0..8e2f516d47 100644
--- a/module/task/view/create.html.php
+++ b/module/task/view/create.html.php
@@ -23,6 +23,7 @@
error->gt, $lang->task->estimate, '0'))?>
lifetime);?>
+hasProduct);?>
task->create->requiredFields) as $field)
diff --git a/module/testcase/control.php b/module/testcase/control.php
index 3fd762ac30..bc0c8115f8 100644
--- a/module/testcase/control.php
+++ b/module/testcase/control.php
@@ -348,8 +348,6 @@ class testcase extends control
$stories = array_chunk($stories, $pager->recPerPage);
$this->view->title = $this->lang->story->zeroCase;
- $this->view->position[] = html::a($this->createLink('testcase', 'browse', "productID=$productID"), $products[$productID]);
- $this->view->position[] = $this->lang->story->zeroCase;
$this->view->stories = empty($stories) ? $stories : $stories[$pageID - 1];
$this->view->users = $this->user->getPairs('noletter');
diff --git a/module/transfer/control.php b/module/transfer/control.php
index 1f58dc5022..b9b7851107 100755
--- a/module/transfer/control.php
+++ b/module/transfer/control.php
@@ -159,14 +159,14 @@ class transfer extends control
if($model == 'story')
{
- $product = $this->loadModel('product')->getByID($this->session->storyPortParams['productID']);
+ $product = $this->loadModel('product')->getByID($this->session->storyTransferParams['productID']);
if($product->type == 'normal') unset($fields['branch']);
if($this->session->storyType == 'requirement') unset($fields['plan']);
}
if($model == 'bug')
{
- $product = $this->loadModel('product')->getByID($this->session->bugPortParams['productID']);
+ $product = $this->loadModel('product')->getByID($this->session->bugTransferParams['productID']);
if($product->type == 'normal') unset($fields['branch']);
if($product->shadow and ($this->app->tab == 'execution' or $this->app->tab == 'project')) unset($fields['product']);
}
diff --git a/module/transfer/model.php b/module/transfer/model.php
index 6ec348d984..0837f45652 100644
--- a/module/transfer/model.php
+++ b/module/transfer/model.php
@@ -56,16 +56,16 @@ class transferModel extends model
}
/**
- * Check tmpFile.
+ * Check tmp file.
*
* @access public
* @return void
*/
public function checkTmpFile()
{
- $file = $this->session->fileImportFileName;
- $tmpPath = $this->loadModel('file')->getPathOfImportedFile();
- $tmpFile = $tmpPath . DS . md5(basename($file));
+ $file = $this->session->fileImportFileName;
+ $tmpPath = $this->loadModel('file')->getPathOfImportedFile();
+ $tmpFile = $tmpPath . DS . md5(basename($file));
if($this->maxImport and file_exists($tmpFile)) return $tmpFile;
return false;
@@ -196,7 +196,7 @@ class transferModel extends model
$rows = $this->getRows($model, $fieldList);
if($model == 'story')
{
- $product = $this->loadModel('product')->getByID((int)$this->session->storyPortParams['productID']);
+ $product = $this->loadModel('product')->getByID((int)$this->session->storyTransferParams['productID']);
if($product and $product->shadow)
{
foreach($rows as $id => $row)
diff --git a/module/tree/control.php b/module/tree/control.php
index 769bc0a4f6..1041211554 100644
--- a/module/tree/control.php
+++ b/module/tree/control.php
@@ -400,15 +400,16 @@ class tree extends control
$this->view->branch = $branch;
$this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted', $module->owner);
- $showProduct = strpos('story|bug|case', $type) !== false ? true : false;
- $this->view->showProduct = $showProduct;
+ $showProduct = strpos('story|bug|case', $type) !== false ? true : false;
if($showProduct)
{
$product = $this->loadModel('product')->getById($module->root);
if($product->type != 'normal') $this->view->branches = $this->loadModel('branch')->getPairs($module->root, 'withClosed');
$this->view->product = $product;
$this->view->products = $this->product->getPairs('', $product->program);
+ if($product->shadow) $showProduct = false;
}
+ $this->view->showProduct = $showProduct;
/* Remove self and childs from the $optionMenu. Because it's parent can't be self or childs. */
$childs = $this->tree->getAllChildId($moduleID);
diff --git a/module/tree/model.php b/module/tree/model.php
index 0815f377a5..3a11582c03 100644
--- a/module/tree/model.php
+++ b/module/tree/model.php
@@ -852,7 +852,7 @@ class treeModel extends model
{
$extra['productID'] = $id;
$projectProductLink = helper::createLink('projectstory', 'story', "projectID=$rootID&productID=$id&branch=all");
- $executionProductLink = helper::createLink('execution', 'story', "executionID=$rootID&ordery=&status=byProduct&praram=$id");
+ $executionProductLink = helper::createLink('execution', 'story', "executionID=$rootID&storyType=story&orderBy=&type=byProduct&praram=$id");
$link = $this->app->rawModule == 'projectstory' ? $projectProductLink : $executionProductLink;
if($productNum > 1) $menu .= "
" . html::a($link, $product, '_self', "id='product$id' title=$product");
diff --git a/module/tutorial/lang/de.php b/module/tutorial/lang/de.php
index eb42def366..581481dc40 100644
--- a/module/tutorial/lang/de.php
+++ b/module/tutorial/lang/de.php
@@ -74,3 +74,6 @@ $lang->tutorial->tasks['createTask']['desc'] = "Aufgaben aufteilen:
<
$lang->tutorial->tasks['createBug'] = array('title' => 'Bug melden');
$lang->tutorial->tasks['createBug']['nav'] = array('module' => 'bug', 'method' => 'create', 'menuModule' => 'qa', 'menu' => 'bug', 'target' => '.btn-bug-create', 'form' => '#dataform', 'submit' => '#submit', 'targetPageName' => 'Bug erstellen');
$lang->tutorial->tasks['createBug']['desc'] = "Bug erstellen:
Öffnen Test Bug Einen Bug erstellen ; Tragen Sie die Bug Informationen ein: Speichern ";
+
+global $config;
+if($config->systemMode == 'light') unset($lang->tutorial->tasks['createProgram']);
diff --git a/module/tutorial/lang/en.php b/module/tutorial/lang/en.php
index 026fc7c429..5182e29620 100644
--- a/module/tutorial/lang/en.php
+++ b/module/tutorial/lang/en.php
@@ -74,3 +74,6 @@ $lang->tutorial->tasks['createTask']['desc'] = "Task breakdown for a story: <
$lang->tutorial->tasks['createBug'] = array('title' => 'Report Bug');
$lang->tutorial->tasks['createBug']['nav'] = array('app' => 'qa', 'module' => 'bug', 'method' => 'create', 'menuModule' => 'bug', 'menu' => 'bug', 'target' => '.create-bug-btn', 'form' => '#dataform', 'submit' => '#submit', 'targetPageName' => 'Report Bug');
$lang->tutorial->tasks['createBug']['desc'] = "
Report a Bug:
Open Test Bug Report Bug ; Fill the form with bug information: Save ";
+
+global $config;
+if($config->systemMode == 'light') unset($lang->tutorial->tasks['createProgram']);
diff --git a/module/tutorial/lang/fr.php b/module/tutorial/lang/fr.php
index b1a29b235e..54852235f1 100644
--- a/module/tutorial/lang/fr.php
+++ b/module/tutorial/lang/fr.php
@@ -74,3 +74,6 @@ $lang->tutorial->tasks['createTask']['desc'] = "Task breakdown for a story: <
$lang->tutorial->tasks['createBug'] = array('title' => 'Report Bug');
$lang->tutorial->tasks['createBug']['nav'] = array('module' => 'bug', 'method' => 'create', 'menuModule' => 'qa', 'menu' => 'bug', 'target' => '.btn-bug-create', 'form' => '#dataform', 'submit' => '#submit', 'targetPageName' => 'Report Bug');
$lang->tutorial->tasks['createBug']['desc'] = "
Report a Bug:
Open Test Bug Report Bug ; Fill the form with bug information: Save ";
+
+global $config;
+if($config->systemMode == 'light') unset($lang->tutorial->tasks['createProgram']);
diff --git a/module/tutorial/lang/zh-cn.php b/module/tutorial/lang/zh-cn.php
index 83b8f77bee..486c56f16b 100644
--- a/module/tutorial/lang/zh-cn.php
+++ b/module/tutorial/lang/zh-cn.php
@@ -74,3 +74,6 @@ $lang->tutorial->tasks['createTask']['desc'] = "将执行{$lang->SRCommon}分
$lang->tutorial->tasks['createBug'] = array('title' => '提Bug');
$lang->tutorial->tasks['createBug']['nav'] = array('app' => 'qa', 'module' => 'bug', 'method' => 'create', 'menuModule' => 'bug', 'menu' => 'bug', 'target' => '.create-bug-btn', 'vars' => 'productID=0', 'form' => '#dataform', 'submit' => '#submit', 'targetPageName' => '提Bug');
$lang->tutorial->tasks['createBug']['desc'] = "
在系统中提交一个Bug:
打开 测试 Bug 提Bug ; 在表单中填写Bug信息; 保存Bug信息。 ";
+
+global $config;
+if($config->systemMode == 'light') unset($lang->tutorial->tasks['createProgram']);