diff --git a/module/upgrade/control.php b/module/upgrade/control.php
index cff56ea18d..6b06d64aea 100644
--- a/module/upgrade/control.php
+++ b/module/upgrade/control.php
@@ -229,6 +229,7 @@ class upgrade extends control
$linkedProducts = array();
$linkedSprints = array();
$unlinkSprints = array();
+ $sprintProducts = array();
/* Compute checked products and sprints, unchecked products and sprints. */
foreach($_POST['products'] as $lineID => $products)
@@ -241,7 +242,8 @@ class upgrade extends control
{
foreach($_POST['sprints'][$lineID][$productID] as $sprintID)
{
- $linkedSprints[$sprintID] = $sprintID;
+ $linkedSprints[$sprintID] = $sprintID;
+ $sprintProducts[$sprintID] = $productID;
unset($_POST['sprintIdList'][$lineID][$productID][$sprintID]);
}
$unlinkSprints[$productID] = $this->post->sprintIdList[$lineID][$productID];
@@ -250,11 +252,21 @@ class upgrade extends control
}
/* Create Program. */
- list($programID, $projectID, $lineID) = $this->upgrade->createProgram($linkedProducts, $linkedSprints);
+ list($programID, $projectList, $lineID) = $this->upgrade->createProgram($linkedProducts, $linkedSprints);
if(dao::isError()) die(js::error(dao::getError()));
/* Process merged products and projects. */
- $this->upgrade->processMergedData($programID, $projectID, $lineID, $linkedProducts, $linkedSprints);
+ if($_POST['projectType'] == 'execution')
+ {
+ $this->upgrade->processMergedData($programID, $projectList, $lineID, $linkedProducts, $linkedSprints);
+ }
+ else
+ {
+ foreach($linkedSprints as $sprint)
+ {
+ $this->upgrade->processMergedData($programID, $projectList[$sprint], $lineID, $sprintProducts[$sprint], array($sprint => $sprint));
+ }
+ }
/* Process unlinked sprint and product. */
foreach($linkedProducts as $productID => $product)
diff --git a/module/upgrade/css/mergeprogram.css b/module/upgrade/css/mergeprogram.css
index 1863986d2a..4ae38cfbfe 100644
--- a/module/upgrade/css/mergeprogram.css
+++ b/module/upgrade/css/mergeprogram.css
@@ -16,6 +16,7 @@ div.divider {vertical-align: middle;}
.main-row .side-col .nav li.active div a {background: #006af1; color: #fff; border-radius: 4px;}
.main-row .side-col .nav li div a {width: 80%; display: inline-block; padding: 8px 15px;}
+#lineBox > .cell {height: 700px;}
#source > .cell {padding: 0; position: relative; height: 450px;}
#source > .cell > .lineGroup-title {position: absolute; top: 0; left: 0; right: 0; padding: 10px;}
#source > .cell > .line-groups {position: absolute; top: 40px; left: 0; bottom: 0; right: 0; overflow: auto; padding: 0 10px 10px 10px;}
diff --git a/module/upgrade/js/mergeprogram.js b/module/upgrade/js/mergeprogram.js
index d8c5b74511..3a1b2bafbb 100644
--- a/module/upgrade/js/mergeprogram.js
+++ b/module/upgrade/js/mergeprogram.js
@@ -13,22 +13,23 @@ $(function()
var options = {
selector: 'input',
listenClick: false,
- clickBehavior:"single",
select: function(e)
{
$('[data-id=' + e.id + ']').prop('checked', true);
- },
- unselect: function(e)
- {
- $('[data-id=' + e.id + ']').prop('checked', false);
- },
- finish: function(e)
- {
+
var lineID = $('.nav li.active').attr('lineid');
var checkedLines = true;
var checkedProduct = true;
var checkedProject = true;
+ /* All products selected. */
+ $("[id^='products\[" + lineID + "\]']").each(function()
+ {
+ if(!$(this).prop('checked')) checkedProduct = false;
+ })
+ $('#checkAllProducts').prop('checked', checkedProduct);
+ $("[id^='productLines\[" + lineID + "\]']").prop('checked', checkedProduct);
+
/* All projects selected. */
$("[id^='sprints\[" + lineID + "\]']").each(function()
{
@@ -46,18 +47,9 @@ $(function()
$('#checkAllProducts').prop('checked', checkedProject);
$("[id^='productLines\[" + lineID + "\]']").prop('checked', checkedProject);
- /* All products selected. */
- $("[id^='products\[" + lineID + "\]']").each(function()
- {
- if(!$(this).prop('checked')) checkedProduct = false;
- })
- $('#checkAllProducts').prop('checked', checkedProduct);
- $("[id^='productLines\[" + lineID + "\]']").prop('checked', checkedProduct);
-
/* Select the product line of the current page. */
if($('.nav li.active').find('[id^=productLines]').prop('checked'))
{
-
var lineID = $('.nav li.active').attr('lineid');
$('#checkAllProducts').prop('checked', true);
$('#checkAllProjects').prop('checked', true);
@@ -81,14 +73,29 @@ $(function()
})
$('#checkAllLines').prop('checked', checkedLines);
+ /* If the project is checked, the relevant form will be displayed according to the selected mode. */
$('[id^=sprints]').each(function()
{
if($(this).prop('checked'))
{
hiddenProject();
var projectType = $('input[name="projectType"]:checked').val();
- if(projectType == 'project') $('.projectName').addClass('hidden');
- if(projectType == 'execution') $('.projectName').removeClass('hidden');
+ if(projectType == 'project')
+ {
+ $('.projectName').addClass('hidden');
+ $('.projectAcl').addClass('hidden');
+ $('.programAcl').removeClass('hidden');
+ $('[name=projectAcl]').attr('disabled', 'disabled');
+ $('[name=programAcl]').removeAttr('disabled');
+ }
+ if(projectType == 'execution')
+ {
+ $('.projectName').removeClass('hidden');
+ $('.programAcl').addClass('hidden');
+ $('.projectAcl').removeClass('hidden');
+ $('[name=programAcl]').attr('disabled', 'disabled');
+ $('[name=projectAcl]').removeAttr('disabled');
+ }
return false;
}
})
@@ -120,6 +127,33 @@ $(function()
$('[name^=products]').prop('checked', false);
$('[name^=sprints]').prop('checked', false);
}
+
+ /* If the project is checked, the relevant form will be displayed according to the selected mode. */
+ $('[id^=sprints]').each(function()
+ {
+ if($(this).prop('checked'))
+ {
+ hiddenProject();
+ var projectType = $('input[name="projectType"]:checked').val();
+ if(projectType == 'project')
+ {
+ $('.projectName').addClass('hidden');
+ $('.projectAcl').addClass('hidden');
+ $('.programAcl').removeClass('hidden');
+ $('[name=projectAcl]').attr('disabled', 'disabled');
+ $('[name=programAcl]').removeAttr('disabled');
+ }
+ if(projectType == 'execution')
+ {
+ $('.projectName').removeClass('hidden');
+ $('.programAcl').addClass('hidden');
+ $('.projectAcl').removeClass('hidden');
+ $('[name=programAcl]').attr('disabled', 'disabled');
+ $('[name=projectAcl]').removeAttr('disabled');
+ }
+ return false;
+ }
+ })
})
$('#checkAllProducts').click(function()
@@ -139,6 +173,7 @@ $(function()
$('[name^=products]').prop('checked', false);
$('[name^=sprints]').prop('checked', false);
}
+ hiddenProject();
})
$('#checkAllProjects').click(function()
@@ -158,6 +193,7 @@ $(function()
$('[name^=products]').prop('checked', false);
$('[name^=sprints]').prop('checked', false);
}
+ hiddenProject();
})
programBegin = $('.programParams #begin').val();
@@ -170,7 +206,7 @@ $(function()
$('[name^=productLines]').change(function()
{
- var value = $(this).val();
+ var value = $(this).val();
var hidden = $('#line' + value).is(':hidden');
if($(this).prop('checked'))
{
@@ -178,8 +214,8 @@ $(function()
{
$('#checkAllProducts').prop('checked', true);
$('#checkAllProjects').prop('checked', true);
- $('[data-line=' + value + ']').prop('checked', true);
}
+ $('[data-line=' + value + ']').prop('checked', true);
}
else
{
@@ -188,8 +224,8 @@ $(function()
{
$('#checkAllProducts').prop('checked', false);
$('#checkAllProjects').prop('checked', false);
- $('[data-line=' + value + ']').prop('checked', false);
}
+ $('[data-line=' + value + ']').prop('checked', false);
}
var checked = true;
@@ -198,6 +234,34 @@ $(function()
if(!$(this).prop('checked') && $(this).val()) checked = false;
})
$('#checkAllLines').prop('checked', checked);
+
+ /* If the project is checked, the relevant form will be displayed according to the selected mode. */
+ $('[id^=sprints]').each(function()
+ {
+ if($(this).prop('checked'))
+ {
+ var projectType = $('input[name="projectType"]:checked').val();
+ if(projectType == 'project')
+ {
+ $('.projectName').addClass('hidden');
+ $('.projectAcl').addClass('hidden');
+ $('.programAcl').removeClass('hidden');
+ $('[name=projectAcl]').attr('disabled', 'disabled');
+ $('[name=programAcl]').removeAttr('disabled');
+ }
+ if(projectType == 'execution')
+ {
+ $('.projectName').removeClass('hidden');
+ $('.programAcl').addClass('hidden');
+ $('.projectAcl').removeClass('hidden');
+ $('[name=programAcl]').attr('disabled', 'disabled');
+ $('[name=projectAcl]').removeAttr('disabled');
+ }
+ hiddenProject();
+ return false;
+ }
+ })
+ hiddenProject();
})
$('[name^=lines]').change(function()
@@ -297,6 +361,32 @@ $(function()
})
$('#checkAllProducts').prop('checked', checkedProduct);
$('#checkAllProjects').prop('checked', checkedProduct);
+
+ $('[id^=sprints]').each(function()
+ {
+ if($(this).prop('checked'))
+ {
+ hiddenProject();
+ var projectType = $('input[name="projectType"]:checked').val();
+ if(projectType == 'project')
+ {
+ $('.projectName').addClass('hidden');
+ $('.projectAcl').addClass('hidden');
+ $('.programAcl').removeClass('hidden');
+ $('[name=projectAcl]').attr('disabled', 'disabled');
+ $('[name=programAcl]').removeAttr('disabled');
+ }
+ if(projectType == 'execution')
+ {
+ $('.projectName').removeClass('hidden');
+ $('.programAcl').addClass('hidden');
+ $('.projectAcl').removeClass('hidden');
+ $('[name=programAcl]').attr('disabled', 'disabled');
+ $('[name=projectAcl]').removeAttr('disabled');
+ }
+ return false;
+ }
+ })
})
$('[name^=products]').change(function()
@@ -385,6 +475,10 @@ $(function()
$('.createExecutionTip').removeClass('hidden');
$('.createProjectTip').addClass('hidden');
$('.projectName').removeClass('hidden');
+ $('.programAcl').addClass('hidden');
+ $('.projectAcl').removeClass('hidden');
+ $('[name=programAcl]').attr('disabled', 'disabled');
+ $('[name=projectAcl]').removeAttr('disabled');
}
if($(this).val() == 'project')
@@ -392,6 +486,10 @@ $(function()
$('.createProjectTip').removeClass('hidden');
$('.createExecutionTip').addClass('hidden');
$('.projectName').addClass('hidden');
+ $('.projectAcl').addClass('hidden');
+ $('.programAcl').removeClass('hidden');
+ $('[name=projectAcl]').attr('disabled', 'disabled');
+ $('[name=programAcl]').removeAttr('disabled');
}
})
});
diff --git a/module/upgrade/lang/de.php b/module/upgrade/lang/de.php
index c3b1cf5533..b7a8fc1097 100644
--- a/module/upgrade/lang/de.php
+++ b/module/upgrade/lang/de.php
@@ -112,6 +112,8 @@ $lang->upgrade->repo = 'Repo';
$lang->upgrade->mergeRepo = 'Merge Repo';
$lang->upgrade->setProgram = 'Set the project to which the program belongs';
$lang->upgrade->dataMethod = 'Data migration method';
+$lang->upgrade->begin = 'Begin Date';
+$lang->upgrade->end = 'End Date';
$lang->upgrade->newProgram = 'Create';
$lang->upgrade->projectEmpty = 'Project must be not empty.';
@@ -130,11 +132,12 @@ $lang->upgrade->projectType['project'] = "Upgrade the historical {$lang->proje
$lang->upgrade->projectType['execution'] = "Upgrade the historical {$lang->projectCommon} as an execution";
$lang->upgrade->createProjectTip = <<
The system will create an execution with the same name as the {$lang->projectCommon} according to the history {$lang->projectCommon}, and replace the previous {$lang->projectCommon} Data such as tasks, requirements, and bugs are migrated to execution.
+After the upgrade, the existing {$lang->projectCommon} will be Project in the new version.
+ZenTao will create an item in Execute with the same name of {$lang->projectCommon} according to the data in {$lang->projectCommon}, and move the tasks, stories, and bugs in {$lang->projectCommon} to it.
+EOT; +$lang->upgrade->createExecutionTip = <<After the upgrade, the data of existing {$lang->projectCommon} will be in a Project - Execute of the new version .
EOT; -$lang->upgrade->createExecutionTip = <<The system will create an execution with the same name as the {$lang->projectCommon} according to the history {$lang->projectCommon}, and replace the previous {$lang->projectCommon} Data such as tasks, requirements, and bugs are migrated to execution.
+After the upgrade, the existing {$lang->projectCommon} will be Project in the new version.
+ZenTao will create an item in Execute with the same name of {$lang->projectCommon} according to the data in {$lang->projectCommon}, and move the tasks, stories, and bugs in {$lang->projectCommon} to it.
+EOT; +$lang->upgrade->createExecutionTip = <<After the upgrade, the data of existing {$lang->projectCommon} will be in a Project - Execute of the new version .
EOT; -$lang->upgrade->createExecutionTip = <<The system will create an execution with the same name as the {$lang->projectCommon} according to the history {$lang->projectCommon}, and replace the previous {$lang->projectCommon} Data such as tasks, requirements, and bugs are migrated to execution.
+After the upgrade, the existing {$lang->projectCommon} will be Project in the new version.
+ZenTao will create an item in Execute with the same name of {$lang->projectCommon} according to the data in {$lang->projectCommon}, and move the tasks, stories, and bugs in {$lang->projectCommon} to it.
+EOT; +$lang->upgrade->createExecutionTip = <<After the upgrade, the data of existing {$lang->projectCommon} will be in a Project - Execute of the new version .
EOT; -$lang->upgrade->createExecutionTip = <<The system will create an execution with the same name as the {$lang->projectCommon} according to the history {$lang->projectCommon}, and replace the previous {$lang->projectCommon} Data such as tasks, requirements, and bugs are migrated to execution.
+After the upgrade, the existing {$lang->projectCommon} will be Project in the new version.
+ZenTao will create an item in Execute with the same name of {$lang->projectCommon} according to the data in {$lang->projectCommon}, and move the tasks, stories, and bugs in {$lang->projectCommon} to it.
+EOT; +$lang->upgrade->createExecutionTip = <<After the upgrade, the data of existing {$lang->projectCommon} will be in a Project - Execute of the new version .
EOT; -$lang->upgrade->createExecutionTip = <<系统会把历史的{$lang->projectCommon}作为迭代进行升级。
+升级后历史的{$lang->projectCommon}数据将对应新版本中项目下的执行。
EOT; include dirname(__FILE__) . '/version.php'; diff --git a/module/upgrade/model.php b/module/upgrade/model.php index 654de76678..e722536278 100644 --- a/module/upgrade/model.php +++ b/module/upgrade/model.php @@ -4261,7 +4261,7 @@ class upgradeModel extends model $program->openedBy = $account; $program->openedDate = helper::now(); $program->openedVersion = $this->config->version; - $program->acl = 'open'; + $program->acl = isset($data->programAcl) ? $data->programAcl : 'open'; $program->days = $this->computeDaysDelta($program->begin, $program->end); $this->app->loadLang('program'); @@ -4327,66 +4327,97 @@ class upgradeModel extends model if(isset($data->newProject)) { - if(!$this->post->longTime and !$this->post->end) die(js::alert(sprintf($this->lang->error->notempty, $this->lang->program->end))); + if(!$this->post->longTime and !$this->post->end) die(js::alert(sprintf($this->lang->error->notempty, $this->lang->upgrade->end))); - /* Insert project. */ - $project = new stdclass(); - $project->name = $data->projectName; - $project->type = 'project'; - $project->model = 'scrum'; - $project->parent = $programID; - $project->status = $data->projectStatus; - $project->begin = $data->begin; - $project->end = isset($data->end) ? $data->end : LONG_TIME; - $project->days = $this->computeDaysDelta($project->begin, $project->end); - $project->PM = $data->PM; - $project->auth = 'extend'; - $project->openedBy = $account; - $project->openedDate = helper::now(); - $project->openedVersion = $this->config->version; - $project->lastEditedBy = $account; - $project->lastEditedDate = helper::now(); - $project->acl = $data->acl; - - $programDate = $this->dao->select('begin,end')->from(TABLE_PROGRAM)->where('id')->eq($programID)->fetch(); - if($data->begin < $programDate->begin) $this->dao->update(TABLE_PROGRAM)->set('begin')->eq($data->begin)->where('id')->eq($programID)->exec(); - if($data->end > $programDate->end) $this->dao->update(TABLE_PROGRAM)->set('end')->eq($data->end)->where('id')->eq($programID)->exec(); - - $this->dao->insert(TABLE_PROJECT)->data($project) - ->batchcheck('name', 'notempty') - ->check('name', 'unique', "deleted='0' and type = 'project'") - ->exec(); - if(dao::isError()) return false; - - $projectID = $this->dao->lastInsertId(); - $this->dao->update(TABLE_PROJECT) - ->set('grade')->eq(2) - ->set('path')->eq(",{$programID},{$projectID},") - ->set('`order`')->eq($projectID * 5) - ->where('id')->eq($projectID) - ->exec(); - - /* Create doc lib. */ + /* Create a project. */ + $this->loadModel('action'); $this->app->loadLang('doc'); - $lib = new stdclass(); - $lib->project = $projectID; - $lib->name = $this->lang->doclib->main['project']; - $lib->type = 'project'; - $lib->main = '1'; - $lib->acl = $project->acl != 'program' ? $project->acl : 'custom'; - $this->dao->insert(TABLE_DOCLIB)->data($lib)->exec(); - - $this->loadModel('action')->create('project', $projectID, 'openedbysystem'); - if($data->projectStatus == 'closed') $this->loadModel('action')->create('project', $projectID, 'closedbysystem'); + if($data->projectType == 'execution') + { + $projectList = $this->createProject($programID, $data); + } + else + { + $nameList = $this->dao->select('id,name')->from(TABLE_PROJECT)->where('id')->in($projectIdList)->fetchPairs(); + foreach($projectIdList as $project) + { + $data->projectName = $nameList[$project]; + $projectList[$project] = $this->createProject($programID, $data); + } + } } else { - $projectID = $data->projects; - $this->dao->update(TABLE_PROJECT)->set('status')->eq($data->projectStatus)->where('id')->eq($projectID)->exec(); - if($data->projectStatus == 'closed') $this->loadModel('action')->create('project', $projectID, 'openedbysystem'); + $projectList = $data->projects; + $this->dao->update(TABLE_PROJECT)->set('status')->eq($data->projectStatus)->where('id')->eq($projectList)->exec(); + if($data->projectStatus == 'closed') $this->loadModel('action')->create('project', $projectList, 'openedbysystem'); } - return array($programID, $projectID, $lineID); + return array($programID, $projectList, $lineID); + } + + /** + * Create a project. + * + * @param int $programID + * @param object $data + * @access public + * @return int|bool + */ + public function createProject($programID = 0, $data = null) + { + $now = helper::now(); + $account = isset($this->app->user->account) ? $this->app->user->account : ''; + + /* Insert project. */ + $project = new stdclass(); + $project->name = $data->projectName; + $project->type = 'project'; + $project->model = 'scrum'; + $project->parent = $programID; + $project->status = $data->projectStatus; + $project->begin = $data->begin; + $project->end = isset($data->end) ? $data->end : LONG_TIME; + $project->days = $this->computeDaysDelta($project->begin, $project->end); + $project->PM = $data->PM; + $project->auth = 'extend'; + $project->openedBy = $account; + $project->openedDate = $now; + $project->openedVersion = $this->config->version; + $project->lastEditedBy = $account; + $project->lastEditedDate = $now; + $project->acl = isset($data->projectAcl) ? $data->projectAcl : 'open'; + + $programDate = $this->dao->select('begin,end')->from(TABLE_PROGRAM)->where('id')->eq($programID)->fetch(); + if($data->begin < $programDate->begin) $this->dao->update(TABLE_PROGRAM)->set('begin')->eq($data->begin)->where('id')->eq($programID)->exec(); + if($data->end > $programDate->end) $this->dao->update(TABLE_PROGRAM)->set('end')->eq($data->end)->where('id')->eq($programID)->exec(); + + $this->dao->insert(TABLE_PROJECT)->data($project) + ->batchcheck('name', 'notempty') + ->check('name', 'unique', "deleted='0' and type = 'project'") + ->exec(); + if(dao::isError()) return false; + + $projectID = $this->dao->lastInsertId(); + $this->dao->update(TABLE_PROJECT) + ->set('grade')->eq(2) + ->set('path')->eq(",{$programID},{$projectID},") + ->set('`order`')->eq($projectID * 5) + ->where('id')->eq($projectID) + ->exec(); + + /* Create doc lib. */ + $lib = new stdclass(); + $lib->project = $projectID; + $lib->name = $this->lang->doclib->main['project']; + $lib->type = 'project'; + $lib->main = '1'; + $lib->acl = $project->acl != 'program' ? $project->acl : 'custom'; + $this->dao->insert(TABLE_DOCLIB)->data($lib)->exec(); + + $this->action->create('project', $projectID, 'openedbysystem'); + if($data->projectStatus == 'closed') $this->action->create('project', $projectID, 'closedbysystem'); + return $projectID; } /** diff --git a/module/upgrade/view/createprogram.html.php b/module/upgrade/view/createprogram.html.php index ec5478e7b4..a6b2c77f02 100644 --- a/module/upgrade/view/createprogram.html.php +++ b/module/upgrade/view/createprogram.html.php @@ -1,4 +1,4 @@ -| lang->upgrade->projectType, 'project');?> | ||
| upgrade->createProjectTip?> | ||
| project->acl;?> | -project->subAclList, 'open', '', 'block'));?> | +program->aclList, 'open', '', 'block'));?> | +
|---|