Merge branch 'sprint/181_liumengyi_fixbug' into 'master'
* Modify plan status flow judgment method. See merge request easycorp/zentaopms!1180
This commit is contained in:
@@ -295,6 +295,7 @@ class productplan extends control
|
||||
$this->view->plans = $this->productplan->getList($productID, $branch, $browseType, $pager, $sort);
|
||||
$this->view->pager = $pager;
|
||||
$this->view->projects = $this->product->getProjectPairsByProduct($productID, $branch);
|
||||
$this->view->statusList = $this->lang->productplan->featureBar['browse'];
|
||||
$this->display();
|
||||
}
|
||||
|
||||
@@ -400,7 +401,7 @@ class productplan extends control
|
||||
else
|
||||
{
|
||||
$changes = $this->productplan->updateStatus($planID, 'doing');
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
|
||||
$actionID = $this->loadModel('action')->create('productplan', $planID, 'started');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
@@ -442,7 +443,7 @@ class productplan extends control
|
||||
else
|
||||
{
|
||||
$changes = $this->productplan->updateStatus($planID, 'done');
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
|
||||
$actionID = $this->loadModel('action')->create('productplan', $planID, 'finished');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
@@ -468,7 +469,7 @@ class productplan extends control
|
||||
else
|
||||
{
|
||||
$changes = $this->productplan->updateStatus($planID, 'closed');
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
|
||||
$actionID = $this->loadModel('action')->create('productplan', $planID, 'closed');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
@@ -494,7 +495,7 @@ class productplan extends control
|
||||
else
|
||||
{
|
||||
$changes = $this->productplan->updateStatus($planID, 'doing');
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
|
||||
$actionID = $this->loadModel('action')->create('productplan', $planID, 'activated');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
|
||||
@@ -26,6 +26,7 @@ td.c-branch {overflow: hidden; text-align: left !important; text-overflow: ellip
|
||||
|
||||
.c-title.has-child > .plan-name.has-suffix > a, .c-title.has-child > .plan-name.has-prefix > a {overflow:hidden; max-width: calc(100% - 70px);}
|
||||
.plan-name.has-suffix > a, .plan-name.has-prefix > a {overflow:hidden; max-width: calc(100% - 46px);}
|
||||
#productplanList .plan-name > .label.label-danger {margin-left:3px; }
|
||||
|
||||
.switchButton {background: #fff !important;}
|
||||
.panel-actions {position: relative; padding: 0 0; padding-top: 1px;}
|
||||
|
||||
@@ -25,5 +25,5 @@ ol, ul {padding-left: 20px;}
|
||||
.body-modal #mainMenu>.btn-toolbar {width: auto;}
|
||||
.body-modal #mainContent {min-height: 240px;}
|
||||
|
||||
.btn.disabled{color: #9e54ae; background-color: transparent; border-color:transparent;}
|
||||
#mainMenu .btn-link.disabled {color: #9e54ae; background: transparent; border-color:transparent;}
|
||||
#mainMenu .icon-checked, #mainMenu .icon-off, #mainMenu .icon-play, #mainMenu .icon-magic {margin-right: 3px;}
|
||||
|
||||
@@ -105,6 +105,8 @@ $lang->productplan->errorNoEnd = 'ID %s end time should not be empty.';
|
||||
$lang->productplan->beginGeEnd = 'ID %s begin time should not be >= end time.';
|
||||
$lang->productplan->beginLetterParent = "The start date of the parent plan: %s, the start date cannot be less than the start date of the parent plan.";
|
||||
$lang->productplan->endGreaterParent = "The completion date of the parent plan: %s, the completion date cannot be greater than the completion date of the parent plan.";
|
||||
$lang->productplan->beginGreaterChild = "The start date of the child plan: %s, the start date cannot be greater than the start date of the child plan.";
|
||||
$lang->productplan->endLetterChild = "The completion date of the child plan: %s, the completion date cannot be less than the completion date of the child plan.";
|
||||
$lang->productplan->noLinkedProject = "The current product has not been linked with a project. Please enter the list of the product to link or create a project.";
|
||||
$lang->productplan->enterProjectList = "Enter the list of the product";
|
||||
|
||||
|
||||
@@ -18,13 +18,12 @@ $lang->productplan->delete = "删除计划";
|
||||
$lang->productplan->start = "开始计划";
|
||||
$lang->productplan->finish = "完成计划";
|
||||
$lang->productplan->close = "关闭计划";
|
||||
$lang->productplan->activate = "激活计划";
|
||||
$lang->productplan->startAB = "开始";
|
||||
$lang->productplan->finishAB = "完成";
|
||||
$lang->productplan->closeAB = "关闭";
|
||||
$lang->productplan->activateAB = "激活";
|
||||
$lang->productplan->view = "计划详情";
|
||||
$lang->productplan->activate = "激活计划";
|
||||
$lang->productplan->view = "计划详情";
|
||||
$lang->productplan->bugSummary = "本页共 <strong>%s</strong> 个Bug";
|
||||
$lang->productplan->basicInfo = '基本信息';
|
||||
$lang->productplan->batchEdit = '批量编辑';
|
||||
@@ -106,6 +105,8 @@ $lang->productplan->errorNoEnd = 'ID %s 结束时间不能为空';
|
||||
$lang->productplan->beginGeEnd = 'ID %s 开始时间不能大于结束时间';
|
||||
$lang->productplan->beginLetterParent = "父计划的开始日期:%s,开始日期不能小于父计划的开始日期";
|
||||
$lang->productplan->endGreaterParent = "父计划的完成日期:%s,完成日期不能大于父计划的完成日期";
|
||||
$lang->productplan->beginGreaterChild = "子计划的开始日期:%s,开始日期不能大于子计划的开始日期";
|
||||
$lang->productplan->endLetterChild = "子计划的完成日期:%s,完成日期不能小于子计划的完成日期";
|
||||
$lang->productplan->noLinkedProject = "当前产品还未关联项目,请进入产品的项目列表关联或创建一个项目";
|
||||
$lang->productplan->enterProjectList = "进入产品的项目列表";
|
||||
|
||||
|
||||
@@ -499,9 +499,11 @@ class productplanModel extends model
|
||||
*/
|
||||
public function updateStatus($planID, $status = '')
|
||||
{
|
||||
$oldPlan = $this->dao->findByID((int)$planID)->from(TABLE_PRODUCTPLAN)->fetch();
|
||||
$planID = (int)$planID;
|
||||
$oldPlan = $this->getByID($planID);
|
||||
if($oldPlan->parent > 0) $parentPlan = $this->getByID($oldPlan->parent);
|
||||
|
||||
if($status == 'doing' and $_POST)
|
||||
if($status == 'doing' and !empty($_POST))
|
||||
{
|
||||
$plan = fixer::input('post')->add('status', $status)->get();
|
||||
|
||||
@@ -510,21 +512,65 @@ class productplanModel extends model
|
||||
->autoCheck()
|
||||
->batchCheck($this->config->productplan->start->requiredFields, 'notempty')
|
||||
->checkIF(!empty($_POST['begin']) && !empty($_POST['end']), 'end', 'ge', $plan->begin)
|
||||
->where('id')->eq((int)$planID)
|
||||
->where('id')->eq($planID)
|
||||
->beginIF(isset($parentPlan))->orWhere('id')->eq($oldPlan->parent)->fi()
|
||||
->exec();
|
||||
}
|
||||
elseif($status == 'doing' and isset($parentPlan) and $parentPlan->status != 'doing')
|
||||
{
|
||||
$this->dao->update(TABLE_PRODUCTPLAN)
|
||||
->set('`status`')->eq($status)
|
||||
->where('id')->eq($planID)
|
||||
->orWhere('id')->eq($oldPlan->parent)
|
||||
->exec();
|
||||
}
|
||||
elseif($status == 'done' and isset($parentPlan))
|
||||
{
|
||||
$parentDone = true;
|
||||
$childPlans = $this->dao->select('*')->from(TABLE_PRODUCTPLAN)->where('parent')->eq($oldPlan->parent)->andWhere('deleted')->eq(0)->fetchAll();
|
||||
foreach($childPlans as $childPlan )
|
||||
{
|
||||
if(in_array($childPlan->status, array('wait', 'doing')) and $planID != $childPlan->id)
|
||||
{
|
||||
$parentDone = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->dao->update(TABLE_PRODUCTPLAN)
|
||||
->set('`status`')->eq($status)
|
||||
->where('id')->eq($planID)
|
||||
->beginIF($parentDone)->orWhere('id')->eq($oldPlan->parent)->fi()
|
||||
->exec();
|
||||
}
|
||||
elseif($status == 'closed' and isset($parentPlan))
|
||||
{
|
||||
$parentClosed = true;
|
||||
$childPlans = $this->dao->select('*')->from(TABLE_PRODUCTPLAN)->where('parent')->eq($oldPlan->parent)->andWhere('deleted')->eq(0)->fetchAll();
|
||||
foreach($childPlans as $childPlan)
|
||||
{
|
||||
if(in_array($childPlan->status, array('wait', 'doing', 'done')) and $planID != $childPlan->id)
|
||||
{
|
||||
$parentClosed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->dao->update(TABLE_PRODUCTPLAN)
|
||||
->set('`status`')->eq($status)
|
||||
->where('id')->eq($planID)
|
||||
->beginIF($parentClosed)->orWhere('id')->eq($oldPlan->parent)->fi()
|
||||
->exec();
|
||||
|
||||
if(dao::isError()) return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->dao->update(TABLE_PRODUCTPLAN)
|
||||
->set('`status`')->eq($status)
|
||||
->where('id')->eq((int)$planID)
|
||||
->where('id')->eq($planID)
|
||||
->exec();
|
||||
|
||||
$plan = $this->dao->findByID((int)$planID)->from(TABLE_PRODUCTPLAN)->fetch();
|
||||
}
|
||||
|
||||
if(dao::isError()) return false;
|
||||
|
||||
if(!isset($plan)) $plan = $this->getByID($planID);
|
||||
if(!dao::isError())return common::createChanges($oldPlan, $plan);
|
||||
}
|
||||
|
||||
@@ -589,6 +635,38 @@ class productplanModel extends model
|
||||
return $changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check date for plan.
|
||||
*
|
||||
* @param object $plan
|
||||
* @param string $begin
|
||||
* @param string $end
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function checkDate4Plan($plan, $begin, $end)
|
||||
{
|
||||
if($plan->parent == -1)
|
||||
{
|
||||
$childPlans = $this->dao->select('*')->from(TABLE_PRODUCTPLAN)->where('parent')->eq($plan->id)->andWhere('deleted')->eq(0)->fetchAll();
|
||||
$minBegin = $begin;
|
||||
$maxEnd = $end;
|
||||
foreach($childPlans as $childPlan)
|
||||
{
|
||||
if($childPlan->begin < $minBegin) $minBegin = $childPlan->begin;
|
||||
if($childPlan->end > $maxEnd) $maxEnd = $childPlan->end;
|
||||
}
|
||||
if($minBegin < $begin) dao::$errors['begin'] = sprintf($this->lang->beginGreaterChild, $minBegin);
|
||||
if($maxEnd > $end) dao::$errors['end'] = sprintf($this->lang->endLetterChild, $maxEnd);
|
||||
}
|
||||
elseif($plan->parent > 0)
|
||||
{
|
||||
$parentPlan = $this->getByID($plan->parent);
|
||||
if($begin < $parentPlan->begin) dao::$errors['begin'] = sprintf($this->lang->productplan->beginLetterParent, $parentPlan->begin);
|
||||
if($end > $parentPlan->end) dao::$errors['end'] = sprintf($this->lang->productplan->endGreaterParent, $parentPlan->end);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change parent field by planID.
|
||||
*
|
||||
@@ -788,4 +866,37 @@ class productplanModel extends model
|
||||
|
||||
return $plans;
|
||||
}
|
||||
|
||||
/**
|
||||
* Judge an action is clickable or not.
|
||||
*
|
||||
* @param object $plan
|
||||
* @param string $action
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public static function isClickable($plan, $action)
|
||||
{
|
||||
$action = strtolower($action);
|
||||
$clickable = commonModel::hasPriv('productplan', $action);
|
||||
if(!$clickable) return false;
|
||||
|
||||
switch($action)
|
||||
{
|
||||
case 'start' :
|
||||
if($plan->status != 'wait' or $plan->parent < 0) return false;
|
||||
break;
|
||||
case 'finish' :
|
||||
if($plan->status != 'doing' or $plan->parent < 0) return false;
|
||||
break;
|
||||
case 'close' :
|
||||
if($plan->status != 'done' or $plan->parent < 0) return false;
|
||||
break;
|
||||
case 'activate' :
|
||||
if($plan->status != 'closed' or $plan->parent < 0) return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
* @link https://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<style>
|
||||
.c-actions {width: 240px;}
|
||||
</style>
|
||||
<style> .c-actions {width: 240px;} </style>
|
||||
<div id="mainMenu" class="clearfix">
|
||||
<div class="btn-toolbar pull-left">
|
||||
<?php foreach(customModel::getFeatureMenu($this->moduleName, $this->methodName) as $menuItem):?>
|
||||
@@ -58,6 +56,9 @@
|
||||
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
|
||||
</th>
|
||||
<th class='c-title'><?php common::printOrderLink('title', $orderBy, $vars, $lang->productplan->title);?></th>
|
||||
<?php if($browseType == 'all'):?>
|
||||
<th><?php common::printOrderLink('status', $orderBy, $vars, $lang->productplan->status);?></th>
|
||||
<?php endif;?>
|
||||
<?php if($this->session->currentProductType != 'normal'):?>
|
||||
<th class='c-branch'><?php common::printOrderLink('branch',$orderBy, $vars, $lang->productplan->branch);?></th>
|
||||
<?php endif;?>
|
||||
@@ -119,6 +120,9 @@
|
||||
if(!empty($suffix)) echo $suffix . '</div>';
|
||||
?>
|
||||
</td>
|
||||
<?php if($browseType == 'all'):?>
|
||||
<td><?php echo zget($statusList, $plan->status)?></td>
|
||||
<?php endif;?>
|
||||
<?php if($this->session->currentProductType != 'normal'):?>
|
||||
<td class='c-branch' title='<?php echo $branchOption[$plan->branch];?>'><?php if($plan->parent != '-1') echo $branchOption[$plan->branch];?></td>
|
||||
<?php endif;?>
|
||||
@@ -135,22 +139,22 @@
|
||||
<?php foreach($extendFields as $extendField) echo "<td>" . $this->loadModel('flow')->getFieldValue($extendField, $plan) . "</td>";?>
|
||||
<td class='c-actions'>
|
||||
<?php
|
||||
$attr = "target='hiddenwin'";
|
||||
$isOnlyBody = false;
|
||||
$class = '';
|
||||
if($plan->begin == '2030-01-01' or $plan->end == '2030-01-01')
|
||||
if($plan->parent >= 0 )
|
||||
{
|
||||
$class = 'iframe';
|
||||
$attr = "data-toggle='modal' data-id='{$plan->id}' data-width='550px'";
|
||||
$isOnlyBody = true;
|
||||
$attr = "target='hiddenwin'";
|
||||
$isOnlyBody = false;
|
||||
$class = '';
|
||||
if($plan->begin == '2030-01-01' or $plan->end == '2030-01-01')
|
||||
{
|
||||
$class = 'iframe';
|
||||
$attr = "data-toggle='modal' data-id='{$plan->id}' data-width='550px'";
|
||||
$isOnlyBody = true;
|
||||
}
|
||||
common::printIcon('productplan', 'start', "planID=$plan->id", $plan, 'list', 'play', '', $class, $isOnlyBody, $attr, $lang->productplan->start);
|
||||
common::printIcon('productplan', 'finish', "planID=$plan->id", $plan, 'list', 'checked', '', $class, false, $attr, $lang->productplan->finish);
|
||||
common::printIcon('productplan', 'close', "planID=$plan->id", $plan, 'list', 'off', '', $class, false, $attr, $lang->productplan->close);
|
||||
}
|
||||
|
||||
$class = $plan->status == 'wait' ? $class : 'disabled';
|
||||
common::printLink('productplan', 'start', "planID=$plan->id", '<i class="icon-play"></i>', '', "class='btn {$class}'{$attr} title='{$lang->productplan->start}'", '', $isOnlyBody);
|
||||
$class = $plan->status == 'doing' ? '' : 'disabled';
|
||||
common::printLink('productplan', 'finish', "planID=$plan->id", '<i class="icon-checked"></i>', '', "class='btn {$class}' target='hiddenwin' title='{$lang->productplan->finish}'");
|
||||
$class = $plan->status == 'done' ? '' : 'disabled';
|
||||
common::printLink('productplan', 'close', "planID=$plan->id", '<i class="icon-off"></i>', '', "class='btn {$class}' target='hiddenwin' title='{$lang->productplan->close}'");
|
||||
$attr = $plan->expired ? "disabled='disabled'" : '';
|
||||
if(common::hasPriv('execution', 'create', $plan) and $plan->parent >= 0)
|
||||
{
|
||||
|
||||
@@ -42,25 +42,27 @@
|
||||
{
|
||||
echo $this->buildOperateMenu($plan, 'view');
|
||||
|
||||
$attr = "target='hiddenwin'";
|
||||
$isOnlyBody = false;
|
||||
$class = '';
|
||||
if($plan->begin == '2030-01-01' or $plan->end == '2030-01-01')
|
||||
if($plan->parent >= 0)
|
||||
{
|
||||
$class = 'iframe';
|
||||
$attr = "data-toggle='modal' data-id='{$plan->id}' data-width='550px'";
|
||||
$isOnlyBody = true;
|
||||
$attr = "target='hiddenwin'";
|
||||
$isOnlyBody = false;
|
||||
$class = '';
|
||||
if($plan->begin == '2030-01-01' or $plan->end == '2030-01-01')
|
||||
{
|
||||
$class = 'iframe';
|
||||
$attr = "data-toggle='modal' data-id='{$plan->id}' data-width='550px'";
|
||||
$isOnlyBody = true;
|
||||
}
|
||||
$class = $plan->status == 'wait' ? $class : 'disabled';
|
||||
common::printLink('productplan', 'start', "planID=$plan->id", "<i class='icon-play'></i>{$lang->productplan->startAB}", '', "class='btn btn-link {$class}'{$attr} title='{$lang->productplan->start}'", '', $isOnlyBody, $plan);
|
||||
$class = $plan->status == 'doing' ? '' : 'disabled';
|
||||
common::printLink('productplan', 'finish', "planID=$plan->id", "<i class='icon-checked'></i>{$lang->productplan->finishAB}", '', "class='btn btn-link {$class}' target='hiddenwin' title='{$lang->productplan->finish}'", '', false, $plan);
|
||||
$class = $plan->status == 'done' ? '' : 'disabled';
|
||||
common::printLink('productplan', 'close', "planID=$plan->id", "<i class='icon-off'></i>{$lang->productplan->closeAB}", '', "class='btn btn-link {$class}' target='hiddenwin' title='{$lang->productplan->close}'", '', false, $plan);
|
||||
$class = $plan->status == 'closed' ? '' : 'disabled';
|
||||
common::printLink('productplan', 'activate', "planID=$plan->id", "<i class='icon-magic'></i>{$lang->productplan->activateAB}", '', "class='btn btn-link {$class}' target='hiddenwin' title='{$lang->productplan->activate}'", '', false, $plan);
|
||||
}
|
||||
|
||||
$class = $plan->status == 'wait' ? $class : 'disabled';
|
||||
common::printLink('productplan', 'start', "planID=$plan->id", "<i class='icon-play'></i>{$lang->productplan->startAB}", '', "class='btn btn-link {$class}'{$attr} title='{$lang->productplan->start}'", '', $isOnlyBody);
|
||||
$class = $plan->status == 'doing' ? '' : 'disabled';
|
||||
common::printLink('productplan', 'finish', "planID=$plan->id", "<i class='icon-checked'></i>{$lang->productplan->finishAB}", '', "class='btn btn-link {$class}' target='hiddenwin' title='{$lang->productplan->finish}'");
|
||||
$class = $plan->status == 'done' ? '' : 'disabled';
|
||||
common::printLink('productplan', 'close', "planID=$plan->id", "<i class='icon-off'></i>{$lang->productplan->closeAB}", '', "class='btn btn-link {$class}' target='hiddenwin' title='{$lang->productplan->close}'");
|
||||
$class = $plan->status == 'closed' ? '' : 'disabled';
|
||||
common::printLink('productplan', 'activate', "planID=$plan->id", "<i class='icon-magic'></i>{$lang->productplan->activateAB}", '', "class='btn btn-link {$class}' target='hiddenwin' title='{$lang->productplan->activate}'");
|
||||
|
||||
if(common::hasPriv('productplan', 'create', $plan) and $plan->parent <= '0') echo html::a($this->createLink('productplan', 'create', "product={$plan->product}&branch={$plan->branch}&parent={$plan->id}"), "<i class='icon-split'></i> " . $this->lang->productplan->children , '', "class='btn btn-link' title='{$this->lang->productplan->children}'");
|
||||
if(common::hasPriv('productplan', 'edit', $plan)) echo html::a($this->createLink('productplan', 'edit', "planID=$plan->id"), "<i class='icon-common-edit icon-edit'></i> " . $this->lang->edit, '', "class='btn btn-link' title='{$this->lang->edit}'");
|
||||
if(common::hasPriv('productplan', 'delete', $plan) and $plan->parent >= 0) echo html::a($this->createLink('productplan', 'delete', "planID=$plan->id"), "<i class='icon-common-delete icon-trash'></i> " . $this->lang->delete, '', "class='btn btn-link' title='{$this->lang->delete}' target='hiddenwin'");
|
||||
|
||||
Reference in New Issue
Block a user