* Adjust code details.

This commit is contained in:
Yagami
2020-11-19 10:41:37 +08:00
parent b919cc45b2
commit aae58fea38
17 changed files with 863 additions and 862 deletions
+6 -6
View File
@@ -18,17 +18,17 @@ $config->block->longBlock = array();
$config->block->longBlock['']['flowchart'] = 'flowchart';
$config->block->longBlock['']['welcome'] = 'welcome';
$config->block->longBlock['product']['statistic'] = 'statistic';
$config->block->longBlock['project']['statistic'] = 'statistic';
$config->block->longBlock['execution']['statistic'] = 'statistic';
$config->block->longBlock['qa']['statistic'] = 'statistic';
$config->block->longBlock['program']['waterfallreport'] = 'waterfallreport';
$config->block->longBlock['program']['waterfallissue'] = 'waterfallissue';
$config->block->longBlock['program']['waterfallrisk'] = 'waterfallrisk';
$config->block->longBlock['project']['waterfallreport'] = 'waterfallreport';
$config->block->longBlock['project']['waterfallissue'] = 'waterfallissue';
$config->block->longBlock['project']['waterfallrisk'] = 'waterfallrisk';
$config->block->shortBlock = array();
$config->block->shortBlock['product']['overview'] = 'overview';
$config->block->shortBlock['project']['overview'] = 'overview';
$config->block->shortBlock['program']['waterfallestimate'] = 'waterfallestimate';
$config->block->shortBlock['program']['waterfallprogress'] = 'waterfallprogress';
$config->block->shortBlock['project']['waterfallestimate'] = 'waterfallestimate';
$config->block->shortBlock['project']['waterfallprogress'] = 'waterfallprogress';
$config->block->shortBlock['']['contribute'] = 'contribute';
$config->statistic = new stdclass();
+50 -50
View File
@@ -65,7 +65,7 @@ class block extends control
elseif(isset($this->lang->block->moduleList[$module]))
{
$this->get->set('mode', 'getblocklist');
if($module == 'program') $this->get->set('dashboard', 'program');
if($module == 'project') $this->get->set('dashboard', 'project');
$this->view->blocks = $this->fetch('block', 'main', "module=$module&id=$id");
$this->view->module = $module;
}
@@ -213,10 +213,10 @@ class block extends control
$blocks = $this->block->getBlockList($module, $type);
$commonField = 'common';
if($module == 'program')
if($module == 'project')
{
$program = $this->loadModel('project')->getByID($this->session->PRJ);
$commonField = $program->model . 'common';
$project = $this->loadModel('program')->getPRJByID($this->session->PRJ);
$commonField = $project->model . 'common';
}
$inited = empty($this->config->$module->$commonField->blockInited) ? '' : $this->config->$module->$commonField->blockInited;
@@ -420,18 +420,18 @@ class block extends control
$block = $this->block->getByID($id);
$dashboard = $this->get->dashboard;
/* Create a program block. */
if($dashboard == 'program')
/* Create a project block. */
if($dashboard == 'project')
{
$program = $this->loadModel('project')->getByID($this->session->PRJ);
$model = $program->model;
$project = $this->loadModel('program')->getPRJByID($this->session->PRJ);
$model = $project->model;
}
/* Edit a program block. */
if($id and $block->module == 'program')
/* Edit a project block. */
if($id and $block->module == 'project')
{
$model = $block->type;
$dashboard = 'program';
$dashboard = 'project';
}
$blocks = $this->block->getAvailableBlocks($module, $dashboard, $model);
@@ -579,8 +579,8 @@ class block extends control
$this->session->set('storyList', $uri);
if(preg_match('/[^a-zA-Z0-9_]/', $this->params->type)) die();
$programID = $this->view->block->module == 'my' ? 0 : (int)$this->session->PRJ;
$this->view->tasks = $this->loadModel('task')->getUserTasks($this->app->user->account, $this->params->type, $this->viewType == 'json' ? 0 : (int)$this->params->count, null, $this->params->orderBy, $programID);
$projectID = $this->view->block->module == 'my' ? 0 : (int)$this->session->PRJ;
$this->view->tasks = $this->loadModel('task')->getUserTasks($this->app->user->account, $this->params->type, $this->viewType == 'json' ? 0 : (int)$this->params->count, null, $this->params->orderBy, $projectID);
}
/**
@@ -594,8 +594,8 @@ class block extends control
$this->session->set('bugList', $this->app->getURI(true));
if(preg_match('/[^a-zA-Z0-9_]/', $this->params->type)) die();
$programID = $this->view->block->module == 'my' ? 0 : (int)$this->session->PRJ;
$this->view->bugs = $this->loadModel('bug')->getUserBugs($this->app->user->account, $this->params->type, $this->params->orderBy, $this->viewType == 'json' ? 0 : (int)$this->params->count, null, $programID);
$projectID = $this->view->block->module == 'my' ? 0 : (int)$this->session->PRJ;
$this->view->bugs = $this->loadModel('bug')->getUserBugs($this->app->user->account, $this->params->type, $this->params->orderBy, $this->viewType == 'json' ? 0 : (int)$this->params->count, null, $projectID);
}
/**
@@ -744,12 +744,12 @@ class block extends control
}
/**
* Print program block.
* Print project block.
*
* @access public
* @return void
*/
public function printProgramBlock()
public function printProjectBlock()
{
$this->app->loadLang('project');
$this->app->loadLang('task');
@@ -757,7 +757,7 @@ class block extends control
$type = isset($this->params->type) ? $this->params->type : 'all';
$orderBy = isset($this->params->orderBy) ? $this->params->orderBy : 'id_desc';
$this->view->programs = $this->loadModel('program')->getProgramOverview('byStatus', $type, $orderBy, $count);
$this->view->projects = $this->loadModel('program')->getPRJOverview('byStatus', $type, $orderBy, $count);
$this->view->users = $this->loadModel('user')->getPairs('noletter');
}
@@ -808,7 +808,7 @@ class block extends control
* @access public
* @return void
*/
public function printProgramStatisticBlock()
public function printProjectStatisticBlock()
{
if(!empty($this->params->type) and preg_match('/[^a-zA-Z0-9_]/', $this->params->type)) die();
@@ -822,11 +822,11 @@ class block extends control
$status = isset($this->params->type) ? $this->params->type : 'all';
$count = isset($this->params->count) ? (int)$this->params->count : 15;
/* Get programs. */
$programs = $this->loadModel('program')->getProgramOverview('byStatus', $status, 'id_desc', $count);
if(empty($programs))
/* Get projects. */
$projects = $this->loadModel('program')->getPRJOverview('byStatus', $status, 'id_desc', $count);
if(empty($projects))
{
$this->view->programs = $programs;
$this->view->projects = $projects;
return false;
}
@@ -836,40 +836,40 @@ class block extends control
sum(consumed) as totalConsumed,
sum(if(status != 'cancel' and status != 'closed', `left`, 0)) as totalLeft")
->from(TABLE_TASK)
->where('PRJ')->in(array_keys($programs))
->where('PRJ')->in(array_keys($projects))
->andWhere('deleted')->eq(0)
->andWhere('parent')->lt(1)
->groupBy('PRJ')
->fetchAll('PRJ');
foreach($programs as $programID => $program)
foreach($projects as $projectID => $project)
{
if($program->model == 'scrum')
if($project->model == 'scrum')
{
$program->progress = $program->allStories == 0 ? 0 : round($program->doneStories / $program->allStories, 3) * 100;
$program->projects = $this->project->getProjectStats('all', 0, 0, 1, 'id_desc', null, $programID);
$project->progress = $project->allStories == 0 ? 0 : round($project->doneStories / $project->allStories, 3) * 100;
$project->executions = $this->project->getExecutionStats($projectID, 'all', 0, 0, 1, 'id_desc', null);
}
elseif($program->model == 'waterfall')
elseif($project->model == 'waterfall')
{
$begin = $program->begin;
$begin = $project->begin;
$weeks = $this->weekly->getWeekPairs($begin);
$current = zget($weeks, $monday, '');
$current = substr($current, 0, -11) . substr($current, -6);
$program->pv = $this->weekly->getPV($programID, $today);
$program->ev = $this->weekly->getEV($programID, $today);
$program->ac = $this->weekly->getAC($programID, $today);
$program->sv = $this->weekly->getSV($program->ev, $program->pv);
$program->cv = $this->weekly->getCV($program->ev, $program->ac);
$project->pv = $this->weekly->getPV($projectID, $today);
$project->ev = $this->weekly->getEV($projectID, $today);
$project->ac = $this->weekly->getAC($projectID, $today);
$project->sv = $this->weekly->getSV($project->ev, $project->pv);
$project->cv = $this->weekly->getCV($project->ev, $project->ac);
$progress = isset($tasks[$programID]) ? (($tasks[$programID]->totalConsumed + $tasks[$programID]->totalLeft)) ? round($tasks[$programID]->totalConsumed / ($tasks[$programID]->totalConsumed + $tasks[$programID]->totalLeft), 3) * 100 : 0 : 0;
$progress = isset($tasks[$projectID]) ? (($tasks[$projectID]->totalConsumed + $tasks[$projectID]->totalLeft)) ? round($tasks[$projectID]->totalConsumed / ($tasks[$projectID]->totalConsumed + $tasks[$projectID]->totalLeft), 3) * 100 : 0 : 0;
$program->current = $current;
$program->progress = $progress;
$project->current = $current;
$project->progress = $progress;
}
}
$this->view->programs = $programs;
$this->view->projects = $projects;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
}
@@ -1003,12 +1003,12 @@ class block extends control
}
/**
* Print project statistic block.
* Print execution statistic block.
*
* @access public
* @return void
*/
public function printProjectStatisticBlock()
public function printExecutionStatisticBlock()
{
if(!empty($this->params->type) and preg_match('/[^a-zA-Z0-9_]/', $this->params->type)) die();
@@ -1279,7 +1279,7 @@ class block extends control
public function printScrumOverviewBlock()
{
$programID = $this->session->PRJ;
$totalData = $this->loadModel('program')->getProgramOverview('byId', $programID, 'id_desc', 1);
$totalData = $this->loadModel('program')->getProjectOverview('byId', $programID, 'id_desc', 1);
$this->view->totalData = $totalData;
$this->view->programID = $programID;
@@ -1364,7 +1364,7 @@ class block extends control
* @access public
* @return void
*/
public function printProgramDynamicBlock()
public function printProjectDynamicBlock()
{
$programID = $this->session->PRJ;
@@ -1618,12 +1618,12 @@ class block extends control
}
/**
* Print project block.
* Print execution block.
*
* @access public
* @return void
*/
public function printProjectBlock()
public function printExecutionBlock()
{
$this->app->loadClass('pager', $static = true);
if(!empty($this->params->type) and preg_match('/[^a-zA-Z0-9_]/', $this->params->type)) die();
@@ -1728,20 +1728,20 @@ class block extends control
}
/**
* Print recent program block.
* Print recent project block.
*
* @access public
* @return void
*/
public function printRecentprogramBlock()
public function printRecentProjectBlock()
{
/* load pager. */
$this->app->loadClass('pager', $static = true);
$pager = new pager(0, 3, 1);
$this->view->programs = $this->loadModel('program')->getProgramStats('all', 30, 'id_desc', $pager);
$this->view->projects = $this->loadModel('program')->getPRJInfo('all', 30, 'id_desc', $pager);
}
public function printProgramteamBlock()
public function printProjectTeamBlock()
{
$this->loadModel('project');
@@ -1750,7 +1750,7 @@ class block extends control
$orderBy = isset($this->params->orderBy) ? $this->params->orderBy : 'id_desc';
/* Get projects. */
$this->view->programs = $this->loadModel('program')->getProgramOverview('byStatus', $status, $orderBy, $count);
$this->view->projects = $this->loadModel('program')->getPRJOverview('byStatus', $status, $orderBy, $count);
}
/**
+96 -96
View File
@@ -90,79 +90,79 @@ $lang->block->spent = '已花费';
$lang->block->budget = '预算';
$lang->block->left = '剩余';
$lang->block->default['waterfall']['program']['1']['title'] = '项目周报';
$lang->block->default['waterfall']['program']['1']['block'] = 'waterfallreport';
$lang->block->default['waterfall']['program']['1']['source'] = 'program';
$lang->block->default['waterfall']['program']['1']['grid'] = 8;
$lang->block->default['waterfall']['project']['1']['title'] = '项目周报';
$lang->block->default['waterfall']['project']['1']['block'] = 'waterfallreport';
$lang->block->default['waterfall']['project']['1']['source'] = 'project';
$lang->block->default['waterfall']['project']['1']['grid'] = 8;
$lang->block->default['waterfall']['program']['2']['title'] = '估算';
$lang->block->default['waterfall']['program']['2']['block'] = 'waterfallestimate';
$lang->block->default['waterfall']['program']['2']['source'] = 'program';
$lang->block->default['waterfall']['program']['2']['grid'] = 4;
$lang->block->default['waterfall']['project']['2']['title'] = '估算';
$lang->block->default['waterfall']['project']['2']['block'] = 'waterfallestimate';
$lang->block->default['waterfall']['project']['2']['source'] = 'project';
$lang->block->default['waterfall']['project']['2']['grid'] = 4;
$lang->block->default['waterfall']['program']['3']['title'] = "项目{$lang->planCommon}";
$lang->block->default['waterfall']['program']['3']['block'] = 'waterfallgantt';
$lang->block->default['waterfall']['program']['3']['source'] = 'program';
$lang->block->default['waterfall']['program']['3']['grid'] = 8;
$lang->block->default['waterfall']['project']['3']['title'] = "项目{$lang->planCommon}";
$lang->block->default['waterfall']['project']['3']['block'] = 'waterfallgantt';
$lang->block->default['waterfall']['project']['3']['source'] = 'project';
$lang->block->default['waterfall']['project']['3']['grid'] = 8;
$lang->block->default['waterfall']['program']['4']['title'] = '到目前为止项目进展趋势图';
$lang->block->default['waterfall']['program']['4']['block'] = 'waterfallprogress';
$lang->block->default['waterfall']['program']['4']['grid'] = 4;
$lang->block->default['waterfall']['project']['4']['title'] = '到目前为止项目进展趋势图';
$lang->block->default['waterfall']['project']['4']['block'] = 'waterfallprogress';
$lang->block->default['waterfall']['project']['4']['grid'] = 4;
$lang->block->default['waterfall']['program']['5']['title'] = '项目问题';
$lang->block->default['waterfall']['program']['5']['block'] = 'waterfallissue';
$lang->block->default['waterfall']['program']['5']['source'] = 'program';
$lang->block->default['waterfall']['program']['5']['grid'] = 8;
$lang->block->default['waterfall']['project']['5']['title'] = '项目问题';
$lang->block->default['waterfall']['project']['5']['block'] = 'waterfallissue';
$lang->block->default['waterfall']['project']['5']['source'] = 'project';
$lang->block->default['waterfall']['project']['5']['grid'] = 8;
$lang->block->default['waterfall']['program']['5']['params']['type'] = 'all';
$lang->block->default['waterfall']['program']['5']['params']['count'] = '15';
$lang->block->default['waterfall']['program']['5']['params']['orderBy'] = 'id_desc';
$lang->block->default['waterfall']['project']['5']['params']['type'] = 'all';
$lang->block->default['waterfall']['project']['5']['params']['count'] = '15';
$lang->block->default['waterfall']['project']['5']['params']['orderBy'] = 'id_desc';
$lang->block->default['waterfall']['program']['6']['title'] = '最新动态';
$lang->block->default['waterfall']['program']['6']['block'] = 'programdynamic';
$lang->block->default['waterfall']['program']['6']['grid'] = 4;
$lang->block->default['waterfall']['program']['6']['source'] = 'program';
$lang->block->default['waterfall']['project']['6']['title'] = '最新动态';
$lang->block->default['waterfall']['project']['6']['block'] = 'projectdynamic';
$lang->block->default['waterfall']['project']['6']['grid'] = 4;
$lang->block->default['waterfall']['project']['6']['source'] = 'project';
$lang->block->default['waterfall']['program']['7']['title'] = '项目风险';
$lang->block->default['waterfall']['program']['7']['block'] = 'waterfallrisk';
$lang->block->default['waterfall']['program']['7']['source'] = 'program';
$lang->block->default['waterfall']['program']['7']['grid'] = 8;
$lang->block->default['waterfall']['project']['7']['title'] = '项目风险';
$lang->block->default['waterfall']['project']['7']['block'] = 'waterfallrisk';
$lang->block->default['waterfall']['project']['7']['source'] = 'project';
$lang->block->default['waterfall']['project']['7']['grid'] = 8;
$lang->block->default['waterfall']['program']['7']['params']['type'] = 'all';
$lang->block->default['waterfall']['program']['7']['params']['count'] = '15';
$lang->block->default['waterfall']['program']['7']['params']['orderBy'] = 'id_desc';
$lang->block->default['waterfall']['project']['7']['params']['type'] = 'all';
$lang->block->default['waterfall']['project']['7']['params']['count'] = '15';
$lang->block->default['waterfall']['project']['7']['params']['orderBy'] = 'id_desc';
$lang->block->default['scrum']['program']['1']['title'] = '项目整体情况';
$lang->block->default['scrum']['program']['1']['block'] = 'scrumoverview';
$lang->block->default['scrum']['program']['1']['grid'] = 8;
$lang->block->default['scrum']['project']['1']['title'] = '项目整体情况';
$lang->block->default['scrum']['project']['1']['block'] = 'scrumoverview';
$lang->block->default['scrum']['project']['1']['grid'] = 8;
$lang->block->default['scrum']['program']['2']['title'] = $lang->projectCommon . '列表';
$lang->block->default['scrum']['program']['2']['block'] = 'scrumlist';
$lang->block->default['scrum']['program']['2']['grid'] = 8;
$lang->block->default['scrum']['project']['2']['title'] = $lang->projectCommon . '列表';
$lang->block->default['scrum']['project']['2']['block'] = 'scrumlist';
$lang->block->default['scrum']['project']['2']['grid'] = 8;
$lang->block->default['scrum']['program']['3']['title'] = $lang->productCommon . '路线图';
$lang->block->default['scrum']['program']['3']['block'] = 'scrumroadmap';
$lang->block->default['scrum']['program']['3']['grid'] = 8;
$lang->block->default['scrum']['project']['3']['title'] = $lang->productCommon . '路线图';
$lang->block->default['scrum']['project']['3']['block'] = 'scrumroadmap';
$lang->block->default['scrum']['project']['3']['grid'] = 8;
$lang->block->default['scrum']['program']['4']['title'] = '待测版本';
$lang->block->default['scrum']['program']['4']['block'] = 'scrumtest';
$lang->block->default['scrum']['program']['4']['grid'] = 8;
$lang->block->default['scrum']['project']['4']['title'] = '待测版本';
$lang->block->default['scrum']['project']['4']['block'] = 'scrumtest';
$lang->block->default['scrum']['project']['4']['grid'] = 8;
$lang->block->default['scrum']['program']['4']['params']['type'] = 'wait';
$lang->block->default['scrum']['program']['4']['params']['count'] = '15';
$lang->block->default['scrum']['program']['4']['params']['orderBy'] = 'id_desc';
$lang->block->default['scrum']['project']['4']['params']['type'] = 'wait';
$lang->block->default['scrum']['project']['4']['params']['count'] = '15';
$lang->block->default['scrum']['project']['4']['params']['orderBy'] = 'id_desc';
$lang->block->default['scrum']['program']['5']['title'] = $lang->productCommon . '总览';
$lang->block->default['scrum']['program']['5']['block'] = 'scrumproduct';
$lang->block->default['scrum']['program']['5']['grid'] = 4;
$lang->block->default['scrum']['project']['5']['title'] = $lang->productCommon . '总览';
$lang->block->default['scrum']['project']['5']['block'] = 'scrumproduct';
$lang->block->default['scrum']['project']['5']['grid'] = 4;
$lang->block->default['scrum']['program']['6']['title'] = $lang->projectCommon . '总览';
$lang->block->default['scrum']['program']['6']['block'] = 'sprint';
$lang->block->default['scrum']['program']['6']['grid'] = 4;
$lang->block->default['scrum']['project']['6']['title'] = $lang->projectCommon . '总览';
$lang->block->default['scrum']['project']['6']['block'] = 'sprint';
$lang->block->default['scrum']['project']['6']['grid'] = 4;
$lang->block->default['scrum']['program']['7']['title'] = '最新动态';
$lang->block->default['scrum']['program']['7']['block'] = 'programdynamic';
$lang->block->default['scrum']['program']['7']['grid'] = 4;
$lang->block->default['scrum']['project']['7']['title'] = '最新动态';
$lang->block->default['scrum']['project']['7']['block'] = 'projectdynamic';
$lang->block->default['scrum']['project']['7']['grid'] = 4;
$lang->block->default['product']['1']['title'] = $lang->productCommon . '统计';
$lang->block->default['product']['1']['block'] = 'statistic';
@@ -270,7 +270,7 @@ $lang->block->default['full']['my']['3']['params']['count'] = '20';
$lang->block->default['full']['my']['4']['title'] = '项目统计';
$lang->block->default['full']['my']['4']['block'] = 'statistic';
$lang->block->default['full']['my']['4']['source'] = 'program';
$lang->block->default['full']['my']['4']['source'] = 'project';
$lang->block->default['full']['my']['4']['grid'] = 8;
$lang->block->default['full']['my']['5']['title'] = '我的贡献';
@@ -279,8 +279,8 @@ $lang->block->default['full']['my']['5']['source'] = '';
$lang->block->default['full']['my']['5']['grid'] = 4;
$lang->block->default['full']['my']['6']['title'] = '我的近期项目';
$lang->block->default['full']['my']['6']['block'] = 'recentprogram';
$lang->block->default['full']['my']['6']['source'] = 'program';
$lang->block->default['full']['my']['6']['block'] = 'recentproject';
$lang->block->default['full']['my']['6']['source'] = 'project';
$lang->block->default['full']['my']['6']['grid'] = 8;
$lang->block->default['full']['my']['7']['title'] = '指派给我';
@@ -292,12 +292,12 @@ $lang->block->default['full']['my']['7']['params']['count'] = '15';
$lang->block->default['full']['my']['7']['params']['type'] = 'assignedTo';
$lang->block->default['full']['my']['8']['title'] = '项目人力投入';
$lang->block->default['full']['my']['8']['block'] = 'programteam';
$lang->block->default['full']['my']['8']['block'] = 'projectteam';
$lang->block->default['full']['my']['8']['grid'] = 8;
$lang->block->default['full']['my']['9']['title'] = '项目列表';
$lang->block->default['full']['my']['9']['block'] = 'program';
$lang->block->default['full']['my']['9']['source'] = 'program';
$lang->block->default['full']['my']['9']['block'] = 'project';
$lang->block->default['full']['my']['9']['source'] = 'project';
$lang->block->default['full']['my']['9']['grid'] = 8;
$lang->block->default['full']['my']['9']['params']['orderBy'] = 'id_desc';
@@ -322,18 +322,18 @@ $lang->block->availableBlocks->build = '版本列表';
$lang->block->availableBlocks->testtask = '测试版本列表';
$lang->block->availableBlocks->risk = '我的风险';
$lang->block->moduleList['program'] = '项目';
$lang->block->moduleList['product'] = $lang->productCommon;
$lang->block->moduleList['project'] = $lang->projectCommon;
$lang->block->moduleList['qa'] = '测试';
$lang->block->moduleList['todo'] = '待办';
$lang->block->moduleList['project'] = '项目';
$lang->block->moduleList['product'] = $lang->productCommon;
$lang->block->moduleList['execution'] = '执行';
$lang->block->moduleList['qa'] = '测试';
$lang->block->moduleList['todo'] = '待办';
$lang->block->modules['program'] = new stdclass();
$lang->block->modules['program']->availableBlocks = new stdclass();
$lang->block->modules['program']->availableBlocks->program = '项目列表';
$lang->block->modules['program']->availableBlocks->recentprogram = '近期项目';
$lang->block->modules['program']->availableBlocks->statistic = '项目统计';
$lang->block->modules['program']->availableBlocks->programteam = '项目人力投入';
$lang->block->modules['project'] = new stdclass();
$lang->block->modules['project']->availableBlocks = new stdclass();
$lang->block->modules['project']->availableBlocks->project = '项目列表';
$lang->block->modules['project']->availableBlocks->recentproject = '近期项目';
$lang->block->modules['project']->availableBlocks->statistic = '项目统计';
$lang->block->modules['project']->availableBlocks->projectteam = '项目人力投入';
$lang->block->modules['scrum']['index'] = new stdclass();
$lang->block->modules['scrum']['index']->availableBlocks = new stdclass();
@@ -343,7 +343,7 @@ $lang->block->modules['scrum']['index']->availableBlocks->scrumroadmap = $lang
$lang->block->modules['scrum']['index']->availableBlocks->sprint = $lang->projectCommon . '总览';
$lang->block->modules['scrum']['index']->availableBlocks->scrumproduct = $lang->productCommon . '总览';
$lang->block->modules['scrum']['index']->availableBlocks->scrumtest = '待测版本';
$lang->block->modules['scrum']['index']->availableBlocks->programdynamic = '最新动态';
$lang->block->modules['scrum']['index']->availableBlocks->projectdynamic = '最新动态';
$lang->block->modules['waterfall']['index'] = new stdclass();
$lang->block->modules['waterfall']['index']->availableBlocks = new stdclass();
@@ -353,7 +353,7 @@ $lang->block->modules['waterfall']['index']->availableBlocks->waterfallgantt
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallprogress = '到目前为止项目进展趋势图';
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallissue = '项目问题';
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallrisk = '项目风险';
$lang->block->modules['waterfall']['index']->availableBlocks->programdynamic = '最新动态';
$lang->block->modules['waterfall']['index']->availableBlocks->projectdynamic = '最新动态';
$lang->block->modules['product'] = new stdclass();
$lang->block->modules['product']->availableBlocks = new stdclass();
@@ -363,13 +363,13 @@ $lang->block->modules['product']->availableBlocks->list = $lang->productCom
$lang->block->modules['product']->availableBlocks->story = "{$lang->storyCommon}列表";
$lang->block->modules['product']->availableBlocks->plan = "{$lang->planCommon}列表";
$lang->block->modules['product']->availableBlocks->release = '发布列表';
$lang->block->modules['project'] = new stdclass();
$lang->block->modules['project']->availableBlocks = new stdclass();
$lang->block->modules['project']->availableBlocks->statistic = $lang->projectCommon . '统计';
$lang->block->modules['project']->availableBlocks->overview = $lang->projectCommon . '总览';
$lang->block->modules['project']->availableBlocks->list = $lang->projectCommon . '列表';
$lang->block->modules['project']->availableBlocks->task = '任务列表';
$lang->block->modules['project']->availableBlocks->build = '版本列表';
$lang->block->modules['execution'] = new stdclass();
$lang->block->modules['execution']->availableBlocks = new stdclass();
$lang->block->modules['execution']->availableBlocks->statistic = $lang->projectCommon . '统计';
$lang->block->modules['execution']->availableBlocks->overview = $lang->projectCommon . '总览';
$lang->block->modules['execution']->availableBlocks->list = $lang->projectCommon . '列表';
$lang->block->modules['execution']->availableBlocks->task = '任务列表';
$lang->block->modules['execution']->availableBlocks->build = '版本列表';
$lang->block->modules['qa'] = new stdclass();
$lang->block->modules['qa']->availableBlocks = new stdclass();
$lang->block->modules['qa']->availableBlocks->statistic = '测试统计';
@@ -478,19 +478,19 @@ $lang->block->typeList->testtask['blocked'] = '阻塞版本';
$lang->block->typeList->testtask['done'] = '已测版本';
$lang->block->typeList->testtask['all'] = '全部';
$lang->block->modules['program']->moreLinkList = new stdclass();
$lang->block->modules['program']->moreLinkList->recentprogram = 'program|prjbrowse|';
$lang->block->modules['program']->moreLinkList->statistic = 'program|prjbrowse|';
$lang->block->modules['program']->moreLinkList->program = 'program|prjbrowse|';
$lang->block->modules['program']->moreLinkList->cmmireport = 'weekly|index|';
$lang->block->modules['program']->moreLinkList->cmmiestimate = 'workestimation|index|';
$lang->block->modules['program']->moreLinkList->cmmiissue = 'issue|browse|';
$lang->block->modules['program']->moreLinkList->cmmirisk = 'risk|browse|';
$lang->block->modules['program']->moreLinkList->scrumlist = 'project|all|';
$lang->block->modules['program']->moreLinkList->scrumtest = 'testtask|browse|';
$lang->block->modules['program']->moreLinkList->scrumproduct = 'product|all|';
$lang->block->modules['program']->moreLinkList->sprint = 'project|all|';
$lang->block->modules['program']->moreLinkList->programdynamic = 'company|dynamic|';
$lang->block->modules['project']->moreLinkList = new stdclass();
$lang->block->modules['project']->moreLinkList->recentproject = 'project|prjbrowse|';
$lang->block->modules['project']->moreLinkList->statistic = 'project|prjbrowse|';
$lang->block->modules['project']->moreLinkList->project = 'project|prjbrowse|';
$lang->block->modules['project']->moreLinkList->cmmireport = 'weekly|index|';
$lang->block->modules['project']->moreLinkList->cmmiestimate = 'workestimation|index|';
$lang->block->modules['project']->moreLinkList->cmmiissue = 'issue|browse|';
$lang->block->modules['project']->moreLinkList->cmmirisk = 'risk|browse|';
$lang->block->modules['project']->moreLinkList->scrumlist = 'project|all|';
$lang->block->modules['project']->moreLinkList->scrumtest = 'testtask|browse|';
$lang->block->modules['project']->moreLinkList->scrumproduct = 'product|all|';
$lang->block->modules['project']->moreLinkList->sprint = 'project|all|';
$lang->block->modules['project']->moreLinkList->projectdynamic = 'company|dynamic|';
$lang->block->modules['product']->moreLinkList = new stdclass();
$lang->block->modules['product']->moreLinkList->list = 'product|all|';
+22 -22
View File
@@ -221,14 +221,14 @@ class blockModel extends model
{
$flow = isset($this->config->global->flow) ? $this->config->global->flow : 'full';
$account = $this->app->user->account;
if($module == 'program')
if($module == 'project')
{
$blocks = $this->lang->block->default[$type]['program'];
$programID = $this->session->PRJ;
$program = $this->loadModel('project')->getByID($programID);
$blocks = $this->lang->block->default[$type]['project'];
$projectID = $this->session->PRJ;
$project = $this->loadModel('project')->getByID($projectID);
/* Mark program block has init. */
$this->loadModel('setting')->setItem("$account.$module.{$program->model}common.blockInited", true);
/* Mark project block has init. */
$this->loadModel('setting')->setItem("$account.$module.{$project->model}common.blockInited", true);
}
else
{
@@ -259,7 +259,7 @@ class blockModel extends model
*
* @param string $module
* @param string $dashboard
* @param object $program
* @param object $model
*
* @access public
* @return string
@@ -267,7 +267,7 @@ class blockModel extends model
public function getAvailableBlocks($module = '', $dashboard = '', $model = '')
{
$blocks = $this->lang->block->availableBlocks;
if($dashboard == 'program')
if($dashboard == 'project')
{
$blocks = $this->lang->block->modules[$model]['index']->availableBlocks;
}
@@ -440,12 +440,12 @@ class blockModel extends model
}
/**
* Get program params.
* Get project params.
*
* @access public
* @return json
*/
public function getProgramParams()
public function getProjectParams()
{
$this->app->loadLang('program');
$params->type['name'] = $this->lang->block->type;
@@ -460,12 +460,12 @@ class blockModel extends model
}
/**
* Get programteam params.
* Get project team params.
*
* @access public
* @return json
*/
public function getProgramTeamParams()
public function getProjectTeamParams()
{
$this->app->loadLang('program');
$params->type['name'] = $this->lang->block->type;
@@ -571,12 +571,12 @@ class blockModel extends model
}
/**
* Get recent program pararms.
* Get recent project pararms.
*
* @access public
* @return string
*/
public function getRecentProgramParams()
public function getRecentProjectParams()
{
return false;
}
@@ -593,7 +593,7 @@ class blockModel extends model
}
/**
* Get waterfall program report pararms.
* Get waterfall project report pararms.
*
* @access public
* @return string
@@ -604,7 +604,7 @@ class blockModel extends model
}
/**
* Get program estimate pararms.
* Get project estimate pararms.
*
* @access public
* @return string
@@ -615,7 +615,7 @@ class blockModel extends model
}
/**
* Get program gantt pararms.
* Get project gantt pararms.
*
* @access public
* @return string
@@ -626,7 +626,7 @@ class blockModel extends model
}
/**
* Get program progress pararms.
* Get project progress pararms.
*
* @access public
* @return string
@@ -682,12 +682,12 @@ class blockModel extends model
}
/**
* Get project params.
* Get execution params.
*
* @access public
* @return json
*/
public function getProjectParams()
public function getExecutionParams()
{
$params->type['name'] = $this->lang->block->type;
$params->type['options'] = $this->lang->block->typeList->project;
@@ -877,13 +877,13 @@ class blockModel extends model
/**
* Get program dynamic params.
* Get project dynamic params.
*
* @param string $module
* @access public
* @return string
*/
public function getProgramDynamicParams($module = '')
public function getProjectDynamicParams($module = '')
{
$params = $this->appendCountParams();
+73
View File
@@ -0,0 +1,73 @@
<?php
/**
* The project block view file of block module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package block
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php if(empty($projectStats)): ?>
<div class='empty-tip'><?php common::printLink('project', 'create', '', "<i class='icon-plus'></i> " . $lang->project->create, '', "class='btn btn-primary'")?></div>
<?php else:?>
<div class="panel-body has-table scrollbar-hover">
<table class='table table-borderless table-hover table-fixed table-fixed-head tablesorter block-projects tablesorter'>
<thead>
<tr class='text-center'>
<th class='c-name text-left'><?php echo $lang->project->name;?></th>
<th class="c-date"><?php echo $lang->project->end;?></th>
<?php if($longBlock):?>
<?php $thClass = common::checkNotCN() ? 'w-85px' : 'c-hours';?>
<th class="c-status"><?php echo $lang->statusAB;?></th>
<th class='<?php echo $thClass?>'><?php echo $lang->project->totalEstimate;?></th>
<th class="c-hours"><?php echo $lang->project->totalConsumed;?></th>
<th class="c-hours"><?php echo $lang->project->totalLeft;?></th>
<?php endif;?>
<th class="c-progress"><?php echo $lang->project->progress;?></th>
<?php if($longBlock):?>
<th><?php echo $lang->project->burn;?></th>
<?php endif;?>
</tr>
</thead>
<tbody class="text-center">
<?php $id = 0; ?>
<?php foreach($projectStats as $project):?>
<?php
$appid = isset($_GET['entry']) ? "class='app-btn text-center' data-id='{$this->get->entry}'" : "class='text-center'";
$viewLink = $this->createLink('project', 'task', 'project=' . $project->id);
?>
<tr data-url='<?php echo empty($sso) ? $viewLink : $sso . $sign . 'referer=' . base64_encode($viewLink); ?>' <?php echo $appid?>>
<td class='c-name text-left' title='<?php echo $project->name;?>'><nobr><?php echo html::a($this->createLink('project', 'task', 'project=' . $project->id), $project->name, '', "title='$project->name'");?></nobr></td>
<td class="c-date"><?php echo $project->end;?></td>
<?php if($longBlock):?>
<td class="w-70px">
<?php if(isset($project->delay)):?>
<span class="status-project status-delayed" title='<?php echo $lang->project->delayed;?>'><?php echo $lang->project->delayed;?></span>
<?php else:?>
<?php $statusName = $this->processStatus('project', $project);?>
<span class="status-project status-<?php echo $project->status?>" title='<?php echo $statusName;?>'><?php echo $statusName;?></span>
<?php endif;?>
</td>
<td class="c-hours"><?php echo $project->hours->totalEstimate;?></td>
<td class="c-hours"><?php echo $project->hours->totalConsumed;?></td>
<td class="c-hours"><?php echo $project->hours->totalLeft;?></td>
<?php endif;?>
<td class="c-progress">
<div class="progress progress-text-left">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="<?php echo $project->hours->progress;?>" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $project->hours->progress;?>%">
<span class="progress-text"><?php echo $project->hours->progress;?>%</span>
</div>
</div>
</td>
<?php if($longBlock):?>
<td id='spark-<?php echo $id++?>' class='no-padding text-left sparkline' values='<?php echo join(',', $project->burns);?>'></td>
<?php endif;?>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
<?php endif;?>
@@ -55,21 +55,9 @@ html[lang="en"] .product-info .type-info {color: #A6AAB8; text-align: center; po
.block-statistic.block-sm .nav-secondary > li.active > a.btn-view {width: auto; left: 0; right: 0;}
.block-statistic.block-sm .nav-secondary > li.active > a.btn-view > i {display: none;}
.block-statistic.block-sm .nav-secondary > li.active > a.btn-view:hover {cursor: pointer; background: rgba(0,0,0,.1)}
.block-statistic .program-info .info span+span{margin-left: 15px}
.block-statistic .project-info{margin-top: 25px}
.block-statistic .project-info .col-xs-5, .block-statistic .project-info .col-xs-7{margin-top: 8px}
.block-statistic .project-info .col-xs-5{padding-left: 0px;}
.status-count{margin:auto}
.status-count tr:first-child td:last-child{color:#000;font-weight:bold}
.block-statistic .progress-group{margin-top: 20px; margin-bottom: 10px; height: 65px;}
.block-statistic .weekly-title{font-weight: bold; font-size:14px; color: #3C4253;}
.block-statistic .weekly-small{font-size:12px; color: #838A9D;}
.block-statistic .weekly-progress {font-weight: bold; font-size:24px;}
.block-statistic .weekly-name{font-size:14px; color: #838A9D;}
.block-statistic .weekly-value{font-size:14px;}
.block-statistic .col-6 .stage{margin-left: 10px}
</style>
<script>
<?php $blockNavId = 'nav-' . uniqid(); ?>
@@ -86,17 +74,17 @@ $(function()
e.preventDefault();
});
var $programLi = $('#activeProject');
if($programLi.length)
var $projectLi = $('#activeProject');
if($projectLi.length)
{
var programLi = $programLi[0];
$(".col ul.nav").animate({scrollTop: programLi.offsetTop}, "slow");
var projectLi = $projectLi[0];
$(".col ul.nav").animate({scrollTop: projectLi.offsetTop}, "slow");
}
});
</script>
<div class="panel-body">
<div class="table-row">
<?php if(empty($programs)):?>
<?php if(empty($projects)):?>
<div class="table-empty-tip">
<p><span class="text-muted"><?php echo $lang->block->noData;?></span></p>
</div>
@@ -104,139 +92,110 @@ $(function()
<div class="col col-nav">
<ul class="nav nav-stacked nav-secondary scrollbar-hover" id='<?php echo $blockNavId;?>'>
<li class='switch-icon prev'><a><i class='icon icon-arrow-left'></i></a></li>
<?php $selected = empty($_SESSION['program']) ? key($programs) : $this->session->PRJ;?>
<?php foreach($programs as $program):?>
<li <?php if($program->id == $selected) echo "class='active' id='activeProject'";?> programID='<?php echo $program->id;?>'>
<a href="###" data-target="#tab3Content<?php echo $program->id;?>" data-toggle="tab"><?php echo $program->name;?></a>
<?php echo html::a(helper::createLink('program', 'pgmindex', "programID=$program->id"), "<i class='icon-arrow-right text-primary'></i>", '', "class='btn-view' title={$lang->program->PGMIndex}");?>
<?php $selected = empty($_SESSION['project']) ? key($projects) : $this->session->project;?>
<?php $selected = !isset($projects[$selected]) ? key($projects) : $selected;?>
<?php foreach($projects as $project):?>
<li <?php if($project->id == $selected) echo "class='active' id='activeProject'";?> projectID='<?php echo $project->id;?>'>
<a href="###" data-target="#tab3Content<?php echo $project->id;?>" data-toggle="tab" title='<?php echo $project->name;?>'><?php echo $project->name;?></a>
<?php echo html::a(helper::createLink('project', 'task', "projectID=$project->id"), "<i class='icon-arrow-right text-primary'></i>", '', "class='btn-view' title={$lang->project->task}");?>
</li>
<?php endforeach;?>
<li class='switch-icon next'><a><i class='icon icon-arrow-right'></i></a></li>
</ul>
</div>
<div class="col tab-content">
<?php foreach($programs as $program):?>
<div class="tab-pane fade<?php if($program->id == $selected) echo ' active in';?>" id="tab3Content<?php echo $program->id;?>">
<?php foreach($projects as $project):?>
<div class="tab-pane fade<?php if($project->id == $selected) echo ' active in';?>" id="tab3Content<?php echo $project->id;?>">
<div class="table-row">
<?php if($program->model == 'scrum'):?>
<div class="col-5 text-middle text-center">
<div class="progress-pie inline-block space" data-value="<?php echo $program->progress;?>" data-doughnut-size="84">
<div class="progress-pie inline-block space" data-value="<?php echo $project->progress;?>" data-doughnut-size="84">
<canvas width="120" height="120"></canvas>
<div class="progress-info">
<small><?php echo $lang->story->common . $lang->program->doneStories;?></small>
<strong><?php echo $program->doneStories;?></strong>
<small><?php echo $lang->task->statusList['done'];?></small>
<strong><?php echo $project->progress;?><small><?php echo $lang->percent;?></small></strong>
</div>
</div>
<div class="table-row text-center small text-muted with-padding">
<div class="col-4 text-bottom">
<div><?php echo $lang->program->allStories;?></div>
<div><?php echo $program->allStories;?></div>
<div><?php echo $lang->project->totalEstimate;?></div>
<div><?php echo $project->totalEstimate;?> <span class="muted"><?php echo $lang->task->hour;?></span></div>
</div>
<div class="col-4">
<span class="label label-dot label-primary"></span>
<div><?php echo $lang->program->doneStories;?></div>
<div><?php echo $program->doneStories;?></div>
<div><?php echo $lang->project->totalConsumed;?></div>
<div><?php echo $project->totalConsumed;?> <span class="muted"><?php echo $lang->task->hour;?></span></div>
</div>
<div class="col-4">
<span class="label label-dot label-pale"></span>
<div><?php echo $lang->program->leftStories;?></div>
<div><?php echo $program->leftStories;?></div>
<div><?php echo $lang->project->totalLeft;?></div>
<div><?php echo $project->totalLeft;?> <span class="muted"><?php echo $lang->task->hour;?></span></div>
</div>
</div>
</div>
<div class="col-7">
<div class="program-info">
<h4><?php echo $lang->program->allInput;?></h4>
<div class='info'>
<span><i class='icon icon-group'></i> <?php echo sprintf($lang->program->membersUnit, $program->teamCount);?></span>
<span><i class='icon icon-clock'></i> <?php echo sprintf($lang->program->hoursUnit, $program->estimate);?></span>
<span><i class='icon icon-cost'></i> <?php echo $program->budget . ' ' . zget($lang->program->unitList, $program->budgetUnit);?></span>
</div>
</div>
<div class="project-info">
<?php $i = 0;?>
<h4><?php echo $lang->program->lastIteration;?></h4>
<?php foreach($program->projects as $project):?>
<?php $i ++;?>
<?php if($i > 3) break;?>
<div class='col-xs-5'><?php echo $project->name;?></div>
<div class='col-xs-7'>
<div class='progress progress-text-left'>
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="<?php echo $project->hours->progress;?>" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $project->hours->progress;?>%">
<span class='progress-text'><?php echo $project->hours->progress . '%';?></span>
</div>
<div class="product-info">
<div class="progress-info"><i class="icon icon-check-circle text-success icon-sm"></i> <span class="text-muted"><?php echo $lang->task->yesterdayFinished;?></span> <strong><?php echo $project->yesterdayFinished;?></strong></div>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="<?php echo $project->taskProgress;?>" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $project->taskProgress;?>%">
</div>
</div>
<?php endforeach;?>
</div>
</div>
<?php else:?>
<div class="col-6">
<div class='table-row text-left weekly-row with-padding'>
<span class='weekly-title'><?php echo $lang->program->weekly;?></span>
<span class='stage text-muted'><?php echo $program->current;?></span>
</div>
<div class='progress-group col-10 center-block'>
<div class='progress-num text-center'>
<div class='weekly-title'><?php echo $lang->program->PRJProgress;?></div>
<div class='weekly-progress'><?php echo $program->progress . '%';?></div>
</div>
<div class='progress'>
<div class="progress-bar" role="progressbar" aria-valuenow="82" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $program->progress;?>%"></div>
<div class="type-info">
<div class="type-label">
<table class='status-count'>
<tr>
<td class='text-right'><?php echo $lang->task->allTasks;?> :</td>
<td class='text-left'><?php echo empty($project->totalTasks) ? 0 : html::a($this->createLink('project', 'task', "projectID={$project->id}&status=all"), $project->totalTasks);?></td>
</tr>
<tr>
<td class='text-right'><?php echo $lang->task->noFinished;?> :</td>
<td class='text-left'><?php echo empty($project->undoneTasks) ? 0 : html::a($this->createLink('project', 'task', "projectID={$project->id}&status=undone"), $project->undoneTasks);?></td>
</tr>
</table>
</div>
</div>
</div>
<div class="table-row text-center small with-padding col-10 center-block">
<div class="col-4 text-bottom">
<div class='weekly-name'><?php echo $lang->program->pv;?></div>
<div class='weekly-value'><?php echo $program->pv;?></div>
<div class="product-info">
<div class="progress-info"><i class="icon icon-check-circle text-success icon-sm"></i> <span class="text-muted"><?php echo $lang->story->released;?></span> <strong><?php echo $project->releasedStories;?></strong></div>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="<?php echo $project->storyProgress;?>" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $project->storyProgress;?>%"></div>
</div>
<div class="col-4">
<div class='weekly-name'><?php echo $lang->program->ev;?></div>
<div class='weekly-value'><?php echo $program->ev;?></div>
<div class="type-info">
<div class="type-label">
<table class='status-count'>
<tr>
<td class='text-right'><?php echo $lang->story->total;?> :</td>
<td class='text-left'><?php echo empty($project->totalStories) ? 0 : html::a($this->createLink('project', 'story', "projectID={$project->id}&orderBy=order_desc&type=all"), $project->totalStories);?></td>
</tr>
<tr>
<td class='text-right'><?php echo $lang->story->unclosed;?> :</td>
<td class='text-left'><?php echo empty($project->unclosedStories) ? 0 : html::a($this->createLink('project', 'story', "projectID={$project->id}&orderBy=order_desc&type=unclosed"), $project->unclosedStories);?></td>
</tr>
</table>
</div>
</div>
<div class="col-4">
<div class='weekly-name'><?php echo $lang->program->sv;?></div>
<div class='weekly-value'><?php echo $program->sv;?></div>
</div>
<div class="product-info">
<div class="progress-info"><i class="icon icon-check-circle text-success icon-sm"></i> <span class="text-muted"><?php echo $lang->bug->yesterdayResolved;?></span> <strong><?php echo $project->yesterdayResolved;?></strong></div>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="<?php echo $project->bugProgress;?>" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $project->bugProgress;?>%">
</div>
</div>
<div class="type-info">
<div class="type-label">
<table class='status-count'>
<tr>
<td class='text-right'><?php echo $lang->bug->allBugs;?> :</td>
<td class='text-left'><?php echo empty($project->totalBugs) ? 0 : html::a($this->createLink('project', 'bug', "projectID={$project->id}&orderBy=status,id_desc&build=0&type=all"), $project->totalBugs);?></td>
</tr>
<tr>
<td class='text-right'><?php echo $lang->bug->unResolved;?> :</td>
<td class='text-left'><?php echo empty($project->activeBugs) ? 0 : html::a($this->createLink('project', 'bug', "projectID={$project->id}&orderBy=status,id_desc&build=0&type=unresolved"), $project->activeBugs);?></td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class='col-6'>
<div class='table-row weekly-row with-padding'>
<div class='col-4 text-center'>
<span class='weekly-title'><?php echo $lang->program->allInput;?></span>
</div>
<div class='col-8'></div>
</div>
<div class='progress-group'>
<div class="table-row text-center small with-padding">
<div class="col-4 text-bottom">
<div class='weekly-name'><?php echo $lang->program->PRJPM;?></div>
<div class='weekly-value'><?php echo $program->PM ? zget($users, $program->PM) : $lang->program->emptyPM;?></div>
</div>
<div class="col-4">
<div class='weekly-name'><?php echo $lang->program->teamCount;?></div>
<div class='weekly-value'><?php echo $program->teamCount;?></div>
</div>
<div class="col-4">
<div class='weekly-name'><?php echo $lang->program->PRJBudget;?></div>
<div class='weekly-value'><?php echo $program->budget;?></div>
</div>
</div>
</div>
<div class="table-row text-center small with-padding">
<div class="col-4 text-bottom">
<div class='weekly-name'><?php echo $lang->program->ac;?></div>
<div class='weekly-value'><?php echo $program->ac;?></div>
</div>
<div class="col-4">
<div class='weekly-name'><?php echo $lang->program->cv;?></div>
<div class='weekly-value'><?php echo $program->cv;?></div>
</div>
<div>
</div>
</div>
</div>
<?php endif;?>
</div>
</div>
<?php endforeach;?>
-49
View File
@@ -1,49 +0,0 @@
<?php if(empty($programs)): ?>
<div class='empty-tip'><?php echo $lang->block->emptyTip;?></div>
<?php else:?>
<style>
.block-programs .c-pri {width: 45px;text-align: center;}
.block-programs .c-status {width: 80px;}
</style>
<div class='panel-body has-table scrollbar-hover'>
<table class='table table-borderless table-hover table-fixed table-fixed-head tablesorter block-programs <?php if(!$longBlock) echo 'block-sm';?>'>
<thead>
<tr>
<th class='c-name'><?php echo $lang->program->PGMName;?></th>
<th class='w-100px'> <?php echo $lang->program->PGMPM;?></th>
<th class='w-80px'><?php echo $lang->program->PGMStatus;?></th>
<?php if($longBlock):?>
<th class='w-80px'><?php echo $lang->program->teamCount;?></th>
<th class='w-80px'><?php echo $lang->task->consumed;?></th>
<th class='w-100px'><?php echo $lang->program->PGMBudget;?></th>
<th class='w-80px'><?php echo $lang->program->leftStories;?></th>
<th class='w-80px'><?php echo $lang->program->leftTasks;?></th>
<th class='w-80px'><?php echo $lang->program->leftBugs;?></th>
<?php endif;?>
</tr>
</thead>
<tbody>
<?php foreach($programs as $program):?>
<?php
$viewLink = $this->createLink('program', 'index', "programID={$program->id}");
?>
<tr>
<td title='<?php echo $program->name?>'><?php echo html::a($viewLink, $program->name);?></td>
<td><?php echo zget($users, $program->PM, $program->PM)?></td>
<td class='c-status'>
<span class="status-program status-<?php echo $program->status?>"><?php echo zget($lang->project->statusList, $program->status);?></span>
</td>
<?php if($longBlock):?>
<td><?php echo $program->teamCount;?></td>
<td><?php echo $program->consumed;?></td>
<td><?php echo $program->budget . ' ' . zget($lang->program->unitList, $program->budgetUnit);?></td>
<td><?php echo $program->leftStories;?></td>
<td><?php echo $program->leftTasks;?></td>
<td><?php echo $program->leftBugs;?></td>
<?php endif;?>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
<?php endif;?>
+34 -58
View File
@@ -1,72 +1,48 @@
<?php
/**
* The project block view file of block module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package block
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php if(empty($projectStats)): ?>
<div class='empty-tip'><?php common::printLink('project', 'create', '', "<i class='icon-plus'></i> " . $lang->project->create, '', "class='btn btn-primary'")?></div>
<?php if(empty($programs)): ?>
<div class='empty-tip'><?php echo $lang->block->emptyTip;?></div>
<?php else:?>
<div class="panel-body has-table scrollbar-hover">
<table class='table table-borderless table-hover table-fixed table-fixed-head tablesorter block-projects tablesorter'>
<style>
.block-programs .c-pri {width: 45px;text-align: center;}
.block-programs .c-status {width: 80px;}
</style>
<div class='panel-body has-table scrollbar-hover'>
<table class='table table-borderless table-hover table-fixed table-fixed-head tablesorter block-programs <?php if(!$longBlock) echo 'block-sm';?>'>
<thead>
<tr class='text-center'>
<th class='c-name text-left'><?php echo $lang->project->name;?></th>
<th class="c-date"><?php echo $lang->project->end;?></th>
<tr>
<th class='c-name'><?php echo $lang->program->PGMName;?></th>
<th class='w-100px'> <?php echo $lang->program->PGMPM;?></th>
<th class='w-80px'><?php echo $lang->program->PGMStatus;?></th>
<?php if($longBlock):?>
<?php $thClass = common::checkNotCN() ? 'w-85px' : 'c-hours';?>
<th class="c-status"><?php echo $lang->statusAB;?></th>
<th class='<?php echo $thClass?>'><?php echo $lang->project->totalEstimate;?></th>
<th class="c-hours"><?php echo $lang->project->totalConsumed;?></th>
<th class="c-hours"><?php echo $lang->project->totalLeft;?></th>
<?php endif;?>
<th class="c-progress"><?php echo $lang->project->progress;?></th>
<?php if($longBlock):?>
<th><?php echo $lang->project->burn;?></th>
<th class='w-80px'><?php echo $lang->program->teamCount;?></th>
<th class='w-80px'><?php echo $lang->task->consumed;?></th>
<th class='w-100px'><?php echo $lang->program->PGMBudget;?></th>
<th class='w-80px'><?php echo $lang->program->leftStories;?></th>
<th class='w-80px'><?php echo $lang->program->leftTasks;?></th>
<th class='w-80px'><?php echo $lang->program->leftBugs;?></th>
<?php endif;?>
</tr>
</thead>
<tbody class="text-center">
<?php $id = 0; ?>
<?php foreach($projectStats as $project):?>
<tbody>
<?php foreach($programs as $program):?>
<?php
$appid = isset($_GET['entry']) ? "class='app-btn text-center' data-id='{$this->get->entry}'" : "class='text-center'";
$viewLink = $this->createLink('project', 'task', 'project=' . $project->id);
$viewLink = $this->createLink('program', 'index', "programID={$program->id}");
?>
<tr data-url='<?php echo empty($sso) ? $viewLink : $sso . $sign . 'referer=' . base64_encode($viewLink); ?>' <?php echo $appid?>>
<td class='c-name text-left' title='<?php echo $project->name;?>'><nobr><?php echo html::a($this->createLink('project', 'task', 'project=' . $project->id), $project->name, '', "title='$project->name'");?></nobr></td>
<td class="c-date"><?php echo $project->end;?></td>
<?php if($longBlock):?>
<td class="w-70px">
<?php if(isset($project->delay)):?>
<span class="status-project status-delayed" title='<?php echo $lang->project->delayed;?>'><?php echo $lang->project->delayed;?></span>
<?php else:?>
<?php $statusName = $this->processStatus('project', $project);?>
<span class="status-project status-<?php echo $project->status?>" title='<?php echo $statusName;?>'><?php echo $statusName;?></span>
<?php endif;?>
</td>
<td class="c-hours"><?php echo $project->hours->totalEstimate;?></td>
<td class="c-hours"><?php echo $project->hours->totalConsumed;?></td>
<td class="c-hours"><?php echo $project->hours->totalLeft;?></td>
<?php endif;?>
<td class="c-progress">
<div class="progress progress-text-left">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="<?php echo $project->hours->progress;?>" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $project->hours->progress;?>%">
<span class="progress-text"><?php echo $project->hours->progress;?>%</span>
</div>
</div>
<tr>
<td title='<?php echo $program->name?>'><?php echo html::a($viewLink, $program->name);?></td>
<td><?php echo zget($users, $program->PM, $program->PM)?></td>
<td class='c-status'>
<span class="status-program status-<?php echo $program->status?>"><?php echo zget($lang->project->statusList, $program->status);?></span>
</td>
<?php if($longBlock):?>
<td id='spark-<?php echo $id++?>' class='no-padding text-left sparkline' values='<?php echo join(',', $project->burns);?>'></td>
<td><?php echo $program->teamCount;?></td>
<td><?php echo $program->consumed;?></td>
<td><?php echo $program->budget . ' ' . zget($lang->program->unitList, $program->budgetUnit);?></td>
<td><?php echo $program->leftStories;?></td>
<td><?php echo $program->leftTasks;?></td>
<td><?php echo $program->leftBugs;?></td>
<?php endif;?>
</tr>
<?php endforeach;?>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
+107 -66
View File
@@ -55,9 +55,21 @@ html[lang="en"] .product-info .type-info {color: #A6AAB8; text-align: center; po
.block-statistic.block-sm .nav-secondary > li.active > a.btn-view {width: auto; left: 0; right: 0;}
.block-statistic.block-sm .nav-secondary > li.active > a.btn-view > i {display: none;}
.block-statistic.block-sm .nav-secondary > li.active > a.btn-view:hover {cursor: pointer; background: rgba(0,0,0,.1)}
.block-statistic .program-info .info span+span{margin-left: 15px}
.block-statistic .project-info{margin-top: 25px}
.block-statistic .project-info .col-xs-5, .block-statistic .project-info .col-xs-7{margin-top: 8px}
.block-statistic .project-info .col-xs-5{padding-left: 0px;}
.status-count{margin:auto}
.status-count tr:first-child td:last-child{color:#000;font-weight:bold}
.block-statistic .progress-group{margin-top: 20px; margin-bottom: 10px; height: 65px;}
.block-statistic .weekly-title{font-weight: bold; font-size:14px; color: #3C4253;}
.block-statistic .weekly-small{font-size:12px; color: #838A9D;}
.block-statistic .weekly-progress {font-weight: bold; font-size:24px;}
.block-statistic .weekly-name{font-size:14px; color: #838A9D;}
.block-statistic .weekly-value{font-size:14px;}
.block-statistic .col-6 .stage{margin-left: 10px}
</style>
<script>
<?php $blockNavId = 'nav-' . uniqid(); ?>
@@ -92,12 +104,11 @@ $(function()
<div class="col col-nav">
<ul class="nav nav-stacked nav-secondary scrollbar-hover" id='<?php echo $blockNavId;?>'>
<li class='switch-icon prev'><a><i class='icon icon-arrow-left'></i></a></li>
<?php $selected = empty($_SESSION['project']) ? key($projects) : $this->session->project;?>
<?php $selected = !isset($projects[$selected]) ? key($projects) : $selected;?>
<?php $selected = key($projects);?>
<?php foreach($projects as $project):?>
<li <?php if($project->id == $selected) echo "class='active' id='activeProject'";?> projectID='<?php echo $project->id;?>'>
<a href="###" data-target="#tab3Content<?php echo $project->id;?>" data-toggle="tab" title='<?php echo $project->name;?>'><?php echo $project->name;?></a>
<?php echo html::a(helper::createLink('project', 'task', "projectID=$project->id"), "<i class='icon-arrow-right text-primary'></i>", '', "class='btn-view' title={$lang->project->task}");?>
<a href="###" data-target="#tab3Content<?php echo $project->id;?>" data-toggle="tab"><?php echo $project->name;?></a>
<?php echo html::a(helper::createLink('program', 'index', "projectID=$project->id"), "<i class='icon-arrow-right text-primary'></i>", '', "class='btn-view' title={$lang->program->PGMIndex}");?>
</li>
<?php endforeach;?>
<li class='switch-icon next'><a><i class='icon icon-arrow-right'></i></a></li>
@@ -107,95 +118,125 @@ $(function()
<?php foreach($projects as $project):?>
<div class="tab-pane fade<?php if($project->id == $selected) echo ' active in';?>" id="tab3Content<?php echo $project->id;?>">
<div class="table-row">
<?php if($project->model == 'scrum'):?>
<div class="col-5 text-middle text-center">
<div class="progress-pie inline-block space" data-value="<?php echo $project->progress;?>" data-doughnut-size="84">
<canvas width="120" height="120"></canvas>
<div class="progress-info">
<small><?php echo $lang->task->statusList['done'];?></small>
<strong><?php echo $project->progress;?><small><?php echo $lang->percent;?></small></strong>
<small><?php echo $lang->story->common . $lang->program->doneStories;?></small>
<strong><?php echo $project->doneStories;?></strong>
</div>
</div>
<div class="table-row text-center small text-muted with-padding">
<div class="col-4 text-bottom">
<div><?php echo $lang->project->totalEstimate;?></div>
<div><?php echo $project->totalEstimate;?> <span class="muted"><?php echo $lang->task->hour;?></span></div>
<div><?php echo $lang->program->allStories;?></div>
<div><?php echo $project->allStories;?></div>
</div>
<div class="col-4">
<span class="label label-dot label-primary"></span>
<div><?php echo $lang->project->totalConsumed;?></div>
<div><?php echo $project->totalConsumed;?> <span class="muted"><?php echo $lang->task->hour;?></span></div>
<div><?php echo $lang->program->doneStories;?></div>
<div><?php echo $project->doneStories;?></div>
</div>
<div class="col-4">
<span class="label label-dot label-pale"></span>
<div><?php echo $lang->project->totalLeft;?></div>
<div><?php echo $project->totalLeft;?> <span class="muted"><?php echo $lang->task->hour;?></span></div>
<div><?php echo $lang->program->leftStories;?></div>
<div><?php echo $project->leftStories;?></div>
</div>
</div>
</div>
<div class="col-7">
<div class="product-info">
<div class="progress-info"><i class="icon icon-check-circle text-success icon-sm"></i> <span class="text-muted"><?php echo $lang->task->yesterdayFinished;?></span> <strong><?php echo $project->yesterdayFinished;?></strong></div>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="<?php echo $project->taskProgress;?>" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $project->taskProgress;?>%">
</div>
</div>
<div class="type-info">
<div class="type-label">
<table class='status-count'>
<tr>
<td class='text-right'><?php echo $lang->task->allTasks;?> :</td>
<td class='text-left'><?php echo empty($project->totalTasks) ? 0 : html::a($this->createLink('project', 'task', "projectID={$project->id}&status=all"), $project->totalTasks);?></td>
</tr>
<tr>
<td class='text-right'><?php echo $lang->task->noFinished;?> :</td>
<td class='text-left'><?php echo empty($project->undoneTasks) ? 0 : html::a($this->createLink('project', 'task', "projectID={$project->id}&status=undone"), $project->undoneTasks);?></td>
</tr>
</table>
</div>
<div class="project-info">
<h4><?php echo $lang->program->allInput;?></h4>
<div class='info'>
<span><i class='icon icon-group'></i> <?php echo sprintf($lang->program->membersUnit, $project->teamCount);?></span>
<span><i class='icon icon-clock'></i> <?php echo sprintf($lang->program->hoursUnit, $project->estimate);?></span>
<span><i class='icon icon-cost'></i> <?php echo $project->budget . ' ' . zget($lang->program->unitList, $project->budgetUnit);?></span>
</div>
</div>
<div class="product-info">
<div class="progress-info"><i class="icon icon-check-circle text-success icon-sm"></i> <span class="text-muted"><?php echo $lang->story->released;?></span> <strong><?php echo $project->releasedStories;?></strong></div>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="<?php echo $project->storyProgress;?>" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $project->storyProgress;?>%"></div>
</div>
<div class="type-info">
<div class="type-label">
<table class='status-count'>
<tr>
<td class='text-right'><?php echo $lang->story->total;?> :</td>
<td class='text-left'><?php echo empty($project->totalStories) ? 0 : html::a($this->createLink('project', 'story', "projectID={$project->id}&orderBy=order_desc&type=all"), $project->totalStories);?></td>
</tr>
<tr>
<td class='text-right'><?php echo $lang->story->unclosed;?> :</td>
<td class='text-left'><?php echo empty($project->unclosedStories) ? 0 : html::a($this->createLink('project', 'story', "projectID={$project->id}&orderBy=order_desc&type=unclosed"), $project->unclosedStories);?></td>
</tr>
</table>
<div class="project-info">
<?php $i = 0;?>
<h4><?php echo $lang->program->lastIteration;?></h4>
<?php foreach($project->executions as $execution):?>
<?php $i ++;?>
<?php if($i > 3) break;?>
<div class='col-xs-5'><?php echo $execution->name;?></div>
<div class='col-xs-7'>
<div class='progress progress-text-left'>
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="<?php echo $execution->hours->progress;?>" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $execution->hours->progress;?>%">
<span class='progress-text'><?php echo $execution->hours->progress . '%';?></span>
</div>
</div>
</div>
<?php endforeach;?>
</div>
</div>
<?php else:?>
<div class="col-6">
<div class='table-row text-left weekly-row with-padding'>
<span class='weekly-title'><?php echo $lang->program->weekly;?></span>
<span class='stage text-muted'><?php echo $project->current;?></span>
</div>
<div class='progress-group col-10 center-block'>
<div class='progress-num text-center'>
<div class='weekly-title'><?php echo $lang->program->PRJProgress;?></div>
<div class='weekly-progress'><?php echo $project->progress . '%';?></div>
</div>
<div class='progress'>
<div class="progress-bar" role="progressbar" aria-valuenow="82" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $project->progress;?>%"></div>
</div>
</div>
<div class="product-info">
<div class="progress-info"><i class="icon icon-check-circle text-success icon-sm"></i> <span class="text-muted"><?php echo $lang->bug->yesterdayResolved;?></span> <strong><?php echo $project->yesterdayResolved;?></strong></div>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="<?php echo $project->bugProgress;?>" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $project->bugProgress;?>%">
</div>
<div class="table-row text-center small with-padding col-10 center-block">
<div class="col-4 text-bottom">
<div class='weekly-name'><?php echo $lang->program->pv;?></div>
<div class='weekly-value'><?php echo $project->pv;?></div>
</div>
<div class="type-info">
<div class="type-label">
<table class='status-count'>
<tr>
<td class='text-right'><?php echo $lang->bug->allBugs;?> :</td>
<td class='text-left'><?php echo empty($project->totalBugs) ? 0 : html::a($this->createLink('project', 'bug', "projectID={$project->id}&orderBy=status,id_desc&build=0&type=all"), $project->totalBugs);?></td>
</tr>
<tr>
<td class='text-right'><?php echo $lang->bug->unResolved;?> :</td>
<td class='text-left'><?php echo empty($project->activeBugs) ? 0 : html::a($this->createLink('project', 'bug', "projectID={$project->id}&orderBy=status,id_desc&build=0&type=unresolved"), $project->activeBugs);?></td>
</tr>
</table>
</div>
<div class="col-4">
<div class='weekly-name'><?php echo $lang->program->ev;?></div>
<div class='weekly-value'><?php echo $project->ev;?></div>
</div>
<div class="col-4">
<div class='weekly-name'><?php echo $lang->program->sv;?></div>
<div class='weekly-value'><?php echo $project->sv;?></div>
</div>
</div>
</div>
<div class='col-6'>
<div class='table-row weekly-row with-padding'>
<div class='col-4 text-center'>
<span class='weekly-title'><?php echo $lang->program->allInput;?></span>
</div>
<div class='col-8'></div>
</div>
<div class='progress-group'>
<div class="table-row text-center small with-padding">
<div class="col-4 text-bottom">
<div class='weekly-name'><?php echo $lang->program->PRJPM;?></div>
<div class='weekly-value'><?php echo $project->PM ? zget($users, $project->PM) : $lang->program->emptyPM;?></div>
</div>
<div class="col-4">
<div class='weekly-name'><?php echo $lang->program->teamCount;?></div>
<div class='weekly-value'><?php echo $project->teamCount;?></div>
</div>
<div class="col-4">
<div class='weekly-name'><?php echo $lang->program->PRJBudget;?></div>
<div class='weekly-value'><?php echo $project->budget;?></div>
</div>
</div>
</div>
<div class="table-row text-center small with-padding">
<div class="col-4 text-bottom">
<div class='weekly-name'><?php echo $lang->program->ac;?></div>
<div class='weekly-value'><?php echo $project->ac;?></div>
</div>
<div class="col-4">
<div class='weekly-name'><?php echo $lang->program->cv;?></div>
<div class='weekly-value'><?php echo $project->cv;?></div>
</div>
<div>
</div>
</div>
</div>
<?php endif;?>
</div>
</div>
<?php endforeach;?>
@@ -1,4 +1,4 @@
<?php if(empty($programs)): ?>
<?php if(empty($projects)): ?>
<div class='empty-tip'><?php echo $lang->block->emptyTip;?></div>
<?php else:?>
<?php
@@ -8,35 +8,35 @@ $maxConsumed = 0;
<div class='panel-body'>
<div class='table-row'>
<div class='table-col chart-titles'>
<?php foreach($programs as $program):?>
<?php foreach($projects as $project):?>
<?php
$maxTeamCount = max($maxTeamCount, $program->teamCount);
$maxConsumed = max($maxConsumed, $program->consumed);
$maxTeamCount = max($maxTeamCount, $project->teamCount);
$maxConsumed = max($maxConsumed, $project->consumed);
?>
<div class='chart-title text-ellipsis'><span><?php echo $program->name;?></span></div>
<div class='chart-title text-ellipsis'><span><?php echo $project->name;?></span></div>
<?php endforeach;?>
</div>
<div class='table-col chart-rows'>
<div class='row'>
<div class='col col-6 program-team'>
<div class='col col-6 project-team'>
<div class='chart-col-title strong'><?php echo $lang->program->teamCount;?></div>
<?php foreach($programs as $program):?>
<?php foreach($projects as $project):?>
<div class='chart-col-item'>
<div class='progress'>
<div class='progress-bar' style='width: <?php echo $maxTeamCount ? (100 * $program->teamCount / $maxTeamCount) : 0; ?>%'>
<div class='progress-text'><?php echo $program->teamCount;?></div>
<div class='progress-bar' style='width: <?php echo $maxTeamCount ? (100 * $project->teamCount / $maxTeamCount) : 0; ?>%'>
<div class='progress-text'><?php echo $project->teamCount;?></div>
</div>
</div>
</div>
<?php endforeach;?>
</div>
<div class='col col-6 program-consumed'>
<div class='col col-6 project-consumed'>
<div class='chart-col-title strong'><?php echo $lang->task->consumed;?></div>
<?php foreach($programs as $program):?>
<?php foreach($projects as $project):?>
<div class='chart-col-item'>
<div class='progress'>
<div class='progress-bar' style='width: <?php echo $maxConsumed ? (100 * $program->consumed / $maxConsumed) : 0; ?>%'>
<div class='progress-text'><?php echo $program->consumed;?></div>
<div class='progress-bar' style='width: <?php echo $maxConsumed ? (100 * $project->consumed / $maxConsumed) : 0; ?>%'>
<div class='progress-text'><?php echo $project->consumed;?></div>
</div>
</div>
</div>
@@ -46,26 +46,26 @@ $maxConsumed = 0;
</div>
</div>
<style>
.block-programteam .panel-body {margin-top: -10px}
.block-projectteam .panel-body {margin-top: -10px}
.chart-titles {width: 110px; padding-right: 10px; padding-top: 30px; position: relative; z-index: 1}
.chart-rows {position: relative; z-index: 0}
.chart-title {width: 100px; line-height: 20px; padding: 5px 0; height: 30px}
.chart-title > span {background: #fff}
.chart-col-title {line-height: 20px; margin-bottom: 10px; padding: 0 10px}
.program-team, .program-consumed {padding: 0}
.program-team {border-right: 1px solid #e5e8ec}
.program-team > .chart-col-title {text-align: right}
.project-team, .project-consumed {padding: 0}
.project-team {border-right: 1px solid #e5e8ec}
.project-team > .chart-col-title {text-align: right}
.chart-col-item {height: 30px; padding: 5px 0; position: relative}
.chart-col-text {width: 50px; position: absolute; top: 5px; line-height: 20px; left: 0}
.program-team .chart-col-item {padding-left: 50px; position: relative}
.program-team .chart-col-item:before {position: absolute; content: ' '; z-index: 0; left: -100px; top: 14px; right: 0; border-top: 1px dotted #e5e8ec}
.program-consumed .chart-col-item {padding-right: 50px}
.project-team .chart-col-item {padding-left: 50px; position: relative}
.project-team .chart-col-item:before {position: absolute; content: ' '; z-index: 0; left: -100px; top: 14px; right: 0; border-top: 1px dotted #e5e8ec}
.project-consumed .chart-col-item {padding-right: 50px}
.chart-col-item .progress {background: none; border-radius: 0; overflow: visible; margin: 6px 0 0 0; position: relative; z-index: 1}
.chart-col-item .progress > .progress-bar {border-radius: 0; position: relative; min-width: 1px}
.program-team .chart-col-item .progress > .progress-bar {float: right; background-color: #39cfff}
.project-team .chart-col-item .progress > .progress-bar {float: right; background-color: #39cfff}
.chart-col-item .progress .progress-text {position: absolute; top: -6px; color: #333; width: 50px; line-height: 20px; white-space: nowrap; overflow: visible}
.program-team .progress .progress-text {text-align: right; left: -50px; padding-right: 5px}
.program-consumed .progress .progress-text {text-align: left; right: -50px; padding-left: 5px}
.project-team .progress .progress-text {text-align: right; left: -50px; padding-right: 5px}
.project-consumed .progress .progress-text {text-align: left; right: -50px; padding-left: 5px}
</style>
</div>
<?php endif;?>
@@ -9,80 +9,80 @@
#cards .panel-actions .dropdown-menu > li > a {padding-left: 5px; text-align: left;}
#cards .panel-actions .dropdown-menu > li > a > i {opacity: .5; display: inline-block; margin-right: 4px; width: 18px; text-align: center;}
#cards .panel-actions .dropdown-menu > li > a:hover > i {opacity: 1;}
#cards .program-type-label {padding: 1px 2px;}
#cards .program-name {font-size: 16px; font-weight: normal; display: inline-block; max-width: 75%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle;}
#cards .program-infos {font-size: 12px;}
#cards .program-infos > span {display: inline-block; line-height: 12px;}
#cards .program-infos > span > .icon {font-size: 12px; display: inline-block; position: relative; top: -1px}
#cards .program-infos > span + span {margin-left: 10px;}
#cards .program-detail {position: absolute; bottom: 16px; left: 16px; right: 16px; font-size: 12px;}
#cards .program-detail > p {margin-bottom: 8px;}
#cards .program-detail .progress {height: 4px;}
#cards .program-detail .progress-text-left .progress-text {width: 50px; left: -50px;}
#cards .project-type-label {padding: 1px 2px;}
#cards .project-name {font-size: 16px; font-weight: normal; display: inline-block; max-width: 75%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle;}
#cards .project-infos {font-size: 12px;}
#cards .project-infos > span {display: inline-block; line-height: 12px;}
#cards .project-infos > span > .icon {font-size: 12px; display: inline-block; position: relative; top: -1px}
#cards .project-infos > span + span {margin-left: 10px;}
#cards .project-detail {position: absolute; bottom: 16px; left: 16px; right: 16px; font-size: 12px;}
#cards .project-detail > p {margin-bottom: 8px;}
#cards .project-detail .progress {height: 4px;}
#cards .project-detail .progress-text-left .progress-text {width: 50px; left: -50px;}
#cards .panel-heading {cursor: pointer;}
#cards .program-stages-container {margin: 0 -16px -16px -16px; padding: 0 4px; height: 46px; overflow-x: auto; position: relative;}
#cards .program-stages:after {content: ' '; width: 30px; display: block; right: -16px; top: 16px; bottom: -6px; z-index: 1; background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%); position: absolute;}
#cards .program-stages-row {position: relative; height: 30px; z-index: 0;}
#cards .program-stage-item {white-space: nowrap; position: absolute; top: 0; min-width: 48px; padding-top: 13px; color: #838A9D;}
#cards .program-stage-item > div {white-space: nowrap; overflow: visible; text-align: center; text-overflow: ellipsis;}
#cards .program-stage-item:before {content: ' '; display: block; width: 8px; height: 8px; border-radius: 50%; background: #D1D1D1; position: absolute; left: 50%; margin-left: -4px; top: 0; z-index: 1;}
#cards .program-stage-item + .program-stage-item:after {content: ' '; display: block; left: -50%; right: 50%; height: 2px; background-color: #D1D1D1; top: 3px; position: absolute; z-index: 0;}
#cards .program-stage-item.is-going {color: #333;}
#cards .program-stage-item.is-going::before {background-color: #0C64EB;}
.block-recentprogram .panel-body{padding: 0;}
#cards .project-stages-container {margin: 0 -16px -16px -16px; padding: 0 4px; height: 46px; overflow-x: auto; position: relative;}
#cards .project-stages:after {content: ' '; width: 30px; display: block; right: -16px; top: 16px; bottom: -6px; z-index: 1; background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%); position: absolute;}
#cards .project-stages-row {position: relative; height: 30px; z-index: 0;}
#cards .project-stage-item {white-space: nowrap; position: absolute; top: 0; min-width: 48px; padding-top: 13px; color: #838A9D;}
#cards .project-stage-item > div {white-space: nowrap; overflow: visible; text-align: center; text-overflow: ellipsis;}
#cards .project-stage-item:before {content: ' '; display: block; width: 8px; height: 8px; border-radius: 50%; background: #D1D1D1; position: absolute; left: 50%; margin-left: -4px; top: 0; z-index: 1;}
#cards .project-stage-item + .project-stage-item:after {content: ' '; display: block; left: -50%; right: 50%; height: 2px; background-color: #D1D1D1; top: 3px; position: absolute; z-index: 0;}
#cards .project-stage-item.is-going {color: #333;}
#cards .project-stage-item.is-going::before {background-color: #0C64EB;}
.block-recentproject .panel-body{padding: 0;}
</style>
<div class="panel-body">
<div class='row' id='cards'>
<?php foreach ($programs as $programID => $program):?>
<div class='col' data-id='<?php echo $programID?>'>
<div class='panel' data-url='<?php echo $this->createLink('program', 'index', "programID=$program->id");?>'>
<?php foreach ($projects as $projectID => $project):?>
<div class='col' data-id='<?php echo $projectID?>'>
<div class='panel' data-url='<?php echo $this->createLink('project', 'index', "projectID=$project->id");?>'>
<div class='panel-heading'>
<?php $parentName = $program->parentName ? $program->parentName . '/' : '';?>
<strong class='program-name' title='<?php echo $parentName . $program->name;?>'> <?php echo html::a($this->createLink('program', 'index', "programID=$program->id", '', '', $program->id), $parentName . $program->name);?> </strong>
<?php if($program->model === 'waterfall'): ?>
<span class='program-type-label label label-warning label-outline'><?php echo $lang->program->waterfall; ?></span>
<?php $parentName = $project->parentName ? $project->parentName . '/' : '';?>
<strong class='project-name' title='<?php echo $parentName . $project->name;?>'> <?php echo html::a($this->createLink('project', 'index', "projectID=$project->id", '', '', $project->id), $parentName . $project->name);?> </strong>
<?php if($project->model === 'waterfall'): ?>
<span class='project-type-label label label-warning label-outline'><?php echo $lang->program->waterfall; ?></span>
<?php else: ?>
<span class='program-type-label label label-info label-outline'><?php echo $lang->program->scrum; ?></span>
<span class='project-type-label label label-info label-outline'><?php echo $lang->program->scrum; ?></span>
<?php endif; ?>
<nav class='panel-actions nav nav-default'>
<li class='dropdown'>
<a href='javascript:;' data-toggle='dropdown' class='panel-action'><i class='icon icon-ellipsis-v'></i></a>
<ul class='dropdown-menu pull-right'>
<li><?php common::printIcon('program', 'PRJGroup', "programID=$program->id", $program, 'button', 'group');?></li>
<li><?php common::printIcon('program', 'PRJManageMembers', "programID=$program->id", $program, 'button', 'persons');?></li>
<li><?php common::printicon('program', 'PRJActivate', "programid=$program->id", $program, 'button', '', '', 'iframe', true);?></li>
<li><?php common::printIcon('program', 'PRJEdit', "programID=$program->id", $program, 'button', ' icon-edit');?></li>
<li><?php common::printIcon('program', 'PRJStart', "programID=$program->id", $program, 'button', ' icon-play', '', 'iframe', true);?></li>
<li><?php common::printIcon('program', 'PRJSuspend', "programID=$program->id", $program, 'button', ' icon-pause', '', 'iframe', true);?></li>
<li><?php common::printIcon('program', 'PRJClose', "programID=$program->id", $program, 'button', ' icon-off', '', 'iframe', true);?></li>
<li><?php common::printIcon('program', 'PRJDelete', "programID=$program->id", $program, 'button', ' icon-trash', 'hiddenwin');?></li>
<li><?php common::printIcon('program', 'PRJGroup', "projectID=$project->id", $project, 'button', 'group');?></li>
<li><?php common::printIcon('program', 'PRJManageMembers', "projectID=$project->id", $project, 'button', 'persons');?></li>
<li><?php common::printicon('program', 'PRJActivate', "projectid=$project->id", $project, 'button', '', '', 'iframe', true);?></li>
<li><?php common::printIcon('program', 'PRJEdit', "projectID=$project->id", $project, 'button', ' icon-edit');?></li>
<li><?php common::printIcon('program', 'PRJStart', "projectID=$project->id", $project, 'button', ' icon-play', '', 'iframe', true);?></li>
<li><?php common::printIcon('program', 'PRJSuspend', "projectID=$project->id", $project, 'button', ' icon-pause', '', 'iframe', true);?></li>
<li><?php common::printIcon('program', 'PRJClose', "projectID=$project->id", $project, 'button', ' icon-off', '', 'iframe', true);?></li>
<li><?php common::printIcon('program', 'PRJDelete', "projectID=$project->id", $project, 'button', ' icon-trash', 'hiddenwin');?></li>
</ul>
</li>
</nav>
</div>
<div class='panel-body'>
<div class='program-infos'>
<span><i class='icon icon-group'></i> <?php printf($lang->program->membersUnit, $program->teamCount); ?></span>
<span><i class='icon icon-clock'></i> <?php printf($lang->program->hoursUnit, $program->estimate); ?></span>
<span><i class='icon icon-cost'></i> <?php echo $program->budget . '' . zget($lang->program->unitList, $program->budgetUnit);?></span>
<div class='project-infos'>
<span><i class='icon icon-group'></i> <?php printf($lang->program->membersUnit, $project->teamCount); ?></span>
<span><i class='icon icon-clock'></i> <?php printf($lang->program->hoursUnit, $project->estimate); ?></span>
<span><i class='icon icon-cost'></i> <?php echo $project->budget . '' . zget($lang->program->unitList, $project->budgetUnit);?></span>
</div>
<?php if($program->model === 'waterfall'): ?>
<div class='program-detail program-stages'>
<?php if($project->model === 'waterfall'): ?>
<div class='project-detail project-stages'>
<p class='text-muted'><?php echo $lang->program->ongoingStage;?></p>
<?php
$programProjects = array();
foreach($program->projects as $project)
$projectProjects = array();
foreach($project->executions as $project)
{
if($project->grade == 1) $programProjects[] = $project;
if($project->grade == 1) $projectProjects[] = $project;
}
?>
<?php if(empty($programProjects)): ?>
<div class='label label-outline'><?php echo zget($lang->project->statusList, $program->status);?></div>
<?php if(empty($projectProjects)): ?>
<div class='label label-outline'><?php echo zget($lang->project->statusList, $project->status);?></div>
<?php else: ?>
<div class='program-stages-container scrollbar-hover'>
<div class='program-stages-row'>
<?php foreach ($programProjects as $project): ?>
<div class='program-stage-item is-<?php echo $project->status;?><?php if($project->status !== 'wait') echo ' is-going'; ?>'>
<div class='project-stages-container scrollbar-hover'>
<div class='project-stages-row'>
<?php foreach ($projectProjects as $project): ?>
<div class='project-stage-item is-<?php echo $project->status;?><?php if($project->status !== 'wait') echo ' is-going'; ?>'>
<div><?php echo $project->name; ?></div>
</div>
<?php endforeach; ?>
@@ -91,8 +91,8 @@
<?php endif; ?>
</div>
<?php else: ?>
<?php $project = empty($program->projects) ? '' : end($program->projects);?>
<div class='program-detail program-iteration'>
<?php $project = empty($project->executions ) ? '' : end($project->executions);?>
<div class='project-detail project-iteration'>
<p class='text-muted'><?php echo $lang->program->lastIteration; ?></p>
<?php if($project):?>
<div class='row'>
@@ -116,7 +116,7 @@
</div>
<script>
/* Auto resize stages */
$('.block-recentprogram #cards .program-stages-container').each(function()
$('.block-recentproject #cards .project-stages-container').each(function()
{
var $container = $(this);
var $row = $container.children();
+5 -5
View File
@@ -158,17 +158,17 @@ class docModel extends model
elseif($type == 'all')
{
/* If extra have unclosedProject then ignore unclosed project libs. */
$status = (strpos($extra, 'unclosedProject') !== false) ? 'undone' : 'all';
$projects = $this->loadModel('project')->getProjectIDByProgram($projectID, $status);
$products = $this->loadModel('product')->getProductIDByProject($projectID, false);
$status = (strpos($extra, 'unclosedProject') !== false) ? 'undone' : 'all';
$executionIdList = $this->loadModel('project')->getExecutionIdList($projectID, $status);
$productIdList = $this->loadModel('product')->getProductIDByProject($projectID, false);
$stmt = $this->dao->select('*')->from(TABLE_DOCLIB)
->where('deleted')->eq(0)
->andWhere()
->markLeft(1)
->where('`type`')->eq('custom')
->orWhere('project')->in($projects)
->orWhere('product')->in($products)
->orWhere('project')->in($executionIdList)
->orWhere('product')->in($productIdList)
->markRight(1)
->orderBy('id_desc')
->query();
+235 -235
View File
@@ -1,155 +1,6 @@
<?php
class programModel extends model
{
/**
* Get program overview for block.
*
* @param varchar $queryType byId|byStatus
* @param varchar|int $param
* @param varchar $orderBy
* @param int $limit
* @access public
* @return void
*/
public function getProgramOverview($queryType = 'byStatus', $param = 'all', $orderBy = 'id_desc', $limit = 15)
{
$queryType = strtolower($queryType);
$programs = $this->dao->select('*')->from(TABLE_PROGRAM)
->where('type')->eq('project')
->andWhere('deleted')->eq(0)
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->programs)->fi()
->beginIF($queryType == 'bystatus' and $param != 'all')->andWhere('status')->eq($param)->fi()
->beginIF($queryType == 'byid')->andWhere('id')->eq($param)->fi()
->orderBy($orderBy)
->limit($limit)
->fetchAll('id');
if(empty($programs)) return array();
$programIdList = array_keys($programs);
$hours = $this->dao->select('PRJ,
cast(sum(consumed) as decimal(10,2)) as consumed,
cast(sum(estimate) as decimal(10,2)) as estimate')
->from(TABLE_TASK)
->where('PRJ')->in($programIdList)
->andWhere('deleted')->eq(0)
->andWhere('parent')->lt(1)
->groupBy('PRJ')
->fetchAll('PRJ');
$teams = $this->dao->select('root, count(*) as count')->from(TABLE_TEAM)
->where('root')->in($programIdList)
->groupBy('root')
->fetchAll('root');
$leftTasks = $this->dao->select('PRJ, count(*) as leftTasks')->from(TABLE_TASK)
->where('PRJ')->in($programIdList)
->andWhere('deleted')->eq(0)
->andWhere('status')->in('wait,doing,pause')
->groupBy('PRJ')
->fetchAll('PRJ');
$allStories = $this->dao->select('PRJ, count(*) as allStories')->from(TABLE_STORY)
->where('PRJ')->in($programIdList)
->andWhere('deleted')->eq(0)
->andWhere('status')->ne('draft')
->groupBy('PRJ')
->fetchAll('PRJ');
$doneStories = $this->dao->select('PRJ, count(*) as doneStories')->from(TABLE_STORY)
->where('PRJ')->in($programIdList)
->andWhere('deleted')->eq(0)
->andWhere('status')->eq('closed')
->andWhere('closedReason')->eq('done')
->groupBy('PRJ')
->fetchAll('PRJ');
$leftStories = $this->dao->select('PRJ, count(*) as leftStories')->from(TABLE_STORY)
->where('PRJ')->in($programIdList)
->andWhere('deleted')->eq(0)
->andWhere('status')->eq('active')
->groupBy('PRJ')
->fetchAll('PRJ');
$leftBugs = $this->dao->select('PRJ, count(*) as leftBugs')->from(TABLE_BUG)
->where('PRJ')->in($programIdList)
->andWhere('deleted')->eq(0)
->andWhere('status')->eq('active')
->groupBy('PRJ')
->fetchAll('PRJ');
$allBugs = $this->dao->select('PRJ, count(*) as allBugs')->from(TABLE_BUG)
->where('PRJ')->in($programIdList)
->andWhere('deleted')->eq(0)
->groupBy('PRJ')
->fetchAll('PRJ');
$doneBugs = $this->dao->select('PRJ, count(*) as doneBugs')->from(TABLE_BUG)
->where('PRJ')->in($programIdList)
->andWhere('deleted')->eq(0)
->andWhere('status')->eq('resolved')
->groupBy('PRJ')
->fetchAll('PRJ');
foreach($programs as $programID => $program)
{
$program->teamCount = isset($teams[$programID]) ? $teams[$programID]->count : 0;
$program->consumed = isset($hours[$programID]) ? $hours[$programID]->consumed : 0;
$program->estimate = isset($hours[$programID]) ? $hours[$programID]->estimate : 0;
$program->leftTasks = isset($leftTasks[$programID]) ? $leftTasks[$programID]->leftTasks : 0;
$program->allStories = isset($allStories[$programID]) ? $allStories[$programID]->allStories : 0;
$program->doneStories = isset($doneStories[$programID]) ? $doneStories[$programID]->doneStories : 0;
$program->leftStories = isset($leftStories[$programID]) ? $leftStories[$programID]->leftStories : 0;
$program->leftBugs = isset($leftBugs[$programID]) ? $leftBugs[$programID]->leftBugs : 0;
$program->allBugs = isset($allBugs[$programID]) ? $allBugs[$programID]->allBugs : 0;
$program->doneBugs = isset($doneBugs[$programID]) ? $doneBugs[$programID]->doneBugs : 0;
}
return $programs;
}
/**
* Get program stats.
*
* @param string $status
* @param int $itemCounts
* @param string $orderBy
* @param int $pager
* @access public
* @return void
*/
public function getProgramStats($status = 'undone', $itemCounts = 30, $orderBy = 'order_desc', $pager = null)
{
/* Init vars. */
$this->loadModel('project');
$programs = $this->getPRJList(0, $status, 0, $orderBy, $pager);
if(empty($programs)) return array();
$programIdList = array_keys($programs);
$teams = $this->dao->select('root, count(*) as count')->from(TABLE_TEAM)
->where('root')->in($programIdList)
->groupBy('root')
->fetchAll('root');
$estimates = $this->dao->select('PRJ, sum(estimate) as estimate')->from(TABLE_TASK)
->where('PRJ')->in($programIdList)
->andWhere('deleted')->eq(0)
->andWhere('parent')->lt(1)
->groupBy('PRJ')
->fetchAll('PRJ');
foreach($programs as $programID => $program)
{
$orderBy = $program->model == 'waterfall' ? 'id_asc' : 'id_desc';
$program->projects = $this->project->getProjectStats($status, 0, 0, $itemCounts, $orderBy, '', $programID);
$program->teamCount = isset($teams[$programID]) ? $teams[$programID]->count : 0;
$program->estimate = isset($estimates[$programID]) ? $estimates[$programID]->estimate : 0;
$program->parentName = $this->project->getProjectParentName($program->parent);
}
return $programs;
}
/**
* Get program pairs.
*
@@ -931,6 +782,241 @@ class programModel extends model
return $project;
}
/**
* Get project info.
*
* @param string $status
* @param int $itemCounts
* @param string $orderBy
* @param int $pager
* @access public
* @return void
*/
public function getPRJInfo($status = 'undone', $itemCounts = 30, $orderBy = 'order_desc', $pager = null)
{
/* Init vars. */
$this->loadModel('project');
$projects = $this->getPRJList(0, $status, 0, $orderBy, $pager);
if(empty($projects)) return array();
$projectIdList = array_keys($projects);
$teams = $this->dao->select('root, count(*) as count')->from(TABLE_TEAM)
->where('root')->in($projectIdList)
->groupBy('root')
->fetchAll('root');
$estimates = $this->dao->select('PRJ, sum(estimate) as estimate')->from(TABLE_TASK)
->where('PRJ')->in($projectIdList)
->andWhere('deleted')->eq(0)
->andWhere('parent')->lt(1)
->groupBy('PRJ')
->fetchAll('PRJ');
foreach($projects as $projectID => $project)
{
$orderBy = $project->model == 'waterfall' ? 'id_asc' : 'id_desc';
$project->executions = $this->project->getExecutionStats($projectID, $status, 0, 0, $itemCounts, $orderBy);
$project->teamCount = isset($teams[$projectID]) ? $teams[$projectID]->count : 0;
$project->estimate = isset($estimates[$projectID]) ? $estimates[$projectID]->estimate : 0;
$project->parentName = $this->project->getProjectParentName($project->parent);
}
return $projects;
}
/**
* Get project overview for block.
*
* @param varchar $queryType byId|byStatus
* @param varchar|int $param
* @param varchar $orderBy
* @param int $limit
* @access public
* @return void
*/
public function getPRJOverview($queryType = 'byStatus', $param = 'all', $orderBy = 'id_desc', $limit = 15)
{
$queryType = strtolower($queryType);
$projects = $this->dao->select('*')->from(TABLE_PROJECT)
->where('type')->eq('project')
->andWhere('deleted')->eq(0)
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->projects)->fi()
->beginIF($queryType == 'bystatus' and $param != 'all')->andWhere('status')->eq($param)->fi()
->beginIF($queryType == 'byid')->andWhere('id')->eq($param)->fi()
->orderBy($orderBy)
->limit($limit)
->fetchAll('id');
if(empty($projects)) return array();
$projectIdList = array_keys($projects);
$hours = $this->dao->select('PRJ,
cast(sum(consumed) as decimal(10,2)) as consumed,
cast(sum(estimate) as decimal(10,2)) as estimate')
->from(TABLE_TASK)
->where('PRJ')->in($projectIdList)
->andWhere('deleted')->eq(0)
->andWhere('parent')->lt(1)
->groupBy('PRJ')
->fetchAll('PRJ');
$teams = $this->dao->select('root, count(*) as count')->from(TABLE_TEAM)
->where('root')->in($projectIdList)
->groupBy('root')
->fetchAll('root');
$leftTasks = $this->dao->select('PRJ, count(*) as leftTasks')->from(TABLE_TASK)
->where('PRJ')->in($projectIdList)
->andWhere('deleted')->eq(0)
->andWhere('status')->in('wait,doing,pause')
->groupBy('PRJ')
->fetchAll('PRJ');
$allStories = $this->dao->select('PRJ, count(*) as allStories')->from(TABLE_STORY)
->where('PRJ')->in($projectIdList)
->andWhere('deleted')->eq(0)
->andWhere('status')->ne('draft')
->groupBy('PRJ')
->fetchAll('PRJ');
$doneStories = $this->dao->select('PRJ, count(*) as doneStories')->from(TABLE_STORY)
->where('PRJ')->in($projectIdList)
->andWhere('deleted')->eq(0)
->andWhere('status')->eq('closed')
->andWhere('closedReason')->eq('done')
->groupBy('PRJ')
->fetchAll('PRJ');
$leftStories = $this->dao->select('PRJ, count(*) as leftStories')->from(TABLE_STORY)
->where('PRJ')->in($projectIdList)
->andWhere('deleted')->eq(0)
->andWhere('status')->eq('active')
->groupBy('PRJ')
->fetchAll('PRJ');
$leftBugs = $this->dao->select('PRJ, count(*) as leftBugs')->from(TABLE_BUG)
->where('PRJ')->in($projectIdList)
->andWhere('deleted')->eq(0)
->andWhere('status')->eq('active')
->groupBy('PRJ')
->fetchAll('PRJ');
$allBugs = $this->dao->select('PRJ, count(*) as allBugs')->from(TABLE_BUG)
->where('PRJ')->in($projectIdList)
->andWhere('deleted')->eq(0)
->groupBy('PRJ')
->fetchAll('PRJ');
$doneBugs = $this->dao->select('PRJ, count(*) as doneBugs')->from(TABLE_BUG)
->where('PRJ')->in($projectIdList)
->andWhere('deleted')->eq(0)
->andWhere('status')->eq('resolved')
->groupBy('PRJ')
->fetchAll('PRJ');
foreach($projects as $projectID => $project)
{
$project->teamCount = isset($teams[$projectID]) ? $teams[$projectID]->count : 0;
$project->consumed = isset($hours[$projectID]) ? $hours[$projectID]->consumed : 0;
$project->estimate = isset($hours[$projectID]) ? $hours[$projectID]->estimate : 0;
$project->leftTasks = isset($leftTasks[$projectID]) ? $leftTasks[$projectID]->leftTasks : 0;
$project->allStories = isset($allStories[$projectID]) ? $allStories[$projectID]->allStories : 0;
$project->doneStories = isset($doneStories[$projectID]) ? $doneStories[$projectID]->doneStories : 0;
$project->leftStories = isset($leftStories[$projectID]) ? $leftStories[$projectID]->leftStories : 0;
$project->leftBugs = isset($leftBugs[$projectID]) ? $leftBugs[$projectID]->leftBugs : 0;
$project->allBugs = isset($allBugs[$projectID]) ? $allBugs[$projectID]->allBugs : 0;
$project->doneBugs = isset($doneBugs[$projectID]) ? $doneBugs[$projectID]->doneBugs : 0;
}
return $projects;
}
/**
* Get project stats.
*
* @param int $programID
* @param string $browseType
* @param string $queryID
* @param string $orderBy
* @param object $pager
* @param int $programTitle
* @param int $PRJMine
* @access public
* @return void
*/
public function getPRJStats($programID = 0, $browseType = 'undone', $queryID = 0, $orderBy = 'id_desc', $pager = null, $programTitle = 0, $PRJMine = 0)
{
/* Init vars. */
$projects = $this->getPRJList($programID, $browseType, $queryID, $orderBy, $pager, $programTitle, $PRJMine);
if(empty($projects)) return array();
$projectKeys = array_keys($projects);
$stats = array();
$hours = array();
$emptyHour = array('totalEstimate' => 0, 'totalConsumed' => 0, 'totalLeft' => 0, 'progress' => 0);
/* Get all tasks and compute totalEstimate, totalConsumed, totalLeft, progress according to them. */
$tasks = $this->dao->select('id, PRJ, estimate, consumed, `left`, status, closedReason')
->from(TABLE_TASK)
->where('PRJ')->in($projectKeys)
->andWhere('parent')->lt(1)
->andWhere('deleted')->eq(0)
->fetchGroup('PRJ', 'id');
/* Compute totalEstimate, totalConsumed, totalLeft. */
foreach($tasks as $projectID => $projectTasks)
{
$hour = (object)$emptyHour;
foreach($projectTasks as $task)
{
if($task->status != 'cancel')
{
$hour->totalEstimate += $task->estimate;
$hour->totalConsumed += $task->consumed;
}
if($task->status != 'cancel' and $task->status != 'closed') $hour->totalLeft += $task->left;
}
$hours[$projectID] = $hour;
}
/* Compute totalReal and progress. */
foreach($hours as $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, 3) * 100 : 0;
}
/* Get the number of project teams. */
$teams = $this->dao->select('root,count(*) as teams')->from(TABLE_TEAM)
->where('root')->in($projectKeys)
->andWhere('type')->eq('project')
->groupBy('root')
->fetchAll('root');
/* Process projects. */
foreach($projects as $key => $project)
{
if($project->end == '0000-00-00') $project->end = '';
/* Judge whether the project is delayed. */
if($project->status != 'done' and $project->status != 'closed' and $project->status != 'suspended')
{
$delay = helper::diffDate(helper::today(), $project->end);
if($delay > 0) $project->delay = $delay;
}
/* Process the hours. */
$project->hours = isset($hours[$project->id]) ? $hours[$project->id] : (object)$emptyHour;
$project->teamCount = isset($teams[$project->id]) ? $teams[$project->id]->teams : 0;
$stats[] = $project;
}
return $stats;
}
/**
* Get the top program which the project belongs to.
*
@@ -1277,92 +1363,6 @@ class programModel extends model
}
}
/**
* Get project stats.
*
* @param int $programID
* @param string $browseType
* @param string $queryID
* @param string $orderBy
* @param object $pager
* @param int $programTitle
* @param int $PRJMine
* @access public
* @return void
*/
public function getPRJStats($programID = 0, $browseType = 'undone', $queryID = 0, $orderBy = 'id_desc', $pager = null, $programTitle = 0, $PRJMine = 0)
{
/* Init vars. */
$projects = $this->getPRJList($programID, $browseType, $queryID, $orderBy, $pager, $programTitle, $PRJMine);
if(empty($projects)) return array();
$projectKeys = array_keys($projects);
$stats = array();
$hours = array();
$emptyHour = array('totalEstimate' => 0, 'totalConsumed' => 0, 'totalLeft' => 0, 'progress' => 0);
/* Get all tasks and compute totalEstimate, totalConsumed, totalLeft, progress according to them. */
$tasks = $this->dao->select('id, PRJ, estimate, consumed, `left`, status, closedReason')
->from(TABLE_TASK)
->where('PRJ')->in($projectKeys)
->andWhere('parent')->lt(1)
->andWhere('deleted')->eq(0)
->fetchGroup('PRJ', 'id');
/* Compute totalEstimate, totalConsumed, totalLeft. */
foreach($tasks as $projectID => $projectTasks)
{
$hour = (object)$emptyHour;
foreach($projectTasks as $task)
{
if($task->status != 'cancel')
{
$hour->totalEstimate += $task->estimate;
$hour->totalConsumed += $task->consumed;
}
if($task->status != 'cancel' and $task->status != 'closed') $hour->totalLeft += $task->left;
}
$hours[$projectID] = $hour;
}
/* Compute totalReal and progress. */
foreach($hours as $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, 3) * 100 : 0;
}
/* Get the number of project teams. */
$teams = $this->dao->select('root,count(*) as teams')->from(TABLE_TEAM)
->where('root')->in($projectKeys)
->andWhere('type')->eq('project')
->groupBy('root')
->fetchAll('root');
/* Process projects. */
foreach($projects as $key => $project)
{
if($project->end == '0000-00-00') $project->end = '';
/* Judge whether the project is delayed. */
if($project->status != 'done' and $project->status != 'closed' and $project->status != 'suspended')
{
$delay = helper::diffDate(helper::today(), $project->end);
if($delay > 0) $project->delay = $delay;
}
/* Process the hours. */
$project->hours = isset($hours[$project->id]) ? $hours[$project->id] : (object)$emptyHour;
$project->teamCount = isset($teams[$project->id]) ? $teams[$project->id]->teams : 0;
$stats[] = $project;
}
return $stats;
}
/**
* Print datatable cell.
*
+51 -47
View File
@@ -787,7 +787,7 @@ class projectModel extends model
*/
public function getExecutionList($projectID = 0, $type = 'all', $status = 'all', $limit = 0, $productID = 0, $branch = 0)
{
if($status == 'involved') return $this->getInvolvedList($status, $limit, $productID, $branch);
if($status == 'involved') return $this->getInvolvedList($projectID, $status, $limit, $productID, $branch);
if($productID != 0)
{
@@ -810,8 +810,8 @@ class projectModel extends model
{
return $this->dao->select('*, IF(INSTR(" done,closed", status) < 2, 0, 1) AS isDone')->from(TABLE_PROJECT)
->where('deleted')->eq(0)
->beginIF($type == 'all')->andWhere('t2.type')->in('sprint,stage,kanban')->fi()
->beginIF($type != 'all')->andWhere('t2.type')->eq($type)->fi()
->beginIF($type == 'all')->andWhere('type')->in('sprint,stage,kanban')->fi()
->beginIF($type != 'all')->andWhere('type')->eq($type)->fi()
->beginIF($projectID)->andWhere('project')->eq($projectID)->fi()
->beginIF($status == 'undone')->andWhere('status')->notIN('done,closed')->fi()
->beginIF($status != 'all' and $status != 'undone')->andWhere('status')->in($status)->fi()
@@ -825,6 +825,7 @@ class projectModel extends model
/**
* Get project lists.
*
* @param int $projectID
* @param string $status involved
* @param int $limit
* @param int $productID
@@ -832,7 +833,7 @@ class projectModel extends model
* @access public
* @return array
*/
public function getInvolvedList($status = 'involved', $limit = 0, $productID = 0, $branch = 0)
public function getInvolvedList($projectID = 0, $status = 'involved', $limit = 0, $productID = 0, $branch = 0)
{
if($productID != 0)
{
@@ -846,7 +847,8 @@ class projectModel extends model
->andWhere('t2.openedBy', true)->eq($this->app->user->account)
->orWhere('t3.account')->eq($this->app->user->account)
->markRight(1)
->andWhere('t3.type')->eq('project')
->andWhere('t3.type')->in('sprint,stage,kanban')
->beginIF($projectID)->andWhere('t3.project')->eq($projectID)->fi()
->orderBy('order_desc')
->beginIF($limit)->limit($limit)->fi()
->fetchAll('id');
@@ -860,7 +862,8 @@ class projectModel extends model
->andWhere('t1.openedBy', true)->eq($this->app->user->account)
->orWhere('t2.account')->eq($this->app->user->account)
->markRight(1)
->andWhere('t2.type')->eq('project')
->andWhere('t1.type')->in('sprint,stage,kanban')
->beginIF($projectID)->andWhere('t1.project')->eq($projectID)->fi()
->orderBy('t1.order_desc')
->beginIF($limit)->limit($limit)->fi()
->fetchAll('id');
@@ -954,8 +957,9 @@ class projectModel extends model
}
/**
* Get project stats.
* Get execution stats.
*
* @param int $projectID
* @param string $status
* @param int $productID
* @param int $itemCounts
@@ -964,51 +968,51 @@ class projectModel extends model
* @access public
* @return void
*/
public function getProjectStats($status = 'undone', $productID = 0, $branch = 0, $itemCounts = 30, $orderBy = 'order_desc', $pager = null, $programID = 0)
public function getExecutionStats($projectID = 0, $status = 'undone', $productID = 0, $branch = 0, $itemCounts = 30, $orderBy = 'order_desc', $pager = null)
{
/* Init vars. */
$projects = $this->getList($status, 0, $productID, $branch, $programID);
$projects = $this->dao->select('*')->from(TABLE_PROJECT)
->where('id')->in(array_keys($projects))
$executions = $this->getExecutionList($projectID, $status, 0, $productID, $branch);
$executions = $this->dao->select('*')->from(TABLE_EXECUTION)
->where('id')->in(array_keys($executions))
->andWhere('grade')->eq(1)
->andWhere('deleted')->eq('0')
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
if(empty($projects)) return array();
if(empty($executions)) return array();
/* In case of a waterfall model, obtain sub-stage data. */
$PRJData = $this->getById($this->session->PRJ);
if($PRJData and $PRJData->model == 'waterfall')
$project = $this->loadModel('program')->getPRJById($this->session->PRJ);
if($project and $project->model == 'waterfall')
{
$childrens = $this->dao->select('*')->from(TABLE_PROJECT)
->where('parent')->in(array_keys($projects))
->where('parent')->in(array_keys($executions))
->andWhere('grade')->eq(2)
->andWhere('deleted')->eq('0')
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
$projects = $projects + $childrens;
$executions += $childrens;
}
$projectKeys = array_keys($projects);
$hours = array();
$emptyHour = array('totalEstimate' => 0, 'totalConsumed' => 0, 'totalLeft' => 0, 'progress' => 0);
/* Get all tasks and compute totalEstimate, totalConsumed, totalLeft, progress according to them. */
$tasks = $this->dao->select('id, project, estimate, consumed, `left`, status, closedReason')
->from(TABLE_TASK)
->where('project')->in($projectKeys)
->where('project')->in(array_keys($executions))
->andWhere('parent')->lt(1)
->andWhere('deleted')->eq(0)
->fetchGroup('project', 'id');
/* Compute totalEstimate, totalConsumed, totalLeft. */
foreach($tasks as $projectID => $projectTasks)
foreach($tasks as $executionID => $executionTasks)
{
$hour = (object)$emptyHour;
foreach($projectTasks as $task)
foreach($executionTasks as $task)
{
if($task->status != 'cancel')
{
@@ -1017,7 +1021,7 @@ class projectModel extends model
}
if($task->status != 'cancel' and $task->status != 'closed') $hour->totalLeft += $task->left;
}
$hours[$projectID] = $hour;
$hours[$executionID] = $hour;
}
/* Compute totalReal and progress. */
@@ -1033,61 +1037,61 @@ class projectModel extends model
/* Get burndown charts datas. */
$burns = $this->dao->select('project, date AS name, `left` AS value')
->from(TABLE_BURN)
->where('project')->in($projectKeys)
->where('project')->in(array_keys($executions))
->andWhere('task')->eq(0)
->orderBy('date desc')
->fetchGroup('project', 'name');
foreach($burns as $projectID => $projectBurns)
foreach($burns as $executionID => $executionBurns)
{
/* If projectBurns > $itemCounts, split it, else call processBurnData() to pad burns. */
$begin = $projects[$projectID]->begin;
$end = $projects[$projectID]->end;
if($begin == '0000-00-00') $begin = $projects[$projectID]->openedDate;
$projectBurns = $this->processBurnData($projectBurns, $itemCounts, $begin, $end);
$begin = $executions[$executionID]->begin;
$end = $executions[$executionID]->end;
if($begin == '0000-00-00') $begin = $executions[$executionID]->openedDate;
$executionBurns = $this->processBurnData($executionBurns, $itemCounts, $begin, $end);
/* Shorter names. */
foreach($projectBurns as $projectBurn)
foreach($executionBurns as $executionBurn)
{
$projectBurn->name = substr($projectBurn->name, 5);
unset($projectBurn->project);
$executionBurn->name = substr($executionBurn->name, 5);
unset($executionBurn->project);
}
ksort($projectBurns);
$burns[$projectID] = $projectBurns;
ksort($executionBurns);
$burns[$executionID] = $executionBurns;
}
/* Process projects. */
/* Process executions. */
$parents = array();
$children = array();
foreach($projects as $key => $project)
foreach($executions as $key => $execution)
{
/* Process the end time. */
$project->end = date(DT_DATE1, strtotime($project->end));
$execution->end = date(DT_DATE1, strtotime($execution->end));
/* Judge whether the project is delayed. */
if($project->status != 'done' and $project->status != 'closed' and $project->status != 'suspended')
/* Judge whether the execution is delayed. */
if($execution->status != 'done' and $execution->status != 'closed' and $execution->status != 'suspended')
{
$delay = helper::diffDate(helper::today(), $project->end);
if($delay > 0) $project->delay = $delay;
$delay = helper::diffDate(helper::today(), $execution->end);
if($delay > 0) $execution->delay = $delay;
}
/* Process the burns. */
$project->burns = array();
$burnData = isset($burns[$project->id]) ? $burns[$project->id] : array();
foreach($burnData as $data) $project->burns[] = $data->value;
$execution->burns = array();
$burnData = isset($burns[$execution->id]) ? $burns[$execution->id] : array();
foreach($burnData as $data) $execution->burns[] = $data->value;
/* Process the hours. */
$project->hours = isset($hours[$project->id]) ? $hours[$project->id] : (object)$emptyHour;
$execution->hours = isset($hours[$execution->id]) ? $hours[$execution->id] : (object)$emptyHour;
$project->children = array();
$project->grade == 1 ? $parents[$project->id] = $project : $children[$project->parent][] = $project;
$execution->children = array();
$execution->grade == 1 ? $parents[$execution->id] = $execution : $children[$execution->parent][] = $execution;
}
/* In the case of the waterfall model, calculate the sub-stage. */
if($PRJData and $PRJData->model == 'waterfall')
if($project and $project->model == 'waterfall')
{
foreach($parents as $id => $project) $project->children = isset($children[$id]) ? $children[$id] : array();
foreach($parents as $id => $execution) $execution->children = isset($children[$id]) ? $children[$id] : array();
}
return $parents;
+31 -34
View File
@@ -84,25 +84,25 @@ class weeklyModel extends model
}
/**
* Save
* Save data.
*
* @param int $program
* @param int $project
* @param int $date
* @access public
* @return void
*/
public function save($program, $date)
public function save($project, $date)
{
$report = new stdclass;
$report->pv = $this->getPV($program, $date);
$report->ev = $this->getEV($program, $date);
$report->ac = $this->getAC($program, $date);
$report->pv = $this->getPV($project, $date);
$report->ev = $this->getEV($project, $date);
$report->ac = $this->getAC($project, $date);
$report->sv = $this->getSV($report->ev, $report->pv);
$report->cv = $this->getCV($report->ev, $report->ac);
$report->PRJ = $program;
$report->PRJ = $project;
$report->weekStart = $this->getThisMonday($date);
$report->staff = $this->getStaff($program);
$report->workload = json_encode($this->getWorkloadByType($program, $date));
$report->staff = $this->getStaff($project);
$report->workload = json_encode($this->getWorkloadByType($project, $date));
$this->dao->replace(TABLE_WEEKLYREPORT)->data($report)->exec();
}
@@ -339,13 +339,11 @@ class weeklyModel extends model
* @access public
* @return int
*/
public function getPV($program, $date = '')
public function getPV($projectID, $date = '')
{
$report = $this->getFromDB($program, $date);
$report = $this->getFromDB($projectID, $date);
if(!empty($report)) return $report->pv;
$program = $this->loadModel('project')->getByID($program);
if(!$date) $date = date('Y-m-d');
$monday = $this->getThisMonday($date);
$sunday = $this->getThisSunday($date);
@@ -353,11 +351,11 @@ class weeklyModel extends model
$nextMonday = date('Y-m-d', strtotime("$sunday +1 days"));
$workdays = $this->loadModel('holiday')->getActualWorkingDays($monday, $sunday);
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $program->id);
$projectIdList = array_keys($projects);
$executions = $this->loadModel('project')->getExecutionList($projectID);
$executionIdList = array_keys($executions);
$tasks = $this->dao->select('*')->from(TABLE_TASK)
->where('project')->in($projectIdList)
->where('project')->in($executionIdList)
->andWhere("(estStarted < '$nextMonday' or estStarted='0000-00-00')")
->fetchAll('id');
@@ -381,20 +379,20 @@ class weeklyModel extends model
}
/**
* GetEV
* Get EV data.
*
* @param int $program
* @param int $projectID
* @param string $date
* @access public
* @return int
*/
public function getEV($program, $date = '')
public function getEV($projectID, $date = '')
{
$report = $this->getFromDB($program, $date);
$report = $this->getFromDB($projectID, $date);
if(!empty($report)) return $report->ev;
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $program);
$projectIdList = array_keys($projects);
$executions = $this->loadModel('project')->getExecutionList($projectID);
$executionIdList = array_keys($executions);
if(!$date) $date = date('Y-m-d');
$monday = $this->getThisMonday($date);
@@ -404,7 +402,7 @@ class weeklyModel extends model
$tasks = $this->dao->select('*')
->from(TABLE_TASK)
->where('project')->in($projectIdList)
->where('project')->in($executionIdList)
->andWhere('consumed')->gt(0)
->andWhere('status')->ne('cancel')
->fetchAll('id');
@@ -426,29 +424,28 @@ class weeklyModel extends model
}
/**
* GetAC
* Get AC data.
*
* @param int $program
* @param int $projectID
* @param string $date
* @access public
* @return int
*/
public function getAC($program, $date = '')
public function getAC($projectID, $date = '')
{
$report = $this->getFromDB($program, $date);
$report = $this->getFromDB($projectID, $date);
if(!empty($report)) return $report->ac;
if(!$date) $date = date('Y-m-d');
$monday = $this->getThisMonday($date);
$nextMonday = date('Y-m-d', strtotime("$monday +7 days"));
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $program);
$projectIdList = array_keys($projects);
$monday = $this->getThisMonday($date);
$nextMonday = date('Y-m-d', strtotime("$monday +7 days"));
$executions = $this->loadModel('project')->getExecutionList($projectID);
$executionIdList = array_keys($executions);
$AC = $this->dao->select('sum(t1.consumed) as consumed')
->from(TABLE_TASKESTIMATE)->alias('t1')
->leftJoin(TABLE_TASK)->alias('t2')->on('t1.task=t2.id')
->where('t2.project')->in($projectIdList)
->where('t2.project')->in($executionIdList)
->andWhere('t1.date')->ge($monday)
->andWhere('t1.date')->lt($nextMonday)
->fetch('consumed');
@@ -457,7 +454,7 @@ class weeklyModel extends model
}
/**
* GetSV
* Get SV data.
*
* @param int $ev
* @param int $pv