This commit is contained in:
holan20180123
2020-08-27 13:48:23 +08:00
108 changed files with 1453 additions and 1878 deletions
+2
View File
@@ -293,3 +293,5 @@ INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('
ALTER TABLE `zt_block` ADD `type` char(30) NOT NULL AFTER `module`;
ALTER TABLE `zt_block` ADD UNIQUE `account_module_type_order` (`account`, `module`, `type`, `order`), DROP INDEX `accountModuleOrder`;
INSERT INTO `zt_cron` (`m`, `h`, `dom`, `mon`, `dow`, `command`, `remark`, `type`, `buildin`, `status`, `lastTime`) VALUES ('1', '0', '*', '*', '*', 'moduleName=weekly&methodName=computeWeekly', '更新项目周报', 'system', 0, 'normal', '2020-08-27 10:07:53');
+2 -1
View File
@@ -1462,7 +1462,8 @@ INSERT INTO `zt_cron` (`m`, `h`, `dom`, `mon`, `dow`, `command`, `remark`, `type
('1', '1', '*', '*', '*', 'moduleName=todo&methodName=createCycle', '生成周期性待办', 'zentao', 1, 'normal', '0000-00-00 00:00:00'),
('1', '0', '*', '*', '*', 'moduleName=ci&methodName=initQueue', '创建周期性任务', 'zentao', 1, 'normal', '0000-00-00 00:00:00'),
('*/5', '*', '*', '*', '*', 'moduleName=ci&methodName=checkCompileStatus', '同步Jenkins任务状态', 'zentao', 1, 'normal', '0000-00-00 00:00:00'),
('*/5', '*', '*', '*', '*', 'moduleName=ci&methodName=exec', '执行Jenkins任务', 'zentao', 1, 'normal', '0000-00-00 00:00:00');
('*/5', '*', '*', '*', '*', 'moduleName=ci&methodName=exec', '执行Jenkins任务', 'zentao', 1, 'normal', '0000-00-00 00:00:00'),
('1', '0', '*', '*', '*', 'moduleName=weekly&methodName=computeWeekly', '更新项目周报', 'system', 0, 'normal', '2020-08-27 10:07:53');
INSERT INTO `zt_group` (`id`, `name`, `role`, `desc`) VALUES
(1, 'ADMIN', 'admin', 'for administrator'),
+26 -18
View File
@@ -1190,29 +1190,26 @@ class block extends control
{
$this->loadModel('milestone');
$this->loadModel('weekly');
$program = $this->loadModel('project')->getByID($this->session->program);
$programID = $this->session->program;
$program = $this->loadModel('project')->getByID($programID);
$begin = $program->begin;
$today = helper::today();
$end = date('Y-m-d', strtotime($today));
$projects = $this->project->getProjectsByProgram($program);
$projectIdList = array_keys($projects);
$charts['PV'] = '[';
$charts['EV'] = '[';
$charts['AC'] = '[';
$i = 1;
$start = $begin;
$longProgram = helper::diffDate($today, $begin) / 7 > 10;
while($start < $end)
$longProgram = helper::diffDate($today, $begin) / 7 > 12;
while($begin < $end)
{
$charts['labels'][] = $longProgram ? $this->lang->milestone->chart->time . $i . $this->lang->milestone->chart->month : $this->lang->milestone->chart->time . $i . $this->lang->milestone->chart->week;
$stageEnd = $longProgram ? date('Y-m-t', strtotime($start)) : $this->weekly->getThisSunday($start);
$charts['PV'] .= $this->milestone->getPV($projectIdList, $begin, $stageEnd) . ',';
$charts['EV'] .= $this->milestone->getEV($projectIdList, $begin, $stageEnd) . ',';
$charts['AC'] .= $this->milestone->getAC($projectIdList, $begin, $stageEnd) . ',';
$start = date('Y-m-d', strtotime("$stageEnd + 1 day"));
$charts['labels'][] = $longProgram ? $this->lang->block->time . $i . $this->lang->block->month : $this->lang->block->time . $i . $this->lang->block->week;
$charts['PV'] .= $this->weekly->getPV($programID, $begin) . ',';
$charts['EV'] .= $this->weekly->getEV($programID, $begin) . ',';
$charts['AC'] .= $this->weekly->getAC($programID, $begin) . ',';
$stageEnd = $longProgram ? date('Y-m-t', strtotime($begin)) : $this->weekly->getThisSunday($begin);
$begin = date('Y-m-d', strtotime("$stageEnd + 1 day"));
$i ++;
}
@@ -1296,11 +1293,22 @@ class block extends control
*/
public function printScrumdynamicBlock()
{
/* Load pager. */
$this->app->loadClass('pager', $static = true);
$pager = new pager(0, 30, 1);
$projects = $this->loadModel('project')->getPairs();
$products = $this->loadModel('product')->getPairs();
$this->view->actions = $this->loadModel('action')->getDynamic('all', 'today', 'date_desc', $pager);
$actions = array();
if(!empty($projects) || !empty($products))
{
$actions = $this->dao->select('*')->from(TABLE_ACTION)
->beginIF($projects && $products)->where('project')->in(array_keys($projects))->orWhere('product')->in(array_keys($products))->fi()
->beginIF($projects && empty($products))->where('project')->in(array_keys($projects))->fi()
->beginIF(empty($projects) && $products)->where('product')->in(array_keys($products))->fi()
->orderBy('id_desc')
->limit(30)
->fetchAll();
}
$this->view->actions = empty($actions) ? array() : $this->loadModel('action')->transformActions($actions);
$this->view->users = $this->loadModel('user')->getPairs('noletter');
}
@@ -1652,7 +1660,7 @@ class block extends control
$num = isset($this->params->num) ? (int)$this->params->num : 15;
/* Get projects. */
$this->view->programs = $this->loadModel('program')->getUserPrograms('all', 'id_desc', $num);
$this->view->programs = $this->loadModel('program')->getUserPrograms('doing', 'id_desc', $num);
}
/**
+3
View File
@@ -59,6 +59,9 @@ $lang->block->doingProject = 'Doning ' . $lang->projectCommon;
$lang->block->finishProject = 'Finish ' . $lang->projectCommon;
$lang->block->estimatedHours = 'Estimated Hours';
$lang->block->consumedHours = 'Consumed Hours';
$lang->block->time = 'No';
$lang->block->week = 'Week';
$lang->block->month = 'Month';
$lang->block->params = new stdclass();
$lang->block->params->name = 'Name';
+5 -2
View File
@@ -59,6 +59,9 @@ $lang->block->doingProject = '进行中的' . $lang->projectCommon;
$lang->block->finishProject = '累积' . $lang->projectCommon;
$lang->block->estimatedHours = '预计工时';
$lang->block->consumedHours = '已消耗';
$lang->block->time = '第';
$lang->block->week = '周';
$lang->block->month = '月';
$lang->block->params = new stdclass();
$lang->block->params->name = '参数名称';
@@ -119,9 +122,9 @@ $lang->block->default['cmmi']['program']['5']['params']['num'] = '15';
$lang->block->default['cmmi']['program']['5']['params']['orderBy'] = 'id_desc';
$lang->block->default['cmmi']['program']['6']['title'] = '最新动态';
$lang->block->default['cmmi']['program']['6']['block'] = 'dynamic';
$lang->block->default['cmmi']['program']['6']['block'] = 'scrumdynamic';
$lang->block->default['cmmi']['program']['6']['grid'] = 4;
$lang->block->default['cmmi']['program']['6']['source'] = '';
$lang->block->default['cmmi']['program']['6']['source'] = 'program';
$lang->block->default['cmmi']['program']['7']['title'] = '项目风险';
$lang->block->default['cmmi']['program']['7']['block'] = 'cmmirisk';
@@ -1,6 +1,8 @@
<div class="panel-body">
<div id='cmmiGantt'>
<?php if(count($products) >= 2): ?>
<?php echo html::select('cmmiGanttProductID', $products, $productID, "class='form-control chosen'"); ?>
<?php endif;?>
<?php if(empty($plans['data'])): ?>
<div class='empty-tip'><?php echo $lang->programplan->noData;?></div>
<?php else:?>
+115 -1
View File
@@ -3,5 +3,119 @@
.block-cmmiprogress .milestone-chart {box-shadow: none}
.block-cmmiprogress .milestone-chart.has-scrollbar {margin-bottom: -10px}
</style>
<?php include '../../milestone/view/chart.html.php';?>
<div class='milestone-chart' id='milestoneChart'>
<div class='chart-canvas scrollbar-hover'>
<div class='chart-wrapper'>
<canvas width='400' height='120' data-responsive='true'></canvas>
</div>
</div>
<div class='chart-unit'><?php echo "({$lang->project->workHour})";?></div>
<div class='chart-legend'>
<span class="barline line-pv">PV</span>
<span class="barline line-ev">EV</span>
<span class="barline line-ac">AC</span>
</div>
</div>
<style>
.milestone-chart {position: relative}
.milestone-chart .chart-canvas {overflow: auto; max-width: 1002px}
.milestone-chart .chart-wrapper {background: none; padding: 15px 0 0 0}
.milestone-chart .chart-unit {position: absolute; left: 10px; top: 0;}
.milestone-chart .chart-legend {position: absolute; right: 5px; top: 0;}
.milestone-chart .barline {padding-left: 20px; position: relative; display: inline-block; line-height: 20px}
.milestone-chart .barline + .barline {margin-left: 5px}
.milestone-chart .barline:before {content: ' '; display: block; position: absolute; top: 8px; left: 0; width: 16px; height: 3px; background: #0c64eb}
.milestone-chart .barline.line-ev:before {background: rgb(0, 218, 136)}
.milestone-chart .barline.line-ac:before {background: rgb(255, 145, 0)}
</style>
<script>
function initMilestoneChart()
{
var data =
{
labels: <?php echo json_encode($charts['labels'])?>,
datasets: [
{
label: 'PV',
color: '#0c64eb',
pointColor: '#0c64eb',
pointStrokeColor: '#0c64eb',
pointHighlightStroke: '#0c64eb',
fillColor: 'rgba(0,106,241, .07)',
pointHighlightFill: '#fff',
data: <?php echo $charts['PV']?>
},
{
label: 'EV',
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 betterWidth = data.labels.length * 15;
var renderChart = function()
{
var $chart = $('#milestoneChart');
var $wrapper = $chart.find('.chart-wrapper');
var $canvas = $chart.find('canvas');
var $chartCanvas = $chart.find('.chart-canvas');
if (betterWidth > 400)
{
var updateWrapperSize = function()
{
$wrapper.hide();
$chartCanvas.css('max-width', 'initial');
var maxWidth = $chartCanvas.width();
$chartCanvas.css('max-width', maxWidth);
$chart.toggleClass('has-scrollbar', maxWidth < betterWidth);
$wrapper.show();
};
updateWrapperSize();
$(window).on('resize', updateWrapperSize);
$wrapper.css('min-width', betterWidth);
$canvas.attr(
{
width: betterWidth,
height: Math.min(200, Math.floor(betterWidth / 4))
});
}
$canvas.lineChart(data,
{
animation: betterWidth < 400,
pointDotStrokeWidth: 1,
pointDotRadius: 2,
datasetStrokeWidth: 2,
datasetFill: false,
datasetStroke: true,
scaleShowBeyondLine: true,
responsive: true,
bezierCurve: false,
scaleFontColor: '#838A9D',
tooltipXPadding: 10,
tooltipYPadding: 10,
multiTooltipTitleTemplate: '<%= label %> <?php echo $lang->project->workHour;?> /h',
multiTooltipTemplate: '<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>',
});
}
setTimeout(renderChart, betterWidth > 200 ? 100 : 10);
}
initMilestoneChart();
</script>
</div>
@@ -35,7 +35,8 @@
<div class='col' data-id='<?php echo $programID?>'>
<div class='panel' data-url='<?php echo $this->createLink('program', 'index', "programID=$program->id");?>'>
<div class='panel-heading'>
<strong class='program-name' title='<?php echo $program->name;?>'> <?php echo html::a($this->createLink('program', 'index', "programID=$program->id", '', '', $program->id), $program->name);?> </strong>
<?php $parentName = $program->parentName ? $program->parentName . '/' : '';?>
<strong class='program-name' title='<?php echo $parentName . $program->name;?>'> <?php echo html::a($this->createLink('program', 'index', "programID=$program->id", '', '', $program->id), $parentName . $program->name);?> </strong>
<?php if($program->template === 'cmmi'): ?>
<span class='program-type-label label label-warning label-outline'><?php echo $lang->program->cmmi; ?></span>
<?php else: ?>
+7 -7
View File
@@ -29,23 +29,23 @@
<div class="text-left" id="totalInvestment"><strong><?php echo $lang->block->totalInvestment;?></strong></div>
<div class="table-row">
<div class="col-4 tile">
<div class="overview-title"><i class="icon-program-group icon-group"></i><?php echo $lang->block->totalPeople;?></div>
<div class="overview-title"><i class="icon-program-group icon-group"></i> <?php echo $lang->block->totalPeople;?></div>
<div class="tile-amount">
<?php echo $totalData[$programID]->teamCount ? html::a($this->createLink('program', 'manageMembers', 'programID=' . $programID), $totalData[$programID]->teamCount) : 0;?>
</div>
</div>
<div class="col-4 tile">
<div class="overview-title"><i class="icon icon-time"></i><?php echo $lang->block->consumedHours;?></div>
<div class="tile-amount"><a href="/my-task-assignedTo.html"><?php echo $totalData[$programID]->consumed;?></a>
<div class="overview-title"><i class="icon icon-clock"></i> <?php echo $lang->block->consumedHours;?></div>
<div class="tile-amount">
<?php echo $totalData[$programID]->consumed ? html::a($this->createLink('project', 'index', 'locate=no'), $totalData[$programID]->consumed) : 0;?>
</div>
<div class="tile-info">
<span class="extra-tips"><?php echo $lang->block->estimatedHours;?> <?php echo $totalData[$programID]->estimate;?></span>
</div>
</div>
<div class="col-4 tile">
<div class="overview-title"><i class="icon icon-circle"></i><?php echo $lang->block->spent;?></div>
<div class="tile-amount"><a href="/my-task-assignedTo.html">¥0</a>
</div>
<div class="overview-title"><i class="icon icon-cost"></i> <?php echo $lang->block->spent;?></div>
<div class="tile-amount">¥0</div>
<div class="tile-info">
<span class="extra-tips"><?php echo $lang->block->budget;?> ¥<?php echo $totalData[$programID]->budget;?></span>
</div>
@@ -72,7 +72,7 @@
<div class="col-3 total-block">
<div><strong><?php echo $lang->block->totalBug;?></strong></div>
<div class="tile-amount">
<?php echo $totalData[$programID]->allBugs ? html::a($this->createLink('qa', 'index', 'pgm=' . $programID), $totalData[$programID]->allBugs) : 0;?>
<?php echo $totalData[$programID]->allBugs ? html::a($this->createLink('qa', 'index'), $totalData[$programID]->allBugs) : 0;?>
</div>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="<?php echo $totalData[$programID]->doneBugs;?>" aria-valuemin="0" aria-valuemax="<?php echo $totalData[$programID]->allBugs;?>" style="width: <?php echo floor(($totalData[$programID]->doneBugs/$totalData[$programID]->allBugs)*100).'%';?>"></div>
+24 -30
View File
@@ -36,36 +36,30 @@
<?php else:?>
<div class="release-path">
<ul class="release-line">
<?php foreach($roadmaps as $year => $mapBranches):?>
<?php foreach($mapBranches as $plans):?>
<?php foreach($plans as $plan):?>
<?php if(isset($plan->begin)):?>
<li <?php if(date('Y-m-d') < $plan->begin) echo 'class="active"';?>>
<a href="<?php echo $this->createLink('productplan', 'view', "planID={$plan->id}");?>">
<span class="title" title="<?php echo $plan->title;?>"><?php echo $plan->title;?></span>
<?php
$plan->begin = date('Y/m/d', strtotime($plan->begin));
$plan->end = '-' . date('m/d', strtotime($plan->end));
?>
<span class="date" title="<?php echo $plan->begin . $plan->end;?>"><?php echo $plan->begin . $plan->end;?></span>
<span class="date"><?php echo $lang->block->estimatedHours;?> <?php echo $plan->hour;?> h</span>
</a>
</li>
<?php else:?>
<li>
<a href="<?php echo $this->createLink('release', 'view', "releaseID={$plan->id}");?>">
<span class="title" title="<?php echo $plan->name;?>"><?php echo $plan->name . "($plan->buildName)";?></span>
<?php
$plan->date = date('Y/m/d', strtotime($plan->date));
?>
<span class="date" title="<?php echo $plan->date;?>"><?php echo $plan->date;?></span>
<?php $estimate = empty($plan->stories) ? 0 : $this->block->getStorysEstimateHours(explode(',', $plan->stories));?>
<span class="date"><?php echo $lang->block->consumedHours;?> <?php echo empty($estimate) ? 0 : $estimate;?> h</span>
</a>
</li>
<?php endif;?>
<?php endforeach;?>
<?php endforeach;?>
<?php foreach($roadmaps as $plan):?>
<?php if(isset($plan->begin)):?>
<li <?php if(date('Y-m-d') < $plan->begin) echo 'class="active"';?>>
<a href="<?php echo $this->createLink('productplan', 'view', "planID={$plan->id}");?>">
<span class="title" title="<?php echo $plan->title;?>"><?php echo $plan->title;?></span>
<?php
$plan->begin = date('Y/m/d', strtotime($plan->begin));
$plan->end = '-' . date('m/d', strtotime($plan->end));
?>
<span class="date" title="<?php echo $plan->begin . $plan->end;?>"><?php echo $plan->begin . $plan->end;?></span>
<span class="date"><?php echo $lang->block->estimatedHours;?> <?php echo $plan->hour;?> h</span>
</a>
</li>
<?php else:?>
<li>
<a href="<?php echo $this->createLink('release', 'view', "releaseID={$plan->id}");?>">
<span class="title" title="<?php echo $plan->name;?>"><?php echo $plan->name . "($plan->buildName)";?></span>
<?php $plan->date = date('Y/m/d', strtotime($plan->date));?>
<span class="date" title="<?php echo $plan->date;?>"><?php echo $plan->date;?></span>
<?php $estimate = empty($plan->stories) ? 0 : $this->block->getStorysEstimateHours(explode(',', $plan->stories));?>
<span class="date"><?php echo $lang->block->consumedHours;?> <?php echo empty($estimate) ? 0 : $estimate;?> h</span>
</a>
</li>
<?php endif;?>
<?php endforeach;?>
</ul>
</div>
+77 -10
View File
@@ -1,12 +1,40 @@
<?php
/**
* The control file of budget 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 budget
* @version $Id: control.php 5107 2013-07-12 01:46:12Z chencongzhi520@gmail.com $
* @link http://www.zentao.net
*/
class budget extends control
{
/**
* __construct
*
* @param string $module
* @param string $method
* @access public
* @return void
*/
public function __construct($module = '', $method = '')
{
parent::__construct($module, $method);
$this->view->program = $this->loadModel('project')->getByID($this->session->program);
$this->view->program = $this->loadModel('project')->getByID($this->session->program);
}
/**
* The budget browse page.
*
* @param varchar $orderBy
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @access public
* @return void
*/
public function browse($orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
$this->app->loadClass('pager', $static = true);
@@ -23,6 +51,12 @@ class budget extends control
$this->display();
}
/**
* The budget summary page.
*
* @access public
* @return void
*/
public function summary()
{
$getSubjectStructure = $this->budget->getSubjectStructure();
@@ -51,6 +85,12 @@ class budget extends control
$this->display();
}
/**
* Create a budget.
*
* @access public
* @return void
*/
public function create()
{
if($_POST)
@@ -58,7 +98,7 @@ class budget extends control
$budgetID = $this->budget->create();
if(dao::isError())
{
{
$response['result'] = 'fail';
$response['message'] = dao::getError();
$this->send($response);
@@ -79,6 +119,12 @@ class budget extends control
$this->display();
}
/**
* Edit a budget.
*
* @access public
* @return void
*/
public function edit($budgetID)
{
if($_POST)
@@ -86,7 +132,7 @@ class budget extends control
$changes = $this->budget->update($budgetID);
if(dao::isError())
{
{
$response['result'] = 'fail';
$response['message'] = dao::getError();
$this->send($response);
@@ -112,6 +158,13 @@ class budget extends control
$this->display();
}
/**
* View a budget.
*
* @param int $budgetID
* @access public
* @return void
*/
public function view($budgetID)
{
$this->view->stages = $this->budget->getStages();
@@ -123,21 +176,35 @@ class budget extends control
$this->display();
}
/**
* Delete a budget.
*
* @param int $budgetID
* @param varchar $confirm
* @access public
* @return void
*/
public function delete($budgetID = 0, $confirm = 'no')
{
if($confirm == 'no')
{
echo js::confirm($this->lang->budget->confirmDelete, $this->createLink('budget', 'delete', "id=$budgetID&confirm=yes"));
{
echo js::confirm($this->lang->budget->confirmDelete, $this->createLink('budget', 'delete', "id=$budgetID&confirm=yes"));
exit;
}
else
{
}
else
{
$this->budget->delete(TABLE_BUDGET, $budgetID);
die(js::locate(inlink('browse'), 'parent'));
}
}
/**
* Batch create budgets.
*
* @access public
* @return void
*/
public function batchCreate()
{
if($_POST)
@@ -145,7 +212,7 @@ class budget extends control
$this->budget->batchCreate();
if(dao::isError())
{
{
$response['result'] = 'fail';
$response['message'] = dao::getError();
$this->send($response);
+76
View File
@@ -1,6 +1,24 @@
<?php
/**
* The model file of budget 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 budget
* @version $Id: model.php 5079 2013-07-10 00:44:34Z chencongzhi520@gmail.com $
* @link http://www.zentao.net
*/
?>
<?php
class budgetModel extends model
{
/**
* Get subject option.
*
* @access public
* @return object
*/
public function getSubjectOption()
{
$subjects = $this->loadModel('tree')->getOptionMenu(0, $viewType = 'subject', $startModuleID = 0);
@@ -15,6 +33,13 @@ class budgetModel extends model
return $subjects;
}
/**
* Get budget by id.
*
* @param int $budgetID
* @access public
* @return array
*/
public function getByID($budgetID)
{
$budget = $this->dao->select('*')->from(TABLE_BUDGET)->where('id')->eq($budgetID)->fetch();
@@ -23,6 +48,14 @@ class budgetModel extends model
return $budget;
}
/**
* Get budget list.
*
* @param varchar $orderBy
* @param pager $object
* @access public
* @return object
*/
public function getList($orderBy = 'id_desc', $pager = null)
{
return $this->dao->select('*')->from(TABLE_BUDGET)
@@ -33,6 +66,12 @@ class budgetModel extends model
->fetchAll();
}
/**
* Get stages.
*
* @access public
* @return array
*/
public function getStages()
{
return $this->dao->select('stage')->from(TABLE_BUDGET)
@@ -42,6 +81,12 @@ class budgetModel extends model
->fetchPairs();
}
/**
* Get subjects.
*
* @access public
* @return array
*/
public function getSubjects()
{
return $this->dao->select('subject')->from(TABLE_BUDGET)
@@ -51,6 +96,12 @@ class budgetModel extends model
->fetchPairs();
}
/**
* Get subject structure.
*
* @access public
* @return array
*/
public function getSubjectStructure()
{
$subjects = $this->getSubjects();
@@ -72,6 +123,12 @@ class budgetModel extends model
return $structure;
}
/**
* Get summary.
*
* @access public
* @return array
*/
public function getSummary()
{
$budgets = $this->dao->select('*')->from(TABLE_BUDGET)
@@ -102,6 +159,12 @@ class budgetModel extends model
return $summary;
}
/**
* Create a budget.
*
* @access public
* @return int
*/
public function create()
{
$budget = fixer::input('post')
@@ -121,6 +184,12 @@ class budgetModel extends model
return $budgetID;
}
/**
* Batch create budgets.
*
* @access public
* @return bool
*/
public function batchCreate()
{
$today = helper::today();
@@ -161,6 +230,13 @@ class budgetModel extends model
return !dao::isError();
}
/**
* Update a budget.
*
* @param int $budgetID
* @access public
* @return array
*/
public function update($budgetID)
{
$oldBudget = $this->getByID($budgetID);
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The batchCreate view of budget 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 budget
* @version $Id: batchCreate.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';?>
<div id="mainContent" class="main-content fade">
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The browse view of budget 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 budget
* @version $Id: browse.html.php 4903 2013-06-26 05:32:59Z wyd621@gmail.com $
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<style>
.browse-active{color: #0c64eb;font-weight: 700;}
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The create view of budget 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 budget
* @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';?>
<div id="mainContent" class="main-content fade">
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The edit view of budget 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 budget
* @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';?>
<div id="mainContent" class="main-content fade">
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The summary view of budget 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 budget
* @version $Id: summary.html.php 4903 2013-06-26 05:32:59Z wyd621@gmail.com $
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<style>
.summary-active{color: #0c64eb;font-weight: 700;}
+2 -2
View File
@@ -1,11 +1,11 @@
<?php
/**
* The view file of bug module of ZenTaoPMS.
* The view file of budget 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 bug
* @package budget
* @version $Id: view.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $
* @link http://www.zentao.net
*/
+79
View File
@@ -814,3 +814,82 @@ $lang->icons['confirmStoryChange'] = 'search';
$lang->icons['score'] = 'tint';
include (dirname(__FILE__) . '/menuOrder.php');
/* Cmmi menu. */
$lang->menu->cmmi = new stdclass();
$lang->menu->cmmi->programindex = array('link' => '仪表盘|program|index|program={PROGRAM}');
$lang->menu->cmmi->programplan = array('link' => '计划|programplan|browse|program={PROGRAM}', 'subModule' => 'programplan');
$lang->menu->cmmi->project = array('link' => $lang->projectCommon . '|project|task|projectID={PROJECT}', 'subModule' => ',project,task,');
$lang->menu->cmmi->weekly = array('link' => '报告|weekly|index|program={PROGRAM}', 'subModule' => ',milestone,');
$lang->menu->cmmi->doc = array('link' => '文档|doc|index|program={PROGRAM}');
$lang->menu->cmmi->product = array('link' => '需求|product|browse|product={PRODUCT}&branch=&browseType=unclosed&queryID=0&storyType=requirement', 'subModule' => ',story,');
$lang->menu->cmmi->design = '设计|design|browse|product={PRODUCT}';
$lang->menu->cmmi->ci = '代码|repo|browse|';
$lang->menu->cmmi->qa = array('link' => '测试|bug|browse|product={PRODUCT}', 'subModule' => ',testcase,testtask,testsuite,testreport,caselib,');
$lang->menu->cmmi->release = array('link' => '发布|release|browse|product={PRODUCT}', 'subModule' => 'release');
$lang->menu->cmmi->issue = '问题|issue|browse|';
$lang->menu->cmmi->risk = '风险|risk|browse|';
$lang->menu->cmmi->list = array('link' => '更多|workestimation|index|program={PROGRAM}', 'class' => 'dropdown dropdown-hover cmmi-list', 'subModule' => 'stakeholder,workestimation,durationestimation,budget,pssp,stakeholder');
/* Srcum menu. */
$lang->menu->srcum = new stdclass();
$lang->menu->srcum->programindex = array('link' => '仪表盘|program|index|program={PROGRAM}');
$lang->cmmi = new stdclass();
$lang->cmmi->subMenu = new stdclass();
$lang->cmmi->subMenu->list = new stdclass();
$lang->cmmi->subMenu->list->workestimation = array('link' => '估算|workestimation|index|program=%s', 'subModule' => 'durationestimation,budget');
$lang->cmmi->subMenu->list->program = '项目|program|edit|';
$lang->cmmiproduct = new stdclass();
$lang->workestimation = new stdclass();
$lang->budget = new stdclass();
$lang->programplan = new stdclass();
$lang->review = new stdclass();
$lang->weekly = new stdclass();
$lang->milestone = new stdclass();
$lang->design = new stdclass();
$lang->auditplan = new stdclass();
$lang->cm = new stdclass();
$lang->nc = new stdclass();
$lang->pssp = new stdclass();
$lang->issue = new stdclass();
$lang->risk = new stdclass();
$lang->stakeholder = new stdclass();
$lang->durationestimation = new stdclass();
$lang->workestimation->menu = new stdclass();
$lang->budget->menu = new stdclass();
$lang->programplan->menu = new stdclass();
$lang->review->menu = new stdclass();
$lang->weekly->menu = new stdclass();
$lang->milestone->menu = new stdclass();
$lang->cmmiproduct->menu = new stdclass();
$lang->design->menu = new stdclass();
$lang->auditplan->menu = new stdclass();
$lang->cm->menu = new stdclass();
$lang->pssp->menu = new stdclass();
$lang->issue->menu = new stdclass();
$lang->risk->menu = new stdclass();
$lang->stakeholder->menu = new stdclass();
$lang->durationestimation->menu = new stdclass();
$lang->workestimation->menu->index = '工作量估算|workestimation|index|program={PROGRAM}';
$lang->workestimation->menu->duration = array('link' => '工期估算|durationestimation|index|program={PROGRAM}', 'subModule' => 'durationestimation');
$lang->workestimation->menu->budget = array('link' => '费用估算|budget|summary|', 'subModule' => 'budget');
$lang->durationestimation->menu = $lang->workestimation->menu;
$lang->budget->menu = $lang->workestimation->menu;
$lang->programplan->menu->gantt = array('link' => '甘特图|programplan|browse|programID={PROGRAM}&productID={PRODUCT}&type=gantt');
$lang->programplan->menu->lists = array('link' => '阶段列表|programplan|browse|programID={PROGRAM}&productID={PRODUCT}&type=lists', 'alias' => 'create');
$lang->cmmiproduct->menu->plan = array('link' => '排期|productplan|browse|productID={PRODUCT}', 'subModule' => 'productplan');
$lang->cmmiproduct->menu->requirement = '用户需求|product|browse|product={PRODUCT}&branch=&browseType=unclosed&queryID=0&storyType=requirement';
$lang->cmmiproduct->menu->story = '软件需求|product|browse|product={PRODUCT}&branch=&browseType=unclosed&queryID=0&storyType=story';
$lang->cmmiproduct->menu->track = '跟踪矩阵|story|track|product={PRODUCT}';
$lang->nc->menu = $lang->auditplan->menu;
$lang->noMenuModule = array('my', 'todo', 'effort', 'program', 'attend', 'leave', 'makeup', 'overtime', 'lieu', 'holiday', 'custom', 'auditcl', 'subject', 'admin', 'mail', 'extension', 'dev', 'backup', 'action', 'cron', 'issue', 'risk', 'pssp', 'sms', 'message', 'webhook', 'search');
$lang->haveMenuMethod = array('custom');
+4 -4
View File
@@ -354,11 +354,11 @@ class custom extends control
* @return void
*/
public function estimate()
{
{
$this->lang->custom->menu = new stdclass();
$this->lang->navGroup->custom = 'system';
if(strtolower($this->server->request_method) == "post")
{
{
$data = fixer::input('post')->get();
$this->loadModel('setting')->setItem('system.custom.hourPoint', $data->hourPoint);
$this->loadModel('setting')->setItem('system.custom.cost', $data->cost);
@@ -368,11 +368,11 @@ class custom extends control
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('custom', 'estimate')));
}
}
$this->app->loadConfig('project');
$this->view->unit = zget($this->config->custom, 'hourPoint', '1');
$this->view->unit = zget($this->config->custom, 'hourPoint', '1');
$this->view->cost = zget($this->config->custom, 'cost', '');
$this->view->efficiency = zget($this->config->custom, 'efficiency', '');
$this->view->hours = zget($this->config->project, 'defaultWorkhours', '');
+3 -3
View File
@@ -362,7 +362,7 @@ class customModel extends model
}
/**
* Get system swapper.
* Get system swapper.
* @param string $module
* @param string $method
* @access public
@@ -370,8 +370,8 @@ class customModel extends model
*/
public function getSwapper()
{
$current = (isset($_COOKIE['systemModel']) and $_COOKIE['systemModel'] == 'scrum') ? 'scrum' : 'cmmi';
$link = (isset($_COOKIE['systemModel']) and $_COOKIE['systemModel'] == 'scrum') ? html::a(helper::createLink('custom', 'setcmmi'), 'CMMI') : html::a(helper::createLink('custom', 'setscrum'), 'SCRUM');
$current = (isset($_COOKIE['systemModel']) and $_COOKIE['systemModel'] == 'scrum') ? 'Scrum' : 'CMMI';
$link = (isset($_COOKIE['systemModel']) and $_COOKIE['systemModel'] == 'scrum') ? html::a(helper::createLink('custom', 'setcmmi'), 'CMMI') : html::a(helper::createLink('custom', 'setscrum'), 'Scrum');
$output = "<div class='btn-group' id='swapper'><button data-toggle='dropdown' type='button' class='btn btn-limit' title='{$current}'>{$current} <i class='icon icon-swap'></i></button>";
$output .= "<ul class='dropdown-menu'><li>" . $link . "</li></ul>";
+3 -2
View File
@@ -1,8 +1,9 @@
<?php
$config->design = new stdclass();
$config->design->editor = new stdclass();
$config->design->editor->create = array('id' => 'desc', 'tools' => 'simpleTools');
$config->design->editor->edit = array('id' => 'desc', 'tools' => 'simpleTools');
$config->design->editor->create = array('id' => 'desc', 'tools' => 'simpleTools');
$config->design->editor->edit = array('id' => 'desc', 'tools' => 'simpleTools');
$config->design->editor->assignto = array('id' => 'comment', 'tools' => 'simpleTools');
$config->design->affectedFixedNum = 7;
+35 -1
View File
@@ -56,6 +56,7 @@ class design extends control
$this->view->orderBy = $orderBy;
$this->view->productID = $productID;
$this->view->pager = $pager;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->display();
}
@@ -238,7 +239,7 @@ class design extends control
if($_POST)
{
$this->design->linkCommit($designID);
$this->design->linkCommit($designID, $repoID);
$result['result'] = 'success';
$result['message'] = $this->lang->saveSuccess;
@@ -294,4 +295,37 @@ class design extends control
die(js::locate($this->session->designList, 'parent'));
}
}
/**
* Update assign of design.
*
* @param int $designID
* @access public
* @return void
*/
public function assignTo($designID)
{
if($_POST)
{
$changes = $this->design->assign($designID);
if(dao::isError()) die(js::error(dao::getError()));
$this->loadModel('action');
if(!empty($changes))
{
$actionID = $this->action->create('design', $designID, 'Assigned', $this->post->comment, $this->post->assignedTo);
$this->action->logHistory($actionID, $changes);
}
if(isonlybody()) die(js::closeModal('parent.parent', 'this'));
die(js::locate($this->createLink('design', 'browse'), 'parent'));
}
$this->view->title = $this->lang->design->assignedTo;
$this->view->position[] = $this->lang->design->assignedTo;
$this->view->design = $this->design->getById($designID);
$this->view->users = $this->loadModel('user')->getPairs();
$this->display();
}
}
+2
View File
@@ -45,6 +45,8 @@ $lang->design->reviewObject = 'Review Object';
$lang->design->createdBy = 'CreatedBy';
$lang->design->createdDate = 'CreatedDate';
$lang->design->basicInfo = 'Basic Information';
$lang->design->assignTo = 'Assign';
$lang->design->noAssigned = 'Unassigned';
$lang->design->typeList = array();
$lang->design->typeList[''] = '';
+2
View File
@@ -45,6 +45,8 @@ $lang->design->reviewObject = '评审对象';
$lang->design->createdBy = '由谁创建';
$lang->design->createdDate = '创建时间';
$lang->design->basicInfo = '基本信息';
$lang->design->assignTo = '指派';
$lang->design->noAssigned = '未指派';
$lang->design->typeList = array();
$lang->design->typeList[''] = '';
+56 -2
View File
@@ -137,10 +137,11 @@ class designModel extends model
* LinkCommit a design.
*
* @param int $designID
* @param int $repoID
* @access public
* @return void
*/
public function linkCommit($designID)
public function linkCommit($designID, $repoID)
{
$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();
@@ -156,7 +157,7 @@ class designModel extends model
$data->BType = 'commit';
$data->BID = $revision;
$data->relation = 'completedin';
$data->extra = $this->session->repoID;
$data->extra = $repoID;
$this->dao->replace(TABLE_RELATION)->data($data)->autoCheck()->exec();
@@ -347,4 +348,57 @@ class designModel extends model
$this->loadModel('search')->setSearchParams($this->config->design->search);
}
/**
* Print assignedTo html
*
* @param int $design
* @param int $users
* @access public
* @return string
*/
public function printAssignedHtml($design, $users)
{
$btnTextClass = '';
$assignedToText = zget($users, $design->assignedTo);
if(empty($design->assignedTo))
{
$btnTextClass = 'text-primary';
$assignedToText = $this->lang->design->noAssigned;
}
if($design->assignedTo == $this->app->user->account) $btnTextClass = 'text-red';
$btnClass = $design->assignedTo == 'closed' ? ' disabled' : '';
$btnClass = "iframe btn btn-icon-left btn-sm {$btnClass}";
$assignToLink = helper::createLink('design', 'assignTo', "designID=$design->id", '', true);
$assignToHtml = html::a($assignToLink, "<i class='icon icon-hand-right'></i> <span title='" . zget($users, $design->assignedTo) . "' class='{$btnTextClass}'>{$assignedToText}</span>", '', "class='$btnClass'");
echo !common::hasPriv('design', 'assignTo', $design) ? "<span style='padding-left: 21px' class='{$btnTextClass}'>{$assignedToText}</span>" : $assignToHtml;
}
/**
* Assign a design.
*
* @param int $designID
* @access public
* @return array|bool
*/
public function assign($designID)
{
$oldDesign = $this->getByID($designID);
$design = fixer::input('post')
->add('editedBy', $this->app->user->account)
->add('editedDate', helper::today())
->setDefault('assignedDate', helper::today())
->stripTags($this->config->design->editor->assignto['id'], $this->config->allowedTags)
->remove('uid,comment,files,label')
->get();
$this->dao->update(TABLE_DESIGN)->data($design)->autoCheck()->where('id')->eq((int)$designID)->exec();
if(!dao::isError()) return common::createChanges($oldDesign, $design);
return false;
}
}
+40
View File
@@ -0,0 +1,40 @@
<?php
/**
* The assign 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: assign.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';?>
<div id='mainContent' class='main-content'>
<div class='main-header'>
<h2>
<span class='prefix label-id'><strong><?php echo $design->id;?></strong></span>
<?php echo "<span title='$design->name'>" . $design->name . '</span>';?>
</h2>
</div>
<form class='load-indicator main-form' method='post' target='hiddenwin'>
<table class='table table-form'>
<tbody>
<tr>
<th class='w-100px'><?php echo $lang->design->assignedTo;?></th>
<td><?php echo html::select('assignedTo', $users, $design->assignedTo, "class='form-control chosen'");?></td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->comment;?></th>
<td colspan='2'><?php echo html::textarea('comment', '', "rows='6' class='form-control kindeditor' hidefocus='true'");?></td>
</tr>
<tr>
<td class='text-center form-actions' colspan='3'><?php echo html::submitButton(); ?></td> </tr>
</tbody>
</table>
</form>
</div>
<?php include "../../common/view/footer.html.php";?>
+2 -2
View File
@@ -48,7 +48,7 @@
<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="c-assignedTo 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>
@@ -61,7 +61,7 @@
<td style="overflow:hidden"><?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-assignedTo"><?php echo $this->design->printAssignedHtml($design, $users);?></td>
<td class='c-actions text-center'>
<?php
$vars = "design={$design->id}";
+1 -1
View File
@@ -38,7 +38,7 @@
</tr>
</table>
</div>
<form id='logForm' class='main-table form-ajax' data-ride='table' action=<?php echo inlink('commit', "designID=$designID");?> method='post'>
<form id='logForm' class='main-table form-ajax' data-ride='table' action=<?php echo inlink('commit', "designID=$designID&repoID=$repoID");?> method='post'>
<table class='table'>
<thead>
<tr>
+1
View File
@@ -39,6 +39,7 @@
<?php if(!isonlybody()) echo "<div class='divider'></div>";?>
<?php if(!$design->deleted):?>
<?php
common::printIcon('design', 'assignTo', "designID=$design->id", $design, 'button', '', '', 'iframe showinonlybody', true);
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');
+1 -1
View File
@@ -285,7 +285,7 @@ class group extends control
$this->view->position = $position;
$this->view->allUsers = $allUsers;
$this->view->group = $group;
$this->view->programs = $this->dao->select('id, name')->from(TABLE_PROJECT)->where('program')->eq(0)->andWhere('deleted')->eq(0)->fetchPairs();
$this->view->programs = $this->dao->select('id, name')->from(TABLE_PROJECT)->where('program')->eq(0)->andWhere('deleted')->eq(0)->andWhere('isCat')->eq(0)->fetchPairs();
$this->view->deptTree = $this->loadModel('dept')->getTreeMenu($rooteDeptID = 0, array('deptModel', 'createManagePgmAdminLink'), $groupID);
$this->view->groupUsers = $groupUsers;
$this->view->userPrograms = $userPrograms;
+2 -16
View File
@@ -44,9 +44,7 @@ $lang->moduleOrder[92] = 'durationestimation';
$lang->moduleOrder[93] = 'budget';
$lang->moduleOrder[95] = 'company';
$lang->moduleOrder[96] = 'milestone';
$lang->moduleOrder[97] = 'stage';
$lang->moduleOrder[98] = 'weekly';
$lang->moduleOrder[100] = 'dept';
$lang->moduleOrder[105] = 'group';
$lang->moduleOrder[110] = 'user';
@@ -514,6 +512,7 @@ $lang->resource->design->commit = 'commit';
$lang->resource->design->revision = 'revision';
$lang->resource->design->delete = 'delete';
$lang->resource->design->view = 'view';
$lang->resource->design->assignTo = 'assignTo';
$lang->design->methodOrder[5] = 'browse';
$lang->design->methodOrder[10] = 'create';
@@ -523,6 +522,7 @@ $lang->design->methodOrder[20] = 'commit';
$lang->design->methodOrder[25] = 'revision';
$lang->design->methodOrder[30] = 'delete';
$lang->design->methodOrder[35] = 'view';
$lang->design->methodOrder[40] = 'assignTo';
/* Program plan. */
$lang->resource->programplan = new stdclass();
@@ -1033,20 +1033,6 @@ $lang->git->methodOrder[5] = 'diff';
$lang->git->methodOrder[10] = 'cat';
$lang->git->methodOrder[15] = 'apiSync';
/* Milestone. */
$lang->resource->milestone = new stdclass();
$lang->resource->milestone->index = 'index';
$lang->resource->milestone->saveOtherProblem = 'saveOtherProblem';
$lang->milestone->methodOrder[0] = 'index';
$lang->milestone->methodOrder[5] = 'saveOtherProblem';
/* Weekly. */
$lang->resource->weekly = new stdclass();
$lang->resource->weekly->index = 'index';
$lang->weekly->methodOrder[0] = 'index';
/* Stage. */
$lang->resource->stage = new stdclass();
$lang->resource->stage->browse = 'browse';
+13 -5
View File
@@ -81,7 +81,7 @@ class issue extends control
*
* @access public
* @return void
*/
*/
public function batchCreate()
{
if($_POST)
@@ -117,7 +117,7 @@ class issue extends control
else
{
$this->issue->delete($issueID);
die(js::reload('parent'));
die(js::locate(inLink('browse'), 'parent'));
}
}
@@ -306,7 +306,7 @@ class issue extends control
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
}
$this->view->title = $this->lang->issue->resolved;
$this->view->title = $this->lang->issue->resolve;
$this->view->issue = $this->issue->getByID($issue);
$this->view->users = $this->loadModel('user')->getPairs('noletter');
@@ -314,6 +314,13 @@ class issue extends control
$this->display();
}
/**
* prepairParams
*
* @param int $issue
* @access public
* @return void
*/
public function prepairParams($issue)
{
$this->loadModel('task');
@@ -396,10 +403,11 @@ class issue extends control
$this->display();
}
/**
* Common actions of issue module.
/**
* commonAction
*
* @param int $issueID
* @param int $object
* @access public
* @return void
*/
+17 -4
View File
@@ -1,4 +1,14 @@
<?php
/**
* The issue module English file 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 issue
* @version $Id: en.php 4729 2013-05-03 07:53:55Z chencongzhi520@gmail.com $
* @link http://www.zentao.net
*/
$lang->issue->common = 'Issue';
$lang->issue->browse = 'List';
$lang->issue->resolvedBy = 'Resolved By';
@@ -27,15 +37,18 @@ $lang->issue->closedDate = 'ClosedDate';
$lang->issue->assignedTo = 'AssignedTo';
$lang->issue->assignedBy = 'AssignedBy';
$lang->issue->assignedDate = 'AssignedDate';
$lang->issue->resolved = 'Resolved';
$lang->issue->resolve = 'Resolved';
$lang->issue->id = 'ID';
$lang->issue->view = 'Issue Details';
$lang->issue->close = 'Closed';
$lang->issue->cancel = 'Cancel';
$lang->issue->delete = 'Delete';
$lang->issue->search = 'Search';
$lang->issue->basicInfo = 'Basic Information';
$lang->issue->active = 'Activate';
$lang->issue->assign = 'Assign';
$lang->issue->create = 'Create Issue';
$lang->issue->activate = 'Activate';
$lang->issue->assignTo = 'Assign';
$lang->issue->create = 'Create';
$lang->issue->edit = 'Edit';
$lang->issue->batchCreate = 'Batch Create';
+18 -12
View File
@@ -1,4 +1,14 @@
<?php
/**
* The issue module zh-cn file 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 issue
* @version $Id: zh-cn.php 4729 2013-05-03 07:53:55Z chencongzhi520@gmail.com $
* @link http://www.zentao.net
*/
$lang->issue->common = '项目问题';
$lang->issue->browse = '问题列表';
$lang->issue->resolvedBy = '解决者';
@@ -27,24 +37,20 @@ $lang->issue->closedDate = '关闭日期';
$lang->issue->assignedTo = '指派给';
$lang->issue->assignedBy = '由谁指派';
$lang->issue->assignedDate = '指派时间';
$lang->issue->resolved = '解决';
$lang->issue->resolve = '解决';
$lang->issue->id = '编号';
$lang->issue->view = '问题详情';
$lang->issue->close = '关闭';
$lang->issue->cancel = '取消';
$lang->issue->delete = '删除';
$lang->issue->search = '搜索';
$lang->issue->basicInfo = '基本信息';
$lang->issue->active = '激活';
$lang->issue->assign = '指派';
$lang->issue->assignTo = '指派问题';
$lang->issue->create = '新建问题';
$lang->issue->edit = '编辑问题';
$lang->issue->activate = '激活';
$lang->issue->assignTo = '指派';
$lang->issue->create = '新建';
$lang->issue->edit = '编辑';
$lang->issue->batchCreate = '批量新建';
$lang->issue->close = '关闭问题';
$lang->issue->cancel = '取消问题';
$lang->issue->activate = '激活问题';
$lang->issue->resolve = '解决问题';
$lang->issue->resolve = '解决问题';
$lang->issue->view = '问题概况';
$lang->issue->labelList['all'] = '全部';
$lang->issue->labelList['open'] = '开放';
+19 -4
View File
@@ -62,7 +62,6 @@ class issueModel extends model
* @param string $owner
* @param string $activityID
* @param object $pager
*
* @access public
* @return object
*/
@@ -94,7 +93,7 @@ class issueModel extends model
$issueQuery = '';
if($browseType == 'bysearch')
{
$query = $queryID ? $this->loadModel('search')->getQuery($queryID) : '';
$query = $queryID ? $this->loadModel('search')->getQuery($queryID) : '';
if($query)
{
$this->session->set('issueQuery', $query->sql);
@@ -120,11 +119,26 @@ class issueModel extends model
return $issueList;
}
/**
* getActivityList
*
* @access public
* @return object
*/
public function getActivityList()
{
return $this->dao->select('id,name')->from(TABLE_ACTIVITY)->where('deleted')->eq('0')->orderBy('id_desc')->fetchPairs();
}
/**
* getBlockIssues
*
* @param string $browseType
* @param int $limit
* @param string $orderBy
* @access public
* @return array
*/
public function getBlockIssues($browseType = 'all', $limit = 15, $orderBy = 'id_desc')
{
$issueList = $this->dao->select('*')->from(TABLE_ISSUE)
@@ -325,7 +339,7 @@ class issueModel extends model
*
* @param int $issueID
* @access public
* @return void
* @return object
*/
public function resolve($issueID)
{
@@ -338,7 +352,7 @@ class issueModel extends model
* Create task.
*
* @access public
* @return void
* @return object
*/
public function createTask()
{
@@ -358,6 +372,7 @@ class issueModel extends model
$story = fixer::input('post')->remove('issue,color')
->setIF($this->post->needNotReview or $this->post->projectID > 0, 'status', 'active')
->get();
$this->dao->insert(TABLE_STORY)->data($story, 'teamMember,storyEstimate,storyDesc,storyPri,labels,files,spec,story,needNotReview')->exec();
$id = $this->dao->lastInsertID();
$this->dao->insert(TABLE_STORYSPEC)
+2
View File
@@ -19,6 +19,7 @@
<table class="table table-form">
<thead>
<tr class="text-center">
<th class="w-50px"><?php echo $lang->issue->id;?></th>
<th class="required"><?php echo $lang->issue->title;?></th>
<th class="w-140px required"><?php echo $lang->issue->type;?></th>
<th class="w-120px required"><?php echo $lang->issue->severity;?></th>
@@ -31,6 +32,7 @@
<tbody>
<?php for($i = 1;$i <= 10;$i++):?>
<tr data-key="<?php echo $i;?>">
<td><?php echo $i;?></td>
<td>
<?php echo html::input("dataList[$i][title]", '', 'id="dataList'.$i.'title" class="form-control" autocomplete="off"')?>
</td>
+3 -3
View File
@@ -62,11 +62,11 @@
<td title="<?php echo $issue->createdDate;?>"><?php echo $issue->createdDate;?></td>
<td class="c-actions">
<?php
echo common::printIcon('issue', 'resolve', "issueID=$issue->id", $issue, 'list', 'checked', '', 'iframe', 'yes', '', $lang->issue->resolved);
echo common::printIcon('issue', 'assignTo', "issueID=$issue->id", $issue, 'list', 'hand-right', '', 'iframe', 'yes', '', $lang->issue->assignedTo);
echo common::printIcon('issue', 'resolve', "issueID=$issue->id", $issue, 'list', 'checked', '', 'iframe', 'yes', '', $lang->issue->resolve);
echo common::printIcon('issue', 'assignTo', "issueID=$issue->id", $issue, 'list', 'hand-right', '', 'iframe', 'yes', '', $lang->issue->assignTo);
echo common::printIcon('issue', 'close', "issueID=$issue->id", $issue, 'list', 'off', '', 'iframe', 'yes');
echo common::printIcon('issue', 'cancel', "issueID=$issue->id", $issue, 'list', 'ban-circle', '', 'iframe', 'yes');
echo common::printIcon('issue', 'activate', "issueID=$issue->id", $issue, 'list', 'magic', '', 'iframe', 'yes', '', $lang->issue->active);
echo common::printIcon('issue', 'activate', "issueID=$issue->id", $issue, 'list', 'magic', '', 'iframe', 'yes', '', $lang->issue->activate);
echo common::printIcon('issue', 'edit', "issueID=$issue->id", $issue, 'list', 'edit');
$deleteClass = common::hasPriv('issue', 'delete') ? 'btn' : 'btn disabled';
echo html::a($this->createLink('issue', 'delete', "issueID=$issue->id"), '<i class="icon-trash"></i>', 'hiddenwin', "title='{$lang->issue->delete}' class='$deleteClass'");
+54 -42
View File
@@ -1,3 +1,15 @@
<?php
/**
* The createbug view of issue 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 Congzhi Chen <congzhi@cnezsoft.com>
* @package issue
* @version $Id$
* @link http://www.zentao.net
*/
?>
<tr class='bugTR storyTR'>
<th class='w-110px'><?php echo $lang->bug->product;?></th>
<td>
@@ -262,14 +274,14 @@ $(function()
/**
* Load all fields.
*
* @param int $productID
*
* @param int $productID
* @access public
* @return void
*/
function loadAll(productID)
{
if(page == 'create')
if(page == 'create')
{
loadProjectTeamMembers(productID);
}
@@ -294,8 +306,8 @@ function loadAll(productID)
$('#taskIdBox').innerHTML = '<select id="task"></select>'; // Reset the task.
$('#task').chosen();
loadProductBranches(productID)
loadProductModules(productID);
loadProductProjects(productID);
loadProductModules(productID);
loadProductProjects(productID);
loadProductBuilds(productID);
loadProductplans(productID);
loadProductStories(productID);
@@ -304,7 +316,7 @@ function loadAll(productID)
/**
* Load by branch.
*
*
* @access public
* @return void
*/
@@ -314,7 +326,7 @@ function loadBranch()
$('#task').chosen();
productID = $('#product').val();
loadProductModules(productID);
loadProductProjects(productID);
loadProductProjects(productID);
loadProductBuilds(productID);
loadProductplans(productID);
loadProductStories(productID);
@@ -351,7 +363,7 @@ function loadAllBuilds(that)
}
}
/**
/**
* Load all builds of the project.
*
* @param int $projectID
@@ -391,7 +403,7 @@ function loadAllProjectBuilds(projectID, productID)
}
}
/**
/**
* Load all builds of the product.
*
* @param int $productID
@@ -402,7 +414,7 @@ function loadAllProductBuilds(productID)
{
branch = $('#branch').val();
if(typeof(branch) == 'undefined') branch = 0;
if(page == 'create')
if(page == 'create')
{
link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + '&varName=openedBuild&build=' + oldOpenedBuild + '&branch=' + branch + '&index=0&type=all');
$.get(link, function(data)
@@ -431,8 +443,8 @@ function loadAllProductBuilds(productID)
/**
* Load product's modules.
*
* @param int $productID
*
* @param int $productID
* @access public
* @return void
*/
@@ -442,16 +454,16 @@ function loadProductModules(productID)
if(typeof(branch) == 'undefined') branch = 0;
link = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + productID + '&viewtype=bug&branch=' + branch + '&rootModuleID=0&returnType=html&fieldID=&needManage=true');
$('#moduleIdBox').load(link, function()
{
{
$(this).find('select').chosen()
if(typeof(bugModule) == 'string') $('#moduleIdBox').prepend("<span class='input-group-addon' style='border-left-width: 1px;'>" + bugModule + "</span>");
});
}
/**
* Load product stories
*
* @param int $productID
* Load product stories
*
* @param int $productID
* @access public
* @return void
*/
@@ -464,9 +476,9 @@ function loadProductStories(productID)
}
/**
* Load projects of product.
*
* @param int $productID
* Load projects of product.
*
* @param int $productID
* @access public
* @return void
*/
@@ -480,8 +492,8 @@ function loadProductProjects(productID)
/**
* Load product plans.
*
* @param productID $productID
*
* @param productID $productID
* @access public
* @return void
*/
@@ -494,9 +506,9 @@ function loadProductplans(productID)
}
/**
* Load product builds.
*
* @param productID $productID
* Load product builds.
*
* @param productID $productID
* @access public
* @return void
*/
@@ -527,8 +539,8 @@ function loadProductBuilds(productID)
/**
* Load project related bugs and tasks.
*
* @param int $projectID
*
* @param int $projectID
* @access public
* @return void
*/
@@ -551,8 +563,8 @@ function loadProjectRelated(projectID)
/**
* Load project tasks.
*
* @param projectID $projectID
*
* @param projectID $projectID
* @access public
* @return void
*/
@@ -570,8 +582,8 @@ function loadProjectTasks(projectID)
/**
* Load project stories.
*
* @param projectID $projectID
*
* @param projectID $projectID
* @access public
* @return void
*/
@@ -585,8 +597,8 @@ function loadProjectStories(projectID)
/**
* Load builds of a project.
*
* @param int $projectID
*
* @param int $projectID
* @access public
* @return void
*/
@@ -613,7 +625,7 @@ function loadProjectBuilds(projectID)
{
link = createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&varName=openedBuild&build=' + oldOpenedBuild + '&branch=' + branch);
$('#openedBuildBox').load(link, function(){$(this).find('select').chosen()});
oldResolvedBuild = $('#resolvedBuild').val() ? $('#resolvedBuild').val() : 0;
link = createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&varName=resolvedBuild&build=' + oldResolvedBuild + '&branch=' + branch);
$('#resolvedBuildBox').load(link, function(){$(this).find('select').chosen()});
@@ -622,9 +634,9 @@ function loadProjectBuilds(projectID)
/**
* Set story field.
*
* @param moduleID $moduleID
* @param productID $productID
*
* @param moduleID $moduleID
* @param productID $productID
* @access public
* @return void
*/
@@ -644,8 +656,8 @@ function setStories(moduleID, productID)
/**
* Load product branches.
*
* @param int $productID
*
* @param int $productID
* @access public
* @return void
*/
@@ -666,8 +678,8 @@ function loadProductBranches(productID)
/**
* Load team members of the project as assignedTo list.
*
* @param int $projectID
*
* @param int $projectID
* @access public
* @return void
*/
@@ -684,14 +696,14 @@ function loadAssignedTo(projectID)
/**
* notice for create build.
*
*
* @access public
* @return void
*/
function notice()
{
$('#buildBoxActions').empty().hide();
if($('#openedBuild').find('option').length <= 1)
if($('#openedBuild').find('option').length <= 1)
{
var html = '';
if($('#project').length == 0 || $('#project').val() == '')
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The createrisk view of issue 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 Congzhi Chen <congzhi@cnezsoft.com>
* @package issue
* @version $Id$
* @link http://www.zentao.net
*/
?>
<tr class="riskTR">
<th><?php echo $lang->risk->name;?></th>
<td>
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The createstory view of issue 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 Congzhi Chen <congzhi@cnezsoft.com>
* @package issue
* @version $Id$
* @link http://www.zentao.net
*/
?>
<tr class='storyTR'>
<th><?php echo $lang->story->reviewedBy;?></th>
<td><?php echo html::select('assignedTo', $users, '', "class='form-control chosen'");?></td>
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The createtask view of issue 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 Congzhi Chen <congzhi@cnezsoft.com>
* @package issue
* @version $Id$
* @link http://www.zentao.net
*/
?>
<tr class='taskTR'>
<th><?php echo $lang->task->project;?></th>
<td><?php echo html::select('project', $projects, $project->id, "class='form-control chosen' onchange='loadAll(this.value)'");?></td><td></td><td></td>
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The resolve view of issue 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 Congzhi Chen <congzhi@cnezsoft.com>
* @package issue
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php
include '../../common/view/header.html.php';
include '../../common/view/kindeditor.html.php';
+18
View File
@@ -49,6 +49,24 @@ foreach($issue as $field => $value)
</div>
<?php $actionFormLink = $this->createLink('action', 'comment', "objectType=issue&objectID=$issue->id");?>
<div class="cell"><?php include '../../common/view/action.html.php';?></div>
<div class='main-actions'>
<div class="btn-toolbar">
<?php common::printBack($browseLink);?>
<?php if(!isonlybody()) echo "<div class='divider'></div>";?>
<?php if(!$issue->deleted):?>
<?php
common::printIcon('issue', 'resolve', "issueID=$issue->id", $issue, 'button', 'checked', '', 'iframe showinonlybody', true);
common::printIcon('issue', 'assignTo', "issueID=$issue->id", $issue, 'button', '', '', 'iframe showinonlybody', true);
common::printIcon('issue', 'cancel', "issueID=$issue->id", $issue, 'button', '', '', 'iframe showinonlybody', true);
common::printIcon('issue', 'close', "issueID=$issue->id", $issue, 'button', '', '', 'iframe showinonlybody', true);
common::printIcon('issue', 'activate', "issueID=$issue->id", $issue, 'button', '', '', 'iframe showinonlybody', true);
echo "<div class='divider'></div>";
common::printIcon('issue', 'edit', "issueID=$issue->id", $issue);
common::printIcon('issue', 'delete', "issueID=$issue->id", $issue, 'button', 'trash', 'hiddenwin');
?>
<?php endif;?>
</div>
</div>
</div>
<div class="side-col col-4">
<div class="cell">
-5
View File
@@ -1,5 +0,0 @@
<?php
$config->milestone = new stdclass();
$config->milestone->story = 'URS,SRS';
$config->milestone->design = 'HLDS,DDS';
$config->milestone->test = 'ITTC,STP,STTC,ITP';
-63
View File
@@ -1,63 +0,0 @@
<?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
View File
@@ -1,15 +0,0 @@
#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
View File
@@ -1,100 +0,0 @@
<?php
$lang->milestone->index = 'Milestone Home';
$lang->milestone->title = 'Milestone Report';
$lang->milestone->common = 'Project Milestone Report';
$lang->milestone->name = 'Milestone Name';
$lang->milestone->stage = 'Milestone Stage';
$lang->milestone->save = 'Save';
$lang->milestone->startedWeeks = 'Started Weeks';
$lang->milestone->finishedWeeks = 'Finished Weeks';
$lang->milestone->offset = 'Milestone Deviation';
$lang->milestone->processCommon = 'Project Current Status';
$lang->milestone->process = 'Project Schedule';
$lang->milestone->projectCost = 'Project Cost';
$lang->milestone->toNow = 'So far';
$lang->milestone->targetRange = 'Target Range';
$lang->milestone->ge = 'ge';
$lang->milestone->le = 'le';
$lang->milestone->analysis = 'Analysis';
$lang->milestone->PV = 'The work to be done(PV)';
$lang->milestone->EV = 'Actual work done(EV)';
$lang->milestone->AC = 'Actual cost(AC)';
$lang->milestone->SPI = 'Project schedule performance(SPI)';
$lang->milestone->CPI = 'Project cost performance(CPI)';
$lang->milestone->SV = 'Rate of progress deviation(SV%)';
$lang->milestone->CV = 'Cost deviation rate(CV%)';
$lang->milestone->workHours = 'Workload (man-hour)';
$lang->milestone->allStage = 'Project Stage';
$lang->milestone->devHours = 'Development Workload';
$lang->milestone->toHours = 'Rework Workload';
$lang->milestone->qaHours = 'Test Workload';
$lang->milestone->rowSummary = 'Workload Subtotal';
$lang->milestone->rowPercent = 'Percentage Distribution(%)';
$lang->milestone->colPercent = 'Percentage of workload(%)';
$lang->milestone->colSummary = 'Total';
$lang->milestone->qatoDev = 'Test Development ratio';
$lang->milestone->projectRisk = '5.Project Risks (top five highest priority risks)';
$lang->milestone->riskCountermove = 'Risk Countermove';
$lang->milestone->riskDescriptio = 'Risk Description';
$lang->milestone->riskPossibility = 'Risk Possibility';
$lang->milestone->riskSeriousness = 'Risk Seriousness';
$lang->milestone->riskFactor = 'Risk Factor';
$lang->milestone->riskMeasures = 'Risk Measures';
$lang->milestone->riskAccumulate = 'Risk Accumulate';
$lang->milestone->otherIssue = 'Other Issue';
$lang->milestone->issueSolutions = 'Issue Solutions';
$lang->milestone->issueDescription = 'Issue Description';
$lang->milestone->needHelp = 'Help';
$lang->milestone->issuePropose = 'Issue Propose';
$lang->milestone->demandStatus = '4.Customer Demand Analysis';
$lang->milestone->storyUnit = 'Unit:Item';
$lang->milestone->engineeringStage = 'Engineering Stage';
$lang->milestone->rateChange = 'Rate of change in demand';
$lang->milestone->originalStory = 'Quantity of original demand';
$lang->milestone->modifyNumber = 'Total post-change requirements';
$lang->milestone->changeStory = 'Number of changed requirements';
$lang->milestone->paogressForecast = 'Project Forecast';
$lang->milestone->duration = 'Construction period(day)';
$lang->milestone->cost = 'Cost(hours)';
$lang->milestone->forecastResults = 'Forecast Results';
$lang->milestone->plannedValue = 'Planned Value';
$lang->milestone->predictedValue = 'Predicted Value';
$lang->milestone->predictedValueDesc = 'Rentenformel (Germany):If the project progress performance(SPI)=0,So the predicted value=0,Otherwise,Predicted value=Planned value divided by Project schedule performance(SPI)';
$lang->milestone->periodDeviation = 'Period Deviation';
$lang->milestone->costDeviation = 'Cost Deviation';
$lang->milestone->nextStage = 'Next Stage';
$lang->milestone->overallProject = 'Overall Project';
$lang->milestone->corrective = 'Corrective Measure';
$lang->milestone->timeOverrun = 'The total construction time will exceed:%s day.';
$lang->milestone->costOverrun = 'The total cost will exceed:%s unit';
$lang->milestone->saveOtherProblem = 'Save Other Problem';
$lang->milestone->chart = new stdclass();
$lang->milestone->chart->title = 'Trend Chart of project progress to date';
$lang->milestone->chart->time = 'No';
$lang->milestone->chart->week = 'week';
$lang->milestone->chart->month = 'month';
$lang->milestone->chart->workhour = 'Development Workload Analysis Chart';
$lang->milestone->otherproblem = '6.Other Problem';
$lang->milestone->problemandsuggest = 'Problem and Suggest';
$lang->milestone->suggest = 'Suggest';
$lang->milestone->needhelp = 'Does it require high-level support?';
$lang->milestone->prodescr = 'Problem Description';
$lang->milestone->quality = new stdclass();
$lang->milestone->quality->total = 'Total';
$lang->milestone->quality->identify = 'Defect identification phase';
$lang->milestone->quality->injection = 'Defect injection phase';
$lang->milestone->quality->scale = 'Scale';
$lang->milestone->quality->identifyRate = 'Defect recognition rate';
$lang->milestone->quality->injectionRate = 'Defect injection rate';
$lang->milestone->options = 'Options';
-101
View File
@@ -1,101 +0,0 @@
<?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->month = '月';
$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 = '操作';
-606
View File
@@ -1,606 +0,0 @@
<?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 : date('Y-m-d', strtotime("$today + 7 days"));
$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['PV'] .= ']';
$charts['EV'] .= ']';
$charts['AC'] .= ']';
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
View File
@@ -1,27 +0,0 @@
<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>
-115
View File
@@ -1,115 +0,0 @@
<div class='milestone-chart' id='milestoneChart'>
<div class='chart-canvas scrollbar-hover'>
<div class='chart-wrapper'>
<canvas width='400' height='120' data-responsive='true'></canvas>
</div>
</div>
<div class='chart-unit'><?php echo "({$lang->project->workHour})";?></div>
<div class='chart-legend'>
<span class="barline line-pv">PV</span>
<span class="barline line-ev">EV</span>
<span class="barline line-ac">AC</span>
</div>
</div>
<style>
.milestone-chart {position: relative}
.milestone-chart .chart-canvas {overflow: auto; max-width: 1002px}
.milestone-chart .chart-wrapper {background: none; padding: 15px 0 0 0}
.milestone-chart .chart-unit {position: absolute; left: 10px; top: 0;}
.milestone-chart .chart-legend {position: absolute; right: 5px; top: 0;}
.milestone-chart .barline {padding-left: 20px; position: relative; display: inline-block; line-height: 20px}
.milestone-chart .barline + .barline {margin-left: 5px}
.milestone-chart .barline:before {content: ' '; display: block; position: absolute; top: 8px; left: 0; width: 16px; height: 3px; background: #0c64eb}
.milestone-chart .barline.line-ev:before {background: rgb(0, 218, 136)}
.milestone-chart .barline.line-ac:before {background: rgb(255, 145, 0)}
</style>
<script>
function initMilestoneChart()
{
var data =
{
labels: <?php echo json_encode($charts['labels'])?>,
datasets: [
{
label: 'PV',
color: '#0c64eb',
pointColor: '#0c64eb',
pointStrokeColor: '#0c64eb',
pointHighlightStroke: '#0c64eb',
fillColor: 'rgba(0,106,241, .07)',
pointHighlightFill: '#fff',
data: <?php echo $charts['PV']?>
},
{
label: 'EV',
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 betterWidth = data.labels.length * 15;
var renderChart = function()
{
var $chart = $('#milestoneChart');
var $wrapper = $chart.find('.chart-wrapper');
var $canvas = $chart.find('canvas');
var $chartCanvas = $chart.find('.chart-canvas');
if (betterWidth > 400)
{
var updateWrapperSize = function()
{
$wrapper.hide();
$chartCanvas.css('max-width', 'initial');
var maxWidth = $chartCanvas.width();
$chartCanvas.css('max-width', maxWidth);
$chart.toggleClass('has-scrollbar', maxWidth < betterWidth);
$wrapper.show();
};
updateWrapperSize();
$(window).on('resize', updateWrapperSize);
$wrapper.css('min-width', betterWidth);
$canvas.attr(
{
width: betterWidth,
height: Math.min(200, Math.floor(betterWidth / 4))
});
}
$canvas.lineChart(data,
{
animation: betterWidth < 400,
pointDotStrokeWidth: 1,
pointDotRadius: 2,
datasetStrokeWidth: 2,
datasetFill: false,
datasetStroke: true,
scaleShowBeyondLine: true,
responsive: true,
bezierCurve: false,
scaleFontColor: '#838A9D',
tooltipXPadding: 10,
tooltipYPadding: 10,
multiTooltipTitleTemplate: '<%= label %> <?php echo $lang->project->workHour;?> /h',
multiTooltipTemplate: '<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>',
});
}
setTimeout(renderChart, betterWidth > 200 ? 100 : 10);
}
initMilestoneChart();
</script>
-49
View File
@@ -1,49 +0,0 @@
<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
View File
@@ -1,66 +0,0 @@
<?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';?>
<div class="cell"><?php include 'chart.html.php';?></div>
<?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';?>
@@ -1,73 +0,0 @@
<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
View File
@@ -1,74 +0,0 @@
<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>
@@ -1,53 +0,0 @@
<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
View File
@@ -1,76 +0,0 @@
<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>
@@ -1,29 +0,0 @@
<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
View File
@@ -1,42 +0,0 @@
<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
View File
@@ -1,102 +0,0 @@
<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>
+1 -1
View File
@@ -57,7 +57,7 @@ class program extends control
}
else
{
$programs = $this->program->getList($status, $orderBy, $pager);
$programs = $this->program->getList($status, $orderBy, $pager, true);
}
$this->view->programs = $programs;
+24
View File
@@ -1,6 +1,30 @@
$(function()
{
$('#copyProjects a').click(function(){setCopyProject($(this).data('id')); $('#copyProjectModal').modal('hide')});
$('#isCat').change(function()
{
if($(this).prop('checked'))
{
$('#longTimeBox').removeClass('hidden');
}
else
{
$('#longTimeBox').addClass('hidden');
$('#longTimeBox').find('#longTime').prop('checked', false).change();
}
});
$('#longTime').change(function()
{
if($(this).prop('checked'))
{
$('#end').val('').attr('disabled', 'disabled');
}
else
{
$('#end').removeAttr('disabled');
}
});
});
function setCopyProject(copiedProgramID)
+31
View File
@@ -0,0 +1,31 @@
$(function()
{
var endDate = $('#end').val();
$('#isCat').change(function()
{
if($(this).prop('checked'))
{
$('#longTimeBox').removeClass('hidden');
$('#longTime').change();
}
else
{
$('#longTimeBox').addClass('hidden');
$('#longTimeBox').find('#longTime').prop('checked', false).change();
}
});
$('#longTime').change(function()
{
if($(this).prop('checked'))
{
$('#end').val('').attr('disabled', 'disabled');
}
else
{
$('#end').val(endDate).removeAttr('disabled');
}
});
$('#isCat').change();
});
+2 -2
View File
@@ -65,6 +65,7 @@ $lang->program->ac = 'AC';
$lang->program->cv = 'CV%';
$lang->program->pm = 'PM';
$lang->program->teamCount = 'The Number Of Team';
$lang->program->longTime = 'Long-term Project';
$lang->program->unitList[''] = '';
$lang->program->unitList['yuan'] = 'Yuan';
@@ -104,10 +105,8 @@ $lang->program->lastIteration = 'Latest iterations';
$lang->program->ongoingStage = 'Ongoing stage';
$lang->program->scrum = 'Scrum';
$lang->program->scrumTitle = 'Scrum development full process project management';
$lang->program->scrumDesc = '<strong>Introduction: </strong>Iterate in small steps, release quickly<br><strong>Contains function points: </strong>Project overview, iterations, plans, stories, etc.';
$lang->program->cmmi = 'CMMI';
$lang->program->cmmiTitle = 'CMMI management';
$lang->program->cmmiDesc = '<strong>Introduction: </strong>Standardized management by stages<br><strong>Contains function points: </strong>Estimate, plan, stage, report, etc.';
$lang->program->cannotCreateChild = 'The project already has actual content and can not add subprojects directly. You can create a parent project for the current project and then add a child project under the new parent project.';
$lang->program->hasChildren = 'This project has a subproject and can not be deleted.';
$lang->program->confirmDelete = 'Do you want to delete this project?';
@@ -120,3 +119,4 @@ $lang->program->beginLetterParent = "Begin date of parent project: %s, Begin da
$lang->program->endGreaterParent = "End date of parent project: %s, End date cannot be greater than the end date of parent project.";
$lang->program->beginGreateChild = "Minimum begin date of child project: %s, the begin date of parent project cannot be greater than the minimum begin date of child project.";
$lang->program->endLetterChild = "Maximum end date of child project: %s, the end date of parent project cannot be less than the maximum end date of child project.";
$lang->program->childLongTime = "There are long-term projects in the sub project, and the parent project should also be a long-term project";
+2 -2
View File
@@ -65,6 +65,7 @@ $lang->program->ac = 'AC';
$lang->program->cv = 'CV%';
$lang->program->pm = '项目负责人';
$lang->program->teamCount = '项目成员';
$lang->program->longTime = '长期项目';
$lang->program->unitList[''] = '';
$lang->program->unitList['yuan'] = '元';
@@ -104,10 +105,8 @@ $lang->program->lastIteration = '近期迭代';
$lang->program->ongoingStage = '进行中的阶段';
$lang->program->scrum = 'Scrum';
$lang->program->scrumTitle = '敏捷开发全流程项目管理';
$lang->program->scrumDesc = '<strong>简介:</strong>小步迭代,快速发布<br><strong>包含功能点:</strong>项目概览、迭代、计划、需求等';
$lang->program->cmmi = '瀑布';
$lang->program->cmmiTitle = '瀑布式项目管理';
$lang->program->cmmiDesc = '<strong>简介:</strong>按阶段规范化管理<br><strong>包含功能点:</strong>估算、计划、阶段、报告';
$lang->program->cannotCreateChild = '该项目已经有实际的内容,无法直接添加子项目。您可以为当前项目创建一个父项目,然后在新的父项目下面添加子项目。';
$lang->program->hasChildren = '该项目有子项目存在,不能删除。';
$lang->program->confirmDelete = "您确定删除项目[%s]吗?";
@@ -120,3 +119,4 @@ $lang->program->beginLetterParent = "父项目的开始日期:%s,开始日
$lang->program->endGreaterParent = "父项目的完成日期:%s,完成日期不能大于父项目的完成日期";
$lang->program->beginGreateChild = "子项目的最小开始日期:%s,父项目的开始日期不能大于子项目的最小开始日期";
$lang->program->endLetterChild = "子项目的最大完成日期:%s,父项目的完成日期不能小于子项目的最大完成日期";
$lang->program->childLongTime = "子项目中有长期项目,父项目也应该是长期项目";
+52 -34
View File
@@ -7,16 +7,17 @@ class programModel extends model
* @param varchar $status
* @param varchar $orderBy
* @param object $pager
* @param bool $includeCat
* @access public
* @return array
*/
public function getList($status = 'all', $orderBy = 'id_desc', $pager = NULL)
public function getList($status = 'all', $orderBy = 'id_desc', $pager = NULL, $includeCat = false)
{
return $this->dao->select('*')->from(TABLE_PROJECT)
->where('iscat')->eq(0)
->where('program')->eq(0)
->andWhere('template')->ne('')
->andWhere('program')->eq(0)
->andWhere('deleted')->eq(0)
->beginIF(!$includeCat)->andWhere('iscat')->eq(0)->fi()
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->programs)->fi()
->beginIF($status != 'all')->andWhere('status')->eq($status)->fi()
->beginIF($this->cookie->mine)
@@ -183,6 +184,7 @@ class programModel extends model
/* Init vars. */
$this->loadModel('project');
$programs = $this->getList($status, $orderBy, $pager);
if(empty($programs)) return array();
$programIdList = array_keys($programs);
@@ -207,9 +209,10 @@ class programModel extends model
foreach($programs as $programID => $program)
{
$orderBy = $program->template == 'cmmi' ? 'id_asc' : 'id_desc';
$program->projects = $this->project->getProjectStats($status, 0, 0, $itemCounts, $orderBy, $pager, $programID);
$program->teamCount = isset($teams[$programID]) ? $teams[$programID]->count : 0;
$program->estimate = isset($estimates[$programID]) ? $estimates[$programID]->estimate : 0;
$program->projects = $this->project->getProjectStats($status, 0, 0, $itemCounts, $orderBy, $pager, $programID);
$program->teamCount = isset($teams[$programID]) ? $teams[$programID]->count : 0;
$program->estimate = isset($estimates[$programID]) ? $estimates[$programID]->estimate : 0;
$program->parentName = $this->project->getProjectParentName($program->parent);
}
return $programs;
@@ -246,26 +249,38 @@ class programModel extends model
->add('type', 'program')
->setIF($this->post->acl != 'custom', 'whitelist', '')
->setDefault('openedBy', $this->app->user->account)
->setDefault('end', '')
->setDefault('openedDate', helper::now())
->setDefault('team', substr($this->post->name, 0, 30))
->join('whitelist', ',')
->cleanInt('budget')
->stripTags($this->config->program->editor->create['id'], $this->config->allowedTags)
->remove('products, workDays, delta, branch, uid, plans')
->remove('products, workDays, delta, branch, uid, plans, longTime')
->get();
if($project->parent)
{
$parentProgram = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($project->parent)->fetch();
if($project->begin < $parentProgram->begin) dao::$errors['begin'] = sprintf($this->lang->program->beginLetterParent, $parentProgram->begin);
if($project->end > $parentProgram->end) dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $parentProgram->end);
if(dao::isError()) return false;
if($parentProgram)
{
/* Child project begin cannot less than parent. */
if($project->begin < $parentProgram->begin) dao::$errors['begin'] = sprintf($this->lang->program->beginLetterParent, $parentProgram->begin);
/* When parent set end then child project end cannot greater than parent. */
if($parentProgram->end != '0000-00-00' and $project->end > $parentProgram->end) dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $parentProgram->end);
/* When parent set end then child project cannot set longTime. */
if(empty($project->end) and $this->post->longTime and $parentProgram->end != '0000-00-00') dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $parentProgram->end);
if(dao::isError()) return false;
}
}
$requiredFields = $this->config->program->create->requiredFields;
if($this->post->longTime) $requiredFields = trim(str_replace(',end,', ',', ",{$requiredFields},"), ',');
$project = $this->loadModel('file')->processImgURL($project, $this->config->program->editor->create['id'], $this->post->uid);
$this->dao->insert(TABLE_PROJECT)->data($project)
->autoCheck()
->batchcheck($this->config->program->create->requiredFields, 'notempty')
->batchcheck($requiredFields, 'notempty')
->check('name', 'unique', "deleted='0'")
->check('code', 'unique', "deleted='0'")
->exec();
@@ -342,15 +357,16 @@ class programModel extends model
$oldProgram = $this->dao->findById($programID)->from(TABLE_PROJECT)->fetch();
$program = fixer::input('post')
->setDefault('team', $this->post->name)
->setDefault('end', '')
->setDefault('isCat', 0)
->setIF($this->post->begin == '0000-00-00', 'begin', '')
->setIF($this->post->end == '0000-00-00', 'end', '')
->setIF($this->post->acl != 'custom', 'whitelist', '')
->setIF($this->post->acl == 'custom' and !isset($_POST['whitelist']), 'whitelist', '')
->setDefault('team', $this->post->name)
->setDefault('isCat', 0)
->join('whitelist', ',')
->stripTags($this->config->program->editor->edit['id'], $this->config->allowedTags)
->remove('products, branch, uid, plans')
->remove('products, branch, uid, plans, longTime')
->get();
$program = $this->loadModel('file')->processImgURL($program, $this->config->program->editor->edit['id'], $this->post->uid);
@@ -360,23 +376,33 @@ class programModel extends model
if(!empty($program->isCat))
{
$minChildBegin = $this->dao->select('min(begin) as minBegin')->from(TABLE_PROJECT)->where('id')->ne($programID)->andWhere('deleted')->eq(0)->andWhere('path')->like("%,{$programID},%")->fetch('minBegin');
$maxChildEnd = $this->dao->select('max(end) as maxEnd')->from(TABLE_PROJECT)->where('id')->ne($programID)->andWhere('deleted')->eq(0)->andWhere('path')->like("%,{$programID},%")->fetch('maxEnd');
$maxChildEnd = $this->dao->select('max(end) as maxEnd')->from(TABLE_PROJECT)->where('id')->ne($programID)->andWhere('deleted')->eq(0)->andWhere('path')->like("%,{$programID},%")->andWhere('end')->ne('0000-00-00')->fetch('maxEnd');
if($minChildBegin and $program->begin > $minChildBegin) dao::$errors['begin'] = sprintf($this->lang->program->beginGreateChild, $minChildBegin);
if($maxChildEnd and $program->end < $maxChildEnd) dao::$errors['end'] = sprintf($this->lang->program->endLetterChild, $maxChildEnd);
$longTimeCount = $this->dao->select('count(*) as count')->from(TABLE_PROJECT)->where('id')->ne($programID)->andWhere('deleted')->eq(0)->andWhere('path')->like("%,{$programID},%")->andWhere('end')->eq('0000-00-00')->fetch('count');
if(!empty($program->end) and $longTimeCount != 0) dao::$errors['end'] = $this->lang->program->childLongTime;
}
if($program->parent)
{
$parentProgram = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($program->parent)->fetch();
if($parentProgram and $program->begin < $parentProgram->begin) dao::$errors['begin'] = sprintf($this->lang->program->beginLetterParent, $parentProgram->begin);
if($parentProgram and $program->end > $parentProgram->end) dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $parentProgram->end);
if($parentProgram)
{
if($program->begin < $parentProgram->begin) dao::$errors['begin'] = sprintf($this->lang->program->beginLetterParent, $parentProgram->begin);
if($parentProgram->end != '0000-00-00' and $program->end > $parentProgram->end) dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $parentProgram->end);
if(empty($program->end) and $this->post->longTime and $parentProgram->end != '0000-00-00') dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $parentProgram->end);
}
}
if(dao::isError()) return false;
$requiredFields = $this->config->program->edit->requiredFields;
if($this->post->longTime) $requiredFields = trim(str_replace(',end,', ',', ",{$requiredFields},"), ',');
$this->dao->update(TABLE_PROJECT)->data($program)
->autoCheck($skipFields = 'begin,end')
->batchcheck($this->config->program->edit->requiredFields, 'notempty')
->batchcheck($requiredFields, 'notempty')
->checkIF($program->begin != '', 'begin', 'date')
->checkIF($program->end != '', 'end', 'date')
->checkIF($program->end != '', 'end', 'gt', $program->begin)
@@ -446,6 +472,13 @@ class programModel extends model
if(empty($program)) return true;
if($program->isCat and $action == 'group') return false;
if($program->isCat and $action == 'managemembers') return false;
if($program->isCat and $action == 'start') return false;
if($program->isCat and $action == 'activate') return false;
if($program->isCat and $action == 'suspend') return false;
if($program->isCat and $action == 'close') return false;
if($action == 'start') return $program->status == 'wait' or $program->status == 'suspended';
if($action == 'finish') return $program->status == 'wait' or $program->status == 'doing';
if($action == 'close') return $program->status != 'closed';
@@ -465,23 +498,8 @@ class programModel extends model
public function checkHasContent($programID)
{
$count = 0;
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_BUDGET)->where('program')->eq($programID)->fetch('count');
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_BUG)->where('program')->eq($programID)->fetch('count');
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_CASE)->where('program')->eq($programID)->fetch('count');
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_DESIGN)->where('program')->eq($programID)->fetch('count');
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_DOC)->where('program')->eq($programID)->fetch('count');
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_DURATIONESTIMATION)->where('program')->eq($programID)->fetch('count');
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_ISSUE)->where('program')->eq($programID)->fetch('count');
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_PROJECT)->where('program')->eq($programID)->fetch('count');
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_RELATION)->where('program')->eq($programID)->fetch('count');
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_RELEASE)->where('program')->eq($programID)->fetch('count');
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_REPO)->where('program')->eq($programID)->fetch('count');
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_RISK)->where('program')->eq($programID)->fetch('count');
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_STORY)->where('program')->eq($programID)->fetch('count');
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_TESTREPORT)->where('program')->eq($programID)->fetch('count');
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_TESTSUITE)->where('program')->eq($programID)->fetch('count');
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_TESTTASK)->where('program')->eq($programID)->fetch('count');
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_WORKESTIMATION)->where('program')->eq($programID)->fetch('count');
$count += (int)$this->dao->select('count(*) as count')->from(TABLE_TASK)->where('program')->eq($programID)->fetch('count');
return $count > 0;
}
+3 -2
View File
@@ -49,9 +49,10 @@ foreach($programs as $program)
?>
</div>
<div class="col-footer">
<?php echo html::a(helper::createLink('program', 'createGuide'), '<i class="icon icon-plus"></i>' . $lang->program->create, '', 'class="not-list-item text-primary" data-toggle=modal'); ?>
<div class='pull-right'>
<div class='pull-left'>
<?php echo html::a(helper::createLink('program', 'browse', 'status=all'), '<i class="icon icon-cards-view muted"></i> ' . $lang->project->all, '', 'class="not-list-item"'); ?>
</div>
<div class='pull-right'>
<span class='text-muted muted'> &nbsp; | &nbsp; </span>
<a class='toggle-right-col not-list-item'><?php echo $lang->project->doneProjects?><i class='icon icon-angle-right'></i></a>
</div>
+26 -6
View File
@@ -1,6 +1,6 @@
<?php $canOrder = (common::hasPriv('program', 'updateOrder') and strpos($orderBy, 'order') !== false)?>
<form class='main-table' id='programForm' method='post' data-ride='table'>
<table class='table has-sort-head table-fixed' id='programList'>
<form class='main-table' id='programForm' method='post' data-ride='table' data-nested='true' data-expand-nest-child='false' data-checkable='false'>
<table class='table has-sort-head table-fixed table-nested' id='programList'>
<?php $vars = "status=$status&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
<thead>
<tr>
@@ -8,7 +8,7 @@
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
</th>
<th class='w-100px'><?php common::printOrderLink('code', $orderBy, $vars, $lang->program->code);?></th>
<th><?php common::printOrderLink('name', $orderBy, $vars, $lang->program->name);?></th>
<th class='table-nest-title'><?php common::printOrderLink('name', $orderBy, $vars, $lang->program->name);?></th>
<th class='w-80px'><?php common::printOrderLink('status', $orderBy, $vars, $lang->program->status);?></th>
<th class='w-100px'><?php common::printOrderLink('begin', $orderBy, $vars, $lang->program->begin);?></th>
<th class='w-100px'><?php common::printOrderLink('end', $orderBy, $vars, $lang->program->end);?></th>
@@ -22,13 +22,33 @@
</thead>
<tbody class='sortable' id='programTableList'>
<?php foreach($programs as $program):?>
<tr data-id='<?php echo $program->id ?>' data-order='<?php echo $program->order ?>'>
<?php
$trClass = '';
$trAttrs = "data-id='$program->id' data-order=$program->order";
if($program->isCat)
{
$trAttrs .= " data-nested='true'";
if($program->parent == '0') $trClass .= ' is-top-level table-nest-child-hide';
else $trClass .= ' is-top-level table-nest-hide';
}
if($program->parent)
{
if(!$program->isCat) $trClass .= ' is-nest-child';
$trClass .= ' table-nest-hide';
$trAttrs .= " data-nest-parent='$program->parent' data-nest-path='$program->path'";
}
else if(!$program->isCat) $trClass .= ' no-nest';
$trAttrs .= " class='$trClass'";
?>
<tr <?php echo $trAttrs;?>>
<td class='c-id'>
<?php printf('%03d', $program->id);?>
</td>
<td class='text-left'><?php echo $program->code;?></td>
<td class='text-left pgm-title' title='<?php echo $program->name?>'>
<?php echo html::a($this->createLink('program', 'index', "programID=$program->id", '', '', $program->id), $program->name);?>
<td class='text-left pgm-title table-nest-title' title='<?php echo $program->name?>'>
<span class="table-nest-icon icon<?php if($program->isCat) echo ' table-nest-toggle' ?>"></span>
<?php echo $program->isCat ? $program->name : html::a($this->createLink('program', 'index', "programID=$program->id", '', '', $program->id), $program->name);?>
</td>
<td class='c-status'><span class="status-program status-<?php echo $program->status?>"><?php echo zget($lang->project->statusList, $program->status, '');?></span></td>
<td class='text-center'><?php echo $program->begin;?></td>
+9 -1
View File
@@ -91,9 +91,17 @@
<?php echo html::input('begin', date('Y-m-d'), "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->program->begin . "' required");?>
<span class='input-group-addon'><?php echo $lang->program->to;?></span>
<?php echo html::input('end', '', "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->program->end . "' required");?>
<?php if(empty($parentProgram) or $parentProgram->end == '0000-00-00'):?>
<span class='input-group-addon hidden' id='longTimeBox'>
<div class="checkbox-primary">
<input type="checkbox" name="longTime" value="1" id="longTime">
<label for="longTime"><?php echo $lang->program->longTime;?></label>
</div>
</span>
<?php endif;?>
</div>
</td>
<td class='muted'><?php if($parentProgram) printf($lang->program->parentBeginEnd, $parentProgram->begin, $parentProgram->end);?></td>
<td class='muted'><?php if($parentProgram) printf($lang->program->parentBeginEnd, $parentProgram->begin, $parentProgram->end == '0000-00-00' ? '' : $parentProgram->end);?></td>
</tr>
<?php if($template == 'scrum'):?>
<tr>
-2
View File
@@ -19,7 +19,6 @@
<img class='program-type-img' data-type='scrum' src='<?php echo $config->webRoot . 'theme/default/images/main/scrum.png'?>'>
<h3><?php echo $lang->program->scrum; ?></h3>
<p><?php echo $lang->program->scrumTitle; ?></p>
<p class='text-left'><?php echo $lang->program->scrumDesc; ?></p>
</div>
</div>
<div class='col-xs-6'>
@@ -27,7 +26,6 @@
<img class='program-type-img' data-type='cmmi' src='<?php echo $config->webRoot . 'theme/default/images/main/cmmi.png'?>'>
<h3><?php echo $lang->program->cmmi; ?></h3>
<p><?php echo $lang->program->cmmiTitle; ?></p>
<p class='text-left'><?php echo $lang->program->cmmiDesc; ?></p>
</div>
</div>
</div>
+7 -1
View File
@@ -60,7 +60,13 @@
<div class='input-group'>
<?php echo html::input('begin', $program->begin, "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->program->begin . "' required");?>
<span class='input-group-addon'><?php echo $lang->program->to;?></span>
<?php echo html::input('end', $program->end, "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->program->end . "' required");?>
<?php echo html::input('end', $program->end == '0000-00-00' ? '' : $program->end, "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->program->end . "' required");?>
<span class='input-group-addon hidden' id='longTimeBox'>
<div class="checkbox-primary">
<input type="checkbox" name="longTime" value="1" id="longTime" <?php if($program->end == '0000-00-00') echo "checked";?>>
<label for="longTime"><?php echo $lang->program->longTime;?></label>
</div>
</span>
</div>
</td>
<td colspan='2'></td>
+45 -28
View File
@@ -63,7 +63,7 @@ class projectModel extends model
public function setMenu($projects, $projectID, $buildID = 0, $extra = '')
{
$program = $this->getByID($this->session->program);
if(empty($projects))
if(empty($projects))
{
if($program->template == 'cmmi')
{
@@ -139,26 +139,26 @@ class projectModel extends model
common::setMenuVars($this->lang->project->menu, $key, $projectID);
if(isset($this->lang->project->subMenu->$key))
{
{
$projectSubMenu = $this->lang->project->subMenu->$key;
$subMenu = common::createSubMenu($this->lang->project->subMenu->$key, $projectID);
if(!empty($subMenu))
{
{
foreach($subMenu as $menuKey => $menu)
{
$itemMenu = zget($projectSubMenu, $menuKey, '');
{
$itemMenu = zget($projectSubMenu, $menuKey, '');
$isActive['method'] = ($moduleName == strtolower($menu->link['module']) and $methodName == strtolower($menu->link['method']));
$isActive['alias'] = ($moduleName == strtolower($menu->link['module']) and (is_array($itemMenu) and isset($itemMenu['alias']) and strpos($itemMenu['alias'], $methodName) !== false));
$isActive['subModule'] = (is_array($itemMenu) and isset($itemMenu['subModule']) and strpos($itemMenu['subModule'], $moduleName) !== false);
if($isActive['method'] or $isActive['alias'] or $isActive['subModule'])
{
{
$this->lang->project->menu->{$key}['link'] = $menu->text . "|" . join('|', $menu->link);
break;
}
}
}
}
$this->lang->project->menu->{$key}['subMenu'] = $subMenu;
}
}
}
}
@@ -848,12 +848,12 @@ class projectModel extends model
/**
* Get projects by program.
*
* @param int $program
* @param object $program
* @access public
* @return array
*/
public function getProjectsByProgram($program)
{
{
$projects = $this->dao->select('t1.*, t3.name as productName')->from(TABLE_PROJECT)->alias('t1')
->leftJoin(TABLE_PROJECTPRODUCT)->alias('t2')->on('t1.id = t2.project')
->leftJoin(TABLE_PRODUCT)->alias('t3')->on('t2.product = t3.id')
@@ -866,13 +866,13 @@ class projectModel extends model
if($program->template == 'cmmi')
{
foreach($projects as $projectID => $project)
{
{
if($project->parent and isset($projects[$project->id]) and isset($projects[$project->parent])) $projects[$project->id]->name = $projects[$project->parent]->name . '/' . $project->name;
}
}
if($program->category == 'multiple')
{
{
foreach($projects as $projectID => $project) $projects[$projectID]->name = $project->productName . '/' . $project->name;
}
}
foreach($projects as $projectID => $project) unset($projects[$project->parent]);
}
@@ -1110,7 +1110,7 @@ class projectModel extends model
* @param int $projectID
* @param bool $setImgSize
* @access public
* @return void
* @return object
*/
public function getById($projectID, $setImgSize = false)
{
@@ -1865,10 +1865,10 @@ class projectModel extends model
/**
* Get team slice.
*
* @param array $teams
* @param string $begin
* @param string $end
*
* @param array $teams
* @param string $begin
* @param string $end
* @access public
* @return array
*/
@@ -2250,11 +2250,11 @@ class projectModel extends model
/**
* Get bugs by search in project.
*
* @param int $products
* @param int $projectID
* @param int $sql
* @param int $pager
* @param int $orderBy
* @param array $products
* @param int $projectID
* @param string $sql
* @param object $pager
* @param string $orderBy
* @access public
* @return mixed
*/
@@ -2499,9 +2499,9 @@ class projectModel extends model
/**
* Build bug search form.
*
* @param int $products
* @param int $queryID
* @param int $actionURL
* @param array $products
* @param int $queryID
* @param string $actionURL
* @access public
* @return void
*/
@@ -2886,6 +2886,23 @@ class projectModel extends model
return $chartData;
}
/**
* Gets the top-level project name.
*
* @access private
* @return void
*/
public function getProjectParentName($parentID = 0)
{
if($parentID == 0) return '';
static $parent;
$parent = $this->dao->select('id,parent,name')->from(TABLE_PROJECT)->where('id')->eq($parentID)->fetch();
if($parent->parent) $this->getProjectParentName($parent->parent);
return $parent->name;
}
/**
* Fill tasks in tree.
* @param object $tree
+6
View File
@@ -154,6 +154,12 @@ class repo extends control
die(js::confirm($this->lang->repo->notice->delete, $this->repo->createLink('delete', "repoID=$repoID&confirm=yes")));
}
$relationID = $this->dao->select('id')->from(TABLE_RELATION)->where('extra')->eq($repoID)->fetch();
if($relationID)
{
die(js::alert($this->lang->repo->error->deleted));
}
$this->dao->delete()->from(TABLE_REPO)->where('id')->eq($repoID)->exec();
$this->dao->delete()->from(TABLE_REPOHISTORY)->where('repo')->eq($repoID)->exec();
$this->dao->delete()->from(TABLE_REPOFILES)->where('repo')->eq($repoID)->exec();
+1
View File
@@ -159,6 +159,7 @@ $lang->repo->error->noPriv = 'The program does not have the privilege to
$lang->repo->error->output = "The command is: %s\nThe error is(%s): %s\n";
$lang->repo->error->clientVersion = "Client version is too low, please upgrade or change SVN client";
$lang->repo->error->encoding = "The encoding maybe wrong. Please change the encoding and try again.";
$lang->repo->error->deleted = "Deletion of the repository failed. The current repository has been committed in relation to the design";
$lang->repo->syncTips = '<strong>You may find the reference about how to set Git sync from <a target="_blank" href="https://www.zentao.pm/book/zentaomanual/free-open-source-project-management-software-git-105.html">here</a>.</strong>';
$lang->repo->encodingsTips = "The encodings of commit comments, can be comma separated values,e.g. utf-8";
+1
View File
@@ -159,6 +159,7 @@ $lang->repo->error->noPriv = 'The program does not have the privilege to
$lang->repo->error->output = "The command is: %s\nThe error is(%s): %s\n";
$lang->repo->error->clientVersion = "Client version is too low, please upgrade or change SVN client";
$lang->repo->error->encoding = "The encoding might be wrong. Please change the encoding and try again.";
$lang->repo->error->deleted = "Deletion of the repository failed. The current repository has been committed in relation to the design";
$lang->repo->syncTips = '<strong>You may find the reference about how to set Git sync from <a target="_blank" href="https://www.zentao.pm/book/zentaomanual/free-open-source-project-management-software-git-105.html">here</a>.</strong>';
$lang->repo->encodingsTips = "The encodings of comments can be comma separated values, e.g. utf-8.";
+1
View File
@@ -159,6 +159,7 @@ $lang->repo->error->noPriv = "Le programme n'a pas les privilèges pour b
$lang->repo->error->output = "La commande est: %s\nL'erreur est (%s): %s\n";
$lang->repo->error->clientVersion = "La version du client est trop ancienne, veuillez mettre à niveau ou changer le client SVN";
$lang->repo->error->encoding = "L'encodage est peut-être erroné. Veuillez modifier l'encodage et réessayer.";
$lang->repo->error->deleted = "Deletion of the repository failed. The current repository has been committed in relation to the design";
$lang->repo->syncTips = '<strong>Vous pouvez trouver la référence sur la façon de définir la synchronisation Git à partir de la page se trouvant <a target="_blank" href="https://www.zentao.pm/book/zentaomanual/free-open-source-project-management-software-git-105.html">ici</a>.</strong>';
$lang->repo->encodingsTips = "Les encodages des commentaires de validation peuvent être des valeurs séparées par des virgules,ex: utf-8";
+1
View File
@@ -159,6 +159,7 @@ $lang->repo->error->noPriv = 'The program does not have the privilege to
$lang->repo->error->output = "The command is: %s\nThe error is(%s): %s\n";
$lang->repo->error->clientVersion = "Client version is too low, please upgrade or change SVN client";
$lang->repo->error->encoding = "The encoding maybe wrong. Vui lòng change the encoding and try again.";
$lang->repo->error->deleted = "Deletion of the repository failed. The current repository has been committed in relation to the design";
$lang->repo->syncTips = '<strong>Bạn có thể tìm tham khảo làm sao thiết lập đồng bộ Git từ <a target="_blank" href="https://www.zentao.pm/book/zentaomanual/free-open-source-project-management-software-git-105.html">here</a>.</strong>';
$lang->repo->encodingsTips = "The encodings of commit comments, can be comma separated values,ví dụ: utf-8";
+1
View File
@@ -159,6 +159,7 @@ $lang->repo->error->noPriv = '程序没有权限切换到目录 %s';
$lang->repo->error->output = "执行命令:%s\n错误结果(%s): %s\n";
$lang->repo->error->clientVersion = "客户端版本过低,请升级或更换SVN客户端";
$lang->repo->error->encoding = "编码可能错误,请更换编码重试。";
$lang->repo->error->deleted = "删除版本库失败,当前版本库已与设计有相关提交";
$lang->repo->syncTips = '请参照<a target="_blank" href="https://www.zentao.net/book/zentaopmshelp/207.html">这里</a>,设置版本库定时同步。';
$lang->repo->encodingsTips = "提交日志的编码,可以用逗号连接起来的多个,比如utf-8。";
+11 -1
View File
@@ -1,4 +1,14 @@
<?php
/**
* The control file of risk 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 risk
* @version $Id: control.php 5107 2013-07-12 01:46:12Z chencongzhi520@gmail.com $
* @link http://www.zentao.net
*/
class risk extends control
{
/**
@@ -178,7 +188,7 @@ class risk extends control
public function delete($riskID, $confirm = 'no')
{
$risk = $this->risk->getById($riskID);
if($confirm == 'no')
{
echo js::confirm($this->lang->risk->confirmDelete, $this->createLink('risk', 'delete', "risk=$riskID&confirm=yes"), '');
+12
View File
@@ -1,4 +1,16 @@
<?php
/**
* The model file of risk 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 risk
* @version $Id: model.php 5079 2013-07-10 00:44:34Z chencongzhi520@gmail.com $
* @link http://www.zentao.net
*/
?>
<?php
class riskModel extends model
{
/**
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The activate of risk 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 risk
* @version $Id: activate.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';?>
<div id='mainContent' class='main-content'>
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The assignto of risk 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 risk
* @version $Id: assignto.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';?>
<div id='mainContent' class='main-content'>
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The batchcreate of risk 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 risk
* @version $Id: batchcreate.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="mainContent" class="main-content fade">
<div class="main-header">
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The browse of risk 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 risk
* @version $Id: browse.html.php 4903 2013-06-26 05:32:59Z wyd621@gmail.com $
* @link http://www.zentao.net
*/
?>
<?php include "../../common/view/header.html.php"?>
<style>
#querybox #searchform{border-bottom: 1px solid #ddd; margin-bottom: 20px;}
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The cancel of risk 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 risk
* @version $Id: cancel.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';?>
<div id='mainContent' class='main-content'>
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The close of risk 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 risk
* @version $Id: close.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';?>
<div id='mainContent' class='main-content'>
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The create of risk 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 risk
* @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';?>
<div id="mainContent" class="main-content fade">
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The edit of risk 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 risk
* @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';?>
<div id="mainContent" class="main-content fade">
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The hangup of risk 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 risk
* @version $Id: hangup.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';?>
<div id='mainContent' class='main-content'>
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The track of risk 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 risk
* @version $Id: track.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';?>
<div id="mainContent" class="main-content fade">
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The view of risk 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 view
* @version $Id: track.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 $browseLink = $app->session->riskList != false ? $app->session->riskList : $this->createLink('risk', 'browse');?>
+55 -5
View File
@@ -1,6 +1,23 @@
<?php
/**
* The control file of stage 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 stage
* @version $Id: control.php 5107 2013-07-12 01:46:12Z chencongzhi520@gmail.com $
* @link http://www.zentao.net
*/
class stage extends control
{
/**
* Browse designs
*
* @param string $orderBy
* @access public
* @return void
*/
public function browse($orderBy = "id_desc")
{
$this->view->stages = $this->stage->getStages($orderBy);
@@ -12,11 +29,17 @@ class stage extends control
$this->display();
}
/**
* Create a stage
*
* @access public
* @return void
*/
public function create()
{
if($_POST)
{
$stageID = $this->stage->create();
$stageID = $this->stage->create();
$response['result'] = 'success';
$response['message'] = $this->lang->saveSuccess;
@@ -39,11 +62,17 @@ class stage extends control
$this->display();
}
/**
* Batch create
*
* @access public
* @return void
*/
public function batchCreate()
{
if($_POST)
{
$this->stage->batchCreate();
$this->stage->batchCreate();
$response['result'] = 'success';
$response['message'] = $this->lang->saveSuccess;
@@ -65,12 +94,19 @@ class stage extends control
$this->display();
}
/**
* Edit a stage
*
* @param int $stageID
* @access public
* @return void
*/
public function edit($stageID = 0)
{
$stage = $this->stage->getByID($stageID);
if($_POST)
{
$changes = $this->stage->update($stageID);
$changes = $this->stage->update($stageID);
$response['result'] = 'success';
$response['message'] = $this->lang->saveSuccess;
@@ -95,6 +131,12 @@ class stage extends control
$this->display();
}
/**
* Set type
*
* @access public
* @return void
*/
public function setType()
{
$this->loadModel('custom');
@@ -103,9 +145,9 @@ class stage extends control
$data = fixer::input('post')->get();
$this->custom->deleteItems("lang=all&module=stage&section=typeList");
foreach($data->keys as $index => $key)
{
{
$value = $data->values[$index];
if(!$value or !$key) continue;
if(!$value or !$key) continue;
$this->custom->setItem("all.stage.typeList.{$key}", $value);
}
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('stage', 'settype')));
@@ -117,6 +159,14 @@ class stage extends control
$this->display();
}
/**
* Delete a stage
*
* @param int $stageID
* @param string $confirm
* @access public
* @return void
*/
public function delete($stageID, $confirm = 'no')
{
$stage = $this->stage->getById($stageID);
+10
View File
@@ -1,4 +1,14 @@
<?php
/**
* The stage module English file 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 stage
* @version $Id: en.php 4729 2013-05-03 07:53:55Z chencongzhi520@gmail.com $
* @link http://www.zentao.net
*/
/* Actions. */
$lang->stage->browse = 'Stage List';
$lang->stage->create = 'Create Stage';
+10
View File
@@ -1,4 +1,14 @@
<?php
/**
* The stage module zh-cn file 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 stage
* @version $Id: zh-cn.php 4729 2013-05-03 07:53:55Z chencongzhi520@gmail.com $
* @link http://www.zentao.net
*/
/* Actions. */
$lang->stage->browse = '浏览列表';
$lang->stage->create = '新建';
+53 -2
View File
@@ -1,6 +1,24 @@
<?php
/**
* The model file of stage 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 stage
* @version $Id: model.php 5079 2013-07-10 00:44:34Z chencongzhi520@gmail.com $
* @link http://www.zentao.net
*/
?>
<?php
class stageModel extends model
{
/**
* Create a stage
*
* @access public
* @return int|bool
*/
public function create()
{
$stage = fixer::input('post')
@@ -14,14 +32,20 @@ class stageModel extends model
return false;
}
/**
* Batch create
*
* @access public
* @return bool
*/
public function batchCreate()
{
$data = fixer::input('post')->get();
$data = fixer::input('post')->get();
$this->loadModel('action');
foreach($data->name as $i => $name)
{
if(!$name) continue;
if(!$name) continue;
$stage = new stdclass();
$stage->name = $name;
@@ -39,6 +63,13 @@ class stageModel extends model
return true;
}
/**
* Update a stage
*
* @param int $stageID
* @access public
* @return bool
*/
public function update($stageID)
{
$oldStage = $this->dao->select('*')->from(TABLE_STAGE)->where('id')->eq((int)$stageID)->fetch();
@@ -54,11 +85,24 @@ class stageModel extends model
return false;
}
/**
* Get stages
*
* @param string $orderBy
* @access public
* @return array
*/
public function getStages($orderBy = 'id_desc')
{
return $this->dao->select('*')->from(TABLE_STAGE)->where('deleted')->eq(0)->orderBy($orderBy)->fetchAll('id');
}
/**
* Get pairs
*
* @access public
* @return array
*/
public function getPairs()
{
$stages = $this->getStages();
@@ -72,6 +116,13 @@ class stageModel extends model
return $pairs;
}
/**
* Get by id
*
* @param int $stageID
* @access public
* @return object
*/
public function getByID($stageID)
{
return $this->dao->select('*')->from(TABLE_STAGE)->where('deleted')->eq(0)->andWhere('id')->eq((int)$stageID)->fetch();
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The batchCreate view of stage 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 stage
* @version $Id: batchCreate.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="mainContent" class="main-content fade">
<div class="main-header">
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The browse view of stage 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 stage
* @version $Id: browse.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-toobar pull-left">
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The create view of stage 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 stage
* @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';?>
<div id="mainContent" class="main-content fade">
<div class="center-block">
+12
View File
@@ -1,3 +1,15 @@
<?php
/**
* The edit view of stage 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 stage
* @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';?>
<div id="mainContent" class="main-content fade">
<div class="center-block">

Some files were not shown because too many files have changed in this diff Show More