status == 'closed' ? 'disabled' : '';?>
- status != 'closed' and $browseType != 'involved' and !empty($unclosedSpace)) common::printLink('kanban', 'create', "spaceID={$space->id}&type={$space->type}", '
' . $lang->kanban->create, '', "class='iframe' data-width='75%'", '', true);?>
-
diff --git a/module/product/control.php b/module/product/control.php
index 92a7c89c24..1bb3799757 100644
--- a/module/product/control.php
+++ b/module/product/control.php
@@ -1047,10 +1047,11 @@ class product extends control
*/
public function ajaxGetPlans($productID, $branch = 0, $planID = 0, $fieldID = '', $needCreate = false, $expired = '', $param = '')
{
- $param = strtolower($param);
- $plans = $this->loadModel('productplan')->getPairs($productID, $branch == 0 ? '' : $branch, $expired, strpos($param, 'skipparent') !== false);
- $field = $fieldID ? "plans[$fieldID]" : 'plan';
- $output = html::select($field, $plans, $planID, "class='form-control chosen'");
+ $param = strtolower($param);
+ $plans = $this->loadModel('productplan')->getPairs($productID, $branch == 0 ? '' : $branch, $expired, strpos($param, 'skipparent') !== false);
+ $field = $fieldID ? "plans[$fieldID]" : 'plan';
+ $multiple = strpos($param, 'multiple') === false ? '' : 'multiple';
+ $output = html::select($field, $plans, $planID, "class='form-control chosen' $multiple");
if($branch == 0 and strpos($param, 'edit')) $output = html::select($field, $plans, $planID, "class='form-control chosen' multiple");
diff --git a/module/program/control.php b/module/program/control.php
index e265a22462..911930d377 100644
--- a/module/program/control.php
+++ b/module/program/control.php
@@ -429,7 +429,7 @@ class program extends control
if($productCount) return print(js::alert($this->lang->program->hasProduct));
$program = $this->dao->select('*')->from(TABLE_PROGRAM)->where('id')->eq($programID)->fetch();
- if($confirm == 'no') return print(js::confirm($this->lang->program->confirmDelete, $this->createLink('program', 'delete', "programID=$programID&confirm=yes")));
+ if($confirm == 'no') return print(js::confirm(sprintf($this->lang->program->confirmDelete, $program->name), $this->createLink('program', 'delete', "programID=$programID&confirm=yes")));
$this->dao->update(TABLE_PROGRAM)->set('deleted')->eq(1)->where('id')->eq($programID)->exec();
$this->loadModel('action')->create('program', $programID, 'deleted', '', ACTIONMODEL::CAN_UNDELETED);
@@ -543,7 +543,7 @@ class program extends control
{
if($confirm == 'no')
{
- return print(js::confirm($this->lang->program->confirmDelete, $this->inlink('unlinkStakeholder', "stakeholderID=$stakeholderID&programID=$programID&confirm=yes")));
+ return print(js::confirm($this->lang->program->unlinkStakeholder, $this->inlink('unlinkStakeholder', "stakeholderID=$stakeholderID&programID=$programID&confirm=yes")));
}
else
{
diff --git a/module/program/lang/en.php b/module/program/lang/en.php
index 81ff6f9c17..8641ad4c6f 100644
--- a/module/program/lang/en.php
+++ b/module/program/lang/en.php
@@ -106,7 +106,8 @@ $lang->program->endLetterChild = "Child latest end: %s, parent end date >
$lang->program->closeErrorMessage = 'There are subprograms or projects that are not closed';
$lang->program->hasChildren = 'The program has a child program or the project exists and can not be deleted.';
$lang->program->hasProduct = 'The program has products exist and can not be deleted.';
-$lang->program->confirmDelete = "Do you want to delete it?";
+$lang->program->confirmDelete = 'Do you want to delete the \"%s\" Program?';
+$lang->program->unlinkStakeholder = 'Do you want to remove the Stakeholder?';
$lang->program->readjustTime = 'Change the program begin&end date.';
$lang->program->accessDenied = 'You have no access to the program.';
$lang->program->beyondParentBudget = 'The remaining budget of the owned program has been exceeded.';
diff --git a/module/program/lang/zh-cn.php b/module/program/lang/zh-cn.php
index 3478e2aebc..7feab8d484 100644
--- a/module/program/lang/zh-cn.php
+++ b/module/program/lang/zh-cn.php
@@ -106,7 +106,8 @@ $lang->program->endLetterChild = "子项目的最大完成日期:%s,父
$lang->program->closeErrorMessage = '存在子项目集或项目为未关闭状态';
$lang->program->hasChildren = '该项目集有子项目集或项目存在,不能删除。';
$lang->program->hasProduct = '该项目集有产品存在,不能删除。';
-$lang->program->confirmDelete = "您确定要删除吗?";
+$lang->program->confirmDelete = '您确定要删除\“%s\”项目集吗?';
+$lang->program->unlinkStakeholder = '您确定要移除干系人吗?';
$lang->program->readjustTime = '重新调整项目集起止时间';
$lang->program->accessDenied = '你无权访问该项目集';
$lang->program->beyondParentBudget = '已超出所属项目集的剩余预算';
diff --git a/module/project/control.php b/module/project/control.php
index 666351ace5..ea790ac855 100644
--- a/module/project/control.php
+++ b/module/project/control.php
@@ -401,7 +401,13 @@ class project extends control
$planIdList = array();
foreach($_POST['plans'] as $plans)
{
- foreach($plans as $planID) $planIdList[$planID] = $planID;
+ foreach($plans as $planList)
+ {
+ foreach($planList as $planID)
+ {
+ $planIdList[$planID] = $planID;
+ }
+ }
}
$planStoryGroup = $this->loadModel('story')->getStoriesByPlanIdList($planIdList);
@@ -557,7 +563,17 @@ class project extends control
if($_POST)
{
- $oldPlans = $this->dao->select('plan')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($projectID)->andWhere('plan')->ne(0)->fetchPairs('plan');
+ $oldPlanList = $this->dao->select('plan')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($projectID)->andWhere('plan')->ne(0)->fetchPairs('plan');
+ $oldPlans = array();
+ foreach($oldPlanList as $oldPlanIDList)
+ {
+ if(is_numeric($oldPlanIDList)) $oldPlans[$oldPlanIDList] = $oldPlanIDList;
+ if(!is_numeric($oldPlanIDList))
+ {
+ $oldPlanIDList = explode(',', $oldPlanIDList);
+ foreach($oldPlanIDList as $oldPlanID) $oldPlans[$oldPlanID] = $oldPlanID;
+ }
+ }
$changes = $this->project->update($projectID);
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
@@ -574,7 +590,10 @@ class project extends control
{
foreach($_POST['plans'] as $plans)
{
- foreach($plans as $planID) $newPlans[$planID] = $planID;
+ foreach($plans as $planIDList)
+ {
+ foreach($planIDList as $planID) $newPlans[$planID] = $planID;
+ }
}
}
diff --git a/module/project/css/create.css b/module/project/css/create.css
index f06cab4405..44de71f011 100644
--- a/module/project/css/create.css
+++ b/module/project/css/create.css
@@ -13,6 +13,9 @@
#budgetUnit {border-left: 0px;}
#projectName {display: inline-block; width: 32%;}
#productsBox a {border-radius: 2px !important;}
+#productsBox .col-sm-4 {padding-right: 5px;}
#productsBox .addProduct {padding-left: 0px !important;}
#productsBox > .required:after{right: -6px !important;}
#productsBox .input-group-addon > div {display: inline-block !important;}
+#plansBox .row {display: inline-table; width: 102%;}
+#plansBox .col-sm-4 {float: none; display: inline-block; padding-right: 5px;}
diff --git a/module/project/css/edit.css b/module/project/css/edit.css
index 191b12ce1d..2ac86731bf 100644
--- a/module/project/css/edit.css
+++ b/module/project/css/edit.css
@@ -1,2 +1,4 @@
#budget {border-right: 0px;}
#budgetUnit {border-left: 0px;}
+#plansBox .row {display: inline-table; width: 102%;}
+#plansBox .col-sm-4 {float: none; display: inline-block;}
diff --git a/module/project/css/view.css b/module/project/css/view.css
index 667a757422..cd7fc24412 100644
--- a/module/project/css/view.css
+++ b/module/project/css/view.css
@@ -1,2 +1,3 @@
.block-dynamic .panel-body {height: 230px; overflow: auto; position: relative;}
.block-team div.col-xs-6 {white-space: nowrap; overflow: hidden;}
+.cell .detail .row-grid {display: list-item;}
diff --git a/module/project/js/common.js b/module/project/js/common.js
index ffc4071fe0..79e9d63c67 100644
--- a/module/project/js/common.js
+++ b/module/project/js/common.js
@@ -196,12 +196,12 @@ function loadPlans(product, branchID)
$("input[name='products[" + index + "]']").remove();
$("input[name='branch[" + index + "]']").remove();
- $.get(createLink('product', 'ajaxGetPlans', "productID=" + productID + '&branch=0,' + branchID + '&planID=0&fieldID&needCreate=&expired=' + (config.currentMethod == 'create' ? 'unexpired' : '') + '¶m=skipParent'), function(data)
+ $.get(createLink('product', 'ajaxGetPlans', "productID=" + productID + '&branch=0,' + branchID + '&planID=0&fieldID&needCreate=&expired=unexpired¶m=skipParent,multiple'), function(data)
{
if(data)
{
if($("div#plan" + index).size() == 0) $("#plansBox .row").append('
');
- $("div#plan" + index).html(data).find('select').attr('name', 'plans[' + productID + ']' + '[' + branchID + ']').attr('id', 'plans' + productID).chosen();
+ $("div#plan" + index).html(data).find('select').attr('name', 'plans[' + productID + ']' + '[' + branchID + '][]').attr('id', 'plans' + productID).chosen();
adjustPlanBoxMargin();
}
@@ -323,12 +323,17 @@ $(document).on('change', "#plansBox select[name^='plans']", function()
var $plan = $(this);
$("#plansBox select[name^='plans']").each(function()
{
- if($plan.val() != 0 && $plan.val() == $(this).val() && $plan.closest('div').attr('id') != $(this).closest('div').attr('id'))
+ var planIDList = $plan.val() == null ? 0 : $plan.val();
+ for(var i = 0; i < planIDList.length; i++)
{
- bootbox.alert(errorSamePlans);
- $plan.val(0);
- $plan.trigger("chosen:updated");
- return false;
+ var planID = planIDList[i];
+ if(planID != 0 && $(this).val() && $(this).val().includes(planID) && $plan.closest('div').attr('id') != $(this).closest('div').attr('id'))
+ {
+ bootbox.alert(errorSamePlans);
+ $plan.val(0);
+ $plan.trigger("chosen:updated");
+ return false;
+ }
}
});
});
diff --git a/module/project/js/create.js b/module/project/js/create.js
index 41df4acfa0..63b03b884e 100644
--- a/module/project/js/create.js
+++ b/module/project/js/create.js
@@ -224,12 +224,12 @@ function loadPlans(product, branchID)
if(productID != 0)
{
- $.get(createLink('product', 'ajaxGetPlans', "productID=" + productID + '&branch=0,' + branchID + '&planID=0&fieldID&needCreate=&expired=unexpired,noclosed¶m=skipParent'), function(data)
+ $.get(createLink('product', 'ajaxGetPlans', "productID=" + productID + '&branch=0,' + branchID + '&planID=0&fieldID&needCreate=&expired=unexpired,noclosed¶m=skipParent,multiple'), function(data)
{
if(data)
{
if($("div#plan" + index).size() == 0) $("#plansBox .row").append('
');
- $("div#plan" + index).html(data).find('select').attr('name', 'plans[' + productID + '][' + branchID + ']').attr('id', 'plans' + productID).chosen();
+ $("div#plan" + index).html(data).find('select').attr('name', 'plans[' + productID + '][' + branchID + '][]').attr('id', 'plans' + productID).chosen();
adjustPlanBoxMargin();
}
diff --git a/module/project/lang/en.php b/module/project/lang/en.php
index 30c8011570..c4338b3430 100644
--- a/module/project/lang/en.php
+++ b/module/project/lang/en.php
@@ -119,7 +119,7 @@ $lang->project->estimate = 'Estimates';
$lang->project->consume = 'Cost';
$lang->project->surplus = 'Left';
$lang->project->progress = 'Progress';
-$lang->project->dateRange = 'Duration';
+$lang->project->dateRange = 'Plan Duration';
$lang->project->to = ' to ';
$lang->project->realBeganAB = 'Actual Begin';
$lang->project->realEndAB = 'Actual End';
diff --git a/module/project/lang/zh-cn.php b/module/project/lang/zh-cn.php
index 0913b1d071..73f13572d7 100644
--- a/module/project/lang/zh-cn.php
+++ b/module/project/lang/zh-cn.php
@@ -119,7 +119,7 @@ $lang->project->estimate = '预计';
$lang->project->consume = '消耗';
$lang->project->surplus = '剩余';
$lang->project->progress = '进度';
-$lang->project->dateRange = '起止日期';
+$lang->project->dateRange = '计划起止日期';
$lang->project->to = '至';
$lang->project->realBeganAB = '实际开始';
$lang->project->realEndAB = '实际完成';
diff --git a/module/project/model.php b/module/project/model.php
index ef7a0fedec..7b88e59877 100644
--- a/module/project/model.php
+++ b/module/project/model.php
@@ -2120,14 +2120,14 @@ class projectModel extends model
if(isset($oldProjectProducts[$productID][$branch]))
{
$oldProjectProduct = $oldProjectProducts[$productID][$branch];
- $oldPlan = $oldProjectProduct->plan;
+ if($this->app->rawMethod != 'edit') $oldPlan = $oldProjectProduct->plan;
}
$data = new stdclass();
$data->project = $projectID;
$data->product = $productID;
$data->branch = $branch;
- $data->plan = isset($plans[$productID][$branch]) ? $plans[$productID][$branch] : $oldPlan;
+ $data->plan = isset($plans[$productID][$branch]) ? implode(',', $plans[$productID][$branch]) : $oldPlan;
$this->dao->insert(TABLE_PROJECTPRODUCT)->data($data)->exec();
$existedProducts[$productID][$branch] = true;
}
diff --git a/module/project/view/create.html.php b/module/project/view/create.html.php
index f961aa09f3..b2b7f7c4f3 100755
--- a/module/project/view/create.html.php
+++ b/module/project/view/create.html.php
@@ -41,7 +41,7 @@