diff --git a/module/common/lang/de.php b/module/common/lang/de.php
index 3a5e9a4571..aa018429a3 100644
--- a/module/common/lang/de.php
+++ b/module/common/lang/de.php
@@ -160,7 +160,7 @@ $lang->program->menu->browse = array('link' => 'Program|program|pgmbrowse|', 'a
$lang->PRJ = new stdclass();
$lang->PRJ->menu = new stdclass();
-$lang->PRJ->menu->browse = array('link' => 'Project|program|prjbrowse|', 'alias' => 'prjcreate,prjedit,prjgroup,prjmanagepriv,prjmanageview,prjmanagemembers');
+$lang->PRJ->menu->browse = array('link' => 'Project|program|prjbrowse|', 'alias' => 'prjcreate,prjedit,prjgroup,prjmanagepriv,prjmanageview,prjmanagemembers,prjbatchedit');
$lang->program->viewMenu = new stdclass();
$lang->program->viewMenu->product = array('link' => 'Product|program|pgmproduct|program=%s', 'alias' => 'view');
diff --git a/module/common/lang/en.php b/module/common/lang/en.php
index 43f27718de..a712f2b8a3 100644
--- a/module/common/lang/en.php
+++ b/module/common/lang/en.php
@@ -160,7 +160,7 @@ $lang->program->menu->browse = array('link' => 'Program|program|pgmbrowse|', 'al
$lang->PRJ = new stdclass();
$lang->PRJ->menu = new stdclass();
-$lang->PRJ->menu->browse = array('link' => 'Project|program|prjbrowse|', 'alias' => 'prjcreate,prjedit,prjgroup,prjmanagepriv,prjmanageview,prjmanagemembers');
+$lang->PRJ->menu->browse = array('link' => 'Project|program|prjbrowse|', 'alias' => 'prjcreate,prjedit,prjgroup,prjmanagepriv,prjmanageview,prjmanagemembers,prjbatchedit');
$lang->program->viewMenu = new stdclass();
$lang->program->viewMenu->product = array('link' => 'Product|program|pgmproduct|program=%s', 'alias' => 'view');
diff --git a/module/common/lang/fr.php b/module/common/lang/fr.php
index 7bb8f96ce0..4056c3feb5 100644
--- a/module/common/lang/fr.php
+++ b/module/common/lang/fr.php
@@ -160,7 +160,7 @@ $lang->program->menu->browse = array('link' => 'Program|program|pgmbrowse|', 'a
$lang->PRJ = new stdclass();
$lang->PRJ->menu = new stdclass();
-$lang->PRJ->menu->browse = array('link' => 'Project|program|prjbrowse|', 'alias' => 'prjcreate,prjedit,prjgroup,prjmanagepriv,prjmanageview,prjmanagemembers');
+$lang->PRJ->menu->browse = array('link' => 'Project|program|prjbrowse|', 'alias' => 'prjcreate,prjedit,prjgroup,prjmanagepriv,prjmanageview,prjmanagemembers,prjbatchedit');
$lang->program->viewMenu = new stdclass();
$lang->program->viewMenu->product = array('link' => 'Product|program|pgmproduct|program=%s', 'alias' => 'view');
diff --git a/module/common/lang/vi.php b/module/common/lang/vi.php
index c01b1f4f10..3c951da3ab 100644
--- a/module/common/lang/vi.php
+++ b/module/common/lang/vi.php
@@ -160,7 +160,7 @@ $lang->program->menu->browse = array('link' => 'Program|program|pgmbrowse|', 'al
$lang->PRJ = new stdclass();
$lang->PRJ->menu = new stdclass();
-$lang->PRJ->menu->browse = array('link' => 'Project|program|prjbrowse|', 'alias' => 'prjcreate,prjedit,prjgroup,prjmanagepriv,prjmanageview,prjmanagemembers');
+$lang->PRJ->menu->browse = array('link' => 'Project|program|prjbrowse|', 'alias' => 'prjcreate,prjedit,prjgroup,prjmanagepriv,prjmanageview,prjmanagemembers,prjbatchedit');
$lang->program->viewMenu = new stdclass();
$lang->program->viewMenu->product = array('link' => 'Product|program|pgmproduct|program=%s', 'alias' => 'view');
diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php
index 7aff5c4c7f..a29e9c3d4c 100644
--- a/module/common/lang/zh-cn.php
+++ b/module/common/lang/zh-cn.php
@@ -160,7 +160,7 @@ $lang->program->menu->browse = array('link' => '项目集|program|pgmbrowse|',
$lang->PRJ = new stdclass();
$lang->PRJ->menu = new stdclass();
-$lang->PRJ->menu->browse = array('link' => '项目|program|prjbrowse|', 'alias' => 'prjcreate,prjedit,prjgroup,prjmanagepriv,prjmanageview,prjmanagemembers,prjmanageproducts,prjwhitelist,prjaddwhitelist');
+$lang->PRJ->menu->browse = array('link' => '项目|program|prjbrowse|', 'alias' => 'prjcreate,prjedit,prjgroup,prjmanagepriv,prjmanageview,prjmanagemembers,prjmanageproducts,prjwhitelist,prjaddwhitelist,prjbatchedit');
$lang->program->viewMenu = new stdclass();
$lang->program->viewMenu->product = array('link' => '产品|program|pgmproduct|program=%s', 'alias' => 'view');
diff --git a/module/common/lang/zh-tw.php b/module/common/lang/zh-tw.php
index 5389bacb07..d3d7207dd1 100644
--- a/module/common/lang/zh-tw.php
+++ b/module/common/lang/zh-tw.php
@@ -160,7 +160,7 @@ $lang->program->menu->browse = array('link' => '項目集|program|pgmbrowse|',
$lang->PRJ = new stdclass();
$lang->PRJ->menu = new stdclass();
-$lang->PRJ->menu->browse = array('link' => '項目|program|prjbrowse|', 'alias' => 'prjcreate,prjedit,prjgroup,prjmanagepriv,prjmanageview,prjmanagemembers,prjmanageproducts,prjwhitelist,prjaddwhitelist');
+$lang->PRJ->menu->browse = array('link' => '項目|program|prjbrowse|', 'alias' => 'prjcreate,prjedit,prjgroup,prjmanagepriv,prjmanageview,prjmanagemembers,prjmanageproducts,prjwhitelist,prjaddwhitelist,prjbatchedit');
$lang->program->viewMenu = new stdclass();
$lang->program->viewMenu->product = array('link' => '產品|program|pgmproduct|program=%s', 'alias' => 'view');
diff --git a/module/group/lang/resource.php b/module/group/lang/resource.php
index 0034950980..5e7710c314 100644
--- a/module/group/lang/resource.php
+++ b/module/group/lang/resource.php
@@ -174,47 +174,48 @@ $lang->todo->methodOrder[80] = 'batchClose';
/* Program. */
$lang->resource->program = new stdclass();
-$lang->resource->program->createGuide = 'createGuide';
+$lang->resource->program->createGuide = 'createGuide';
//$lang->resource->program->PGMIndex = 'PGMIndex';
-$lang->resource->program->PGMBrowse = 'PGMBrowse';
-$lang->resource->program->PGMProduct = 'PGMProduct';
-$lang->resource->program->PGMCreate = 'PGMCreate';
-$lang->resource->program->PGMEdit = 'PGMEdit';
-$lang->resource->program->PGMStart = 'PGMStart';
-$lang->resource->program->PGMSuspend = 'PGMSuspend';
-$lang->resource->program->PGMActivate = 'PGMActivate';
-$lang->resource->program->PGMClose = 'PGMClose';
-$lang->resource->program->PGMDelete = 'PGMDelete';
-$lang->resource->program->PGMProject = 'PGMProject';
-$lang->resource->program->PGMStakeholder = 'PGMStakeholder';
-$lang->resource->program->createStakeholder = 'createStakeholder';
-$lang->resource->program->unlinkStakeholder = 'unlinkStakeholder';
-$lang->resource->program->batchUnlinkStakeholders = 'batchUnlinkStakeholders';
-$lang->resource->program->export = 'export';
-$lang->resource->program->index = 'PRJIndex';
-$lang->resource->program->PRJBrowse = 'PRJBrowse';
-$lang->resource->program->PRJProgramTitle = 'PRJModuleOpen';
-$lang->resource->program->PRJCreate = 'PRJCreate';
-$lang->resource->program->PRJEdit = 'PRJEdit';
-$lang->resource->program->PRJGroup = 'PRJGroup';
-$lang->resource->program->PRJCreateGroup = 'PRJCreateGroup';
-$lang->resource->program->PRJManageView = 'PRJManageView';
-$lang->resource->program->PRJManagePriv = 'PRJManagePriv';
-$lang->resource->program->PRJManageMembers = 'PRJManageMembers';
-$lang->resource->program->PRJManageGroupMember = 'PRJManageGroupMember';
-$lang->resource->program->PRJCopyGroup = 'PRJCopyGroup';
-$lang->resource->program->PRJEditGroup = 'PRJEditGroup';
-$lang->resource->program->PRJStart = 'PRJStart';
-$lang->resource->program->PRJSuspend = 'PRJSuspend';
-$lang->resource->program->PRJClose = 'PRJClose';
-$lang->resource->program->PRJActivate = 'PRJActivate';
-$lang->resource->program->PRJDelete = 'PRJDelete';
-$lang->resource->program->PRJView = 'PRJView';
-$lang->resource->program->PRJWhitelist = 'PRJWhitelist';
-$lang->resource->program->PRJAddWhitelist = 'PRJAddWhitelist';
-$lang->resource->program->unbindWhielist = 'unbindWhielist';
-$lang->resource->program->PRJManageProducts = 'PRJManageProducts';
-$lang->resource->program->view = 'view';
+$lang->resource->program->PGMBrowse = 'PGMBrowse';
+$lang->resource->program->PGMProduct = 'PGMProduct';
+$lang->resource->program->PGMCreate = 'PGMCreate';
+$lang->resource->program->PGMEdit = 'PGMEdit';
+$lang->resource->program->PGMStart = 'PGMStart';
+$lang->resource->program->PGMSuspend = 'PGMSuspend';
+$lang->resource->program->PGMActivate = 'PGMActivate';
+$lang->resource->program->PGMClose = 'PGMClose';
+$lang->resource->program->PGMDelete = 'PGMDelete';
+$lang->resource->program->PGMProject = 'PGMProject';
+$lang->resource->program->PGMStakeholder = 'PGMStakeholder';
+$lang->resource->program->createStakeholder = 'createStakeholder';
+$lang->resource->program->unlinkStakeholder = 'unlinkStakeholder';
+$lang->resource->program->batchUnlinkStakeholders = 'batchUnlinkStakeholders';
+$lang->resource->program->export = 'export';
+$lang->resource->program->index = 'PRJIndex';
+$lang->resource->program->PRJBrowse = 'PRJBrowse';
+$lang->resource->program->PRJProgramTitle = 'PRJModuleOpen';
+$lang->resource->program->PRJCreate = 'PRJCreate';
+$lang->resource->program->PRJEdit = 'PRJEdit';
+$lang->resource->program->PRJBatchEdit = 'PRJBatchEdit';
+$lang->resource->program->PRJGroup = 'PRJGroup';
+$lang->resource->program->PRJCreateGroup = 'PRJCreateGroup';
+$lang->resource->program->PRJManageView = 'PRJManageView';
+$lang->resource->program->PRJManagePriv = 'PRJManagePriv';
+$lang->resource->program->PRJManageMembers = 'PRJManageMembers';
+$lang->resource->program->PRJManageGroupMember = 'PRJManageGroupMember';
+$lang->resource->program->PRJCopyGroup = 'PRJCopyGroup';
+$lang->resource->program->PRJEditGroup = 'PRJEditGroup';
+$lang->resource->program->PRJStart = 'PRJStart';
+$lang->resource->program->PRJSuspend = 'PRJSuspend';
+$lang->resource->program->PRJClose = 'PRJClose';
+$lang->resource->program->PRJActivate = 'PRJActivate';
+$lang->resource->program->PRJDelete = 'PRJDelete';
+$lang->resource->program->PRJView = 'PRJView';
+$lang->resource->program->PRJWhitelist = 'PRJWhitelist';
+$lang->resource->program->PRJAddWhitelist = 'PRJAddWhitelist';
+$lang->resource->program->unbindWhielist = 'unbindWhielist';
+$lang->resource->program->PRJManageProducts = 'PRJManageProducts';
+$lang->resource->program->view = 'view';
$lang->program->methodOrder[0] = 'createGuide';
//$lang->program->methodOrder[5] = 'PGMIndex';
@@ -238,6 +239,7 @@ $lang->program->methodOrder[90] = 'PRJBrowse';
$lang->program->methodOrder[95] = 'PRJProgramTitle';
$lang->program->methodOrder[100] = 'PRJCreate';
$lang->program->methodOrder[105] = 'PRJEdit';
+$lang->program->methodOrder[106] = 'PRJBatchEdit';
$lang->program->methodOrder[110] = 'PRJGroup';
$lang->program->methodOrder[115] = 'PRJCreateGroup';
$lang->program->methodOrder[120] = 'PRJManageView';
diff --git a/module/my/view/project.html.php b/module/my/view/project.html.php
index 44251c75a6..fb0881cab1 100644
--- a/module/my/view/project.html.php
+++ b/module/my/view/project.html.php
@@ -79,7 +79,7 @@
- id&programID=$project->parent&from=PRJ", $project, 'list', 'edit', '', '', false, "data-group='project'", '', $project->id);?>
+ id&from=PRJ", $project, 'list', 'edit', '', '', false, "data-group='project'", '', $project->id);?>
id", $project, 'list', 'group', '', '', false, "data-group='project'", '', $project->id);?>
id", $project, 'list', 'lock', '', '', false, "data-group='project'", '', $project->id);?>
diff --git a/module/program/config.php b/module/program/config.php
index 40c93befa2..affe69d5e5 100644
--- a/module/program/config.php
+++ b/module/program/config.php
@@ -32,7 +32,7 @@ $config->program->PRJCreate->requiredFields = 'name,code,begin,end';
$config->program->PRJEdit->requiredFields = 'name,code,begin,end';
$config->program->sortFields = new stdclass();
-$config->program->sortFields->idAB = 'id';
+$config->program->sortFields->id = 'id';
$config->program->sortFields->begin = 'begin';
$config->program->sortFields->end = 'end';
$config->program->sortFields->PRJStatus = 'status';
@@ -40,12 +40,12 @@ $config->program->sortFields->PRJBudget = 'budget';
global $lang;
$config->program->datatable = new stdclass();
-$config->program->datatable->defaultField = array('idAB', 'PRJName', 'PM', 'PRJStatus', 'begin', 'end', 'PRJBudget', 'teamCount','PRJEstimate','PRJConsume', 'PRJProgress', 'actions');
+$config->program->datatable->defaultField = array('id', 'PRJName', 'PM', 'PRJStatus', 'begin', 'end', 'PRJBudget', 'teamCount','PRJEstimate','PRJConsume', 'PRJProgress', 'actions');
-$config->program->datatable->fieldList['idAB']['title'] = 'idAB';
-$config->program->datatable->fieldList['idAB']['fixed'] = 'left';
-$config->program->datatable->fieldList['idAB']['width'] = '60';
-$config->program->datatable->fieldList['idAB']['required'] = 'yes';
+$config->program->datatable->fieldList['id']['title'] = 'ID';
+$config->program->datatable->fieldList['id']['fixed'] = 'left';
+$config->program->datatable->fieldList['id']['width'] = '60';
+$config->program->datatable->fieldList['id']['required'] = 'yes';
$config->program->datatable->fieldList['PRJName']['title'] = 'PRJName';
$config->program->datatable->fieldList['PRJName']['fixed'] = 'left';
diff --git a/module/program/control.php b/module/program/control.php
index 2dc3aefa98..3a2bd2cf85 100644
--- a/module/program/control.php
+++ b/module/program/control.php
@@ -951,17 +951,19 @@ class program extends control
* Edit a project.
*
* @param int $projectID
- * @param int $programID
* @param string $from PRJ|pgmbrowse|pgmproject
* @access public
* @return void
*/
- public function PRJEdit($projectID = 0, $programID = 0, $from = 'PRJ')
+ public function PRJEdit($projectID = 0, $from = 'PRJ')
{
$this->app->loadLang('custom');
$this->app->loadLang('project');
$this->loadModel('productplan');
+ $project = $this->program->getPRJByID($projectID);
+ $programID = $project->parent;
+
/* Navigation stay in program when enter from program list. */
if($from == 'PRJ')
{
@@ -998,12 +1000,11 @@ class program extends control
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $locateLink));
}
- $project = $this->program->getPRJByID($projectID);
$linkedBranches = array();
$productPlans = array(0 => '');
- $allProducts = $programID != $project->parent ? $this->program->getPGMProductPairs($programID) : $this->program->getPGMProductPairs($project->parent, 'assign', 'noclosed');
- $linkedProducts = $programID != $project->parent ? array() : $this->project->getProducts($projectID);
+ $allProducts = $this->program->getPGMProductPairs($project->parent, 'assign', 'noclosed');
+ $linkedProducts = $this->project->getProducts($projectID);
$parentProgram = $this->program->getPGMByID($programID);
/* If the story of the product which linked the project, you don't allow to remove the product. */
@@ -1047,6 +1048,33 @@ class program extends control
$this->display();
}
+ /**
+ * Batch edit projects.
+ *
+ * @param string $from
+ * @param int $programID
+ * @access public
+ * @return void
+ */
+ public function PRJBatchEdit($from = 'prjbrowse', $programID = 0)
+ {
+ if($from == 'pgmproject')
+ {
+ $this->app->rawMethod = 'pgmproject';
+ $this->lang->program->switcherMenu = $this->program->getPGMSwitcher($programID, true);
+ $this->program->setPGMViewMenu($programID);
+ }
+
+ if($from == 'prjbrowse')
+ {
+ $this->lang->program->menu = $this->lang->PRJ->menu;
+ }
+
+ $projectIdList = $this->post->projectIdList;
+
+ $this->display();
+ }
+
/**
* View a project.
*
@@ -1780,4 +1808,42 @@ class program extends control
echo $this->fetch('program', 'PGMProduct', "programID=$programID");
}
+
+ /**
+ * AJAX: Check products.
+ *
+ * @param int $programID
+ * @param int $projectID
+ * @access public
+ * @return array
+ */
+ public function ajaxCheckProduct($programID, $projectID)
+ {
+ $project = $this->program->getPRJByID($projectID);
+ $oldTopPGM = $this->program->getTopPGMByID($project->parent);
+ $newTopPGM = $this->program->getTopPGMByID($programID);
+
+ if($oldTopPGM == $newTopPGM) die();
+
+ $response = array();
+ $response['result'] = true;
+
+ $multiLinkedProducts = $this->program->getMultiLinkedProducts($projectID);
+ if($multiLinkedProducts)
+ {
+ $multiLinkedProjects = array();
+ foreach($multiLinkedProducts as $productID => $product)
+ {
+ $multiLinkedProjects[$productID] = $this->loadModel('product')->getProjectPairsByProduct($productID);
+ }
+ $response['result'] = false;
+ $response['message'] = $multiLinkedProducts;
+ $response['multiLinkedProjects'] = $multiLinkedProjects;
+ }
+ else
+ {
+ $response['message'] = $this->lang->program->changeProgramTip;
+ }
+ die(json_encode($response));
+ }
}
diff --git a/module/program/js/prjedit.js b/module/program/js/prjedit.js
index 583e9019f9..5a3173a6b7 100644
--- a/module/program/js/prjedit.js
+++ b/module/program/js/prjedit.js
@@ -1,9 +1,53 @@
$(function()
{
- $('#parent').click(function()
+ $('#parent').change(function()
{
- if(!confirm(PGMChangeTips)) return false;
- })
+ var programID = $(this).val();
+
+ link = createLink('program', 'ajaxCheckProduct', 'programID=' + programID + '&projectID=' + projectID);
+ $.getJSON(link, function(data)
+ {
+ var changed = true;
+
+ if(data && data.result)
+ {
+ changed = confirm(data.message);
+ if(changed)
+ {
+ $('#productsBox select').prop('disabled', true).trigger("chosen:updated");
+ }
+ }
+
+ if(data && !data.result)
+ {
+ $('#promptTable td').remove();
+ for(var i in data.message)
+ {
+ var product = data.message[i];
+ $('#promptTable').append("
| " + product +" " + linkedProjectsTip +" |
");
+ for(var j in data.multiLinkedProjects)
+ {
+ if(i == j)
+ {
+ html = ''
+ for(k in data.multiLinkedProjects[j])
+ {
+ var project = data.multiLinkedProjects[j][k];
+ html += "" + project +"
";
+ }
+ $('#promptTable').append("| " + html + " |
");
+ }
+ }
+ }
+
+ changed = false;
+ $('#promptBox').modal({show: true});
+ }
+
+ if(!changed) $("#parent").val(oldParent).trigger("chosen:updated");
+ oldParent = $('#parent').val();
+ });
+ });
adjustProductBoxMargin();
adjustPlanBoxMargin();
@@ -39,24 +83,3 @@ function setAclList(programID)
$('.aclBox').html($('#PRJAcl').html());
}
}
-
-/**
- * Set parent program.
- *
- * @access public
- * @return void
- */
-function setParentProgram()
-{
- var parentProgram = $("#parent").val();
-
- if(confirm(PGMChangeTips))
- {
- location.href = createLink('program', 'PRJEdit', 'projectID=' + projectID + '&programID=' + parentProgram + '&from=' + from);
- }
- else
- {
- $('#parent').val(oldParent);
- $("#parent").trigger("chosen:updated");
- }
-}
diff --git a/module/program/lang/de.php b/module/program/lang/de.php
index 14015041e3..a547739255 100644
--- a/module/program/lang/de.php
+++ b/module/program/lang/de.php
@@ -5,8 +5,9 @@ $lang->program->PRJIndex = 'Dashboard';
$lang->program->PRJHome = 'Home';
$lang->program->PRJCreate = 'Create Project';
$lang->program->PRJEdit = 'Edit';
+$lang->program->PRJBatchEdit = 'Batch Edit Projects';
$lang->program->PRJView = 'Project View';
-$lang->program->PRJBatchEdit = 'Batch Edit';
+$lang->program->batchEdit = 'Batch Edit';
$lang->program->PRJBrowse = 'Projects';
$lang->program->PRJAll = 'All';
$lang->program->PRJStart = 'Start';
@@ -90,8 +91,12 @@ $lang->program->PRJLongTime = 'Long-Term Project';
$lang->program->future = 'TBD';
$lang->program->morePRJ = 'More Project';
-$lang->program->productNotEmpty = 'Please link products or create products.';
-$lang->program->existProductName = 'Product name already exists.';
+$lang->program->productNotEmpty = 'Please link products or create products.';
+$lang->program->existProductName = 'Product name already exists.';
+$lang->program->changeProgram = 'Change program';
+$lang->program->changeProgramTip = 'After modifying the program set, the products linked with the project will also modify the program set to which it belongs. Please confirm whether to modify it.';
+$lang->program->linkedProjectsTip = 'Linked projects are as follows';
+$lang->program->multiLinkedProductsTip = 'The following products linked to this project are also linked to other projects, please unlink before proceeding.';
$lang->program->unitList['CNY'] = 'RMB';
$lang->program->unitList['USD'] = 'USD';
@@ -266,7 +271,6 @@ $lang->program->PGMLongTime = 'Long-Term';
$lang->program->noPGM = 'No program.';
$lang->program->PGMShowClosed = 'Closed programs.';
$lang->program->PGMTips = 'If a parent item set is selected, products under that parent item set can be associated. If no item set is selected, a product with the same name as the item is created by default and associated with that item.';
-$lang->program->PGMChangeTips = 'After modifying the parent program set, the products associated with the project will be cleared, and the requirements, bugs and other data under the project will also be affected, is it modified?';
$lang->program->PGMAclList['private'] = "Private (accessible to project portfolio holders and stakeholders, stakeholders can follow up maintenance)";
$lang->program->PGMAclList['open'] = "Default(user who can visit the program can access it)";
diff --git a/module/program/lang/en.php b/module/program/lang/en.php
index 07ab8e20fa..dca155e9ba 100644
--- a/module/program/lang/en.php
+++ b/module/program/lang/en.php
@@ -5,8 +5,9 @@ $lang->program->PRJIndex = 'Dashboard';
$lang->program->PRJHome = 'Home';
$lang->program->PRJCreate = 'Create Project';
$lang->program->PRJEdit = 'Edit';
+$lang->program->PRJBatchEdit = 'Batch Edit Projects';
$lang->program->PRJView = 'Project View';
-$lang->program->PRJBatchEdit = 'Batch Edit';
+$lang->program->batchEdit = 'Batch Edit';
$lang->program->PRJBrowse = 'Projects';
$lang->program->PRJAll = 'All';
$lang->program->PRJStart = 'Start';
@@ -90,8 +91,12 @@ $lang->program->PRJLongTime = 'Long-Term Project';
$lang->program->future = 'TBD';
$lang->program->morePRJ = 'More Project';
-$lang->program->productNotEmpty = 'Please link products or create products.';
-$lang->program->existProductName = 'Product name already exists.';
+$lang->program->productNotEmpty = 'Please link products or create products.';
+$lang->program->existProductName = 'Product name already exists.';
+$lang->program->changeProgram = 'Change program';
+$lang->program->changeProgramTip = 'After modifying the program set, the products linked with the project will also modify the program set to which it belongs. Please confirm whether to modify it.';
+$lang->program->linkedProjectsTip = 'Linked projects are as follows';
+$lang->program->multiLinkedProductsTip = 'The following products linked to this project are also linked to other projects, please unlink before proceeding.';
$lang->program->unitList['CNY'] = 'RMB';
$lang->program->unitList['USD'] = 'USD';
@@ -266,7 +271,6 @@ $lang->program->PGMLongTime = 'Long-Term';
$lang->program->noPGM = 'No program.';
$lang->program->PGMShowClosed = 'Closed programs.';
$lang->program->PGMTips = 'If a parent item set is selected, products under that parent item set can be associated. If no item set is selected, a product with the same name as the item is created by default and associated with that item.';
-$lang->program->PGMChangeTips = 'After modifying the parent program set, the products associated with the project will be cleared, and the requirements, bugs and other data under the project will also be affected, is it modified?';
$lang->program->PGMAclList['private'] = "Private (accessible to project portfolio holders and stakeholders, stakeholders can follow up maintenance)";
$lang->program->PGMAclList['open'] = "Default(user who can visit the program can access it)";
diff --git a/module/program/lang/fr.php b/module/program/lang/fr.php
index 81b88bca01..1edad18b4f 100644
--- a/module/program/lang/fr.php
+++ b/module/program/lang/fr.php
@@ -5,8 +5,9 @@ $lang->program->PRJIndex = 'Dashboard';
$lang->program->PRJHome = 'Home';
$lang->program->PRJCreate = 'Create Project';
$lang->program->PRJEdit = 'Edit';
+$lang->program->PRJBatchEdit = 'Batch Edit Projects';
$lang->program->PRJView = 'Project View';
-$lang->program->PRJBatchEdit = 'Batch Edit';
+$lang->program->batchEdit = 'Batch Edit';
$lang->program->PRJBrowse = 'Projects';
$lang->program->PRJAll = 'All';
$lang->program->PRJStart = 'Start';
@@ -90,8 +91,12 @@ $lang->program->PRJLongTime = 'Long-Term Project';
$lang->program->future = 'TBD';
$lang->program->morePRJ = 'More Projects';
-$lang->program->productNotEmpty = 'Please link products or create products.';
-$lang->program->existProductName = 'Product name already exists.';
+$lang->program->productNotEmpty = 'Please link products or create products.';
+$lang->program->existProductName = 'Product name already exists.';
+$lang->program->changeProgram = 'Change program';
+$lang->program->changeProgramTip = 'After modifying the program set, the products linked with the project will also modify the program set to which it belongs. Please confirm whether to modify it.';
+$lang->program->linkedProjectsTip = 'Linked projects are as follows';
+$lang->program->multiLinkedProductsTip = 'The following products linked to this project are also linked to other projects, please unlink before proceeding.';
$lang->program->unitList['CNY'] = 'RMB';
$lang->program->unitList['USD'] = 'USD';
@@ -266,7 +271,6 @@ $lang->program->PGMLongTime = 'Long-Term';
$lang->program->noPGM = 'No program.';
$lang->program->PGMShowClosed = 'Closed programs.';
$lang->program->PGMTips = 'If a parent item set is selected, products under that parent item set can be associated. If no item set is selected, a product with the same name as the item is created by default and associated with that item.';
-$lang->program->PGMChangeTips = 'After modifying the parent program set, the products associated with the project will be cleared, and the requirements, bugs and other data under the project will also be affected, is it modified?';
$lang->program->PGMAclList['private'] = "Private (accessible to project portfolio holders and stakeholders, stakeholders can follow up maintenance)";
$lang->program->PGMAclList['open'] = "Default(user who can visit the program can access it)";
diff --git a/module/program/lang/vi.php b/module/program/lang/vi.php
index 81b88bca01..1edad18b4f 100644
--- a/module/program/lang/vi.php
+++ b/module/program/lang/vi.php
@@ -5,8 +5,9 @@ $lang->program->PRJIndex = 'Dashboard';
$lang->program->PRJHome = 'Home';
$lang->program->PRJCreate = 'Create Project';
$lang->program->PRJEdit = 'Edit';
+$lang->program->PRJBatchEdit = 'Batch Edit Projects';
$lang->program->PRJView = 'Project View';
-$lang->program->PRJBatchEdit = 'Batch Edit';
+$lang->program->batchEdit = 'Batch Edit';
$lang->program->PRJBrowse = 'Projects';
$lang->program->PRJAll = 'All';
$lang->program->PRJStart = 'Start';
@@ -90,8 +91,12 @@ $lang->program->PRJLongTime = 'Long-Term Project';
$lang->program->future = 'TBD';
$lang->program->morePRJ = 'More Projects';
-$lang->program->productNotEmpty = 'Please link products or create products.';
-$lang->program->existProductName = 'Product name already exists.';
+$lang->program->productNotEmpty = 'Please link products or create products.';
+$lang->program->existProductName = 'Product name already exists.';
+$lang->program->changeProgram = 'Change program';
+$lang->program->changeProgramTip = 'After modifying the program set, the products linked with the project will also modify the program set to which it belongs. Please confirm whether to modify it.';
+$lang->program->linkedProjectsTip = 'Linked projects are as follows';
+$lang->program->multiLinkedProductsTip = 'The following products linked to this project are also linked to other projects, please unlink before proceeding.';
$lang->program->unitList['CNY'] = 'RMB';
$lang->program->unitList['USD'] = 'USD';
@@ -266,7 +271,6 @@ $lang->program->PGMLongTime = 'Long-Term';
$lang->program->noPGM = 'No program.';
$lang->program->PGMShowClosed = 'Closed programs.';
$lang->program->PGMTips = 'If a parent item set is selected, products under that parent item set can be associated. If no item set is selected, a product with the same name as the item is created by default and associated with that item.';
-$lang->program->PGMChangeTips = 'After modifying the parent program set, the products associated with the project will be cleared, and the requirements, bugs and other data under the project will also be affected, is it modified?';
$lang->program->PGMAclList['private'] = "Private (accessible to project portfolio holders and stakeholders, stakeholders can follow up maintenance)";
$lang->program->PGMAclList['open'] = "Default(user who can visit the program can access it)";
diff --git a/module/program/lang/zh-cn.php b/module/program/lang/zh-cn.php
index 69cc46ed2a..49edca7809 100644
--- a/module/program/lang/zh-cn.php
+++ b/module/program/lang/zh-cn.php
@@ -5,8 +5,9 @@ $lang->program->PRJIndex = '项目仪表盘';
$lang->program->PRJHome = '项目主页';
$lang->program->PRJCreate = '创建项目';
$lang->program->PRJEdit = '编辑项目';
+$lang->program->PRJBatchEdit = '批量编辑项目';
$lang->program->PRJView = '项目概况';
-$lang->program->PRJBatchEdit = '批量编辑';
+$lang->program->batchEdit = '批量编辑';
$lang->program->PRJBrowse = '项目列表';
$lang->program->PRJAll = '所有项目';
$lang->program->PRJStart = '启动项目';
@@ -90,8 +91,12 @@ $lang->program->PRJLongTime = '长期';
$lang->program->future = '待定';
$lang->program->morePRJ = '更多项目';
-$lang->program->productNotEmpty = '请关联产品或创建产品。';
-$lang->program->existProductName = '产品名称已存在。';
+$lang->program->productNotEmpty = '请关联产品或创建产品。';
+$lang->program->existProductName = '产品名称已存在。';
+$lang->program->changeProgram = '修改项目集';
+$lang->program->changeProgramTip = '修改项目集后,该项目关联的产品也会同时修改所属项目集,请确认是否修改。';
+$lang->program->linkedProjectsTip = '关联的项目如下';
+$lang->program->multiLinkedProductsTip = '该项目关联的如下产品还关联了其他项目,请取消关联后再操作';
$lang->program->unitList['CNY'] = '人民币';
$lang->program->unitList['USD'] = '美元';
@@ -266,7 +271,6 @@ $lang->program->PGMLongTime = '长期项目';
$lang->program->noPGM = '暂时没有项目集';
$lang->program->PGMShowClosed = '显示已关闭';
$lang->program->PGMTips = '选择了父项目集,则可关联该父项目集下的产品。如果项目未选择任何项目集,则系统会默认创建一个和该项目同名的产品并关联该项目。';
-$lang->program->PGMChangeTips = '修改父项目集后,项目已关联的产品会被清空,并且项目下的需求、bug等数据也会受影响,是否修改?';
$lang->program->PGMAclList['private'] = "私有(项目集负责人和干系人可访问,干系人可后续维护)";
$lang->program->PGMAclList['open'] = "公开(有项目集视图权限,即可访问)";
diff --git a/module/program/lang/zh-tw.php b/module/program/lang/zh-tw.php
index 1b96bafa70..47f8ac3839 100644
--- a/module/program/lang/zh-tw.php
+++ b/module/program/lang/zh-tw.php
@@ -6,7 +6,7 @@ $lang->program->PRJHome = '項目主頁';
$lang->program->PRJCreate = '創建項目';
$lang->program->PRJEdit = '編輯項目';
$lang->program->PRJView = '項目概況';
-$lang->program->PRJBatchEdit = '批量編輯';
+$lang->program->batchEdit = '批量編輯';
$lang->program->PRJBrowse = '項目列表';
$lang->program->PRJAll = '所有項目';
$lang->program->PRJStart = '啟動項目';
@@ -266,7 +266,6 @@ $lang->program->PGMLongTime = '長期項目';
$lang->program->noPGM = '暫時沒有項目集';
$lang->program->PGMShowClosed = '顯示已關閉';
$lang->program->PGMTips = '選擇了父項目集,則可關聯該父項目集下的產品。如果項目未選擇任何項目集,則系統會預設創建一個和該項目同名的產品並關聯該項目。';
-$lang->program->PGMChangeTips = '修改父項目集後,項目已關聯的產品會被清空,並且項目下的需求、bug等數據也會受影響,是否修改?';
$lang->program->PGMAclList['private'] = "私有(項目集負責人和干係人可訪問,干係人可後續維護)";
$lang->program->PGMAclList['open'] = "公開(有項目集視圖權限,即可訪問)";
diff --git a/module/program/model.php b/module/program/model.php
index 4f9f2e6bb6..c2f65c35f0 100644
--- a/module/program/model.php
+++ b/module/program/model.php
@@ -456,6 +456,45 @@ class programModel extends model
->fetchPairs();
}
+ /**
+ * Get top program by id.
+ *
+ * @param int $programID
+ * @access public
+ * @return int
+ */
+ public function getTopPGMByID($programID)
+ {
+ $topPGM = 0;
+ if(empty($programID)) return $topPGM;
+
+ $program = $this->getPGMByID($programID);
+ list($topPGM) = explode(',', trim($program->path, ','));
+ return $topPGM;
+ }
+
+ /**
+ * Get Multiple linked products for project.
+ *
+ * @param int $projectID
+ * @access public
+ * @return array
+ */
+ public function getMultiLinkedProducts($projectID)
+ {
+ $linkedProducts = $this->dao->select('product')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($projectID)->fetchPairs();
+ $multiLinkedProducts = $this->dao->select('t3.id,t3.name')->from(TABLE_PROJECTPRODUCT)->alias('t1')
+ ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
+ ->leftJoin(TABLE_PRODUCT)->alias('t3')->on('t1.product = t3.id')
+ ->where('t1.product')->in($linkedProducts)
+ ->andWhere('t1.project')->ne($projectID)
+ ->andWhere('t2.deleted')->eq('0')
+ ->andWhere('t3.deleted')->eq('0')
+ ->fetchPairs('id', 'name');
+
+ return $multiLinkedProducts;
+ }
+
/**
* Get children by program id.
*
@@ -1149,15 +1188,15 @@ class programModel extends model
}
/**
- * Get project workhour info.
- *
- * @param int $projectID
+ * Get project workhour info.
+ *
+ * @param int $projectID
* @access public
- * @return object
+ * @return object
*/
public function getPRJWorkhour($projectID)
{
- $executions = $this->loadModel('project')->getExecutionPairs($projectID);
+ $executions = $this->loadModel('project')->getExecutionPairs($projectID);
$total = $this->dao->select('
ROUND(SUM(estimate), 2) AS totalEstimate,
@@ -1186,14 +1225,14 @@ class programModel extends model
/**
* Get project stat data .
- *
- * @param int $projectID
+ *
+ * @param int $projectID
* @access public
- * @return object
+ * @return object
*/
public function getPRJStatData($projectID)
{
- $executions = $this->loadModel('project')->getExecutionPairs($projectID);
+ $executions = $this->loadModel('project')->getExecutionPairs($projectID);
$storyCount = $this->dao->select('count(t2.story) as storyCount')->from(TABLE_STORY)->alias('t1')
->leftJoin(TABLE_PROJECTSTORY)->alias('t2')->on('t1.id = t2.story')
->where('t2.project')->eq($projectID)
@@ -1615,7 +1654,9 @@ class programModel extends model
*/
public function PRJUpdate($projectID = 0)
{
- $oldProject = $this->dao->findById($projectID)->from(TABLE_PROJECT)->fetch();
+ $oldProject = $this->dao->findById($projectID)->from(TABLE_PROJECT)->fetch();
+ $linkedProducts = $this->dao->select('product')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($projectID)->fetchPairs();
+ $_POST['products'] = isset($_POST['products']) ? $_POST['products'] : $linkedProducts;
$project = fixer::input('post')
->setDefault('team', substr($this->post->name, 0, 30))
@@ -1655,6 +1696,18 @@ class programModel extends model
}
}
+ /* Product belonging program set processing. */
+ $oldTopPGM = $this->getTopPGMByID($oldProject->parent);
+ $newTopPGM = $this->getTopPGMByID($project->parent);
+ if($oldTopPGM != $newTopPGM)
+ {
+ foreach($_POST['products'] as $productID => $product)
+ {
+ $this->dao->update(TABLE_PRODUCT)->set('program')->eq($newTopPGM)->where('id')->eq($productID)->exec();
+ }
+ }
+
+
/* Judge products not empty. */
$linkedProductsCount = 0;
foreach($_POST['products'] as $product)
@@ -1691,7 +1744,7 @@ class programModel extends model
if(!dao::isError())
{
- $this->loadModel('project')->updateProducts($projectID);
+ $this->loadModel('project')->updateProducts($projectID, $_POST['products']);
$this->file->updateObjectID($this->post->uid, $projectID, 'project');
$whitelist = explode(',', $project->whitelist);
@@ -1716,16 +1769,18 @@ class programModel extends model
*/
public function printCell($col, $project, $users, $programID = 0)
{
- $canOrder = common::hasPriv('program', 'PRJOrderUpdate');
- $account = $this->app->user->account;
- $id = $col->id;
+ $canOrder = common::hasPriv('program', 'PRJOrderUpdate');
+ $canBatchEdit = common::hasPriv('program', 'PRJBatchEdit');
+ $projectLink = helper::createLink('program', 'index', "projectID=$project->id", '', '', $project->id);
+ $account = $this->app->user->account;
+ $id = $col->id;
if($col->show)
{
$class = "c-$id";
$title = '';
- if($id == 'idAB') $class .= ' cell-id';
+ if($id == 'id') $class .= ' cell-id';
if($id == 'PRJName')
{
@@ -1759,11 +1814,17 @@ class programModel extends model
echo "";
switch($id)
{
- case 'idAB':
- printf('%03d', $project->id);
+ case 'id':
+ if($canBatchEdit)
+ {
+ echo html::checkbox('projectIdList', array($project->id => '')) . html::a($projectLink, sprintf('%03d', $project->id));
+ }
+ else
+ {
+ printf('%03d', $project->id);
+ }
break;
case 'PRJName':
- $projectLink = helper::createLink('program', 'index', "projectID=$project->id", '', '', $project->id);
echo html::a($projectLink, $project->name);
if($project->model === 'waterfall') echo "{$this->lang->program->waterfall}";
if($project->model === 'scrum') echo "{$this->lang->program->scrum}";
@@ -1823,7 +1884,7 @@ class programModel extends model
$from = $project->from == 'PRJ' ? 'PRJ' : 'pgmproject';
$openModule = $project->from == 'PRJ' ? 'project' : 'program';
- common::printIcon('program', 'PRJEdit', "projectID=$project->id&programID=$project->parent&from=$from", $project, 'list', 'edit', '', '', '', "data-group=$openModule", '', $project->id);
+ common::printIcon('program', 'PRJEdit', "projectID=$project->id&from=$from", $project, 'list', 'edit', '', '', '', "data-group=$openModule", '', $project->id);
common::printIcon('program', 'PRJManageMembers', "projectID=$project->id", $project, 'list', 'group', '', '', '', '', '', $project->id);
common::printIcon('program', 'PRJGroup', "projectID=$project->id&programID=$programID", $project, 'list', 'lock', '', '', '', '', '', $project->id);
diff --git a/module/program/view/pgmbrowsebylist.html.php b/module/program/view/pgmbrowsebylist.html.php
index 7c7d57c243..75995e8e89 100644
--- a/module/program/view/pgmbrowsebylist.html.php
+++ b/module/program/view/pgmbrowsebylist.html.php
@@ -94,7 +94,7 @@
- id&programID=$program->parent&from=pgmbrowse", $program, 'list', 'edit', '', '', '', "data-group='program'", '', $program->id);?>
+ id&from=pgmbrowse", $program, 'list', 'edit', '', '', '', "data-group='program'", '', $program->id);?>
id", $program, 'list', 'group', '', '', '', 'data-group="program"', '', $program->id);?>
id", $program, 'list', 'lock', '', '', '', 'data-group="program"', '', $program->id);?>
diff --git a/module/program/view/pgmproject.html.php b/module/program/view/pgmproject.html.php
index aa0bcbe88d..cd7f1a9181 100644
--- a/module/program/view/pgmproject.html.php
+++ b/module/program/view/pgmproject.html.php
@@ -45,13 +45,14 @@ js::set('browseType', $browseType);
$setting = $this->datatable->getSetting('program');
?>
+
id == 'PRJStatus' and $browseType !== 'all') $value->show = false;
- if($value->show) $this->datatable->printHead($value, $orderBy, $vars);
+ if($value->show) $this->datatable->printHead($value, $orderBy, $vars, $canBatchEdit);
}
?>
@@ -66,6 +67,19 @@ js::set('browseType', $browseType);
diff --git a/module/program/view/prjbatchedit.html.php b/module/program/view/prjbatchedit.html.php
new file mode 100644
index 0000000000..beb236de60
--- /dev/null
+++ b/module/program/view/prjbatchedit.html.php
@@ -0,0 +1,14 @@
+
+ * @package program
+ * @version $Id: prjbatchedit.html.php 4769 2021-02-020 11:13:21Z $
+ * @link https://www.zentao.net
+ */
+?>
+
+
diff --git a/module/program/view/prjbrowse.html.php b/module/program/view/prjbrowse.html.php
index e11048d48d..6b70341343 100644
--- a/module/program/view/prjbrowse.html.php
+++ b/module/program/view/prjbrowse.html.php
@@ -55,7 +55,7 @@ js::set('browseType', $browseType);
-
diff --git a/module/program/view/prjedit.html.php b/module/program/view/prjedit.html.php
index 0083dc241b..c2d8a16a21 100644
--- a/module/program/view/prjedit.html.php
+++ b/module/program/view/prjedit.html.php
@@ -17,11 +17,11 @@
program->errorSameProducts);?>
parent);?>
id);?>
-program->PGMChangeTips);?>
program->PRJLongTime);?>
program->notAllowRemoveProducts);?>
+program->linkedProjectsTip);?>
parent ? $lang->program->PGMPRJAclList : $lang->program->PRJAclList;?>
program->PRJEdit->requiredFields;?>
|