From 1619a3f7e39d73841ba906ce868ae06bcdfb5ffa Mon Sep 17 00:00:00 2001 From: wangyidong Date: Mon, 21 Aug 2023 15:14:42 +0800 Subject: [PATCH] * Code for task #99424. --- module/program/css/browse.ui.css | 2 + module/program/js/browse.ui.js | 20 +++++++- module/program/lang/de.php | 6 +++ module/program/lang/en.php | 6 +++ module/program/lang/fr.php | 6 +++ module/program/lang/zh-cn.php | 6 +++ module/program/ui/browse.html.php | 79 ++++++++++++++++++++++++++++--- 7 files changed, 116 insertions(+), 9 deletions(-) diff --git a/module/program/css/browse.ui.css b/module/program/css/browse.ui.css index ff1e2a3fc6..60fe1671e8 100644 --- a/module/program/css/browse.ui.css +++ b/module/program/css/browse.ui.css @@ -1 +1,3 @@ #mainContent .dtable .dtable-header .dtable-checkbox {display: none} +.dtable-cell[data-col="budget"] .dtable-cell-content {overflow: visible; z-index: 10;} +.dtable-cell[data-col="budget"] menu {padding: 5px;} diff --git a/module/program/js/browse.ui.js b/module/program/js/browse.ui.js index 01f3606bd1..6119d6eff8 100644 --- a/module/program/js/browse.ui.js +++ b/module/program/js/browse.ui.js @@ -13,9 +13,25 @@ window.renderCell = function(result, {col, row}) return result; } - if(col.name === 'budget') + if(col.name === 'budget' && typeof(row.data.exceedBudget) != 'undefined') { - result[0] = {html: '
' + row.data.budget + '
', className:'flex items-end w-full items-end', style:{flexDirection:"column"}}; + let iconSign = ' '; + let menu = ''; + let dropMenu = menu; + dropMenu += '
' + projectBudgetLang + ': ' + row.data.rawBudget + '
'; + dropMenu += '
' + remainingBudgetLang + ': ' + row.data.remainingBudget + '
'; + dropMenu += '
' + exceededBudgetLang + ': ' + row.data.exceedBudget + '
'; + + if(row.data.type == 'program') + { + if(row.data.parent == 0) iconSign = ' '; + dropMenu = menu; + dropMenu += '
' + programBudgetLang + ': ' + row.data.rawBudget + '
'; + dropMenu += '
' + sumSubBudgetLang + ': ' + row.data.subBudget + '
'; + dropMenu += '
' + exceededBudgetLang + ': ' + row.data.exceedBudget + '
'; + } + iconSign = '' + iconSign + ''; + result[0] = {html: '
' + row.data.budget + iconSign + dropMenu + '
', className:'flex items-end w-full items-end', style:{flexDirection:"column"}}; return result; } diff --git a/module/program/lang/de.php b/module/program/lang/de.php index db16162eba..9e20be7bf0 100644 --- a/module/program/lang/de.php +++ b/module/program/lang/de.php @@ -221,3 +221,9 @@ $lang->program->latestReleaseDate = 'Latest Release Date'; $lang->program->latestRelease = 'Latest Release'; $lang->program->manageLine = 'Verwalte Produktlinie'; $lang->program->checkedProducts = '%total%  products selected.'; + +$lang->program->programBudget = 'Program Budget'; +$lang->program->projectBudget = 'Project Budget'; +$lang->program->sumSubBudget = 'Sum For Sub Program'; +$lang->program->exceededBudget = 'Exceeded Budget'; +$lang->program->remainingBudget = 'Remaining For Program'; diff --git a/module/program/lang/en.php b/module/program/lang/en.php index b45bccd041..0304c17072 100644 --- a/module/program/lang/en.php +++ b/module/program/lang/en.php @@ -221,3 +221,9 @@ $lang->program->latestReleaseDate = 'Latest Release Date'; $lang->program->latestRelease = 'Latest Release'; $lang->program->manageLine = 'Manage Product Line'; $lang->program->checkedProducts = '%total%  products selected.'; + +$lang->program->programBudget = 'Program Budget'; +$lang->program->projectBudget = 'Project Budget'; +$lang->program->sumSubBudget = 'Sum For Sub Program'; +$lang->program->exceededBudget = 'Exceeded Budget'; +$lang->program->remainingBudget = 'Remaining For Program'; diff --git a/module/program/lang/fr.php b/module/program/lang/fr.php index 49a614cb19..20a89dca6c 100644 --- a/module/program/lang/fr.php +++ b/module/program/lang/fr.php @@ -221,3 +221,9 @@ $lang->program->latestReleaseDate = 'Latest Release Date'; $lang->program->latestRelease = 'Latest Release'; $lang->program->manageLine = 'Gérer Ligne Produit'; $lang->program->checkedProducts = '%total%  products selected.'; + +$lang->program->programBudget = 'Program Budget'; +$lang->program->projectBudget = 'Project Budget'; +$lang->program->sumSubBudget = 'Sum For Sub Program'; +$lang->program->exceededBudget = 'Exceeded Budget'; +$lang->program->remainingBudget = 'Remaining For Program'; diff --git a/module/program/lang/zh-cn.php b/module/program/lang/zh-cn.php index dcdbf88705..afc201f68b 100644 --- a/module/program/lang/zh-cn.php +++ b/module/program/lang/zh-cn.php @@ -220,3 +220,9 @@ $lang->program->latestReleaseDate = '最新发布时间'; $lang->program->latestRelease = '最新发布'; $lang->program->manageLine = '维护产品线'; $lang->program->checkedProducts = '共选中 %total% 个产品。'; + +$lang->program->programBudget = '项目集预算'; +$lang->program->projectBudget = '项目预算'; +$lang->program->sumSubBudget = '子集预算和'; +$lang->program->exceededBudget = '已超出预算'; +$lang->program->remainingBudget = '项目集剩余'; diff --git a/module/program/ui/browse.html.php b/module/program/ui/browse.html.php index fb99e3cce7..756ec3457c 100644 --- a/module/program/ui/browse.html.php +++ b/module/program/ui/browse.html.php @@ -3,10 +3,17 @@ namespace zin; $confirmDeleteLang['program'] = $lang->program->confirmDelete; $confirmDeleteLang['project'] = $lang->project->confirmDelete; -jsVar('confirmDeleteLang', $confirmDeleteLang); +jsVar('confirmDeleteLang', $confirmDeleteLang); +jsVar('programBudgetLang', $lang->program->programBudget); +jsVar('projectBudgetLang', $lang->program->projectBudget); +jsVar('sumSubBudgetLang', $lang->program->sumSubBudget); +jsVar('exceededBudgetLang', $lang->program->exceededBudget); +jsVar('remainingBudgetLang', $lang->program->remainingBudget); -$cols = $this->loadModel('datatable')->getSetting('program'); -$data = array(); +$this->loadModel('project'); +$cols = $this->loadModel('datatable')->getSetting('program'); +$data = array(); +$parents = array(); foreach($programs as $program) { if(empty($program->parent)) $program->parent = 0; @@ -31,8 +38,10 @@ foreach($programs as $program) } /* Calculate budget.*/ - $programBudget = $this->loadModel('project')->getBudgetWithUnit($program->budget); - $program->budget = $program->budget != 0 ? zget($lang->project->currencySymbol, $program->budgetUnit) . ' ' . $programBudget : $lang->project->future; + $programBudget = $this->project->getBudgetWithUnit($program->budget); + $program->rawBudget = (int)$program->budget; + $program->budget = !empty($program->budget) ? zget($lang->project->currencySymbol, $program->budgetUnit) . ' ' . $programBudget : $lang->project->future; + $parents[$program->parent][] = $program->id; /* Progress. */ if(isset($progressList[$program->id])) $program->progress = round($progressList[$program->id]); @@ -56,7 +65,63 @@ foreach($programs as $program) $program->actions[] = $action; } - $data[] = $program; + $data[$program->id] = $program; +} + +$fnComputeSubBudget = function($programID, $sumBudget) use($parents, $data, &$fnComputeSubBudget) +{ + if(!isset($parents[$programID])) + { + $sumBudget += $data[$programID]->rawBudget; + } + else + { + foreach($parents[$programID] as $subID) $sumBudget = $fnComputeSubBudget($subID, $sumBudget); + } + return $sumBudget; +}; + +foreach($data as $programID => $program) +{ + if(!isset($parents[$programID])) continue; + $program->subBudget = $fnComputeSubBudget($programID, 0); +} + +/* Compute remaining budget. */ +foreach($parents as $parentID => $subs) +{ + if(!isset($data[$parentID])) continue; + + $parentBudget = $data[$parentID]->rawBudget; + if(empty($parentBudget)) continue; + foreach($subs as $subID) + { + $subProgram = $data[$subID]; + if($subProgram->type == 'program') continue; + $subProgram->remainingBudget = $parentBudget; + array_map(function($programID) use ($data, $subProgram) + { + if($programID != $subProgram->id) $subProgram->remainingBudget -= $data[$programID]->rawBudget; + }, $subs); + } +} + +foreach($data as $programID => $program) +{ + if($program->rawBudget == 0) continue; + if($program->type == 'program' && !empty($program->subBudget) && $program->rawBudget < $program->subBudget) + { + $program->exceedBudget = $program->subBudget - $program->rawBudget; + $program->exceedBudget = $this->project->getBudgetWithUnit($program->exceedBudget); + $program->subBudget = $this->project->getBudgetWithUnit($program->subBudget); + } + elseif($program->type == 'project' && !empty($program->remainingBudget) && $program->rawBudget > $program->remainingBudget) + { + $program->exceedBudget = $program->rawBudget - $program->remainingBudget; + $program->exceedBudget = $this->project->getBudgetWithUnit($program->exceedBudget); + $program->remainingBudget = $this->project->getBudgetWithUnit($program->remainingBudget); + } + $program->rawBudget = $this->project->getBudgetWithUnit($program->rawBudget); } jsVar('langManDay', $lang->program->manDay); @@ -92,7 +157,7 @@ $footToolbar = common::hasPriv('project', 'batchEdit') ? array('items' => array( dtable ( set::cols($cols), - set::data($data), + set::data(array_values($data)), set::nested(true), set::onRenderCell(jsRaw('window.renderCell')), set::canRowCheckable(jsRaw("function(rowID){return this.getRowInfo(rowID).data.type == 'project';}")),