diff --git a/db/update17.0.sql b/db/update17.0.sql index 376cb9f0fc..832ca723af 100644 --- a/db/update17.0.sql +++ b/db/update17.0.sql @@ -9,3 +9,5 @@ ALTER TABLE `zt_review` ADD docVersion smallint(6) NOT NULL AFTER `doc`; DELETE FROM `zt_workflowaction` WHERE `module`='story' AND `action`='browse'; DELETE FROM `zt_workflowaction` WHERE `module`='task' AND `action`='browse'; DELETE FROM `zt_workflowaction` WHERE `module`='build' AND `action`='browse'; + +ALTER TABLE `zt_projectproduct` MODIFY COLUMN `plan` varchar(255) NOT NULL; diff --git a/db/zentao.sql b/db/zentao.sql index f721373b2e..61a99aecd5 100755 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -1159,7 +1159,7 @@ CREATE TABLE IF NOT EXISTS `zt_projectproduct` ( `project` mediumint(8) unsigned NOT NULL, `product` mediumint(8) unsigned NOT NULL, `branch` mediumint(8) unsigned NOT NULL, - `plan` mediumint(8) unsigned NOT NULL, + `plan` varchar(255) NOT NULL, PRIMARY KEY (`project`, `product`, `branch`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- DROP TABLE IF EXISTS `zt_projectspec`; 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/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..e047d680eb 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=' + (config.currentMethod == 'create' ? '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/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..34b1509517 100755 --- a/module/project/view/create.html.php +++ b/module/project/view/create.html.php @@ -56,7 +56,7 @@