Merge branch '20.x' of github.com:easysoft/zentaopms into 20.x
This commit is contained in:
@@ -290,3 +290,6 @@ ALTER TABLE `zt_project` ADD `path` varchar(255) NOT NULL AFTER `parent`;
|
||||
ALTER TABLE `zt_project` ADD `grade` tinyint unsigned NOT NULL AFTER `path`;
|
||||
|
||||
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system','custom','','URAndSR','1'),('system','custom','','URSRName','{\"urCommon\":{\"zh-cn\":\"\\u7528\\u6237\\u9700\\u6c42\"},\"srCommon\":{\"zh-cn\":\"\\u8f6f\\u4ef6\\u9700\\u6c42\"}}'),('system','custom','','storyPoint','1');
|
||||
|
||||
ALTER TABLE `zt_block` ADD `type` char(30) NOT NULL AFTER `module`;
|
||||
ALTER TABLE `zt_block` ADD UNIQUE `account_module_type_order` (`account`, `module`, `type`, `order`), DROP INDEX `account_module_order_type`;
|
||||
|
||||
@@ -30,3 +30,5 @@ $config->action->majorList['task'] = array('assigned', 'finished', 'activated
|
||||
$config->action->majorList['bug'] = array('assigned', 'resolved');
|
||||
$config->action->majorList['release'] = array('opened');
|
||||
$config->action->majorList['build'] = array('opened');
|
||||
$config->action->majorList['product'] = array('opened', 'edited');
|
||||
$config->action->majorList['project'] = array('opened', 'edited');
|
||||
|
||||
+17
-7
@@ -15,15 +15,25 @@ $config->block->editor = new stdclass();
|
||||
$config->block->editor->set = array('id' => 'html', 'tools' => 'simple');
|
||||
|
||||
$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['qa']['statistic'] = 'statistic';
|
||||
$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['qa']['statistic'] = 'statistic';
|
||||
$config->block->longBlock['program']['cmmireport'] = 'cmmireport';
|
||||
$config->block->longBlock['program']['cmmiissue'] = 'cmmiissue';
|
||||
$config->block->longBlock['program']['cmmirisk'] = 'cmmirisk';
|
||||
|
||||
$config->block->shortBlock = array();
|
||||
$config->block->shortBlock['product']['overview'] = 'overview';
|
||||
$config->block->shortBlock['project']['overview'] = 'overview';
|
||||
$config->block->shortBlock['product']['overview'] = 'overview';
|
||||
$config->block->shortBlock['project']['overview'] = 'overview';
|
||||
$config->block->shortBlock['program']['cmmiestimate'] = 'cmmiestimate';
|
||||
$config->block->shortBlock['program']['cmmiprogress'] = 'cmmiprogress';
|
||||
$config->block->shortBlock['']['contribute'] = 'contribute';
|
||||
|
||||
$config->block->showAction['overview'] = array('block' => 'qa', 'module' => 'testcase', 'method' => 'create', 'vars' => '');
|
||||
$config->block->showAction['scrumlist'] = array('block' => 'program', 'module' => 'project', 'method' => 'create', 'vars' => '');
|
||||
$config->block->showAction['scrumproduct'] = array('block' => 'program', 'module' => 'product', 'method' => 'create', 'vars' => '');
|
||||
|
||||
$config->statistic = new stdclass();
|
||||
$config->statistic->storyStages = array('wait', 'planned', 'developing', 'testing', 'released');
|
||||
|
||||
+122
-50
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
/**
|
||||
/**
|
||||
* The control file of block of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
@@ -59,6 +59,7 @@ class block extends control
|
||||
if(strpos(",$closedBlock,", ",|flowchart,") === false and $this->config->global->flow == 'full') $modules['flowchart'] = $this->lang->block->lblFlowchart;
|
||||
if(strpos(",$closedBlock,", ",|welcome,") === false and $this->config->global->flow == 'full') $modules['welcome'] = $this->lang->block->welcome;
|
||||
if(strpos(",$closedBlock,", ",|html,") === false) $modules['html'] = 'HTML';
|
||||
if(strpos(",$closedBlock,", ",|contribute,") === false) $modules['contribute'] = $this->lang->block->contribute;
|
||||
$modules = array('' => '') + $modules;
|
||||
|
||||
$hiddenBlocks = $this->block->getHiddenBlocks();
|
||||
@@ -207,11 +208,11 @@ class block extends control
|
||||
public function dashboard($module, $type = '')
|
||||
{
|
||||
if($this->loadModel('user')->isLogon()) $this->session->set('blockModule', $module);
|
||||
$blocks = $this->block->getBlockList($module);
|
||||
$blocks = $this->block->getBlockList($module, $type);
|
||||
$inited = empty($this->config->$module->common->blockInited) ? '' : $this->config->$module->common->blockInited;
|
||||
|
||||
/* Init block when vist index first. */
|
||||
if(empty($blocks) and !$inited and !defined('TUTORIAL'))
|
||||
if((empty($blocks) and !$inited and !defined('TUTORIAL')) || (empty($blocks) and $module == 'program'))
|
||||
{
|
||||
if($this->block->initBlock($module, $type)) die(js::reload());
|
||||
}
|
||||
@@ -246,13 +247,15 @@ class block extends control
|
||||
$block->moreLink = $this->createLink('company', 'dynamic');
|
||||
}
|
||||
|
||||
|
||||
$block->actionLink = '';
|
||||
if($block->block == 'overview')
|
||||
if(isset($this->config->block->showAction[$block->block]))
|
||||
{
|
||||
if($module == 'qa' && common::hasPriv('testcase', 'create'))
|
||||
$action = $this->config->block->showAction[$block->block];
|
||||
if(common::hasPriv($action['module'], $action['method']))
|
||||
{
|
||||
$this->app->loadLang('testcase');
|
||||
$block->actionLink = html::a($this->createLink('testcase', 'create', 'productID='), "<i class='icon icon-sm icon-plus'></i> " . $this->lang->testcase->create, '', "class='btn btn-primary'");
|
||||
$this->app->loadLang($action['module']);
|
||||
$block->actionLink = html::a($this->createLink($action['module'], $action['method'], $action['vars']), "<i class='icon icon-sm icon-plus'></i> " . $this->lang->$action['module']->create, '', "class='btn btn-mini'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,6 +325,19 @@ class block extends control
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print contribute block.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function contribute()
|
||||
{
|
||||
$this->view->data = $this->block->getContributeBlockData();
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print block.
|
||||
*
|
||||
@@ -374,6 +390,10 @@ class block extends control
|
||||
{
|
||||
$html = $this->fetch('block', 'welcome');
|
||||
}
|
||||
elseif($block->block == 'contribute')
|
||||
{
|
||||
$html = $this->fetch('block', 'contribute');
|
||||
}
|
||||
|
||||
echo $html;
|
||||
}
|
||||
@@ -758,6 +778,7 @@ class block extends control
|
||||
if(!empty($this->params->type) and preg_match('/[^a-zA-Z0-9_]/', $this->params->type)) die();
|
||||
|
||||
$this->loadModel('project');
|
||||
$this->loadModel('weekly');
|
||||
$this->app->loadLang('task');
|
||||
$this->app->loadLang('story');
|
||||
|
||||
@@ -772,29 +793,43 @@ class block extends control
|
||||
return false;
|
||||
}
|
||||
|
||||
$today = date('Y-m-d', strtotime(helper::today()));
|
||||
$date = date('Ymd', strtotime($this->loadModel('weekly')->getThisMonday($today)));
|
||||
$tasks = $this->dao->select("program, sum(consumed) as totalConsumed, sum(if(status != 'cancel' and status != 'closed', `left`, 0)) as totalLeft")->from(TABLE_TASK)
|
||||
->where('program')->in(array_keys($programs))
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('parent')->lt(1)
|
||||
->groupBy('program')
|
||||
->fetchAll('program');
|
||||
|
||||
foreach($programs as $programID => $program)
|
||||
{
|
||||
$program->allStories = $program->doneStories = $program->leftStories = 0;
|
||||
|
||||
$stories = $this->dao->select('id, status')->from(TABLE_STORY)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('type')->eq('story')
|
||||
->andWhere('status')->ne('draft')
|
||||
->andWhere('program')->eq($programID)
|
||||
->fetchPairs();
|
||||
foreach($stories as $id => $status)
|
||||
if($program->template == 'scrum')
|
||||
{
|
||||
$program->allStories ++;
|
||||
if($status == 'closed') $program->doneStories ++;
|
||||
if($status != 'closed') $program->leftStories ++;
|
||||
$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);
|
||||
}
|
||||
else
|
||||
{
|
||||
$begin = $program->begin;
|
||||
$weeks = $this->weekly->getWeekPairs($begin);
|
||||
$current = zget($weeks, $date, '');
|
||||
|
||||
$program->progress = $program->allStories == 0 ? 0 : ceil($program->doneStories / $program->allStories) * 100;
|
||||
$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);
|
||||
|
||||
//$program->projects = $this->dao->select('*')
|
||||
$progress = isset($tasks[$programID]) ? (($tasks[$programID]->totalConsumed + $tasks[$programID]->totalLeft)) ? round($tasks[$programID]->totalConsumed / ($tasks[$programID]->totalConsumed + $tasks[$programID]->totalLeft), 3) * 100 : 0 : 0;
|
||||
|
||||
$program->current = $current;
|
||||
$program->progress = $progress;
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->programs = $programs;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1030,7 +1065,7 @@ class block extends control
|
||||
$projects[$project->id]->releasedStories = 0;
|
||||
}
|
||||
|
||||
$projects[$project->id]->progress = ($project->totalConsumed || $project->totalLeft) ? round($project->totalConsumed / ($project->totalConsumed + $project->totalLeft), 2) * 100 : 0;
|
||||
$projects[$project->id]->progress = ($project->totalConsumed || $project->totalLeft) ? round($project->totalConsumed / ($project->totalConsumed + $project->totalLeft), 3) * 100 : 0;
|
||||
$projects[$project->id]->taskProgress = $project->totalTasks ? round(($project->totalTasks - $project->undoneTasks) / $project->totalTasks, 2) * 100 : 0;
|
||||
$projects[$project->id]->storyProgress = $project->totalStories ? round(($project->totalStories - $project->unclosedStories) / $project->totalStories, 2) * 100 : 0;
|
||||
$projects[$project->id]->bugProgress = $project->totalBugs ? round(($project->totalBugs - $project->activeBugs) / $project->totalBugs, 2) * 100 : 0;
|
||||
@@ -1047,6 +1082,7 @@ class block extends control
|
||||
*/
|
||||
public function printCmmiReportBlock()
|
||||
{
|
||||
$this->loadModel('program');
|
||||
$program = $this->loadModel('project')->getByID($this->session->program);
|
||||
$today = date('Y-m-d', strtotime(helper::today()));
|
||||
$date = date('Ymd', strtotime($this->loadModel('weekly')->getThisMonday($today)));
|
||||
@@ -1065,7 +1101,7 @@ class block extends control
|
||||
$this->view->cv = $this->weekly->getCV($this->view->ev, $this->view->ac);
|
||||
|
||||
$this->view->current = $current;
|
||||
$this->view->progress = ($task->totalConsumed + $task->totalLeft) ? round($task->totalConsumed / ($task->totalConsumed + $task->totalLeft), 2) * 100 : 0;
|
||||
$this->view->progress = ($task->totalConsumed + $task->totalLeft) ? round($task->totalConsumed / ($task->totalConsumed + $task->totalLeft), 3) * 100 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1365,6 +1401,7 @@ class block extends control
|
||||
if(common::hasPriv('todo', 'view')) $hasViewPriv['todo'] = true;
|
||||
if(common::hasPriv('task', 'view')) $hasViewPriv['task'] = true;
|
||||
if(common::hasPriv('bug', 'view')) $hasViewPriv['bug'] = true;
|
||||
if(common::hasPriv('risk', 'view')) $hasViewPriv['risk'] = true;
|
||||
|
||||
$params = $this->get->param;
|
||||
$params = json_decode(base64_decode($params));
|
||||
@@ -1419,6 +1456,19 @@ class block extends control
|
||||
|
||||
$this->view->bugs = $bugs;
|
||||
}
|
||||
if(isset($hasViewPriv['risk']))
|
||||
{
|
||||
$this->app->loadLang('risk');
|
||||
$stmt = $this->dao->select('*')->from(TABLE_RISK)
|
||||
->where('assignedTo')->eq($this->app->user->account)
|
||||
->andWhere('deleted')->eq('0')
|
||||
->andWhere('status')->ne('closed')
|
||||
->orderBy('id_desc');
|
||||
if(isset($params->riskNum)) $stmt->limit($params->riskNum);
|
||||
$risks = $stmt->fetchAll();
|
||||
|
||||
$this->view->risks = $risks;
|
||||
}
|
||||
|
||||
$this->view->selfCall = $this->selfCall;
|
||||
$this->view->hasViewPriv = $hasViewPriv;
|
||||
@@ -1426,17 +1476,6 @@ class block extends control
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print contribute block.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function printContributeBlock()
|
||||
{
|
||||
$this->view->data = $this->block->getContributeBlockData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print recent program block.
|
||||
*
|
||||
@@ -1535,15 +1574,20 @@ class block extends control
|
||||
}
|
||||
|
||||
/**
|
||||
* Print srcum progress block.
|
||||
* Print srcum project list block.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function printScrumprogressBlock()
|
||||
public function printScrumlistBlock()
|
||||
{
|
||||
$this->view->program = $this->loadModel('project')->getByID($this->session->program);
|
||||
}
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
if(!empty($this->params->type) and preg_match('/[^a-zA-Z0-9_]/', $this->params->type)) die();
|
||||
$num = isset($this->params->num) ? (int)$this->params->num : 0;
|
||||
$type = isset($this->params->type) ? $this->params->type : 'all';
|
||||
$pager = pager::init(0, $num, 1);
|
||||
$this->view->projectStats = $this->loadModel('project')->getProjectStats($type, $productID = 0, $branch = 0, $itemCounts = 30, $orderBy = 'order_desc', $this->viewType != 'json' ? $pager : '', $this->session->program);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print srcum road map block.
|
||||
@@ -1553,11 +1597,15 @@ class block extends control
|
||||
*/
|
||||
public function printScrumroadmapBlock()
|
||||
{
|
||||
$this->view->program = $this->loadModel('project')->getByID($this->session->program);
|
||||
$this->session->set('releaseList', $this->app->getURI(true));
|
||||
$this->session->set('productPlanList', $this->app->getURI(true));
|
||||
|
||||
$products = $this->loadModel('product')->getPairs();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Print srcum road map block.
|
||||
* Print srcum test block.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
@@ -1574,7 +1622,7 @@ class block extends control
|
||||
->leftJoin(TABLE_PROJECT)->alias('t4')->on('t1.project=t4.id')
|
||||
->leftJoin(TABLE_PROJECTPRODUCT)->alias('t5')->on('t1.project=t5.project')
|
||||
->where('t1.deleted')->eq('0')
|
||||
->andWhere('t1.product')->eq($this->session->program)->fi()
|
||||
->andWhere('t1.program')->eq($this->session->program)->fi()
|
||||
->andWhere('t1.product = t5.product')
|
||||
->beginIF($this->params->type != 'all')->andWhere('t1.status')->eq($this->params->type)->fi()
|
||||
->orderBy('t1.id desc')
|
||||
@@ -1590,7 +1638,17 @@ class block extends control
|
||||
*/
|
||||
public function printScrumproductBlock()
|
||||
{
|
||||
$this->view->program = $this->loadModel('project')->getByID($this->session->program);
|
||||
$products = $this->dao->select('id,name')->from(TABLE_PRODUCT)->where('program')->eq($this->session->program)->limit(15)->fetchPairs();
|
||||
$productID = array_keys($products);
|
||||
|
||||
$stories = empty($productID) ? array() : $this->dao->select('count(*) as total, product')->from(TABLE_STORY)->where('product')->in($productID)->andWhere('deleted')->eq('0')->groupBy('product')->fetchPairs('product', 'total');
|
||||
$bugs = empty($productID) ? array() : $this->dao->select('count(*) as total, product')->from(TABLE_BUG)->where('product')->in($productID)->andWhere('deleted')->eq('0')->groupBy('product')->fetchPairs('product', 'total');
|
||||
$releases = empty($productID) ? array() : $this->dao->select('count(*) as total, product')->from(TABLE_RELEASE)->where('product')->in($productID)->andWhere('deleted')->eq('0')->groupBy('product')->fetchPairs('product', 'total');
|
||||
|
||||
$this->view->products = $products;
|
||||
$this->view->stories = $stories;
|
||||
$this->view->bugs = $bugs;
|
||||
$this->view->releases = $releases;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1601,7 +1659,7 @@ class block extends control
|
||||
*/
|
||||
public function printScrumprojectBlock()
|
||||
{
|
||||
$this->view->projectOverview = $this->dao->select('count(*) total, count(if(status="doing", id, null)) as doing, count(if(status="closed", id, null)) as finish')->from(TABLE_PROJECT)
|
||||
$this->view->summary = $this->dao->select('count(*) as total, count(if(status="doing", id, null)) as doing, count(if(status="closed", id, null)) as finish')->from(TABLE_PROJECT)
|
||||
->where('program')->eq($this->session->program)
|
||||
->fetch();
|
||||
}
|
||||
@@ -1614,13 +1672,27 @@ class block extends control
|
||||
*/
|
||||
public function printScrumdynamicBlock()
|
||||
{
|
||||
$projects = $this->loadModel('project')->getPairs();
|
||||
$actions = $this->dao->select('*')->from(TABLE_ACTION)
|
||||
->where('project')->in(array_keys($projects))
|
||||
->orderBy('id_desc')
|
||||
->fetchAll();
|
||||
$projects = $this->loadModel('project')->getPairs();
|
||||
$products = $this->loadModel('product')->getPairs();
|
||||
$productID = array();
|
||||
foreach($products as $id => $name) $productID[] = ',' . $id . ',';
|
||||
|
||||
$this->view->actions = $this->loadModel('action')->transformActions($actions);
|
||||
if(empty($projects) && empty($products))
|
||||
{
|
||||
$actions = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
$actions = $this->dao->select('*')->from(TABLE_ACTION)
|
||||
->beginIF($projects && $products)->where('project')->in(array_keys($projects))->orWhere('product')->in($productID)->fi()
|
||||
->beginIF($projects && empty($products))->where('project')->in(array_keys($projects))->fi()
|
||||
->beginIF(empty($projects) && $products)->where('product')->in($productID)->fi()
|
||||
->orderBy('id_desc')
|
||||
->limit(30)
|
||||
->fetchAll();
|
||||
}
|
||||
|
||||
$this->view->actions = empty($actions) ? array() : $this->loadModel('action')->transformActions($actions);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ $(function()
|
||||
return true;
|
||||
}
|
||||
|
||||
if(moduleID == 'html' || moduleID == 'dynamic' || moduleID == 'flowchart' || moduleID == 'assigntome' || moduleID == 'welcome')
|
||||
if(moduleID == 'html' || moduleID == 'dynamic' || moduleID == 'flowchart' || moduleID == 'assigntome' || moduleID == 'welcome' || moduleID == 'contribute')
|
||||
{
|
||||
getNotSourceParams(moduleID, blockID, onFinish);
|
||||
return true;
|
||||
|
||||
@@ -79,6 +79,7 @@ function refreshBlock($panel, afterRefresh)
|
||||
}
|
||||
$panel.find('.tablesorter').sortTable();
|
||||
initTableHeader($panel);
|
||||
$(".sparkline").sparkline();
|
||||
}).fail(function()
|
||||
{
|
||||
$panel.addClass('panel-error');
|
||||
|
||||
@@ -252,6 +252,7 @@ $lang->block->availableBlocks->plan = 'Plan';
|
||||
$lang->block->availableBlocks->release = 'Release';
|
||||
$lang->block->availableBlocks->build = 'Build';
|
||||
$lang->block->availableBlocks->testtask = 'Testaufgaben';
|
||||
$lang->block->availableBlocks->risk = 'My Risks';
|
||||
|
||||
$lang->block->moduleList['product'] = $lang->productCommon;
|
||||
$lang->block->moduleList['project'] = $lang->projectCommon;
|
||||
|
||||
@@ -252,6 +252,7 @@ $lang->block->availableBlocks->plan = 'Plans';
|
||||
$lang->block->availableBlocks->release = 'Releases';
|
||||
$lang->block->availableBlocks->build = 'Builds';
|
||||
$lang->block->availableBlocks->testtask = 'Requests';
|
||||
$lang->block->availableBlocks->risk = 'My Risks';
|
||||
|
||||
$lang->block->moduleList['product'] = $lang->productCommon;
|
||||
$lang->block->moduleList['project'] = $lang->projectCommon;
|
||||
|
||||
@@ -252,6 +252,7 @@ $lang->block->availableBlocks->plan = 'Plans';
|
||||
$lang->block->availableBlocks->release = 'Releases';
|
||||
$lang->block->availableBlocks->build = 'Builds';
|
||||
$lang->block->availableBlocks->testtask = 'Recettes';
|
||||
$lang->block->availableBlocks->risk = 'My Risks';
|
||||
|
||||
$lang->block->moduleList['product'] = $lang->productCommon;
|
||||
$lang->block->moduleList['project'] = $lang->projectCommon;
|
||||
|
||||
@@ -252,6 +252,7 @@ $lang->block->availableBlocks->plan = 'Kế hoạch';
|
||||
$lang->block->availableBlocks->release = 'Phát hành';
|
||||
$lang->block->availableBlocks->build = 'Bản dựng';
|
||||
$lang->block->availableBlocks->testtask = 'Yêu cầu';
|
||||
$lang->block->availableBlocks->risk = 'My Risks';
|
||||
|
||||
$lang->block->moduleList['product'] = $lang->productCommon;
|
||||
$lang->block->moduleList['project'] = $lang->projectCommon;
|
||||
|
||||
+73
-32
@@ -36,6 +36,7 @@ $lang->block->done = '已完成';
|
||||
$lang->block->lblFlowchart = '流程图';
|
||||
$lang->block->welcome = '欢迎总览';
|
||||
$lang->block->lblTesttask = '查看测试详情';
|
||||
$lang->block->contribute = '个人贡献';
|
||||
|
||||
$lang->block->leftToday = '今天剩余工作总计';
|
||||
$lang->block->myTask = '我的任务';
|
||||
@@ -53,6 +54,9 @@ $lang->block->resolvedBugs = '解决Bug数';
|
||||
$lang->block->openedTestcases = '创建用例数';
|
||||
$lang->block->cmmi = 'CMMI 3';
|
||||
$lang->block->scrum = 'Scrum+';
|
||||
$lang->block->allProject = '所有' . $lang->projectCommon;
|
||||
$lang->block->doingProject = '进行中的' . $lang->projectCommon;
|
||||
$lang->block->finishProject = '累积' . $lang->projectCommon;
|
||||
|
||||
$lang->block->params = new stdclass();
|
||||
$lang->block->params->name = '参数名称';
|
||||
@@ -72,25 +76,34 @@ $lang->block->nbsp = '';
|
||||
$lang->block->hidden = '隐藏';
|
||||
$lang->block->dynamicInfo = "<span class='timeline-tag'>%s</span> <span class='timeline-text'>%s <em>%s</em> %s <a href='%s' title='%s'>%s</a></span>";
|
||||
|
||||
$lang->block->default['cmmi']['program']['1']['title'] = '项目周报';
|
||||
$lang->block->default['cmmi']['program']['1']['block'] = 'cmmireport';
|
||||
$lang->block->default['cmmi']['program']['1']['grid'] = 8;
|
||||
$lang->block->productName = $lang->productCommon . '名称';
|
||||
$lang->block->totalStory = '总' . $lang->storyCommon;
|
||||
$lang->block->totalBug = '总Bug';
|
||||
$lang->block->totalRelease = '发布次数';
|
||||
|
||||
$lang->block->default['cmmi']['program']['2']['title'] = '估算';
|
||||
$lang->block->default['cmmi']['program']['2']['block'] = 'cmmiestimate';
|
||||
$lang->block->default['cmmi']['program']['2']['grid'] = 4;
|
||||
$lang->block->default['cmmi']['program']['1']['title'] = '项目周报';
|
||||
$lang->block->default['cmmi']['program']['1']['block'] = 'cmmireport';
|
||||
$lang->block->default['cmmi']['program']['1']['source'] = 'program';
|
||||
$lang->block->default['cmmi']['program']['1']['grid'] = 8;
|
||||
|
||||
$lang->block->default['cmmi']['program']['3']['title'] = '计划甘特图';
|
||||
$lang->block->default['cmmi']['program']['3']['block'] = 'cmmigantt';
|
||||
$lang->block->default['cmmi']['program']['3']['grid'] = 8;
|
||||
$lang->block->default['cmmi']['program']['2']['title'] = '估算';
|
||||
$lang->block->default['cmmi']['program']['2']['block'] = 'cmmiestimate';
|
||||
$lang->block->default['cmmi']['program']['2']['source'] = 'program';
|
||||
$lang->block->default['cmmi']['program']['2']['grid'] = 4;
|
||||
|
||||
$lang->block->default['cmmi']['program']['4']['title'] = '到目前为止项目进展趋势图';
|
||||
$lang->block->default['cmmi']['program']['4']['block'] = 'cmmiprogress';
|
||||
$lang->block->default['cmmi']['program']['4']['grid'] = 4;
|
||||
$lang->block->default['cmmi']['program']['3']['title'] = '计划甘特图';
|
||||
$lang->block->default['cmmi']['program']['3']['block'] = 'cmmigantt';
|
||||
$lang->block->default['cmmi']['program']['3']['source'] = 'program';
|
||||
$lang->block->default['cmmi']['program']['3']['grid'] = 8;
|
||||
|
||||
$lang->block->default['cmmi']['program']['5']['title'] = '项目问题';
|
||||
$lang->block->default['cmmi']['program']['5']['block'] = 'cmmiissue';
|
||||
$lang->block->default['cmmi']['program']['5']['grid'] = 8;
|
||||
$lang->block->default['cmmi']['program']['4']['title'] = '到目前为止项目进展趋势图';
|
||||
$lang->block->default['cmmi']['program']['4']['block'] = 'cmmiprogress';
|
||||
$lang->block->default['cmmi']['program']['4']['grid'] = 4;
|
||||
|
||||
$lang->block->default['cmmi']['program']['5']['title'] = '项目问题';
|
||||
$lang->block->default['cmmi']['program']['5']['block'] = 'cmmiissue';
|
||||
$lang->block->default['cmmi']['program']['5']['source'] = 'program';
|
||||
$lang->block->default['cmmi']['program']['5']['grid'] = 8;
|
||||
|
||||
$lang->block->default['cmmi']['program']['5']['params']['type'] = 'all';
|
||||
$lang->block->default['cmmi']['program']['5']['params']['num'] = '15';
|
||||
@@ -101,23 +114,24 @@ $lang->block->default['cmmi']['program']['6']['block'] = 'dynamic';
|
||||
$lang->block->default['cmmi']['program']['6']['grid'] = 4;
|
||||
$lang->block->default['cmmi']['program']['6']['source'] = '';
|
||||
|
||||
$lang->block->default['cmmi']['program']['7']['title'] = '项目风险';
|
||||
$lang->block->default['cmmi']['program']['7']['block'] = 'cmmirisk';
|
||||
$lang->block->default['cmmi']['program']['7']['grid'] = 8;
|
||||
$lang->block->default['cmmi']['program']['7']['title'] = '项目风险';
|
||||
$lang->block->default['cmmi']['program']['7']['block'] = 'cmmirisk';
|
||||
$lang->block->default['cmmi']['program']['7']['source'] = 'program';
|
||||
$lang->block->default['cmmi']['program']['7']['grid'] = 8;
|
||||
|
||||
$lang->block->default['cmmi']['program']['7']['params']['type'] = 'all';
|
||||
$lang->block->default['cmmi']['program']['7']['params']['num'] = '15';
|
||||
$lang->block->default['cmmi']['program']['7']['params']['orderBy'] = 'id_desc';
|
||||
|
||||
$lang->block->default['scrum']['program']['1']['title'] = '项目整体情况';
|
||||
$lang->block->default['scrum']['program']['1']['title'] = '项目整体情况';
|
||||
$lang->block->default['scrum']['program']['1']['block'] = 'scrumoverall';
|
||||
$lang->block->default['scrum']['program']['1']['grid'] = 8;
|
||||
|
||||
$lang->block->default['scrum']['program']['2']['title'] = '进行中的迭代';
|
||||
$lang->block->default['scrum']['program']['2']['block'] = 'scrumprogress';
|
||||
$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']['program']['3']['title'] = '产品路线图';
|
||||
$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;
|
||||
|
||||
@@ -129,11 +143,11 @@ $lang->block->default['scrum']['program']['4']['params']['type'] = 'all';
|
||||
$lang->block->default['scrum']['program']['4']['params']['num'] = '15';
|
||||
$lang->block->default['scrum']['program']['4']['params']['orderBy'] = 'id_desc';
|
||||
|
||||
$lang->block->default['scrum']['program']['5']['title'] = '产品总览';
|
||||
$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']['program']['6']['title'] = '迭代总览';
|
||||
$lang->block->default['scrum']['program']['6']['title'] = $lang->projectCommon . '总览';
|
||||
$lang->block->default['scrum']['program']['6']['block'] = 'scrumproject';
|
||||
$lang->block->default['scrum']['program']['6']['grid'] = 4;
|
||||
|
||||
@@ -252,10 +266,12 @@ $lang->block->default['full']['my']['4']['grid'] = 8;
|
||||
|
||||
$lang->block->default['full']['my']['5']['title'] = '个人贡献';
|
||||
$lang->block->default['full']['my']['5']['block'] = 'contribute';
|
||||
$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']['grid'] = 8;
|
||||
|
||||
$lang->block->default['full']['my']['7']['title'] = '指派给我';
|
||||
@@ -270,9 +286,10 @@ $lang->block->default['full']['my']['8']['title'] = '项目人力投入';
|
||||
$lang->block->default['full']['my']['8']['block'] = 'programteam';
|
||||
$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']['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']['grid'] = 8;
|
||||
|
||||
$lang->block->default['full']['my']['9']['params']['orderBy'] = 'id_desc';
|
||||
$lang->block->default['full']['my']['9']['params']['num'] = '15';
|
||||
@@ -294,6 +311,7 @@ $lang->block->availableBlocks->plan = '计划列表';
|
||||
$lang->block->availableBlocks->release = '发布列表';
|
||||
$lang->block->availableBlocks->build = '版本列表';
|
||||
$lang->block->availableBlocks->testtask = '测试版本列表';
|
||||
$lang->block->availableBlocks->risk = '我的风险';
|
||||
|
||||
$lang->block->moduleList['program'] = '项目';
|
||||
$lang->block->moduleList['product'] = $lang->productCommon;
|
||||
@@ -303,16 +321,18 @@ $lang->block->moduleList['todo'] = '待办';
|
||||
|
||||
$lang->block->modules['program'] = new stdclass();
|
||||
$lang->block->modules['program']->availableBlocks = new stdclass();
|
||||
$lang->block->modules['program']->availableBlocks->list = '项目列表';
|
||||
$lang->block->modules['program']->availableBlocks->program = '项目列表';
|
||||
$lang->block->modules['program']->availableBlocks->recentprogram = '近期项目';
|
||||
$lang->block->modules['program']->availableBlocks->statistic = '项目统计';
|
||||
|
||||
$lang->block->modules['scrum']['index'] = new stdclass();
|
||||
$lang->block->modules['scrum']['index']->availableBlocks = new stdclass();
|
||||
$lang->block->modules['scrum']['index']->availableBlocks->scrumoverall = '项目整体情况';
|
||||
$lang->block->modules['scrum']['index']->availableBlocks->scrumprogress = '进行中的迭代';
|
||||
$lang->block->modules['scrum']['index']->availableBlocks->scrumproject = '迭代总览';
|
||||
$lang->block->modules['scrum']['index']->availableBlocks->scrumproduct = '产品总览';
|
||||
$lang->block->modules['scrum']['index']->availableBlocks->scrumlist = $lang->projectCommon . '列表';
|
||||
$lang->block->modules['scrum']['index']->availableBlocks->scrumproject = $lang->projectCommon . '总览';
|
||||
$lang->block->modules['scrum']['index']->availableBlocks->scrumproduct = $lang->productCommon . '总览';
|
||||
$lang->block->modules['scrum']['index']->availableBlocks->scrumtest = '待测版本';
|
||||
$lang->block->modules['scrum']['index']->availableBlocks->scrumroadmap = '产品路线图';
|
||||
$lang->block->modules['scrum']['index']->availableBlocks->scrumroadmap = $lang->productCommon . '路线图';
|
||||
|
||||
$lang->block->modules['cmmi']['index'] = new stdclass();
|
||||
$lang->block->modules['cmmi']['index']->availableBlocks = new stdclass();
|
||||
@@ -402,6 +422,7 @@ $lang->block->orderByList->story['stage_desc'] = '阶段倒序';
|
||||
$lang->block->todoNum = '待办数';
|
||||
$lang->block->taskNum = '任务数';
|
||||
$lang->block->bugNum = 'Bug数';
|
||||
$lang->block->riskNum = '风险数';
|
||||
|
||||
$lang->block->typeList = new stdclass();
|
||||
|
||||
@@ -434,12 +455,32 @@ $lang->block->typeList->project['doing'] = '进行中';
|
||||
$lang->block->typeList->project['all'] = '全部';
|
||||
$lang->block->typeList->project['involved'] = '我参与的';
|
||||
|
||||
$lang->block->typeList->scrum['undone'] = '未完成';
|
||||
$lang->block->typeList->scrum['doing'] = '进行中';
|
||||
$lang->block->typeList->scrum['all'] = '全部';
|
||||
$lang->block->typeList->scrum['involved'] = '我参与的';
|
||||
|
||||
$lang->block->typeList->testtask['wait'] = '待测版本';
|
||||
$lang->block->typeList->testtask['doing'] = '测试中版本';
|
||||
$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|browse|';
|
||||
$lang->block->modules['program']->moreLinkList->statistic = 'program|browse|';
|
||||
$lang->block->modules['program']->moreLinkList->program = 'program|browse|';
|
||||
$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->scrumroadmap = 'product|all|';
|
||||
$lang->block->modules['program']->moreLinkList->scrumtest = 'testtask|browse|';
|
||||
$lang->block->modules['program']->moreLinkList->scrumproduct = 'product|all|';
|
||||
$lang->block->modules['program']->moreLinkList->scrumproject = 'project|all|';
|
||||
$lang->block->modules['program']->moreLinkList->scrumdynamic = 'company|dynamic|';
|
||||
|
||||
$lang->block->modules['product']->moreLinkList = new stdclass();
|
||||
$lang->block->modules['product']->moreLinkList->list = 'product|all|product=&line=0&status=%s';
|
||||
$lang->block->modules['product']->moreLinkList->story = 'my|story|type=%s';
|
||||
|
||||
@@ -252,6 +252,7 @@ $lang->block->availableBlocks->plan = '計劃列表';
|
||||
$lang->block->availableBlocks->release = '發佈列表';
|
||||
$lang->block->availableBlocks->build = '版本列表';
|
||||
$lang->block->availableBlocks->testtask = '測試版本列表';
|
||||
$lang->block->availableBlocks->risk = '我的風險';
|
||||
|
||||
$lang->block->moduleList['product'] = $lang->productCommon;
|
||||
$lang->block->moduleList['project'] = $lang->projectCommon;
|
||||
|
||||
+158
-29
@@ -59,6 +59,8 @@ class blockModel extends model
|
||||
unset($_SESSION['album'][$uid]);
|
||||
}
|
||||
|
||||
if(strpos($data->block, 'cmmi') !== false) $data->type = 'cmmi';
|
||||
if(strpos($data->block, 'scrum') !== false) $data->type = 'scrum';
|
||||
$data->params = helper::jsonEncode($data->params);
|
||||
$this->dao->replace(TABLE_BLOCK)->data($data)->exec();
|
||||
if(!dao::isError()) $this->loadModel('score')->create('block', 'set');
|
||||
@@ -129,11 +131,12 @@ class blockModel extends model
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getBlockList($module = 'my')
|
||||
public function getBlockList($module = 'my', $type = '')
|
||||
{
|
||||
$blocks = $this->dao->select('*')->from(TABLE_BLOCK)->where('account')->eq($this->app->user->account)
|
||||
->andWhere('module')->eq($module)
|
||||
->andWhere('hidden')->eq(0)
|
||||
->beginIF($type)->andWhere('type')->eq($type)->fi()
|
||||
->beginIF($this->config->global->flow == 'onlyStory')->andWhere('source')->notin('project,qa')->fi()
|
||||
->beginIF($this->config->global->flow == 'onlyTask')->andWhere('source')->notin('product,qa')->fi()
|
||||
->beginIF($this->config->global->flow == 'onlyTest')->andWhere('source')->notin('product,project')->fi()
|
||||
@@ -233,6 +236,7 @@ class blockModel extends model
|
||||
{
|
||||
$block['order'] = $index;
|
||||
$block['module'] = $module;
|
||||
$block['type'] = $type;
|
||||
$block['account'] = $account;
|
||||
$block['params'] = isset($block['params']) ? helper::jsonEncode($block['params']) : '';
|
||||
if(!isset($block['source'])) $block['source'] = $module;
|
||||
@@ -446,6 +450,26 @@ class blockModel extends model
|
||||
return json_encode($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get program params.
|
||||
*
|
||||
* @access public
|
||||
* @return json
|
||||
*/
|
||||
public function getProgramParams()
|
||||
{
|
||||
$this->app->loadLang('program');
|
||||
$params->type['name'] = $this->lang->block->type;
|
||||
$params->type['options'] = $this->lang->program->featureBar;
|
||||
$params->type['control'] = 'select';
|
||||
|
||||
$params->orderBy['name'] = $this->lang->block->orderBy;
|
||||
$params->orderBy['options'] = $this->lang->block->orderByList->product;
|
||||
$params->orderBy['control'] = 'select';
|
||||
|
||||
return json_encode($this->onlyNumParams($params));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Build params.
|
||||
*
|
||||
@@ -547,6 +571,17 @@ class blockModel extends model
|
||||
return json_encode($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get recent program pararms.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getRecentprogramParams()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get product overview pararms.
|
||||
*
|
||||
@@ -558,6 +593,102 @@ class blockModel extends model
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cmmi program report pararms.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getCmmireportParams()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get program estimate pararms.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getCmmiestimateParams()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get program gantt pararms.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getCmmiganttParams()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get program progress pararms.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getCmmiprogressParams()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cmmi issue params.
|
||||
*
|
||||
* @param string $module
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getCmmiissueParams($module = '')
|
||||
{
|
||||
$this->app->loadLang('issue');
|
||||
$params = new stdclass();
|
||||
$params->type['name'] = $this->lang->block->type;
|
||||
$params->type['options'] = $this->lang->issue->labelList;
|
||||
$params->type['control'] = 'select';
|
||||
|
||||
$params->num['name'] = $this->lang->block->num;
|
||||
$params->num['default'] = 20;
|
||||
$params->num['control'] = 'input';
|
||||
|
||||
$params->orderBy['name'] = $this->lang->block->orderBy;
|
||||
$params->orderBy['options'] = $this->lang->block->orderByList->product;
|
||||
$params->orderBy['control'] = 'select';
|
||||
|
||||
return json_encode($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cmmi risk params.
|
||||
*
|
||||
* @param string $module▫
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getCmmiriskParams($module = '')
|
||||
{
|
||||
$this->app->loadLang('risk');
|
||||
$params = new stdclass();
|
||||
$params->type['name'] = $this->lang->block->type;
|
||||
$params->type['options'] = $this->lang->risk->featureBar['browse'];
|
||||
$params->type['control'] = 'select';
|
||||
|
||||
$params->num['name'] = $this->lang->block->num;
|
||||
$params->num['default'] = 20;
|
||||
$params->num['control'] = 'input';
|
||||
|
||||
$params->orderBy['name'] = $this->lang->block->orderBy;
|
||||
$params->orderBy['options'] = $this->lang->block->orderByList->product;
|
||||
$params->orderBy['control'] = 'select';
|
||||
|
||||
return json_encode($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get project params.
|
||||
*
|
||||
@@ -587,6 +718,10 @@ class blockModel extends model
|
||||
$params->bugNum['default'] = 20;
|
||||
$params->bugNum['control'] = 'input';
|
||||
|
||||
$params->riskNum['name'] = $this->lang->block->riskNum;
|
||||
$params->riskNum['default'] = 20;
|
||||
$params->riskNum['control'] = 'input';
|
||||
|
||||
return json_encode($params);
|
||||
}
|
||||
|
||||
@@ -709,40 +844,14 @@ class blockModel extends model
|
||||
return $key == $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cmmi issue params.
|
||||
*
|
||||
* @param string $module▫
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getCmmiissueParams($module = '')
|
||||
{
|
||||
$this->app->loadLang('issue');
|
||||
$params = new stdclass();
|
||||
$params->type['name'] = $this->lang->block->type;
|
||||
$params->type['options'] = $this->lang->issue->labelList;
|
||||
$params->type['control'] = 'select';
|
||||
|
||||
$params->num['name'] = $this->lang->block->num;
|
||||
$params->num['default'] = 20;
|
||||
$params->num['control'] = 'input';
|
||||
|
||||
$params->orderBy['name'] = $this->lang->block->orderBy;
|
||||
$params->orderBy['options'] = $this->lang->block->orderByList->product;
|
||||
$params->orderBy['control'] = 'select';
|
||||
|
||||
return json_encode($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get testtask params.
|
||||
*▫
|
||||
* @param string $module▫
|
||||
* @param string $module
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getScrumtestParams($module = '')
|
||||
public function getScrumtestParams($module = '')
|
||||
{
|
||||
$params = new stdclass();
|
||||
$params->type['name'] = $this->lang->block->type;
|
||||
@@ -756,4 +865,24 @@ class blockModel extends model
|
||||
return json_encode($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get scrum project list params.
|
||||
*▫
|
||||
* @param string $module
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getScrumListParams($module = '')
|
||||
{
|
||||
$params = new stdclass();
|
||||
$params->type['name'] = $this->lang->block->type;
|
||||
$params->type['options'] = $this->lang->block->typeList->scrum;
|
||||
$params->type['control'] = 'select';
|
||||
|
||||
$params->num['name'] = $this->lang->block->num;
|
||||
$params->num['default'] = 20;
|
||||
$params->num['control'] = 'input';
|
||||
|
||||
return json_encode($params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
<div class="panel-body">
|
||||
<style>
|
||||
.block-cmmiprogress #chartUnit {position: absolute; color: #999; top: 80px; left: 15px;}
|
||||
.block-cmmiprogress #chartLegend {position: absolute; right: 0; width: 80px; height: 60px; top: 50%; margin-top: -30px; line-height: 30px; color: #838A9D; font-size: 12px;}
|
||||
.block-cmmiprogress #chartLegend > div {position: relative; padding-left: 30px;}
|
||||
.block-cmmiprogress #chartLegend > div > .barline {position: absolute; width: 20px; left: 0; top: 13px; height: 3px;}
|
||||
.block-cmmiprogress #chartLegend .line-pv .barline{background: #1183fb}
|
||||
.block-cmmiprogress #chartLegend .line-ev .barline{background: rgb(0, 218, 136)}
|
||||
.block-cmmiprogress #chartLegend .line-ac .barline{background: rgb(255, 145, 0)}
|
||||
.block-cmmiprogress .milestone-chart {box-shadow: none}
|
||||
.block-cmmiprogress .milestone-chart.has-scrollbar {margin-bottom: -10px}
|
||||
</style>
|
||||
<?php include '../../milestone/view/chart.html.php';?>
|
||||
</div>
|
||||
|
||||
@@ -55,6 +55,10 @@ 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}
|
||||
@@ -106,6 +110,7 @@ $(function()
|
||||
<?php foreach($programs as $program):?>
|
||||
<div class="tab-pane fade<?php if($program->id == $selected) echo ' active in';?>" id="tab3Content<?php echo $program->id;?>">
|
||||
<div class="table-row">
|
||||
<?php if($program->template == '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">
|
||||
<canvas width="120" height="120"></canvas>
|
||||
@@ -133,16 +138,32 @@ $(function()
|
||||
</div>
|
||||
<div class="col-7">
|
||||
<div class="program-info">
|
||||
<div class='title'><?php echo $lang->program->allInput;?></div>
|
||||
<h4><?php echo $lang->program->allInput;?></h4>
|
||||
<div class='info'>
|
||||
<span><i class='icon icon-group'></i> <?php echo $program->countMembers;?></span>
|
||||
<span><i class='icon icon-clock'></i> <?php echo $program->consumed;?></span>
|
||||
<span><i class='icon icon-cost'></i> <?php echo $program->budget;?></span>
|
||||
<span><i class='icon icon-group'></i> <?php echo $program->teamCount;?></span>
|
||||
<span><i class='icon icon-clock'></i> <?php echo $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>
|
||||
</div>
|
||||
<?php endforeach;?>
|
||||
</div>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach;?>
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php if(empty($risks)): ?>
|
||||
<div class='empty-tip'><?php echo $lang->block->emptyTip;?></div>
|
||||
<?php else:?>
|
||||
<style>
|
||||
.block-risks .c-id {width: 50px;}
|
||||
.block-risks .c-pri {width: 50px;text-align: center;}
|
||||
.block-risks .c-identifiedDate {width: 95px;}
|
||||
.block-risks .c-category {width: 80px;}
|
||||
.block-risks .c-status {width: 80px;}
|
||||
.block-risks.block-sm .c-status {text-align: center;}
|
||||
</style>
|
||||
<div class='panel-body has-table scrollbar-hover'>
|
||||
<table class='table table-borderless table-fixed table-fixed-head table-hover tablesorter block-risks <?php if(!$longBlock) echo 'block-sm'?>'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class='c-id'><?php echo $lang->idAB?></th>
|
||||
<th class='c-name'><?php echo $lang->risk->name?></th>
|
||||
<?php if($longBlock):?>
|
||||
<th class='c-pri'><?php echo $lang->priAB?></th>
|
||||
<th class='c-category'><?php echo $lang->risk->category;?></th>
|
||||
<th class='c-identifiedDate'><?php echo $lang->risk->identifiedDate;?></th>
|
||||
<?php endif;?>
|
||||
<th class='c-status'><?php echo $lang->risk->status;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($risks as $risk):?>
|
||||
<?php
|
||||
$appid = isset($_GET['entry']) ? "class='app-btn' data-id='{$this->get->entry}'" : '';
|
||||
$viewLink = $this->createLink('risk', 'view', "riskID={$risk->id}");
|
||||
?>
|
||||
<tr data-url='<?php echo empty($sso) ? $viewLink : $sso . $sign . 'referer=' . base64_encode($viewLink); ?>' <?php echo $appid?>>
|
||||
<td class='c-id-xs'><?php echo sprintf('%03d', $risk->id);?></td>
|
||||
<td class='c-name' title='<?php echo $risk->name?>'><?php echo $risk->name?></td>
|
||||
<?php if($longBlock):?>
|
||||
<td class='c-pri'><?php echo zget($lang->risk->priList, $risk->pri)?></td>
|
||||
<td class='c-category'><?php echo zget($lang->risk->categoryList, $risk->category)?></td>
|
||||
<td class='c-identifiedDate'><?php echo $risk->identifiedDate == '0000-00-00' ? '' : $risk->identifiedDate;?></td>
|
||||
<?php endif;?>
|
||||
<?php $status = $this->processStatus('risk', $risk);?>
|
||||
<td class='c-status' title='<?php echo $status;?>'>
|
||||
<span class="status-risk status-<?php echo $risk->status?>"><?php echo $status;?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
@@ -1,10 +1,6 @@
|
||||
<?php if(empty($actions)): ?>
|
||||
<div class='empty-tip'><?php echo $lang->block->emptyTip;?></div>
|
||||
<?php else:?>
|
||||
<style>
|
||||
.block-dynamic .timeline > li .timeline-text {display: block; overflow: hidden; text-overflow: ellipsis; max-height: 20px; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; }
|
||||
.block-dynamic .panel-body {padding-top: 0;}
|
||||
</style>
|
||||
<div class='panel-body scrollbar-hover'>
|
||||
<ul class="timeline timeline-tag-left no-margin">
|
||||
<?php
|
||||
|
||||
@@ -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;?>
|
||||
@@ -0,0 +1,43 @@
|
||||
<?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($products)): ?>
|
||||
<div class='empty-tip'><?php common::printLink('product', 'create', '', "<i class='icon-plus'></i> " . $lang->product->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-num'><?php echo $lang->block->productName;?></th>
|
||||
<th class='c-num'><?php echo $lang->block->totalStory;?></th>
|
||||
<th class='c-num'><?php echo $lang->block->totalBug;?></th>
|
||||
<th class='c-num'><?php echo $lang->block->totalRelease;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-center">
|
||||
<?php $id = 0; ?>
|
||||
<?php foreach($products as $id => $name):?>
|
||||
<?php
|
||||
$appid = isset($_GET['entry']) ? "class='app-btn' data-id='{$this->get->entry}'" : "";
|
||||
$viewLink = $this->createLink('product', 'browse', 'productID=' . $id);
|
||||
?>
|
||||
<tr class='text-center' data-url='<?php echo empty($sso) ? $viewLink : $sso . $sign . 'referer=' . base64_encode($viewLink); ?>' <?php echo $appid?>>
|
||||
<td class="c-num text-ellipsis" title="<?php echo $name;?>"><?php echo $name;?></td>
|
||||
<td class="c-num"><?php echo empty($stories[$id]) ? 0: $stories[$id];?></td>
|
||||
<td class="c-num"><?php echo empty($bugs[$id]) ? 0: $bugs[$id];?></td>
|
||||
<td class="c-num"><?php echo empty($releases[$id]) ? 0: $releases[$id];?></td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php if(empty($projectOverview)): ?>
|
||||
<?php if(empty($summary)): ?>
|
||||
<div class='empty-tip'><?php echo $lang->block->emptyTip;?></div>
|
||||
<?php else:?>
|
||||
<style>
|
||||
@@ -27,19 +27,19 @@
|
||||
<div class="panel-body table-row">
|
||||
<div class="col-4 text-middle text-center">
|
||||
<div class="tile">
|
||||
<div class="tile-title">所有阶段</div>
|
||||
<div class="tile-amount">25</div>
|
||||
<div class="tile-title"><?php echo $lang->block->allProject;?></div>
|
||||
<div class="tile-amount"><?php echo $summary->total;?></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8 text-middle">
|
||||
<ul class="status-bars" style="transform: rotate(90deg);">
|
||||
<ul class="status-bars all-statistics">
|
||||
<li>
|
||||
<span class="bar" style="height: 0%"><span class="value">0</span></span>
|
||||
<span class="title">进行中</span>
|
||||
<span class="bar" style="height: <?php echo empty($summary->doing) ? 0 : round(($summary->doing/$summary->total) * 100);?>%"><span class="value"><?php echo $summary->doing;?></span></span>
|
||||
<span class="title"><?php echo $lang->block->doingProject;?></span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="bar" style="height: 100%"><span class="value">100</span></span>
|
||||
<span class="title">已挂起</span>
|
||||
<span class="bar" style="height: <?php echo empty($summary->finish) ? 0 : round(($summary->finish/$summary->total) * 100);?>%"><span class="value"><?php echo $summary->finish;?></span></span>
|
||||
<span class="title"><?php echo $lang->block->finishProject;?></span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* The roadmap view file of product 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 Chunsheng Wang <chunsheng@cnezsoft.com>
|
||||
* @package product
|
||||
* @version $Id: roadmap.html.php 4129 2013-01-18 01:58:14Z wwccss $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<div class="panel-body">
|
||||
<div class="release-path">
|
||||
<ul class="release-line">
|
||||
<li>
|
||||
<a href="/index.php?m=release&f=view&releaseID=2&pgm=7">
|
||||
<span class="title" title="发布二">渠成一期V1.1.2</span>
|
||||
<span class="date">2020/08/01-09/01</span>
|
||||
<span class="date">总消耗 120h</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/index.php?m=release&f=view&releaseID=2&pgm=7">
|
||||
<span class="title" title="发布二">渠成一期V1.1.2</span>
|
||||
<span class="date">2020/08/01-09/01</span>
|
||||
<span class="date">总消耗 120h</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/index.php?m=release&f=view&releaseID=2&pgm=7">
|
||||
<span class="title" title="发布二">渠成一期V1.1.2</span>
|
||||
<span class="date">2020/08/01-09/01</span>
|
||||
<span class="date">总消耗 120h</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/index.php?m=release&f=view&releaseID=2&pgm=7">
|
||||
<span class="title" title="发布二">渠成一期V1.1.2</span>
|
||||
<span class="date">2020/08/01-09/01</span>
|
||||
<span class="date">总消耗 120h</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/index.php?m=release&f=view&releaseID=2&pgm=7">
|
||||
<span class="title" title="发布二">渠成一期V1.1.2</span>
|
||||
<span class="date">2020/08/01-09/01</span>
|
||||
<span class="date">总消耗 120h</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -35,14 +35,14 @@
|
||||
$viewLink = $this->createLink('testtask', 'view', "testtaskID={$testtask->id}");
|
||||
?>
|
||||
<tr class='text-center' data-url='<?php echo empty($sso) ? $viewLink : $sso . $sign . 'referer=' . base64_encode($viewLink); ?>' <?php echo $appid?>>
|
||||
<td class='text-left' title='<?php echo $testtask->name?>'><?php echo $testtask->name?></td>
|
||||
<td class='text-left text-ellipsis' title='<?php echo $testtask->name?>'><?php echo $testtask->name?></td>
|
||||
<?php if($longBlock):?>
|
||||
<td class='text-left' title='<?php echo $testtask->productName?>'><?php echo $testtask->productName?></td>
|
||||
<td class='text-left text-ellipsis' title='<?php echo $testtask->productName?>'><?php echo $testtask->productName?></td>
|
||||
<?php endif;?>
|
||||
<?php if($longBlock):?>
|
||||
<td class='text-left' title='<?php echo $testtask->projectName?>'><?php echo $testtask->projectName?></td>
|
||||
<td class='text-left text-ellipsis' title='<?php echo $testtask->projectName?>'><?php echo $testtask->projectName?></td>
|
||||
<?php endif;?>
|
||||
<td class='text-left' title='<?php echo $testtask->buildName?>'><?php echo $testtask->buildName?></td>
|
||||
<td class='text-left text-ellipsis' title='<?php echo $testtask->buildName?>'><?php echo $testtask->buildName?></td>
|
||||
<td><?php echo zget($lang->testtask->statusList, $testtask->status)?></td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
.block-welcome .progress-group{margin-top: 20px;}
|
||||
.block-welcome .progress{margin-top: 10px; width: 85%}
|
||||
</style>
|
||||
<?php $progress = $tasks == 0 ? 0 : ceil($doneTasks / $tasks) * 100;?>
|
||||
<?php $progress = $tasks == 0 ? 0 : round($doneTasks / $tasks, 3) * 100;?>
|
||||
<div class='panel-move-handler'></div>
|
||||
<div class="panel-body conatiner-fluid">
|
||||
<div class="table-row">
|
||||
|
||||
@@ -33,7 +33,8 @@ $lang->my->menuOrder[75] = 'score';
|
||||
$lang->todo->menuOrder = $lang->my->menuOrder;
|
||||
|
||||
/* product menu order. */
|
||||
$lang->product->menuOrder[0] = 'plan';
|
||||
$lang->product->menuOrder[0] = 'plan';
|
||||
$lang->product->menuOrder[1] = 'requirement';
|
||||
$lang->product->menuOrder[5] = 'story';
|
||||
$lang->product->menuOrder[15] = 'release';
|
||||
$lang->product->menuOrder[20] = 'roadmap';
|
||||
|
||||
@@ -1179,9 +1179,8 @@ $lang->cmmiproduct->menu->requirement = '用户需求|product|browse|product={PR
|
||||
$lang->cmmiproduct->menu->story = '软件需求|product|browse|product={PRODUCT}&branch=&browseType=unclosed&queryID=0&storyType=story';
|
||||
$lang->cmmiproduct->menu->track = '跟踪矩阵|story|track|product={PRODUCT}';
|
||||
|
||||
$lang->story->menu = $lang->cmmiproduct->menu;
|
||||
$lang->milestone->menu = $lang->weekly->menu;
|
||||
$lang->nc->menu = $lang->auditplan->menu;
|
||||
$lang->milestone->menu = $lang->weekly->menu;
|
||||
$lang->nc->menu = $lang->auditplan->menu;
|
||||
|
||||
$lang->noMenuModule = array('my', 'todo', 'effort', 'program', 'attend', 'leave', 'makeup', 'overtime', 'lieu', 'holiday', 'custom', 'auditcl', 'subject', 'admin', 'mail', 'extension', 'dev', 'backup', 'action', 'cron', 'issue', 'risk', 'pssp', 'sms', 'message', 'webhook', 'search');
|
||||
$lang->haveMenuMethod = array('custom');
|
||||
|
||||
@@ -2213,6 +2213,7 @@ EOD;
|
||||
{
|
||||
$lang->product->menu = $lang->cmmiproduct->menu;
|
||||
$lang->productplan->menu = $lang->cmmiproduct->menu;
|
||||
$lang->story->menu = $lang->cmmiproduct->menu;
|
||||
$lang->$moduleName->menu = self::processMenuVars($lang->$moduleName->menu);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,47 @@
|
||||
<div class='cell table-row chart-row'>
|
||||
<div class='chart-wrapper text-center'>
|
||||
<h4><?php echo $lang->milestone->chart->title;?></h4>
|
||||
<div class='chart-canvas'><canvas id='chart-line' width='500' height='140' data-responsive='true'></canvas></div>
|
||||
<div class='milestone-chart' id='milestoneChart'>
|
||||
<div class='chart-canvas scrollbar-hover'>
|
||||
<div class='chart-wrapper'>
|
||||
<canvas width='400' height='120' data-responsive='true'></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div id="chartUnit"><?php echo "({$lang->project->workHour})";?></div>
|
||||
<div id="chartLegend">
|
||||
<div class="line-pv"><div class='barline bg-primary'></div>PV</div>
|
||||
<div class="line-ev"><div class='barline'></div>EV</div>
|
||||
<div class="line-ac"><div class='barline'></div>AC</div>
|
||||
<div class='chart-unit'><?php echo "({$lang->project->workHour})";?></div>
|
||||
<div class='chart-legend'>
|
||||
<span class="barline line-pv">PV</span>
|
||||
<span class="barline line-ev">EV</span>
|
||||
<span class="barline line-ac">AC</span>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
.milestone-chart {position: relative}
|
||||
.milestone-chart .chart-canvas {overflow: auto; max-width: 1002px}
|
||||
.milestone-chart .chart-wrapper {background: none; padding: 15px 0 0 0}
|
||||
.milestone-chart .chart-unit {position: absolute; left: 10px; top: 0;}
|
||||
.milestone-chart .chart-legend {position: absolute; right: 5px; top: 0;}
|
||||
.milestone-chart .barline {padding-left: 20px; position: relative; display: inline-block; line-height: 20px}
|
||||
.milestone-chart .barline + .barline {margin-left: 5px}
|
||||
.milestone-chart .barline:before {content: ' '; display: block; position: absolute; top: 8px; left: 0; width: 16px; height: 3px; background: #0c64eb}
|
||||
.milestone-chart .barline.line-ev:before {background: rgb(0, 218, 136)}
|
||||
.milestone-chart .barline.line-ac:before {background: rgb(255, 145, 0)}
|
||||
</style>
|
||||
<script>
|
||||
function initChar()
|
||||
function initMilestoneChart()
|
||||
{
|
||||
var themePrimaryColor = $.getThemeColor('primary');
|
||||
var data =
|
||||
{
|
||||
labels: <?php echo json_encode($charts['labels'])?>,
|
||||
datasets: [
|
||||
{
|
||||
label: "PV",
|
||||
color: themePrimaryColor,
|
||||
pointColor: themePrimaryColor,
|
||||
pointStrokeColor: themePrimaryColor,
|
||||
pointHighlightStroke: themePrimaryColor,
|
||||
label: 'PV',
|
||||
color: '#0c64eb',
|
||||
pointColor: '#0c64eb',
|
||||
pointStrokeColor: '#0c64eb',
|
||||
pointHighlightStroke: '#0c64eb',
|
||||
fillColor: 'rgba(0,106,241, .07)',
|
||||
pointHighlightFill: '#fff',
|
||||
data: <?php echo $charts['PV']?>
|
||||
},
|
||||
{
|
||||
label: "EV",
|
||||
label: 'EV',
|
||||
color: 'rgb(0, 218, 136)',
|
||||
pointColor: 'rgb(0, 218, 136)',
|
||||
pointStrokeColor: 'rgb(0, 218, 136)',
|
||||
@@ -39,7 +51,7 @@ function initChar()
|
||||
data: <?php echo $charts['EV']?>
|
||||
},
|
||||
{
|
||||
label: "AC",
|
||||
label: 'AC',
|
||||
color: 'rgb(255, 145, 0)',
|
||||
pointColor: 'rgb(255, 145, 0)',
|
||||
pointStrokeColor: 'rgb(255, 145, 0)',
|
||||
@@ -50,22 +62,55 @@ function initChar()
|
||||
}]
|
||||
};
|
||||
|
||||
var chartLine= $("#chart-line").lineChart(data,
|
||||
var betterWidth = data.labels.length * 15;
|
||||
var renderChart = function()
|
||||
{
|
||||
pointDotStrokeWidth: 2,
|
||||
pointDotRadius: 3,
|
||||
datasetStrokeWidth: 3,
|
||||
datasetFill: true,
|
||||
datasetStroke: true,
|
||||
scaleShowBeyondLine: false,
|
||||
responsive: true,
|
||||
bezierCurve: false,
|
||||
scaleFontColor: '#838A9D',
|
||||
tooltipXPadding: 10,
|
||||
tooltipYPadding: 10,
|
||||
multiTooltipTitleTemplate: '<%= label %> <?php echo $lang->project->workHour;?> /h',
|
||||
multiTooltipTemplate: "<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>",
|
||||
});
|
||||
var $chart = $('#milestoneChart');
|
||||
var $wrapper = $chart.find('.chart-wrapper');
|
||||
var $canvas = $chart.find('canvas');
|
||||
var $chartCanvas = $chart.find('.chart-canvas');
|
||||
if (betterWidth > 400)
|
||||
{
|
||||
var updateWrapperSize = function()
|
||||
{
|
||||
$wrapper.hide();
|
||||
$chartCanvas.css('max-width', 'initial');
|
||||
var maxWidth = $chartCanvas.width();
|
||||
$chartCanvas.css('max-width', maxWidth);
|
||||
$chart.toggleClass('has-scrollbar', maxWidth < betterWidth);
|
||||
$wrapper.show();
|
||||
};
|
||||
updateWrapperSize();
|
||||
$(window).on('resize', updateWrapperSize);
|
||||
|
||||
$wrapper.css('min-width', betterWidth);
|
||||
$canvas.attr(
|
||||
{
|
||||
width: betterWidth,
|
||||
height: Math.min(200, Math.floor(betterWidth / 4))
|
||||
});
|
||||
}
|
||||
$canvas.lineChart(data,
|
||||
{
|
||||
animation: betterWidth < 400,
|
||||
pointDotStrokeWidth: 1,
|
||||
pointDotRadius: 2,
|
||||
datasetStrokeWidth: 2,
|
||||
datasetFill: false,
|
||||
datasetStroke: true,
|
||||
scaleShowBeyondLine: true,
|
||||
responsive: true,
|
||||
bezierCurve: false,
|
||||
scaleFontColor: '#838A9D',
|
||||
tooltipXPadding: 10,
|
||||
tooltipYPadding: 10,
|
||||
multiTooltipTitleTemplate: '<%= label %> <?php echo $lang->project->workHour;?> /h',
|
||||
multiTooltipTemplate: '<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>',
|
||||
});
|
||||
}
|
||||
|
||||
if(betterWidth > 200) setTimeout(renderChart, 100);
|
||||
else renderChart();
|
||||
}
|
||||
initChar();
|
||||
initMilestoneChart();
|
||||
</script>
|
||||
|
||||
@@ -11,7 +11,7 @@ table .btn.addItem, table .btn.delItem{padding: 3px 8px; font-size: 12px; line-h
|
||||
<div class="main-table">
|
||||
<?php include 'basicinfo.html.php';?>
|
||||
<?php include 'process.html.php';?>
|
||||
<?php include 'chart.html.php';?>
|
||||
<div class="cell"><?php include 'chart.html.php';?></div>
|
||||
<?php include 'productquality.html.php';?>
|
||||
<?php include 'workhour.html.php';?>
|
||||
<?php include 'progress.html.php';?>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<tr class='text-center'>
|
||||
<td><?php echo $program->id;?></td>
|
||||
<td class='text-left'><?php echo $program->code;?></td>
|
||||
<td class='text-left'><?php echo html::a($this->createLink('program', 'index', "programID=$program->id"), $program->name);?></td>
|
||||
<td class='text-left'><?php echo html::a($this->createLink('program', 'index', "programID=$program->id", '', '', $program->id), $program->name);?></td>
|
||||
<td><?php echo $program->begin;?></td>
|
||||
<td><?php echo $program->end;?></td>
|
||||
<td class="c-status">
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
$(function()
|
||||
{
|
||||
$('#subNavbar .nav li').removeClass('active');
|
||||
$("#subNavbar .nav li[data-id=" + storyType + ']').addClass('active');
|
||||
|
||||
if($('#storyList thead th.c-title').width() < 150) $('#storyList thead th.c-title').width(150);
|
||||
$('#storyList td.has-child .story-toggle').each(function()
|
||||
{
|
||||
|
||||
@@ -23,6 +23,8 @@ $config->product->browse->unfoldID = zget($config->product->browse->unfoldID, $p
|
||||
js::set('unfoldID', $config->product->browse->unfoldID);
|
||||
js::set('unfoldAll', $lang->project->treeLevel['all']);
|
||||
js::set('foldAll', $lang->project->treeLevel['root']);
|
||||
js::set('storyType', $storyType);
|
||||
$lang->story->create = $storyType == 'story' ? $lang->story->createStory : $lang->story->createRequirement;
|
||||
?>
|
||||
<div id="mainMenu" class="clearfix">
|
||||
<div id="sidebarHeader">
|
||||
@@ -95,7 +97,7 @@ js::set('foldAll', $lang->project->treeLevel['root']);
|
||||
</ul>
|
||||
</div>
|
||||
<?php if(!common::checkNotCN()):?>
|
||||
<?php if(common::hasPriv('story', 'batchCreate')) echo html::a($this->createLink('story', 'batchCreate', "productID=$productID&branch=$branch&moduleID=$moduleID"), "<i class='icon icon-plus'></i> {$lang->story->batchCreate}", '', "class='btn btn btn-secondary'");?>
|
||||
<?php if(common::hasPriv('story', 'batchCreate')) echo html::a($this->createLink('story', 'batchCreate', "productID=$productID&branch=$branch&moduleID=$moduleID&storyID=0&project=0&plan=0&type=$storyType"), "<i class='icon icon-plus'></i> {$lang->story->batchCreate}", '', "class='btn btn btn-secondary'");?>
|
||||
<?php
|
||||
if(commonModel::isTutorialMode())
|
||||
{
|
||||
@@ -105,7 +107,7 @@ js::set('foldAll', $lang->project->treeLevel['root']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$link = $this->createLink('story', 'create', "productID=$productID&branch=$branch&moduleID=$moduleID");
|
||||
$link = $this->createLink('story', 'create', "productID=$productID&branch=$branch&moduleID=$moduleID&storyID=0&projectID=0&bugID=0&planID=0&todoID=0&extra=&type=$storyType");
|
||||
if(common::hasPriv('story', 'create')) echo html::a($link, "<i class='icon icon-plus'></i> {$lang->story->create}", '', "class='btn btn-primary'");
|
||||
}
|
||||
?>
|
||||
@@ -120,7 +122,7 @@ js::set('foldAll', $lang->project->treeLevel['root']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$link = $this->createLink('story', 'create', "product=$productID&branch=$branch&moduleID=$moduleID");
|
||||
$link = $this->createLink('story', 'create', "product=$productID&branch=$branch&moduleID=$moduleID&storyID=0&projectID=0&bugID=0&planID=0&todoID=0&extra=&type=$storyType");
|
||||
$disabled = '';
|
||||
if(!common::hasPriv('story', 'create'))
|
||||
{
|
||||
@@ -134,7 +136,7 @@ js::set('foldAll', $lang->project->treeLevel['root']);
|
||||
<?php $disabled = common::hasPriv('story', 'batchCreate') ? '' : "class='disabled'";?>
|
||||
<li <?php echo $disabled?>>
|
||||
<?php
|
||||
$batchLink = $this->createLink('story', 'batchCreate', "productID=$productID&branch=$branch&moduleID=$moduleID");
|
||||
$batchLink = $this->createLink('story', 'batchCreate', "productID=$productID&branch=$branch&moduleID=$moduleID&storyID=0&project=0&plan=0&type=$storyType");
|
||||
echo "<li>" . html::a($batchLink, "<i class='icon icon-plus'></i>" . $lang->story->batchCreate) . "</li>";
|
||||
?>
|
||||
</li>
|
||||
@@ -168,7 +170,7 @@ js::set('foldAll', $lang->project->treeLevel['root']);
|
||||
<p>
|
||||
<span class="text-muted"><?php echo $lang->story->noStory;?></span>
|
||||
<?php if(common::hasPriv('story', 'create')):?>
|
||||
<?php echo html::a($this->createLink('story', 'create', "productID={$productID}&branch={$branch}&moduleID={$moduleID}"), "<i class='icon icon-plus'></i> " . $lang->story->create, '', "class='btn btn-info'");?>
|
||||
<?php echo html::a($this->createLink('story', 'create', "productID={$productID}&branch={$branch}&moduleID={$moduleID}&storyID=0&projectID=0&bugID=0&planID=0&todoID=0&extra=&type=$storyType"), "<i class='icon icon-plus'></i> " . $lang->story->create, '', "class='btn btn-info'");?>
|
||||
<?php endif;?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -11,3 +11,8 @@ $config->program->editor->suspend = array('id' => 'comment', 'tools' => 'simple
|
||||
|
||||
$config->program->list = new stdclass();
|
||||
$config->program->list->exportFields = 'id,name,code,template,category,status,begin,end,budget,PM,end,desc';
|
||||
|
||||
$config->program->create = new stdclass();
|
||||
$config->program->edit = new stdclass();
|
||||
$config->program->create->requiredFields = 'name,code,begin,end';
|
||||
$config->program->edit->requiredFields = 'name,code,begin,end';
|
||||
|
||||
+16
-11
@@ -44,6 +44,8 @@ class program extends control
|
||||
{
|
||||
if(common::hasPriv('program', 'createGuide')) $this->lang->pageActions = html::a($this->createLink('program', 'createGuide'), "<i class='icon icon-sm icon-plus'></i> " . $this->lang->program->create, '', "class='btn btn-primary' data-toggle=modal");
|
||||
|
||||
$this->app->session->set('programList', $this->app->getURI(true));
|
||||
|
||||
$programType = $this->cookie->programType ? $this->cookie->programType : 'bylist';
|
||||
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
@@ -151,30 +153,33 @@ class program extends control
|
||||
/**
|
||||
* Edit a program.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @param int $programID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function edit($projectID = 0)
|
||||
public function edit($programID = 0)
|
||||
{
|
||||
$project = $this->project->getByID($projectID);
|
||||
$program = $this->project->getByID($programID);
|
||||
|
||||
if($_POST)
|
||||
{
|
||||
$changes = $this->project->update($projectID);
|
||||
$changes = $this->program->update($programID);
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => $this->processErrors(dao::getError())));
|
||||
if($changes)
|
||||
{
|
||||
$actionID = $this->loadModel('action')->create('project', $projectID, 'edited');
|
||||
$actionID = $this->loadModel('action')->create('program', $programID, 'edited');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
|
||||
|
||||
$url = $this->session->programList ? $this->session->programList : inlink('browse');
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $url));
|
||||
}
|
||||
|
||||
$this->view->pmUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst', $project->PM);
|
||||
$this->view->title = $this->lang->project->edit;
|
||||
$this->view->position[] = $this->lang->project->edit;
|
||||
$this->view->project = $project;
|
||||
$this->view->pmUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst', $program->PM);
|
||||
$this->view->title = $this->lang->program->edit;
|
||||
$this->view->position[] = $this->lang->program->edit;
|
||||
$this->view->program = $program;
|
||||
$this->view->parents = $this->program->getParentPairs();
|
||||
$this->view->groups = $this->loadModel('group')->getPairs();
|
||||
$this->display();
|
||||
}
|
||||
@@ -689,7 +694,7 @@ class program extends control
|
||||
public function ajaxGetDropMenu($programID, $module, $method, $extra)
|
||||
{
|
||||
$this->loadModel('project');
|
||||
$this->view->link = $this->createLink('program', 'index', "programID=$programID");
|
||||
$this->view->link = $this->createLink('program', 'index', "programID=$programID", '', '', $programID);
|
||||
$this->view->programID = $programID;
|
||||
$this->view->module = $module;
|
||||
$this->view->method = $method;
|
||||
|
||||
@@ -103,3 +103,5 @@ $lang->program->cmmiDesc = '<strong>简介:</strong>按阶段规范
|
||||
$lang->program->cannotCreateChild = '该项目已经有实际的内容,无法直接添加子项目。您可以为当前项目创建一个父项目,然后在新的父项目下面添加子项目。';
|
||||
$lang->program->hasChildren = '该项目有子项目存在,不能删除。';
|
||||
$lang->program->confirmDelete = "您确定删除项目[%s]吗?";
|
||||
$lang->program->cannotChangeToCat = "该项目已经有实际的内容,无法修改为父项目";
|
||||
$lang->program->cannotCancelCat = "该项目下已经有子项目,无法取消父项目标记";
|
||||
|
||||
+236
-20
@@ -1,6 +1,15 @@
|
||||
<?php
|
||||
class programModel extends model
|
||||
{
|
||||
/**
|
||||
* Get program list.
|
||||
*
|
||||
* @param varchar $status
|
||||
* @param varchar $orderBy
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getList($status = 'all', $orderBy = 'id_desc', $pager = NULL)
|
||||
{
|
||||
return $this->dao->select('*')->from(TABLE_PROJECT)
|
||||
@@ -20,6 +29,12 @@ class programModel extends model
|
||||
->fetchAll('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get program pairs.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getPairs()
|
||||
{
|
||||
return $this->dao->select('id, name')->from(TABLE_PROJECT)
|
||||
@@ -30,6 +45,13 @@ class programModel extends model
|
||||
->fetchPairs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get program pairs by template.
|
||||
*
|
||||
* @param varchar $template
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getPairsByTemplate($template)
|
||||
{
|
||||
return $this->dao->select('id, name')->from(TABLE_PROJECT)
|
||||
@@ -41,6 +63,15 @@ class programModel extends model
|
||||
->fetchPairs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user programs for block.
|
||||
*
|
||||
* @param varchar $status
|
||||
* @param varchar $orderBy
|
||||
* @param int $limit
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getUserPrograms($status = 'all', $orderBy = 'id_desc', $limit = 15)
|
||||
{
|
||||
$programs = $this->dao->select('*')->from(TABLE_PROJECT)
|
||||
@@ -57,7 +88,7 @@ class programModel extends model
|
||||
if(empty($programs)) return array();
|
||||
$programIdList = array_keys($programs);
|
||||
|
||||
$consumes = $this->dao->select('program, sum(consumed) as consumed')->from(TABLE_TASK)
|
||||
$hours = $this->dao->select('program, sum(consumed) as consumed, sum(estimate) as estimate')->from(TABLE_TASK)
|
||||
->where('program')->in($programIdList)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('parent')->lt(1)
|
||||
@@ -76,6 +107,21 @@ class programModel extends model
|
||||
->groupBy('program')
|
||||
->fetchAll('program');
|
||||
|
||||
$allStories = $this->dao->select('program, count(*) as allStories')->from(TABLE_STORY)
|
||||
->where('program')->in($programIdList)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('status')->ne('draft')
|
||||
->groupBy('program')
|
||||
->fetchAll('program');
|
||||
|
||||
$doneStories = $this->dao->select('program, count(*) as doneStories')->from(TABLE_STORY)
|
||||
->where('program')->in($programIdList)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('status')->eq('closed')
|
||||
->andWhere('closedReason')->eq('done')
|
||||
->groupBy('program')
|
||||
->fetchAll('program');
|
||||
|
||||
$leftStories = $this->dao->select('program, count(*) as leftStories')->from(TABLE_STORY)
|
||||
->where('program')->in($programIdList)
|
||||
->andWhere('deleted')->eq(0)
|
||||
@@ -93,10 +139,13 @@ class programModel extends model
|
||||
foreach($programs as $programID => $program)
|
||||
{
|
||||
$program->teamCount = isset($teams[$programID]) ? $teams[$programID]->count : 0;
|
||||
$program->consumed = isset($consumes[$programID]) ? $consumes[$programID] : 0;
|
||||
$program->leftTasks = isset($leftTasks[$programID]) ? $leftTasks[$programID] : 0;
|
||||
$program->leftStories = isset($leftStories[$programID]) ? $leftStories[$programID] : 0;
|
||||
$program->leftBugs = isset($leftBugs[$programID]) ? $leftBugs[$programID] : 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;
|
||||
}
|
||||
|
||||
return $programs;
|
||||
@@ -166,9 +215,14 @@ class programModel extends model
|
||||
die(js::locate('back'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a program.
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->lang->project->team = $this->lang->project->teamname;
|
||||
$project = fixer::input('post')
|
||||
->setDefault('status', 'wait')
|
||||
->add('type', 'program')
|
||||
@@ -178,14 +232,14 @@ class programModel extends model
|
||||
->setDefault('team', substr($this->post->name,0, 30))
|
||||
->join('whitelist', ',')
|
||||
->cleanInt('budget')
|
||||
->stripTags($this->config->project->editor->create['id'], $this->config->allowedTags)
|
||||
->stripTags($this->config->program->editor->create['id'], $this->config->allowedTags)
|
||||
->remove('products, workDays, delta, branch, uid, plans')
|
||||
->get();
|
||||
|
||||
$project = $this->loadModel('file')->processImgURL($project, $this->config->project->editor->create['id'], $this->post->uid);
|
||||
$project = $this->loadModel('file')->processImgURL($project, $this->config->program->editor->create['id'], $this->post->uid);
|
||||
$this->dao->insert(TABLE_PROJECT)->data($project)
|
||||
->autoCheck()
|
||||
->batchcheck($this->config->project->create->requiredFields, 'notempty')
|
||||
->batchcheck($this->config->program->create->requiredFields, 'notempty')
|
||||
->check('name', 'unique', "deleted='0'")
|
||||
->check('code', 'unique', "deleted='0'")
|
||||
->exec();
|
||||
@@ -249,6 +303,72 @@ class programModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update program.
|
||||
*
|
||||
* @param int $programID
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function update($programID)
|
||||
{
|
||||
$programID = (int)$programID;
|
||||
$oldProgram = $this->dao->findById($programID)->from(TABLE_PROJECT)->fetch();
|
||||
|
||||
$program = fixer::input('post')
|
||||
->setIF($this->post->begin == '0000-00-00', 'begin', '')
|
||||
->setIF($this->post->end == '0000-00-00', 'end', '')
|
||||
->setIF($this->post->acl != 'custom', 'whitelist', '')
|
||||
->setIF($this->post->acl == 'custom' and !isset($_POST['whitelist']), 'whitelist', '')
|
||||
->setDefault('team', $this->post->name)
|
||||
->join('whitelist', ',')
|
||||
->stripTags($this->config->program->editor->edit['id'], $this->config->allowedTags)
|
||||
->remove('products, branch, uid, plans')
|
||||
->get();
|
||||
$program = $this->loadModel('file')->processImgURL($program, $this->config->program->editor->edit['id'], $this->post->uid);
|
||||
|
||||
if(!empty($program->isCat) and $this->checkHasContent($programID)) dao::$errors['isCat'] = $this->lang->program->cannotChangeToCat;
|
||||
if(empty($program->isCat) and $this->checkHasChildren($programID)) dao::$errors['isCat'] = $this->lang->program->cannotCancelCat;
|
||||
if(dao::isError()) return false;
|
||||
|
||||
|
||||
$this->dao->update(TABLE_PROJECT)->data($program)
|
||||
->autoCheck($skipFields = 'begin,end')
|
||||
->batchcheck($this->config->program->edit->requiredFields, 'notempty')
|
||||
->checkIF($program->begin != '', 'begin', 'date')
|
||||
->checkIF($program->end != '', 'end', 'date')
|
||||
->checkIF($program->end != '', 'end', 'gt', $program->begin)
|
||||
->check('name', 'unique', "id!=$programID and deleted='0'")
|
||||
->check('code', 'unique', "id!=$programID and deleted='0'")
|
||||
->where('id')->eq($programID)
|
||||
->limit(1)
|
||||
->exec();
|
||||
|
||||
if(!dao::isError())
|
||||
{
|
||||
$this->file->updateObjectID($this->post->uid, $programID, 'project');
|
||||
if($program->acl != 'open' and ($program->acl != $oldProject->acl or $program->whitelist != $oldProgram->whitelist))
|
||||
{
|
||||
$this->loadModel('user')->updateUserView($programID, 'program');
|
||||
}
|
||||
|
||||
if($oldProgram->parent != $program->parent) $this->moveNode($programID, $program->parent, $oldProgram->path, $oldProgram->grade);
|
||||
|
||||
return common::createChanges($oldProgram, $program);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get program swapper.
|
||||
*
|
||||
* @param object $programs
|
||||
* @param int $programID
|
||||
* @param varchar $currentModule
|
||||
* @param varchar $currentMethod
|
||||
* @param varchar $extra
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
public function getSwapper($programs, $programID, $currentModule, $currentMethod, $extra = '')
|
||||
{
|
||||
$this->loadModel('project');
|
||||
@@ -270,24 +390,36 @@ class programModel extends model
|
||||
return $output;
|
||||
}
|
||||
|
||||
public static function isClickable($project, $action)
|
||||
/**
|
||||
* Judge an action is clickable or not.
|
||||
*
|
||||
* @param object $project
|
||||
* @param string $action
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public static function isClickable($program, $action)
|
||||
{
|
||||
$action = strtolower($action);
|
||||
|
||||
if($action == 'start') return $project->status == 'wait' or $project->status == 'suspended';
|
||||
if($action == 'finish') return $project->status == 'wait' or $project->status == 'doing';
|
||||
if($action == 'close') return $project->status != 'closed';
|
||||
if($action == 'suspend') return $project->status == 'wait' or $project->status == 'doing';
|
||||
if($action == 'activate') return $project->status == 'done';
|
||||
if(empty($program)) return true;
|
||||
|
||||
if($action == 'start') return $program->status == 'wait' or $program->status == 'suspended';
|
||||
if($action == 'finish') return $program->status == 'wait' or $program->status == 'doing';
|
||||
if($action == 'close') return $program->status != 'closed';
|
||||
if($action == 'suspend') return $program->status == 'wait' or $program->status == 'doing';
|
||||
if($action == 'activate') return $program->status == 'done';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getProducts($program)
|
||||
{
|
||||
return $this->dao->select('*')->from(TABLE_PRODUCT)->where('project')->eq($program)->fetchAll('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check has content for program
|
||||
*
|
||||
* @param int $programID
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function checkHasContent($programID)
|
||||
{
|
||||
$count = 0;
|
||||
@@ -312,6 +444,26 @@ class programModel extends model
|
||||
return $count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check has children project.
|
||||
*
|
||||
* @param int $programID
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function checkHasChildren($programID)
|
||||
{
|
||||
$count = $this->dao->select('count(*) as count')->from(TABLE_PROJECT)->where('parent')->eq($programID)->fetch('count');
|
||||
return $count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set program tree path.
|
||||
*
|
||||
* @param int $programID
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function setTreePath($programID)
|
||||
{
|
||||
$program = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($programID)->fetch();
|
||||
@@ -327,5 +479,69 @@ class programModel extends model
|
||||
$path['grade'] = $parent->grade + 1;
|
||||
}
|
||||
$this->dao->update(TABLE_PROJECT)->set('path')->eq($path['path'])->set('grade')->eq($path['grade'])->where('id')->eq($program->id)->exec();
|
||||
return !dao::isError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get program parent pairs
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getParentPairs()
|
||||
{
|
||||
$stmt = $this->dao->select('id,name,parent,path,grade')->from(TABLE_PROJECT)->where('isCat')->eq(1)->andWhere('deleted')->eq(0)->orderBy('grade, `order`')->query();
|
||||
|
||||
$pairs = array();
|
||||
$pairs[0] = '/';
|
||||
while($program = $stmt->fetch())
|
||||
{
|
||||
if($program->grade == 1)
|
||||
{
|
||||
$pairs[$program->id] = '/' . $program->name;
|
||||
continue;
|
||||
}
|
||||
|
||||
$programName = '/' . $program->name;
|
||||
$pairs[$program->id] = isset($pairs[$program->parent]) ? $pairs[$program->parent] . $programName : $programName;
|
||||
}
|
||||
|
||||
return $pairs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move project node.
|
||||
*
|
||||
* @param int $programID
|
||||
* @param int $parentID
|
||||
* @param string $oldPath
|
||||
* @param int $oldGrade
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function moveNode($programID, $parentID, $oldPath, $oldGrade)
|
||||
{
|
||||
$parent = $this->dao->select('id,parent,path,grade')->from(TABLE_PROJECT)->where('id')->eq($parentID)->fetch();
|
||||
|
||||
$childNodes = $this->dao->select('id,parent,path,grade')->from(TABLE_PROJECT)
|
||||
->where('path')->like("{$oldPath}%")
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('template')->ne('')
|
||||
->orderBy('grade')
|
||||
->fetchAll();
|
||||
/* Process child node path and grade field. */
|
||||
foreach($childNodes as $childNode)
|
||||
{
|
||||
$path = substr($childNode->path, strpos($childNode->path, ",{$programID},"));
|
||||
$grade = $oldGrade - $childNode->grade + 1;
|
||||
if($parent)
|
||||
{
|
||||
$path = rtrim($parent->path, ',') . $path;
|
||||
$grade = $parent->grade + $grade;
|
||||
}
|
||||
$this->dao->update(TABLE_PROJECT)->set('path')->eq($path)->set('grade')->eq($grade)->where('id')->eq($childNode->id)->exec();
|
||||
}
|
||||
|
||||
return !dao::isError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class='row cell' 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");?>'>
|
||||
<div class='panel' data-url='<?php echo $this->createLink('program', 'index', "programID=$program->id", '', '', $program->id);?>'>
|
||||
<div class='panel-heading'>
|
||||
<strong class='program-name' title='<?php echo $program->name;?>'><?php echo $program->name;?></strong>
|
||||
<?php if($program->template === 'cmmi'): ?>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
</td>
|
||||
<td class='text-left'><?php echo $program->code;?></td>
|
||||
<td class='text-left pgm-title' title='<?php echo $program->name?>'>
|
||||
<?php echo html::a(inlink('index', "programID=$program->id"), $program->name);?>
|
||||
<?php echo html::a($this->createLink('program', 'index', "programID=$program->id", '', '', $program->id), $program->name);?>
|
||||
</td>
|
||||
<td class='c-status'><span class="status-program status-<?php echo $program->status?>"><?php echo zget($lang->project->statusList, $program->status, '');?></span></td>
|
||||
<td class='text-center'><?php echo $program->begin;?></td>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* The create view of project module of ZenTaoPMS.
|
||||
* The edit view of program 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 Chunsheng Wang <chunsheng@cnezsoft.com>
|
||||
* @package project
|
||||
* @package program
|
||||
* @version $Id: create.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
@@ -21,46 +21,56 @@
|
||||
<form class='form-indicator main-form form-ajax' method='post' target='hiddenwin' id='dataform'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th class='w-120px'><?php echo $lang->program->name;?></th>
|
||||
<td class="col-main"><?php echo html::input('name', $project->name, "class='form-control' required");?></td>
|
||||
<th class='w-120px'><?php echo $lang->program->parent;?></th>
|
||||
<td class="col-main"><?php echo html::select('parent', $parents, $program->parent, "class='form-control chosen'");?></td>
|
||||
<td></td><td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->code;?></th>
|
||||
<td><?php echo html::input('code', $project->code, "class='form-control' required");?></td><td></td><td></td>
|
||||
<th class='w-120px'><?php echo $lang->program->name;?></th>
|
||||
<td class="col-main"><?php echo html::input('name', $program->name, "class='form-control' required");?></td>
|
||||
<td>
|
||||
<div class="checkbox-primary">
|
||||
<input type="checkbox" name="isCat" value="1" id="isCat" <?php if($program->isCat) echo "checked";?>>
|
||||
<label for="isCat"><?php echo $lang->program->parent;?></label>
|
||||
</div>
|
||||
</td><td></td>
|
||||
</tr>
|
||||
<?php if($project->template == 'cmmi'):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->code;?></th>
|
||||
<td><?php echo html::input('code', $program->code, "class='form-control' required");?></td><td></td><td></td>
|
||||
</tr>
|
||||
<?php if($program->template == 'cmmi'):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->category;?></th>
|
||||
<td><?php echo html::select('category', $lang->program->categoryList, $project->category, "class='form-control'");?></td><td></td><td></td>
|
||||
<td><?php echo html::select('category', $lang->program->categoryList, $program->category, "class='form-control'");?></td><td></td><td></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->PM;?></th>
|
||||
<td><?php echo html::select('PM', $pmUsers, $project->PM, "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::select('PM', $pmUsers, $program->PM, "class='form-control chosen'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->budget;?></th>
|
||||
<td><?php echo html::input('budget', $project->budget, "class='form-control'");?></td>
|
||||
<td style='float:left'><?php echo html::select('budgetUnit', $lang->program->unitList, $project->budgetUnit, "class='form-control'");?></td><td></td>
|
||||
<td><?php echo html::input('budget', $program->budget, "class='form-control'");?></td>
|
||||
<td style='float:left'><?php echo html::select('budgetUnit', $lang->program->unitList, $program->budgetUnit, "class='form-control'");?></td><td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->dateRange;?></th>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<?php echo html::input('begin', $project->begin, "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->program->begin . "' required");?>
|
||||
<?php echo html::input('begin', $program->begin, "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->program->begin . "' required");?>
|
||||
<span class='input-group-addon'><?php echo $lang->program->to;?></span>
|
||||
<?php echo html::input('end', $project->end, "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->program->end . "' required");?>
|
||||
<?php echo html::input('end', $program->end, "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->program->end . "' required");?>
|
||||
</div>
|
||||
</td>
|
||||
<td colspan='2'></td>
|
||||
</tr>
|
||||
<?php if($project->template == 'scrum'):?>
|
||||
<?php if($program->template == 'scrum'):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->project->days;?></th>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<?php echo html::input('days', $project->days, "class='form-control'");?>
|
||||
<?php echo html::input('days', $program->days, "class='form-control'");?>
|
||||
<span class='input-group-addon'><?php echo $lang->project->day;?></span>
|
||||
</div>
|
||||
</td><td></td><td></td>
|
||||
@@ -68,30 +78,30 @@
|
||||
<?php endif;?>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->realStarted;?></th>
|
||||
<td><?php echo html::input('realStarted', $project->realStarted, "class='form-control form-date'");?></td><td></td><td></td>
|
||||
<td><?php echo html::input('realStarted', $program->realStarted, "class='form-control form-date'");?></td><td></td><td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->project->teamname;?></th>
|
||||
<td><?php echo html::input('team', $project->team, "class='form-control'");?></td><td></td><td></td>
|
||||
<td><?php echo html::input('team', $program->team, "class='form-control'");?></td><td></td><td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->desc;?></th>
|
||||
<td colspan='3'>
|
||||
<?php echo $this->fetch('user', 'ajaxPrintTemplates', 'type=project&link=desc');?>
|
||||
<?php echo html::textarea('desc', $project->desc, "rows='6' class='form-control kindeditor' hidefocus='true'");?>
|
||||
<?php echo $this->fetch('user', 'ajaxPrintTemplates', 'type=program&link=desc');?>
|
||||
<?php echo html::textarea('desc', $program->desc, "rows='6' class='form-control kindeditor' hidefocus='true'");?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->privway;?></th>
|
||||
<td colspan='3'><?php echo html::radio('privway', $lang->program->privwayList, $project->privway, '', 'block');?></td>
|
||||
<td colspan='3'><?php echo html::radio('privway', $lang->program->privwayList, $program->privway, '', 'block');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->project->acl;?></th>
|
||||
<td colspan='3'><?php echo nl2br(html::radio('acl', $lang->program->aclList, $project->acl, "onclick='setWhite(this.value);'", 'block'));?></td>
|
||||
<td colspan='3'><?php echo nl2br(html::radio('acl', $lang->program->aclList, $program->acl, "onclick='setWhite(this.value);'", 'block'));?></td>
|
||||
</tr>
|
||||
<tr id='whitelistBox' <?php if($project->acl != 'custom') echo "class='hidden'";?>>
|
||||
<tr id='whitelistBox' <?php if($program->acl != 'custom') echo "class='hidden'";?>>
|
||||
<th><?php echo $lang->project->whitelist;?></th>
|
||||
<td colspan='3'><?php echo html::checkbox('whitelist', $groups, $project->whitelist, '', '', 'inline');?></td>
|
||||
<td colspan='3'><?php echo html::checkbox('whitelist', $groups, $program->whitelist, '', '', 'inline');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='4' class='text-center form-actions'>
|
||||
|
||||
@@ -935,11 +935,12 @@ class project extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function burn($projectID = 0, $type = 'noweekend', $interval = 0)
|
||||
public function burn($projectID = 0, $type = 'noweekend', $interval = 0, $burnBy = 'left')
|
||||
{
|
||||
$this->loadModel('report');
|
||||
$project = $this->commonAction($projectID);
|
||||
$projectID = $project->id;
|
||||
$burnBy = $this->cookie->burnBy ? $this->cookie->burnBy : $burnBy;
|
||||
|
||||
/* Header and position. */
|
||||
$title = $project->name . $this->lang->colon . $this->lang->project->burn;
|
||||
@@ -949,7 +950,7 @@ class project extends control
|
||||
/* Get date list. */
|
||||
$projectInfo = $this->project->getByID($projectID);
|
||||
list($dateList, $interval) = $this->project->getDateList($projectInfo->begin, $projectInfo->end, $type, $interval, 'Y-m-d');
|
||||
$chartData = $this->project->buildBurnData($projectID, $dateList, $type);
|
||||
$chartData = $this->project->buildBurnData($projectID, $dateList, $type, $burnBy);
|
||||
|
||||
$dayList = array_fill(1, floor($project->days / $this->config->project->maxBurnDay) + 5, '');
|
||||
foreach($dayList as $key => $val) $dayList[$key] = $this->lang->project->interval . ($key + 1) . $this->lang->day;
|
||||
@@ -958,6 +959,7 @@ class project extends control
|
||||
$this->view->title = $title;
|
||||
$this->view->position = $position;
|
||||
$this->view->tabID = 'burn';
|
||||
$this->view->burnBy = $burnBy;
|
||||
$this->view->projectID = $projectID;
|
||||
$this->view->projectName = $project->name;
|
||||
$this->view->type = $type;
|
||||
|
||||
@@ -5,3 +5,5 @@
|
||||
#burnLegend > div {position: relative; padding-left: 30px;}
|
||||
#burnLegend > div > .barline {position: absolute; width: 20px; left: 0; top: 13px; height: 3px; background: #EEEEEE;}
|
||||
#burnLegend .line-real .bg-primary{background: #1183fb}
|
||||
|
||||
.pull-left .input-control{margin-right: 10px}
|
||||
|
||||
@@ -117,6 +117,12 @@ $lang->project->aclList['open'] = "默认设置(有{$lang->projectCommon}视
|
||||
$lang->project->aclList['private'] = "私有{$lang->projectCommon}(只有{$lang->projectCommon}团队成员才能访问)";
|
||||
$lang->project->aclList['custom'] = "自定义白名单(团队成员和白名单的成员可以访问)";
|
||||
|
||||
$lang->project->storyPoint = '故事点';
|
||||
|
||||
$lang->project->burnByList['left'] = '按剩余工时查看';
|
||||
$lang->project->burnByList['estimate'] = '按计划工时查看';
|
||||
$lang->project->burnByList['storyPoint'] = '按故事点查看';
|
||||
|
||||
/* 方法列表。*/
|
||||
$lang->project->index = "{$lang->projectCommon}主页";
|
||||
$lang->project->task = '任务列表';
|
||||
|
||||
@@ -1969,6 +1969,23 @@ class projectModel extends model
|
||||
->andWhere('status')->eq('closed')
|
||||
->groupBy('project')
|
||||
->fetchAll('project');
|
||||
$finishedEstimates = $this->dao->select("project, sum(`estimate`) AS `estimate`")->from(TABLE_TASK)
|
||||
->where('project')->in(array_keys($projects))
|
||||
->andWhere('deleted')->eq('0')
|
||||
->andWhere('parent')->ge('0')
|
||||
->andWhere('status')->eq('done')
|
||||
->orWhere('status')->eq('closed')
|
||||
->groupBy('project')
|
||||
->fetchAll('project');
|
||||
$storyPoints = $this->dao->select('t1.project, sum(t2.estimate) AS `storyPoint`')->from(TABLE_PROJECTSTORY)->alias('t1')
|
||||
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id')
|
||||
->leftJoin(TABLE_PRODUCT)->alias('t3')->on('t2.product = t3.id')
|
||||
->where('t1.project')->in(array_keys($projects))
|
||||
->andWhere('t2.deleted')->eq(0)
|
||||
->andWhere('t2.status')->ne('closed')
|
||||
->andWhere('t2.stage')->in('wait,planned,projected,developing')
|
||||
->groupBy('project')
|
||||
->fetchAll('project');
|
||||
|
||||
foreach($burns as $projectID => $burn)
|
||||
{
|
||||
@@ -1978,6 +1995,14 @@ class projectModel extends model
|
||||
$burn->left -= (int)$closedLeft->left;
|
||||
}
|
||||
|
||||
if(isset($finishedEstimates[$projectID]))
|
||||
{
|
||||
$finishedEstimate = $finishedEstimates[$projectID];
|
||||
$burn->estimate -= (int)$finishedEstimate->estimate;
|
||||
}
|
||||
|
||||
if(isset($storyPoints[$projectID])) $burn->storyPoint = $storyPoints[$projectID]->storyPoint;
|
||||
|
||||
$this->dao->replace(TABLE_BURN)->data($burn)->exec();
|
||||
$burn->projectName = $projects[$burn->project];
|
||||
}
|
||||
@@ -2013,16 +2038,17 @@ class projectModel extends model
|
||||
* Get burn data for flot
|
||||
*
|
||||
* @param int $projectID
|
||||
* @param string $burnBy
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getBurnDataFlot($projectID = 0)
|
||||
public function getBurnDataFlot($projectID = 0, $burnBy = '')
|
||||
{
|
||||
/* Get project and burn counts. */
|
||||
$project = $this->getById($projectID);
|
||||
|
||||
/* If the burnCounts > $itemCounts, get the latest $itemCounts records. */
|
||||
$sets = $this->dao->select('date AS name, `left` AS value, estimate')->from(TABLE_BURN)->where('project')->eq((int)$projectID)->andWhere('task')->eq(0)->orderBy('date DESC')->fetchAll('name');
|
||||
$sets = $this->dao->select("date AS name, `$burnBy` AS value, `$burnBy`")->from(TABLE_BURN)->where('project')->eq((int)$projectID)->andWhere('task')->eq(0)->orderBy('date DESC')->fetchAll('name');
|
||||
|
||||
$count = 0;
|
||||
$burnData = array();
|
||||
@@ -2757,19 +2783,21 @@ class projectModel extends model
|
||||
* @param int $projectID
|
||||
* @param array $dateList
|
||||
* @param string $type
|
||||
* @param string $burnBy
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function buildBurnData($projectID, $dateList, $type)
|
||||
public function buildBurnData($projectID, $dateList, $type, $burnBy = 'left')
|
||||
{
|
||||
$this->loadModel('report');
|
||||
$burnBy = $burnBy ? $burnBy : 'left';
|
||||
|
||||
$sets = $this->getBurnDataFlot($projectID);
|
||||
$sets = $this->getBurnDataFlot($projectID, $burnBy);
|
||||
$limitJSON = '[]';
|
||||
$baselineJSON = '[]';
|
||||
|
||||
$firstBurn = empty($sets) ? 0 : reset($sets);
|
||||
$firstTime = !empty($firstBurn->estimate) ? $firstBurn->estimate : (!empty($firstBurn->value) ? $firstBurn->value : 0);
|
||||
$firstTime = !empty($firstBurn->$burnBy) ? $firstBurn->$burnBy : (!empty($firstBurn->value) ? $firstBurn->value : 0);
|
||||
$days = count($dateList) - 1;
|
||||
$rate = $firstTime / $days;
|
||||
$baselineJSON = '[';
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
common::printLink('project', 'fixFirst', "project=$project->id", $lang->project->fixFirst, '', "class='btn btn-link iframe' data-width='700'");
|
||||
echo $lang->project->howToUpdateBurn;
|
||||
?>
|
||||
<div class='input-control w-150px'>
|
||||
<?php echo html::select('burnBy', $lang->project->burnByList, $burnBy, "class='form-control chosen'");?>
|
||||
</div>
|
||||
<?php if($interval):?>
|
||||
<div class='input-control thWidth'>
|
||||
<?php echo html::select('interval', $dayList, $interval, "class='form-control chosen'");?>
|
||||
@@ -37,12 +40,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<h2 class='text-center'><?php echo $projectName . ' ' . $this->lang->project->burn;?></h2>
|
||||
<h2 class='text-center'><?php echo $projectName . ' ' . $this->lang->project->burn . '(' . zget($lang->project->burnByList, $burnBy) . ')';?></h2>
|
||||
<div id="burnWrapper">
|
||||
<div id="burnChart">
|
||||
<canvas id="burnCanvas"></canvas>
|
||||
</div>
|
||||
<div id="burnYUnit"><?php echo "({$lang->project->workHour})";?></div>
|
||||
<div id="burnYUnit"><?php echo $burnBy == 'storyPoint' ? "({$lang->project->storyPoint})" : "({$lang->project->workHour})";?></div>
|
||||
<div id="burnLegend">
|
||||
<div class="line-ref"><div class='barline'></div><?php echo $lang->project->charts->burn->graph->reference;?></div>
|
||||
<div class="line-real"><div class='barline bg-primary'></div><?php echo $lang->project->charts->burn->graph->actuality;?></div>
|
||||
@@ -50,6 +53,13 @@
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$('#burnBy').change(function()
|
||||
{
|
||||
$.cookie('burnBy', $(this).val(), {expires:config.cookieLife, path:config.webRoot});
|
||||
var interval = typeof($('#interval').val()) == 'undefined' ? 0 : $('#interval').val() ;
|
||||
location.href = createLink('project', 'burn', 'projectID=' + projectID + '&type=' + type + '&interval=' + interval + '&burnBy=' + $(this).val());
|
||||
});
|
||||
|
||||
function initBurnChar()
|
||||
{
|
||||
var themePrimaryColor = $.getThemeColor('primary');
|
||||
|
||||
@@ -208,6 +208,8 @@ class riskModel extends model
|
||||
{
|
||||
return $this->dao->select('*')->from(TABLE_RISK)
|
||||
->where('program')->eq($this->session->program)
|
||||
->beginIF($browseType != 'all' and $browseType != 'assignTo')->andWhere('status')->eq($browseType)->fi()
|
||||
->beginIF($browseType == 'assignTo')->andWhere('assignedTo')->eq($this->app->user->account)->fi()
|
||||
->andWhere('deleted')->eq('0')
|
||||
->orderBy($orderBy)
|
||||
->limit($limit)
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
$(function()
|
||||
{
|
||||
if(typeof(storyType) == 'undefined') storyType = '';
|
||||
$('#subNavbar .nav li').removeClass('active');
|
||||
$("#subNavbar .nav li[data-id=" + storyType + ']').addClass('active');
|
||||
})
|
||||
|
||||
function getStatus(method, params)
|
||||
{
|
||||
$.get(createLink('story', 'ajaxGetStatus', "method=" + method + '¶ms=' + params), function(status)
|
||||
|
||||
+45
-43
@@ -9,49 +9,51 @@
|
||||
* @version $Id: zh-cn.php 5141 2013-07-15 05:57:15Z chencongzhi520@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
$lang->story->create = "提{$lang->storyCommon}";
|
||||
$lang->story->batchCreate = "批量创建";
|
||||
$lang->story->change = "变更";
|
||||
$lang->story->changeAction = "变更{$lang->storyCommon}";
|
||||
$lang->story->changed = "{$lang->storyCommon}变更";
|
||||
$lang->story->assignTo = '指派';
|
||||
$lang->story->assignAction = "指派{$lang->storyCommon}";
|
||||
$lang->story->review = '评审';
|
||||
$lang->story->reviewAction = "评审{$lang->storyCommon}";
|
||||
$lang->story->needReview = '需要评审';
|
||||
$lang->story->batchReview = '批量评审';
|
||||
$lang->story->edit = "编辑";
|
||||
$lang->story->batchEdit = "批量编辑";
|
||||
$lang->story->subdivide = '细分';
|
||||
$lang->story->subdivideAction = "细分{$lang->storyCommon}";
|
||||
$lang->story->splitRequirent = '拆分';
|
||||
$lang->story->close = '关闭';
|
||||
$lang->story->closeAction = "关闭{$lang->storyCommon}";
|
||||
$lang->story->batchClose = '批量关闭';
|
||||
$lang->story->activate = '激活';
|
||||
$lang->story->activateAction = "激活{$lang->storyCommon}";
|
||||
$lang->story->delete = "删除";
|
||||
$lang->story->deleteAction = "删除{$lang->storyCommon}";
|
||||
$lang->story->view = "{$lang->storyCommon}详情";
|
||||
$lang->story->setting = "设置";
|
||||
$lang->story->tasks = "相关任务";
|
||||
$lang->story->bugs = "相关Bug";
|
||||
$lang->story->cases = "相关用例";
|
||||
$lang->story->taskCount = '任务数';
|
||||
$lang->story->bugCount = 'Bug数';
|
||||
$lang->story->caseCount = '用例数';
|
||||
$lang->story->taskCountAB = 'T';
|
||||
$lang->story->bugCountAB = 'B';
|
||||
$lang->story->caseCountAB = 'C';
|
||||
$lang->story->linkStory = "关联{$lang->storyCommon}";
|
||||
$lang->story->unlinkStory = "移除相关{$lang->storyCommon}";
|
||||
$lang->story->export = "导出数据";
|
||||
$lang->story->exportAction = "导出{$lang->storyCommon}";
|
||||
$lang->story->zeroCase = "零用例{$lang->storyCommon}";
|
||||
$lang->story->zeroTask = "只列零任务{$lang->storyCommon}";
|
||||
$lang->story->reportChart = "统计报表";
|
||||
$lang->story->reportAction = "统计报表";
|
||||
$lang->story->copyTitle = "同{$lang->storyCommon}名称";
|
||||
$lang->story->create = "提{$lang->storyCommon}";
|
||||
$lang->story->createStory = '添加软需';
|
||||
$lang->story->createRequirement = '添加用需';
|
||||
$lang->story->batchCreate = "批量创建";
|
||||
$lang->story->change = "变更";
|
||||
$lang->story->changeAction = "变更{$lang->storyCommon}";
|
||||
$lang->story->changed = "{$lang->storyCommon}变更";
|
||||
$lang->story->assignTo = '指派';
|
||||
$lang->story->assignAction = "指派{$lang->storyCommon}";
|
||||
$lang->story->review = '评审';
|
||||
$lang->story->reviewAction = "评审{$lang->storyCommon}";
|
||||
$lang->story->needReview = '需要评审';
|
||||
$lang->story->batchReview = '批量评审';
|
||||
$lang->story->edit = "编辑";
|
||||
$lang->story->batchEdit = "批量编辑";
|
||||
$lang->story->subdivide = '细分';
|
||||
$lang->story->subdivideAction = "细分{$lang->storyCommon}";
|
||||
$lang->story->splitRequirent = '拆分';
|
||||
$lang->story->close = '关闭';
|
||||
$lang->story->closeAction = "关闭{$lang->storyCommon}";
|
||||
$lang->story->batchClose = '批量关闭';
|
||||
$lang->story->activate = '激活';
|
||||
$lang->story->activateAction = "激活{$lang->storyCommon}";
|
||||
$lang->story->delete = "删除";
|
||||
$lang->story->deleteAction = "删除{$lang->storyCommon}";
|
||||
$lang->story->view = "{$lang->storyCommon}详情";
|
||||
$lang->story->setting = "设置";
|
||||
$lang->story->tasks = "相关任务";
|
||||
$lang->story->bugs = "相关Bug";
|
||||
$lang->story->cases = "相关用例";
|
||||
$lang->story->taskCount = '任务数';
|
||||
$lang->story->bugCount = 'Bug数';
|
||||
$lang->story->caseCount = '用例数';
|
||||
$lang->story->taskCountAB = 'T';
|
||||
$lang->story->bugCountAB = 'B';
|
||||
$lang->story->caseCountAB = 'C';
|
||||
$lang->story->linkStory = "关联{$lang->storyCommon}";
|
||||
$lang->story->unlinkStory = "移除相关{$lang->storyCommon}";
|
||||
$lang->story->export = "导出数据";
|
||||
$lang->story->exportAction = "导出{$lang->storyCommon}";
|
||||
$lang->story->zeroCase = "零用例{$lang->storyCommon}";
|
||||
$lang->story->zeroTask = "只列零任务{$lang->storyCommon}";
|
||||
$lang->story->reportChart = "统计报表";
|
||||
$lang->story->reportAction = "统计报表";
|
||||
$lang->story->copyTitle = "同{$lang->storyCommon}名称";
|
||||
$lang->story->batchChangePlan = "批量修改计划";
|
||||
$lang->story->batchChangeBranch = "批量修改分支";
|
||||
$lang->story->batchChangeStage = "批量修改阶段";
|
||||
|
||||
+51
-18
@@ -993,29 +993,62 @@ class storyModel extends model
|
||||
{
|
||||
$now = helper::now();
|
||||
$oldStory = $this->dao->findById($storyID)->from(TABLE_STORY)->fetch();
|
||||
if($oldStory->type == 'requirement')
|
||||
{
|
||||
foreach($stories as $id)
|
||||
{
|
||||
$data = new stdclass();
|
||||
$data->product = $oldStory->product;
|
||||
$data->AType = 'requirement';
|
||||
$data->relation = 'subdivideinto';
|
||||
$data->BType = 'story';
|
||||
$data->AID = $storyID;
|
||||
$data->BID = $id;
|
||||
$data->AVersion = $oldStory->version;
|
||||
$data->BVersion = 1;
|
||||
$data->extra = 1;
|
||||
|
||||
/* Set parent to child story. */
|
||||
$this->dao->update(TABLE_STORY)->set('parent')->eq($storyID)->where('id')->in($stories)->exec();
|
||||
$this->computeEstimate($storyID);
|
||||
$this->dao->insert(TABLE_RELATION)->data($data)->autoCheck()->exec();
|
||||
|
||||
/* Set childStories. */
|
||||
$childStories = join(',', $stories);
|
||||
$data->AType = 'story';
|
||||
$data->relation = 'subdividedfrom';
|
||||
$data->BType = 'requirement';
|
||||
$data->AID = $id;
|
||||
$data->BID = $storyID;
|
||||
$data->AVersion = 1;
|
||||
$data->BVersion = $oldStory->version;
|
||||
|
||||
$newStory = new stdClass();
|
||||
$newStory->parent = '-1';
|
||||
$newStory->plan = 0;
|
||||
$newStory->lastEditedBy = $this->app->user->account;
|
||||
$newStory->lastEditedDate = $now;
|
||||
$newStory->childStories = trim($oldStory->childStories . ',' . $childStories, ',');
|
||||
$this->dao->insert(TABLE_RELATION)->data($data)->autoCheck()->exec();
|
||||
}
|
||||
|
||||
/* Subdivide story. */
|
||||
$this->dao->update(TABLE_STORY)->data($newStory)->autoCheck()->where('id')->eq($storyID)->exec();
|
||||
|
||||
$changes = common::createChanges($oldStory, $newStory);
|
||||
if($changes)
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
die(js::locate(helper::createLink('product', 'browse', "productID=$oldStory->product&branch=0&browseType=unclosed&queryID=0&type=story"), 'parent.parent'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$actionID = $this->loadModel('action')->create('story', $storyID, 'createChildrenStory', '', $childStories);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
/* Set parent to child story. */
|
||||
$this->dao->update(TABLE_STORY)->set('parent')->eq($storyID)->where('id')->in($stories)->exec();
|
||||
$this->computeEstimate($storyID);
|
||||
|
||||
/* Set childStories. */
|
||||
$childStories = join(',', $stories);
|
||||
|
||||
$newStory = new stdClass();
|
||||
$newStory->parent = '-1';
|
||||
$newStory->plan = 0;
|
||||
$newStory->lastEditedBy = $this->app->user->account;
|
||||
$newStory->lastEditedDate = $now;
|
||||
$newStory->childStories = trim($oldStory->childStories . ',' . $childStories, ',');
|
||||
|
||||
/* Subdivide story. */
|
||||
$this->dao->update(TABLE_STORY)->data($newStory)->autoCheck()->where('id')->eq($storyID)->exec();
|
||||
|
||||
$changes = common::createChanges($oldStory, $newStory);
|
||||
if($changes)
|
||||
{
|
||||
$actionID = $this->loadModel('action')->create('story', $storyID, 'createChildrenStory', '', $childStories);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php if($type == 'story'):?>
|
||||
<tr>
|
||||
<th class='planTh'><?php echo $lang->story->planAB;?></th>
|
||||
<td colspan="2">
|
||||
@@ -88,6 +89,7 @@
|
||||
</td>
|
||||
<?php endif;?>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->reviewedBy;?></th>
|
||||
<td><?php echo html::select('assignedTo', $users, empty($needReview) ? $product->PO : '', "class='form-control chosen'");?></td>
|
||||
@@ -99,6 +101,20 @@
|
||||
</div>
|
||||
</td>
|
||||
<?php endif;?>
|
||||
<?php if($type == 'requirement'):?>
|
||||
<?php if(strpos(",$showFields,", ',source,') !== false):?>
|
||||
<td colspan="2" class='sourceTd'>
|
||||
<div class="input-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon"><?php echo $lang->story->source;?></div>
|
||||
<?php echo html::select('source', $lang->story->sourceList, $source, "class='form-control chosen'");?>
|
||||
<span class='input-group-addon'><?php echo $lang->story->sourceNote;?></span>
|
||||
<?php echo html::input('sourceNote', $sourceNote, "class='form-control' style='width:140px;'");?>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<?php endif;?>
|
||||
<?php endif;?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->title;?></th>
|
||||
|
||||
@@ -3804,6 +3804,7 @@ class upgradeModel extends model
|
||||
if(dao::isError()) return false;
|
||||
|
||||
$programID = $this->dao->lastInsertId();
|
||||
$this->dao->update(TABLE_PROJECT)->set('grade')->eq(1)->set('path')->eq(",{$programID},")->where('id')->eq($programID)->exec();
|
||||
|
||||
if($pgmAdmins)
|
||||
{
|
||||
|
||||
@@ -17,8 +17,9 @@ class weekly extends control
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
}
|
||||
|
||||
public function index($program, $date = '')
|
||||
public function index($program = 0, $date = '')
|
||||
{
|
||||
$program = $program ? $program : $this->session->program;
|
||||
if(!$date) $date = helper::today();
|
||||
$date = date('Y-m-d', strtotime($date));
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ class weeklyModel extends model
|
||||
if(!$date) $date = date('Y-m-d');
|
||||
$monday = $this->getThisMonday($date);
|
||||
$sunday = $this->getThisSunday($date);
|
||||
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $type = 'project', $program);
|
||||
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $program);
|
||||
$projectIdList = array_keys($projects);
|
||||
|
||||
return $this->dao->select('count(distinct t1.account) as count')
|
||||
@@ -128,7 +128,7 @@ class weeklyModel extends model
|
||||
$monday = $this->getThisMonday($date);
|
||||
$sunday = $this->getThisSunday($date);
|
||||
|
||||
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $type = 'project', $program);
|
||||
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $program);
|
||||
$projectIdList = array_keys($projects);
|
||||
|
||||
$tasks = $this->dao->select('*')
|
||||
@@ -148,7 +148,7 @@ class weeklyModel extends model
|
||||
$sunday = $this->getThisSunday($date);
|
||||
$nextMonday = date('Y-m-d', strtotime("$sunday +1 days"));
|
||||
|
||||
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $type = 'project', $program);
|
||||
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $program);
|
||||
$projectIdList = array_keys($projects);
|
||||
$unFinished = $this->dao->select('*')
|
||||
->from(TABLE_TASK)
|
||||
@@ -177,7 +177,7 @@ class weeklyModel extends model
|
||||
$nextMonday = date('Y-m-d', strtotime("$sunday +1 days"));
|
||||
$sencondMondy = date('Y-m-d', strtotime("$sunday +8 days"));
|
||||
|
||||
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $type = 'project', $program);
|
||||
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $program);
|
||||
$projectIdList = array_keys($projects);
|
||||
|
||||
$tasks = $this->dao->select('*')
|
||||
@@ -197,7 +197,7 @@ class weeklyModel extends model
|
||||
$nextMonday = date('Y-m-d', strtotime("$sunday +1 days"));
|
||||
$sencondMondy = date('Y-m-d', strtotime("$sunday +8 days"));
|
||||
|
||||
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $type = 'project', $program);
|
||||
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $program);
|
||||
$projectIdList = array_keys($projects);
|
||||
|
||||
return $this->dao->select('type, sum(cast(estimate as decimal(10,2))) as workload')
|
||||
@@ -213,7 +213,7 @@ class weeklyModel extends model
|
||||
$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, $type = 'project', $program);
|
||||
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $program);
|
||||
$projectIdList = array_keys($projects);
|
||||
|
||||
return $this->dao->select('*')
|
||||
@@ -237,7 +237,7 @@ 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, $type = 'project', $program->id);
|
||||
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $program->id);
|
||||
$projectIdList = array_keys($projects);
|
||||
|
||||
$tasks = $this->dao->select('*')->from(TABLE_TASK)
|
||||
@@ -269,7 +269,7 @@ class weeklyModel extends model
|
||||
$report = $this->getFromDB($program, $date);
|
||||
if(!empty($report)) return $report->ev;
|
||||
|
||||
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $type = 'project', $program);
|
||||
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $program);
|
||||
$projectIdList = array_keys($projects);
|
||||
|
||||
if(!$date) $date = date('Y-m-d');
|
||||
@@ -310,7 +310,7 @@ class weeklyModel extends model
|
||||
|
||||
$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, $type = 'project', $program);
|
||||
$projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $program);
|
||||
$projectIdList = array_keys($projects);
|
||||
|
||||
$AC = $this->dao->select('sum(t1.consumed) as consumed')
|
||||
|
||||
@@ -11,8 +11,9 @@
|
||||
*/
|
||||
class workestimation extends control
|
||||
{
|
||||
public function index($program)
|
||||
public function index($program = 0)
|
||||
{
|
||||
$program = $program ? $program : $this->session->program;
|
||||
if($_POST)
|
||||
{
|
||||
$result = $this->workestimation->save($program);
|
||||
|
||||
Reference in New Issue
Block a user