Merge branch '20.x' of github.com:easysoft/zentaopms into 20.x

This commit is contained in:
tianshujie98
2020-08-25 13:33:03 +08:00
28 changed files with 952 additions and 256 deletions
+1
View File
@@ -224,6 +224,7 @@ $config->objectTables['module'] = TABLE_MODULE;
$config->objectTables['caselib'] = TABLE_TESTSUITE;
$config->objectTables['entry'] = TABLE_ENTRY;
$config->objectTables['webhook'] = TABLE_WEBHOOK;
$config->objectTables['risk'] = TABLE_RISK;
/* Program privs.*/
$config->programPriv = new stdclass();
+1 -1
View File
@@ -292,4 +292,4 @@ 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`;
ALTER TABLE `zt_block` ADD UNIQUE `account_module_type_order` (`account`, `module`, `type`, `order`), DROP INDEX `accountModuleOrder`;
+1
View File
@@ -22,6 +22,7 @@ $config->action->objectNameFields['caselib'] = 'name';
$config->action->objectNameFields['testreport'] = 'title';
$config->action->objectNameFields['entry'] = 'name';
$config->action->objectNameFields['webhook'] = 'name';
$config->action->objectNameFields['risk'] = 'name';
$config->action->commonImgSize = 870;
+19 -12
View File
@@ -1178,7 +1178,7 @@ class block extends control
$begin = $program->begin;
$today = helper::today();
$end = date('Y-m-d', strtotime("$today + 7 days"));
$end = date('Y-m-d', strtotime($today));
$projects = $this->project->getProjectsByProgram($program);
$projectIdList = array_keys($projects);
@@ -1188,14 +1188,15 @@ class block extends control
$charts['AC'] = '[';
$i = 1;
$start = $begin;
$longProgram = helper::diffDate($today, $begin) / 7 > 10;
while($start < $end)
{
$charts['labels'][] = $this->lang->milestone->chart->time . $i . $this->lang->milestone->chart->week;
$sunday = $this->weekly->getThisSunday($start);
$charts['PV'] .= $this->milestone->getPV($projectIdList, $begin, $sunday) . ',';
$charts['EV'] .= $this->milestone->getEV($projectIdList, $begin, $sunday) . ',';
$charts['AC'] .= $this->milestone->getAC($projectIdList, $begin, $sunday) . ',';
$start = date('Y-m-d', strtotime("$start + 7 days"));
$charts['labels'][] = $longProgram ? $this->lang->milestone->chart->time . $i . $this->lang->milestone->chart->month : $this->lang->milestone->chart->time . $i . $this->lang->milestone->chart->week;
$stageEnd = $longProgram ? date('Y-m-t', strtotime($start)) : $this->weekly->getThisSunday($start);
$charts['PV'] .= $this->milestone->getPV($projectIdList, $begin, $stageEnd) . ',';
$charts['EV'] .= $this->milestone->getEV($projectIdList, $begin, $stageEnd) . ',';
$charts['AC'] .= $this->milestone->getAC($projectIdList, $begin, $stageEnd) . ',';
$start = $longProgram ? date('Y-m-d', strtotime("$start + 1 month")) : date('Y-m-d', strtotime("$start + 7 days"));
$i ++;
}
@@ -1398,13 +1399,14 @@ class block extends control
*/
public function printAssignToMeBlock($longBlock = true)
{
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;
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));
$count = array();
if(isset($hasViewPriv['todo']))
{
@@ -1428,6 +1430,7 @@ class block extends control
$todo->begin = date::formatTime($todo->begin);
$todo->end = date::formatTime($todo->end);
}
$count['todo'] = count($todos);
$this->view->todos = $todos;
}
if(isset($hasViewPriv['task']))
@@ -1441,6 +1444,7 @@ class block extends control
if(isset($params->taskNum)) $stmt->limit($params->taskNum);
$tasks = $stmt->fetchAll();
$count['task'] = count($tasks);
$this->view->tasks = $tasks;
}
if(isset($hasViewPriv['bug']))
@@ -1454,6 +1458,7 @@ class block extends control
if(isset($params->bugNum)) $stmt->limit($params->bugNum);
$bugs = $stmt->fetchAll();
$count['bug'] = count($bugs);
$this->view->bugs = $bugs;
}
if(isset($hasViewPriv['risk']))
@@ -1467,11 +1472,13 @@ class block extends control
if(isset($params->riskNum)) $stmt->limit($params->riskNum);
$risks = $stmt->fetchAll();
$count['risk'] = count($risks);
$this->view->risks = $risks;
}
$this->view->selfCall = $this->selfCall;
$this->view->hasViewPriv = $hasViewPriv;
$this->view->count = $count;
$this->view->longBlock = $longBlock;
$this->display();
}
@@ -1491,7 +1498,7 @@ class block extends control
{
$this->loadModel('project');
$num = isset($this->params->num) ? (int)$this->params->num : 15;
$num = isset($this->params->num) ? (int)$this->params->num : 15;
/* Get projects. */
$this->view->programs = $this->loadModel('program')->getUserPrograms('all', 'id_desc', $num);
+168 -64
View File
@@ -32,9 +32,11 @@ $lang->block->lblNum = 'Number';
$lang->block->lblHtml = 'HTML';
$lang->block->dynamic = 'Dynamics';
$lang->block->assignToMe = 'AssignedToMe';
$lang->block->done = 'Done';
$lang->block->lblFlowchart = 'Flowchart';
$lang->block->welcome = 'Welcome';
$lang->block->lblTesttask = 'Test Request Detail';
$lang->block->contribute = 'Personal Contribution';
$lang->block->leftToday = 'Remained Work';
$lang->block->myTask = 'My Tasks';
@@ -52,6 +54,9 @@ $lang->block->resolvedBugs = 'The Number Of Bugs Resolved';
$lang->block->openedTestcases = 'The Number Of Test Case Created';
$lang->block->cmmi = 'CMMI 3';
$lang->block->scrum = 'Scrum+';
$lang->block->allProject = 'All ' . $lang->projectCommon;
$lang->block->doingProject = 'Doning ' . $lang->projectCommon;
$lang->block->finishProject = 'Finish ' . $lang->projectCommon;
$lang->block->params = new stdclass();
$lang->block->params->name = 'Name';
@@ -71,6 +76,85 @@ $lang->block->nbsp = ' ';
$lang->block->hidden = 'Hide';
$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->productName = $lang->productCommon . ' Name';
$lang->block->totalStory = 'The Total ' . $lang->storyCommon;
$lang->block->totalBug = 'The Total Bug';
$lang->block->totalRelease = 'Release The Number';
$lang->block->default['cmmi']['program']['1']['title'] = $lang->projectCommon . 'Weekly';
$lang->block->default['cmmi']['program']['1']['block'] = 'Pmmireport';
$lang->block->default['cmmi']['program']['1']['source'] = 'Program';
$lang->block->default['cmmi']['program']['1']['grid'] = 8;
$lang->block->default['cmmi']['program']['2']['title'] = 'Estimate';
$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']['3']['title'] = 'Plan Gantt Chart';
$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']['4']['title'] = 'Progress Chart';
$lang->block->default['cmmi']['program']['4']['block'] = 'cmmiprogress';
$lang->block->default['cmmi']['program']['4']['grid'] = 4;
$lang->block->default['cmmi']['program']['5']['title'] = 'Program Issue';
$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';
$lang->block->default['cmmi']['program']['5']['params']['orderBy'] = 'id_desc';
$lang->block->default['cmmi']['program']['6']['title'] = 'Dynamic';
$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->projectCommon . 'Risk';
$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->projectCommon . ' Overall';
$lang->block->default['scrum']['program']['1']['block'] = 'scrumoverall';
$lang->block->default['scrum']['program']['1']['grid'] = 8;
$lang->block->default['scrum']['program']['2']['title'] = $lang->projectCommon . ' List';
$lang->block->default['scrum']['program']['2']['block'] = 'scrumlist';
$lang->block->default['scrum']['program']['2']['grid'] = 8;
$lang->block->default['scrum']['program']['3']['title'] = $lang->productCommon . ' Road Map';
$lang->block->default['scrum']['program']['3']['block'] = 'scrumroadmap';
$lang->block->default['scrum']['program']['3']['grid'] = 8;
$lang->block->default['scrum']['program']['4']['title'] = 'Test Version';
$lang->block->default['scrum']['program']['4']['block'] = 'scrumtest';
$lang->block->default['scrum']['program']['4']['grid'] = 8;
$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->productCommon . ' Overview';
$lang->block->default['scrum']['program']['5']['block'] = 'scrumproduct';
$lang->block->default['scrum']['program']['5']['grid'] = 4;
$lang->block->default['scrum']['program']['6']['title'] = $lang->projectCommon . ' Overview';
$lang->block->default['scrum']['program']['6']['block'] = 'scrumproject';
$lang->block->default['scrum']['program']['6']['grid'] = 4;
$lang->block->default['scrum']['program']['7']['title'] = 'Dynamic';
$lang->block->default['scrum']['program']['7']['block'] = 'scrumdynamic';
$lang->block->default['scrum']['program']['7']['grid'] = 4;
$lang->block->default['product']['1']['title'] = $lang->productCommon . ' Report';
$lang->block->default['product']['1']['block'] = 'statistic';
$lang->block->default['product']['1']['grid'] = 8;
@@ -167,73 +251,47 @@ $lang->block->default['full']['my']['2']['title'] = 'Dynamics';
$lang->block->default['full']['my']['2']['block'] = 'dynamic';
$lang->block->default['full']['my']['2']['grid'] = 4;
$lang->block->default['full']['my']['2']['source'] = '';
$lang->block->default['full']['my']['3']['title'] = 'Flowchart';
$lang->block->default['full']['my']['3']['block'] = 'flowchart';
$lang->block->default['full']['my']['3']['grid'] = 8;
$lang->block->default['full']['my']['3']['source'] = '';
$lang->block->default['full']['my']['4']['title'] = 'My Todos';
$lang->block->default['full']['my']['4']['block'] = 'list';
$lang->block->default['full']['my']['4']['grid'] = 4;
$lang->block->default['full']['my']['4']['source'] = 'todo';
$lang->block->default['full']['my']['4']['params']['num'] = '20';
$lang->block->default['full']['my']['5'] = $lang->block->default['project']['1'];
$lang->block->default['full']['my']['5']['source'] = 'project';
$lang->block->default['full']['my']['6'] = $lang->block->default['project']['2'];
$lang->block->default['full']['my']['6']['source'] = 'project';
$lang->block->default['full']['my']['7'] = $lang->block->default['product']['1'];
$lang->block->default['full']['my']['7']['source'] = 'product';
$lang->block->default['full']['my']['8'] = $lang->block->default['product']['2'];
$lang->block->default['full']['my']['8']['source'] = 'product';
$lang->block->default['full']['my']['9'] = $lang->block->default['qa']['2'];
$lang->block->default['full']['my']['9']['source'] = 'qa';
$lang->block->default['onlyTest']['my']['1'] = $lang->block->default['qa']['1'];
$lang->block->default['onlyTest']['my']['1']['source'] = 'qa';
$lang->block->default['onlyTest']['my']['1']['grid'] = '8';
$lang->block->default['onlyTest']['my']['2']['title'] = 'Dynamics';
$lang->block->default['onlyTest']['my']['2']['block'] = 'dynamic';
$lang->block->default['onlyTest']['my']['2']['grid'] = 4;
$lang->block->default['onlyTest']['my']['2']['source'] = '';
$lang->block->default['onlyTest']['my']['3']['title'] = 'My Todos';
$lang->block->default['onlyTest']['my']['3']['block'] = 'list';
$lang->block->default['onlyTest']['my']['3']['grid'] = 6;
$lang->block->default['onlyTest']['my']['3']['source'] = 'todo';
$lang->block->default['onlyTest']['my']['3']['params']['num'] = '20';
$lang->block->default['onlyTest']['my']['4'] = $lang->block->default['qa']['2'];
$lang->block->default['onlyTest']['my']['4']['source'] = 'qa';
$lang->block->default['onlyTest']['my']['4']['grid'] = 6;
$lang->block->default['full']['my']['3']['title'] = 'My Todos';
$lang->block->default['full']['my']['3']['block'] = 'list';
$lang->block->default['full']['my']['3']['grid'] = 4;
$lang->block->default['full']['my']['3']['source'] = 'todo';
$lang->block->default['full']['my']['3']['params']['num'] = '20';
$lang->block->default['onlyStory']['my']['1'] = $lang->block->default['project']['1'];
$lang->block->default['onlyStory']['my']['1']['source'] = 'project';
$lang->block->default['onlyStory']['my']['1']['grid'] = 8;
$lang->block->default['onlyStory']['my']['2']['title'] = 'Dynamics';
$lang->block->default['onlyStory']['my']['2']['block'] = 'dynamic';
$lang->block->default['onlyStory']['my']['2']['grid'] = 4;
$lang->block->default['onlyStory']['my']['2']['source'] = '';
$lang->block->default['onlyStory']['my']['3']['title'] = 'My Todos';
$lang->block->default['onlyStory']['my']['3']['block'] = 'list';
$lang->block->default['onlyStory']['my']['3']['grid'] = 6;
$lang->block->default['onlyStory']['my']['3']['source'] = 'todo';
$lang->block->default['onlyStory']['my']['3']['params']['num'] = '20';
$lang->block->default['onlyStory']['my']['4'] = $lang->block->default['product']['2'];
$lang->block->default['onlyStory']['my']['4']['source'] = 'product';
$lang->block->default['onlyStory']['my']['4']['grid'] = 6;
$lang->block->default['full']['my']['4']['title'] = $lang->projectCommon . ' Statistic';
$lang->block->default['full']['my']['4']['source'] = 'statistic';
$lang->block->default['full']['my']['4']['source'] = 'program';
$lang->block->default['full']['my']['4']['grid'] = 8;
$lang->block->default['onlyTask']['my']['1'] = $lang->block->default['project']['1'];
$lang->block->default['onlyTask']['my']['1']['source'] = 'project';
$lang->block->default['onlyTask']['my']['1']['grid'] = 8;
$lang->block->default['onlyTask']['my']['2']['title'] = 'Dynamics';
$lang->block->default['onlyTask']['my']['2']['block'] = 'dynamic';
$lang->block->default['onlyTask']['my']['2']['grid'] = 4;
$lang->block->default['onlyTask']['my']['2']['source'] = '';
$lang->block->default['onlyTask']['my']['3']['title'] = 'My Todos';
$lang->block->default['onlyTask']['my']['3']['block'] = 'list';
$lang->block->default['onlyTask']['my']['3']['grid'] = 6;
$lang->block->default['onlyTask']['my']['3']['source'] = 'todo';
$lang->block->default['onlyTask']['my']['3']['params']['num'] = '20';
$lang->block->default['onlyTask']['my']['4'] = $lang->block->default['project']['2'];
$lang->block->default['onlyTask']['my']['4']['source'] = 'project';
$lang->block->default['onlyTask']['my']['4']['grid'] = 6;
$lang->block->default['full']['my']['5']['title'] = 'Personal Contribution';
$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'] = 'Recent ' . $lang->projectCommon;
$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'] = 'Assigned To Me';
$lang->block->default['full']['my']['7']['block'] = 'task';
$lang->block->default['full']['my']['7']['grid'] = 4;
$lang->block->default['full']['my']['7']['params']['orderBy'] = 'id_desc';
$lang->block->default['full']['my']['7']['params']['num'] = '15';
$lang->block->default['full']['my']['7']['params']['type'] = 'assignedTo';
$lang->block->default['full']['my']['8']['title'] = 'Human Input';
$lang->block->default['full']['my']['8']['block'] = 'programteam';
$lang->block->default['full']['my']['8']['grid'] = 8;
$lang->block->default['full']['my']['9']['title'] = $lang->projectCommon . ' List';
$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';
$lang->block->num = 'Number';
$lang->block->type = 'Type';
@@ -254,11 +312,36 @@ $lang->block->availableBlocks->build = 'Builds';
$lang->block->availableBlocks->testtask = 'Requests';
$lang->block->availableBlocks->risk = 'My Risks';
$lang->block->moduleList['program'] = $lang->projectCommon;
$lang->block->moduleList['product'] = $lang->productCommon;
$lang->block->moduleList['project'] = $lang->projectCommon;
$lang->block->moduleList['qa'] = 'QA';
$lang->block->moduleList['todo'] = 'Todo';
$lang->block->modules['program'] = new stdclass();
$lang->block->modules['program']->availableBlocks = new stdclass();
$lang->block->modules['program']->availableBlocks->program = $lang->projectCommon . ' List';
$lang->block->modules['program']->availableBlocks->recentprogram = 'Recent ' . $lang->projectCommon;
$lang->block->modules['program']->availableBlocks->statistic = $lang->projectCommon . ' Statistic';
$lang->block->modules['scrum']['index'] = new stdclass();
$lang->block->modules['scrum']['index']->availableBlocks = new stdclass();
$lang->block->modules['scrum']['index']->availableBlocks->scrumoverall = $lang->projectCommon . ' Overall';
$lang->block->modules['scrum']['index']->availableBlocks->scrumlist = $lang->projectCommon . ' List';
$lang->block->modules['scrum']['index']->availableBlocks->scrumproject = $lang->projectCommon . ' Overview';
$lang->block->modules['scrum']['index']->availableBlocks->scrumproduct = $lang->productCommon . ' Overview';
$lang->block->modules['scrum']['index']->availableBlocks->scrumtest = 'Test Version';
$lang->block->modules['scrum']['index']->availableBlocks->scrumroadmap = $lang->productCommon . ' Rode Map';
$lang->block->modules['cmmi']['index'] = new stdclass();
$lang->block->modules['cmmi']['index']->availableBlocks = new stdclass();
$lang->block->modules['cmmi']['index']->availableBlocks->cmmireport = $lang->projectCommon . ' Weekly';
$lang->block->modules['cmmi']['index']->availableBlocks->cmmiestimate = 'Estimate';
$lang->block->modules['cmmi']['index']->availableBlocks->cmmigantt = 'Plan Gantt Chart';
$lang->block->modules['cmmi']['index']->availableBlocks->cmmiprogress = 'Progress Chart';
$lang->block->modules['cmmi']['index']->availableBlocks->cmmiissue = $lang->projectCommon . ' Issue';
$lang->block->modules['cmmi']['index']->availableBlocks->cmmirisk = $lang->projectCommon . ' Risk';
$lang->block->modules['product'] = new stdclass();
$lang->block->modules['product']->availableBlocks = new stdclass();
$lang->block->modules['product']->availableBlocks->statistic = $lang->productCommon . ' Report';
@@ -338,6 +421,7 @@ $lang->block->orderByList->story['stage_desc'] = 'Story Phase DESC';
$lang->block->todoNum = 'Todo';
$lang->block->taskNum = 'Task';
$lang->block->bugNum = 'Bug';
$lang->block->riskNum = 'Risk';
$lang->block->typeList = new stdclass();
@@ -370,12 +454,32 @@ $lang->block->typeList->project['doing'] = 'Ongoing';
$lang->block->typeList->project['all'] = 'All';
$lang->block->typeList->project['involved'] = 'Involved';
$lang->block->typeList->scrum['undone'] = 'Unfinished';
$lang->block->typeList->scrum['doing'] = 'Ongoing中';
$lang->block->typeList->scrum['all'] = 'All';
$lang->block->typeList->scrum['involved'] = 'Involved';
$lang->block->typeList->testtask['wait'] = 'Waiting';
$lang->block->typeList->testtask['doing'] = 'Ongoing';
$lang->block->typeList->testtask['blocked'] = 'Blocked';
$lang->block->typeList->testtask['done'] = 'Done';
$lang->block->typeList->testtask['all'] = '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';
@@ -16,7 +16,12 @@
<?php foreach($hasViewPriv as $type => $bool):?>
<?php if($config->global->flow != 'full' && $config->global->flow != 'onlyTask' && $type == 'task') continue;?>
<?php if($config->global->flow != 'full' && $config->global->flow != 'onlyTest' && $type == 'bug') continue;?>
<li<?php if($isFirstTab) {echo ' class="active"'; $isFirstTab = false;}?>><a data-tab href='#assigntomeTab-<?php echo $type;?>'><?php echo $lang->block->availableBlocks->$type;?></a></li>
<li<?php if($isFirstTab) {echo ' class="active"';}?>>
<a data-tab href='#assigntomeTab-<?php echo $type;?>' onClick="changeLabel('<?php echo $type;?>')">
<?php echo $lang->block->availableBlocks->$type;?>
<span class='label label-light label-badge label-assignto <?php echo $type . "-count "; echo $isFirstTab ? '' : 'hidden'; $isFirstTab = false ?>'><?php echo $count[$type];?></span>
</a>
</li>
<?php endforeach;?>
</ul>
<div class="tab-content">
@@ -36,3 +41,10 @@
#assigntomeBlock > .nav {position: absolute; top: -41px; left: 120px;}
#assigntomeBlock .block-todoes .todoes-form{top: -50px;}
</style>
<script>
function changeLabel(type)
{
$('.label-assignto').addClass('hidden');
$('.' + type + '-count').removeClass('hidden');
}
</script>
@@ -62,6 +62,14 @@ html[lang="en"] .product-info .type-info {color: #A6AAB8; text-align: center; po
.status-count{margin:auto}
.status-count tr:first-child td:last-child{color:#000;font-weight:bold}
.block-statistic .progress-group{margin-top: 20px; height: 65px;}
.block-statistic .weekly-title{font-weight: bold; font-size:14px; color: #3C4253;}
.block-statistic .weekly-small{font-size:12px; color: #838A9D;}
.block-statistic .weekly-progress {font-weight: bold; font-size:24px;}
.block-statistic .weekly-name{font-size:14px; color: #838A9D;}
.block-statistic .weekly-value{font-size:18px; color: #3C4253;}
.block-statistic .col-6 .stage{margin-left: 10px}
</style>
<script>
<?php $blockNavId = 'nav-' . uniqid(); ?>
@@ -140,8 +148,8 @@ $(function()
<div class="program-info">
<h4><?php echo $lang->program->allInput;?></h4>
<div class='info'>
<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-group'></i> <?php echo sprintf($lang->program->membersUnit, $program->teamCount);?></span>
<span><i class='icon icon-clock'></i> <?php echo sprintf($lang->program->hoursUnit, $program->estimate);?></span>
<span><i class='icon icon-cost'></i> <?php echo $program->budget . ' ' . zget($lang->program->unitList, $program->budgetUnit);?></span>
</div>
</div>
@@ -163,6 +171,71 @@ $(function()
</div>
</div>
<?php else:?>
<div class="col-6">
<div class='table-row text-left weekly-row with-padding'>
<span class='weekly-title'><?php echo $lang->program->weekly;?></span>
<span class='stage text-muted'><?php echo $program->current;?></span>
</div>
<div class='progress-group col-10 center-block'>
<div class='progress-num text-center'>
<div class='weekly-title'><?php echo $lang->program->progress;?></div>
<div class='weekly-progress'><?php echo $program->progress . '%';?></div>
</div>
<div class='progress'>
<div class="progress-bar" role="progressbar" aria-valuenow="82" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $program->progress;?>%"></div>
</div>
</div>
<div class="table-row text-center small text-muted with-padding col-10 center-block">
<div class="col-4 text-bottom">
<div class='weekly-name'><?php echo $lang->program->pv;?></div>
<div class='weekly-value'><?php echo $program->pv;?></div>
</div>
<div class="col-4">
<div class='weekly-name'><?php echo $lang->program->ev;?></div>
<div class='weekly-value'><?php echo $program->ev;?></div>
</div>
<div class="col-4">
<div class='weekly-name'><?php echo $lang->program->sv;?></div>
<div class='weekly-value'><?php echo $program->sv;?></div>
</div>
</div>
</div>
<div class='col-6'>
<div class='table-row weekly-row with-padding'>
<div class='col-4 text-center'>
<span class='weekly-title'><?php echo $lang->program->allInput;?></span>
</div>
<div class='col-8'></div>
</div>
<div class='progress-group'>
<div class="table-row text-center small text-muted with-padding">
<div class="col-4 text-bottom">
<div class='weekly-name'><?php echo $lang->program->pm;?></div>
<div class='weekly-value'><?php echo $program->PM ? $program->PM : $lang->program->emptyPM;?></div>
</div>
<div class="col-4">
<div class='weekly-name'><?php echo $lang->program->teamCount;?></div>
<div class='weekly-value'><?php echo $program->teamCount;?></div>
</div>
<div class="col-4">
<div class='weekly-name'><?php echo $lang->program->budget;?></div>
<div class='weekly-value'><?php echo $program->budget;?></div>
</div>
</div>
</div>
<div class="table-row text-center small text-muted with-padding">
<div class="col-4 text-bottom">
<div class='weekly-name'><?php echo $lang->program->ac;?></div>
<div class='weekly-value'><?php echo $program->ac;?></div>
</div>
<div class="col-4">
<div class='weekly-name'><?php echo $lang->program->cv;?></div>
<div class='weekly-value'><?php echo $program->cv;?></div>
</div>
<div>
</div>
</div>
</div>
<?php endif;?>
</div>
</div>
@@ -19,13 +19,14 @@
#cards .program-detail > p {margin-bottom: 8px;}
#cards .program-detail .progress {height: 4px;}
#cards .program-detail .progress-text-left .progress-text {width: 50px; left: -50px;}
#cards .panel-heading {cursor: pointer;}
</style>
<div class='row' id='cards'>
<?php foreach ($programs as $programID => $program):?>
<div class='col' data-id='<?php echo $programID?>'>
<div class='panel' data-url='<?php echo $this->createLink('program', 'index', "programID=$program->id");?>'>
<div class='panel-heading'>
<strong class='program-name' title='<?php echo $program->name;?>'><?php echo $program->name;?></strong>
<strong class='program-name' title='<?php echo $program->name;?>'> <?php echo html::a($this->createLink('program', 'index', "programID=$program->id", '', '', $program->id), $program->name);?> </strong>
<?php if($program->template === 'cmmi'): ?>
<span class='program-type-label label label-warning label-outline'><?php echo $lang->program->cmmi; ?></span>
<?php else: ?>
@@ -64,7 +65,7 @@
<p class='text-muted'><?php echo $lang->program->lastIteration; ?></p>
<?php if($project):?>
<div class='row'>
<div class='col-xs-5'><?php echo $project->name; ?></div>
<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;?>%">
+1
View File
@@ -81,6 +81,7 @@ $lang->milestone->chart = new stdclass();
$lang->milestone->chart->title = '到目前为止项目进展趋势图';
$lang->milestone->chart->time = '第';
$lang->milestone->chart->week = '周';
$lang->milestone->chart->month = '月';
$lang->milestone->chart->workhour = '研发工作量分析图';
$lang->milestone->otherproblem = '6.其它问题';
+1
View File
@@ -180,6 +180,7 @@ class product extends control
$this->view->position[] = $this->products[$productID];
$this->view->position[] = $this->lang->product->browse;
$this->view->productID = $productID;
$this->view->program = $this->loadModel('project')->getById($this->session->program);
$this->view->product = $this->product->getById($productID);
$this->view->productName = $this->products[$productID];
$this->view->moduleID = $moduleID;
+1 -1
View File
@@ -24,7 +24,7 @@ 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;
if($program->template == 'cmmi') $lang->story->create = $storyType == 'story' ? $lang->story->createStory : $lang->story->createRequirement;
?>
<div id="mainMenu" class="clearfix">
<div id="sidebarHeader">
+4 -1
View File
@@ -175,11 +175,14 @@ class program extends control
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $url));
}
$parents = $this->program->getParentPairs();
unset($parents[$programID]);
$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->parents = $parents;
$this->view->groups = $this->loadModel('group')->getPairs();
$this->display();
}
+61 -41
View File
@@ -1,45 +1,64 @@
<?php
$lang->program->index = 'Project';
$lang->program->common = 'Project';
$lang->program->stage = 'Stage';
$lang->program->name = 'Name';
$lang->program->template = 'Template';
$lang->program->category = 'Category';
$lang->program->desc = 'Description';
$lang->program->code = 'Code';
$lang->program->copy = 'Copy';
$lang->program->begin = 'Begin';
$lang->program->end = 'End';
$lang->program->status = 'Status';
$lang->program->PM = 'Project Manager';
$lang->program->create = 'Create';
$lang->program->edit = 'Edit';
$lang->program->all = 'All';
$lang->program->start = 'Start';
$lang->program->finish = 'Finish';
$lang->program->suspend = 'Suspend';
$lang->program->delete = 'Delete';
$lang->program->close = 'Close';
$lang->program->activate = 'Activate';
$lang->program->budget = 'Budget';
$lang->program->dateRange = 'Date Range';
$lang->program->to = ' to ';
$lang->program->realFinished = 'Real finished';
$lang->program->realStarted = 'Real started';
$lang->program->bygrid = 'Grid';
$lang->program->bylist = 'List';
$lang->program->mine = 'Participated';
$lang->program->group = 'Group';
$lang->program->createGroup = 'Create Group';
$lang->program->editGroup = 'Edit Group';
$lang->program->copyGroup = 'Copy Group';
$lang->program->manageView = 'Manage View';
$lang->program->managePriv = 'Manage Priv';
$lang->program->manageMembers = 'Manage Members';
$lang->program->transfer = 'Transfer';
$lang->program->setPlanduration = 'Set Planduration';
$lang->program->export = 'Export';
$lang->program->privway = 'Priv Way';
$lang->program->index = 'Project';
$lang->program->common = 'Project';
$lang->program->stage = 'Stage';
$lang->program->name = 'Name';
$lang->program->template = 'Template';
$lang->program->category = 'Category';
$lang->program->desc = 'Description';
$lang->program->code = 'Code';
$lang->program->copy = 'Copy';
$lang->program->begin = 'Begin';
$lang->program->end = 'End';
$lang->program->status = 'Status';
$lang->program->PM = 'Project Manager';
$lang->program->create = 'Create';
$lang->program->edit = 'Edit';
$lang->program->all = 'All';
$lang->program->start = 'Start';
$lang->program->finish = 'Finish';
$lang->program->suspend = 'Suspend';
$lang->program->delete = 'Delete';
$lang->program->close = 'Close';
$lang->program->activate = 'Activate';
$lang->program->budget = 'Budget';
$lang->program->dateRange = 'Date Range';
$lang->program->to = ' to ';
$lang->program->realFinished = 'Real finished';
$lang->program->realStarted = 'Real started';
$lang->program->bygrid = 'Grid';
$lang->program->bylist = 'List';
$lang->program->mine = 'Participated';
$lang->program->group = 'Group';
$lang->program->createGroup = 'Create Group';
$lang->program->editGroup = 'Edit Group';
$lang->program->copyGroup = 'Copy Group';
$lang->program->manageView = 'Manage View';
$lang->program->managePriv = 'Manage Priv';
$lang->program->manageMembers = 'Manage Members';
$lang->program->transfer = 'Transfer';
$lang->program->setPlanduration = 'Set Planduration';
$lang->program->export = 'Export';
$lang->program->privway = 'Priv Way';
$lang->program->durationEstimation = 'Duration Estimation';
$lang->program->progress = 'Program Progress';
$lang->program->teamCount = 'The Number Of Team';
$lang->program->leftStories = 'Left Stories';
$lang->program->leftTasks = 'Left Tasks';
$lang->program->leftBugs = 'Left Bugs';
$lang->program->children = 'Subprogram';
$lang->program->parent = 'Parent Program';
$lang->program->allStories = 'All stories';
$lang->program->doneStories = 'Done stories';
$lang->program->leftStories = 'Left stories';
$lang->program->allInput = 'All Input';
$lang->program->weekly = 'Program Weekly';
$lang->program->pv = 'PV';
$lang->program->ev = 'EV';
$lang->program->sv = 'SV%';
$lang->program->ac = 'AC';
$lang->program->cv = 'CV%';
$lang->program->pm = 'PM';
$lang->program->manageGroupMember = 'Manage Group Members';
$lang->program->durationEstimation = 'Workload estimate';
@@ -80,3 +99,4 @@ $lang->program->scrumDesc = '<strong>Introduction: </strong>Iterate in s
$lang->program->cmmi = 'CMMI';
$lang->program->cmmiTitle = 'CMMI management';
$lang->program->cmmiDesc = '<strong>Introduction: </strong>Standardized management by stages<br><strong>Contains function points: </strong>Estimate, plan, stage, report, etc.';
$lang->program->emptyPM = 'No program manager';
+9
View File
@@ -57,6 +57,14 @@ $lang->program->allStories = '总需求';
$lang->program->doneStories = '已完成';
$lang->program->leftStories = '剩余需求';
$lang->program->allInput = '项目总投入';
$lang->program->weekly = '项目周报';
$lang->program->pv = 'PV';
$lang->program->ev = 'EV';
$lang->program->sv = 'SV%';
$lang->program->ac = 'AC';
$lang->program->cv = 'CV%';
$lang->program->pm = '项目负责人';
$lang->program->teamCount = '项目成员';
$lang->program->unitList[''] = '';
$lang->program->unitList['yuan'] = '元';
@@ -103,5 +111,6 @@ $lang->program->cmmiDesc = '<strong>简介:</strong>按阶段规范
$lang->program->cannotCreateChild = '该项目已经有实际的内容,无法直接添加子项目。您可以为当前项目创建一个父项目,然后在新的父项目下面添加子项目。';
$lang->program->hasChildren = '该项目有子项目存在,不能删除。';
$lang->program->confirmDelete = "您确定删除项目[%s]吗?";
$lang->program->emptyPM = '暂无';
$lang->program->cannotChangeToCat = "该项目已经有实际的内容,无法修改为父项目";
$lang->program->cannotCancelCat = "该项目下已经有子项目,无法取消父项目标记";
+30 -12
View File
@@ -189,7 +189,8 @@ class programModel extends model
foreach($programs as $programID => $program)
{
$program->projects = $this->project->getProjectStats($status, 0, 0, $itemCounts, 'id_desc', $pager, $programID);
$orderBy = $program->template == 'cmmi' ? 'id_asc' : 'id_desc';
$program->projects = $this->project->getProjectStats($status, 0, 0, $itemCounts, $orderBy, $pager, $programID);
$program->teamCount = isset($teams[$programID]) ? $teams[$programID]->count : 0;
$program->estimate = isset($estimates[$programID]) ? $estimates[$programID]->estimate : 0;
}
@@ -490,23 +491,40 @@ class programModel extends model
*/
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();
$modules = $this->dao->select('id,name,parent,path,grade')->from(TABLE_PROJECT)->where('isCat')->eq(1)->andWhere('deleted')->eq(0)->orderBy('grade desc, `order`')->fetchAll('id');
$pairs = array();
$pairs[0] = '/';
while($program = $stmt->fetch())
$treeMenu = array();
foreach($modules as $module)
{
if($program->grade == 1)
$moduleName = '/';
$parentModules = explode(',', $module->path);
foreach($parentModules as $parentModuleID)
{
$pairs[$program->id] = '/' . $program->name;
continue;
if(empty($parentModuleID)) continue;
if(empty($modules[$parentModuleID])) continue;
$moduleName .= $modules[$parentModuleID]->name . '/';
}
$moduleName = str_replace('|', '&#166;', rtrim($moduleName, '/'));
$moduleName .= "|$module->id\n";
$programName = '/' . $program->name;
$pairs[$program->id] = isset($pairs[$program->parent]) ? $pairs[$program->parent] . $programName : $programName;
if(!isset($treeMenu[$module->parent])) $treeMenu[$module->parent] = '';
$treeMenu[$module->parent] .= $moduleName;
if(isset($treeMenu[$module->id]) and !empty($treeMenu[$module->id])) $treeMenu[$module->parent] .= $treeMenu[$module->id];
}
return $pairs;
ksort($treeMenu);
$topMenu = array_shift($treeMenu);
$topMenu = explode("\n", trim($topMenu));
$lastMenu[] = '/';
foreach($topMenu as $menu)
{
if(strpos($menu, '|') === false) continue;
list($label, $moduleID) = explode('|', $menu);
$lastMenu[$moduleID] = str_replace('&#166;', '|', $label);
}
return $lastMenu;
}
/**
@@ -533,7 +551,7 @@ class programModel extends model
foreach($childNodes as $childNode)
{
$path = substr($childNode->path, strpos($childNode->path, ",{$programID},"));
$grade = $oldGrade - $childNode->grade + 1;
$grade = $childNode->grade - $oldGrade + 1;
if($parent)
{
$path = rtrim($parent->path, ',') . $path;
+1 -1
View File
@@ -74,7 +74,7 @@ class programplan extends control
$this->app->loadLang('stage');
$program = $this->loadModel('project')->getById($programID);
$stages = $planID ? array() : $this->loadModel('stage')->getStages();
$stages = $planID ? array() : $this->loadModel('stage')->getStages('id_asc');
$plans = $this->programplan->getList($programID, $this->productID, $planID);
$title = $this->lang->programplan->create . $this->lang->colon . $program->name;
+42 -4
View File
@@ -752,8 +752,11 @@ class story extends control
$this->view->fromBug = $fromBug;
$this->view->cases = $cases;
$this->view->story = $story;
$this->view->track = $this->story->getTrackByID($story->id);
$this->view->users = $users;
$this->view->relations = $this->story->getStoryRelation($story->id, $story->type);
$this->view->projects = $this->loadModel('project')->getPairs('nocode');
$this->view->program = $this->project->getByID($story->program);
$this->view->actions = $this->action->getList('story', $storyID);
$this->view->storyModule = $storyModule;
$this->view->modulePath = $modulePath;
@@ -1166,6 +1169,26 @@ class story extends control
die(js::locate($this->session->storyList, 'parent'));
}
/**
* Story track.
*
* @param int $productID
* @access public
* @return void
*/
public function track($productID)
{
$products = $this->loadModel('product')->getPairs($this->session->program);
$productID = $this->product->saveState($productID, $products);
$this->product->setMenu($products, $productID, 0, 0, '');
$tracks = $this->story->getTracks($productID);
$this->view->tracks = $tracks;
$this->view->title = $this->lang->story->track;
$this->view->posision[] = $this->lang->story->track;
$this->display();
}
/**
* Tasks of a story.
*
@@ -1260,21 +1283,36 @@ class story extends control
* @access public
* @return void
*/
public function linkStory($storyID, $type = 'linkStories', $browseType = '', $param = 0)
public function linkStory($storyID, $type = 'linkStories', $linkedStoryID = 0, $browseType = '', $queryID = 0)
{
$this->commonAction($storyID);
if($type == 'remove')
{
$result = $this->story->unlinkStory($storyID, $linkedStoryID);
die(js::reload('parent'));
}
if($_POST)
{
$this->story->linkStories($storyID);
if(dao::isError()) die(js::error(dao::getError()));
die(js::closeModal('parent.parent', 'this'));
}
/* Get story, product, products, and queryID. */
$story = $this->story->getById($storyID);
$products = $this->product->getPairs();
$queryID = ($browseType == 'bySearch') ? (int)$param : 0;
$queryID = 0;
/* Build search form. */
$actionURL = $this->createLink('story', 'linkStory', "storyID=$storyID&type=$type&browseType=bySearch&queryID=myQueryID", '', true);
$actionURL = $this->createLink('story', 'linkStory', "storyID=$storyID&type=$type&linkedStoryID=$linkedStoryID&browseType=bySearch&queryID=myQueryID", '', true);
$this->loadModel('product')->buildSearchForm($story->product, $products, $queryID, $actionURL);
/* Get stories to link. */
$stories2Link = $this->story->getStories2Link($storyID, $type, $browseType, $queryID);
$storyType = $story->type;
$stories2Link = $this->story->getStories2Link($storyID, $type, $browseType, $queryID, $storyType);
/* Assign. */
$this->view->title = $this->lang->story->linkStory . "STORY" . $this->lang->colon .$this->lang->story->linkStory;
+1
View File
@@ -1,3 +1,4 @@
.side-col .cell{padding:0px;}
.side-col #legendProjectAndTask .list-unstyled{padding:10px; border-top:0px; margin:0px;}
.col-4 .cell .tab-content .text-top{padding-top: 1px}
#legendStories ul li{padding: 10px 0 0 12px; line-height: 20px}
+14
View File
@@ -8,4 +8,18 @@ $(function()
/* Add for task #5385. */
if(config.onlybody == 'yes') $('.main-actions').css('width', '100%')
$('#unlinkStory').click(function()
{
if($('.removeButton').hasClass('hide'))
{
$('.removeButton').removeClass('hide');
$(this).text(cancel);
}
else
{
$('.removeButton').addClass('hide');
$(this).text(unlink);
}
})
});
+55 -43
View File
@@ -9,49 +9,56 @@
* @version $Id: en.php 5141 2013-07-15 05:57:15Z chencongzhi520@gmail.com $
* @link http://www.zentao.net
*/
$lang->story->create = "Create Story";
$lang->story->batchCreate = "Batch Create";
$lang->story->change = "Change";
$lang->story->changeAction = "Change Story";
$lang->story->changed = 'Change';
$lang->story->assignTo = 'Assign';
$lang->story->assignAction = 'Assign Story';
$lang->story->review = 'Review';
$lang->story->reviewAction = 'Review Story';
$lang->story->needReview = 'Need Review';
$lang->story->batchReview = 'Batch Review';
$lang->story->edit = "Edit Story";
$lang->story->batchEdit = "Batch Edit";
$lang->story->subdivide = 'Decompose';
$lang->story->subdivideAction = 'Decompose Story';
$lang->story->splitRequirent = 'Decompose';
$lang->story->close = 'Close';
$lang->story->closeAction = 'Close Story';
$lang->story->batchClose = 'Batch Close';
$lang->story->activate = 'Activate';
$lang->story->activateAction = 'Activate Story';
$lang->story->delete = "Delete";
$lang->story->deleteAction = "Delete Story";
$lang->story->view = "Story Detail";
$lang->story->setting = "Settings";
$lang->story->tasks = "Linked Tasks";
$lang->story->bugs = "Linked Bugs";
$lang->story->cases = "Linked Cases";
$lang->story->taskCount = 'Tasks';
$lang->story->bugCount = 'Bugs';
$lang->story->caseCount = 'Cases';
$lang->story->taskCountAB = 'T';
$lang->story->bugCountAB = 'B';
$lang->story->caseCountAB = 'C';
$lang->story->linkStory = 'Link Story';
$lang->story->unlinkStory = 'UnLinked';
$lang->story->export = "Export Data";
$lang->story->exportAction = "Export Story";
$lang->story->zeroCase = "Stories without cases";
$lang->story->zeroTask = "Only list stories without tasks";
$lang->story->reportChart = "Report";
$lang->story->reportAction = "Story Report";
$lang->story->copyTitle = "Copy Title";
$lang->story->create = "Create Story";
$lang->story->createStory = 'Create Story';
$lang->story->createRequirement = 'Create Requirement';
$lang->story->requirement = 'Requirement';
$lang->story->story = 'Story';
$lang->story->batchCreate = "Batch Create";
$lang->story->change = "Change";
$lang->story->changeAction = "Change Story";
$lang->story->changed = 'Change';
$lang->story->assignTo = 'Assign';
$lang->story->assignAction = 'Assign Story';
$lang->story->review = 'Review';
$lang->story->reviewAction = 'Review Story';
$lang->story->needReview = 'Need Review';
$lang->story->batchReview = 'Batch Review';
$lang->story->edit = "Edit Story";
$lang->story->batchEdit = "Batch Edit";
$lang->story->subdivide = 'Decompose';
$lang->story->link = 'Link';
$lang->story->unlink = 'Unlink';
$lang->story->track = 'Track';
$lang->story->subdivideAction = 'Decompose Story';
$lang->story->splitRequirent = 'Decompose';
$lang->story->close = 'Close';
$lang->story->closeAction = 'Close Story';
$lang->story->batchClose = 'Batch Close';
$lang->story->activate = 'Activate';
$lang->story->activateAction = 'Activate Story';
$lang->story->delete = "Delete";
$lang->story->deleteAction = "Delete Story";
$lang->story->view = "Story Detail";
$lang->story->setting = "Settings";
$lang->story->tasks = "Linked Tasks";
$lang->story->bugs = "Linked Bugs";
$lang->story->cases = "Linked Cases";
$lang->story->taskCount = 'Tasks';
$lang->story->bugCount = 'Bugs';
$lang->story->caseCount = 'Cases';
$lang->story->taskCountAB = 'T';
$lang->story->bugCountAB = 'B';
$lang->story->caseCountAB = 'C';
$lang->story->linkStory = 'Link Story';
$lang->story->unlinkStory = 'UnLinked';
$lang->story->export = "Export Data";
$lang->story->exportAction = "Export Story";
$lang->story->zeroCase = "Stories without cases";
$lang->story->zeroTask = "Only list stories without tasks";
$lang->story->reportChart = "Report";
$lang->story->reportAction = "Story Report";
$lang->story->copyTitle = "Copy Title";
$lang->story->batchChangePlan = "Batch Change Plans";
$lang->story->batchChangeBranch = "Batch Change Branches";
$lang->story->batchChangeStage = "Batch Change Phases";
@@ -120,6 +127,11 @@ $lang->story->allStories = 'All Stories';
$lang->story->unclosed = 'Unclosed';
$lang->story->deleted = 'Deleted';
$lang->story->released = 'Released Stories';
$lang->story->design = 'Designs';
$lang->story->case = 'Cases';
$lang->story->bug = 'Bugs';
$lang->story->repoCommit = 'Commits';
$lang->story->noRequirement = 'No Requirements';
$lang->story->ditto = 'Ditto';
$lang->story->dittoNotice = 'This story is not linked to the same product as the last one is!';
+10
View File
@@ -12,6 +12,8 @@
$lang->story->create = "提{$lang->storyCommon}";
$lang->story->createStory = '添加软需';
$lang->story->createRequirement = '添加用需';
$lang->story->requirement = '用户需求';
$lang->story->story = '软件需求';
$lang->story->batchCreate = "批量创建";
$lang->story->change = "变更";
$lang->story->changeAction = "变更{$lang->storyCommon}";
@@ -25,6 +27,9 @@ $lang->story->batchReview = '批量评审';
$lang->story->edit = "编辑";
$lang->story->batchEdit = "批量编辑";
$lang->story->subdivide = '细分';
$lang->story->link = '关联';
$lang->story->unlink = '移除';
$lang->story->track = '跟踪矩阵';
$lang->story->subdivideAction = "细分{$lang->storyCommon}";
$lang->story->splitRequirent = '拆分';
$lang->story->close = '关闭';
@@ -122,6 +127,11 @@ $lang->story->allStories = "所有{$lang->storyCommon}";
$lang->story->unclosed = '未关闭';
$lang->story->deleted = '已删除';
$lang->story->released = "已发布{$lang->storyCommon}数";
$lang->story->design = '相关设计';
$lang->story->case = '相关用例';
$lang->story->bug = '相关Bug';
$lang->story->repoCommit = '相关提交';
$lang->story->noRequirement = '无需求';
$lang->story->ditto = '同上';
$lang->story->dittoNotice = "该{$lang->storyCommon}与上一{$lang->storyCommon}不属于同一产品!";
+268 -15
View File
@@ -1572,30 +1572,43 @@ class storyModel extends model
/**
* Get stories to link.
*
* @param int $storyID
* @param string $type
* @param string $browseType
* @param int $queryID
* @param int $storyID
* @param string $type
* @param string $browseType
* @param int $queryID
* @param varchar $storyType
* @access public
* @return array
*/
public function getStories2Link($storyID, $type = 'linkStories', $browseType = 'bySearch', $queryID = 0)
public function getStories2Link($storyID, $type = 'linkStories', $browseType = 'bySearch', $queryID = 0, $storyType = 'story')
{
$story = $this->getById($storyID);
$linkedStories = $this->getRelation($storyID, $story->type);
$linkedStories = empty($linkedStories) ? array() : $linkedStories;
$tmpStoryType = $storyType == 'story' ? 'requirement' : 'story';
if($browseType == 'bySearch')
{
$story = $this->getById($storyID);
$stories2Link = $this->getBySearch($story->product, $queryID, 'id', null, '', $story->branch);
{
$stories2Link = $this->getBySearch($story->product, $queryID, 'id', null, '', $story->branch, $tmpStoryType);
foreach($stories2Link as $key => $story2Link)
{
{
if($story2Link->id == $storyID) unset($stories2Link[$key]);
if(in_array($story2Link->id, explode(',', $story->$type))) unset($stories2Link[$key]);
}
return $stories2Link;
}
}
}
else
{
return array();
}
{
$status = $storyType == 'story' ? 'active' : 'all';
$stories2Link = $this->getProductStories($story->product, $story->branch, 0, $status, $tmpStoryType, $orderBy = 'id_desc');
}
foreach($stories2Link as $id => $story)
{
if(in_array($story->id, array_keys($linkedStories))) unset($stories2Link[$id]);
if($storyType == 'story' && $story->status == 'draft') unset($stories2Link[$id]);
}
return $stories2Link;
}
/**
@@ -3135,4 +3148,244 @@ class storyModel extends model
return array($toList, $ccList);
}
/**
* Get tracks.
*
* @param int $productID
* @access public
* @return bool|array
*/
public function getTracks($productID)
{
$requirements = $this->getProductStories($productID, 0, 0, 'all', 'requirement', 'id_desc');
foreach($requirements as $requirement)
{
$stories = $this->getRelation($requirement->id, 'requirement');
$stories = empty($stories) ? array() : $stories;
foreach($stories as $id => $title)
{
$stories[$id] = new stdclass();
$stories[$id]->title = $title;
$stories[$id]->case = $this->loadModel('testcase')->getStoryCases($id);
$stories[$id]->bug = $this->loadModel('bug')->getStoryBugs($id);
$stories[$id]->design = $this->dao->select('id, name')->from(TABLE_DESIGN)->where('story')->eq($id)->fetchAll('id');
$stories[$id]->revision = $this->dao->select('BID, extra')->from(TABLE_RELATION)->where('AType')->eq('design')->andWhere('BType')->eq('commit')->andWhere('AID')->in(array_keys($stories[$id]->design))->fetchPairs();
}
$requirement->track = $stories;
}
/* Get no requirements story. */
$stories = $this->getProductStories($productID, 0, 0, 'all', 'story', 'id_desc');
foreach($stories as $id => $story)
{
$counts = $this->getStoryRelationCounts($story->id, 'story');
if($counts != 0)
{
unset($stories[$id]);
continue;
}
$title = $stories[$id]->title;
$stories[$id] = new stdclass();
$stories[$id]->title = $title;
$stories[$id]->case = $this->loadModel('testcase')->getStoryCases($id);
$stories[$id]->bug = $this->loadModel('bug')->getStoryBugs($id);
$stories[$id]->design = $this->dao->select('id, name')->from(TABLE_DESIGN)->where('story')->eq($id)->fetchAll('id');
$stories[$id]->revision = $this->dao->select('BID, extra')->from(TABLE_RELATION)->where('AType')->eq('design')->andWhere('BType')->eq('commit')->andWhere('AID')->in(array_keys($stories[$id]->design))->fetchPairs();
}
$requirements['noRequirement'] = $stories;
return $requirements;
}
/**
* Get track by id.
*
* @param int $storyID
* @access public
* @return bool|array
*/
public function getTrackByID($storyID)
{
$requirement = $this->getByID($storyID);
$stories = $this->getRelation($requirement->id, 'requirement');
$track = array();
$stories = empty($stories) ? array() : $stories;
foreach($stories as $id => $title)
{
$track[$id] = new stdclass();
$track[$id]->title = $title;
$track[$id]->case = $this->loadModel('testcase')->getStoryCases($id);
$track[$id]->bug = $this->loadModel('bug')->getStoryBugs($id);
$track[$id]->design = $this->dao->select('id, name')->from(TABLE_DESIGN)->where('story')->eq($id)->fetchAll('id');
$track[$id]->story = $this->getByID($id);
$track[$id]->revision = $this->dao->select('BID, extra')->from(TABLE_RELATION)->where('AType')->eq('design')->andWhere('BType')->eq('commit')->andWhere('AID')->in(array_keys($track[$id]->design))->fetchPairs();
}
return $track;
}
/**
* Obtain the direct relationship between UR and SR.
*
* @param int $storyID
* @param string $storyType
* @param string $storyType
* @access public
* @return int
*/
public function getStoryRelation($storyID, $storyType, $fields = array())
{
$conditionField = ($storyType == 'story') ? 'BID' : 'AID';
$storyType = ($storyType == 'story') ? 'AID' : 'BID';
$relations = $this->dao->select($storyType)->from(TABLE_RELATION)
->where('AType')->eq('requirement')
->andWhere('BType')->eq('story')
->andWhere('relation')->eq('subdivideinto')
->andWhere($conditionField)->eq($storyID)
->fetchAll($storyType);
if(empty($relations)) return array();
$fields = empty($fields) ? '*' : implode(',', $fields);
$story = $this->dao->select($fields)->from(TABLE_STORY)
->where('id')->in(array_keys($relations))
->andWhere('deleted')->eq(0)
->orderBy('id_desc')
->fetchAll();
return $story;
}
/**
* Link stories.
*
* @param int $storyID
* @access public
* @return void
*/
public function linkStories($storyID)
{
$story = $this->getByID($storyID);
$stories = $this->post->stories;
$isStory = ($story->type == 'story');
foreach($stories as $id)
{
$requirement = $this->getByID($id);
$data = new stdclass();
$data->program = $this->session->program;
$data->product = $this->session->product;
$data->AType = 'requirement';
$data->BType = 'story';
$data->relation = 'subdivideinto';
$data->AID = $isStory ? $id : $storyID;
$data->BID = $isStory ? $storyID : $id;
$data->AVersion = $isStory ? $requirement->version : $story->version;
$data->BVersion = $isStory ? $story->version : $requirement->version;
$this->dao->insert(TABLE_RELATION)->data($data)->autoCheck()->exec();
$data->AType = 'story';
$data->BType = 'requirement';
$data->relation = 'subdividedfrom';
$data->AID = $isStory ? $storyID : $id;
$data->BID = $isStory ? $id : $storyID;
$data->AVersion = $isStory ? $story->version : $requirement->version;
$data->BVersion = $isStory ? $requirement->version : $story->version;
$this->dao->insert(TABLE_RELATION)->data($data)->autoCheck()->exec();
}
}
/**
* Unlink story.
*
* @param int $storyID
* @param int $linkedStoryID
* @access public
* @return void
*/
public function unlinkStory($storyID, $linkedStoryID)
{
$idList = "$storyID,$linkedStoryID";
$this->dao->delete()->from(TABLE_RELATION)
->where('AType')->in('story,requirement')
->andWhere('BType')->in('story,requirement')
->andWhere('relation')->in('subdivideinto,subdividedfrom')
->andWhere('AID')->in($idList)
->andWhere('BID')->in($idList)
->exec();
return !dao::isError();
}
/**
* Get story relations.
*
* @param int $storyID
* @param varchar $storyType
* @access public
* @return int
*/
public function getRelation($storyID, $storyType, $extraField = array())
{
$BType = $storyType == 'story' ? 'requirement' : 'story';
$relation = $storyType == 'story' ? 'subdividedfrom' : 'subdivideinto';
$relations = $this->dao->select('BID')->from(TABLE_RELATION)
->where('AType')->eq($storyType)
->andWhere('BType')->eq($BType)
->andWhere('relation')->eq($relation)
->andWhere('AID')->eq($storyID)
->fetchPairs();
if(!empty($relations))
{
if(empty($extraField))
{
return $this->dao->select('id, title')
->from(TABLE_STORY)
->where('deleted')->eq(0)
->andWhere('id')->in($relations)
->fetchPairs();
}
else
{
return $this->dao->select(implode($extraField, ','))
->from(TABLE_STORY)
->where('deleted')->eq(0)
->andWhere('id')->in($relations)
->fetchAll('id');
}
}
}
/**
* Get software requirements associated with user needs.
*
* @param array $storyID
* @param string $storyType
* @access public
* @return int
*/
public function getStoryRelationCounts($storyID, $storyType = '')
{
$selectField = ($storyType == 'story') ? 'AID' : 'BID';
$conditionField = ($storyType == 'story') ? 'BID' : 'AID';
$relations = $this->dao->select('count('. $selectField .') as id')->from(TABLE_RELATION)
->where('AType')->eq('requirement')
->andWhere('BType')->eq('story')
->andWhere('relation')->eq('subdivideinto')
->andWhere($conditionField)->eq($storyID)
->fetch('id');
return $relations;
}
}
-28
View File
@@ -219,34 +219,6 @@
<td><?php echo html::input('duplicateStory', $story->duplicateStory, "class='form-control'");?></td>
</tr>
<?php endif;?>
<tr>
<th class='linkThWidth'><?php echo $lang->story->linkStories;?></th>
<td><?php echo html::a($this->createLink('story', 'linkStory', "storyID=$story->id&type=linkStories", '', true), $lang->story->linkStory, '', "data-toggle='modal' data-type='iframe' data-width='95%'");?></td>
</tr>
<tr>
<th></th>
<td>
<ul class='list-unstyled'>
<?php
if($story->linkStories)
{
$linkStories = explode(',', $story->linkStories);
foreach($linkStories as $linkStoryID)
{
if(isset($story->extraStories[$linkStoryID]))
{
echo "<li><div class='checkbox-primary'>";
echo "<input type='checkbox' checked='checked' name='linkStories[]' value=$linkStoryID />";
echo "<label>#{$linkStoryID} {$story->extraStories[$linkStoryID]}</label>";
echo '</div></li>';
}
}
}
?>
<span id='linkStoriesBox'></span>
</ul>
</td>
</tr>
<?php if($story->status == 'closed'):?>
<tr class='text-top'>
<th><?php echo $lang->story->childStories;?></th>
+4 -18
View File
@@ -36,11 +36,11 @@
<?php echo $lang->idAB;?>
</th>
<th class='c-pri'><?php echo $lang->priAB;?></th>
<th><?php echo $lang->story->product;?></th>
<th><?php echo $lang->story->title;?></th>
<th><?php echo $lang->story->plan;?></th>
<th class='w-80px'><?php echo $lang->story->status;?></th>
<?php if($story->type == 'requirement'):?>
<th class='w-80px'><?php echo $lang->story->stage;?></th>
<?php endif;?>
<th class='w-user'><?php echo $lang->openedByAB;?></th>
<th class='w-80px'><?php echo $lang->story->estimateAB;?></th>
</tr>
@@ -58,11 +58,11 @@
<?php echo html::a($storyLink, sprintf('%03d', $story2Link->id));?>
</td>
<td class='c-pri'><span class='label-pri <?php echo 'label-pri-' . $story2Link->pri?>' title='<?php echo zget($lang->story->priList, $story2Link->pri, $story2Link->pri);?>'><?php echo zget($lang->story->priList, $story2Link->pri, $story2Link->pri);?></span></td>
<td><?php echo html::a($this->createLink('product', 'browse', "productID=$story2Link->product&branch=$story2Link->branch"), $products[$story2Link->product], '_blank');?></td>
<td class='text-left nobr' title="<?php echo $story2Link->title?>"><?php echo html::a($storyLink, $story2Link->title, '_blank');?></td>
<td><?php echo $story2Link->planTitle;?></td>
<td><?php echo $this->processStatus('story', $story2Link);?></td>
<?php if($story->type == 'requirement'):?>
<td><?php echo zget($lang->story->stageList, $story2Link->stage);?></td>
<?php endif;?>
<td><?php echo zget($users, $story2Link->openedBy);?></td>
<td><?php echo $story2Link->estimate;?></td>
</tr>
@@ -87,20 +87,6 @@ $(function()
$('#linkStoryForm').table();
setTimeout(function(){$('#linkStoryForm .table-footer').removeClass('fixed-footer');}, 100);
<?php endif;?>
$('#submit').click(function(){
var output = '';
$('#linkStoryForm').find('tr.checked').each(function(){
var storyID = $(this).find('td.c-id').find('div.checkbox-primary input').attr('value');
var storyName = "#" + storyID + ' ' + $(this).find('td').eq(3).attr('title');
var checkbox = "<li><div class='checkbox-primary'><input type='checkbox' checked='checked' name='" + linkType + "[]' " + "value=" + storyID + " /><label>" + storyName + "</label></div></li>";
output += checkbox;
});
$.closeModal();
parent.$('#' + linkType + 'Box').html(output);
return false;
});
});
</script>
<?php include '../../common/view/footer.html.php';?>
+86
View File
@@ -0,0 +1,86 @@
<?php include '../../common/view/header.html.php';?>
<?php js::set('storyType', 'track');?>
<style>
.table td{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}
.requirement{background: #fff}
.main-table tbody>tr:hover { background-color: #fff; }
.main-table tbody>tr:nth-child(odd):hover { background-color: #f5f5f5; }
</style>
<div id="mainContent" class="main-row fade">
<div class="main-col">
<?php if(empty($tracks)):?>
<div class="table-empty-tip">
<p>
<span class="text-muted"><?php echo $lang->noData;?></span>
</p>
</div>
<?php else:?>
<div class='main-table' data-ride="table">
<table class='table table-bordered' id="trackList">
<thead>
<tr>
<th><?php echo $lang->story->requirement;?></th>
<th><?php echo $lang->story->story;?></th>
<th><?php echo $lang->story->design;?></th>
<th><?php echo $lang->story->case;?></th>
<th><?php echo $lang->story->repoCommit;?></th>
<th><?php echo $lang->story->bug;?></th>
</tr>
</thead>
<tbody>
<?php foreach($tracks as $key => $requirement):?>
<?php $track = ($key == 'noRequirement') ? $requirement : $requirement->track;?>
<?php $rowspan = count($track);?>
<tr>
<td <?php if($rowspan != 0) echo "rowspan=" . $rowspan;?> class='requirement'>
<?php echo $key == 'noRequirement' ? $lang->story->noRequirement : html::a($this->createLink('story', 'view', "storyID=$requirement->id"), $requirement->title, '', "title=$requirement->title");?>
<?php if($key != 'noRequirement'):?>
<span class="label label-primary label-outline"><?php echo zget($lang->story->statusList, $requirement->status);?></span>
<?php endif;?>
</td>
<?php if(count($track) != 0):?>
<?php $i = 1;?>
<?php foreach($track as $storyID => $story):?>
<?php if($i != 1) echo '<tr>';?>
<td style='padding-left: 10px;'><?php echo html::a($this->createLink('story', 'view', "storyID=$storyID"), $story->title, '',"title='$story->title'");?></td>
<td>
<?php foreach($story->design as $designID => $design):?>
<?php echo html::a($this->createLink('design', 'view', "designID=$designID"), $design->name, '', "title='$design->name'") . '<br/>';?>
<?php endforeach;?>
</td>
<td>
<?php foreach($story->case as $caseID => $case):?>
<?php echo html::a($this->createLink('testcase', 'view', "caseID=$caseID"), $case->title, '', "title='$case->title'") . '<br/>';?>
<?php endforeach;?>
</td>
<td>
<?php foreach($story->revision as $revision => $repoID):?>
<?php
echo html::a($this->createLink('design', 'revision', "repoID=$revision"), '#'. $revision) . '<br/>';
?>
<?php endforeach;?>
</td>
<td>
<?php foreach($story->bug as $bugID => $bug):?>
<?php echo html::a($this->createLink('bug', 'view', "bugID=$bugID"), $bug->title, '', "title='$bug->title'") . '<br/>';?>
<?php endforeach;?>
</td>
<?php if($i != 1) echo '</tr>';?>
<?php $i++;?>
<?php endforeach;?>
<?php else:?>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<?php endif;?>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
<?php endif;?>
</div>
</div>
<?php include '../../common/view/footer.html.php';?>
+74
View File
@@ -62,6 +62,56 @@
<div class="detail-title"><?php echo $lang->story->legendVerify;?></div>
<div class="detail-content article-content"><?php echo $story->verify;?></div>
</div>
<?php if($story->type == 'requirement'):?>
<?php if(!empty($track)):?>
<div class="detail">
<div class="detail-title"><?php echo $lang->story->track;?></div>
<div class="detail-content article-content main-table">
<table class="table">
<thead>
<tr>
<th class="w-120px"><?php echo $lang->story->story;?></th>
<th class="w-120px"><?php echo $lang->story->design;?></th>
<th class="w-120px"><?php echo $lang->story->case;?></th>
<th class="w-60px"><?php echo $lang->story->repoCommit;?></th>
<th class="w-120px"><?php echo $lang->story->bug;?></th>
</tr>
</thead>
<tbody>
<?php foreach($track as $storyID => $storyInfo):?>
<tr>
<td style='padding-left: 10px;'><?php echo html::a($this->createLink('story', 'view', "storyID=$storyID"), $storyInfo->title, '', "title='$storyInfo->title'");?>
</td>
<td>
<?php foreach($storyInfo->design as $designID => $design):?>
<?php echo html::a($this->createLink('design', 'view', "designID=$designID"), $design->name, '', "title='$design->name'") . '<br/>';?>
<?php endforeach;?>
</td>
<td>
<?php foreach($storyInfo->case as $caseID => $case):?>
<?php echo html::a($this->createLink('testcase', 'view', "caseID=$caseID"), $case->title, '', "title='$case->title'") . '<br/>';?>
<?php endforeach;?>
</td>
<td>
<?php foreach($storyInfo->revision as $revision => $repoID):?>
<?php
echo html::a($this->createLink('design', 'revision', "repoID=$revision"), '#'. $revision) . '<br/>';
?>
<?php endforeach;?>
</td>
<td>
<?php foreach($storyInfo->bug as $bugID => $bug):?>
<?php echo html::a($this->createLink('bug', 'view', "bugID=$bugID"), $bug->title, '', "title='$bug->title'") . '<br/>';?>
<?php endforeach;?>
</td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
</div>
<?php endif;?>
<?php endif;?>
<?php echo $this->fetch('file', 'printFiles', array('files' => $story->files, 'fieldset' => 'true'));?>
<?php $actionFormLink = $this->createLink('action', 'comment', "objectType=story&objectID=$story->id");?>
<?php if(!empty($story->children)):?>
@@ -334,12 +384,34 @@
<ul class='nav nav-tabs'>
<?php if($config->global->flow == 'onlyStory'):?>
<li class='active'><a href='#legendRelated' data-toggle='tab'><?php echo $lang->story->legendRelated;?></a></li>
<?php elseif($program->template == 'cmmi'):?>
<li class='active'><a href='#legendStories' data-toggle='tab'><?php echo $story->type == 'story' ? $lang->story->requirement : $lang->story->story;?></a></li>
<li><a href='#legendProjectAndTask' data-toggle='tab'><?php echo $lang->story->legendProjectAndTask;?></a></li>
<li><a href='#legendRelated' data-toggle='tab'><?php echo $lang->story->legendRelated;?></a></li>
<?php else:?>
<li class='active'><a href='#legendProjectAndTask' data-toggle='tab'><?php echo $lang->story->legendProjectAndTask;?></a></li>
<li><a href='#legendRelated' data-toggle='tab'><?php echo $lang->story->legendRelated;?></a></li>
<?php endif;?>
</ul>
<div class='tab-content'>
<?php if($program->template == 'cmmi'):?>
<div class='tab-pane active' id='legendStories'>
<ul class="list-unstyled">
<?php
$relation = array();
foreach($relations as $item) $relation[$item->id] = $item->title;
foreach($relation as $id => $title)
{
echo "<li title='$title'>" . html::a($this->createLink('story', 'view', "id=$id", '', true), "#$id $title", '', "class='iframe' data-width='80%'");
echo html::a($this->createLink('story', 'linkStory', "storyID=$story->id&type=remove&linkedID=$id"), '<i class="icon icon-close"></i>', 'hiddenwin', "class='deleter hide removeButton'");
}
?>
<?php $linkLang = ($story->type == 'story') ? $lang->story->requirement : $lang->story->story;?>
<li><?php echo html::a($this->createLink('story', 'linkStory', "storyID=$story->id", '', true), $lang->story->link . $linkLang, '', "class='btn btn-info iframe' data-width='95%' id='linkButton'");?>
<?php if(!empty($relations)) echo html::a('javascript:void(0)', $lang->story->unlink . $linkLang, '', "class='btn btn-info' id='unlinkStory'");?></li>
</ul>
</div>
<?php endif;?>
<?php if($config->global->flow != 'onlyStory'):?>
<div class='tab-pane active' id='legendProjectAndTask'>
<ul class="list-unstyled">
@@ -454,6 +526,8 @@ js::set('productID', $story->product);
js::set('branch', $story->branch);
js::set('moduleID', $story->module);
js::set('storyType', $story->type);
js::set('unlink', $lang->story->unlink);
js::set('cancel', $lang->cancel);
?>
<?php include '../../common/view/syntaxhighlighter.html.php';?>
<?php include '../../common/view/footer.html.php';?>
+1 -1
View File
@@ -40,7 +40,7 @@ class weekly extends control
$this->view->postponed = $this->weekly->getPostponed($program);
$this->view->nextWeek = $this->weekly->getTasksOfNextWeek($program, $date);
$this->view->workload = $this->weekly->getWorkloadByType($program, $date);
$this->weekly->save($program, $this->view, $date);
$this->weekly->save($program, $date);
$this->lang->modulePageNav = $this->weekly->getPageNav($this->view->program, $date);
$this->display();
+8 -9
View File
@@ -60,19 +60,18 @@ class weeklyModel extends model
->fetch();
}
public function save($program, $data, $date)
public function save($program, $date)
{
$report = new stdclass;
$report->pv = zget($data, 'pv', '');
$report->ev = zget($data, 'ev', '');
$report->ac = zget($data, 'ac', '');
$report->sv = zget($data, 'sv', '');
$report->cv = zget($data, 'cv', '');
$report->pv = $this->getPV($program, $date);
$report->ev = $this->getEV($program, $date);
$report->ac = $this->getAC($program, $date);
$report->sv = $this->getSV($report->ev, $report->pv);
$report->cv = $this->getCV($report->ev, $report->ac);
$report->program = $program;
$report->weekStart = $this->getThisMonday($date);
$report->staff = zget($data, 'staff', '');
$report->progress = zget($data, 'progress', '');
$report->workload = json_encode(zget($data, 'workload', ''));
$report->staff = $this->getStaff($program);
$report->workload = json_encode($this->getWorkloadByType($program, $date));
$this->dao->replace(TABLE_WEEKLYREPORT)->data($report)->exec();
}