diff --git a/config/zentaopms.php b/config/zentaopms.php
index 4b8f72d147..8bf7fdc792 100644
--- a/config/zentaopms.php
+++ b/config/zentaopms.php
@@ -280,5 +280,5 @@ $config->newFeatures = array('introduction', 'tutorial', 'youngBlueTheme');
/* Program privs.*/
$config->programPriv = new stdclass();
-$config->programPriv->scrum = array('projectstory', 'projectrelease', 'project', 'build', 'bug', 'testcase', 'testreport', 'caselib', 'doc', 'repo', 'meeting');
+$config->programPriv->scrum = array('projectstory', 'projectrelease', 'project', 'build', 'bug', 'testcase', 'testreport', 'caselib', 'doc', 'repo', 'meeting', 'stakeholder');
$config->programPriv->waterfall = array_merge($config->programPriv->scrum, array('workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'milestone', 'design', 'issue', 'risk', 'opportunity', 'measrecord', 'auditplan', 'trainplan', 'gapanalysis', 'pssp'));
diff --git a/module/action/lang/en.php b/module/action/lang/en.php
index d8f8cdd729..9767de0ddb 100755
--- a/module/action/lang/en.php
+++ b/module/action/lang/en.php
@@ -498,7 +498,7 @@ $lang->action->label->testtask = 'Request|testtask|view|caseID=%s';
$lang->action->label->testsuite = 'Test Suite|testsuite|view|suiteID=%s';
$lang->action->label->caselib = 'Case Library|caselib|view|libID=%s';
$lang->action->label->todo = 'Todo|todo|view|todoID=%s';
-$lang->action->label->doclib = 'Doc Library|doc|objectLibs|type=%s&objectID=%s&libID=%s&docID=&version=&appendLib=%s';
+$lang->action->label->doclib = 'Doc Library|doc|objectLibs|type=%s&objectID=%s&libID=%s';
$lang->action->label->doc = 'Doc|doc|view|docID=%s';
$lang->action->label->user = 'User|user|view|account=%s';
$lang->action->label->testreport = 'Report|testreport|view|report=%s';
diff --git a/module/action/model.php b/module/action/model.php
index 8c289f283e..f665e432e9 100755
--- a/module/action/model.php
+++ b/module/action/model.php
@@ -1424,10 +1424,11 @@ class actionModel extends model
* @param array $actions
* @param string $direction
* @param string $type all|today|yesterday|thisweek|lastweek|thismonth|lastmonth
+ * @param string $orderBy date_desc|date_asc
* @access public
* @return array
*/
- public function buildDateGroup($actions, $direction = 'next', $type = 'today')
+ public function buildDateGroup($actions, $direction = 'next', $type = 'today', $orderBy = 'date_desc')
{
$dateGroup = array();
foreach($actions as $action)
@@ -1455,7 +1456,17 @@ class actionModel extends model
}
}
- if($direction != 'next') $dateGroup = array_reverse($dateGroup);
+ /* Modify date to the corrret order. */
+ if($this->app->rawModule != 'company' and $direction != 'next')
+ {
+ $dateGroup = array_reverse($dateGroup);
+ }
+ elseif($this->app->rawModule == 'company' and (($direction == 'next' and $orderBy == 'date_asc') or ($direction == 'pre' and $orderBy == 'date_desc')))
+ {
+ $dateGroup = array_reverse($dateGroup);
+ foreach($dateGroup as $key => $dateItem) $dateGroup[$key] = array_reverse($dateItem);
+ }
+
return $dateGroup;
}
diff --git a/module/backup/lang/en.php b/module/backup/lang/en.php
index a0139051a0..2b5109c58b 100644
--- a/module/backup/lang/en.php
+++ b/module/backup/lang/en.php
@@ -8,14 +8,14 @@ $lang->backup->restore = 'Restore';
$lang->backup->change = 'Edit Expiration';
$lang->backup->changeAB = 'Edit';
$lang->backup->rmPHPHeader = 'Remove PHP header';
-$lang->backup->setting = 'Setting';
+$lang->backup->setting = 'Settings';
-$lang->backup->settingAction = 'Backup Setting';
+$lang->backup->settingAction = 'Backup Settings';
$lang->backup->time = 'Date';
$lang->backup->files = 'Files';
-$lang->backup->allCount = 'All Count';
-$lang->backup->count = 'Backup Count';
+$lang->backup->allCount = 'All Files';
+$lang->backup->count = 'Backup Files';
$lang->backup->size = 'Size';
$lang->backup->status = 'Status';
diff --git a/module/block/model.php b/module/block/model.php
index ab34ff2761..6c2acd1c37 100644
--- a/module/block/model.php
+++ b/module/block/model.php
@@ -173,7 +173,7 @@ class blockModel extends model
->andWhere('t2.status')->ne('suspended')
->andWhere('t3.status')->ne('suspended')
->andWhere('t2.type')->eq('project')
- ->andWhere('t3.type')->eq('sprint')
+ ->andWhere('t3.type')->in('sprint,stage')
->andWhere('t1.deleted')->eq(0)
->andWhere('t2.deleted')->eq(0)
->andWhere('t3.deleted')->eq(0)
diff --git a/module/company/control.php b/module/company/control.php
index ca4c93f11c..1ce38f6366 100644
--- a/module/company/control.php
+++ b/module/company/control.php
@@ -167,7 +167,7 @@ class company extends control
* @param int $productID
* @param int $projectID
* @param int $executionID
- * @param string $orderBy
+ * @param string $orderBy date_deac|date_asc
* @access public
* @return void
*/
@@ -204,7 +204,8 @@ class company extends control
$pager = new pager($recTotal, $recPerPage = 50, $pageID = 1);
/* Append id for secend sort. */
- $sort = $this->loadModel('common')->appendOrder($orderBy);
+ $order = $direction == 'next' ? 'date_desc' : 'date_asc';
+ $sort = $this->loadModel('common')->appendOrder($order);
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
$date = empty($date) ? '' : date('Y-m-d', $date);
@@ -289,7 +290,7 @@ class company extends control
$this->view->userID = $userID;
$this->view->param = $param;
$this->view->browseType = $browseType;
- $this->view->dateGroups = $this->action->buildDateGroup($actions, $direction, $browseType);
+ $this->view->dateGroups = $this->action->buildDateGroup($actions, $direction, $browseType, $orderBy);
$this->view->direction = $direction;
$this->display();
}
diff --git a/module/company/view/dynamic.html.php b/module/company/view/dynamic.html.php
index 3c5bc77f7e..65620af0ed 100644
--- a/module/company/view/dynamic.html.php
+++ b/module/company/view/dynamic.html.php
@@ -96,8 +96,8 @@ $firstDate = date('Y-m-d', strtotime($firstAction->originalDate) + 24 * 3600);
$lastDate = substr($action->originalDate, 0, 10);
$hasPre = $this->action->hasPreOrNext($firstDate, 'pre');
$hasNext = $this->action->hasPreOrNext($lastDate, 'next');
-$preLink = $hasPre ? inlink('dynamic', "browseType=$browseType¶m=$param&recTotal={$pager->recTotal}&date=" . strtotime($firstDate) . '&direction=pre') : 'javascript:;';
-$nextLink = $hasNext ? inlink('dynamic', "browseType=$browseType¶m=$param&recTotal={$pager->recTotal}&date=" . strtotime($lastDate) . '&direction=next') : 'javascript:;';
+$preLink = $hasPre ? inlink('dynamic', "browseType=$browseType¶m=$param&recTotal={$pager->recTotal}&date=" . strtotime($firstDate) . "&direction=pre&userID=$userID&productID=$productID&projectID=$projectID&executionID=$executionID&orderBy=$orderBy") : 'javascript:;';
+$nextLink = $hasNext ? inlink('dynamic', "browseType=$browseType¶m=$param&recTotal={$pager->recTotal}&date=" . strtotime($lastDate) . "&direction=next&userID=$userID&productID=$productID&projectID=$projectID&executionID=$executionID&orderBy=$orderBy") : 'javascript:;';
?>
diff --git a/module/execution/lang/en.php b/module/execution/lang/en.php
index 5ff823d2c8..34e75a84cf 100644
--- a/module/execution/lang/en.php
+++ b/module/execution/lang/en.php
@@ -31,15 +31,17 @@ $lang->execution->canceledDate = 'CanceledDate';
$lang->execution->begin = 'Begin';
$lang->execution->end = 'End';
$lang->execution->dateRange = 'Duration';
-$lang->execution->realBegan = 'Actual start';
-$lang->execution->realEnd = 'Actual end';
+$lang->execution->realBeganAB = 'Actual Begin';
+$lang->execution->realEndAB = 'Actual End';
+$lang->execution->realBegan = 'Actual Begin';
+$lang->execution->realEnd = 'Actual End';
$lang->execution->to = 'To';
-$lang->execution->days = 'Available Days';
+$lang->execution->days = ' Days';
$lang->execution->day = ' Days';
$lang->execution->workHour = ' Hours';
$lang->execution->workHourUnit = 'H';
-$lang->execution->totalHours = 'Available Hours';
-$lang->execution->totalDays = 'Available Days';
+$lang->execution->totalHours = ' Hours';
+$lang->execution->totalDays = ' Days';
$lang->execution->status = $lang->executionCommon . 'Status';
$lang->execution->execStatus = 'Status';
$lang->execution->subStatus = 'Sub Status';
@@ -351,6 +353,10 @@ $lang->execution->unfinishedExecution = "This {$lang->executionCommon} h
$lang->execution->unfinishedTask = "[%s] unfinished tasks. ";
$lang->execution->unresolvedBug = "[%s] unresolved bugs. ";
$lang->execution->projectNotEmpty = 'Project cannot be empty.';
+$lang->execution->realBeganNotEmpty = 'Actual Begin should not be empty.';
+$lang->execution->realBeganNotFuture = 'Actual Begin should be < = today.';
+$lang->execution->realEndNotEmpty = 'Actual End should not be empty.';
+$lang->execution->realEndNotFuture = 'Actual End should be < = today.';
/* Statistics. */
$lang->execution->charts = new stdclass();
diff --git a/module/execution/lang/zh-cn.php b/module/execution/lang/zh-cn.php
index 6213a08bf4..2e1a39d7ef 100644
--- a/module/execution/lang/zh-cn.php
+++ b/module/execution/lang/zh-cn.php
@@ -31,8 +31,10 @@ $lang->execution->canceledDate = '取消日期';
$lang->execution->begin = '计划开始';
$lang->execution->end = '计划完成';
$lang->execution->dateRange = '起始日期';
-$lang->execution->realBegan = '实际开始';
-$lang->execution->realEnd = '实际完成';
+$lang->execution->realBeganAB = '实际开始';
+$lang->execution->realEndAB = '实际完成';
+$lang->execution->realBegan = '实际开始日期';
+$lang->execution->realEnd = '实际完成日期';
$lang->execution->to = '至';
$lang->execution->days = '可用工作日';
$lang->execution->day = '天';
@@ -351,6 +353,11 @@ $lang->execution->unfinishedExecution = "该{$lang->executionCommon}下
$lang->execution->unfinishedTask = "[%s]个未完成的任务,";
$lang->execution->unresolvedBug = "[%s]个未解决的bug,";
$lang->execution->projectNotEmpty = '所属项目不能为空。';
+$lang->execution->realBeganNotEmpty = "实际开始不能为空。";
+$lang->execution->realBeganNotFuture = "实际开始不能大于当前日期。";
+$lang->execution->realEndNotEmpty = "实际完成不能为空。";
+$lang->execution->realEndNotFuture = "实际完成不能大于当前日期。";
+
/* 统计。*/
$lang->execution->charts = new stdclass();
diff --git a/module/execution/model.php b/module/execution/model.php
index b9bfe0d9f1..b31e98d682 100644
--- a/module/execution/model.php
+++ b/module/execution/model.php
@@ -700,14 +700,24 @@ class executionModel extends model
$now = helper::now();
$execution = fixer::input('post')
- ->add('realBegan', helper::today())
->setDefault('status', 'doing')
->setDefault('lastEditedBy', $this->app->user->account)
->setDefault('lastEditedDate', $now)
->remove('comment')->get();
+
+ if($execution->realBegan == '')
+ {
+ dao::$errors['realBegan'] = $this->lang->execution->realBeganNotEmpty;
+ return false;
+ }
+ if($execution->realBegan > helper::today())
+ {
+ dao::$errors['realBegan'] = $this->lang->execution->realBeganNotFuture;
+ return false;
+ }
$this->dao->update(TABLE_EXECUTION)->data($execution)->autoCheck()->where('id')->eq((int)$executionID)->exec();
-
+
if(!dao::isError()) return common::createChanges($oldExecution, $execution);
}
@@ -779,6 +789,7 @@ class executionModel extends model
$now = helper::now();
$execution = fixer::input('post')
+ ->setDefault('realEnd', '')
->setDefault('status', 'doing')
->setDefault('lastEditedBy', $this->app->user->account)
->setDefault('lastEditedDate', $now)
@@ -848,18 +859,30 @@ class executionModel extends model
$execution = fixer::input('post')
->setDefault('status', 'closed')
- ->setDefault('realEnd', helper::today())
->setDefault('closedBy', $this->app->user->account)
->setDefault('closedDate', $now)
->setDefault('lastEditedBy', $this->app->user->account)
->setDefault('lastEditedDate', $now)
->remove('comment')
->get();
+
+ if($execution->realEnd == '')
+ {
+ dao::$errors['realEnd'] = $this->lang->execution->realEndNotEmpty;
+ return false;
+ }
+
+ if($execution->realEnd > helper::today())
+ {
+ dao::$errors['realEnd'] = $this->lang->execution->realEndNotFuture;
+ return false;
+ }
$this->dao->update(TABLE_EXECUTION)->data($execution)
->autoCheck()
->where('id')->eq((int)$executionID)
->exec();
+
if(!dao::isError())
{
$this->loadModel('score')->create('execution', 'close', $oldExecution);
diff --git a/module/execution/view/close.html.php b/module/execution/view/close.html.php
index cd2f0062bf..11ebcd1ed4 100644
--- a/module/execution/view/close.html.php
+++ b/module/execution/view/close.html.php
@@ -30,6 +30,14 @@
|
printExtendFields($execution, 'table');?>
+
+ | execution->realEnd;?> |
+
+
+ realEnd) && $execution->realEnd != '0000-00-00' ? $execution->realEnd : date('Y-m-d')), "class='form-control form-date' required");?>
+
+ |
+
| comment;?> |
|
diff --git a/module/execution/view/start.html.php b/module/execution/view/start.html.php
index b45485f913..8a67e8954b 100644
--- a/module/execution/view/start.html.php
+++ b/module/execution/view/start.html.php
@@ -26,6 +26,14 @@
diff --git a/module/repo/lang/en.php b/module/repo/lang/en.php
index da7c51712f..1c58036410 100644
--- a/module/repo/lang/en.php
+++ b/module/repo/lang/en.php
@@ -133,7 +133,7 @@ $lang->repo->scmList['Subversion'] = 'SVN';
$lang->repo->gitlabHost = 'Gitlab Host';
$lang->repo->gitlabToken = 'Gitlab Token';
-$lang->repo->gitlabProject = 'Projects';
+$lang->repo->gitlabProject = 'Project';
$lang->repo->placeholder = new stdclass;
$lang->repo->placeholder->gitlabHost = 'Input url of gitlab';
diff --git a/module/tree/lang/en.php b/module/tree/lang/en.php
index 2da5813be5..9b8e08da48 100644
--- a/module/tree/lang/en.php
+++ b/module/tree/lang/en.php
@@ -29,7 +29,7 @@ $lang->tree->updateOrder = 'Rank Module';
$lang->tree->manageChild = 'Manage Child Modules';
$lang->tree->manageStoryChild = 'Manage Child Modules';
$lang->tree->manageLineChild = "Manage {$lang->productCommon} Line";
-$lang->tree->manageBugChild = 'Manage Child Bugs';
+$lang->tree->manageBugChild = 'Manage Child Modules of Bugs';
$lang->tree->manageCaseChild = 'Manage Child Cases';
$lang->tree->manageCaselibChild = 'Manage Child Libraries';
$lang->tree->manageTaskChild = "Manage Child {$lang->executionCommon} Modules";