Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms
This commit is contained in:
+31
-17
@@ -1469,35 +1469,50 @@ EOD;
|
||||
*/
|
||||
public function getPreAndNextObject($type, $objectID)
|
||||
{
|
||||
$preAndNextObject = new stdClass();
|
||||
$preAndNextObject->pre = '';
|
||||
$preAndNextObject->next = '';
|
||||
|
||||
/* Get objectIDList. */
|
||||
$table = $this->config->objectTables[$type];
|
||||
/* Get SQL. */
|
||||
$queryCondition = $type . 'QueryCondition';
|
||||
$typeOnlyCondition = $type . 'OnlyCondition';
|
||||
$queryCondition = $this->session->$queryCondition;
|
||||
$queryCondition = $this->session->$queryCondition;
|
||||
|
||||
$table = $this->config->objectTables[$type];
|
||||
$orderBy = $type . 'OrderBy';
|
||||
$orderBy = $this->session->$orderBy;
|
||||
if(empty($queryCondition) or $this->session->$typeOnlyCondition)
|
||||
{
|
||||
$queryObjects = $this->dao->select('*')->from($table)->where('id')->eq($objectID)
|
||||
->beginIF($queryCondition != false)->orWhere($queryCondition)->fi()
|
||||
$sql = $this->dao->select('*')->from($table)
|
||||
->beginIF($queryCondition != false)->where($queryCondition)->fi()
|
||||
->beginIF($orderBy != false)->orderBy($orderBy)->fi()
|
||||
->query();
|
||||
->get();
|
||||
}
|
||||
else
|
||||
{
|
||||
$queryObjects = $this->dao->query($queryCondition . (empty($orderBy) ? '' : " ORDER BY $orderBy"));
|
||||
$sql = $queryCondition . (empty($orderBy) ? '' : " ORDER BY $orderBy");
|
||||
}
|
||||
|
||||
$preObj = false;
|
||||
while($object = $queryObjects->fetch())
|
||||
/* Get objectIDList. */
|
||||
$objectIdListKey = $type . 'BrowseList';
|
||||
$existsObjectList = $this->session->$objectIdListKey;
|
||||
if(empty($existsObjectList) or $existsObjectList['sql'] != $sql)
|
||||
{
|
||||
$key = (!$this->session->$typeOnlyCondition and $type == 'testcase' and isset($object->case)) ? 'case' : 'id';
|
||||
$id = $object->$key;
|
||||
$queryObjects = $this->dao->query($sql);
|
||||
$objectList = array();
|
||||
while($object = $queryObjects->fetch())
|
||||
{
|
||||
$key = (!$this->session->$typeOnlyCondition and $type == 'testcase' and isset($object->case)) ? 'case' : 'id';
|
||||
$id = $object->$key;
|
||||
$objectList[$id] = $object;
|
||||
}
|
||||
$this->session->set($objectIdListKey, array('sql' => $sql, 'objectList' => $objectList));
|
||||
$existsObjectList = $this->session->$objectIdListKey;
|
||||
}
|
||||
|
||||
$preAndNextObject = new stdClass();
|
||||
$preAndNextObject->pre = '';
|
||||
$preAndNextObject->next = '';
|
||||
|
||||
$preObj = false;
|
||||
foreach($existsObjectList['objectList'] as $id => $object)
|
||||
{
|
||||
/* Get next object. */
|
||||
if($preObj === true)
|
||||
{
|
||||
@@ -1514,8 +1529,6 @@ EOD;
|
||||
if($preObj !== true) $preObj = $object;
|
||||
}
|
||||
|
||||
$existObject = $type . 'PreAndNext';
|
||||
$this->session->set($existObject, array('objectID' => $objectID, 'preAndNextObject' => $preAndNextObject));
|
||||
return $preAndNextObject;
|
||||
}
|
||||
|
||||
@@ -1561,6 +1574,7 @@ EOD;
|
||||
if($onlyCondition) $orderBy = str_replace('t1.', '', $orderBy);
|
||||
}
|
||||
$this->session->set($objectType . 'OrderBy', $orderBy);
|
||||
$this->session->set($objectType . 'BrowseList', array());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -594,6 +594,34 @@ class custom extends control
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Mode.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function mode()
|
||||
{
|
||||
if($_POST)
|
||||
{
|
||||
$after15mode = fixer::input('post')->get('after15mode');
|
||||
$this->loadModel('setting')->setItem('system.custom.after15mode', $after15mode);
|
||||
if($after15mode == 'new') $this->locate($this->createLink('upgrade', 'mergeTips'));
|
||||
}
|
||||
|
||||
$after15mode = zget($this->config->custom, 'after15mode', 'old');
|
||||
if($after15mode == 'new')
|
||||
{
|
||||
if(isset($this->config->global->upgradeStep) and $this->config->global->upgradeStep == 'mergeProgram') $this->locate($this->createLink('upgrade', 'mergeProgram'));
|
||||
|
||||
unset($_SESSION['upgrading']);
|
||||
$this->locate(inlink('index'));
|
||||
}
|
||||
|
||||
$this->app->loadLang('upgrade');
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax save custom fields.
|
||||
*
|
||||
|
||||
@@ -38,6 +38,7 @@ $lang->custom->URStory = "用户需求";
|
||||
$lang->custom->SRStory = "软件需求";
|
||||
$lang->custom->epic = "史诗";
|
||||
$lang->custom->default = "默认";
|
||||
$lang->custom->mode = "模式";
|
||||
$lang->custom->scrumStory = "故事";
|
||||
$lang->custom->waterfallCommon = "瀑布";
|
||||
$lang->custom->buildin = "系统内置";
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
{
|
||||
common::printLink('custom', $sysObject, "", "<span class='text'>{$lang->custom->$sysObject}</span>", '', "class='btn btn-link' id='{$sysObject}Tab'");
|
||||
}
|
||||
if(isset($config->custom->after15mode) and $config->custom->after15mode == 'old')
|
||||
{
|
||||
common::printLink('custom', 'mode', "", "<span class='text'>{$lang->custom->mode}</span>", '', "class='btn btn-link' id='modeTab'");
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* The set view file of custom 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 Tingting Dai <daitingting@xirangit.com>
|
||||
* @package custom
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include 'header.html.php';?>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<form class="load-indicator main-form" method='post'>
|
||||
<div class='main-header'>
|
||||
<div class='heading'>
|
||||
<strong><?php echo $lang->custom->mode?></strong>
|
||||
</div>
|
||||
</div>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th class='text-top'><?php echo $lang->custom->mode;?></th>
|
||||
<td>
|
||||
<p><label class="radio-inline"><input type="radio" name="after15mode" value="new" checked='checked' id="after15modenew"><?php echo $lang->upgrade->to15Mode['new'];?></label></p>
|
||||
<p class='text-info'><?php echo $lang->upgrade->selectedModeTips['new'];?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td></td><td><?php echo html::submitButton()?></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<script>
|
||||
$('#modeTab').addClass('btn-active-text');
|
||||
</script>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
@@ -2,7 +2,7 @@ body {padding-left: 96px}
|
||||
|
||||
#menu {position: fixed; left: 0; top: 0; bottom: 0; background-color: #3C495C; width: 96px; z-index: 1015;}
|
||||
#menuNav {position: absolute; top: 0; bottom: 80px; width: 100%;}
|
||||
#menu .nav > li {float: none; padding: 4px 8px;}
|
||||
#menu .nav > li {float: none; padding: 2px 8px;}
|
||||
#menu .nav > li > a {color: #fff; line-height: 20px; padding: 8px 6px; border-radius: 2px; white-space: nowrap;}
|
||||
#menu .nav > li > a > .icon {display: inline-block; font-size: 16px;}
|
||||
#menu .nav > li > a > .icon + .text {margin-left: 4px}
|
||||
|
||||
@@ -469,7 +469,7 @@ class programModel extends model
|
||||
if(empty($programID)) return $topPGM;
|
||||
|
||||
$program = $this->getPGMByID($programID);
|
||||
list($topPGM) = explode(',', trim($program->path, ','));
|
||||
if(!empty($program))list($topPGM) = explode(',', trim($program->path, ','));
|
||||
return $topPGM;
|
||||
}
|
||||
|
||||
@@ -488,6 +488,7 @@ class programModel extends model
|
||||
->leftJoin(TABLE_PRODUCT)->alias('t3')->on('t1.product = t3.id')
|
||||
->where('t1.product')->in($linkedProducts)
|
||||
->andWhere('t1.project')->ne($projectID)
|
||||
->andWhere('t2.type')->eq('project')
|
||||
->andWhere('t2.deleted')->eq('0')
|
||||
->andWhere('t3.deleted')->eq('0')
|
||||
->fetchPairs('id', 'name');
|
||||
@@ -1709,7 +1710,6 @@ class programModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Judge products not empty. */
|
||||
$linkedProductsCount = 0;
|
||||
foreach($_POST['products'] as $product)
|
||||
@@ -1759,6 +1759,54 @@ class programModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch update products.
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function PRJBatchUpdate()
|
||||
{
|
||||
$projects = array();
|
||||
$allChanges = array();
|
||||
$data = fixer::input('post')->get();
|
||||
$oldProjects = $this->getPRJByIdList($this->post->projectIdList);
|
||||
$nameList = array();
|
||||
|
||||
foreach($data->projectIdList as $projectID)
|
||||
{
|
||||
$projectName = $data->names[$projectID];
|
||||
$parentProgram = $data->parents[$projectID];
|
||||
|
||||
$projectID = (int)$projectID;
|
||||
$projects[$projectID] = new stdClass();
|
||||
$projects[$projectID]->name = $projectName;
|
||||
$projects[$projectID]->parent = $parentProgram;
|
||||
$projects[$projectID]->PM = $data->PMs[$projectID];
|
||||
|
||||
/* Check unique name for edited projects. */
|
||||
if(isset($nameList[$projectName])) dao::$errors['name'][] = 'project#' . $projectID . sprintf($this->lang->error->unique, $this->lang->program->PRJName, $projectName);
|
||||
$nameList[$projectName] = $projectName;
|
||||
}
|
||||
|
||||
foreach($projects as $projectID => $project)
|
||||
{
|
||||
$oldProject = $oldProjects[$projectID];
|
||||
$this->dao->update(TABLE_PROJECT)
|
||||
->data($project)
|
||||
->autoCheck()
|
||||
->batchCheck($this->config->program->PRJEdit->requiredFields , 'notempty')
|
||||
->check('name', 'unique', "id NOT " . helper::dbIN($data->projectIdList) . " and deleted='0'")
|
||||
->where('id')->eq($projectID)
|
||||
->exec();
|
||||
|
||||
if(dao::isError()) die(js::error('project#' . $projectID . dao::getError(true)));
|
||||
|
||||
$allChanges[$projectID] = common::createChanges($oldProject, $project);
|
||||
}
|
||||
return $allChanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print datatable cell.
|
||||
*
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
<?php $userID = isset($PMList[$program->PM]) ? $PMList[$program->PM]->id : ''?>
|
||||
<?php if(!empty($program->PM)) echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), zget($users, $program->PM), '', "data-toggle='modal' data-type='iframe' data-width='600'");?>
|
||||
</td>
|
||||
<?php $programBudget = in_array($this->app->getClientLang(), ['zh-cn','zh-tw']) && $program->budget >= 10000 ? number_format($program->budget / 10000, 1) . $lang->program->tenThousand : number_format($program->budget, 1);?>
|
||||
<?php $programBudget = in_array($this->app->getClientLang(), ['zh-cn','zh-tw']) && $program->budget >= 10000 ? number_format($program->budget / 10000, 1) . $lang->program->tenThousand : number_format((float)$program->budget, 1);?>
|
||||
<td class='text-right'><?php echo $program->budget != 0 ? zget($lang->program->currencySymbol, $program->budgetUnit) . ' ' . $programBudget : $lang->program->future;?></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><?php echo $program->begin;?></td>
|
||||
|
||||
@@ -1490,6 +1490,7 @@ class projectModel extends model
|
||||
$this->session->set('taskQueryCondition', $taskQuery);
|
||||
$this->session->set('taskOnlyCondition', true);
|
||||
$this->session->set('taskOrderBy', $sort);
|
||||
$this->session->set('taskBrowseList', array());
|
||||
|
||||
$tasks = $this->getSearchTasks($taskQuery, $pager, $sort);
|
||||
}
|
||||
|
||||
+31
-21
@@ -23,7 +23,7 @@ class upgrade extends control
|
||||
$upgradeFile = $this->app->wwwRoot . 'upgrade.php';
|
||||
if(!file_exists($upgradeFile)) $this->locate($this->createLink('my', 'index'));
|
||||
|
||||
if((version_compare($this->config->installedVersion, '20', '<')
|
||||
if((version_compare($this->config->installedVersion, '15', '<')
|
||||
|| strpos($this->config->installedVersion, 'biz') !== false
|
||||
|| strpos($this->config->installedVersion, 'pro') !== false)
|
||||
&& strpos($this->config->installedVersion, 'max') === false)
|
||||
@@ -31,26 +31,11 @@ class upgrade extends control
|
||||
/* Judge upgrade step. */
|
||||
$upgradeStep = $this->loadModel('setting')->getItem('owner=system&module=common§ion=global&key=upgradeStep');
|
||||
if($upgradeStep == 'mergeProgram') $this->locate(inlink('mergeProgram'));
|
||||
|
||||
$this->locate(inlink('to20'));
|
||||
}
|
||||
if(version_compare($this->config->installedVersion, '6.4', '<=')) $this->locate(inlink('license'));
|
||||
$this->locate(inlink('backup'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade to 20 version.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function to20()
|
||||
{
|
||||
$this->view->title = $this->lang->upgrade->to20Tips;
|
||||
$this->view->video = $this->lang->upgrade->videoURL;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check agree license.
|
||||
*
|
||||
@@ -152,11 +137,11 @@ class upgrade extends control
|
||||
|
||||
if(!$this->upgrade->isError())
|
||||
{
|
||||
if((version_compare($fromVersion, '20', '<')
|
||||
|| strpos($fromVersion, 'biz') !== false
|
||||
|| strpos($fromVersion, 'pro') !== false)
|
||||
if((version_compare($fromVersion, '15', '<')
|
||||
|| strpos($fromVersion, 'biz') !== false
|
||||
|| strpos($fromVersion, 'pro') !== false)
|
||||
&& strpos($fromVersion, 'max') === false
|
||||
&& !isset($this->config->qcVersion)) $this->locate(inlink('mergeTips'));
|
||||
&& !isset($this->config->qcVersion)) $this->locate(inlink('to15Guide', "fromVersion=$fromVersion"));
|
||||
$this->locate(inlink('afterExec', "fromVersion=$fromVersion"));
|
||||
}
|
||||
|
||||
@@ -165,6 +150,28 @@ class upgrade extends control
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Guide to 15 version.
|
||||
*
|
||||
* @param string $fromVersion
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function to15Guide($fromVersion)
|
||||
{
|
||||
if($_POST)
|
||||
{
|
||||
$after15mode = fixer::input('post')->get('after15mode');
|
||||
$this->loadModel('setting')->setItem('system.custom.after15mode', $after15mode);
|
||||
|
||||
if($after15mode == 'old') $this->locate(inlink('afterExec', "fromVersion=$fromVersion"));
|
||||
if($after15mode == 'new') $this->locate(inlink('mergeTips'));
|
||||
}
|
||||
|
||||
$this->view->title = $this->lang->upgrade->to15Guide;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge program tips.
|
||||
*
|
||||
@@ -433,11 +440,12 @@ class upgrade extends control
|
||||
}
|
||||
|
||||
$programs = $this->upgrade->getProgramPairs();
|
||||
$currentProgramID = $programID ? $programID : key($programs);
|
||||
|
||||
$this->view->title = $this->lang->upgrade->mergeProgram;
|
||||
$this->view->programs = $programs;
|
||||
$this->view->programID = $programID;
|
||||
$this->view->projects = array('' => '') + $this->upgrade->getProjectPairsByProgram(key($programs));
|
||||
$this->view->projects = array('' => '') + $this->upgrade->getProjectPairsByProgram($currentProgramID);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed|noempty');
|
||||
$this->view->groups = $this->loadModel('group')->getPairs();
|
||||
$this->display();
|
||||
@@ -462,6 +470,8 @@ class upgrade extends control
|
||||
if(empty($repos))
|
||||
{
|
||||
$this->loadModel('setting')->deleteItems('owner=system&module=common§ion=global&key=upgradeStep');
|
||||
|
||||
if($this->config->version == $this->config->installedVersion) die(js::locate($this->createLink('custom', 'mode')));
|
||||
die(js::locate($this->createLink('upgrade', 'afterExec', "fromVersion=&processed=no")));
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ function getProjectByProgram(obj)
|
||||
|
||||
function toggleProgram(obj)
|
||||
{
|
||||
var $obj = $(obj);
|
||||
var $obj = $(obj);
|
||||
if($obj.length == 0) return false;
|
||||
|
||||
var $programs = $obj.closest('table').find('#programs');
|
||||
@@ -140,6 +140,7 @@ function toggleProgram(obj)
|
||||
$('form .pgm-no-exist').removeClass('hidden');
|
||||
$('form .pgm-exist').addClass('hidden');
|
||||
$programs.attr('disabled', 'disabled');
|
||||
$('#PGMStatus').closest('.PGMParams').show();
|
||||
|
||||
$('form #newProject0').prop('checked', true);
|
||||
toggleProject($('form #newProject0'));
|
||||
@@ -148,6 +149,7 @@ function toggleProgram(obj)
|
||||
{
|
||||
$('form .pgm-exist').removeClass('hidden');
|
||||
$('form .pgm-no-exist').addClass('hidden');
|
||||
$('#PGMStatus').closest('.PGMParams').hide();
|
||||
$programs.removeAttr('disabled');
|
||||
}
|
||||
}
|
||||
@@ -181,6 +183,38 @@ function toggleProject(obj)
|
||||
}
|
||||
}
|
||||
|
||||
function setPRJStatus()
|
||||
{
|
||||
var PRJStatus = 'closed';
|
||||
$(':checkbox:checked[data-status]').each(function()
|
||||
{
|
||||
var status = $(this).attr('data-status');
|
||||
if(status == 'doing' || status == 'suspended')
|
||||
{
|
||||
PRJStatus = 'doing';
|
||||
return false;
|
||||
}
|
||||
|
||||
if(status == 'wait') PRJStatus = 'wait';
|
||||
});
|
||||
if($(':checkbox:checked[data-status]').length == 0) PRJStatus = 'wait';
|
||||
|
||||
$('#PRJStatus').val(PRJStatus);
|
||||
$('#PRJStatus').trigger('chosen:updated');
|
||||
|
||||
setPGMStatus(PRJStatus);
|
||||
}
|
||||
|
||||
function setPGMStatus(PRJStatus)
|
||||
{
|
||||
var PGMStatus = 'wait';
|
||||
if(PRJStatus != 'wait') PGMStatus = 'doing';
|
||||
if(PRJStatus == 'closed') PGMStatus = 'closed';
|
||||
|
||||
$('#PGMStatus').val(PGMStatus);
|
||||
$('#PGMStatus').trigger('chosen:updated');
|
||||
}
|
||||
|
||||
function setPGMBegin(PGMBegin)
|
||||
{
|
||||
$(':checkbox:checked[data-begin]').each(function()
|
||||
@@ -194,6 +228,8 @@ function setPGMBegin(PGMBegin)
|
||||
$('.PGMParams #begin').val(PGMBegin);
|
||||
}
|
||||
});
|
||||
|
||||
setPRJStatus();
|
||||
}
|
||||
|
||||
function setPGMEnd(PGMEnd)
|
||||
|
||||
@@ -49,21 +49,16 @@ $lang->upgrade->noticeSQL = '检查到你的数据库跟标准不一致,
|
||||
$lang->upgrade->afterDeleted = '以上文件未能删除, 删除后刷新!';
|
||||
$lang->upgrade->mergeProgram = '数据迁移';
|
||||
$lang->upgrade->mergeTips = '数据迁移提示';
|
||||
$lang->upgrade->to20Demo = '查看20版本Demo';
|
||||
$lang->upgrade->demoURL = 'http://zentao20.demo.zentao.net';
|
||||
$lang->upgrade->videoURL = 'https://qc.zentao.net/zentao20.mp4';
|
||||
$lang->upgrade->to20Tips = '禅道20版本升级提示';
|
||||
$lang->upgrade->to20Button = '我已经做好备份,开始升级吧!';
|
||||
$lang->upgrade->to20TipsHeader = "<p>尊敬的用户,感谢对禅道的支持。自20版本开始,禅道全面升级成为通用的项目管理平台。相关介绍请看如下视频(如视频无法正常播放,请直接访问 <a href='http://zentao20.demo.zentao.net/zentao20.mp4' target='_blank'><u>禅道20版本介绍</u></a>):</p><br />";
|
||||
$lang->upgrade->to20Desc = <<<EOD
|
||||
<div class='text-warning' style='width:60%; margin: auto;'>
|
||||
<p>友情提示:</p>
|
||||
<ol>
|
||||
<li>您可以先安装一个20版本的禅道,体验一下里边的概念和流程。</li>
|
||||
<li>20版本禅道改动比较大,升级之前请做好备份。</li>
|
||||
<li>请放心升级,即使第一次升级不到位,后续还可以再调整,不会影响系统数据。</li>
|
||||
</ol>
|
||||
</div>
|
||||
$lang->upgrade->to15Guide = '升级15版本后引导';
|
||||
$lang->upgrade->to15Desc = <<<EOD
|
||||
<p>尊敬的用户,禅道从15版本开始对导航和概念做了调整,主要改动如下:</p>
|
||||
<ol>
|
||||
<li>增加了项目集概念。一个项目集可以包括多个产品和多个项目。</li>
|
||||
<li>细分了项目和迭代概念,一个项目可以包含多个迭代。</li>
|
||||
<li>导航增加了左侧菜单并支持多页面操作。</li>
|
||||
</ol>
|
||||
<p>您可以在线体验最新版本的功能以决定是否启用的模式:<a href='http://zentaomax.demo.zentao.net' target='_blank'>演示链接</a>。</p>
|
||||
<p>请问您计划如何使用禅道的新版本呢?</p>
|
||||
EOD;
|
||||
$lang->upgrade->mergeProgramDesc = <<<EOD
|
||||
<p>接下来我们会把之前历史产品和迭代数据迁移到项目集和项目下,迁移的方案如下:</p><br />
|
||||
@@ -77,6 +72,12 @@ $lang->upgrade->mergeProgramDesc = <<<EOD
|
||||
<p>可以选择这些迭代归属于某个新项目下。</p>
|
||||
EOD;
|
||||
|
||||
$lang->upgrade->to15Mode['old'] = '保持老版本的习惯';
|
||||
$lang->upgrade->to15Mode['new'] = '全新项目集管理模式';
|
||||
|
||||
$lang->upgrade->selectedModeTips['old'] = '后续您还可以在后台-自定义里面切换为全新项目集管理的模式。';
|
||||
$lang->upgrade->selectedModeTips['new'] = '切换为项目集管理模式需要对之前的数据进行归并处理,系统会引导您完成这个操作。';
|
||||
|
||||
$lang->upgrade->line = '产品线';
|
||||
$lang->upgrade->program = '目标项目集和项目';
|
||||
$lang->upgrade->existPGM = '已有项目集';
|
||||
|
||||
+57
-27
@@ -3998,7 +3998,7 @@ class upgradeModel extends model
|
||||
$program = new stdclass();
|
||||
$program->name = $data->PGMName;
|
||||
$program->type = 'program';
|
||||
$program->status = 'wait';
|
||||
$program->status = $data->PGMStatus;
|
||||
$program->begin = $data->begin;
|
||||
$program->end = isset($data->end) ? $data->end : '';
|
||||
$program->openedBy = $account;
|
||||
@@ -4042,7 +4042,7 @@ class upgradeModel extends model
|
||||
$project->type = 'project';
|
||||
$project->model = 'scrum';
|
||||
$project->parent = $programID;
|
||||
$project->status = 'wait';
|
||||
$project->status = $data->PRJStatus;
|
||||
$project->begin = $data->begin;
|
||||
$project->end = isset($data->end) ? $data->end : '';
|
||||
$project->PM = $data->PM;
|
||||
@@ -4115,29 +4115,9 @@ class upgradeModel extends model
|
||||
{
|
||||
$projectStory = $sprintStory;
|
||||
$projectStory->project = $projectID;
|
||||
$this->dao->insert(TABLE_PROJECTSTORY)->data($projectStory)->exec();
|
||||
$this->dao->replace(TABLE_PROJECTSTORY)->data($projectStory)->exec();
|
||||
}
|
||||
|
||||
/* Compute project date. */
|
||||
$linkedSprintIdList = $this->dao->select('id')->from(TABLE_PROJECT)->where('project')->eq($projectID)->fetchPairs();
|
||||
$linkedSprintIdList += $sprintIdList;
|
||||
$undoneSprints = $this->dao->select("count('*') as count")->from(TABLE_PROJECT)->where('id')->in($linkedSprintIdList)->andWhere('status')->ne('closed')->fetch('count');
|
||||
$minRealBegan = $this->dao->select('date')->from(TABLE_ACTION)->where('objectID')->in($linkedSprintIdList)->andWhere('objectType')->eq('project')->andWhere('action')->eq('started')->orderBy('date_asc')->fetch('date');
|
||||
$maxRealEnd = $this->dao->select('date')->from(TABLE_ACTION)->where('objectID')->in($linkedSprintIdList)->andWhere('objectType')->eq('project')->andWhere('action')->eq('closed')->orderBy('date_desc')->fetch('date');
|
||||
|
||||
$data = new stdClass();
|
||||
$data->realBegan = $minRealBegan ? substr($minRealBegan, 0, 10) : '0000-00-00';
|
||||
if($maxRealEnd and !$undoneSprints)
|
||||
{
|
||||
$data->realEnd = substr($maxRealEnd, 0, 10);
|
||||
$data->closedDate = $maxRealEnd;
|
||||
$data->status = 'closed';
|
||||
}
|
||||
|
||||
$this->dao->update(TABLE_PROJECT)->data($data)->where('id')->eq($projectID)->exec();
|
||||
|
||||
if($maxRealEnd and !$undoneSprints) $this->loadModel('action')->create('project', $projectID, 'closedbysystem');
|
||||
|
||||
/* Compute product acl. */
|
||||
$products = $this->dao->select('id,program,acl')->from(TABLE_PRODUCT)->where('id')->in($productIdList)->fetchAll();
|
||||
foreach($products as $product)
|
||||
@@ -4167,7 +4147,32 @@ class upgradeModel extends model
|
||||
$this->dao->update(TABLE_PROJECT)->data($data)->where('id')->eq($sprint->id)->exec();
|
||||
}
|
||||
|
||||
/* Set product and project relation. */
|
||||
/* Compute project date and status. */
|
||||
$linkedSprintIdList = $this->dao->select('id')->from(TABLE_PROJECT)->where('project')->eq($projectID)->fetchPairs();
|
||||
$linkedSprintIdList += $sprintIdList;
|
||||
$minRealBegan = $this->dao->select('date')->from(TABLE_ACTION)->where('objectID')->in($linkedSprintIdList)->andWhere('objectType')->eq('project')->andWhere('action')->eq('started')->orderBy('date_asc')->fetch('date');
|
||||
$maxRealEnd = $this->dao->select('date')->from(TABLE_ACTION)->where('objectID')->in($linkedSprintIdList)->andWhere('objectType')->eq('project')->andWhere('action')->eq('closed')->orderBy('date_desc')->fetch('date');
|
||||
|
||||
$PRJStatus = $this->computeStatus($projectID);
|
||||
|
||||
$data = new stdClass();
|
||||
$data->realBegan = $minRealBegan ? substr($minRealBegan, 0, 10) : '0000-00-00';
|
||||
$data->status = $PRJStatus;
|
||||
if($PRJStatus == 'closed')
|
||||
{
|
||||
$data->realEnd = substr($maxRealEnd, 0, 10);
|
||||
$data->closedDate = $maxRealEnd;
|
||||
}
|
||||
|
||||
$this->dao->update(TABLE_PROJECT)->data($data)->where('id')->eq($projectID)->exec();
|
||||
if($PRJStatus == 'closed') $this->loadModel('action')->create('project', $projectID, 'closedbysystem');
|
||||
|
||||
/* Compute program status. */
|
||||
$PGMStatus = $this->computeStatus($programID);
|
||||
$this->dao->update(TABLE_PROJECT)->set('status')->eq($PGMStatus)->where('id')->eq($programID)->exec();
|
||||
if($PGMStatus == 'closed') $this->loadModel('action')->create('program', $programID, 'closedbysystem');
|
||||
|
||||
/* Set product and project relation. */
|
||||
foreach($productIdList as $productID)
|
||||
{
|
||||
$data = new stdclass();
|
||||
@@ -4180,9 +4185,34 @@ class upgradeModel extends model
|
||||
$this->computeObjectMembers($programID, $projectID, $productIdList, $sprintIdList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute program and project members.
|
||||
*
|
||||
/**
|
||||
* Compute project or program status.
|
||||
*
|
||||
* @param int $objectID
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function computeStatus($objectID)
|
||||
{
|
||||
$objects = $this->dao->select('id, status')->from(TABLE_PROJECT)->where('parent')->eq($objectID)->fetchPairs();
|
||||
$objectStatus = empty($objects) ? 'wait' : 'closed';
|
||||
foreach($objects as $status)
|
||||
{
|
||||
if($status == 'doing' || $status == 'suspended')
|
||||
{
|
||||
$objectStatus = 'doing';
|
||||
break;
|
||||
}
|
||||
|
||||
if($status == 'wait') $objectStatus = 'wait';
|
||||
}
|
||||
|
||||
return $objectStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute program and project members.
|
||||
*
|
||||
* @param int $programID
|
||||
* @param int $projectID
|
||||
* @param array $productIdList
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<tr>
|
||||
<th>
|
||||
<span class="pgm-exist hidden"><?php echo $lang->upgrade->existPGM;?></span>
|
||||
<span class="pgm-no-exist"><?php echo $lang->program->PGMName;?></span></th>
|
||||
<span class="pgm-no-exist"><?php echo $lang->program->PGMName;?></span>
|
||||
</th>
|
||||
<td class='required'>
|
||||
<div class='input-group'>
|
||||
<?php echo html::select("programs", $programs, $programID, "class='form-control hidden pgm-exist' onchange='getProjectByProgram(this)'");?>
|
||||
<?php echo html::input("PGMName", isset($programName) ? $programName : '', "class='form-control pgm-no-exist'");?>
|
||||
<?php if(count(programs)):?>
|
||||
<?php if(count($programs)):?>
|
||||
<span class='input-group-addon'>
|
||||
<div class="checkbox-primary">
|
||||
<input type="checkbox" name="newProgram" value="0" checked onchange="toggleProgram(this)" id="newProgram0" />
|
||||
@@ -20,11 +20,15 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='PGMParams'>
|
||||
<th><?php echo $lang->program->PGMCommon . $lang->program->PGMStatus;?></th>
|
||||
<td><?php echo html::select('PGMStatus', $lang->program->statusList, '', "class='form-control chosen'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<span class="prj-exist hidden"><?php echo $lang->upgrade->existPRJ;?></span>
|
||||
<span class="prj-no-exist"><?php echo $lang->program->PRJName;?></span></th>
|
||||
</th>
|
||||
<span class="prj-no-exist"><?php echo $lang->program->PRJName;?></span>
|
||||
</th>
|
||||
<td class='required'>
|
||||
<div class='input-group'>
|
||||
<?php echo html::select("projects", $projects, '', "class='form-control hidden prj-exist'");?>
|
||||
@@ -40,6 +44,10 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='PGMParams'>
|
||||
<th><?php echo $lang->program->PRJCommon . $lang->program->PRJStatus;?></th>
|
||||
<td><?php echo html::select('PRJStatus', $lang->program->statusList, '', "class='form-control chosen'");?></td>
|
||||
</tr>
|
||||
<tr class='PGMParams'>
|
||||
<th><?php echo $lang->program->PRJPM;?></th>
|
||||
<td><?php echo html::select('PM', array('' => '') + $users, '', "class='form-control chosen'");?></td>
|
||||
|
||||
@@ -37,14 +37,14 @@
|
||||
<?php foreach($lineGroups[$line->id] as $productID => $product):?>
|
||||
<div class='lineGroup'>
|
||||
<div class='productList'>
|
||||
<?php echo html::checkBox("products[$line->id]", array($productID => "{$lang->productCommon} #{$product->id} {$product->name}"), $i == 0 ? $product->id : 0, "title='{$product->name}' data-productid='{$product->id}' data-line='{$line->id}' data-begin='{$product->createdDate}'");?>
|
||||
<?php echo html::checkBox("products[$line->id]", array($productID => $product->name), $i == 0 ? $product->id : 0, "title='{$product->name}' data-productid='{$product->id}' data-line='{$line->id}' data-begin='{$product->createdDate}'");?>
|
||||
<?php echo html::hidden("productIdList[$line->id][$productID]", $productID);?>
|
||||
</div>
|
||||
<div class='projectList'>
|
||||
<div class='scroll-handle'>
|
||||
<?php if(isset($productGroups[$productID])):?>
|
||||
<?php foreach($productGroups[$productID] as $sprint):?>
|
||||
<?php echo html::checkBox("sprints[$line->id][$productID]", array($sprint->id => "{$lang->upgrade->project} #{$sprint->id} {$sprint->name}"), $i == 0 ? $sprint->id : 0, "title='{$sprint->name}' data-product='{$product->id}' data-line='{$line->id}' data-begin='{$sprint->begin}' data-end='{$sprint->end}' data-pm='{$sprint->PM}'");?>
|
||||
<?php echo html::checkBox("sprints[$line->id][$productID]", array($sprint->id => $sprint->name), $i == 0 ? $sprint->id : 0, "title='{$sprint->name}' data-product='{$product->id}' data-line='{$line->id}' data-begin='{$sprint->begin}' data-end='{$sprint->end}' data-status='{$sprint->status}' data-pm='{$sprint->PM}'");?>
|
||||
<?php echo html::hidden("sprintIdList[$line->id][$productID][$sprint->id]", $sprint->id);?>
|
||||
<?php endforeach;?>
|
||||
<?php endif;?>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<div class='scroll-handle'>
|
||||
<?php if(isset($productGroups[$productID])):?>
|
||||
<?php foreach($productGroups[$productID] as $sprint):?>
|
||||
<?php echo html::checkBox("sprints[$productID]", array($sprint->id => "{$sprint->name}"), $isChecked ? $sprint->id : '', "data-product='{$productID}' data-begin='{$sprint->begin}' data-end='{$sprint->end}' data-pm='{$sprint->PM}'");?>
|
||||
<?php echo html::checkBox("sprints[$productID]", array($sprint->id => "{$sprint->name}"), $isChecked ? $sprint->id : '', "data-product='{$productID}' data-begin='{$sprint->begin}' data-end='{$sprint->end}' data-status='{$sprint->status}' data-pm='{$sprint->PM}'");?>
|
||||
<?php echo html::hidden("sprintIdList[$productID][$sprint->id]", $sprint->id);?>
|
||||
<?php endforeach;?>
|
||||
<?php endif;?>
|
||||
@@ -38,7 +38,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='table-col divider strong'></div>
|
||||
<div class='table-col divider strong'><i class='icon icon-angle-double-right'></i></div>
|
||||
<div class='table-col pgmWidth' id='programBox'>
|
||||
<div class='cell'>
|
||||
<?php include "./createprogram.html.php";?>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</div>
|
||||
<div class='line-groups'>
|
||||
<?php foreach($noMergedSprints as $sprintID => $sprint):?>
|
||||
<?php echo html::checkBox("sprints", array($sprint->id => "{$lang->upgrade->project} #{$sprint->id} {$sprint->name}"), $sprint->id, "data-begin='{$sprint->begin}' data-end='{$sprint->end}' data-pm='{$sprint->PM}'");?>
|
||||
<?php echo html::checkBox("sprints", array($sprint->id => "{$lang->upgrade->project} #{$sprint->id} {$sprint->name}"), $sprint->id, "data-begin='{$sprint->begin}' data-end='{$sprint->end}' data-status='{$sprint->status}' data-pm='{$sprint->PM}'");?>
|
||||
<?php endforeach;?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* The to20 view file of upgrade 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 Yidong Wang <yidong@cnezsoft.com>
|
||||
* @package upgrade
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.lite.html.php';?>
|
||||
<div class='container'>
|
||||
<div class='panel' style='padding:20px;'>
|
||||
<form method='post'>
|
||||
<div class='panel-title text-center'><?php echo $lang->upgrade->to15Guide;?></div>
|
||||
<div class='panel-body'>
|
||||
<div style='width:600px; margin: auto;'>
|
||||
<?php echo $lang->upgrade->to15Desc;?>
|
||||
<?php echo html::radio('after15mode', $lang->upgrade->to15Mode, 'old');?>
|
||||
<div id='selectedModeTips' class='text-info'><?php echo $lang->upgrade->selectedModeTips['old'];?></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='panel-footer text-center'><?php echo html::submitButton();?></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php js::set('selectedModeTips', $lang->upgrade->selectedModeTips);?>
|
||||
<script>
|
||||
$(function()
|
||||
{
|
||||
$('[name=after15mode]').change(function()
|
||||
{
|
||||
$('#selectedModeTips').html(selectedModeTips[$(this).val()]);
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<?php include '../../common/view/footer.lite.html.php';?>
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The to20 view file of upgrade 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 Yidong Wang <yidong@cnezsoft.com>
|
||||
* @package upgrade
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.lite.html.php';?>
|
||||
<div class='container'>
|
||||
<div class='panel' style='padding:20px;'>
|
||||
<div class='panel-title text-center'><?php echo $lang->upgrade->to20Tips;?></div>
|
||||
<div class='panel-body text-center'>
|
||||
<?php echo $lang->upgrade->to20TipsHeader;?>
|
||||
<div class='video'>
|
||||
<video src=<?php echo $video;?> height='400px' controls='controls' width='60%'></video>
|
||||
</div>
|
||||
<div class='desc text-left' style='margin-top: 20px'><?php echo $lang->upgrade->to20Desc;?></div>
|
||||
</div>
|
||||
<div class='panel-footer text-center'>
|
||||
<?php echo html::a($lang->upgrade->demoURL, $lang->upgrade->to20Demo, '_blank', "class='btn btn-secondary'");?>
|
||||
<?php echo html::a($this->createLink('upgrade', 'backup'), $lang->upgrade->to20Button, '', "class='btn btn-primary'");?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.lite.html.php';?>
|
||||
|
||||
Reference in New Issue
Block a user