From d560f6d2ab861df343def38c7ac180eb2d4a44d1 Mon Sep 17 00:00:00 2001 From: mayue Date: Wed, 11 May 2022 05:38:29 +0000 Subject: [PATCH 01/21] * Finish task #53652. --- module/project/control.php | 1 + module/project/model.php | 205 ++++++++++++++++++- module/project/view/ajaxgetdropmenu.html.php | 26 ++- 3 files changed, 218 insertions(+), 14 deletions(-) diff --git a/module/project/control.php b/module/project/control.php index e46b59976d..2642eb68b5 100644 --- a/module/project/control.php +++ b/module/project/control.php @@ -127,6 +127,7 @@ class project extends control unset($projects[$project->id]); } + $this->view->link = $this->project->getProjectLink($module, $method, $projectID); $this->view->projectID = $projectID; $this->view->projects = $orderedProjects; $this->view->module = $module; diff --git a/module/project/model.php b/module/project/model.php index 04a76c89f2..145776ad82 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -457,6 +457,189 @@ class projectModel extends model return $projects; } + + /** + * Create the link from module,method. + * + * @param string $module + * @param string $method + * @param int $projectID + * @access public + * @return void + */ + public function getProjectLink($module, $method, $projectID) + { + $link = helper::createLink('project', 'index', "projectID=%s"); + $project = $this->getByID($projectID); + + if(strpos(',project,product,projectstory,story,bug,testcase,testtask,testreport,build,projectrelease,stakeholder,', ',' . $module . ',') !== false) + { + if($module == 'project' and $method == 'execution') + { + $link = helper::createLink($module, $method, "status=all&projectID=%s"); + } + elseif($module == 'project' and $method == 'bug') + { + $link = helper::createLink($module, $method, "projectID=%s"); + } + elseif($module == 'project' and $method == 'testcase') + { + $link = helper::createLink($module, $method, "projectID=%s"); + } + elseif($module == 'project' and $method == 'testtask') + { + $link = helper::createLink($module, $method, "projectID=%s"); + } + elseif($module == 'project' and $method == 'testreport') + { $link = helper::createLink($module, $method, "projectID=%s"); } + elseif($module == 'project' and $method == 'build') + { + $link = helper::createLink($module, $method, "projectID=%s"); + } + elseif($module == 'project' and $method == 'dynamic') + { + $link = helper::createLink($module, $method, "projectID=%s"); + } + elseif($module == 'project' and $method == 'view') + { + $link = helper::createLink($module, $method, "projectID=%s"); + } + elseif($module == 'project' and $method == 'manageproducts') + { + $link = helper::createLink($module, $method, "projectID=%s"); + } + elseif($module == 'project' and $method == 'team') + { + $link = helper::createLink($module, $method, "projectID=%s"); + } + elseif($module == 'project' and $method == 'managemembers') + { + $link = helper::createLink($module, $method, "projectID=%s"); + } + elseif($module == 'project' and $method == 'whitelist') + { + $link = helper::createLink($module, $method, "projectID=%s"); + } + elseif($module == 'project' and $method == 'addwhitelist') + { + $link = helper::createLink($module, $method, "projectID=%s"); + } + elseif($module == 'project' and $method == 'group') + { + $link = helper::createLink($module, $method, "projectID=%s"); + } + elseif($module == 'project' and $method == 'managePriv') + { + $link = helper::createLink($module, 'group', "projectID=%s"); + } + elseif($module == 'projectstory' and $method == 'linkstory') + { + $link = helper::createLink($module, $method, "projectID=%s"); + } + elseif($module == 'bug') + { + if($method == 'create') + { + $link = helper::createLink($module, $method, "productID=0&branch=0&extras=projectID=%s"); + } + elseif($method == 'edit') + { + $link = helper::createLink('project', 'bug', "projectID=%s"); + } + } + elseif($module == 'story' and $method == 'create') + { + $link = helper::createLink($module, $method); + } + elseif($module == 'story' and $method == 'change') + { + $link = helper::createLink('projectstory', 'story', "projectID=%s"); + } + elseif($module == 'story' and $method == 'zerocase') + { + $link = helper::createLink('project', 'testcase', "projectID=%s"); + } + elseif($module == 'testcase' and $method == 'create') + { + if($method == 'create') + { + $link = helper::createLink($module, $method); + } + elseif($method == 'edit') + { + $link = helper::createLink('project', 'testcase', "projectID=%s"); + } + } + elseif($module == 'testtask') + { + if($method == 'create') + { + $link = helper::createLink($module, $method, "product=0&executionID=0&build=0&projectID=%s"); + } + else + { + $link = helper::createLink($module, 'browseunits'); + } + } + elseif($module == 'testreport') + { + $link = helper::createLink('project', 'testreport', "projectID=%s"); + } + elseif($module == 'repo') + { + if($method == 'create') + { + $link = helper::createLink($module, $method, "objectID=%s#app=project"); + } + else + { + $link = helper::createLink($module, 'browse', "repoID=&branchID=&objectID=%s#app=project"); + } + } + elseif($module == 'doc') + { + $link = helper::createLink($module, 'tablecontents', "type=projectprojectID=%s#app=project"); + } + elseif($module == 'build') + { + if($method == 'create') + { + $link = helper::createLink($module, $method, "executionID=&productID=&projectID=%s#app=project"); + } + else + { + $link = helper::createLink('project', 'build', "projectID=%s"); + } + } + elseif($module == 'projectrelease') + { + if($method == 'create') + { + $link = helper::createLink($module, $method, "projectID=%s"); + } + else + { + $link = helper::createLink('projectrelease', 'browse', "projectID=%s"); + } + } + elseif($module == 'stakeholder') + { + if($method == 'create') + { + $link = helper::createLink($module, $method, "projectID=%s"); + } + else + { + $link = helper::createLink($module, 'browse', "projectID=%s"); + } + } + } + + if($project->model == 'kanban') $link = helper::createLink('project', 'index', "projectID=%s"); + + return $link; + } + /** * Get project stat data . * @@ -517,7 +700,7 @@ class projectModel extends model ->andWhere('deleted')->eq(0) ->andWhere('vision')->eq($this->config->vision) ->beginIF($programID !== '')->andWhere('parent')->eq($programID)->fi() - ->beginIF($status != 'all' && $status != 'noclosed')->andWhere('status')->eq($status)->fi() + ->beginIF($status != 'all' and $status != 'noclosed')->andWhere('status')->eq($status)->fi() ->beginIF($excludedModel)->andWhere('model')->ne($excludedModel)->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() @@ -981,7 +1164,7 @@ class projectModel extends model $this->updateProducts($projectID); - if(isset($_POST['newProduct']) || (!$project->parent && empty($linkedProductsCount))) + if(isset($_POST['newProduct']) or (!$project->parent and empty($linkedProductsCount))) { /* If parent not empty, link products or create products. */ $product = new stdclass(); @@ -1719,11 +1902,11 @@ class projectModel extends model if($project->model === 'scrum') $prefix = "{$this->lang->project->scrum} "; if($project->model === 'kanban') $prefix = "{$this->lang->project->kanban} "; if(isset($project->delay)) $suffix = "{$this->lang->project->statusList['delay']}"; - if(!empty($suffix) || !empty($prefix)) echo '
'; + if(!empty($suffix) or !empty($prefix)) echo '
'; if(!empty($prefix)) echo $prefix; echo html::a($projectLink, $project->name, '', "class='text-ellipsis text-primary'"); if(!empty($suffix)) echo $suffix; - if(!empty($suffix) || !empty($prefix)) echo '
'; + if(!empty($suffix) or !empty($prefix)) echo '
'; break; case 'code': echo $project->code; @@ -1764,11 +1947,11 @@ class projectModel extends model break; case 'actions': $moduleName = $this->config->systemMode == 'classic' ? "execution" : "project"; - if($project->status == 'wait' || $project->status == 'suspended') common::printIcon($moduleName, 'start', "projectID=$project->id", $project, 'list', 'play', '', 'iframe', true); + if($project->status == 'wait' or $project->status == 'suspended') common::printIcon($moduleName, 'start', "projectID=$project->id", $project, 'list', 'play', '', 'iframe', true); if($project->status == 'doing') common::printIcon($moduleName, 'close', "projectID=$project->id", $project, 'list', 'off', '', 'iframe', true); if($project->status == 'closed') common::printIcon($moduleName, 'activate', "projectID=$project->id", $project, 'list', 'magic', '', 'iframe', true); - if(common::hasPriv($moduleName, 'suspend') || (common::hasPriv($moduleName, 'close') && $project->status != 'doing') || (common::hasPriv($moduleName, 'activate') && $project->status != 'closed')) + if(common::hasPriv($moduleName, 'suspend') or (common::hasPriv($moduleName, 'close') and $project->status != 'doing') or (common::hasPriv($moduleName, 'activate') && $project->status != 'closed')) { echo "
"; echo ""; @@ -1793,7 +1976,7 @@ class projectModel extends model common::printIcon($moduleName, 'team', "projectID=$project->id", $project, 'list', 'group', '', '', '', $dataApp . $attr, $this->lang->execution->team); if($this->config->systemMode == 'new') common::printIcon('project', 'group', "projectID=$project->id&programID=$programID", $project, 'list', 'lock', '', '', '', $dataApp . $attr); - if(common::hasPriv($moduleName, 'manageProducts') || common::hasPriv($moduleName, 'whitelist') || common::hasPriv($moduleName, 'delete')) + if(common::hasPriv($moduleName, 'manageProducts') or common::hasPriv($moduleName, 'whitelist') or common::hasPriv($moduleName, 'delete')) { echo "
"; echo ""; @@ -2028,7 +2211,7 @@ class projectModel extends model ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id') ->where('t1.type')->in('sprint,stage,kanban') ->beginIF($projectID != 0)->andWhere('t1.project')->eq($projectID)->fi() - ->beginIF($projectID == 0 && $this->config->vision)->andWhere('t1.vision')->eq($this->config->vision)->fi() + ->beginIF($projectID == 0 and $this->config->vision)->andWhere('t1.vision')->eq($this->config->vision)->fi() ->beginIF(!empty($myExecutionIDList))->andWhere('t1.id')->in(array_keys($myExecutionIDList))->fi() ->beginIF($status == 'undone')->andWhere('t1.status')->notIN('done,closed')->fi() ->beginIF($status != 'all' and $status != 'undone' and $status != 'involved')->andWhere('t1.status')->eq($status)->fi() @@ -2298,14 +2481,14 @@ class projectModel extends model $lang->project->dividerMenu = $lang->{$model}->dividerMenu; } - $this->lang->switcherMenu = $this->getSwitcher($objectID, $this->app->rawModule, $this->app->rawMethod); - /* Reset project priv. */ $moduleName = $this->app->rawModule; $methodName = $this->app->rawMethod; - $this->loadModel('common')->resetProjectPriv($objectID); if(!$this->common->isOpenMethod($moduleName, $methodName) and !commonModel::hasPriv($moduleName, $methodName)) $this->common->deny($moduleName, $methodName, false); + + $this->lang->switcherMenu = $this->getSwitcher($objectID, $this->app->rawModule, $this->app->rawMethod); + common::setMenuVars('project', $objectID); } diff --git a/module/project/view/ajaxgetdropmenu.html.php b/module/project/view/ajaxgetdropmenu.html.php index 85a2b1bf4e..e1d549a031 100644 --- a/module/project/view/ajaxgetdropmenu.html.php +++ b/module/project/view/ajaxgetdropmenu.html.php @@ -30,6 +30,7 @@ $programProjects) foreach($programProjects as $index => $project) { - $selected = $project->id == $projectID ? 'selected' : ''; - $link = helper::createLink('project', 'index', "projectID=%s", '', '', $project->id); - $icon = ' '; + $selected = $project->id == $projectID ? 'selected' : ''; + $icon = ' '; + + if($project->model == 'waterfall' and $module == 'design') + { + $link = helper::createLink('design', 'browse', "projectID=%s"); + } + elseif($project->model == 'kanban') + { + $link = helper::createLink('project', 'index', "projectID=%s"); + } + else + { + $link = $defaultLink; + } + + /* Set link when project redefines permissions. */ + if($project->auth == 'reset') + { + $this->loadModel('common')->resetProjectPriv($project->id); + $link = helper::createLink('project', 'index', "projectID=%s"); + } if($project->model != 'scrum') $icon = " "; $projectName = $icon . $project->name; From ca2fc749cde295abe5f3e44afa55696a3efa3410 Mon Sep 17 00:00:00 2001 From: mayue Date: Wed, 11 May 2022 05:40:31 +0000 Subject: [PATCH 02/21] * Optimize code. --- module/project/model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/project/model.php b/module/project/model.php index 145776ad82..ef25e5e64b 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -465,7 +465,7 @@ class projectModel extends model * @param string $method * @param int $projectID * @access public - * @return void + * @return string */ public function getProjectLink($module, $method, $projectID) { From 98dcd7517ff8c98dfa9c5ed4378b4baa5cd73d3b Mon Sep 17 00:00:00 2001 From: mayue Date: Wed, 11 May 2022 06:38:46 +0000 Subject: [PATCH 03/21] * Optimize code. --- module/product/control.php | 2 +- module/product/model.php | 8 +++++--- module/project/model.php | 8 ++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/module/product/control.php b/module/product/control.php index 17e5520626..fc85c81ebf 100644 --- a/module/product/control.php +++ b/module/product/control.php @@ -301,7 +301,7 @@ class product extends control $actionURL = $this->createLink($rawModule, $rawMethod, $params . "productID=$productID&branch=$branch&browseType=bySearch&queryID=myQueryID&storyType=$storyType"); $this->config->product->search['onMenuBar'] = 'yes'; - $this->product->buildSearchForm($productID, $this->products, $queryID, $actionURL, $branch); + $this->product->buildSearchForm($productID, $this->products, $queryID, $actionURL, $branch, $projectID); $showModule = !empty($this->config->datatable->productBrowse->showModule) ? $this->config->datatable->productBrowse->showModule : ''; diff --git a/module/product/model.php b/module/product/model.php index aa01af3093..f8427994e5 100644 --- a/module/product/model.php +++ b/module/product/model.php @@ -975,13 +975,15 @@ class productModel extends model * @param int $queryID * @param int $actionURL * @param int $branch + * @param int $projectID * @access public * @return void */ - public function buildSearchForm($productID, $products, $queryID, $actionURL, $branch = 0) + public function buildSearchForm($productID, $products, $queryID, $actionURL, $branch = 0, $projectID = 0) { $productIdList = ($this->app->tab == 'project' and empty($productID)) ? array_keys($products) : $productID; $branchParam = ($this->app->tab == 'project' and empty($productID)) ? '' : $branch; + $projectID = ($this->app->tab == 'project' and empty($projectID)) ? $this->session->project : $projectID; $this->config->product->search['actionURL'] = $actionURL; $this->config->product->search['queryID'] = $queryID; @@ -997,7 +999,7 @@ class productModel extends model if($productID) { $modules = array(); - $branchList = $this->loadModel('branch')->getPairs($productID, '', $this->session->project); + $branchList = $this->loadModel('branch')->getPairs($productID, '', $projectID); $branchModuleList = $this->tree->getOptionMenu($productID, 'story', 0, array_keys($branchList)); foreach($branchModuleList as $branchID => $branchModules) $modules[] = $branchModules; } @@ -1005,7 +1007,7 @@ class productModel extends model { $moduleList = array(); $modules = array('/'); - $branchGroup = $this->loadModel('execution')->getBranchByProduct(array_keys($products), $this->session->project, ''); + $branchGroup = $this->loadModel('execution')->getBranchByProduct(array_keys($products), $projectID, ''); foreach($products as $productID => $productName) { if(isset($branchGroup[$productID])) diff --git a/module/project/model.php b/module/project/model.php index ef25e5e64b..0a4b6d9110 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -532,6 +532,14 @@ class projectModel extends model { $link = helper::createLink($module, 'group', "projectID=%s"); } + elseif($module == 'product' and $method == 'showerrornone') + { + $link = helper::createLink('projectstory', 'story', "projectID=%s"); + } + elseif($module == 'projectstory' and $method == 'story') + { + $link = helper::createLink($module, $method, "projectID=%s"); + } elseif($module == 'projectstory' and $method == 'linkstory') { $link = helper::createLink($module, $method, "projectID=%s"); From bbb5ec189d03ae1f5cdf9f2ecce0a335e2699546 Mon Sep 17 00:00:00 2001 From: mayue Date: Wed, 11 May 2022 07:57:36 +0000 Subject: [PATCH 04/21] * Optimize code. --- module/project/model.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/project/model.php b/module/project/model.php index 0a4b6d9110..3a4b42f608 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -472,7 +472,7 @@ class projectModel extends model $link = helper::createLink('project', 'index', "projectID=%s"); $project = $this->getByID($projectID); - if(strpos(',project,product,projectstory,story,bug,testcase,testtask,testreport,build,projectrelease,stakeholder,', ',' . $module . ',') !== false) + if(strpos(',project,product,projectstory,story,bug,doc,testcase,testtask,testreport,build,projectrelease,stakeholder,', ',' . $module . ',') !== false) { if($module == 'project' and $method == 'execution') { @@ -606,7 +606,7 @@ class projectModel extends model } elseif($module == 'doc') { - $link = helper::createLink($module, 'tablecontents', "type=projectprojectID=%s#app=project"); + $link = helper::createLink($module, 'tablecontents', "type=project&objectID=%s#app=project"); } elseif($module == 'build') { From ce7c0afdc112b9be7c6c1d171872f11072db1def Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Wed, 11 May 2022 18:24:13 +0800 Subject: [PATCH 05/21] * Finish task#53666. --- lib/date/date.class.php | 76 ++++++++++++++--------------- module/execution/control.php | 7 +-- module/execution/css/burn.css | 1 + module/execution/js/burn.js | 12 +++++ module/execution/lang/en.php | 3 ++ module/execution/lang/zh-cn.php | 3 ++ module/execution/model.php | 16 ++++-- module/execution/view/burn.html.php | 23 ++++++++- 8 files changed, 94 insertions(+), 47 deletions(-) diff --git a/lib/date/date.class.php b/lib/date/date.class.php index efdc37eb02..5737e68cb2 100644 --- a/lib/date/date.class.php +++ b/lib/date/date.class.php @@ -9,14 +9,14 @@ * @version $Id: date.class.php 2605 2013-01-09 07:22:58Z wwccss $ * @link http://www.zentao.net */ -class date +class date { /** * Build hour time list. - * - * @param int $begin - * @param int $end - * @param int $delta + * + * @param int $begin + * @param int $end + * @param int $delta * @access public * @return array */ @@ -37,7 +37,7 @@ class date /** * Get today. - * + * * @access public * @return date */ @@ -47,8 +47,8 @@ class date } /** - * Get yesterday - * + * Get yesterday + * * @access public * @return date */ @@ -59,7 +59,7 @@ class date /** * Get tomorrow. - * + * * @access public * @return date */ @@ -70,7 +70,7 @@ class date /** * Get the day before yesterday. - * + * * @access public * @return date */ @@ -81,8 +81,8 @@ class date /** * Get now time period. - * - * @param int $delta + * + * @param int $delta * @access public * @return string the current time period, like 0915 */ @@ -114,8 +114,8 @@ class date /** * Format time 0915 to 09:15 - * - * @param string $time + * + * @param string $time * @access public * @return string */ @@ -127,7 +127,7 @@ class date /** * Get the begin and end date of this week. - * + * * @access public * @return array */ @@ -141,7 +141,7 @@ class date /** * Get the begin and end date of last week. - * + * * @access public * @return array */ @@ -155,7 +155,7 @@ class date /** * Get the time at the middle of this week. - * + * * If today in week is 1, move it one day in future. Else is 7, move it back one day. To keep the time geted in this week. * * @access public @@ -172,7 +172,7 @@ class date /** * Get middle of last week. - * + * * @access public * @return time */ @@ -188,7 +188,7 @@ class date /** * Get begin and end time of this month. - * + * * @access public * @return array */ @@ -201,7 +201,7 @@ class date /** * Get begin and end time of last month. - * + * * @access public * @return array */ @@ -213,11 +213,11 @@ class date } /** - * Get begin and end time of this season. - * + * Get begin and end time of this season. + * * @static * @access public - * @return array + * @return array */ public static function getThisSeason() { @@ -230,11 +230,11 @@ class date } /** - * Get begin and end time of last season. - * + * Get begin and end time of last season. + * * @static * @access public - * @return array + * @return array */ public static function getLastSeason() { @@ -242,43 +242,43 @@ class date $begin = date('Y-m-d H:i:s', mktime(0, 0, 0, $season * 3 - 2, 1, date('Y'))); $endDay = date('t', mktime(0, 0 , 0, $season * 3, 1, date("Y"))); // Get end day. $end = date('Y-m-d H:i:s', mktime(23, 59, 59, $season * 3, $endDay, date('Y'))); - + return array('begin' => $begin, 'end' => $end); } /** * Get begin and end time of this year. - * + * * @static * @access public - * @return array + * @return array */ public static function getThisYear() { $begin = date(DT_DATE1, strtotime('1/1 this year')) . ' 00:00:00'; - $end = date(DT_DATE1, strtotime('1/1 next year -1 day')) . ' 23:59:59'; + $end = date(DT_DATE1, strtotime('1/1 next year -1 day')) . ' 23:59:59'; return array('begin' => $begin, 'end' => $end); } /** * Get begin and end time of last year. - * + * * @static * @access public - * @return array + * @return array */ public static function getLastYear() { $begin = date(DT_DATE1, strtotime('1/1 last year')) . ' 00:00:00'; - $end = date(DT_DATE1, strtotime('1/1 this year -1 day')) . ' 23:59:59'; + $end = date(DT_DATE1, strtotime('1/1 this year -1 day')) . ' 23:59:59'; return array('begin' => $begin, 'end' => $end); } /** - * Get date list - * - * @param string $begin - * @param string $end + * Get date list + * + * @param string $begin + * @param string $end * @param string $format m/d/Y|Y-m-d * @param string $type noweekend|withweekend * @param int $weekend 2|1 @@ -295,7 +295,7 @@ class date for($date = $begin; $date <= $end; $date += 24 * 3600) { $weekDay = date('w', $date); - if($type == 'noweekend' and (($weekend == 2 and $weekDay == 6) or $weekDay == 0)) continue; + if(strpos($type, 'noweekend') !== false and (($weekend == 2 and $weekDay == 6) or $weekDay == 0)) continue; $dateList[] = date($format, $date); } diff --git a/module/execution/control.php b/module/execution/control.php index be01e4169e..8ed62988e5 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -1149,12 +1149,12 @@ class execution extends control * @access public * @return void */ - public function burn($executionID = 0, $type = 'noweekend', $interval = 0, $burnBy = 'left') + public function burn($executionID = 0, $type = 'noweekend,nodelay', $interval = 0, $burnBy = 'left') { $this->loadModel('report'); $execution = $this->commonAction($executionID); $executionID = $execution->id; - $burnBy = $this->cookie->burnBy ? $this->cookie->burnBy : $burnBy; + $burnBy = $this->cookie->burnBy ? $this->cookie->burnBy : $burnBy; /* Header and position. */ $title = $execution->name . $this->lang->colon . $this->lang->execution->burn; @@ -1163,7 +1163,8 @@ class execution extends control /* Get date list. */ $executionInfo = $this->execution->getByID($executionID); - list($dateList, $interval) = $this->execution->getDateList($executionInfo->begin, $executionInfo->end, $type, $interval, 'Y-m-d'); + $endDate = strpos($type, 'withdelay') !== false ? helper::today() : $executionInfo->end; + list($dateList, $interval) = $this->execution->getDateList($executionInfo->begin, $endDate, $type, $interval, 'Y-m-d'); $chartData = $this->execution->buildBurnData($executionID, $dateList, $type, $burnBy); $dayList = array_fill(1, floor((int)$execution->days / $this->config->execution->maxBurnDay) + 5, ''); diff --git a/module/execution/css/burn.css b/module/execution/css/burn.css index b954f140ad..71e7d4b506 100644 --- a/module/execution/css/burn.css +++ b/module/execution/css/burn.css @@ -6,5 +6,6 @@ #burnLegend > div {position: relative; padding-left: 30px;} #burnLegend > div > .barline {position: absolute; width: 20px; left: 0; top: 13px; height: 3px; background: #EEEEEE;} #burnLegend .line-real .bg-primary {background: #1183fb;} +#burnLegend .line-real .bg-delay {background: red;} .pull-left .input-control {margin-right: 10px;} diff --git a/module/execution/js/burn.js b/module/execution/js/burn.js index 85e78025cf..192151808a 100644 --- a/module/execution/js/burn.js +++ b/module/execution/js/burn.js @@ -5,6 +5,18 @@ $(function() { location.href = createLink('execution', 'burn', 'executionID=' + executionID + '&type=' + type + '&interval=' + $(this).val()); }); + + $('#weekend').click(function() + { + var browseType = type.match('noweekend') ? type.replace('noweekend', 'withweekend') : type.replace('withweekend', 'noweekend'); + location.href = createLink('execution', 'burn', 'executionID=' + executionID + '&type=' + browseType + '&interval=' + interval); + }); + + $('#delay').click(function() + { + var browseType = type.match('nodelay') ? type.replace('nodelay', 'withdelay') : type.replace('withdelay', 'nodelay'); + location.href = createLink('execution', 'burn', 'executionID=' + executionID + '&type=' + browseType + '&interval=' + interval); + }); }) /* Save burn as image.*/ diff --git a/module/execution/lang/en.php b/module/execution/lang/en.php index c9aa6aa2f0..5cff2f8144 100644 --- a/module/execution/lang/en.php +++ b/module/execution/lang/en.php @@ -359,7 +359,9 @@ $lang->execution->linkStory = 'Link Story'; $lang->execution->createTask = 'Create Task'; $lang->execution->goback = "Go Back"; $lang->execution->noweekend = 'Exclude Weekend'; +$lang->execution->nowdelay = 'Exclude Delay Date'; $lang->execution->withweekend = 'Include Weekend'; +$lang->execution->withdelay = 'Include Delay Date'; $lang->execution->interval = 'Intervals '; $lang->execution->fixFirstWithLeft = 'Update hours left too'; $lang->execution->unfinishedExecution = "This {$lang->executionCommon} has "; @@ -384,6 +386,7 @@ $lang->execution->charts->burn->graph->rotateNames = 1; $lang->execution->charts->burn->graph->showValues = 0; $lang->execution->charts->burn->graph->reference = 'Ideal'; $lang->execution->charts->burn->graph->actuality = 'Actual'; +$lang->execution->charts->burn->graph->delay = 'Delay'; $lang->execution->placeholder = new stdclass(); $lang->execution->placeholder->code = "Abbreviation of {$lang->executionCommon} name"; diff --git a/module/execution/lang/zh-cn.php b/module/execution/lang/zh-cn.php index 9248f804cb..377421ee64 100644 --- a/module/execution/lang/zh-cn.php +++ b/module/execution/lang/zh-cn.php @@ -359,7 +359,9 @@ $lang->execution->linkStory = "关联{$lang->SRCommon}"; $lang->execution->createTask = '创建任务'; $lang->execution->goback = "返回任务列表"; $lang->execution->noweekend = '去除周末'; +$lang->execution->nodelay = '去除延期日期'; $lang->execution->withweekend = '显示周末'; +$lang->execution->withdelay = '显示延期日期'; $lang->execution->interval = '间隔'; $lang->execution->fixFirstWithLeft = '修改剩余工时'; $lang->execution->unfinishedExecution = "该{$lang->executionCommon}下还有"; @@ -384,6 +386,7 @@ $lang->execution->charts->burn->graph->rotateNames = 1; $lang->execution->charts->burn->graph->showValues = 0; $lang->execution->charts->burn->graph->reference = '参考'; $lang->execution->charts->burn->graph->actuality = '实际'; +$lang->execution->charts->burn->graph->delay = '延期'; $lang->execution->placeholder = new stdclass(); $lang->execution->placeholder->code = '团队内部的简称'; diff --git a/module/execution/model.php b/module/execution/model.php index b3180f1394..9bfb2c0046 100644 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -2792,8 +2792,7 @@ class executionModel extends model { $today = helper::today(); $executions = $this->dao->select('id, code')->from(TABLE_EXECUTION) - ->where('end')->ge($today) - ->andWhere('type')->in('sprint,stage') + ->where('type')->in('sprint,stage') ->andWhere('lifetime')->ne('ops') ->andWhere('status')->notin('done,closed,suspended') ->fetchPairs(); @@ -2943,10 +2942,11 @@ class executionModel extends model * * @param int $executionID * @param string $burnBy + * @param bool $showDelay * @access public * @return array */ - public function getBurnDataFlot($executionID = 0, $burnBy = '') + public function getBurnDataFlot($executionID = 0, $burnBy = '', $showDelay = false) { /* Get execution and burn counts. */ $execution = $this->getById($executionID); @@ -2959,7 +2959,8 @@ class executionModel extends model foreach($sets as $date => $set) { if($date < $execution->begin) continue; - if($date > $execution->end) continue; + if(!$showDelay and $date > $execution->end) $set->value = 'null'; + if($showDelay and $date < $execution->end) $set->value = 'null'; $burnData[$date] = $set; $count++; @@ -3648,6 +3649,13 @@ class executionModel extends model $chartData['burnLine'] = $this->report->createSingleJSON($sets, $dateList); $chartData['baseLine'] = $baselineJSON; + $execution = $this->getById($executionID); + if($execution->status != 'closed' and helper::today() > $execution->end) + { + $delaySets = $this->getBurnDataFlot($executionID, $burnBy, true); + $chartData['delayLine'] = $this->report->createSingleJSON($delaySets, $dateList); + } + return $chartData; } diff --git a/module/execution/view/burn.html.php b/module/execution/view/burn.html.php index 2d0bd26ae7..fd640bf56b 100644 --- a/module/execution/view/burn.html.php +++ b/module/execution/view/burn.html.php @@ -18,13 +18,16 @@ execution->burnXUnit);?> execution->burnYUnit);?> + @@ -94,6 +100,19 @@ function initBurnChar() }] }; + var delaySets = + { + label: "execution->charts->burn->graph->delay;?>", + color: 'red', + pointStrokeColor: 'red', + pointHighlightStroke: 'red', + pointColor: 'red', + fillColor: 'rgba(0,106,241, .07)', + pointHighlightFill: '#fff', + data: + } + if(type.match('withdelay')) data.datasets.push(delaySets); + var burnChart = $("#burnCanvas").lineChart(data, { pointDotStrokeWidth: 2, From 691de86d4a9ef1058d377f38917df9d2607444c4 Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Thu, 12 May 2022 08:15:25 +0800 Subject: [PATCH 06/21] * Code for task#53661. --- module/execution/control.php | 4 +++- module/execution/model.php | 8 +++++--- module/execution/view/burn.html.php | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/module/execution/control.php b/module/execution/control.php index 8ed62988e5..78e3ee06cc 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -1163,7 +1163,8 @@ class execution extends control /* Get date list. */ $executionInfo = $this->execution->getByID($executionID); - $endDate = strpos($type, 'withdelay') !== false ? helper::today() : $executionInfo->end; + $deadline = $execution->status != 'closed' ? helper::today() : substr($execution->closedDate, 0, 10); + $endDate = strpos($type, 'withdelay') !== false ? $deadline : $executionInfo->end; list($dateList, $interval) = $this->execution->getDateList($executionInfo->begin, $endDate, $type, $interval, 'Y-m-d'); $chartData = $this->execution->buildBurnData($executionID, $dateList, $type, $burnBy); @@ -1928,6 +1929,7 @@ class execution extends control if(!empty($_POST)) { $this->loadModel('action'); + $this->execution->computeBurn($executionID); $changes = $this->execution->close($executionID); if(dao::isError()) return print(js::error(dao::getError())); diff --git a/module/execution/model.php b/module/execution/model.php index 9bfb2c0046..7b40302a85 100644 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -2785,16 +2785,18 @@ class executionModel extends model /** * Compute burn of a execution. * + * @param int $executionID * @access public - * @return array + * @return void */ - public function computeBurn() + public function computeBurn($executionID = 0) { $today = helper::today(); $executions = $this->dao->select('id, code')->from(TABLE_EXECUTION) ->where('type')->in('sprint,stage') ->andWhere('lifetime')->ne('ops') ->andWhere('status')->notin('done,closed,suspended') + ->beginIF($executionID)->andWhere('id')->eq($executionID)->fi() ->fetchPairs(); if(!$executions) return array(); @@ -3650,7 +3652,7 @@ class executionModel extends model $chartData['baseLine'] = $baselineJSON; $execution = $this->getById($executionID); - if($execution->status != 'closed' and helper::today() > $execution->end) + if(($execution->status != 'closed' and helper::today() > $execution->end) or ($execution->status == 'closed' and substr($execution->closedDate, 0, 10) > $execution->end)) { $delaySets = $this->getBurnDataFlot($executionID, $burnBy, true); $chartData['delayLine'] = $this->report->createSingleJSON($delaySets, $dateList); diff --git a/module/execution/view/burn.html.php b/module/execution/view/burn.html.php index fd640bf56b..6374ef4835 100644 --- a/module/execution/view/burn.html.php +++ b/module/execution/view/burn.html.php @@ -27,7 +27,7 @@ common::printLink('execution', 'computeBurn', 'reload=yes', ' ' . $lang->execution->computeBurn, 'hiddenwin', "title='{$lang->execution->computeBurn}' class='btn btn-primary' id='computeBurn'"); echo '
'; echo html::a('#', $lang->execution->$weekend, '', "class='btn btn-link' id='weekend'"); - if($execution->status != 'closed' and helper::today() > $execution->end) echo html::a('#', $lang->execution->$delay, '', "class='btn btn-link' id='delay'"); + if(($execution->status != 'closed' and helper::today() > $execution->end) or ($execution->status == 'closed' and substr($execution->closedDate, 0, 10) > $execution->end)) echo html::a('#', $lang->execution->$delay, '', "class='btn btn-link' id='delay'"); if(common::canModify('execution', $execution)) common::printLink('execution', 'fixFirst', "execution=$execution->id", $lang->execution->fixFirst, '', "class='btn btn-link iframe' data-width='700'"); echo $lang->execution->howToUpdateBurn; ?> @@ -109,7 +109,7 @@ function initBurnChar() pointColor: 'red', fillColor: 'rgba(0,106,241, .07)', pointHighlightFill: '#fff', - data: + data: } if(type.match('withdelay')) data.datasets.push(delaySets); From 1cab87893e38e9559ee4720a6c82db04d2541375 Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Thu, 12 May 2022 09:19:49 +0800 Subject: [PATCH 07/21] * Finish task#53661. --- module/execution/control.php | 1 + module/execution/model.php | 2 ++ 2 files changed, 3 insertions(+) diff --git a/module/execution/control.php b/module/execution/control.php index 78e3ee06cc..060128b0f2 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -1834,6 +1834,7 @@ class execution extends control if(!empty($_POST)) { $this->loadModel('action'); + $this->execution->computeBurn($executionID); $changes = $this->execution->suspend($executionID); if(dao::isError()) return print(js::error(dao::getError())); diff --git a/module/execution/model.php b/module/execution/model.php index 7b40302a85..37e7304e64 100644 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -481,6 +481,8 @@ class executionModel extends model ->remove('products, branch, uid, plans, syncStories, contactListMenu, teamMembers') ->get(); + if(in_array($execution->status, array('closed', 'suspended'))) $this->computeBurn($executionID); + if($this->config->systemMode == 'new' and (empty($execution->project) or $execution->project == $oldExecution->project)) $this->checkBeginAndEndDate($oldExecution->project, $execution->begin, $execution->end); if(dao::isError()) return false; From ffa1ec828df11d7ca2987217f043dd6644ababfa Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Thu, 12 May 2022 10:38:22 +0800 Subject: [PATCH 08/21] * Code for task#53661. --- module/execution/control.php | 2 +- module/execution/model.php | 5 ++++- module/execution/view/burn.html.php | 13 ++++++++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/module/execution/control.php b/module/execution/control.php index 060128b0f2..44c81b6cd1 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -1163,7 +1163,7 @@ class execution extends control /* Get date list. */ $executionInfo = $this->execution->getByID($executionID); - $deadline = $execution->status != 'closed' ? helper::today() : substr($execution->closedDate, 0, 10); + $deadline = strpos('closed,suspended', $execution->status) === false ? helper::today() : ($execution->status == 'closed' ? substr($execution->closedDate, 0, 10) : $execution->suspendedDate); $endDate = strpos($type, 'withdelay') !== false ? $deadline : $executionInfo->end; list($dateList, $interval) = $this->execution->getDateList($executionInfo->begin, $endDate, $type, $interval, 'Y-m-d'); $chartData = $this->execution->buildBurnData($executionID, $dateList, $type, $burnBy); diff --git a/module/execution/model.php b/module/execution/model.php index 37e7304e64..25be47604a 100644 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -827,6 +827,7 @@ class executionModel extends model ->setDefault('status', 'suspended') ->setDefault('lastEditedBy', $this->app->user->account) ->setDefault('lastEditedDate', $now) + ->setDefault('suspendedDate', helper::today()) ->remove('comment')->get(); $this->dao->update(TABLE_EXECUTION)->data($execution) @@ -3654,7 +3655,9 @@ class executionModel extends model $chartData['baseLine'] = $baselineJSON; $execution = $this->getById($executionID); - if(($execution->status != 'closed' and helper::today() > $execution->end) or ($execution->status == 'closed' and substr($execution->closedDate, 0, 10) > $execution->end)) + if((strpos('closed,suspended', $execution->status) === false and helper::today() > $execution->end) + or ($execution->status == 'closed' and substr($execution->closedDate, 0, 10) > $execution->end) + or ($execution->status == 'suspended' and $execution->suspendedDate > $execution->end)) { $delaySets = $this->getBurnDataFlot($executionID, $burnBy, true); $chartData['delayLine'] = $this->report->createSingleJSON($delaySets, $dateList); diff --git a/module/execution/view/burn.html.php b/module/execution/view/burn.html.php index 6374ef4835..b1f9af0f86 100644 --- a/module/execution/view/burn.html.php +++ b/module/execution/view/burn.html.php @@ -24,10 +24,17 @@ ' . $lang->execution->computeBurn, 'hiddenwin', "title='{$lang->execution->computeBurn}' class='btn btn-primary' id='computeBurn'"); - echo '
'; + if(strpos('closed,suspended', $execution->status) === false) + { + common::printLink('execution', 'computeBurn', 'reload=yes', ' ' . $lang->execution->computeBurn, 'hiddenwin', "title='{$lang->execution->computeBurn}' class='btn btn-primary' id='computeBurn'"); + echo '
'; + } echo html::a('#', $lang->execution->$weekend, '', "class='btn btn-link' id='weekend'"); - if(($execution->status != 'closed' and helper::today() > $execution->end) or ($execution->status == 'closed' and substr($execution->closedDate, 0, 10) > $execution->end)) echo html::a('#', $lang->execution->$delay, '', "class='btn btn-link' id='delay'"); + if((strpos('closed,suspended', $execution->status) === false and helper::today() > $execution->end) + or ($execution->status == 'closed' and substr($execution->closedDate, 0, 10) > $execution->end) + or ($execution->status == 'suspended' and $execution->suspendedDate > $execution->end)) + echo html::a('#', $lang->execution->$delay, '', "class='btn btn-link' id='delay'"); + if(common::canModify('execution', $execution)) common::printLink('execution', 'fixFirst', "execution=$execution->id", $lang->execution->fixFirst, '', "class='btn btn-link iframe' data-width='700'"); echo $lang->execution->howToUpdateBurn; ?> From dab8c1bb1ea8917ee4164b821bcd5410d092c9d6 Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Thu, 12 May 2022 10:55:50 +0800 Subject: [PATCH 09/21] * Modify review code. --- module/execution/control.php | 3 ++- module/execution/view/burn.html.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/module/execution/control.php b/module/execution/control.php index 44c81b6cd1..3c03258f1d 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -1163,7 +1163,8 @@ class execution extends control /* Get date list. */ $executionInfo = $this->execution->getByID($executionID); - $deadline = strpos('closed,suspended', $execution->status) === false ? helper::today() : ($execution->status == 'closed' ? substr($execution->closedDate, 0, 10) : $execution->suspendedDate); + $deadline = $execution->status == 'closed' ? substr($execution->closedDate, 0, 10) : $execution->suspendedDate; + $deadline = strpos('closed,suspended', $execution->status) === false ? helper::today() : $deadline; $endDate = strpos($type, 'withdelay') !== false ? $deadline : $executionInfo->end; list($dateList, $interval) = $this->execution->getDateList($executionInfo->begin, $endDate, $type, $interval, 'Y-m-d'); $chartData = $this->execution->buildBurnData($executionID, $dateList, $type, $burnBy); diff --git a/module/execution/view/burn.html.php b/module/execution/view/burn.html.php index b1f9af0f86..d84e0a834b 100644 --- a/module/execution/view/burn.html.php +++ b/module/execution/view/burn.html.php @@ -24,7 +24,7 @@ status) === false) + if(strpos('wait,doing', $execution->status) !== false) { common::printLink('execution', 'computeBurn', 'reload=yes', ' ' . $lang->execution->computeBurn, 'hiddenwin', "title='{$lang->execution->computeBurn}' class='btn btn-primary' id='computeBurn'"); echo '
'; From 612a2b656efc3486cf5369d24c50b3e2a96475c7 Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Thu, 12 May 2022 00:18:05 +0800 Subject: [PATCH 10/21] * Adjust code style. --- module/execution/model.php | 2 +- module/execution/view/burn.html.php | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/module/execution/model.php b/module/execution/model.php index 25be47604a..e886b3c703 100644 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -2790,7 +2790,7 @@ class executionModel extends model * * @param int $executionID * @access public - * @return void + * @return array */ public function computeBurn($executionID = 0) { diff --git a/module/execution/view/burn.html.php b/module/execution/view/burn.html.php index d84e0a834b..81ea61c552 100644 --- a/module/execution/view/burn.html.php +++ b/module/execution/view/burn.html.php @@ -22,13 +22,14 @@