Merge branch '20.x' of github.com:easysoft/zentaopms into 20.x
This commit is contained in:
@@ -224,6 +224,8 @@ $lang->action->label->unlinkchildrenstory = "unlinked a child story";
|
||||
$lang->action->label->linkparentstory = "linked a parent story";
|
||||
$lang->action->label->unlinkparentstory = "unlink from parent story";
|
||||
$lang->action->label->deletechildrenstory = "delete children story";
|
||||
$lang->action->label->tracked = 'tracked';
|
||||
$lang->action->label->hangup = 'hangup';
|
||||
|
||||
/* 动态信息按照对象分组 */
|
||||
$lang->action->dynamicAction = new stdclass;
|
||||
@@ -400,6 +402,7 @@ $lang->action->label->testreport = 'Berichte|testreport|view|report=%s';
|
||||
$lang->action->label->entry = 'Eintrag|entry|browse|';
|
||||
$lang->action->label->webhook = 'Webhook|webhook|browse|';
|
||||
$lang->action->label->space = ' ';
|
||||
$lang->action->label->risk = 'Risk|risk|view|riskID=%s';
|
||||
|
||||
/* Object type. */
|
||||
$lang->action->search->objectTypeList[''] = '';
|
||||
|
||||
@@ -224,6 +224,8 @@ $lang->action->label->unlinkchildrenstory = "unlinked a child story";
|
||||
$lang->action->label->linkparentstory = "linked a parent story";
|
||||
$lang->action->label->unlinkparentstory = "unlink from parent story";
|
||||
$lang->action->label->deletechildrenstory = "delete children story";
|
||||
$lang->action->label->tracked = 'tracked';
|
||||
$lang->action->label->hangup = 'hangup';
|
||||
|
||||
/* Dynamic information is grouped by object. */
|
||||
$lang->action->dynamicAction = new stdclass;
|
||||
@@ -400,6 +402,7 @@ $lang->action->label->testreport = 'Report|testreport|view|report=%s';
|
||||
$lang->action->label->entry = 'Application|entry|browse|';
|
||||
$lang->action->label->webhook = 'Webhook|webhook|browse|';
|
||||
$lang->action->label->space = ' ';
|
||||
$lang->action->label->risk = 'Risk|risk|view|riskID=%s';
|
||||
|
||||
/* Object type. */
|
||||
$lang->action->search->objectTypeList[''] = '';
|
||||
|
||||
@@ -224,6 +224,8 @@ $lang->action->label->unlinkchildrenstory = "unlinked a child story";
|
||||
$lang->action->label->linkparentstory = "linked a parent story";
|
||||
$lang->action->label->unlinkparentstory = "unlink from parent story";
|
||||
$lang->action->label->deletechildrenstory = "delete children story";
|
||||
$lang->action->label->tracked = 'tracked';
|
||||
$lang->action->label->hangup = 'hangup';
|
||||
|
||||
/* 动态信息按照对象分组 */
|
||||
$lang->action->dynamicAction = new stdclass;
|
||||
@@ -400,6 +402,7 @@ $lang->action->label->testreport = 'Rapport|testreport|view|report=%s';
|
||||
$lang->action->label->entry = 'Application|entry|browse|';
|
||||
$lang->action->label->webhook = 'Webhook|webhook|browse|';
|
||||
$lang->action->label->space = ' ';
|
||||
$lang->action->label->risk = 'Risk|risk|view|riskID=%s';
|
||||
|
||||
/* Object type. */
|
||||
$lang->action->search->objectTypeList[''] = '';
|
||||
|
||||
@@ -224,6 +224,8 @@ $lang->action->label->unlinkchildrenstory = "hủy liên kết a child story";
|
||||
$lang->action->label->linkparentstory = "linked a parent story";
|
||||
$lang->action->label->unlinkparentstory = "unlink from parent story";
|
||||
$lang->action->label->deletechildrenstory = "delete children story";
|
||||
$lang->action->label->tracked = 'tracked';
|
||||
$lang->action->label->hangup = 'hangup';
|
||||
|
||||
/* Dynamic information is grouped by object. */
|
||||
$lang->action->dynamicAction = new stdclass;
|
||||
@@ -400,6 +402,7 @@ $lang->action->label->testreport = 'Báo cáo|testreport|view|report=%s';
|
||||
$lang->action->label->entry = 'Ứng dụng|entry|browse|';
|
||||
$lang->action->label->webhook = 'Webhook|webhook|browse|';
|
||||
$lang->action->label->space = ' ';
|
||||
$lang->action->label->risk = 'Risk|risk|view|riskID%s';
|
||||
|
||||
/* Object type. */
|
||||
$lang->action->search->objectTypeList[''] = '';
|
||||
|
||||
@@ -224,6 +224,8 @@ $lang->action->label->unlinkchildrenstory = "取消关联子需求";
|
||||
$lang->action->label->linkparentstory = "关联到父需求";
|
||||
$lang->action->label->unlinkparentstory = "从父需求取消关联";
|
||||
$lang->action->label->deletechildrenstory = "删除子需求";
|
||||
$lang->action->label->tracked = '跟踪了';
|
||||
$lang->action->label->hangup = '挂起了';
|
||||
|
||||
/* 动态信息按照对象分组 */
|
||||
$lang->action->dynamicAction = new stdclass();
|
||||
@@ -400,6 +402,7 @@ $lang->action->label->testreport = '报告|testreport|view|report=%s';
|
||||
$lang->action->label->entry = '应用|entry|browse|';
|
||||
$lang->action->label->webhook = 'Webhook|webhook|browse|';
|
||||
$lang->action->label->space = ' ';
|
||||
$lang->action->label->risk = '风险|risk|view|riskID=%s';
|
||||
|
||||
/* Object type. */
|
||||
$lang->action->search->objectTypeList[''] = '';
|
||||
|
||||
@@ -224,6 +224,8 @@ $lang->action->label->unlinkchildrenstory = "取消關聯子需求";
|
||||
$lang->action->label->linkparentstory = "關聯到父需求";
|
||||
$lang->action->label->unlinkparentstory = "從父需求取消關聯";
|
||||
$lang->action->label->deletechildrenstory = "刪除子需求";
|
||||
$lang->action->label->tracked = '跟踪了';
|
||||
$lang->action->label->hangup = '挂起了';
|
||||
|
||||
/* 動態信息按照對象分組 */
|
||||
$lang->action->dynamicAction = new stdclass();
|
||||
@@ -400,6 +402,7 @@ $lang->action->label->testreport = '報告|testreport|view|report=%s';
|
||||
$lang->action->label->entry = '應用|entry|browse|';
|
||||
$lang->action->label->webhook = 'Webhook|webhook|browse|';
|
||||
$lang->action->label->space = ' ';
|
||||
$lang->action->label->risk = '風險|risk|view|riskID=%s';
|
||||
|
||||
/* Object type. */
|
||||
$lang->action->search->objectTypeList[''] = '';
|
||||
|
||||
@@ -1034,7 +1034,7 @@ class block extends control
|
||||
$this->session->set('riskList', $uri);
|
||||
if(preg_match('/[^a-zA-Z0-9_]/', $this->params->type)) die();
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
$this->view->issues = $this->loadModel('issue')->getBlockIssues($this->params->type, $this->viewType == 'json' ? 0 : (int)$this->params->num, null, $this->params->orderBy);
|
||||
$this->view->issues = $this->loadModel('issue')->getBlockIssues($this->params->type, $this->viewType == 'json' ? 0 : (int)$this->params->num, $this->params->orderBy);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1045,7 +1045,10 @@ class block extends control
|
||||
*/
|
||||
public function printCmmiRiskBlock()
|
||||
{
|
||||
$this->view->program = $this->loadModel('project')->getByID($this->session->program);
|
||||
$uri = $this->app->getURI(true);
|
||||
$this->session->set('riskList', $uri);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
$this->view->risks = $this->loadModel('risk')->getBlockRisks($this->params->type, $this->viewType == 'json' ? 0 : (int)$this->params->num, $this->params->orderBy);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1073,9 +1076,40 @@ class block extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function printCmmiprogressBlock()
|
||||
public function printCmmiProgressBlock()
|
||||
{
|
||||
$this->view->program = $this->loadModel('project')->getByID($this->session->program);
|
||||
$this->loadModel('milestone');
|
||||
$this->loadModel('weekly');
|
||||
$program = $this->loadModel('project')->getByID($this->session->program);
|
||||
|
||||
$begin = $program->begin;
|
||||
$end = helper::today();
|
||||
|
||||
$projects = $this->project->getProjectsByProgram($program);
|
||||
$projectIdList = array_keys($projects);
|
||||
|
||||
$charts['PV'] = '[';
|
||||
$charts['EV'] = '[';
|
||||
$charts['AC'] = '[';
|
||||
$i = 1;
|
||||
$start = $begin;
|
||||
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"));
|
||||
$i ++;
|
||||
}
|
||||
|
||||
$charts['labels'][] = $this->lang->milestone->chart->time . $i . $this->lang->milestone->chart->week;
|
||||
$charts['PV'] .= $this->milestone->getPV($projectIdList, $begin, $end) . ']';
|
||||
$charts['EV'] .= $this->milestone->getEV($projectIdList, $begin, $end) . ']';
|
||||
$charts['AC'] .= $this->milestone->getAC($projectIdList, $begin, $end) . ']';
|
||||
|
||||
$this->view->charts = $charts;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1488,6 +1522,13 @@ class block extends control
|
||||
*/
|
||||
public function printScrumdynamicBlock()
|
||||
{
|
||||
$this->view->program = $this->loadModel('project')->getByID($this->session->program);
|
||||
}
|
||||
$projects = $this->loadModel('project')->getPairs();
|
||||
$actions = $this->dao->select('*')->from(TABLE_ACTION)
|
||||
->where('project')->in(array_keys($projects))
|
||||
->orderBy('id_desc')
|
||||
->fetchAll();
|
||||
|
||||
$this->view->actions = $this->loadModel('action')->transformActions($actions);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -682,4 +682,5 @@ class blockModel extends model
|
||||
|
||||
return json_encode($params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<th><?php echo $lang->workestimation->duration;?></th>
|
||||
<td><?php echo zget($budget, 'duration', 0) . ' ' . $lang->workestimation->hour;?></td>
|
||||
<th><?php echo $lang->workestimation->consumed;?></th>
|
||||
<td><?php echo zget($budget, 'productivity', '') . ' ' . $lang->workestimation->hour;?></td>
|
||||
<td><?php echo zget($budget, 'productivity', 0) . ' ' . $lang->workestimation->hour;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->workestimation->totalLaborCost;?></th>
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
<?php if($longBlock):?>
|
||||
<th class='w-80px'><?php echo $lang->issue->severity;?></th>
|
||||
<th class='w-80px'><?php echo $lang->issue->pri;?></th>
|
||||
<?php endif;?>
|
||||
<th class='w-120px'><?php echo $lang->issue->owner;?></th>
|
||||
<th class='w-120px'><?php echo $lang->issue->assignedTo;?></th>
|
||||
<?php endif;?>
|
||||
<th class='w-80px'><?php echo $lang->issue->status;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -36,10 +36,10 @@
|
||||
<td class='c-name' title='<?php echo $issue->title?>'><?php echo html::a($viewLink, $issue->title);?></td>
|
||||
<?php if($longBlock):?>
|
||||
<td class='c-severity'><?php echo zget($lang->issue->severityList, $issue->severity, $issue->severity)?></td>
|
||||
<td class='c-pri'><span class='label-pri label-pri-<?php echo $issue->pri;?>' title='<?php echo zget($lang->issue->priList, $issue->pri, $issue->pri)?>'><?php echo zget($lang->issue->priList, $issue->pri, $issue->pri)?></span></td>
|
||||
<?php endif;?>
|
||||
<td class='c-pri'><?php echo zget($lang->issue->priList, $issue->pri, $issue->pri)?></td>
|
||||
<td><?php echo zget($users, $issue->owner, $issue->owner)?></td>
|
||||
<td><?php echo zget($users, $issue->assignedTo, $issue->assignedTo)?></td>
|
||||
<?php endif;?>
|
||||
<td class='c-status'>
|
||||
<span class="status-issue status-<?php echo $issue->status?>"><?php echo zget($lang->issue->statusList, $issue->status);?></span>
|
||||
</td>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<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)}
|
||||
</style>
|
||||
<?php include '../../milestone/view/chart.html.php';?>
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php if(empty($risks)): ?>
|
||||
<div class='empty-tip'><?php echo $lang->block->emptyTip;?></div>
|
||||
<?php else:?>
|
||||
<style>
|
||||
.block-risks .c-pri {width: 45px;text-align: center;}
|
||||
.block-risks .c-status {width: 80px;}
|
||||
</style>
|
||||
<div class='panel-body has-table scrollbar-hover'>
|
||||
<table class='table table-borderless table-hover table-fixed table-fixed-head tablesorter block-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='w-100px'> <?php echo $lang->risk->strategy;?></th>
|
||||
<?php endif;?>
|
||||
<th class='w-80px'><?php echo $lang->risk->status;?></th>
|
||||
<?php if($longBlock):?>
|
||||
<th class='w-80px'><?php echo $lang->risk->riskindex;?></th>
|
||||
<th class='w-80px'><?php echo $lang->risk->pri;?></th>
|
||||
<th class='w-120px'><?php echo $lang->risk->assignedTo;?></th>
|
||||
<th class='w-120px'><?php echo $lang->risk->category;?></th>
|
||||
<?php endif;?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($risks as $risk):?>
|
||||
<?php
|
||||
$viewLink = $this->createLink('risk', 'view', "riskID={$risk->id}");
|
||||
?>
|
||||
<tr>
|
||||
<td class='c-id-xs'><?php echo sprintf('%03d', $risk->id);?></td>
|
||||
<td class='c-name' title='<?php echo $risk->name?>'><?php echo html::a($viewLink, $risk->name);?></td>
|
||||
<?php if($longBlock):?>
|
||||
<td class='c-strategy'><?php echo zget($lang->risk->strategyList, $risk->strategy, $risk->strategy)?></td>
|
||||
<?php endif;?>
|
||||
<td class='c-status'>
|
||||
<span class="status-risk status-<?php echo $risk->status?>"><?php echo zget($lang->risk->statusList, $risk->status);?></span>
|
||||
</td>
|
||||
<?php if($longBlock):?>
|
||||
<td class='c-riskindex'><?php echo $risk->riskindex?></td>
|
||||
<td class='c-pri'><?php echo zget($lang->risk->priList, $risk->pri, $risk->pri)?></td>
|
||||
<td><?php echo zget($users, $risk->assignedTo, $risk->assignedTo)?></td>
|
||||
<td class='c-category'><?php echo zget($lang->risk->categoryList, $risk->category, $risk->category)?></td>
|
||||
<?php endif;?>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?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
|
||||
$i = 0;
|
||||
foreach($actions as $action)
|
||||
{
|
||||
$user = zget($users, $action->actor);
|
||||
if($action->action == 'login' or $action->action == 'logout') $action->objectName = $action->objectLabel = '';
|
||||
$class = $action->major ? "class='active'" : '';
|
||||
echo "<li $class><div>";
|
||||
printf($lang->block->dynamicInfo, $action->date, $user, $action->actionLabel, $action->objectLabel, $action->objectLink, $action->objectName, $action->objectName);
|
||||
echo "</div></li>";
|
||||
$i++;
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
|
||||
@@ -1,101 +1,134 @@
|
||||
<?php
|
||||
/**
|
||||
* The control file of design currentModule 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 design
|
||||
* @version $Id: control.php 5107 2013-07-12 01:46:12Z chencongzhi520@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
class design extends control
|
||||
{
|
||||
public function browse($productID = 0,$type = 'all', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
/**
|
||||
* Browse designs.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param string $type
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function browse($productID = 0, $type = 'all', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
$productID = $this->loadModel('product')->saveState($productID, $this->product->getPairs('nocode'));
|
||||
|
||||
$this->design->setProductMenu($productID);
|
||||
$product = $this->loadModel('product')->getById($productID);
|
||||
$project = $this->loadModel('project')->getById($product->program);
|
||||
$program = $this->loadModel('project')->getById($product->program);
|
||||
|
||||
$this->app->session->set('designList', $this->app->getURI(true));
|
||||
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
if($this->app->getViewType() == 'mhtml') $recPerPager = 10;
|
||||
$pager = pager::init($recTotal, $recPerPage, $pageID);
|
||||
$pager = pager::init($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$designs = $this->design->getList($productID, $type, $orderBy, $pager);
|
||||
|
||||
$this->view->title = $this->lang->design->browse;
|
||||
$this->view->position[] = $this->lang->design->browse;
|
||||
$this->view->title = $this->lang->design->browse;
|
||||
$this->view->position[] = $this->lang->design->browse;
|
||||
|
||||
$this->view->designs = $designs;
|
||||
$this->view->type = $type;
|
||||
$this->view->recTotal = $recTotal;
|
||||
$this->view->recPerPage = $recPerPage;
|
||||
$this->view->pageID = $pageID;
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->productID = $productID;
|
||||
$this->view->program = $project;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->designs = $designs;
|
||||
$this->view->type = $type;
|
||||
$this->view->recTotal = $recTotal;
|
||||
$this->view->recPerPage = $recPerPage;
|
||||
$this->view->pageID = $pageID;
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->productID = $productID;
|
||||
$this->view->pager = $pager;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a design.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param string $prevModule
|
||||
* @param int $prevID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function create($productID = 0, $prevModule = '', $prevID = 0)
|
||||
{
|
||||
$productID = $this->loadModel('product')->saveState($productID, $this->product->getPairs('nocode'));
|
||||
$this->design->setProductMenu($productID);
|
||||
|
||||
if($_POST)
|
||||
{
|
||||
$productID = $_POST['product'];
|
||||
|
||||
$designID = $this->design->create();
|
||||
if($designID)
|
||||
$productID = $this->post->product;
|
||||
$designID = $this->design->create();
|
||||
if(dao::isError())
|
||||
{
|
||||
$this->loadModel('action')->create('design', $designID, 'created');
|
||||
|
||||
$response['result'] = 'success';
|
||||
$response['message'] = $this->lang->saveSuccess;
|
||||
$response['locate'] = $this->createLink('design', 'browse', "productID=$productID");
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = dao::getError();
|
||||
$this->send($response);
|
||||
}
|
||||
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = dao::getError();
|
||||
$this->loadModel('action')->create('design', $designID, 'created');
|
||||
|
||||
$response['result'] = 'success';
|
||||
$response['message'] = $this->lang->saveSuccess;
|
||||
$response['locate'] = $this->createLink('design', 'browse', "productID=$productID");
|
||||
$this->send($response);
|
||||
}
|
||||
|
||||
$this->view->title = $this->lang->design->create;
|
||||
$this->view->position[] = $this->lang->design->create;
|
||||
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed');
|
||||
$this->view->stories = $this->loadModel('story')->getProductStoryPairs($productID);
|
||||
$this->view->products = $this->loadModel('product')->getPairs($this->session->program);
|
||||
$this->view->productID = $productID;
|
||||
$this->view->program = $this->loadModel('project')->getByID($this->session->program);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed');
|
||||
$this->view->stories = $this->loadModel('story')->getProductStoryPairs($productID);
|
||||
$this->view->products = $this->loadModel('product')->getPairs($this->session->program);
|
||||
$this->view->productID = $productID;
|
||||
$this->view->program = $this->loadModel('project')->getByID($this->session->program);
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* View a design.
|
||||
*
|
||||
* @param int $designID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function view($designID = 0)
|
||||
{
|
||||
$data = $this->design->getById($designID);
|
||||
$data->productName = $this->dao->findByID($data->product)->from(TABLE_PRODUCT)->fetch('name');
|
||||
$data->files = $this->loadModel('file')->getByObject('design', $designID);
|
||||
|
||||
$relations = $this->loadModel('common')->getRelations('design', $data->id, 'commit');
|
||||
$data->commit = '';
|
||||
foreach($relations as $relation) $data->commit .= html::a(helper::createLink('design', 'revision', "repoID=$relation->BID", '', true), "#$relation->BID", '', "class='iframe' data-width='80%' data-height='550'");
|
||||
|
||||
$storyTitle = $this->dao->findByID($data->story)->from(TABLE_STORY)->fetch('title');
|
||||
$data->story = $storyTitle ? html::a($this->createLink('story', 'view', "id=$data->story"), $storyTitle) : '';
|
||||
|
||||
$actions = $this->loadModel('action')->getList('design', $data->id);
|
||||
$design = $this->design->getById($designID);
|
||||
$this->design->setProductMenu($design->product);
|
||||
|
||||
$this->view->title = $this->lang->design->designView;
|
||||
$this->view->position[] = $this->lang->design->designView;
|
||||
|
||||
$this->view->productID = $data->product;
|
||||
$this->view->data = $data;
|
||||
$this->view->relations = $relations;
|
||||
$this->view->design = $design;
|
||||
$this->view->stories = $this->loadModel('story')->getProductStoryPairs($design->product);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
$this->view->actions = $actions;
|
||||
$this->view->actions = $this->loadModel('action')->getList('design', $design->id);
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a design.
|
||||
*
|
||||
* @param int $designID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function edit($designID = 0)
|
||||
{
|
||||
$design = $this->design->getByID($designID);
|
||||
@@ -105,11 +138,17 @@ class design extends control
|
||||
if($_POST)
|
||||
{
|
||||
$changes = $this->design->update($designID);
|
||||
if($changes)
|
||||
if(dao::isError())
|
||||
{
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = dao::getError();
|
||||
$this->send($response);
|
||||
}
|
||||
|
||||
if(!empty($changes))
|
||||
{
|
||||
$actionID = $this->loadModel('action')->create('design', $designID, 'changed');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
|
||||
}
|
||||
|
||||
$response['result'] = 'success';
|
||||
@@ -129,18 +168,30 @@ class design extends control
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit a design.
|
||||
*
|
||||
* @param int $designID
|
||||
* @param string $begin
|
||||
* @param string $end
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function commit($designID, $begin = '', $end = '', $recTotal = 0, $recPerPage = 50, $pageID = 1)
|
||||
{
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$program = $this->loadModel('project')->getByID($this->session->program);
|
||||
$begin = $begin ? date('Y-m-d', strtotime($begin)) : $program->begin;
|
||||
$end = $end ? date('Y-m-d', strtotime($end)) : helper::today();
|
||||
|
||||
$repoID = $this->session->repoID;
|
||||
$repo = $this->loadModel('repo')->getRepoByID($repoID);
|
||||
$revisions = $this->repo->getCommits($repo, '', 'HEAD', '', $pager, $begin, $end);
|
||||
$repoID = $this->session->repoID;
|
||||
$repo = $this->loadModel('repo')->getRepoByID($repoID);
|
||||
$revisions = $this->repo->getCommits($repo, '', 'HEAD', '', $pager, $begin, $end);
|
||||
|
||||
if($_POST)
|
||||
{
|
||||
@@ -172,6 +223,21 @@ class design extends control
|
||||
$this->display();
|
||||
}
|
||||
|
||||
public function revision($repoID)
|
||||
{
|
||||
$repo = $this->dao->select('*')->from(TABLE_REPOHISTORY)->where('id')->eq($repoID)->fetch();
|
||||
$repoURL = $this->createLink('repo', 'revision', "repoID=$repo->repo&revistion=$repo->revision");
|
||||
header("location:" . $repoURL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a design.
|
||||
*
|
||||
* @param int $designID
|
||||
* @param string $confirm
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function delete($designID, $confirm = 'no')
|
||||
{
|
||||
if($confirm == 'no')
|
||||
|
||||
3
module/design/css/browse.css
Normal file
3
module/design/css/browse.css
Normal file
@@ -0,0 +1,3 @@
|
||||
#featurebar{display:inline-block;}
|
||||
.modal-dialog{width:70% !important}
|
||||
table td{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}
|
||||
1
module/design/css/edit.css
Normal file
1
module/design/css/edit.css
Normal file
@@ -0,0 +1 @@
|
||||
.tabs .tab-pane .table{border: 1px solid #ddd; border-top: none}
|
||||
@@ -3,3 +3,14 @@ $(document).on('click', '.ajaxPager', function()
|
||||
$('#logBox').load($(this).attr('href'));
|
||||
return false;
|
||||
})
|
||||
$('#product').change(function()
|
||||
{
|
||||
productID = $(this).val();
|
||||
var link = createLink('story', 'ajaxGetProductStories', 'productID=' + productID);
|
||||
$.post(link, function(data)
|
||||
{
|
||||
$('#story').replaceWith(data);
|
||||
$('#story_chosen').remove();
|
||||
$('#story').chosen();
|
||||
})
|
||||
})
|
||||
|
||||
@@ -28,9 +28,9 @@ $lang->design->designView = '查看详情';
|
||||
$lang->design->reviewObject = '评审对象';
|
||||
$lang->design->createdBy = '由谁创建';
|
||||
$lang->design->createdDate = '创建时间';
|
||||
$lang->design->basicInfo = '基本信息';
|
||||
|
||||
$lang->design->typeList = array();
|
||||
$lang->design->typeList['all'] = '所有';
|
||||
$lang->design->typeList['HLDS'] = '概要设计';
|
||||
$lang->design->typeList['DDS'] = '详细设计';
|
||||
$lang->design->typeList['DBDS'] = '数据库设计';
|
||||
@@ -44,3 +44,5 @@ $lang->design->rangeList = array();
|
||||
$lang->design->rangeList['all'] = '全部记录';
|
||||
$lang->design->rangeList['assign'] = '选中记录';
|
||||
|
||||
$lang->design->featureBar['all'] = '所有';
|
||||
$lang->design->featureBar += $lang->design->typeList;
|
||||
|
||||
@@ -1,6 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* The model file of design 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 design
|
||||
* @version $Id: model.php 5079 2013-07-10 00:44:34Z chencongzhi520@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php
|
||||
class designModel extends model
|
||||
{
|
||||
/**
|
||||
* Create a design.
|
||||
*
|
||||
* @access public
|
||||
* @return int|bool
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$design = fixer::input('post')
|
||||
@@ -9,14 +27,14 @@ class designModel extends model
|
||||
->add('createdDate', helper::now())
|
||||
->add('program', $this->session->program)
|
||||
->add('version', 1)
|
||||
->remove('file,files,labels,children, toList')
|
||||
->remove('file,files,labels,children,toList')
|
||||
->get();
|
||||
|
||||
$design = $this->loadModel('file')->processImgURL($design, 'desc', $this->post->uid);
|
||||
$this->dao->insert(TABLE_DESIGN)->data($design)->autoCheck()->batchCheck('name,type', 'notempty')->exec();
|
||||
|
||||
if(!dao::isError())
|
||||
{
|
||||
{
|
||||
$designID = $this->dao->lastInsertID();
|
||||
$this->file->updateObjectID($this->post->uid, $designID, 'design');
|
||||
$files = $this->file->saveUpload('design', $designID);
|
||||
@@ -30,11 +48,18 @@ class designModel extends model
|
||||
$this->dao->insert(TABLE_DESIGNSPEC)->data($spec)->exec();
|
||||
|
||||
return $designID;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a design.
|
||||
*
|
||||
* @param int $designID
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function update($designID)
|
||||
{
|
||||
$oldDesign = $this->getByID($designID);
|
||||
@@ -42,7 +67,7 @@ class designModel extends model
|
||||
->add('editedBy', $this->app->user->account)
|
||||
->add('editedDate', helper::now())
|
||||
->stripTags($this->config->design->editor->edit['id'], $this->config->allowedTags)
|
||||
->remove('file,files,labels,children, toList')
|
||||
->remove('file,files,labels,children,toList')
|
||||
->get();
|
||||
|
||||
$design = $this->loadModel('file')->processImgURL($design, 'desc', $this->post->uid);
|
||||
@@ -57,7 +82,7 @@ class designModel extends model
|
||||
if($designChanged)
|
||||
{
|
||||
$design = $this->getByID($designID);
|
||||
$version = $design->version + 1;
|
||||
$version = $design->version + 1;
|
||||
$spec = new stdclass();
|
||||
$spec->design = $designID;
|
||||
$spec->version = $version;
|
||||
@@ -70,16 +95,23 @@ class designModel extends model
|
||||
}
|
||||
|
||||
return common::createChanges($oldDesign, $design);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* LinkCommit a design.
|
||||
*
|
||||
* @param int $designID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function linkCommit($designID)
|
||||
{
|
||||
$this->dao->delete()->from(TABLE_RELATION)->where('AType')->eq('design')->andWhere('AID')->eq($designID)->andWhere('BType')->eq('commit')->andWhere('relation')->eq('completedin')->exec();
|
||||
$this->dao->delete()->from(TABLE_RELATION)->where('AType')->eq('commit')->andWhere('BID')->eq($designID)->andWhere('BType')->eq('design')->andWhere('relation')->eq('completedfrom')->exec();
|
||||
$revisions = $_POST['revision'];
|
||||
$revisions = $_POST['revision'];
|
||||
|
||||
foreach($revisions as $revision)
|
||||
{
|
||||
@@ -105,52 +137,52 @@ class designModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
public function setFlowActionFields($module, $action)
|
||||
{
|
||||
$flow = $this->loadModel('workflow', 'flow')->getByModule($module);
|
||||
$action = $this->loadModel('workflowaction', 'flow')->getByModuleAndAction($flow->module, $action);
|
||||
$fields = $this->workflowaction->getFields($flow->module, $action->action);
|
||||
|
||||
return array($flow, $action, $fields);
|
||||
}
|
||||
|
||||
public function setFlowChild($module, $action, $fields, $dataID = 0)
|
||||
{
|
||||
$this->loadModel('workflowlayout', 'flow');
|
||||
|
||||
$childFields = array();
|
||||
$childDatas = array();
|
||||
$childModules = $this->loadModel('workflow', 'flow')->getList($module, 'table');
|
||||
foreach($childModules as $childModule)
|
||||
{
|
||||
$key = 'sub_' . $childModule->module;
|
||||
|
||||
if(isset($fields[$key]) && $fields[$key]->show)
|
||||
{
|
||||
$childFields[$key] = $this->workflowaction->getFields($childModule->module, $action);
|
||||
$childDatas[$key] = $this->flow->getDataList($childModule, '', 0, $dataID);
|
||||
}
|
||||
}
|
||||
|
||||
return array($childFields, $childDatas);
|
||||
}
|
||||
|
||||
/**
|
||||
* SetProductMenu
|
||||
*
|
||||
* @param int $productID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function setProductMenu($productID = 0)
|
||||
{
|
||||
{
|
||||
$programID = $this->session->program;
|
||||
$program = $this->loadModel('project')->getByID($programID);
|
||||
$products = $this->loadModel('product')->getPairs($programID);
|
||||
$productID = in_array($productID, array_keys($products)) ? $productID : key($products);
|
||||
|
||||
$productID = $this->loadModel('product')->saveState($productID, $products);
|
||||
$this->loadModel('product')->setMenu($products, $productID);
|
||||
if($program->category == 'multiple') $this->loadModel('product')->setMenu($products, $productID);
|
||||
}
|
||||
|
||||
/**
|
||||
* GetByID
|
||||
*
|
||||
* @param int $designID
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getByID($designID)
|
||||
{
|
||||
$design = $this->dao->select('*')->from(TABLE_DESIGN)->where('id')->eq($designID)->fetch();
|
||||
return $this->loadModel('file')->replaceImgURL($design, 'desc');
|
||||
$design->files = $this->loadModel('file')->getByObject('design', $designID);
|
||||
$design->productName = $this->dao->findByID($design->product)->from(TABLE_PRODUCT)->fetch('name');
|
||||
|
||||
|
||||
$design->commit = '';
|
||||
$relations = $this->loadModel('common')->getRelations('design', $designID, 'commit');
|
||||
foreach($relations as $relation) $design->commit .= html::a(helper::createLink('design', 'revision', "repoID=$relation->BID"), "#$relation->BID", '_blank');
|
||||
return $this->loadModel('file')->replaceImgURL($design, 'desc');
|
||||
}
|
||||
|
||||
/**
|
||||
* GetDesignPairs
|
||||
*
|
||||
* @param int $productID
|
||||
* @param string $type
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getDesignPairs($productID = 0, $type = 'detailed')
|
||||
{
|
||||
$designs = $this->dao->select('id, name')->from(TABLE_DESIGN)
|
||||
@@ -158,13 +190,20 @@ class designModel extends model
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('type')->eq($type)
|
||||
->fetchPairs();
|
||||
foreach($designs as $id => $name) $designs[$id] = $id . ':' . $name;
|
||||
foreach($designs as $id => $name) $designs[$id] = $id . ':' . $name;
|
||||
|
||||
return $designs;
|
||||
}
|
||||
|
||||
/**
|
||||
* GetAffectedScope
|
||||
*
|
||||
* @param int $design
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getAffectedScope($design)
|
||||
{
|
||||
{
|
||||
/* Get affected tasks. */
|
||||
$design->tasks = $this->dao->select('*')->from(TABLE_TASK)
|
||||
->where('deleted')->eq(0)
|
||||
@@ -175,16 +214,34 @@ class designModel extends model
|
||||
return $design;
|
||||
}
|
||||
|
||||
public function getList($productID, $type, $orderBy, $pager)
|
||||
/**
|
||||
* GetList
|
||||
*
|
||||
* @param int $productID
|
||||
* @param int $type
|
||||
* @param int $orderBy
|
||||
* @param int $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getList($productID, $type = 'all', $orderBy = 'id_desc', $pager = null)
|
||||
{
|
||||
return $this->dao->select('*')->from(TABLE_DESIGN)
|
||||
$designs = $this->dao->select('*')->from(TABLE_DESIGN)
|
||||
->where('deleted')->eq(0)
|
||||
->beginIF($this->session->program)->andWhere('program')->eq($this->session->program)->fi()
|
||||
->beginIF(!$this->app->user->admin)->andWhere('product')->in($this->app->user->view->products)->fi()
|
||||
->beginIF($type !='all')->andWhere('type')->in($type)->fi()
|
||||
->beginIF($type != 'all')->andWhere('type')->in($type)->fi()
|
||||
->andWhere('product')->eq($productID)
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
|
||||
foreach($designs as $id => $design)
|
||||
{
|
||||
$design->commit = '';
|
||||
$relations = $this->loadModel('common')->getRelations('design', $id, 'commit');
|
||||
foreach($relations as $relation) $design->commit .= html::a(helper::createLink('design', 'revision', "repoID=$relation->BID", '', true), "#$relation->BID", '_blank');
|
||||
}
|
||||
|
||||
return $designs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,123 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* The browse view file of flow module of RanZhi.
|
||||
* The browse view file of design module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2016 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license 商业软件,非开源软件
|
||||
* @author Gang Liu <liugang@cnezsoft.com>
|
||||
* @package flow
|
||||
* @version $Id$
|
||||
* @link http://www.ranzhico.com
|
||||
* @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 design
|
||||
* @version $Id: browse.html.php 5102 2013-07-12 00:59:54Z chencongzhi520@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php
|
||||
if(!empty($dataList))
|
||||
{
|
||||
foreach($dataList as $data)
|
||||
{
|
||||
$relations = $this->loadModel('common')->getRelations('design', $data->id, 'commit');
|
||||
$data->commit = '';
|
||||
foreach($relations as $relation) $data->commit .= html::a(helper::createLink('design', 'revision', "repoID=$relation->BID", '', true), "#$relation->BID", '', "class='iframe' data-width='80%' data-height='550'");
|
||||
}
|
||||
}
|
||||
?>
|
||||
<?php include '../../' . 'common/view/header.html.php';?>
|
||||
<style>
|
||||
#featurebar{display:inline-block;}
|
||||
.modal-dialog{width:70% !important}
|
||||
table td{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}
|
||||
</style>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php include '../../common/view/sortable.html.php';?>
|
||||
<?php js::set('productID', $productID);?>
|
||||
<?php
|
||||
$showSubHeader = $program->category == 'single' ? 'hidden' : 'show';
|
||||
js::set('showSubHeader', $showSubHeader);
|
||||
?>
|
||||
<div id='mainMenu' class='clearfix'>
|
||||
<div class='btn-toolbar pull-left'>
|
||||
<?php
|
||||
$recTotalLabel = " <span class='label label-light label-badge'>{$pager->recTotal}</span>";
|
||||
echo html::a(inlink('browse', "productID={$productID}&type=all"), "<span class='text'>{$lang->design->typeList['all']}</span>" . ($type == 'all' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'all' ? ' btn-active-text' : '') . "'");
|
||||
echo html::a(inlink('browse', "productID={$productID}&type=HLDS"), "<span class='text'>{$lang->design->typeList['HLDS']}</span>" . ($type == 'HLDS' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'HLDS' ? ' btn-active-text' : '') . "'");
|
||||
echo html::a(inlink('browse', "productID={$productID}&type=DDS"), "<span class='text'>{$lang->design->typeList['DDS']}</span>" . ($type == 'DDS' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'DDS' ? ' btn-active-text' : '') . "'");
|
||||
echo html::a(inlink('browse', "productID={$productID}&type=DBDS"), "<span class='text'>{$lang->design->typeList['DBDS']}</span>" . ($type == 'DBDS' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'DBDS' ? ' btn-active-text' : '') . "'");
|
||||
echo html::a(inlink('browse', "productID={$productID}&type=ADS"), "<span class='text'>{$lang->design->typeList['ADS']}</span>" . ($type == 'ADS' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'ADS' ? ' btn-active-text' : '') . "'");
|
||||
foreach($lang->design->featureBar as $key => $label)
|
||||
{
|
||||
$active = $key == $type ? 'btn-active-text' : '';
|
||||
$recTotalLabel = $key == $type ? " <span class='label label-light label-badge'>{$pager->recTotal}</span>" : '';
|
||||
echo html::a(inlink('browse', "productID={$productID}&type=$key"), "<span class='text'>$label</span>" . $recTotalLabel, '', "class='btn btn-link $active'");
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class='btn-toolbar pull-right'>
|
||||
<?php
|
||||
if(common::hasPriv('design', 'create')) echo html::a($this->createLink('design', 'create', "productID=$productID&designID=0"), "<i class='icon icon-plus'></i> {$lang->design->create}", '', "class='btn btn-primary'");
|
||||
?>
|
||||
<?php if(common::hasPriv('design', 'create')) echo html::a($this->createLink('design', 'create', "productID=$productID&designID=0"), "<i class='icon icon-plus'></i> {$lang->design->create}", '', "class='btn btn-primary'");?>
|
||||
</div>
|
||||
</div>
|
||||
<div id="mainContent" class="main-row fade in">
|
||||
<?php if(empty($designs)):?>
|
||||
<div class="table-empty-tip">
|
||||
<p><span class="text-muted"><?php echo $lang->design->noDesign;?></span></p>
|
||||
<p><span class="text-muted"><?php echo $lang->design->noDesign;?></span></p>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<form id='designFrom' method='post' class="main-table">
|
||||
<table class='table has-sort-head table-fixrd' id="designTable">
|
||||
<?php $vars = "productID=$productID&orderBy=%s&recTotal=$pager->recTotal&recPerPage=$pager->recPerPage&pageID=$pager->pageID";?>
|
||||
<?php $vars = "productID=$productID&type=$type&orderBy=%s&recTotal=$pager->recTotal&recPerPage=$pager->recPerPage&pageID=$pager->pageID";?>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-left w-120px">
|
||||
<div class="checkbox-primary check-all" title="<?php echo $lang->selectAll;?>"></div>
|
||||
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
|
||||
</th>
|
||||
<th class="text-left w-120px">
|
||||
<?php common::printOrderLink('type', $orderBy, $vars, $lang->design->type);?>
|
||||
</th>
|
||||
<th class="text-left">
|
||||
<?php common::printOrderLink('name', $orderBy, $vars, $lang->design->name);?>
|
||||
</th>
|
||||
<th class="text-left w-130px">
|
||||
<?php common::printOrderLink('commit', $orderBy, $vars, $lang->design->submission);?>
|
||||
</th>
|
||||
<th class="text-left w-70px">
|
||||
<?php common::printOrderLink('version', $orderBy, $vars, $lang->design->version);?>
|
||||
</th>
|
||||
<th class="text-left w-120px">
|
||||
<?php common::printOrderLink('createdBy', $orderBy, $vars, $lang->design->createdBy);?>
|
||||
</th>
|
||||
<th class="text-left w-150px">
|
||||
<?php common::printOrderLink('createdDate', $orderBy, $vars, $lang->design->createdDate);?>
|
||||
</th>
|
||||
<th class="text-left w-120px">
|
||||
<?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->design->assignedTo);?>
|
||||
</th>
|
||||
<th class="text-center w-100px">
|
||||
<?php echo $lang->design->actions;?>
|
||||
</th>
|
||||
<th class="text-left w-60px"> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
|
||||
<th class="text-left w-100px"> <?php common::printOrderLink('type', $orderBy, $vars, $lang->design->type);?></th>
|
||||
<th class="text-left"> <?php common::printOrderLink('name', $orderBy, $vars, $lang->design->name);?></th>
|
||||
<th class="text-left w-150px"> <?php common::printOrderLink('commit', $orderBy, $vars, $lang->design->submission);?></th>
|
||||
<th class="text-left w-120px"> <?php common::printOrderLink('createdBy', $orderBy, $vars, $lang->design->createdBy);?></th>
|
||||
<th class="text-left w-150px"> <?php common::printOrderLink('createdDate', $orderBy, $vars, $lang->design->createdDate);?></th>
|
||||
<th class="text-left w-120px"> <?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->design->assignedTo);?></th>
|
||||
<th class="text-center w-100px"><?php echo $lang->design->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($designs as $design):?>
|
||||
<tr>
|
||||
<td class='text-left'><?php printf('%03d', $design->id);?></td>
|
||||
<td class='text-left'><?php echo zget($lang->design->typeList, $design->type);?></td>
|
||||
<td class='text-left' title="<?php echo $design->name;?>"><?php echo html::a($this->createLink('design', 'view', "id={$design->id}"), $design->name);?></td>
|
||||
<td class='text-left'><?php echo zget($lang->design->submission, $design->commit);?></td>
|
||||
<td class='text-left'><?php echo zget($lang->design->version, $design->version);?></td>
|
||||
<td class='text-left'><?php echo $design->createdBy;?></td>
|
||||
<td class='text-left'><?php echo $design->createdDate;?></td>
|
||||
<td class='text-left'><?php echo $design->assignedTo;?></td>
|
||||
<td><?php printf('%03d', $design->id);?></td>
|
||||
<td><?php echo zget($lang->design->typeList, $design->type);?></td>
|
||||
<td title="<?php echo $design->name;?>"><?php echo html::a($this->createLink('design', 'view', "id={$design->id}"), $design->name);?></td>
|
||||
<td><?php echo $design->commit;?></td>
|
||||
<td><?php echo $design->createdBy;?></td>
|
||||
<td><?php echo substr($design->createdDate, 0, 11);?></td>
|
||||
<td><?php echo $design->assignedTo;?></td>
|
||||
<td class='c-actions text-center'>
|
||||
<?php
|
||||
$vars = "design={$design->id}";
|
||||
common::printIcon('design', 'edit', $vars, $design, 'list', 'fork', '', '', '', '', '', $design->program);
|
||||
common::printIcon('design', 'commit', $vars, $design, 'list', 'link', '', 'iframe showinonlybody', true);
|
||||
common::printIcon('design', 'delete', $vars, $design, 'list', 'trash', 'hiddenwin', '', '', '', '', $design->program);
|
||||
?>
|
||||
<?php
|
||||
$vars = "design={$design->id}";
|
||||
common::printIcon('design', 'edit', $vars, $design, 'list', 'fork', '', '', '', '', '', $design->program);
|
||||
common::printIcon('design', 'commit', $vars, $design, 'list', 'link', '', 'iframe showinonlybody', true);
|
||||
common::printIcon('design', 'delete', $vars, $design, 'list', 'trash', 'hiddenwin', '', '', '', '', $design->program);
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class='table-footer'>
|
||||
<?php $pager->show('right', 'pagerjs');?>
|
||||
<?php $pager->show('right', 'pagerjs');?>
|
||||
</div>
|
||||
</form>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<?php include '../../' . 'common/view/footer.html.php';?>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* The commit view of design 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 design
|
||||
* @version $Id: commit.html.php 4903 2013-06-26 05:32:59Z wyd621@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.lite.html.php';?>
|
||||
<style>.m-design-commit{padding-left: 0px;}</style>
|
||||
<div class='main-content' id='mainContent'>
|
||||
<div class='main-header'>
|
||||
<h2>
|
||||
@@ -9,9 +20,9 @@
|
||||
</h2>
|
||||
</div>
|
||||
<div class='searchBox'>
|
||||
<h4><?php echo $lang->design->commitDate . ':';?></h4>
|
||||
<?php echo html::input('begin', $begin, "class='form-control form-date srearch-date'");?>
|
||||
<span>~</span>
|
||||
<h4><?php echo $lang->design->commitDate . ':';?></h4>
|
||||
<?php echo html::input('begin', $begin, "class='form-control form-date srearch-date'");?>
|
||||
<span>~</span>
|
||||
<?php echo html::input('end', $end, "class='form-control form-date srearch-date'");?>
|
||||
</div>
|
||||
<form id='logForm' class='main-table form-ajax' data-ride='table' action=<?php echo inlink('commit', "designID=$designID");?> method='post'>
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* The create view of design 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 design
|
||||
* @version $Id: create.html.php 4903 2013-06-26 05:32:59Z wyd621@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php include '../../common/view/kindeditor.html.php';?>
|
||||
<?php
|
||||
$showSubHeader = $program->category == 'single' ? 'hidden' : 'show';
|
||||
js::set('showSubHeader', $showSubHeader);
|
||||
?>
|
||||
<div id="mainContent" class="main-content fade">
|
||||
<div class="center-block">
|
||||
<div class="main-header">
|
||||
@@ -19,9 +27,7 @@ js::set('showSubHeader', $showSubHeader);
|
||||
<td></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<?php if($program->category == 'single'):?>
|
||||
<?php echo html::hidden('product', $productID);?>
|
||||
<?php endif;?>
|
||||
<?php if($program->category == 'single') echo html::hidden('product', $productID);?>
|
||||
<tr>
|
||||
<th class='w-120px'><?php echo $lang->design->story;?></th>
|
||||
<td><?php echo html::select('story', empty($stories) ? '' : $stories, '', "class='form-control chosen'");?></td>
|
||||
@@ -53,19 +59,4 @@ js::set('showSubHeader', $showSubHeader);
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$('#product').change(function()
|
||||
{
|
||||
productID = $(this).val();
|
||||
var link = createLink('story', 'ajaxGetProductStories', 'productID=' + productID);
|
||||
$.post(link, function(data)
|
||||
{
|
||||
$('#story').replaceWith(data);
|
||||
$('#story_chosen').remove();
|
||||
$('#story').chosen();
|
||||
})
|
||||
})
|
||||
|
||||
if(showSubHeader == 'hidden') $("#subHeader").remove();
|
||||
</script>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* The edit view of design 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 design
|
||||
* @version $Id: edit.html.php 4903 2013-06-26 05:32:59Z wyd621@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php include '../../common/view/kindeditor.html.php';?>
|
||||
<?php
|
||||
$showSubHeader = $program->category == 'single' ? 'hidden' : 'show';
|
||||
js::set('showSubHeader', $showSubHeader);
|
||||
?>
|
||||
<style> .tabs .tab-pane .table{border: 1px solid #ddd; border-top: none} </style>
|
||||
<div id="mainContent" class="main-content fade">
|
||||
<div class="center-block">
|
||||
<div class="main-header">
|
||||
@@ -89,19 +96,4 @@ js::set('showSubHeader', $showSubHeader);
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$('#product').change(function()
|
||||
{
|
||||
productID = $(this).val();
|
||||
var link = createLink('story', 'ajaxGetProductStories', 'productID=' + productID);
|
||||
$.post(link, function(data)
|
||||
{
|
||||
$('#story').replaceWith(data);
|
||||
$('#story_chosen').remove();
|
||||
$('#story').chosen();
|
||||
})
|
||||
})
|
||||
|
||||
if(showSubHeader == 'hidden') $("#subHeader").remove();
|
||||
</script>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
<?php include '../../' . 'common/view/header.html.php';?>
|
||||
<?php
|
||||
if(!empty($_GET['onlybody']))
|
||||
{
|
||||
$data->commit = '';
|
||||
foreach($relations as $relation) $data->commit .= " #$relation->BID";
|
||||
$data->story = $storyTitle;
|
||||
}
|
||||
/**
|
||||
* The view of design 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 design
|
||||
* @version $Id: view.html.php 4903 2013-06-26 05:32:59Z wyd621@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div id="mainMenu" class="clearfix">
|
||||
<div class="btn-toolbar pull-left">
|
||||
<?php echo html::a($this->createLink('design', 'browse', "productID=$productID"), '<i class="icon icon-back icon-sm"></i> ' . $lang->goback, '', "class='btn btn-secondary'");?>
|
||||
<?php echo html::a($this->createLink('design', 'browse', "productID=$design->product"), '<i class="icon icon-back icon-sm"></i> ' . $lang->goback, '', "class='btn btn-secondary'");?>
|
||||
<div class="divider"></div>
|
||||
<div class="page-title">
|
||||
<span class="label label-id"><?php echo $data->id?></span>
|
||||
<span class="text" title="<?php echo $data->name;?>"><?php echo $data->name;?></span>
|
||||
<span class="label label-id"><?php echo $design->id?></span>
|
||||
<span class="text" title="<?php echo $design->name;?>"><?php echo $design->name;?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -23,65 +27,60 @@ if(!empty($_GET['onlybody']))
|
||||
<div class="detail">
|
||||
<div class="detail-title"><?php echo $lang->design->desc;?></div>
|
||||
<div class="detail-content article-content">
|
||||
<?php echo $data->desc;?>
|
||||
<?php echo $this->fetch('file', 'printFiles', array('files' => $data->files, 'fieldset' => 'true'));?>
|
||||
<?php echo $design->desc;?>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo $this->fetch('file', 'printFiles', array('files' => $design->files, 'fieldset' => 'true'));?>
|
||||
</div>
|
||||
<div class='cell'><?php include '../../common/view/action.html.php';?></div>
|
||||
<div class='main-actions'>
|
||||
<div class="btn-toolbar">
|
||||
<?php common::printBack($this->session->designList);?>
|
||||
<?php if(!isonlybody()) echo "<div class='divider'></div>";?>
|
||||
<?php if(!$data->deleted):?>
|
||||
<?php if(!$design->deleted):?>
|
||||
<?php
|
||||
common::printIcon('design', 'commit',"designID=$data->id", $data, 'button', 'link', '', 'iframe showinonlybody', true);
|
||||
common::printIcon('design', 'edit', "designID=$data->id", $data, 'button', '', '', '', true);
|
||||
common::printIcon('design', 'delete', "designID=$data->id", $data, 'button', 'trash', 'hiddenwin');
|
||||
common::printIcon('design', 'commit', "designID=$design->id", $design, 'button', 'link', '', 'iframe showinonlybody', true);
|
||||
common::printIcon('design', 'edit', "designID=$design->id", $design, 'button', 'fork', '', '', true);
|
||||
common::printIcon('design', 'delete', "designID=$design->id", $design, 'button', 'trash', 'hiddenwin');
|
||||
?>
|
||||
<?php endif;?>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='side-col col4'>
|
||||
<div class='side-col col-4'>
|
||||
<div class='cell'>
|
||||
<div class="detail">
|
||||
<table class='table table-data'>
|
||||
<tr>
|
||||
<th><?php echo $lang->design->type;?></th>
|
||||
<td><?php echo zget($lang->design->typeList, $data->type);?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->design->product;?></th>
|
||||
<td><?php echo $data->productName;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->design->story;?></th>
|
||||
<td><?php echo $data->story;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->design->commit;?></th>
|
||||
<td><?php echo $data->commit;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->design->createdBy;?></th>
|
||||
<td><?php echo zget($users, $data->createdBy);?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->design->createdDate;?></th>
|
||||
<td><?php echo $data->createdDate;?></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class='detail-title'><?php echo $lang->design->basicInfo;?></div>
|
||||
<div class='detail-content'>
|
||||
<table class='table table-data'>
|
||||
<tr>
|
||||
<th><?php echo $lang->design->type;?></th>
|
||||
<td><?php echo zget($lang->design->typeList, $design->type);?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->design->product;?></th>
|
||||
<td><?php echo $design->productName;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->design->story;?></th>
|
||||
<td><?php echo $design->story ? html::a($this->createLink('story', 'view', "id=$design->story"), zget($stories, $design->story)) : '';?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->design->commit;?></th>
|
||||
<td><?php echo $design->commit;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->design->createdBy;?></th>
|
||||
<td><?php echo zget($users, $design->createdBy);?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->design->createdDate;?></th>
|
||||
<td><?php echo substr($design->createdDate, 0, 11);?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$('.main-actions').width($('.main-col').outerWidth());
|
||||
if(showAction == 'hidden')
|
||||
{
|
||||
$('.main-actions').remove();
|
||||
$('.pull-left').children('a').remove();
|
||||
};
|
||||
</script>
|
||||
<?php include '../../' . 'common/view/footer.html.php';?>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -16,13 +16,13 @@ $lang->moduleOrder[5] = 'my';
|
||||
$lang->moduleOrder[10] = 'todo';
|
||||
|
||||
$lang->moduleOrder[11] = 'program';
|
||||
$lang->moduleOrder[12] = 'design';
|
||||
$lang->moduleOrder[15] = 'product';
|
||||
$lang->moduleOrder[20] = 'story';
|
||||
$lang->moduleOrder[25] = 'productplan';
|
||||
$lang->moduleOrder[30] = 'release';
|
||||
|
||||
$lang->moduleOrder[35] = 'project';
|
||||
$lang->moduleOrder[36] = 'design';
|
||||
$lang->moduleOrder[40] = 'task';
|
||||
$lang->moduleOrder[45] = 'build';
|
||||
|
||||
@@ -180,6 +180,30 @@ $lang->program->methodOrder[60] = 'setPlanduration';
|
||||
$lang->program->methodOrder[65] = 'manageMembers';
|
||||
$lang->program->methodOrder[70] = 'export';
|
||||
|
||||
/* Risk . */
|
||||
$lang->resource->risk = new stdclass();
|
||||
$lang->resource->risk->browse = 'browse';
|
||||
$lang->resource->risk->create = 'create';
|
||||
$lang->resource->risk->edit = 'edit';
|
||||
$lang->resource->risk->delete = 'delete';
|
||||
$lang->resource->risk->activate = 'activate';
|
||||
$lang->resource->risk->close = 'close';
|
||||
$lang->resource->risk->hangup = 'hangup';
|
||||
$lang->resource->risk->batchCreate = 'batchCreate';
|
||||
$lang->resource->risk->cancel = 'cancel';
|
||||
$lang->resource->risk->track = 'track';
|
||||
|
||||
$lang->risk->methodOrder[5] = 'browse';
|
||||
$lang->risk->methodOrder[10] = 'create';
|
||||
$lang->risk->methodOrder[15] = 'edit';
|
||||
$lang->risk->methodOrder[20] = 'delete';
|
||||
$lang->risk->methodOrder[25] = 'activate';
|
||||
$lang->risk->methodOrder[30] = 'close';
|
||||
$lang->risk->methodOrder[35] = 'hangup';
|
||||
$lang->risk->methodOrder[40] = 'batchCreate';
|
||||
$lang->risk->methodOrder[45] = 'cancel';
|
||||
$lang->risk->methodOrder[50] = 'track';
|
||||
|
||||
/* Product. */
|
||||
$lang->resource->product = new stdclass();
|
||||
$lang->resource->product->index = 'index';
|
||||
@@ -440,6 +464,7 @@ $lang->resource->design->browse = 'browse';
|
||||
$lang->resource->design->create = 'create';
|
||||
$lang->resource->design->edit = 'edit';
|
||||
$lang->resource->design->commit = 'commit';
|
||||
$lang->resource->design->revision = 'revision';
|
||||
$lang->resource->design->delete = 'delete';
|
||||
$lang->resource->design->view = 'view';
|
||||
|
||||
@@ -447,8 +472,9 @@ $lang->design->methodOrder[5] = 'browse';
|
||||
$lang->design->methodOrder[10] = 'create';
|
||||
$lang->design->methodOrder[15] = 'edit';
|
||||
$lang->design->methodOrder[20] = 'commit';
|
||||
$lang->design->methodOrder[25] = 'delete';
|
||||
$lang->design->methodOrder[30] = 'view';
|
||||
$lang->design->methodOrder[25] = 'revision';
|
||||
$lang->design->methodOrder[30] = 'delete';
|
||||
$lang->design->methodOrder[35] = 'view';
|
||||
|
||||
/* Task. */
|
||||
$lang->resource->task = new stdclass();
|
||||
|
||||
5
module/milestone/config.php
Normal file
5
module/milestone/config.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
$config->milestone = new stdclass();
|
||||
$config->milestone->story = 'URS,SRS';
|
||||
$config->milestone->design = 'HLDS,DDS';
|
||||
$config->milestone->test = 'ITTC,STP,STTC,ITP';
|
||||
61
module/milestone/control.php
Normal file
61
module/milestone/control.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
class milestone extends control
|
||||
{
|
||||
public function index($programID = 0, $projectID = 0, $productID = 0)
|
||||
{
|
||||
$this->loadModel('program');
|
||||
$this->loadModel('project');
|
||||
list($this->lang->modulePageNav, $projectID) = $this->milestone->getPageNav($programID, $projectID, $productID);
|
||||
|
||||
$this->view->title = $this->lang->milestone->title;
|
||||
|
||||
if(!$projectID)
|
||||
{
|
||||
$this->view->projectID = $projectID;
|
||||
$this->display();
|
||||
die;
|
||||
}
|
||||
|
||||
$productID = $this->loadModel('product')->getProductIDByProject($projectID);
|
||||
$stageList = $this->loadModel('programplan')->getPairs($programID, $productID);
|
||||
unset($stageList[0]);
|
||||
|
||||
$this->view->projectID = $projectID;
|
||||
$this->view->programID = $programID;
|
||||
$this->view->stageList = $stageList;
|
||||
$this->view->basicInfo = $this->milestone->getBasicInfo($programID, $projectID);
|
||||
$this->view->process = $this->milestone->getProcess($programID, $projectID);
|
||||
$this->view->charts = $this->milestone->getCharts($programID, $projectID);
|
||||
$this->view->productQuality = $this->milestone->getProductQuality($programID, $projectID);
|
||||
$this->view->workhours = $this->milestone->getWorkhours($programID, $projectID);
|
||||
$this->view->measures = $this->milestone->getMeasures($programID, $projectID);
|
||||
$this->view->projectRisk = $this->milestone->getProjectRisk($programID);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed|noletter');
|
||||
$this->view->stageInfo = $this->milestone->getStageDemand($programID, $projectID, $productID, $stageList);
|
||||
$this->view->otherproblems = $this->milestone->otherProblemsList($programID, $projectID);
|
||||
$this->view->nextMilestone = $this->milestone->getNextMilestone($programID, $projectID, $stageList);
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
public function ajaxAddMeasures()
|
||||
{
|
||||
$data = fixer::input('post')->get();
|
||||
if(empty($data->projectID)) return 0;
|
||||
return $this->milestone->ajaxAddMeasures($data);
|
||||
}
|
||||
|
||||
public function saveOtherProblem()
|
||||
{
|
||||
$re = $this->milestone->saveOtherProblem();
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess));
|
||||
}
|
||||
|
||||
public function ajaxSaveEstimate()
|
||||
{
|
||||
$taskID = $this->post->taskID;
|
||||
$estimate = $this->post->estimate;
|
||||
$re = $this->milestone->ajaxSaveEstimate($taskID,$estimate);
|
||||
$this->send(array('result' => 'success','message' => $this->lang->saveSuccess));
|
||||
}
|
||||
}
|
||||
15
module/milestone/css/index.css
Normal file
15
module/milestone/css/index.css
Normal file
@@ -0,0 +1,15 @@
|
||||
#dropMenu .col-left .list-group {margin-bottom: 0px; }
|
||||
.table, .cell{margin-bottom: 15px !important}
|
||||
.main-table tbody>tr>td {position: relative; border-bottom: 0; border-bottom: 1px solid #ddd;}
|
||||
.main-table tbody>tr:last-child>td {border-bottom: none;}
|
||||
.cell{position: relative;}
|
||||
#chartUnit {position: absolute; color: #000; top: 20px; left: 15px;}
|
||||
#chartLegend {position: absolute; right: 0; width: 80px; height: 60px; top: 50%; margin-top: -30px; line-height: 30px; color: #838A9D; font-size: 12px;}
|
||||
#chartLegend > div {position: relative; padding-left: 30px;}
|
||||
#chartLegend > div > .barline {position: absolute; width: 20px; left: 0; top: 13px; height: 3px;}
|
||||
#chartLegend .line-pv .barline{background: #1183fb}
|
||||
#chartLegend .line-ev .barline{background: rgb(0, 218, 136)}
|
||||
#chartLegend .line-ac .barline{background: rgb(255, 145, 0)}
|
||||
|
||||
.scroll-table {overflow-x: scroll}
|
||||
.scroll-table > .table {min-width:350%}
|
||||
100
module/milestone/lang/zh-cn.php
Normal file
100
module/milestone/lang/zh-cn.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
$lang->milestone->index = '报告首页';
|
||||
$lang->milestone->title = '里程碑报告';
|
||||
$lang->milestone->common = '项目里程碑报告';
|
||||
$lang->milestone->name = '里程碑名称';
|
||||
$lang->milestone->stage = '里程碑阶段';
|
||||
$lang->milestone->save = '保存';
|
||||
|
||||
$lang->milestone->startedWeeks = '开始周数';
|
||||
$lang->milestone->finishedWeeks = '结束周数';
|
||||
$lang->milestone->offset = '里程碑工期偏差';
|
||||
|
||||
$lang->milestone->processCommon = '项目当前进展状况';
|
||||
$lang->milestone->process = '项目进度';
|
||||
$lang->milestone->projectCost = '项目成本';
|
||||
$lang->milestone->toNow = '到目前为止';
|
||||
$lang->milestone->targetRange = '目标控制范围';
|
||||
$lang->milestone->ge = '大于等于';
|
||||
$lang->milestone->le = '小于等于';
|
||||
$lang->milestone->analysis = '分析结果';
|
||||
$lang->milestone->PV = '计划完成的工作(PV)';
|
||||
$lang->milestone->EV = '实际完成的工作(EV)';
|
||||
$lang->milestone->AC = '实际花费的成本(AC)';
|
||||
$lang->milestone->SPI = '项目进度绩效(SPI)';
|
||||
$lang->milestone->CPI = '项目成本绩效(CPI)';
|
||||
$lang->milestone->SV = '进度偏差率(SV%)';
|
||||
$lang->milestone->CV = '成本偏差率(CV%)';
|
||||
|
||||
$lang->milestone->workHours = '工作量(人时)';
|
||||
$lang->milestone->allStage = '工程阶段';
|
||||
$lang->milestone->devHours = '研发工作量';
|
||||
$lang->milestone->toHours = '返工工作量';
|
||||
$lang->milestone->reviewHours = '评审工作量';
|
||||
$lang->milestone->qaHours = '测试工作量';
|
||||
$lang->milestone->rowSummary = '工作量小计';
|
||||
$lang->milestone->rowPercent = '分布百分比(%)';
|
||||
$lang->milestone->colPercent = '占工作量百分比(%)';
|
||||
$lang->milestone->colSummary = '总和';
|
||||
$lang->milestone->qatoDev = '测试研发比';
|
||||
|
||||
$lang->milestone->projectRisk = '5.项目风险(优先最高的前五项风险)';
|
||||
$lang->milestone->riskCountermove = '风险对策';
|
||||
$lang->milestone->riskDescriptio = '风险描述';
|
||||
$lang->milestone->riskPossibility = '可能性';
|
||||
$lang->milestone->riskSeriousness = '严重性';
|
||||
$lang->milestone->riskFactor = '风险系数';
|
||||
$lang->milestone->riskMeasures = '风险对策';
|
||||
$lang->milestone->riskAccumulate = '累积的高风险';
|
||||
|
||||
$lang->milestone->otherIssue = '其它问题';
|
||||
$lang->milestone->issueSolutions = '问题及解决建议';
|
||||
$lang->milestone->issueDescription = '问题描述';
|
||||
$lang->milestone->needHelp = '是否需要高层支持';
|
||||
$lang->milestone->issuePropose = '解决建议';
|
||||
|
||||
$lang->milestone->demandStatus = '4.用户需求状况分析';
|
||||
$lang->milestone->storyUnit = '单位:Item';
|
||||
$lang->milestone->engineeringStage = '工程阶段';
|
||||
$lang->milestone->rateChange = '需求变化率';
|
||||
$lang->milestone->originalStory = '原始需求数量';
|
||||
$lang->milestone->modifyNumber = '变更后需求总数';
|
||||
$lang->milestone->changeStory = '变更的需求数';
|
||||
|
||||
$lang->milestone->paogressForecast = '项目进展预测';
|
||||
$lang->milestone->duration = '工期(天)';
|
||||
$lang->milestone->cost = '成本(人时)';
|
||||
$lang->milestone->forecastResults = '预测结果分析';
|
||||
$lang->milestone->plannedValue = '计划值';
|
||||
$lang->milestone->predictedValue = '预测值';
|
||||
$lang->milestone->predictedValueDesc = '计算公式:如果项目进度绩效(SPI)=0,那么预测值=0,否则,预测值=计划值 除以 项目进度绩效(SPI)';
|
||||
$lang->milestone->periodDeviation = '工期偏差';
|
||||
$lang->milestone->costDeviation = '成本偏差';
|
||||
$lang->milestone->nextStage = '下一里程碑阶段';
|
||||
$lang->milestone->overallProject = '项目总体';
|
||||
$lang->milestone->corrective = '纠偏措施';
|
||||
$lang->milestone->timeOverrun = '总工期将超出:%s天。';
|
||||
$lang->milestone->costOverrun = '总成本将超出:%s个单位。';
|
||||
$lang->milestone->saveOtherProblem = '保存其他问题';
|
||||
|
||||
$lang->milestone->chart = new stdclass();
|
||||
$lang->milestone->chart->title = '到目前为止项目进展趋势图';
|
||||
$lang->milestone->chart->time = '第';
|
||||
$lang->milestone->chart->week = '周';
|
||||
$lang->milestone->chart->workhour = '研发工作量分析图';
|
||||
|
||||
$lang->milestone->otherproblem = '6.其它问题';
|
||||
$lang->milestone->problemandsuggest = '问题及解决建议';
|
||||
$lang->milestone->suggest = '解决建议';
|
||||
$lang->milestone->needhelp = '是否需要高层支持?';
|
||||
$lang->milestone->prodescr = '问题描述';
|
||||
|
||||
$lang->milestone->quality = new stdclass();
|
||||
$lang->milestone->quality->total = '合计';
|
||||
$lang->milestone->quality->identify = '缺陷识别阶段';
|
||||
$lang->milestone->quality->injection = '缺陷注入阶段';
|
||||
$lang->milestone->quality->scale = '规模';
|
||||
$lang->milestone->quality->identifyRate = '缺陷识别率';
|
||||
$lang->milestone->quality->injectionRate = '缺陷注入率';
|
||||
|
||||
$lang->milestone->options = '操作';
|
||||
607
module/milestone/model.php
Normal file
607
module/milestone/model.php
Normal file
@@ -0,0 +1,607 @@
|
||||
<?php
|
||||
class milestoneModel extends model
|
||||
{
|
||||
public function getPageNav($programID, $projectID, $productID)
|
||||
{
|
||||
$milestones = $this->loadModel('programplan')->getMilestones($programID);
|
||||
if(empty($milestones)) return false;
|
||||
$current = zget($milestones, $projectID) ? zget($milestones, $projectID) : current($milestones);
|
||||
$currentProjectID = $projectID ? $projectID : key($milestones);
|
||||
$program = $this->loadModel('project')->getByID($programID);
|
||||
|
||||
$selectHtml = '';
|
||||
if($program->category == 'multiple')
|
||||
{
|
||||
$products = $this->loadModel('product')->getPairs($programID);
|
||||
$currentProductID = $productID ? $productID : $this->product->getProductIDByProject($projectID);
|
||||
if(!$currentProductID) $currentProductID = key($products);
|
||||
$productName = $this->dao->findByID($currentProductID)->from(TABLE_PRODUCT)->fetch('name');
|
||||
$pinYin = common::convert2Pinyin($products);
|
||||
|
||||
$selectHtml .= "<div class='btn-group angle-btn'>";
|
||||
$selectHtml .= "<a data-toggle='dropdown' class='btn' title=$productName>" . $productName . " <span class='caret'></span></a>";
|
||||
$selectHtml .= '<div id="dropMenu" class="dropdown-menu search-list load-indicator" data-ride="searchList">';
|
||||
$selectHtml .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
|
||||
$selectHtml .= '<div class="list-group"><div class="table-row"><div class="table-col col-left"><div class="list-group">';
|
||||
foreach($products as $id => $name)
|
||||
{
|
||||
$selectHtml .= html::a(helper::createLink('milestone', 'index', "program={$programID}&project=0&productID=$id"), "<i class='icon icon-folder-outline'></i> " . $name, '', "title='{$name}' data-key='" . zget($pinYin, $name, '') . "'");
|
||||
}
|
||||
$selectHtml .='</div></div></div></div></div></div>';
|
||||
|
||||
$milestones = $this->loadModel('programplan')->getMilestoneByProduct($currentProductID);
|
||||
$current = zget($milestones, $projectID) ? zget($milestones, $projectID) : current($milestones);
|
||||
$currentProjectID = $projectID ? $projectID : key($milestones);
|
||||
if(!$current) $current = $this->lang->noData;
|
||||
}
|
||||
|
||||
$pinYin = common::convert2Pinyin($milestones);
|
||||
|
||||
$selectHtml .= "<div class='btn-group angle-btn'>";
|
||||
$selectHtml .= "<a data-toggle='dropdown' class='btn' title=$current>" . $current . " <span class='caret'></span></a>";
|
||||
$selectHtml .= '<div id="dropMenu" class="dropdown-menu search-list load-indicator" data-ride="searchList">';
|
||||
$selectHtml .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
|
||||
$selectHtml .= '<div class="list-group"><div class="table-row"><div class="table-col col-left"><div class="list-group">';
|
||||
foreach($milestones as $id => $name)
|
||||
{
|
||||
$selectHtml .= html::a(helper::createLink('milestone', 'index', "program={$programID}&project=$id"), "<i class='icon icon-folder-outline'></i> " . $name, '', "title='{$name}' data-key='" . zget($pinYin, $name, '') . "'");
|
||||
}
|
||||
$selectHtml .='</div></div></div></div></div></div>';
|
||||
return array($selectHtml, $currentProjectID);
|
||||
}
|
||||
|
||||
public function getBasicInfo($programID, $projectID)
|
||||
{
|
||||
$program = $this->loadModel('project')->getByID($programID);
|
||||
$project = $this->loadModel('project')->getByID($projectID);
|
||||
/* Get startedWeeks and finishedWeeks.*/
|
||||
$project->startedWeeks = $project->realStarted == '0000-00-00' ? 0 : ceil((strtotime(helper::today()) - strtotime($project->realStarted )) / 3600 / 24 / 7);
|
||||
$project->finishedWeeks = $project->realFinished == '0000-00-00' ? 0 : ceil((strtotime(helper::today()) - strtotime($project->realFinished)) / 3600 / 24 / 7);
|
||||
$project->offset = $project->realFinished == '0000-00-00' ? 0 : helper::diffDate($project->end, $project->realFinished);
|
||||
|
||||
$basicInfo = new stdclass();
|
||||
$basicInfo->program = $program;
|
||||
$basicInfo->project = $project;
|
||||
return $basicInfo;
|
||||
}
|
||||
|
||||
public function getProcess($programID, $projectID)
|
||||
{
|
||||
$process = new stdclass();
|
||||
$program = $this->loadModel('project')->getByID($programID);
|
||||
$project = $this->loadModel('project')->getByID($projectID);
|
||||
$productID = $this->loadModel('product')->getProductIDByProject($projectID);
|
||||
$projectIdList = $this->loadModel('programplan')->getProjectsByProduct($productID);
|
||||
$projectBegin = $project->begin;
|
||||
$projectEnd = $project->end;
|
||||
$programBegin = $program->begin;
|
||||
$today = helper::today();
|
||||
|
||||
$process->milestonePV = $this->getPV($projectID, $projectBegin, $projectEnd);
|
||||
$process->nowPV = $this->getPV($projectIdList, $programBegin, $projectEnd);
|
||||
|
||||
$process->milestoneEV = $this->getEV($projectID, $projectBegin, $projectEnd);
|
||||
$process->nowEV = $this->getEV($projectIdList, $programBegin, $projectEnd);
|
||||
|
||||
$process->milestoneAC = $this->getAC($projectID, $projectBegin, $projectEnd);
|
||||
$process->nowAC = $this->getAC($projectIdList, $projectBegin, $projectEnd);
|
||||
|
||||
$process->milestoneSPI = $process->milestonePV == 0 ? 0 : round($process->milestoneEV / $process->milestonePV, 2);
|
||||
$process->nowSPI = $process->nowPV == 0 ? 0 : round($process->nowEV / $process->nowPV, 2);
|
||||
|
||||
$process->milestoneCPI = $process->milestoneAC == 0 ? 0 : round($process->milestoneEV / $process->milestoneAC, 2);
|
||||
$process->nowCPI = $process->nowAC == 0 ? 0 : round($process->nowEV / $process->nowAC, 2);
|
||||
|
||||
$process->milestoneSV = $process->milestonePV == 0 ? 0 : round(($process->milestoneEV - $process->milestonePV) / $process->milestonePV, 2) * 100;
|
||||
$process->nowSV = $process->nowPV == 0 ? 0 : round(($process->nowEV - $process->nowPV) / $process->nowPV, 2) * 100;
|
||||
|
||||
$process->milestoneCV = $process->milestoneAC == 0 ? 0 : round(($process->milestoneEV - $process->milestoneAC) / $process->milestoneAC, 2) * 100;
|
||||
$process->nowCV = $process->nowAC == 0 ? 0 : round(($process->nowEV - $process->nowAC) / $process->nowAC, 2) * 100;
|
||||
|
||||
$process->spiMin = '';
|
||||
$process->spiMax = '';
|
||||
$process->svMin = '';
|
||||
$process->svMax = '';
|
||||
$process->cpiMin = '';
|
||||
$process->cpiMax = '';
|
||||
$process->cvMin = '';
|
||||
$process->cvMax = '';
|
||||
$process->cvMax = '';
|
||||
$process->cvMax = '';
|
||||
$process->cvMax = '';
|
||||
$process->nowSpiTip = '';
|
||||
$process->nowCpiTip = '';
|
||||
$process->milestoneSpiTip = '';
|
||||
$process->milestoneCpiTip = '';
|
||||
$spiTip = isset($this->config->custom->SPI) ? json_decode($this->config->custom->SPI->progressTip) : new stdclass();
|
||||
$svTip = isset($this->config->custom->SV) ? json_decode($this->config->custom->SV->progressTip) : new stdclass();
|
||||
$cpiTip = isset($this->config->custom->CPI) ? json_decode($this->config->custom->CPI->costTip) : new stdclass();
|
||||
$cvTip = isset($this->config->custom->CV) ? json_decode($this->config->custom->CV->costTip) : new stdclass();
|
||||
|
||||
foreach($spiTip as $tip)
|
||||
{
|
||||
if($tip->min <= $process->milestoneSPI and $process->milestoneSPI < $tip->max) $process->milestoneSpiTip = $tip->tip;
|
||||
if($tip->min <= $process->nowSPI and $process->nowSPI < $tip->max) $process->nowSpiTip = $tip->tip;
|
||||
if($tip->range)
|
||||
{
|
||||
$process->spiMin = $tip->min;
|
||||
$process->spiMax = $tip->max;
|
||||
}
|
||||
}
|
||||
|
||||
foreach($svTip as $tip)
|
||||
{
|
||||
if($tip->range)
|
||||
{
|
||||
$process->svMin = $tip->min;
|
||||
$process->svMax = $tip->max;
|
||||
}
|
||||
}
|
||||
|
||||
foreach($cpiTip as $tip)
|
||||
{
|
||||
if($tip->min <= $process->milestoneCPI and $process->milestoneCPI < $tip->max) $process->milestoneCpiTip = $tip->tip;
|
||||
if($tip->min <= $process->nowCPI and $process->nowCPI < $tip->max) $process->nowCpiTip = $tip->tip;
|
||||
if($tip->range)
|
||||
{
|
||||
$process->cpiMin = $tip->min;
|
||||
$process->cpiMax = $tip->max;
|
||||
}
|
||||
}
|
||||
|
||||
foreach($cvTip as $tip)
|
||||
{
|
||||
if($tip->range)
|
||||
{
|
||||
$process->cvMin = $tip->min;
|
||||
$process->cvMax = $tip->max;
|
||||
}
|
||||
}
|
||||
|
||||
return $process;
|
||||
}
|
||||
|
||||
public function getCharts($programID, $projectID)
|
||||
{
|
||||
$this->loadModel('weekly');
|
||||
$charts = array();
|
||||
$program = $this->loadModel('project')->getByID($programID);
|
||||
$project = $this->loadModel('project')->getByID($projectID);
|
||||
$productID = $this->loadModel('product')->getProductIDByProject($projectID);
|
||||
$projectIdList = $this->loadModel('programplan')->getProjectsByProduct($productID);
|
||||
$today = helper::today();
|
||||
$begin = $program->begin;
|
||||
$projectEnd = $project->end;
|
||||
$end = $today > $projectEnd ? $projectEnd : $today;
|
||||
|
||||
$charts['PV'] = '[';
|
||||
$charts['EV'] = '[';
|
||||
$charts['AC'] = '[';
|
||||
$i = 1;
|
||||
$start = $begin;
|
||||
while($start < $end)
|
||||
{
|
||||
$charts['labels'][] = $this->lang->milestone->chart->time . $i . $this->lang->milestone->chart->week;
|
||||
$sunday = $this->weekly->getThisSunday($start);
|
||||
$charts['PV'] .= $this->getPV($projectIdList, $begin, $sunday) . ',';
|
||||
$charts['EV'] .= $this->getEV($projectIdList, $begin, $sunday) . ',';
|
||||
$charts['AC'] .= $this->getAC($projectIdList, $begin, $sunday) . ',';
|
||||
$start = date('Y-m-d', strtotime("$start + 7 days"));
|
||||
$i ++;
|
||||
}
|
||||
|
||||
$charts['labels'][] = $this->lang->milestone->chart->time . $i . $this->lang->milestone->chart->week;
|
||||
$charts['PV'] .= $this->getPV($projectIdList, $begin, $end) . ']';
|
||||
$charts['EV'] .= $this->getEV($projectIdList, $begin, $end) . ']';
|
||||
$charts['AC'] .= $this->getAC($projectIdList, $begin, $end) . ']';
|
||||
|
||||
return $charts;
|
||||
}
|
||||
|
||||
public function getPV($projectID, $begin, $end)
|
||||
{
|
||||
$tasks = $this->dao->select('*')->from(TABLE_TASK)
|
||||
->where('project')->in($projectID)
|
||||
->andWhere('estStarted')->ge($begin)
|
||||
->andWhere("(estStarted < '$end' or estStarted='0000-00-00')")
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetchAll('id');
|
||||
|
||||
$PV = 0;
|
||||
foreach($tasks as $task)
|
||||
{
|
||||
if($task->estStarted == '0000-00-00') $task->estStarted = date('Y-m-d', strtotime($task->openedDate));
|
||||
if($task->deadline < $end)
|
||||
{
|
||||
$PV += $task->estimate;
|
||||
continue;
|
||||
}
|
||||
|
||||
$fullDays = $this->loadModel('holiday')->getActualWorkingDays($task->estStarted, $task->deadline);
|
||||
$passedDays = $this->loadModel('holiday')->getActualWorkingDays($task->estStarted, $end);
|
||||
|
||||
$PV += round(count($passedDays) * $task->estimate / count($fullDays), 2);
|
||||
}
|
||||
|
||||
return $PV;
|
||||
}
|
||||
|
||||
public function getEV($projectID, $begin, $end)
|
||||
{
|
||||
$tasks = $this->dao->select('*')->from(TABLE_TASK)
|
||||
->where('estStarted')->ge($begin)
|
||||
->andWhere('estStarted')->lt($end)
|
||||
->andWhere('consumed')->gt(0)
|
||||
->andWhere('status')->ne('cancel')
|
||||
->andWhere('project')->in($projectID)
|
||||
->fetchAll('id');
|
||||
|
||||
$EV = 0;
|
||||
foreach($tasks as $task)
|
||||
{
|
||||
if($task->status == 'done' or $task->closedReason == 'done')
|
||||
{
|
||||
$EV += $task->estimate;
|
||||
}
|
||||
else
|
||||
{
|
||||
$task->progress = round($task->consumed / ($task->consumed + $task->left), 2) * 100;
|
||||
$EV += round($task->estimate * $task->progress / 100, 2);
|
||||
}
|
||||
}
|
||||
return $EV;
|
||||
}
|
||||
|
||||
public function getAC($projectID, $begin, $end)
|
||||
{
|
||||
$consumed = $this->dao->select('sum(t1.consumed) as consumed')
|
||||
->from(TABLE_TASKESTIMATE)->alias('t1')
|
||||
->leftJoin(TABLE_TASK)->alias('t2')->on('t1.task=t2.id')
|
||||
->where('t1.date')->ge($begin)
|
||||
->andWhere('t1.date')->lt($end)
|
||||
->andWhere('t2.project')->in($projectID)
|
||||
->fetch('consumed');
|
||||
if(!$consumed) $consumed = 0;
|
||||
|
||||
return round($consumed, 2);
|
||||
}
|
||||
|
||||
public function getProductQuality($programID, $projectID)
|
||||
{
|
||||
$productID = $this->loadModel('product')->getProductIDByProject($projectID);
|
||||
$stages = $this->loadModel('programplan')->getPairs($programID, $productID);
|
||||
$reviews = $this->loadModel('review')->getPairs($programID, $productID);
|
||||
unset($stages[0]);
|
||||
foreach($reviews as $reviewID => $review)
|
||||
{
|
||||
foreach($stages as $stageID => $stageName)
|
||||
{
|
||||
$productQuality['stages'][$stageID]['total'] = 0;
|
||||
$bugs = $this->dao->select("count(*) as bugs")->from(TABLE_BUG)
|
||||
->where('project')->eq($stageID)
|
||||
->andWhere('identify')->eq($reviewID)
|
||||
->andWhere('resolution')->notin('bydesign,duplicate,notrepro,willnotfix')
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetch('bugs');
|
||||
|
||||
$issues = $this->dao->select("count(*) as issues")->from(TABLE_REVIEWISSUE)
|
||||
->where('injection')->eq($stageID)
|
||||
->andWhere('review')->eq($reviewID)
|
||||
->andWhere('resolution')->notin('bydesign,duplicate,notrepro,willnotfix')
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetch('issues');
|
||||
|
||||
$productQuality['stages'][$stageID]['name'] = $stageName;
|
||||
$productQuality['stages'][$stageID][$reviewID]['counts'] = ($bugs + $issues) == 0 ? '' : (int)($bugs + $issues);
|
||||
//$productQuality['stages'][$stageID]['estimate'] = $this->dao->select('estimate')->from(TABLE_PROJECT)->where('id')->eq($stageID)->fetch('estimate');
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($productQuality['stages']))
|
||||
foreach($productQuality['stages'] as $stageID => $stages)
|
||||
{
|
||||
$total = 0;
|
||||
foreach($stages as $reviewID => $stage) $total += (int) zget($stage, 'counts', 0);
|
||||
$productQuality['stages'][$stageID]['total'] = $total;
|
||||
}
|
||||
|
||||
$productQuality['reviews'] = $reviews;
|
||||
return $productQuality;
|
||||
}
|
||||
|
||||
public function getWorkhours($programID, $projectID)
|
||||
{
|
||||
$productID = $this->loadModel('product')->getProductIDByProject($projectID);
|
||||
$stages = $this->loadModel('programplan')->getPairs($programID, $productID);
|
||||
unset($stages[0]);
|
||||
$dev = 0;
|
||||
$to = 0;
|
||||
$review = 0;
|
||||
$qa = 0;
|
||||
foreach($stages as $stageID => $stageName)
|
||||
{
|
||||
$workhours[$stageID]['name'] = $stageName;
|
||||
$workhours[$stageID]['dev'] = $this->getWorkhourByType($stageID, 'devel');
|
||||
$workhours[$stageID]['to'] = $this->getTo($stageID);
|
||||
$workhours[$stageID]['review'] = $this->getReviewHours($stageID, $projectID);
|
||||
$workhours[$stageID]['qa'] = $this->getWorkhourByType($stageID, 'test');;
|
||||
$workhours[$stageID]['count'] = $workhours[$stageID]['dev'] + $workhours[$stageID]['to'] + $workhours[$stageID]['review'] + $workhours[$stageID]['qa'];
|
||||
$workhours[$stageID]['qaToDev'] = ($workhours[$stageID]['dev'] + $workhours[$stageID]['to']) == 0 ? 0 : round($workhours[$stageID]['qa'] / ($workhours[$stageID]['dev'] + $workhours[$stageID]['to']), 2);
|
||||
|
||||
$dev += $workhours[$stageID]['dev'];
|
||||
$to += $workhours[$stageID]['to'];
|
||||
$review += $workhours[$stageID]['review'];
|
||||
$qa += $workhours[$stageID]['qa'];
|
||||
}
|
||||
|
||||
$workhours['count']['dev'] = $dev;
|
||||
$workhours['count']['to'] = $to;
|
||||
$workhours['count']['review'] = $review;
|
||||
$workhours['count']['qa'] = $qa;
|
||||
$workhours['count']['total'] = $dev + $to + $review + $qa;
|
||||
|
||||
return $workhours;
|
||||
}
|
||||
|
||||
public function getWorkhourByType($stageID, $type)
|
||||
{
|
||||
$consumed = $this->dao->select('sum(consumed) as consumed')->from(TABLE_TASK)->where('project')->eq($stageID)->andWhere('type')->eq($type)->fetch('consumed');
|
||||
return round($consumed, 2);
|
||||
}
|
||||
|
||||
public function getReviewHours($stageID, $projectID = 0)
|
||||
{
|
||||
$productID = $this->loadModel('product')->getProductIDByProject($projectID);
|
||||
$stage = $this->loadModel('programplan')->getByID($stageID);
|
||||
$consumed = 0;
|
||||
$consumed += $this->getWorkhourByType($stageID, 'review');
|
||||
$attribute = isset($this->config->milestone->{$stage->attribute}) ? $this->config->milestone->{$stage->attribute} : '';
|
||||
|
||||
$reviewConsumed = $this->dao->select('sum(t1.consumed) as consumed')->from(TABLE_REVIEWRESULT)->alias('t1')
|
||||
->leftJoin(TABLE_REVIEW)->alias('t2')->on('t1.review=t2.id')
|
||||
->leftJoin(TABLE_OBJECT)->alias('t3')->on('t2.object=t3.id')
|
||||
->where('t3.category')->in($attribute)
|
||||
->andWhere('t3.product')->eq($productID)
|
||||
->fetch('consumed');
|
||||
|
||||
$consumed += $reviewConsumed;
|
||||
return round($consumed, 2);
|
||||
}
|
||||
|
||||
public function getTo($stageID)
|
||||
{
|
||||
$tasks = $this->dao->select('id, activatedDate')->from(TABLE_TASK)->where('project')->eq($stageID)->andWhere('activatedDate')->ne('0000-00-00')->fetchPairs();
|
||||
$to = 0;
|
||||
foreach($tasks as $taskID => $activatedDate)
|
||||
{
|
||||
$consumed = $this->dao->select('sum(consumed) as consumed')->from(TABLE_TASKESTIMATE)
|
||||
->where('task')->eq($taskID)
|
||||
->andWhere('date')->ge($activatedDate)
|
||||
->fetch('consumed');
|
||||
$to += $consumed;
|
||||
}
|
||||
|
||||
return round($to, 2);
|
||||
}
|
||||
|
||||
public function getProjectRisk($programID)
|
||||
{
|
||||
return $this->dao->select('*,riskindex * 1 as riskindex')->from(TABLE_RISK)
|
||||
->where('status')->eq('active')
|
||||
->andWhere('program')->eq($programID)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->orderBy('riskindex_desc')
|
||||
->limit(5)
|
||||
->fetchAll();
|
||||
}
|
||||
|
||||
public function getStageDemand($programID, $projectID, $productID, $stageList = array())
|
||||
{
|
||||
$productList = array();
|
||||
foreach($stageList as $stageID => $name) $productList[$stageID] = $productID;
|
||||
$stages = $this->loadModel('programplan')->getPlans($programID, $productID);
|
||||
|
||||
$originStory = array();
|
||||
$afterStory = array();
|
||||
$changeStory = array();
|
||||
|
||||
foreach($stages as $id => $stage)
|
||||
{
|
||||
$productID = $productList[$id];
|
||||
if($productID === 0) continue;
|
||||
|
||||
$originStory[$id] = $this->dao->select('count(id) as total')->from(TABLE_STORY)
|
||||
->where('product')->eq($productID)
|
||||
->andWhere('type')->eq('requirement')
|
||||
->andWhere('openedDate')->between($stage->begin, $stage->end)
|
||||
->fetch('total');
|
||||
|
||||
$afterStory[$id] = $this->dao->select('count(id) as total')->from(TABLE_STORY)
|
||||
->where('product')->eq($productID)
|
||||
->andWhere('type')->eq('requirement')
|
||||
->andWhere('openedDate')->between($stage->begin, $stage->end)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetch('total');
|
||||
|
||||
$sql = 'select count(id) as total from ' . TABLE_STORY;
|
||||
$sql .= ' where (product = ' . $productID . ' and type = "requirement" and openedDate between "' . $stage->begin . '" and "' . $stage->end . '" and deleted = "1")';
|
||||
$sql .= ' or (product = ' . $productID . ' and type = "requirement" and openedDate between "' . $stage->begin . '" and "' . $stage->end . '" and version > 1)';
|
||||
$changeStory[$id] = $this->dao->query($sql)->fetch();
|
||||
|
||||
foreach($stage->children as $stage)
|
||||
{
|
||||
$id = $stage->id;
|
||||
$productID = $productList[$id];
|
||||
if($productID === 0) continue;
|
||||
|
||||
$originStory[$id] = $this->dao->select('count(id) as total')->from(TABLE_STORY)
|
||||
->where('product')->eq($productID)
|
||||
->andWhere('type')->eq('requirement')
|
||||
->andWhere('openedDate')->between($stage->begin, $stage->end)
|
||||
->fetch('total');
|
||||
|
||||
$afterStory[$id] = $this->dao->select('count(id) as total')->from(TABLE_STORY)
|
||||
->where('product')->eq($productID)
|
||||
->andWhere('type')->eq('requirement')
|
||||
->andWhere('openedDate')->between($stage->begin, $stage->end)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetch('total');
|
||||
|
||||
$sql = 'select count(id) as total from ' . TABLE_STORY;
|
||||
$sql .= ' where (product = ' . $productID . ' and type = "requirement" and openedDate between "' . $stage->begin . '" and "' . $stage->end . '" and deleted = "1")';
|
||||
$sql .= ' or (product = ' . $productID . ' and type = "requirement" and openedDate between "' . $stage->begin . '" and "' . $stage->end . '" and version > 1)';
|
||||
$changeStory[$id] = $this->dao->query($sql)->fetch();
|
||||
}
|
||||
}
|
||||
|
||||
$stageInfo = array('origin' => array(), 'after' => array(), 'change' => array());
|
||||
$beginID = 0;
|
||||
|
||||
foreach($stageList as $key => $stage)
|
||||
{
|
||||
$beginID === 0 ? $stageInfo['origin'][$key] = $originStory[$key] : $stageInfo['origin'][$key] = $afterStory[$beginID];
|
||||
$stageInfo['after'][$key] = $afterStory[$key];
|
||||
$stageInfo['change'][$key] = $changeStory[$key]->total;
|
||||
$beginID = $key;
|
||||
}
|
||||
|
||||
return $stageInfo;
|
||||
}
|
||||
|
||||
public function getMeasures($programID, $projectID)
|
||||
{
|
||||
if(empty($projectID)) return array();
|
||||
return $this->dao->select('id,contents')->from(TABLE_SOLUTIONS)
|
||||
->where('program')->eq($programID)
|
||||
->andWhere('project')->eq($projectID)
|
||||
->andWhere('type')->eq('measures')
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetchPairs('id', 'contents');
|
||||
}
|
||||
|
||||
public function ajaxAddMeasures($data)
|
||||
{
|
||||
$this->dao->update(TABLE_SOLUTIONS)
|
||||
->set('deleted')->eq(1)
|
||||
->where('program')->eq($data->programID)
|
||||
->andWhere('project')->eq($data->projectID)
|
||||
->andWhere('type')->eq('measures')
|
||||
->exec();
|
||||
|
||||
foreach($data->measures as $item)
|
||||
{
|
||||
$item = trim($item);
|
||||
if(empty($item)) continue;
|
||||
|
||||
$addData = new stdClass();
|
||||
$addData->program = $data->programID;
|
||||
$addData->project = $data->projectID;
|
||||
$addData->contents = $item;
|
||||
$addData->type = 'measures';
|
||||
$addData->addedBy = $this->app->user->account;
|
||||
$addData->addedDate = helper::now();
|
||||
$addData->deleted = 0;
|
||||
|
||||
$this->dao->insert(TABLE_SOLUTIONS)->data($addData)->autoCheck()->exec();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function saveOtherProblem()
|
||||
{
|
||||
$data = fixer::input('post')->get();
|
||||
|
||||
$this->dao->update(TABLE_SOLUTIONS)
|
||||
->set('deleted')->eq(1)
|
||||
->where('program')->eq($data->programID)
|
||||
->andWhere('project')->eq($data->projectID)
|
||||
->andWhere('type')->eq('otherproblem')
|
||||
->exec();
|
||||
|
||||
foreach($data->contents as $key => $contents){
|
||||
$addData = new stdClass();
|
||||
$addData->program = $data->programID;
|
||||
$addData->project = $data->projectID;
|
||||
$addData->contents = $contents;
|
||||
$addData->support = $data->support[$key];
|
||||
$addData->measures = $data->measures[$key];
|
||||
$addData->type = 'otherproblem';
|
||||
$addData->addedBy = $this->app->user->account;
|
||||
$addData->addedDate = helper::now();
|
||||
$addData->deleted = 0;
|
||||
|
||||
$this->dao->insert(TABLE_SOLUTIONS)->data($addData)->autoCheck()->exec();
|
||||
}
|
||||
}
|
||||
|
||||
public function otherProblemsList($programID,$projectID)
|
||||
{
|
||||
$list = $this->dao->select('*')
|
||||
->from(TABLE_SOLUTIONS)
|
||||
->where('program')->eq($programID)
|
||||
->andWhere('project')->eq($projectID)
|
||||
->andWhere('type')->eq('otherproblem')
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetchAll();
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
public function getNextMilestone($programID, $projectID, $stageList)
|
||||
{
|
||||
$nextID = $this->dao->select('min(id) as id')->from(TABLE_PROJECT)
|
||||
->where('id')->gt($projectID)
|
||||
->andWhere('program')->eq($programID)
|
||||
->andWhere('milestone')->eq(1)
|
||||
->fetch('id');
|
||||
|
||||
$stageID = array_keys($stageList);
|
||||
$nextID = in_array($nextID, $stageID) ? $nextID : 0;
|
||||
|
||||
$totalDays = $this->dao->select('sum(days) as days')->from(TABLE_PROJECT)
|
||||
->where('id')->in($stageID)
|
||||
->andWhere('program')->eq($programID)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetch('days');
|
||||
|
||||
$totalHours = $this->dao->select('sum(days * hours) as totalHours')->from(TABLE_TEAM)
|
||||
->where('root')->in($stageID)
|
||||
->fetch('totalHours');
|
||||
|
||||
$nextHours = 0;
|
||||
$nextDays = 0;
|
||||
if($nextID)
|
||||
{
|
||||
$nextDays = $this->dao->select('days')->from(TABLE_PROJECT)
|
||||
->where('id')->eq($nextID)
|
||||
->andWhere('program')->eq($programID)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetch('days');
|
||||
|
||||
$nextHours = $this->dao->select('sum(days * hours) as totalHours')->from(TABLE_TEAM)
|
||||
->where('root')->eq($nextID)
|
||||
->fetch('totalHours');
|
||||
}
|
||||
|
||||
$result = new stdClass();
|
||||
$result->nextDays = empty($nextDays) ? 0 : $nextDays;
|
||||
$result->nextHours = empty($nextHours) ? 0 : $nextHours;
|
||||
$result->totalDays = empty($totalDays) ? 0 : $totalDays;
|
||||
$result->totalHours = empty($totalHours) ? 0 : $totalHours;
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function ajaxSaveEstimate($taskID,$estimate)
|
||||
{
|
||||
$this->dao->update(TABLE_PROJECT)
|
||||
->set('estimate')
|
||||
->eq($estimate)
|
||||
->where('id')->eq($taskID)
|
||||
->exec();
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
echo js::error(dao::getError());
|
||||
}
|
||||
}
|
||||
}
|
||||
27
module/milestone/view/basicinfo.html.php
Normal file
27
module/milestone/view/basicinfo.html.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<table class="table table-bordered basicInfo">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowspan='3'><strong><?php echo $lang->milestone->common;?></strong></td>
|
||||
<th><?php echo $lang->program->name;?></th>
|
||||
<td colspan='3'><?php echo $basicInfo->program->name;?></td>
|
||||
<th><?php echo $lang->program->end;?></th>
|
||||
<td><?php echo $basicInfo->project->end;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->PM;?></th>
|
||||
<td><?php echo zget($users, $basicInfo->program->PM);?></td>
|
||||
<th><?php echo $lang->milestone->name;?></th>
|
||||
<td><?php echo $basicInfo->project->name;?></td>
|
||||
<th><?php echo $lang->program->realFinished;?></th>
|
||||
<td><?php echo $basicInfo->project->realFinished;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->milestone->startedWeeks;?></th>
|
||||
<td><?php echo $basicInfo->project->startedWeeks;?></td>
|
||||
<th><?php echo $lang->milestone->finishedWeeks;?></th>
|
||||
<td><?php echo $basicInfo->project->finishedWeeks;?></td>
|
||||
<th><?php echo $lang->milestone->offset;?></th>
|
||||
<td><?php echo $basicInfo->project->offset;?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
71
module/milestone/view/chart.html.php
Normal file
71
module/milestone/view/chart.html.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
<script>
|
||||
function initChar()
|
||||
{
|
||||
var themePrimaryColor = $.getThemeColor('primary');
|
||||
var data =
|
||||
{
|
||||
labels: <?php echo json_encode($charts['labels'])?>,
|
||||
datasets: [
|
||||
{
|
||||
label: "PV",
|
||||
color: themePrimaryColor,
|
||||
pointColor: themePrimaryColor,
|
||||
pointStrokeColor: themePrimaryColor,
|
||||
pointHighlightStroke: themePrimaryColor,
|
||||
fillColor: 'rgba(0,106,241, .07)',
|
||||
pointHighlightFill: '#fff',
|
||||
data: <?php echo $charts['PV']?>
|
||||
},
|
||||
{
|
||||
label: "EV",
|
||||
color: 'rgb(0, 218, 136)',
|
||||
pointColor: 'rgb(0, 218, 136)',
|
||||
pointStrokeColor: 'rgb(0, 218, 136)',
|
||||
pointHighlightStroke: 'rgb(0, 218, 136)',
|
||||
fillColor: 'rgb(0, 218, 136, .07)',
|
||||
pointHighlightFill: '#fff',
|
||||
data: <?php echo $charts['EV']?>
|
||||
},
|
||||
{
|
||||
label: "AC",
|
||||
color: 'rgb(255, 145, 0)',
|
||||
pointColor: 'rgb(255, 145, 0)',
|
||||
pointStrokeColor: 'rgb(255, 145, 0)',
|
||||
pointHighlightStroke: 'rgb(255, 145, 0)',
|
||||
fillColor: 'rgb(255, 145, 0, .07)',
|
||||
pointHighlightFill: '#fff',
|
||||
data: <?php echo $charts['AC']?>
|
||||
}]
|
||||
};
|
||||
|
||||
var chartLine= $("#chart-line").lineChart(data,
|
||||
{
|
||||
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 %>",
|
||||
});
|
||||
}
|
||||
initChar();
|
||||
</script>
|
||||
49
module/milestone/view/condition.html.php
Normal file
49
module/milestone/view/condition.html.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<div class='panel-body scroll-table' style='padding: 0;'>
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<?php count($stageList) === 0 ? $totalStoryTd = 4 : $totalStoryTd = 3;?>
|
||||
<th colspan="<?php echo $totalStoryTd + count($stageList);?>"><?php echo $lang->milestone->demandStatus;?></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th rowspan="2"><?php echo $lang->milestone->storyUnit;?></th>
|
||||
<th colspan="<?php echo count($stageList);?>" class="text-center"><?php echo $lang->milestone->engineeringStage;?></th>
|
||||
<th rowspan="2" colspan="2"><?php echo $lang->milestone->rateChange;?></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<?php foreach($stageList as $stage):?>
|
||||
<th><?php echo $stage;?></th>
|
||||
<?php endforeach;?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong><?php echo $lang->milestone->originalStory;?></strong></td>
|
||||
<?php if(count($stageList) === 0) echo '<td rowspan="3"></td>';?>
|
||||
<?php foreach($stageList as $key => $stage):?>
|
||||
<td><?php echo $stageInfo['origin'][$key];?></td>
|
||||
<?php endforeach;?>
|
||||
<td colspan="2" rowspan="3">
|
||||
<?php
|
||||
$rateNumber = '0%';
|
||||
if(count($stageInfo['after']) && current($stageInfo['after']))
|
||||
$rateNumber = round((array_sum($stageInfo['change'])/current($stageInfo['origin'])) * 100, 2).'%';
|
||||
echo $rateNumber;
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><?php echo $lang->milestone->modifyNumber;?></strong></td<>
|
||||
<?php foreach($stageList as $key => $stage):?>
|
||||
<td><?php echo $stageInfo['after'][$key];?></td>
|
||||
<?php endforeach;?>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><?php echo $lang->milestone->changeStory;?></strong></td>
|
||||
<?php foreach($stageList as $key => $stage):?>
|
||||
<td><?php echo $stageInfo['change'][$key];?></td>
|
||||
<?php endforeach;?>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
66
module/milestone/view/index.html.php
Normal file
66
module/milestone/view/index.html.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<style>
|
||||
table .btn.addItem, table .btn.delItem{padding: 3px 8px; font-size: 12px; line-height: 18px; border-radius: 4px;}
|
||||
.measures-input{width: 80%; float: left; margin-right: 5px;}
|
||||
.main-table tbody>tr>td:first-child{padding-left: 8px;}
|
||||
.angle-btn+.angle-btn{ border-left: 1px solid #0c64eb;}
|
||||
</style>
|
||||
<?php if($projectID):?>
|
||||
<div id="mainContent" class="main-row fade in">
|
||||
<div class="main-col">
|
||||
<div class="main-table">
|
||||
<?php include 'basicinfo.html.php';?>
|
||||
<?php include 'process.html.php';?>
|
||||
<?php include 'chart.html.php';?>
|
||||
<?php include 'productquality.html.php';?>
|
||||
<?php include 'workhour.html.php';?>
|
||||
<?php include 'progress.html.php';?>
|
||||
<?php include 'rectifying.html.php';?>
|
||||
<?php include 'condition.html.php';?>
|
||||
<?php include 'projectrisk.html.php';?>
|
||||
<?php include 'otherproblem.html.php';?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php js::set('measuresUrl', $this->createLink('milestone', 'ajaxAddMeasures'));?>
|
||||
<script>
|
||||
function addItem(add)
|
||||
{
|
||||
var rowspan = $("#measuresTd").attr("rowspan");
|
||||
$("#measuresTd").attr("rowspan", Number(rowspan) + 1);
|
||||
$(add).parent().parent().after('<tr>' + $("#measuresDiv").html() + '</tr>');
|
||||
submitMeasurse();
|
||||
}
|
||||
|
||||
function delItem(del)
|
||||
{
|
||||
if($(del).attr('id')) return false;
|
||||
var rowspan = $("#measuresTd").attr("rowspan");
|
||||
if(rowspan == '1') return false;
|
||||
$("#measuresTd").attr("rowspan", Number(rowspan) - 1);
|
||||
$(del).parent().parent().remove();
|
||||
submitMeasurse();
|
||||
}
|
||||
|
||||
function submitMeasurse()
|
||||
{
|
||||
$.ajax(
|
||||
{
|
||||
type: "post",
|
||||
url: measuresUrl,
|
||||
data: $("#ajaxFormMeasures").serialize(),
|
||||
success: function(data)
|
||||
{
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<?php else:?>
|
||||
<div class='main-col'>
|
||||
<div class="table-empty-tip">
|
||||
<p><?php echo $lang->noData;?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
73
module/milestone/view/otherproblem.html.php
Normal file
73
module/milestone/view/otherproblem.html.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<form target="hiddenwin" method="post" action="<?php echo $this->createLink('milestone','saveOtherProblem');?>">
|
||||
<table class="table table-bordered" id="otherproblems">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan='5'><?php echo $lang->milestone->otherproblem;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowspan='<?php echo 2 + count($otherproblems);?>' id='problemTd'><?php echo $lang->milestone->problemandsuggest;?></td>
|
||||
<td><?php echo $lang->milestone->prodescr;?></td>
|
||||
<td><?php echo $lang->milestone->needhelp;?></td>
|
||||
<td><?php echo $lang->milestone->suggest;?></td>
|
||||
<td><?php echo $lang->milestone->options;?></td>
|
||||
</tr>
|
||||
<?php if(empty($otherproblems)): ?>
|
||||
<tr>
|
||||
<td><input type="text" value="" name="contents[]" class="form-control"/></td>
|
||||
<td><input type="text" value="" name="support[]" class="form-control"/></td>
|
||||
<td><input type="text" value="" name="measures[]" class="form-control"/></td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-link btn-icon btn-add" onclick="addItems($(this))">
|
||||
<i class="icon icon-plus"></i></button>
|
||||
<button type="button" class="btn btn-link btn-icon btn-delete" onclick="deleteItems($(this))">
|
||||
<i class="icon icon-close"></i></button>
|
||||
<?php echo html::submitButton('', '', 'btn btn-primary');?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<?php foreach($otherproblems as $value):?>
|
||||
<tr>
|
||||
<td><input type="text" value="<?php echo $value->contents;?>" name="contents[]" class="form-control"/></td>
|
||||
<td><input type="text" value="<?php echo $value->support;?>" name="support[]" class="form-control"/></td>
|
||||
<td><input type="text" value="<?php echo $value->measures;?>" name="measures[]" class="form-control"/></td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-link btn-icon btn-add" onclick="addItems($(this))">
|
||||
<i class="icon icon-plus"></i></button>
|
||||
<button type="button" class="btn btn-link btn-icon btn-delete" onclick="deleteItems($(this))">
|
||||
<i class="icon icon-close"></i></button>
|
||||
<?php echo html::submitButton('', '', 'btn btn-primary');?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php echo html::hidden('programID', $programID);?>
|
||||
<?php echo html::hidden('projectID', $projectID);?>
|
||||
</form>
|
||||
<?php js::set('save', $lang->milestone->save);?>
|
||||
<script>
|
||||
function addItems(obj)
|
||||
{
|
||||
var items = '<tr>\
|
||||
<td><input type="text" value="" name="contents[]" class="form-control"/></td>\
|
||||
<td><input type="text" value="" name="support[]" class="form-control"/></td>\
|
||||
<td><input type="text" value="" name="measures[]" class="form-control"/></td>\
|
||||
<td>\
|
||||
<button type="button" class="btn btn-link btn-icon btn-add" onclick="addItems($(this))">\
|
||||
<i class="icon icon-plus"></i></button>\
|
||||
<button type="button" class="btn btn-link btn-icon btn-delete" onclick="deleteItems($(this))">\
|
||||
<i class="icon icon-close"></i></button>\
|
||||
<button type="submit" id="submit" class="btn btn-primary">' + save +'</button>\
|
||||
</td></tr>';
|
||||
obj.parent('td').parent('tr').after(items);
|
||||
$('#problemTd').attr('rowspan', $('#problemTd').attr('rowspan') + 1)
|
||||
}
|
||||
|
||||
function deleteItems(obj)
|
||||
{
|
||||
var len = $('#otherproblems tbody tr').length;
|
||||
if(len > 2) obj.parent('td').parent('tr').remove();
|
||||
}
|
||||
</script>
|
||||
74
module/milestone/view/process.html.php
Normal file
74
module/milestone/view/process.html.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<table class="table table-bordered basicInfo">
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowspan='2'><?php echo $lang->milestone->processCommon;?></th>
|
||||
<th rowspan='2'><?php echo $lang->milestone->stage;?></th>
|
||||
<th rowspan='2'><?php echo $lang->milestone->toNow;?></th>
|
||||
<th colspan='2' class='text-center'><?php echo $lang->milestone->targetRange;?></th>
|
||||
<th rowspan='2' class='text-center'><?php echo $lang->milestone->analysis;?></th>
|
||||
<th rowspan='2' class='text-center'><?php echo $lang->milestone->stage;?></th>
|
||||
<th rowspan='2' class='text-center'><?php echo $lang->milestone->toNow;?></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='text-center'><?php echo $lang->milestone->ge;?></th>
|
||||
<th class='text-center'><?php echo $lang->milestone->le;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><?php echo $lang->milestone->PV;?></td>
|
||||
<td><?php echo $process->milestonePV;?></td>
|
||||
<td><?php echo $process->nowPV;?></td>
|
||||
<td class='text-center'>-</td>
|
||||
<td class='text-center'>-</td>
|
||||
<td rowspan='3' class='text-center'><?php echo $lang->milestone->process;?></td>
|
||||
<td rowspan='3'><?php echo $process->milestoneSpiTip;?></td>
|
||||
<td rowspan='3'><?php echo $process->nowSpiTip;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo $lang->milestone->EV;?></td>
|
||||
<td><?php echo $process->milestoneEV;?></td>
|
||||
<td><?php echo $process->nowEV;?></td>
|
||||
<td class='text-center'>-</td>
|
||||
<td class='text-center'>-</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo $lang->milestone->AC;?></td>
|
||||
<td><?php echo $process->milestoneAC;?></td>
|
||||
<td><?php echo $process->nowAC;?></td>
|
||||
<td class='text-center'>-</td>
|
||||
<td class='text-center'>-</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo $lang->milestone->SPI;?></td>
|
||||
<td><?php echo $process->milestoneSPI;?></td>
|
||||
<td><?php echo $process->nowSPI;?></td>
|
||||
<td class='text-center'><?php echo $process->spiMin;?></td>
|
||||
<td class='text-center'><?php echo $process->spiMax;?></td>
|
||||
<td rowspan='4' class='text-center'><?php echo $lang->milestone->projectCost;?></td>
|
||||
<td rowspan='4'><?php echo $process->milestoneCpiTip;?></td>
|
||||
<td rowspan='4'><?php echo $process->nowCpiTip;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo $lang->milestone->CPI;?></td>
|
||||
<td><?php echo $process->milestoneCPI;?></td>
|
||||
<td><?php echo $process->nowCPI;?></td>
|
||||
<td class='text-center'><?php echo $process->cpiMin;?></td>
|
||||
<td class='text-center'><?php echo $process->cpiMax;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo $lang->milestone->SV;?></td>
|
||||
<td><?php echo $process->milestoneSV . '%';?></td>
|
||||
<td><?php echo $process->nowSV . '%';?></td>
|
||||
<td class='text-center'><?php echo $process->svMin . '%';?></td>
|
||||
<td class='text-center'><?php echo $process->svMax . '%';?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo $lang->milestone->CV;?></td>
|
||||
<td><?php echo $process->milestoneCV . '%';?></td>
|
||||
<td><?php echo $process->nowCV . '%';?></td>
|
||||
<td class='text-center'><?php echo $process->cvMin . '%';?></td>
|
||||
<td class='text-center'><?php echo $process->cvMax . '%';?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
53
module/milestone/view/productquality.html.php
Normal file
53
module/milestone/view/productquality.html.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<div class='panel-body scroll-table' style='padding: 0;'>
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowspan='2'><?php echo $lang->milestone->quality->identify;?></th>
|
||||
<th class='text-center' colspan='<?php if(isset($productQuality['stages'])) echo count($productQuality['stages']);?>'>
|
||||
<?php echo $lang->milestone->quality->injection;?></th>
|
||||
<th rowspan='2'><?php echo $lang->milestone->quality->scale;?></th>
|
||||
<th rowspan='2'><?php echo $lang->milestone->quality->identifyRate;?></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<?php if(isset($productQuality['stages'])):?>
|
||||
<?php foreach($productQuality['stages'] as $stages):?>
|
||||
<th><?php echo $stages['name'];?></th>
|
||||
<?php endforeach;?>
|
||||
<?php endif;?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($productQuality['reviews'] as $reviewID => $reviewName):?>
|
||||
<tr>
|
||||
<td><?php echo $reviewName;?></td>
|
||||
<?php foreach($productQuality['stages'] as $stages):?>
|
||||
<td><?php echo $stages[$reviewID]['counts'];?></td>
|
||||
<?php endforeach;?>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
<tr>
|
||||
<th><?php echo $lang->milestone->quality->total;?></th>
|
||||
<?php if(isset($productQuality['stages'])):?>
|
||||
<?php foreach($productQuality['stages'] as $stages):?>
|
||||
<td><?php echo $stages['total'];?></td>
|
||||
<?php endforeach;?>
|
||||
<?php endif;?>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->milestone->quality->injectionRate;?>
|
||||
</th>
|
||||
<?php if(isset($productQuality['stages'])):?>
|
||||
<?php foreach($productQuality['stages'] as $stages):?>
|
||||
<td></td>
|
||||
<?php endforeach;?>
|
||||
<?php endif;?>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
76
module/milestone/view/progress.html.php
Normal file
76
module/milestone/view/progress.html.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowspan="2"><?php echo $lang->milestone->paogressForecast;?></th>
|
||||
<th colspan="3" class="text-center"><?php echo $lang->milestone->duration;?></th>
|
||||
<th colspan="3" class="text-center"><?php echo $lang->milestone->cost;?></th>
|
||||
<th colspan="3" rowspan="2"><?php echo $lang->milestone->forecastResults;?></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->milestone->plannedValue;?></th>
|
||||
<th><?php echo $lang->milestone->predictedValue;?>
|
||||
<i class="icon icon-help" title="<?php echo $lang->milestone->predictedValueDesc;?>"></i>
|
||||
</th>
|
||||
<th><?php echo $lang->milestone->periodDeviation;?></th>
|
||||
<th><?php echo $lang->milestone->plannedValue;?></th>
|
||||
<th><?php echo $lang->milestone->predictedValue;?></th>
|
||||
<th><?php echo $lang->milestone->costDeviation;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong><?php echo $lang->milestone->nextStage;?></strong></td>
|
||||
<td><?php echo $nextMilestone->nextDays;?></td>
|
||||
<td>
|
||||
<?php
|
||||
$nextDuration = empty($process->milestoneSPI) || empty($nextMilestone->nextDays) ? 0 : round($nextMilestone->nextDays/$process->milestoneSPI, 2);
|
||||
echo $nextDuration;
|
||||
$nextDurationValue = $nextMilestone->nextDays - $nextDuration;
|
||||
?>
|
||||
</td>
|
||||
<td><?php echo $nextDurationValue;?></td>
|
||||
<td><?php echo $nextMilestone->nextHours;?></td>
|
||||
<td>
|
||||
<?php
|
||||
$nextCost = empty($process->nowCPI) || empty($nextMilestone->nextHours) ? 0 : round($nextMilestone->nextHours/$process->milestoneCPI);
|
||||
echo $nextCost;
|
||||
$nextCostValue = $nextMilestone->nextHours - $nextCost;
|
||||
?>
|
||||
</td>
|
||||
<td><?php echo $nextCostValue;?></td>
|
||||
<td colspan="3">
|
||||
<?php
|
||||
if($nextDurationValue < 0) echo sprintf($lang->milestone->timeOverrun, abs($nextDurationValue));
|
||||
if($nextCostValue < 0) echo sprintf($lang->milestone->costOverrun, abs($nextCostValue));
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><?php echo $lang->milestone->overallProject;?></strong></td>
|
||||
<td><?php echo $nextMilestone->totalDays;?></td>
|
||||
<td>
|
||||
<?php
|
||||
$totalDuration = empty($process->milestoneSPI) || empty($nextMilestone->totalDays) ? 0 : round($nextMilestone->totalDays/$process->milestoneSPI, 2);
|
||||
echo $totalDuration;
|
||||
$totalDurationValue = $nextMilestone->totalDays - $totalDuration;
|
||||
?>
|
||||
</td>
|
||||
<td><?php echo $totalDurationValue;?></td>
|
||||
<td><?php echo $nextMilestone->totalHours;?></td>
|
||||
<td>
|
||||
<?php
|
||||
$totalCost = empty($process->nowCPI) || empty($nextMilestone->totalHours) ? 0 : round($nextMilestone->totalHours/$process->nowCPI, 2);
|
||||
echo $totalCost;
|
||||
$totalCostValue = $nextMilestone->totalHours - $totalCost;
|
||||
?>
|
||||
</td>
|
||||
<td><?php echo $totalCostValue;?></td>
|
||||
<td colspan="3">
|
||||
<?php
|
||||
if($totalDurationValue < 0) echo sprintf($lang->milestone->timeOverrun, abs($totalDurationValue));
|
||||
if($totalCostValue < 0) echo sprintf($lang->milestone->costOverrun, abs($totalCostValue));
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
29
module/milestone/view/projectrisk.html.php
Normal file
29
module/milestone/view/projectrisk.html.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr><th colspan="6"><?php echo $lang->milestone->projectRisk;?></th></tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->milestone->riskCountermove;?></th>
|
||||
<th><?php echo $lang->milestone->riskDescriptio;?></th>
|
||||
<th><?php echo $lang->milestone->riskPossibility;?></th>
|
||||
<th><?php echo $lang->milestone->riskSeriousness;?></th>
|
||||
<th><?php echo $lang->milestone->riskFactor;?></th>
|
||||
<th><?php echo $lang->milestone->riskMeasures;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $totalRisk = count($projectRisk);?>
|
||||
<?php foreach($projectRisk as $risk):?>
|
||||
<tr>
|
||||
<?php if($totalRisk):?>
|
||||
<td rowspan="<?php echo $totalRisk;?>"><strong><?php echo $lang->milestone->riskAccumulate;?></strong></td>
|
||||
<?php endif;?>
|
||||
<td><?php echo $risk->name;?></td>
|
||||
<td><?php echo $risk->impact;?></td>
|
||||
<td><?php echo $risk->probability;?></td>
|
||||
<td><?php echo $risk->riskindex;?></td>
|
||||
<td><?php echo $risk->prevention;?></td>
|
||||
</tr>
|
||||
<?php $totalRisk = 0;?>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
42
module/milestone/view/rectifying.html.php
Normal file
42
module/milestone/view/rectifying.html.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<form method="post" id="ajaxFormMeasures">
|
||||
<table class="table table-bordered">
|
||||
<tbody>
|
||||
<?php if(count($measures)):?>
|
||||
<?php $totalMeasures = count($measures);?>
|
||||
<?php $delOrigin = 'id="delOrigin"';?>
|
||||
<?php foreach($measures as $item):?>
|
||||
<tr>
|
||||
<?php if($totalMeasures):?>
|
||||
<td rowspan="<?php echo $totalMeasures;?>" class="text-center" id="measuresTd"><strong><?php echo $lang->milestone->corrective;?></strong></td>
|
||||
<?php endif;?>
|
||||
<td colspan="6">
|
||||
<?php echo html::input('measures[]', $item, 'class="form-control measures-input" onchange="submitMeasurse()";');?>
|
||||
<?php echo html::a('javascript:;', '<i class="icon icon-plus"></i>', '', 'class="btn btn-link addItem" onclick="addItem(this)"');?>
|
||||
<?php echo html::a('javascript:;', '<i class="icon icon-close"></i>', '', 'class="btn btn-link delItem" onclick="delItem(this)"' . $delOrigin);?>
|
||||
<?php $totalMeasures = 0;?>
|
||||
<?php $delOrigin = '';?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
<?php else:?>
|
||||
<tr>
|
||||
<td rowspan="1" class="text-center" id="measuresTd"><strong><?php echo $lang->milestone->corrective;?></strong></td>
|
||||
<td colspan="6">
|
||||
<?php echo html::input('measures[]', '', 'class="form-control measures-input" onchange="submitMeasurse()";');?>
|
||||
<?php echo html::a('javascript:;', '<i class="icon icon-plus"></i>', '', 'class="btn btn-link addItem" onclick="addItem(this)"');?>
|
||||
<?php echo html::a('javascript:;', '<i class="icon icon-close"></i>', '', 'class="btn btn-link delItem" onclick="delItem(this)" id="delOrigin"');?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr class="hidden" id="measuresDiv">
|
||||
<td colspan="6">
|
||||
<?php echo html::input('measures[]', '', 'class="form-control measures-input" onchange="submitMeasurse()"');?>
|
||||
<?php echo html::a('javascript:;', '<i class="icon icon-plus"></i>', '', 'class="btn btn-link addItem" onclick="addItem(this)"');?>
|
||||
<?php echo html::a('javascript:;', '<i class="icon icon-close"></i>', '', 'class="btn btn-link delItem" onclick="delItem(this)"');?>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<?php echo html::hidden('programID', $programID);?>
|
||||
<?php echo html::hidden('projectID', $projectID);?>
|
||||
</table>
|
||||
</form>
|
||||
102
module/milestone/view/workhour.html.php
Normal file
102
module/milestone/view/workhour.html.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<div class='panel-body scroll-table' style='padding: 0;'>
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowspan='2'><?php echo $lang->milestone->workHours;?></th>
|
||||
<th class='text-center' colspan='<?php echo count($workhours) - 1;?>'><?php echo $lang->milestone->allStage;?></th>
|
||||
<th rowspan='2' class='text-center'><?php echo $lang->milestone->colSummary;?></th>
|
||||
<th rowspan='2' class='text-center'><?php echo $lang->milestone->colPercent;?></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<?php foreach($workhours as $id => $stage):?>
|
||||
<?php if($id == 'count') continue;?>
|
||||
<th><?php echo $stage['name'];?></th>
|
||||
<?php endforeach;?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><?php echo $lang->milestone->devHours;?></th>
|
||||
<?php foreach($workhours as $id => $stage):?>
|
||||
<?php if($id == 'count') continue;?>
|
||||
<td><?php echo $stage['dev'];?></td>
|
||||
<?php endforeach;?>
|
||||
<td class='text-center'><?php echo $workhours['count']['dev'];?></td>
|
||||
<td class='text-center'><?php echo $workhours['count']['total'] == '0' ? '0%' : round($stage['dev'] / $workhours['count']['total'], 2) * 100 . '%';?> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->milestone->toHours;?></th>
|
||||
<?php foreach($workhours as $id => $stage):?>
|
||||
<?php if($id == 'count') continue;?>
|
||||
<td><?php echo $stage['to'];?></td>
|
||||
<?php endforeach;?>
|
||||
<td class='text-center'><?php echo $workhours['count']['to'];?></td>
|
||||
<td class='text-center'><?php echo $workhours['count']['total'] == '0' ? '0%' : round($stage['to'] / $workhours['count']['total'], 2) * 100 . '%';?> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->milestone->reviewHours;?></th>
|
||||
<?php foreach($workhours as $id => $stage):?>
|
||||
<?php if($id == 'count') continue;?>
|
||||
<td><?php echo $stage['review'];?></td>
|
||||
<?php endforeach;?>
|
||||
<td class='text-center'><?php echo $workhours['count']['review'];?></td>
|
||||
<td class='text-center'><?php echo $workhours['count']['total'] == '0' ? '0%' : round($stage['review'] / $workhours['count']['total'], 2) * 100 . '%';?> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->milestone->qaHours;?></th>
|
||||
<?php foreach($workhours as $id => $stage):?>
|
||||
<?php if($id == 'count') continue;?>
|
||||
<td><?php echo $stage['qa'];?></td>
|
||||
<?php endforeach;?>
|
||||
<td class='text-center'><?php echo $workhours['count']['qa'];?></td>
|
||||
<td class='text-center'><?php echo $workhours['count']['total'] == '0' ? '0%' : round($stage['qa'] / $workhours['count']['total'], 2) * 100 . '%';?> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->milestone->rowSummary;?></th>
|
||||
<?php foreach($workhours as $id => $stage):?>
|
||||
<?php if($id == 'count') continue;?>
|
||||
<td><?php echo $stage['count'];?></td>
|
||||
<?php endforeach;?>
|
||||
<td class='text-center'><?php echo $workhours['count']['total'];?></td>
|
||||
<td class='text-center'><?php echo $workhours['count']['total'] == '0' ? '0%' : round($stage['total'] / $workhours['count']['total'], 2) * 100 . '%';?> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->milestone->rowPercent;?></th>
|
||||
<?php foreach($workhours as $id => $stage):?>
|
||||
<?php if($id == 'count') continue;?>
|
||||
<td><?php echo $workhours['count']['total'] == 0 ? '0%' : round($stage['count'] / $workhours['count']['total'] * 100, 2) . '%';?></td>
|
||||
<?php endforeach;?>
|
||||
<td class='text-center'>100%</td>
|
||||
<td class='text-center'>100%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->milestone->qatoDev;?></th>
|
||||
<?php foreach($workhours as $id => $stage):?>
|
||||
<?php if($id == 'count') continue;?>
|
||||
<td><?php echo $stage['qaToDev'];?></td>
|
||||
<?php endforeach;?>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class='cell chart-row'>
|
||||
<div class='main-col'>
|
||||
<div class='chart-wrapper text-center'>
|
||||
<h4><?php echo $lang->milestone->chart->workhour;?></h4>
|
||||
<div class='chart-canvas'><canvas id='chart-workhour' width='400' height='140' data-responsive='true'></canvas></div>
|
||||
</div>
|
||||
</div>
|
||||
<table class='table table-chart hidden' data-chart='bar' data-target='#chart-workhour' data-animation='false'>
|
||||
<tbody>
|
||||
<?php foreach($workhours as $id => $stage):?>
|
||||
<?php if($id == 'count') continue;?>
|
||||
<tr>
|
||||
<td class='chart-label text-left'><?php echo $stage['name'];?></td>
|
||||
<td class='chart-value text-right'><?php echo $workhours['count']['total'] == 0 ? '0%' : round($stage['count'] / $workhours['count']['total'] * 100, 2) . '%';?></td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -11,7 +11,7 @@ $lang->risk->close = '关闭';
|
||||
$lang->risk->cancel = '取消';
|
||||
$lang->risk->track = '跟踪';
|
||||
$lang->risk->assignTo = '指派';
|
||||
$lang->risk->deleted = '删除';
|
||||
$lang->risk->delete = '删除';
|
||||
$lang->risk->byQuery = '搜索';
|
||||
|
||||
/* Fields */
|
||||
|
||||
@@ -195,6 +195,25 @@ class riskModel extends model
|
||||
return $this->dao->select('*')->from(TABLE_RISK)->where('id')->eq((int)$riskID)->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get block risks
|
||||
*
|
||||
* @param string $browseType
|
||||
* @param int $limit
|
||||
* @param string $orderBy
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getBlockRisks($browseType = 'all', $limit = 15, $orderBy = 'id_desc')
|
||||
{
|
||||
return $this->dao->select('*')->from(TABLE_RISK)
|
||||
->where('program')->eq($this->session->program)
|
||||
->andWhere('deleted')->eq('0')
|
||||
->orderBy($orderBy)
|
||||
->limit($limit)
|
||||
->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print assignedTo html
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user