Merge branch 'master' into 'master_xieqiyu_67691'

# Conflicts:
#   db/update17.6.sql
This commit is contained in:
王怡栋
2022-09-08 01:38:22 +00:00
14 changed files with 178 additions and 76 deletions
+1
View File
@@ -14,3 +14,4 @@ CREATE TABLE `zt_taskteam` (
ALTER TABLE `zt_taskestimate` ADD `order` tinyint unsigned NULL DEFAULT '0';
ALTER TABLE `zt_effort` ADD `order` tinyint unsigned NOT NULL DEFAULT '0' AFTER `end`;
ALTER TABLE `zt_storyspec` ADD `files` text NOT NULL AFTER `verify`;
ALTER TABLE `zt_block` CHANGE `block` `block` varchar(30) COLLATE 'utf8_general_ci' NOT NULL AFTER `source`;
+1 -1
View File
@@ -218,7 +218,7 @@ CREATE TABLE IF NOT EXISTS `zt_block` (
`type` char(30) NOT NULL,
`title` varchar(100) NOT NULL,
`source` varchar(20) NOT NULL,
`block` varchar(20) NOT NULL,
`block` varchar(30) NOT NULL,
`params` text NOT NULL,
`order` tinyint(3) unsigned NOT NULL DEFAULT '0',
`grid` tinyint(3) unsigned NOT NULL DEFAULT '0',
+28 -4
View File
@@ -935,8 +935,9 @@ class block extends control
$current = zget($weeks, $monday, '');
$current = substr($current, 0, -11) . substr($current, -6);
$project->pv = $this->weekly->getPV($projectID, $today);
$project->ev = $this->weekly->getEV($projectID, $today);
$PVEV = $this->weekly->getPVEV($projectID, $today);
$project->pv = $PVEV['PV'];
$project->ev = $PVEV['EV'];
$project->ac = $this->weekly->getAC($projectID, $today);
$project->sv = $this->weekly->getSV($project->ev, $project->pv);
$project->cv = $this->weekly->getCV($project->ev, $project->ac);
@@ -1200,8 +1201,9 @@ class block extends control
$this->weekly->save($this->session->project, $date);
$this->view->pv = (float)$this->weekly->getPV($this->session->project, $today);
$this->view->ev = (float)$this->weekly->getEV($this->session->project, $today);
$PVEV = $this->weekly->getPVEV($this->session->project, $today);
$this->view->pv = (float)$PVEV['PV'];
$this->view->ev = (float)$PVEV['EV'];
$this->view->ac = (float)$this->weekly->getAC($this->session->project, $today);
$this->view->sv = $this->weekly->getSV($this->view->ev, $this->view->pv);
$this->view->cv = $this->weekly->getCV($this->view->ev, $this->view->ac);
@@ -1210,6 +1212,28 @@ class block extends control
$this->view->progress = !empty($this->view->pv) ? floor($this->view->ac / $this->view->pv * 1000) / 1000 * 100 : 0;
}
/**
* Print waterfall general report block.
*
* @access public
* @return void
*/
public function printWaterfallGeneralReportBlock()
{
$this->app->loadLang('programplan');
$this->loadModel('project');
$this->loadModel('weekly');
$PVEV = $this->project->getWaterfallPVEV($this->session->project);
$this->view->pv = (float)$PVEV['PV'];
$this->view->ev = (float)$PVEV['EV'];
$this->view->ac = (float)$this->project->getWaterfallAC($this->session->project);
$this->view->sv = $this->weekly->getSV($this->view->ev, $this->view->pv);
$this->view->cv = $this->weekly->getCV($this->view->ev, $this->view->ac);
$this->view->progress = !empty($this->view->pv) ? floor($this->view->ac / $this->view->pv * 1000) / 1000 * 100 : 0;
}
/**
* Print waterfall gantt block.
*
+13 -2
View File
@@ -656,18 +656,29 @@ class blockModel extends model
* Get waterfall project report pararms.
*
* @access public
* @return string
* @return bool
*/
public function getWaterfallReportParams()
{
return false;
}
/**
* Get waterfall general report params.
*
* @access public
* @return bool
*/
public function getWaterfallGeneralReportParams()
{
return false;
}
/**
* Get project estimate pararms.
*
* @access public
* @return string
* @return bool
*/
public function getWaterfallEstimateParams()
{
@@ -0,0 +1,54 @@
<style>
.block-waterfallgeneralreport .col-left {width: 25%; text-align: center;}
.block-waterfallgeneralreport .col-right {width: 87%;}
.block-waterfallgeneralreport .panel-body {padding-top: 0;}
.block-waterfallgeneralreport .table-row {margin-bottom: 20px;}
<?php if(common::checkNotCN()):?>
.block-waterfallgeneralreport .stage {position: absolute; top: 14px; left: 140px;}
<?php else:?>
.block-waterfallgeneralreport .stage {position: absolute; top: 14px; left: 90px;}
<?php endif;?>
.block-waterfallgeneralreport .col-right .tiles {padding: 10px 0 0 16px;}
.block-waterfallgeneralreport .col-right .tile {width: 20%;}
.block-waterfallgeneralreport .col-right .tile .tile-title {font-weight: 700;}
.block-waterfallgeneralreport .progress {position: absolute; left: 45px; top: 90px; right: 40px;}
.block-waterfallgeneralreport .progress-num {font-size: 20px; font-weight: 700;}
.block-waterfallgeneralreport .col-right .tile-amount {font-size: 20px;}
</style>
<div class="panel-body conatiner-fluid">
<div class='table-row'>
<div class="col col-left hide-in-sm">
<h4><?php echo $lang->project->progress;?></h4>
<span class='progress-num'><?php echo $progress . '%';?></span>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="<?php echo $progress;?>" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $progress;?>%">
</div>
</div>
</div>
<div class='col-right'>
<div class='row tiles'>
<div class="col tile">
<div class="tile-title"><?php echo 'PV(' . $lang->programplan->end . ')';?></div>
<div class="tile-amount"><?php echo $pv == 0 ? 0 : $pv;?></div>
</div>
<div class="col tile">
<div class="tile-title"><?php echo 'EV(' . $lang->programplan->realEnd . ')';?></div>
<div class="tile-amount"><?php echo $ev == 0 ? 0 : $ev;?></div>
</div>
<div class="col tile">
<div class="tile-title"><?php echo 'AC(' . $lang->programplan->ac . ')';?></div>
<div class="tile-amount"><?php echo $ac == 0 ? 0 : $ac;?></div>
</div>
<div class="col tile">
<div class="tile-title"><?php echo 'SV(' . $lang->programplan->sv . ')';?></div>
<div class="tile-amount"><?php echo $sv . '%';?></div>
</div>
<div class="col tile">
<div class="tile-title"><?php echo 'CV(' . $lang->programplan->cv . ')';?></div>
<div class="tile-amount"><?php echo $cv . '%';?></div>
</div>
</div>
</div>
</div>
</div>
+1
View File
@@ -153,6 +153,7 @@ class my extends control
$riskCount = 0;
$reviewCount = 0;
$ncCount = 0;
$qaCount = 0;
$meetingCount = 0;
$isMax = $this->config->edition == 'max' ? 1 : 0;
+1 -1
View File
@@ -109,7 +109,7 @@ $config->product->all->search['fields']['createdDate'] = $lang->product->created
$config->product->all->search['fields']['createdBy'] = $lang->product->createdBy;
$config->product->all->search['params']['name'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
$config->product->all->search['params']['code'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
if(!isset($config->setCode) or $config->setCode == 1) $config->product->all->search['params']['code'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
$config->product->all->search['params']['id'] = array('operator' => '=', 'control' => 'input', 'values' => '');
if($config->systemMode == 'new') $config->product->all->search['params']['program'] = array('operator' => '=', 'control' => 'select', 'values' => '');
$config->product->all->search['params']['line'] = array('operator' => '=', 'control' => 'select', 'values' => '');
+49
View File
@@ -415,6 +415,55 @@ class projectModel extends model
return is_numeric($projectIDList) ? (empty($progressList) ? 0 : $progressList[$projectIDList]) : $progressList;
}
/**
* Get waterfall general PV and EV.
*
* @param int $projectID
* @access public
* @return array
*/
public function getWaterfallPVEV($projectID)
{
$executions = $this->dao->select('id,begin,end,realEnd,status')->from(TABLE_EXECUTION)->where('deleted')->eq(0)->andWhere('vision')->eq($this->config->vision)->andWhere('project')->eq($projectID)->fetchAll('id');
$stmt = $this->dao->select('id,status,estimate,consumed,`left`,closedReason')->from(TABLE_TASK)->where('execution')->in(array_keys($executions))->andWhere("parent")->ge(0)->andWhere("deleted")->eq(0)->query();
$PV = 0;
$EV = 0;
while($task = $stmt->fetch())
{
$PV += $task->estimate;
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 array('PV' => sprintf("%.2f", $PV), 'EV' => sprintf("%.2f", $EV));
}
/**
* Get waterfall general AC
*
* @param int $projectID
* @access public
* @return string
*/
public function getWaterfallAC($projectID)
{
$executions = $this->dao->select('id,begin,end,realEnd,status')->from(TABLE_EXECUTION)->where('deleted')->eq(0)->andWhere('vision')->eq($this->config->vision)->andWhere('project')->eq($projectID)->fetchAll('id');
$taskIdList = $this->dao->select('id')->from(TABLE_TASK)->where('execution')->in(array_keys($executions))->andWhere("parent")->ge(0)->andWhere("deleted")->eq(0)->fetchPairs('id', 'id');
$AC = $this->dao->select('sum(consumed) as consumed')->from(TABLE_EFFORT)->where('objectType')->eq('task')->andWhere('objectID')->in($taskIdList)->andWhere('deleted')->eq('0')->fetch('consumed');
if(is_null($AC)) $AC = 0;
return sprintf("%.2f", $AC);
}
/**
* Get project workhour info.
*
+1
View File
@@ -48,6 +48,7 @@ foreach($efforts as $effort)
</thead>
<tbody>
<?php foreach($allEfforts[$order] as $effort):?>
<?php if($effort->account != $this->app->user->account) continue;?>
<tr class="text-center">
<td><?php echo $effort->date;?></td>
<td><?php echo zget($users, $effort->account);?></td>
+3 -3
View File
@@ -74,10 +74,10 @@
<div class="alert with-icon">
<i class="icon-exclamation-sign"></i>
<div class="content">
<?php if($task->assignedTo != $app->user->account and $task->mode == 'linear'):?>
<p><?php echo sprintf($lang->task->deniedNotice, '<strong>' . $task->assignedToRealName . '</strong>', $lang->task->logEfforts);?></p>
<?php elseif(!isset($task->members[$app->user->account])):?>
<?php if(!isset($task->members[$app->user->account])):?>
<p><?php echo sprintf($lang->task->deniedNotice, '<strong>' . $lang->task->teamMember . '</strong>', $lang->task->logEfforts);?></p>
<?php elseif($task->assignedTo != $app->user->account and $task->mode == 'linear'):?>
<p><?php echo sprintf($lang->task->deniedNotice, '<strong>' . $task->assignedToRealName . '</strong>', $lang->task->logEfforts);?></p>
<?php endif;?>
</div>
</div>
+1 -1
View File
@@ -49,7 +49,7 @@ $lang->testreport->legendCase = 'CasTests associés';
$lang->testreport->legendLegacyBugs = 'Bugs Restants';
$lang->testreport->legendReport = 'Rapport';
$lang->testreport->legendComment = 'Résumé';
$lang->testreport->legendMore = 'Plus...';
$lang->testreport->legendMore = 'Plus';
$lang->testreport->date = 'Date';
$lang->testreport->bugSeverityGroups = 'Distribution Sévérité de Bug';
+1 -1
View File
@@ -7308,7 +7308,7 @@ class upgradeModel extends model
$this->dao->insert(TABLE_TASKTEAM)->data($oldTeam)->exec();
$this->dao->update(TABLE_TASKESTIMATE)->set('`order`')->eq($order)->where('task')->($oldTeam->task)->andWhere('account')->eq($oldTeam->account)->exec();
$this->dao->update(TABLE_TASKESTIMATE)->set('`order`')->eq($order)->where('task')->eq($oldTeam->task)->andWhere('account')->eq($oldTeam->account)->exec();
$this->dao->update(TABLE_EFFORT)->set('`order`')->eq($order)->where('objectType')->eq('task')->andWhere('objectID')->eq($oldTeam->task)->andWhere('account')->eq($oldTeam->account)->exec();
$order ++;
}
+3 -2
View File
@@ -54,8 +54,9 @@ class weekly extends control
$this->view->title = $this->lang->weekly->common;
$this->view->pv = $this->weekly->getPV($projectID, $date);
$this->view->ev = $this->weekly->getEV($projectID, $date);
$PVEV = $this->weekly->getPVEV($projectID, $date);
$this->view->pv = $PVEV['PV'];
$this->view->ev = $PVEV['EV'];
$this->view->ac = $this->weekly->getAC($projectID, $date);
$this->view->sv = $this->weekly->getSV($this->view->ev, $this->view->pv);
$this->view->cv = $this->weekly->getCV($this->view->ev, $this->view->ac);
+21 -61
View File
@@ -121,8 +121,9 @@ class weeklyModel extends model
->exec();
$report = new stdclass;
$report->pv = $this->getPV($project, $date);
$report->ev = $this->getEV($project, $date);
$PVEV = $this->getPVEV($project, $date);
$report->pv = $PVEV['PV'];
$report->ev = $PVEV['EV'];
$report->ac = $this->getAC($project, $date);
$report->sv = $this->getSV($report->ev, $report->pv);
$report->cv = $this->getCV($report->ev, $report->ac);
@@ -369,17 +370,17 @@ class weeklyModel extends model
}
/**
* GetPV
* Get PV and EV
*
* @param int $project
* @param string $date
* @access public
* @return int
* @return array
*/
public function getPV($projectID, $date = '')
public function getPVEV($projectID, $date = '')
{
$report = $this->getFromDB($projectID, $date);
if(!empty($report)) return $report->pv;
if(!empty($report)) return array('PV' => $report->pv, 'EV' => $report->ev);
if(!$date) $date = date('Y-m-d');
$monday = $this->getThisMonday($date);
@@ -397,6 +398,8 @@ class weeklyModel extends model
->fetchAll('id');
$PV = 0;
$EV = 0;
$this->loadModel('holiday');
foreach($tasks as $task)
{
if(helper::isZeroDate($task->estStarted)) $task->estStarted = date('Y-m-d', strtotime($task->openedDate));
@@ -407,74 +410,36 @@ class weeklyModel extends model
if(helper::isZeroDate($task->finishedDate)) $task->deadline = date('Y-m-d', strtotime($task->finishedDate));
}
$fullDays = $this->loadModel('holiday')->getActualWorkingDays($task->estStarted, $task->deadline);
$fullDays = $this->holiday->getActualWorkingDays($task->estStarted, $task->deadline);
if($task->estStarted < $monday and $task->deadline >= $nextMonday)
{
$weekActualDays = $workdays;
}
elseif($task->estStarted >= $monday and $task->estStarted < $nextMonday)
{
$weekActualDays = $this->loadModel('holiday')->getActualWorkingDays($task->estStarted, $task->deadline >= $nextMonday ? $sunday : $task->deadline);
$weekActualDays = $this->holiday->getActualWorkingDays($task->estStarted, $task->deadline >= $nextMonday ? $sunday : $task->deadline);
}
elseif($task->deadline >= $monday and $task->deadline < $nextMonday)
{
$weekActualDays = $this->loadModel('holiday')->getActualWorkingDays($monday, $task->deadline);
$weekActualDays = $this->holiday->getActualWorkingDays($monday, $task->deadline);
}
if(empty($fullDays) or empty($weekActualDays) or empty($task->estimate)) continue;
$PV += round(count($weekActualDays) / count($fullDays) * $task->estimate, 2);
}
$thisPV = round(count($weekActualDays) / count($fullDays) * $task->estimate, 2);
return sprintf("%.2f",$PV);
}
/**
* Get EV data.
*
* @param int $projectID
* @param string $date
* @access public
* @return int
*/
public function getEV($projectID, $date = '')
{
$report = $this->getFromDB($projectID, $date);
if(!empty($report)) return $report->ev;
$executions = $this->loadModel('execution')->getList($projectID);
$executionIdList = array_keys($executions);
if(!$date) $date = date('Y-m-d');
$monday = $this->getThisMonday($date);
$sunday = $this->getThisSunday($date);
$lastDay = $this->getLastDay($date);
$nextMonday = date('Y-m-d', strtotime($sunday) + 24 * 3600);
$tasks = $this->dao->select('*')
->from(TABLE_TASK)
->where('execution')->in($executionIdList)
->andWhere('consumed')->gt(0)
->andWhere("((estStarted >= '$monday' AND estStarted < '$nextMonday') OR (deadline >= '$monday' AND deadline < '$nextMonday') OR (estStarted < '$monday' AND deadline > '$nextMonday'))")
->andWhere("parent")->ge(0)
->andWhere("deleted")->eq(0)
->andWhere('status')->ne('cancel')
->query();
$EV = 0;
foreach($tasks as $task)
{
if($task->status == 'done' or $task->closedReason == 'done')
{
$EV += $task->estimate;
$EV += $thisPV;
}
else
{
$task->progress = round($task->consumed / ($task->consumed + $task->left), 2) * 100;
$EV += $task->estimate * $task->progress / 100;
$EV += round($thisPV * $task->progress / 100, 2);
}
$PV += $thisPV;
}
return sprintf("%.2f", $EV);
return array('PV' => sprintf("%.2f", $PV), 'EV' => sprintf("%.2f", $EV));
}
/**
@@ -492,15 +457,10 @@ class weeklyModel extends model
if(!$date) $date = date('Y-m-d');
$monday = $this->getThisMonday($date);
$nextMonday = date('Y-m-d', strtotime($monday) + (7 * 24 * 3600));
$executions = $this->dao->select('id,begin,end,realEnd,status')->from(TABLE_EXECUTION)->where('deleted')->eq(0)->andWhere('vision')->eq($this->config->vision)->andWhere('project')->eq($project)->fetchAll('id');
$executionIdList = array_keys($executions);
$taskIdList = $this->dao->select('id')->from(TABLE_TASK)
->where('execution')->in($executionIdList)
->andWhere("parent")->ge(0)
->andWhere("deleted")->eq(0)
->fetchPairs();
$monday = $this->getThisMonday($date);
$nextMonday = date('Y-m-d', strtotime($monday) + (7 * 24 * 3600));
$executions = $this->dao->select('id,begin,end,realEnd,status')->from(TABLE_EXECUTION)->where('deleted')->eq(0)->andWhere('vision')->eq($this->config->vision)->andWhere('project')->eq($project)->fetchAll('id');
$taskIdList = $this->dao->select('id')->from(TABLE_TASK)->where('execution')->in(array_keys($executions))->andWhere("parent")->ge(0)->andWhere("deleted")->eq(0)->fetchPairs();
$AC = $this->dao->select('sum(consumed) as consumed')
->from(TABLE_EFFORT)