From cd8247954caa6105aeb9b1899d0667e0c8cbcfde Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Wed, 27 Jul 2022 13:31:48 +0800 Subject: [PATCH 01/13] * Fix bug#25004. --- module/product/model.php | 5 ++-- module/program/model.php | 5 ++-- module/project/model.php | 41 +++++++++++++++++++++++++++++++ module/project/view/view.html.php | 2 +- 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/module/product/model.php b/module/product/model.php index 2f8350ac1d..083154e73f 100644 --- a/module/product/model.php +++ b/module/product/model.php @@ -1271,13 +1271,14 @@ class productModel extends model } /* Compute totalReal and progress. */ - foreach($hours as $hour) + $this->loadModel('project'); + foreach($hours as $projectID => $hour) { $hour->totalEstimate = round($hour->totalEstimate, 1) ; $hour->totalConsumed = round($hour->totalConsumed, 1); $hour->totalLeft = round($hour->totalLeft, 1); $hour->totalReal = $hour->totalConsumed + $hour->totalLeft; - $hour->progress = $hour->totalReal ? round($hour->totalConsumed / $hour->totalReal, 2) * 100 : 0; + $hour->progress = $projects[$projectID]->model == 'waterfall' ? $this->project->getWaterfallProgress($projectID) : ($hour->totalReal ? round($hour->totalConsumed / $hour->totalReal, 2) * 100 : 0); } /* Get the number of project teams. */ diff --git a/module/program/model.php b/module/program/model.php index 47b702d040..a9f376915e 100644 --- a/module/program/model.php +++ b/module/program/model.php @@ -1434,13 +1434,14 @@ class programModel extends model } /* Compute totalReal and progress. */ - foreach($hours as $hour) + $this->loadModel('project'); + foreach($hours as $projectID => $hour) { $hour->totalEstimate = round($hour->totalEstimate, 1) ; $hour->totalConsumed = round($hour->totalConsumed, 1); $hour->totalLeft = round($hour->totalLeft, 1); $hour->totalReal = $hour->totalConsumed + $hour->totalLeft; - $hour->progress = $hour->totalReal ? round($hour->totalConsumed / $hour->totalReal, 2) * 100 : 0; + $hour->progress = $projects[$projectID]->model == 'waterfall' ? $this->project->getWaterfallProgress($projectID) : ($hour->totalReal ? round($hour->totalConsumed / $hour->totalReal, 2) * 100 : 0); } /* Get the number of left tasks. */ diff --git a/module/project/model.php b/module/project/model.php index 3e815f6808..9b52db5478 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -393,6 +393,47 @@ class projectModel extends model ->fetchAll('project'); } + /** + * Get waterfall project progress. + * + * @param int $projectID + * @access public + * @return int + */ + public function getWaterfallProgress($projectID) + { + $executions = $this->loadModel('execution')->getByProject($projectID); + + $totalHour = $this->dao->select('execution, ROUND(SUM(`left`), 2) AS totalLeft, ROUND(SUM(consumed), 1) AS totalConsumed')->from(TABLE_TASK) + ->where('execution')->in(array_keys($executions)) + ->andWhere('deleted')->eq(0) + ->andWhere('parent')->lt(1) + ->groupBy('execution') + ->fetchAll('execution'); + + $closedTotalLeft = $this->dao->select('execution, ROUND(SUM(`left`), 2) AS totalLeft')->from(TABLE_TASK) + ->where('execution')->in(array_keys($executions)) + ->andWhere('deleted')->eq(0) + ->andWhere('parent')->lt(1) + ->andWhere('status')->in('closed,cancel') + ->groupBy('execution') + ->fetchPairs('execution'); + + $progress = 0; + foreach($executions as $executionID => $execution) + { + $executionClosedLeft = isset($closedTotalLeft[$executionID]) ? $closedTotalLeft[$executionID] : 0; + $executionTotalConsumed = isset($totalHour[$executionID]) ? $totalHour[$executionID]->totalConsumed : 0; + $executionTotalLeft = isset($totalHour[$executionID]) ? round($totalHour[$executionID]->totalLeft - $executionClosedLeft, 1) : 0; + + $executionProgress = ($executionTotalConsumed + $executionTotalLeft) ? floor($executionTotalConsumed / ($executionTotalConsumed + $executionTotalLeft) * 1000) / 1000 * 100 : 0; + + $progress += $executionProgress * ($execution->percent / 100); + } + + return $progress; + } + /** * Get project workhour info. * diff --git a/module/project/view/view.html.php b/module/project/view/view.html.php index 28b98330fa..2ae7484bee 100644 --- a/module/project/view/view.html.php +++ b/module/project/view/view.html.php @@ -195,7 +195,7 @@ - totalConsumed + $workhour->totalLeft) ? floor($workhour->totalConsumed / ($workhour->totalConsumed + $workhour->totalLeft) * 1000) / 1000 * 100 : 0;?> + model == 'waterfall' ? $this->project->getWaterfallProgress($project->id) : (($workhour->totalConsumed + $workhour->totalLeft) ? floor($workhour->totalConsumed / ($workhour->totalConsumed + $workhour->totalLeft) * 1000) / 1000 * 100 : 0);?> project->progress;?> percent;?>  
From b13e504ec45ba8e69904afb2d195ea07e969b8a7 Mon Sep 17 00:00:00 2001 From: Hao Sun Date: Wed, 27 Jul 2022 08:58:40 +0000 Subject: [PATCH 02/13] * fix open tab with same url occurs blank page. --- module/index/js/index.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/module/index/js/index.js b/module/index/js/index.js index d8dfe59d94..2c8f76f6d9 100644 --- a/module/index/js/index.js +++ b/module/index/js/index.js @@ -187,7 +187,7 @@ * @param {string} [appCode] The code of target app to open * @return {void} */ - function openTab(url, appCode) + function openTab(url, appCode, forceReload) { /* Check params */ if(!appCode) @@ -264,7 +264,9 @@ } /* Show page app and update iframe source */ - if (url) + var iframe = app.$iframe[0]; + var isSameUrl = iframe && url && iframe.contentWindow.location.href.endsWith(url); + if (url && (!isSameUrl || forceReload)) { app.$app.toggleClass('open-from-hidden', app.$app.is(':hidden')) reloadApp(appCode, url, true); @@ -441,7 +443,8 @@ if(url === true) url = app.url; else if($.tabSession) url = $.tabSession.convertUrlWithTid(url); - var iframe = app.$iframe[0]; + var iframe = app.$iframe[0]; + var isSameUrl = iframe && url && iframe.contentWindow.location.href.endsWith(url); /* Add hook to page before reload it */ if (iframe && iframe.contentWindow.beforeAppReload) @@ -451,7 +454,7 @@ try { - if(url) iframe.contentWindow.location.assign(url); + if(url && !isSameUrl) iframe.contentWindow.location.assign(url); else iframe.contentWindow.location.reload(true); } catch(_) @@ -462,7 +465,7 @@ if(!notTriggerEvent) app.$app.trigger('reloadapp', app); if(url) $(iframe.contentWindow.document.body).hide(); // Code for task #59703. - app.$app.addClass('loading'); + if(!isSameUrl) app.$app.addClass('loading'); if(app._loadTimer) clearTimeout(app._loadTimer); app._loadTimer = setTimeout(function() { From 45ace8beb58c912fcb3d98a757ba404750aad3fa Mon Sep 17 00:00:00 2001 From: zhouxudong Date: Wed, 27 Jul 2022 09:11:56 +0000 Subject: [PATCH 03/13] * Fix bug #25103. --- module/branch/css/manage.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/branch/css/manage.css b/module/branch/css/manage.css index 7cea3742c9..b5f2deac74 100644 --- a/module/branch/css/manage.css +++ b/module/branch/css/manage.css @@ -10,5 +10,5 @@ td.branchName > span {vertical-align: middle;} #mergeBranch .form-actions {padding-top: 20px;} .modal-body {padding-top: 0;} .tips {background-color: #ffffff; max-width: 650px; display: flex; padding: 14px;} -.icon-exclamation-sign.icon {align-self: center; color: #2667E3; font-size: 24px;} +.icon-exclamation-sign.icon {align-self: center; color: #2667E3; font-size: 24px; opacity: 1;} #marginTips {max-width: 585px; margin-left: 10px;} From a9f10fe868f903ffc063af0ce86a0cc5dd9bc0ca Mon Sep 17 00:00:00 2001 From: hufangzhou Date: Wed, 27 Jul 2022 17:40:31 +0800 Subject: [PATCH 04/13] * Remove the unsed code. --- module/doc/js/selectlibtype.js | 1 - 1 file changed, 1 deletion(-) diff --git a/module/doc/js/selectlibtype.js b/module/doc/js/selectlibtype.js index 79f8803cba..02393b4e56 100644 --- a/module/doc/js/selectlibtype.js +++ b/module/doc/js/selectlibtype.js @@ -18,7 +18,6 @@ function redirectParentWindow(objectType, libID, docType) { var link = createLink('doc', 'create', 'objectType=' + objectType + '&objectID=0&libID=' + libID + '&moduleID=0&docType=' + docType + '&fromGlobal=true') + '#app=doc'; } - window.parent.$.apps.close('doc'); window.parent.$.apps.open(link); } From 0ec68feb10f5877634e169266f10bd7061b38da2 Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Wed, 27 Jul 2022 21:38:28 +0800 Subject: [PATCH 05/13] * Fix bug#25004. --- module/product/model.php | 4 +- module/product/view/project.html.php | 4 +- module/program/model.php | 4 +- module/project/model.php | 56 +++++++++++++++------------- 4 files changed, 37 insertions(+), 31 deletions(-) diff --git a/module/product/model.php b/module/product/model.php index 083154e73f..43e1d0f115 100644 --- a/module/product/model.php +++ b/module/product/model.php @@ -1271,14 +1271,14 @@ class productModel extends model } /* Compute totalReal and progress. */ - $this->loadModel('project'); + $progressList = $this->loadModel('project')->getWaterfallProgress(array_keys($hours)); foreach($hours as $projectID => $hour) { $hour->totalEstimate = round($hour->totalEstimate, 1) ; $hour->totalConsumed = round($hour->totalConsumed, 1); $hour->totalLeft = round($hour->totalLeft, 1); $hour->totalReal = $hour->totalConsumed + $hour->totalLeft; - $hour->progress = $projects[$projectID]->model == 'waterfall' ? $this->project->getWaterfallProgress($projectID) : ($hour->totalReal ? round($hour->totalConsumed / $hour->totalReal, 2) * 100 : 0); + $hour->progress = $projects[$projectID]->model == 'waterfall' ? $progressList[$projectID] : ($hour->totalReal ? round($hour->totalConsumed / $hour->totalReal, 2) * 100 : 0); } /* Get the number of project teams. */ diff --git a/module/product/view/project.html.php b/module/product/view/project.html.php index 32cb6a14d9..2037c8943c 100644 --- a/module/product/view/project.html.php +++ b/module/product/view/project.html.php @@ -96,8 +96,8 @@ hours->totalEstimate . $lang->execution->workHourUnit;?> hours->totalConsumed . $lang->execution->workHourUnit;?> -
-
hours->progress;?>
+
+
hours->progress);?>
diff --git a/module/program/model.php b/module/program/model.php index a9f376915e..64cce62d4a 100644 --- a/module/program/model.php +++ b/module/program/model.php @@ -1434,14 +1434,14 @@ class programModel extends model } /* Compute totalReal and progress. */ - $this->loadModel('project'); + $progressList = $this->loadModel('project')->getWaterfallProgress(array_keys($hours)); foreach($hours as $projectID => $hour) { $hour->totalEstimate = round($hour->totalEstimate, 1) ; $hour->totalConsumed = round($hour->totalConsumed, 1); $hour->totalLeft = round($hour->totalLeft, 1); $hour->totalReal = $hour->totalConsumed + $hour->totalLeft; - $hour->progress = $projects[$projectID]->model == 'waterfall' ? $this->project->getWaterfallProgress($projectID) : ($hour->totalReal ? round($hour->totalConsumed / $hour->totalReal, 2) * 100 : 0); + $hour->progress = $projects[$projectID]->model == 'waterfall' ? $progressList[$projectID] : ($hour->totalReal ? round($hour->totalConsumed / $hour->totalReal, 2) * 100 : 0); } /* Get the number of left tasks. */ diff --git a/module/project/model.php b/module/project/model.php index 9b52db5478..9505afc7f1 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -396,42 +396,48 @@ class projectModel extends model /** * Get waterfall project progress. * - * @param int $projectID + * @param array $projectIDList * @access public * @return int */ - public function getWaterfallProgress($projectID) + public function getWaterfallProgress($projectIDList) { - $executions = $this->loadModel('execution')->getByProject($projectID); + $projectList = $this->dao->select('t1.*')->from(TABLE_EXECUTION)->alias('t1') + ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project=t2.id') + ->where('t1.type')->in('stage') + ->andWhere('t1.deleted')->eq('0') + ->andWhere('t1.vision')->eq($this->config->vision) + ->andWhere('t1.project')->in($projectIDList) + ->andWhere('t2.model')->eq('waterfall') + ->fetchGroup('project', 'id'); - $totalHour = $this->dao->select('execution, ROUND(SUM(`left`), 2) AS totalLeft, ROUND(SUM(consumed), 1) AS totalConsumed')->from(TABLE_TASK) - ->where('execution')->in(array_keys($executions)) - ->andWhere('deleted')->eq(0) - ->andWhere('parent')->lt(1) - ->groupBy('execution') - ->fetchAll('execution'); + $totalHour = $this->dao->select('t1.project, t1.execution, ROUND(SUM(if(t1.status !="closed" && t1.status !="cancel", `left`, 0)), 2) AS totalLeft, ROUND(SUM(consumed), 1) AS totalConsumed')->from(TABLE_TASK)->alias('t1') + ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.execution = t2.id') + ->where('t2.project')->in(array_keys($projectList)) + ->andWhere('t1.deleted')->eq(0) + ->andWhere('t1.parent')->lt(1) + ->groupBy('t1.execution') + ->fetchGroup('project', 'execution'); - $closedTotalLeft = $this->dao->select('execution, ROUND(SUM(`left`), 2) AS totalLeft')->from(TABLE_TASK) - ->where('execution')->in(array_keys($executions)) - ->andWhere('deleted')->eq(0) - ->andWhere('parent')->lt(1) - ->andWhere('status')->in('closed,cancel') - ->groupBy('execution') - ->fetchPairs('execution'); - - $progress = 0; - foreach($executions as $executionID => $execution) + $progressList = array(); + foreach($projectList as $projectID => $stageList) { - $executionClosedLeft = isset($closedTotalLeft[$executionID]) ? $closedTotalLeft[$executionID] : 0; - $executionTotalConsumed = isset($totalHour[$executionID]) ? $totalHour[$executionID]->totalConsumed : 0; - $executionTotalLeft = isset($totalHour[$executionID]) ? round($totalHour[$executionID]->totalLeft - $executionClosedLeft, 1) : 0; + $progress = 0; + foreach($stageList as $stageID => $stage) + { + if($stage->project != $projectID) continue; - $executionProgress = ($executionTotalConsumed + $executionTotalLeft) ? floor($executionTotalConsumed / ($executionTotalConsumed + $executionTotalLeft) * 1000) / 1000 * 100 : 0; + $stageTotalConsumed = isset($totalHour[$projectID][$stageID]) ? $totalHour[$projectID][$stageID]->totalConsumed : 0; + $stageTotalLeft = isset($totalHour[$projectID][$stageID]) ? round($totalHour[$projectID][$stageID]->totalLeft, 1) : 0; - $progress += $executionProgress * ($execution->percent / 100); + $stageProgress = ($stageTotalConsumed + $stageTotalLeft) ? floor($stageTotalConsumed / ($stageTotalConsumed + $stageTotalLeft) * 1000) / 1000 * 100 : 0; + + $progress += $stageProgress * ($stage->percent / 100); + } + $progressList[$projectID] = $progress; } - return $progress; + return is_numeric($projectIDList) ? $progressList[$projectIDList] : $progressList; } /** From e92779664118169b3cf11da1cac7855ec3f51d19 Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Thu, 28 Jul 2022 08:16:07 +0800 Subject: [PATCH 06/13] * Fix bug#25004. --- module/program/view/browsebylist.html.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/program/view/browsebylist.html.php b/module/program/view/browsebylist.html.php index faefdc1c04..44da6a7f16 100644 --- a/module/program/view/browsebylist.html.php +++ b/module/program/view/browsebylist.html.php @@ -85,8 +85,8 @@ end == LONG_TIME ? $lang->program->longTime : $program->end;?> id])):?> -
-
id];?>
+
+
id]);?>
From 48285709d339c5d62aee8258637c3380e7bb84db Mon Sep 17 00:00:00 2001 From: hufangzhou Date: Thu, 28 Jul 2022 08:29:54 +0800 Subject: [PATCH 07/13] * Fix bug #25621. --- module/api/css/editlib.css | 1 + 1 file changed, 1 insertion(+) create mode 100644 module/api/css/editlib.css diff --git a/module/api/css/editlib.css b/module/api/css/editlib.css new file mode 100644 index 0000000000..a6a00155ce --- /dev/null +++ b/module/api/css/editlib.css @@ -0,0 +1 @@ +#whiteListBox .input-group:last-child {margin-top: 10px;} From 2e6ef972b084f0112aa94493b8e803f786c35226 Mon Sep 17 00:00:00 2001 From: zhouxudong Date: Thu, 28 Jul 2022 00:47:37 +0000 Subject: [PATCH 08/13] * Fix bug #25748. --- module/project/view/browsebycard.html.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/module/project/view/browsebycard.html.php b/module/project/view/browsebycard.html.php index 0cd1d727d8..8bd4074daa 100644 --- a/module/project/view/browsebycard.html.php +++ b/module/project/view/browsebycard.html.php @@ -57,7 +57,8 @@