From 055d52f45e0ec3bc6d01c056acf3d0c609b66524 Mon Sep 17 00:00:00 2001
From: leiyong <1549684884@qq.com>
Date: Fri, 30 Oct 2020 10:55:11 +0800
Subject: [PATCH] * Project related products.
---
module/group/lang/resource.php | 2 +
module/program/control.php | 127 ++++++++++++++++--
module/program/css/prjcreate.css | 1 +
module/program/css/prjedit.css | 1 +
module/program/css/prjmanageproducts.css | 9 ++
module/program/js/common.js | 100 ++++++++++++++
module/program/js/prjcreate.js | 114 +++++++++++++++-
module/program/js/prjmanageproducts.js | 14 ++
module/program/lang/de.php | 3 +-
module/program/lang/en.php | 3 +-
module/program/lang/fr.php | 3 +-
module/program/lang/vi.php | 3 +-
module/program/lang/zh-cn.php | 1 +
module/program/lang/zh-tw.php | 3 +-
module/program/model.php | 40 +++++-
module/program/view/prjcreate.html.php | 45 ++++++-
module/program/view/prjedit.html.php | 39 ++++++
.../program/view/prjmanageproducts.html.php | 66 +++++++++
18 files changed, 554 insertions(+), 20 deletions(-)
create mode 100644 module/program/css/prjmanageproducts.css
create mode 100644 module/program/js/prjmanageproducts.js
create mode 100644 module/program/view/prjmanageproducts.html.php
diff --git a/module/group/lang/resource.php b/module/group/lang/resource.php
index efae3fe999..fe8e3eb9e3 100644
--- a/module/group/lang/resource.php
+++ b/module/group/lang/resource.php
@@ -197,6 +197,7 @@ $lang->resource->program->PRJDelete = 'PRJDelete';
$lang->resource->program->PRJWhitelist = 'PRJWhitelist';
$lang->resource->program->PRJAddWhitelist = 'PRJAddWhitelist';
$lang->resource->program->unbindWhielist = 'unbindWhielist';
+$lang->resource->program->PRJManageProducts = 'PRJManageProducts';
$lang->program->methodOrder[0] = 'createGuide';
$lang->program->methodOrder[5] = 'PGMIndex';
@@ -236,6 +237,7 @@ $lang->program->methodOrder[165] = 'PRJDelete';
$lang->program->methodOrder[170] = 'PRJWhitelist';
$lang->program->methodOrder[175] = 'PRJAddWhitelist';
$lang->program->methodOrder[180] = 'unbindWhielist';
+$lang->program->methodOrder[185] = 'PRJManageProducts';
/* Personnel . */
$lang->resource->personnel = new stdclass();
diff --git a/module/program/control.php b/module/program/control.php
index fbd8be05ea..79ccd7a83d 100644
--- a/module/program/control.php
+++ b/module/program/control.php
@@ -764,13 +764,16 @@ class program extends control
$this->lang->navGroup->program = 'program';
$this->lang->program->switcherMenu = $this->program->getPGMCommonAction();
}
+ $this->loadModel('project');
if($_POST)
{
$projectID = $this->program->PRJCreate();
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => $this->processErrors(dao::getError())));
+ $this->project->updateProducts($projectID);
$this->loadModel('action')->create('project', $projectID, 'opened');
+
if($from == 'PGM')
{
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('PGMBrowse')));
@@ -783,7 +786,10 @@ class program extends control
$team = '';
$whitelist = '';
$acl = 'open';
- $privway = 'extend';
+ $auth = 'extend';
+
+ $products = array();
+ $productPlans = array();
if($copyProjectID)
{
@@ -792,25 +798,36 @@ class program extends control
$code = $copyProgram->code;
$team = $copyProgram->team;
$acl = $copyProgram->acl;
- $privway = $copyProgram->privway;
+ $auth = $copyProgram->auth;
$whitelist = $copyProgram->whitelist;
if(empty($model)) $model = $copyProgram->model;
+
+ $products = $this->project->getProducts($copyProjectID);
+ foreach($products as $product)
+ {
+ $productPlans[$product->id] = $this->loadModel('productplan')->getPairs($product->id);
+ }
}
+ $allProducts = $this->program->getPGMProduct($programID);
+
$this->view->title = $this->lang->program->PRJCreate;
$this->view->position[] = $this->lang->program->PRJCreate;
- $this->view->groups = $this->loadModel('group')->getPairs();
$this->view->pmUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst');
$this->view->users = $this->user->getPairs('noclosed|nodeleted');
$this->view->programs = array('' => '') + $this->program->getPRJPairsByTemplate($model, $programID);
+ $this->view->products = $products;
+ $this->view->allProducts = array('0' => '') + $allProducts;
+ $this->view->productPlans = array('0' => '') + $productPlans;
+ $this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products));
$this->view->programID = $programID;
$this->view->model = $model;
$this->view->name = $name;
$this->view->code = $code;
$this->view->team = $team;
$this->view->acl = $acl;
- $this->view->privway = $privway;
+ $this->view->auth = $auth;
$this->view->whitelist = $whitelist;
$this->view->copyProjectID = $copyProjectID;
$this->view->from = $from;
@@ -830,12 +847,17 @@ class program extends control
public function PRJEdit($projectID = 0)
{
$this->lang->navGroup->program = 'project';
+ $this->app->loadLang('project');
+ $this->loadModel('productplan');
if($_POST)
{
$changes = $this->program->PRJUpdate($projectID);
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => $this->processErrors(dao::getError())));
+ $this->project->updateProducts($projectID);
+ if(dao::isError()) $this->send(array('result' => 'fail', 'message' => $this->processErrors(dao::getError())));
+
if($changes)
{
$actionID = $this->loadModel('action')->create('project', $projectID, 'edited');
@@ -846,17 +868,41 @@ class program extends control
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $url));
}
- $project = $this->program->getPRJByID($projectID);
- $parents = $this->program->getParentPairs();
+ $project = $this->program->getPRJByID($projectID);
+ $parents = $this->program->getParentPairs();
+ $programID = $this->program->getPRJProgramID($projectID);
+ $allProducts = $this->program->getPGMProduct($programID);
+ $linkedProducts = $this->project->getProducts($projectID);
+ $linkedBranches = array();
+ foreach($linkedProducts as $product)
+ {
+ if(!isset($allProducts[$product->id])) $allProducts[$product->id] = $product->name;
+ if($product->branch) $linkedBranches[$product->branch] = $product->branch;
+ }
+ foreach($linkedProducts as $product)
+ {
+ if(!isset($allProducts[$product->id])) $allProducts[$product->id] = $product->name;
+ if($product->branch) $linkedBranches[$product->branch] = $product->branch;
+ }
+
+ $productPlans = array(0 => '');
+ foreach($linkedProducts as $product)
+ {
+ $productPlans[$product->id] = $this->productplan->getPairs($product->id);
+ }
$this->view->title = $this->lang->program->PRJEdit;
$this->view->position[] = $this->lang->program->PRJEdit;
- $this->view->pmUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst', $project->PM);
- $this->view->users = $this->user->getPairs('noclosed|nodeleted');
- $this->view->project = $project;
- $this->view->parents = $parents;
- $this->view->groups = $this->loadModel('group')->getPairs();
+ $this->view->pmUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst', $project->PM);
+ $this->view->users = $this->user->getPairs('noclosed|nodeleted');
+ $this->view->project = $project;
+ $this->view->parents = $parents;
+ $this->view->allProducts = array('0' => '') + $allProducts;
+ $this->view->productPlans = $productPlans;
+ $this->view->linkedProducts = $linkedProducts;
+ $this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($linkedProducts), '', $linkedBranches);
+
$this->display();
}
@@ -1388,4 +1434,63 @@ class program extends control
{
echo $this->fetch('personnel', 'unbindWhielist', "id=$id&confirm=$confirm");
}
+
+ /**
+ * Manage products.
+ *
+ * @param int $projectID
+ * @param int $programID
+ * @param string $from
+ * @access public
+ * @return void
+ */
+ public function PRJManageProducts($projectID, $programID, $from = '')
+ {
+ $this->lang->navGroup->program = 'project';
+ $browseProjectLink = $this->createLink('program', 'PRJBrowse', "programID=$programID");
+
+ if(!empty($_POST))
+ {
+ $oldProducts = $this->project->getProducts($projectID);
+ $this->project->updateProducts($projectID);
+ if(dao::isError()) die(js::error(dao::getError()));
+
+ $oldProducts = array_keys($oldProducts);
+ $newProducts = $this->project->getProducts($projectID);
+ $newProducts = array_keys($newProducts);
+ $diffProducts = array_merge(array_diff($oldProducts, $newProducts), array_diff($newProducts, $oldProducts));
+ if($diffProducts) $this->loadModel('action')->create('project', $projectID, 'Managed', '', !empty($_POST['products']) ? join(',', $_POST['products']) : '');
+
+ die(js::locate($browseProjectLink));
+ }
+
+ $this->loadModel('product');
+ $project = $this->project->getById($projectID);
+ $programID = $this->program->getPRJProgramID($projectID);
+
+ /* Title and position. */
+ $title = $this->lang->project->manageProducts . $this->lang->colon . $project->name;
+ $position[] = html::a($browseProjectLink, $project->name);
+ $position[] = $this->lang->project->manageProducts;
+
+ $allProducts = $this->product->getPairs('noclosed|nocode', $programID);
+ $linkedProducts = $this->project->getProducts($project->id);
+ $linkedBranches = array();
+
+ /* Merge allProducts and linkedProducts for closed product. */
+ foreach($linkedProducts as $product)
+ {
+ if(!isset($allProducts[$product->id])) $allProducts[$product->id] = $product->name;
+ if(!empty($product->branch)) $linkedBranches[$product->branch] = $product->branch;
+ }
+
+ /* Assign. */
+ $this->view->title = $title;
+ $this->view->position = $position;
+ $this->view->allProducts = $allProducts;
+ $this->view->linkedProducts = $linkedProducts;
+ $this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($allProducts), '', $linkedBranches);
+
+ $this->display();
+ }
}
diff --git a/module/program/css/prjcreate.css b/module/program/css/prjcreate.css
index 6400101703..d165700116 100644
--- a/module/program/css/prjcreate.css
+++ b/module/program/css/prjcreate.css
@@ -8,3 +8,4 @@
#copyProjectModal a.active:after {position: absolute; content: '\e92f'; font-family: ZentaoIcon; font-size: 20px; right: 25px;}
#copyProjectModal a.cancel {color: #ff5d5d}
#budget {border-right:0px;}
+.col-sm-4{margin-bottom: 10px;}
diff --git a/module/program/css/prjedit.css b/module/program/css/prjedit.css
index e7c1b33177..bb9e7152f1 100644
--- a/module/program/css/prjedit.css
+++ b/module/program/css/prjedit.css
@@ -1 +1,2 @@
#budget {border-right:0px;}
+.col-sm-4{margin-bottom: 10px;}
diff --git a/module/program/css/prjmanageproducts.css b/module/program/css/prjmanageproducts.css
new file mode 100644
index 0000000000..88e5890170
--- /dev/null
+++ b/module/program/css/prjmanageproducts.css
@@ -0,0 +1,9 @@
+#productsBox .product {border: 1px solid #ddd; margin-bottom:5px; position: relative; height: 40px; border-radius: 4px;}
+#productsBox .product:hover {background: #f1f1f1;}
+#productsBox .product.checked,
+#productsBox .product.checked:hover {background: #E5FFE6; border: 1px solid #229F24;}
+#productsBox .product .checkbox-primary {padding: 9px; cursor: pointer;}
+#productsBox .product.has-branch {padding-right: 40%;}
+#productsBox .product.has-branch > .chosen-container {position: absolute; width: 40%!important; right: 3px; top: 3px;}
+#productsBox .product.has-branch > .chosen-container > .chosen-single {background: rgba(0,0,0,.05);}
+#productsBox .product.has-branch > .chosen-container > .chosen-single:hover {background: #fff;}
diff --git a/module/program/js/common.js b/module/program/js/common.js
index 92f22064b6..1ef90b5d67 100644
--- a/module/program/js/common.js
+++ b/module/program/js/common.js
@@ -110,6 +110,106 @@ function computeEndDate(delta)
computeWorkDays();
}
+/**
+ * Load branches.
+ *
+ * @param int $product
+ * @access public
+ * @return void
+ */
+function loadBranches(product)
+{
+ $('#productsBox select').each(function()
+ {
+ var $product = $(product);
+ if($product.val() != 0 && $product.val() == $(this).val() && $product.attr('id') != $(this).attr('id'))
+ {
+ alert(errorSameProducts);
+ $product.val(0);
+ $product.trigger("chosen:updated");
+ return false;
+ }
+ });
+
+ if($('#productsBox .input-group:last select:first').val() != 0)
+ {
+ var length = $('#productsBox .input-group').size();
+ $('#productsBox .row').append('
' + $('#productsBox .col-sm-4:last').html() + '
');
+ if($('#productsBox .input-group:last select').size() >= 2) $('#productsBox .input-group:last select:last').remove();
+ $('#productsBox .input-group:last .chosen-container').remove();
+ $('#productsBox .input-group:last select:first').attr('name', 'products[' + length + ']').attr('id', 'products' + length);
+ $('#productsBox .input-group:last .chosen').chosen();
+
+ adjustProductBoxMargin();
+ }
+
+ var $inputgroup = $(product).closest('.input-group');
+ if($inputgroup.find('select').size() >= 2) $inputgroup.removeClass('has-branch').find('select:last').remove();
+ if($inputgroup.find('.chosen-container').size() >= 2) $inputgroup.find('.chosen-container:last').remove();
+
+ var index = $inputgroup.find('select:first').attr('id').replace('products' , '');
+ $.get(createLink('branch', 'ajaxGetBranches', "productID=" + $(product).val()), function(data)
+ {
+ if(data)
+ {
+ $inputgroup.addClass('has-branch').append(data);
+ $inputgroup.find('select:last').attr('name', 'branch[' + index + ']').attr('id', 'branch' + index).attr('onchange', "loadPlans('#products" + index + "', this.value)").chosen();
+ }
+ });
+
+ loadPlans(product);
+}
+
+function loadPlans(product, branchID)
+{
+ if($('#plansBox').size() == 0) return false;
+
+ var productID = $(product).val();
+ var branchID = typeof(branchID) == 'undefined' ? 0 : branchID;
+ var index = $(product).attr('id').replace('products', '');
+
+ if(productID != 0)
+ {
+ if(typeof(planID) == 'undefined') planID = 0;
+ planID = $("select#plans" + productID).val() != '' ? $("select#plans" + productID).val() : planID;
+ $.get(createLink('product', 'ajaxGetPlans', "productID=" + productID + '&branch=' + branchID + '&planID=' + planID + '&fieldID&needCreate=&expired=' + ((config.currentMethod == 'create' || config.currentMethod == 'edit') ? 'unexpired' : '')), function(data)
+ {
+ if(data)
+ {
+ if($("div#plan" + index).size() == 0) $("#plansBox .row").append('');
+ $("div#plan" + index).html(data).find('select').attr('name', 'plans[' + productID + ']').attr('id', 'plans' + productID).chosen();
+
+ adjustPlanBoxMargin();
+ }
+ });
+ }
+}
+
+
+function adjustProductBoxMargin()
+{
+ var productRows = Math.ceil($('#productsBox > .row > .col-sm-4').length / 3);
+ if(productRows > 1)
+ {
+ for(i = 1; i <= productRows - 1; i++)
+ {
+ $('#productsBox .col-sm-4:lt(' + (i * 3) + ')').css('margin-bottom', '10px');
+ }
+ }
+}
+
+function adjustPlanBoxMargin()
+{
+ var planRows = Math.ceil($('#plansBox > .row > .col-sm-4').length / 3);
+ if(planRows > 1)
+ {
+ for(j = 1; j <= planRows - 1; j++)
+ {
+ $('#plansBox .col-sm-4:lt(' + (j * 3) + ')').css('margin-bottom', '10px');
+ }
+ }
+}
+
$(function()
{
$('#privList > tbody > tr > th input[type=checkbox]').change(function()
diff --git a/module/program/js/prjcreate.js b/module/program/js/prjcreate.js
index f2c94b6c5a..f131a58f09 100644
--- a/module/program/js/prjcreate.js
+++ b/module/program/js/prjcreate.js
@@ -13,11 +13,24 @@ $(function()
$('#end').removeAttr('disabled');
}
});
+
+ if(typeof(currentPlanID) == 'undefined')
+ {
+ $('#productsBox select[id^="products"]').each(function()
+ {
+ var branchID = 0;
+ if($(this).closest('.input-group').find('select[id^="branch"]').size() > 0)
+ {
+ var branchID = $(this).closest('.input-group').find('select[id^="branch"]').val();
+ }
+ loadPlans($(this), branchID);
+ });
+ }
});
function setCopyProject(copyProjectID)
{
- location.href = createLink('program', 'PRJCreate', 'template=' + template + '&programID=' + programID + '&from=' + from + '©ProjectID=' + copyProjectID);
+ location.href = createLink('program', 'PRJCreate', 'model=' + model + '&programID=' + programID + '&from=' + from + '©ProjectID=' + copyProjectID);
}
function setAclList(programID)
@@ -31,3 +44,102 @@ function setAclList(programID)
$('.aclBox').html($('#PRJAcl').html());
}
}
+
+/**
+ * Load branches.
+ *
+ * @param int $product
+ * @access public
+ * @return void
+ */
+function loadBranches(product)
+{
+ $('#productsBox select').each(function()
+ {
+ var $product = $(product);
+ if($product.val() != 0 && $product.val() == $(this).val() && $product.attr('id') != $(this).attr('id'))
+ {
+ alert(errorSameProducts);
+ $product.val(0);
+ $product.trigger("chosen:updated");
+ return false;
+ }
+ });
+
+ if($('#productsBox .input-group:last select:first').val() != 0)
+ {
+ var length = $('#productsBox .input-group').size();
+ $('#productsBox .row').append('' + $('#productsBox .col-sm-4:last').html() + '
');
+ if($('#productsBox .input-group:last select').size() >= 2) $('#productsBox .input-group:last select:last').remove();
+ $('#productsBox .input-group:last .chosen-container').remove();
+ $('#productsBox .input-group:last select:first').attr('name', 'products[' + length + ']').attr('id', 'products' + length);
+ $('#productsBox .input-group:last .chosen').chosen();
+
+ adjustProductBoxMargin();
+ }
+
+ var $inputgroup = $(product).closest('.input-group');
+ if($inputgroup.find('select').size() >= 2) $inputgroup.removeClass('has-branch').find('select:last').remove();
+ if($inputgroup.find('.chosen-container').size() >= 2) $inputgroup.find('.chosen-container:last').remove();
+
+ var index = $inputgroup.find('select:first').attr('id').replace('products' , '');
+ $.get(createLink('branch', 'ajaxGetBranches', "productID=" + $(product).val()), function(data)
+ {
+ if(data)
+ {
+ $inputgroup.addClass('has-branch').append(data);
+ $inputgroup.find('select:last').attr('name', 'branch[' + index + ']').attr('id', 'branch' + index).attr('onchange', "loadPlans('#products" + index + "', this.value)").chosen();
+ }
+ });
+
+ loadPlans(product);
+}
+
+function loadPlans(product, branchID)
+{
+ if($('#plansBox').size() == 0) return false;
+
+ var productID = $(product).val();
+ var branchID = typeof(branchID) == 'undefined' ? 0 : branchID;
+ var index = $(product).attr('id').replace('products', '');
+
+ if(productID != 0)
+ {
+ if(typeof(planID) == 'undefined') planID = 0;
+ planID = $("select#plans" + productID).val() != '' ? $("select#plans" + productID).val() : planID;
+ $.get(createLink('product', 'ajaxGetPlans', "productID=" + productID + '&branch=' + branchID + '&planID=' + planID + '&fieldID&needCreate=&expired=' + ((config.currentMethod == 'create' || config.currentMethod == 'edit') ? 'unexpired' : '')), function(data)
+ {
+ if(data)
+ {
+ if($("div#plan" + index).size() == 0) $("#plansBox .row").append('');
+ $("div#plan" + index).html(data).find('select').attr('name', 'plans[' + productID + ']').attr('id', 'plans' + productID).chosen();
+
+ adjustPlanBoxMargin();
+ }
+ });
+ }
+}
+
+function adjustProductBoxMargin()
+{
+ var productRows = Math.ceil($('#productsBox > .row > .col-sm-4').length / 3);
+ if(productRows > 1)
+ {
+ for(i = 1; i <= productRows - 1; i++)
+ {
+ $('#productsBox .col-sm-4:lt(' + (i * 3) + ')').css('margin-bottom', '10px');
+ }
+ }
+}
+
+function adjustPlanBoxMargin()
+{
+ var planRows = Math.ceil($('#plansBox > .row > .col-sm-4').length / 3);
+ if(planRows > 1)
+ {
+ for(j = 1; j <= planRows - 1; j++)
+ {
+ $('#plansBox .col-sm-4:lt(' + (j * 3) + ')').css('margin-bottom', '10px');
+ }
+ }
+}
diff --git a/module/program/js/prjmanageproducts.js b/module/program/js/prjmanageproducts.js
new file mode 100644
index 0000000000..f89adde86e
--- /dev/null
+++ b/module/program/js/prjmanageproducts.js
@@ -0,0 +1,14 @@
+$(function()
+{
+ $('#productsBox input:checkbox').each(function()
+ {
+ var $cb = $(this);
+ if($cb.prop('checked')) $cb.closest('.product').addClass('checked');
+ });
+
+ $('#productsBox input:checkbox').change(function()
+ {
+ var $cb = $(this);
+ $cb.closest('.product').toggleClass('checked', $cb.prop('checked'));
+ });
+});
diff --git a/module/program/lang/de.php b/module/program/lang/de.php
index 2172e76e66..8ca4c00e09 100644
--- a/module/program/lang/de.php
+++ b/module/program/lang/de.php
@@ -30,6 +30,7 @@ $lang->program->PRJSort = 'Order';
$lang->program->PRJWhitelist = 'Project Whitelist';
$lang->program->PRJAddWhitelist = 'Project Add Whitelist';
$lang->program->unbindWhielist = 'Project Remove Whitelist';
+$lang->program->PRJManageProducts = 'Manage Products';
/* Fields. */
$lang->program->common = 'Project';
@@ -168,7 +169,7 @@ $lang->program->PGMCreateGuide = 'Select Template';
$lang->program->PGMEdit = 'Edit Program';
$lang->program->PGMBrowse = 'Programs';
$lang->program->PGMProduct = 'Products';
-$lang->program->PGMProject = 'Program Project';
+$lang->program->PGMProject = 'Program Project List';
$lang->program->PGMAll = 'All Programs';
$lang->program->PGMStart = 'Start';
$lang->program->PGMFinish = 'Finish';
diff --git a/module/program/lang/en.php b/module/program/lang/en.php
index 2172e76e66..8ca4c00e09 100644
--- a/module/program/lang/en.php
+++ b/module/program/lang/en.php
@@ -30,6 +30,7 @@ $lang->program->PRJSort = 'Order';
$lang->program->PRJWhitelist = 'Project Whitelist';
$lang->program->PRJAddWhitelist = 'Project Add Whitelist';
$lang->program->unbindWhielist = 'Project Remove Whitelist';
+$lang->program->PRJManageProducts = 'Manage Products';
/* Fields. */
$lang->program->common = 'Project';
@@ -168,7 +169,7 @@ $lang->program->PGMCreateGuide = 'Select Template';
$lang->program->PGMEdit = 'Edit Program';
$lang->program->PGMBrowse = 'Programs';
$lang->program->PGMProduct = 'Products';
-$lang->program->PGMProject = 'Program Project';
+$lang->program->PGMProject = 'Program Project List';
$lang->program->PGMAll = 'All Programs';
$lang->program->PGMStart = 'Start';
$lang->program->PGMFinish = 'Finish';
diff --git a/module/program/lang/fr.php b/module/program/lang/fr.php
index 2172e76e66..8ca4c00e09 100644
--- a/module/program/lang/fr.php
+++ b/module/program/lang/fr.php
@@ -30,6 +30,7 @@ $lang->program->PRJSort = 'Order';
$lang->program->PRJWhitelist = 'Project Whitelist';
$lang->program->PRJAddWhitelist = 'Project Add Whitelist';
$lang->program->unbindWhielist = 'Project Remove Whitelist';
+$lang->program->PRJManageProducts = 'Manage Products';
/* Fields. */
$lang->program->common = 'Project';
@@ -168,7 +169,7 @@ $lang->program->PGMCreateGuide = 'Select Template';
$lang->program->PGMEdit = 'Edit Program';
$lang->program->PGMBrowse = 'Programs';
$lang->program->PGMProduct = 'Products';
-$lang->program->PGMProject = 'Program Project';
+$lang->program->PGMProject = 'Program Project List';
$lang->program->PGMAll = 'All Programs';
$lang->program->PGMStart = 'Start';
$lang->program->PGMFinish = 'Finish';
diff --git a/module/program/lang/vi.php b/module/program/lang/vi.php
index 2172e76e66..8ca4c00e09 100644
--- a/module/program/lang/vi.php
+++ b/module/program/lang/vi.php
@@ -30,6 +30,7 @@ $lang->program->PRJSort = 'Order';
$lang->program->PRJWhitelist = 'Project Whitelist';
$lang->program->PRJAddWhitelist = 'Project Add Whitelist';
$lang->program->unbindWhielist = 'Project Remove Whitelist';
+$lang->program->PRJManageProducts = 'Manage Products';
/* Fields. */
$lang->program->common = 'Project';
@@ -168,7 +169,7 @@ $lang->program->PGMCreateGuide = 'Select Template';
$lang->program->PGMEdit = 'Edit Program';
$lang->program->PGMBrowse = 'Programs';
$lang->program->PGMProduct = 'Products';
-$lang->program->PGMProject = 'Program Project';
+$lang->program->PGMProject = 'Program Project List';
$lang->program->PGMAll = 'All Programs';
$lang->program->PGMStart = 'Start';
$lang->program->PGMFinish = 'Finish';
diff --git a/module/program/lang/zh-cn.php b/module/program/lang/zh-cn.php
index d23476c412..48c84f189f 100644
--- a/module/program/lang/zh-cn.php
+++ b/module/program/lang/zh-cn.php
@@ -30,6 +30,7 @@ $lang->program->PRJSort = '项目排序';
$lang->program->PRJWhitelist = '项目白名单';
$lang->program->PRJAddWhitelist = '项目添加白名单';
$lang->program->unbindWhielist = '项目删除白名单';
+$lang->program->PRJManageProducts = '项目关联产品';
/* Fields. */
$lang->program->common = '项目集';
diff --git a/module/program/lang/zh-tw.php b/module/program/lang/zh-tw.php
index 020ae4ab5c..f0bbeaf8fd 100644
--- a/module/program/lang/zh-tw.php
+++ b/module/program/lang/zh-tw.php
@@ -30,6 +30,7 @@ $lang->program->PRJSort = '項目排序';
$lang->program->PRJWhitelist = '項目白名單';
$lang->program->PRJAddWhitelist = '項目添加白名單';
$lang->program->unbindWhielist = '項目刪除白名單';
+$lang->program->PRJManageProducts = '項目關聯產品';
/* Fields. */
$lang->program->common = '項目集';
@@ -168,7 +169,7 @@ $lang->program->PGMCreateGuide = '選擇項目模板';
$lang->program->PGMEdit = '編輯項目集';
$lang->program->PGMBrowse = '項目集列表';
$lang->program->PGMProduct = '產品列表';
-$lang->program->PGMProject = '项目集项目列表';
+$lang->program->PGMProject = '項目集項目列表';
$lang->program->PGMAll = '所有項目集';
$lang->program->PGMStart = '啟動項目集';
$lang->program->PGMFinish = '完成項目集';
diff --git a/module/program/model.php b/module/program/model.php
index beb9ade147..f8fd22eecc 100644
--- a/module/program/model.php
+++ b/module/program/model.php
@@ -172,6 +172,19 @@ class programModel extends model
->fetchPairs();
}
+ /**
+ * Get the product associated with the project.
+ *
+ * @param int $programID
+ * @access public
+ * @return array
+ */
+ public function getPGMProduct($programID = 0)
+ {
+ if(!empty($programID)) $programID = $this->getPRJProgramID($programID);
+ return $this->loadModel('product')->getPairs('noclosed', $programID);
+ }
+
/**
* Get program by id.
*
@@ -915,6 +928,28 @@ class programModel extends model
return $project;
}
+ /**
+ * Get the program to which the project belongs.
+ *
+ * @param int $projectID
+ * @access public
+ * @return object
+ */
+ public function getPRJProgramID($projectID)
+ {
+ if(empty($projectID)) return 0;
+ $program = $this->getPGMByID($projectID);
+
+ $programID = 0;
+ if($program->parent > 0)
+ {
+ $path = explode(',', $program->path);
+ $path = array_filter($path);
+ $programID = current($path);
+ }
+ return $programID;
+ }
+
/**
* Get project name.
*
@@ -1073,7 +1108,7 @@ class programModel extends model
->join('whitelist', ',')
->cleanInt('budget')
->stripTags($this->config->program->editor->prjcreate['id'], $this->config->allowedTags)
- ->remove('longTime')
+ ->remove('longTime,products,branch,plans')
->get();
if($project->parent)
@@ -1161,7 +1196,7 @@ class programModel extends model
->setIF($this->post->acl == 'open', 'whitelist', '')
->join('whitelist', ',')
->stripTags($this->config->program->editor->prjedit['id'], $this->config->allowedTags)
- ->remove('longTime')
+ ->remove('longTime,products,branch,plans')
->get();
if($project->parent)
@@ -1373,6 +1408,7 @@ class programModel extends model
common::printIcon('program', 'PRJGroup', "projectID=$project->id&programID=$programID", $project, 'list', 'lock');
common::printIcon('program', 'PRJManageMembers', "programID=$project->id", $project, 'list', 'persons');
common::printIcon('program', 'PRJWhitelist', "projectID=$project->id&programID=$programID", $project, 'list', 'group');
+ common::printIcon('program', 'PRJManageProducts', "projectID=$project->id&programID=$programID", $project, 'list', 'icon icon-menu-project');
common::printIcon('program', 'PRJStart', "programID=$project->id", $project, 'list', 'start', '', 'iframe', true);
common::printIcon('program', 'PRJActivate', "programID=$project->id", $project, 'list', 'magic', '', 'iframe', true);
common::printIcon('program', 'PRJSuspend', "programID=$project->id", $project, 'list', 'pause', '', 'iframe', true);
diff --git a/module/program/view/prjcreate.html.php b/module/program/view/prjcreate.html.php
index b8b327b7bc..af0096c96b 100644
--- a/module/program/view/prjcreate.html.php
+++ b/module/program/view/prjcreate.html.php
@@ -17,6 +17,7 @@
project->weekend);?>
+project->errorSameProducts);?>
@@ -56,6 +57,48 @@
program->PRJCategoryList, '', "class='form-control'");?> | | |
+
+ | project->manageProducts;?> |
+
+
+
+
+
+ type != 'normal' and isset($branchGroups[$product->id]);?>
+
+ id, "class='form-control chosen' onchange='loadBranches(this)' data-last='" . $product->id . "'");?>
+
+ id], $product->branch, "class='form-control chosen' onchange=\"loadPlans('#products{$i}', this.value)\"");?>
+
+
+
+
+
+
+ |
+
+
+ | project->linkPlan;?> |
+
+
+
+
+
+ id, array(0 => ''));?>
+ id . "]", $plans, '', "class='form-control chosen'");?>
+
+
+
+
+
+
+ |
+
| program->PRJPM;?> |
|
@@ -113,7 +156,7 @@
| program->auth;?> |
- program->PRJAuthList, $privway, '', 'block');?> |
+ program->PRJAuthList, $auth, '', 'block');?> |
| project->acl;?> |
diff --git a/module/program/view/prjedit.html.php b/module/program/view/prjedit.html.php
index 493db5a4d0..20564c56f9 100644
--- a/module/program/view/prjedit.html.php
+++ b/module/program/view/prjedit.html.php
@@ -14,6 +14,7 @@
project->weekend);?>
+project->errorSameProducts);?>
parent ? $lang->program->PGMPRJAclList : $lang->program->PRJAclList;?>
@@ -51,6 +52,44 @@
program->PRJCategoryList, $project->product, "class='form-control'");?> | | |
+
+ | project->manageProducts;?> |
+
+
+
+
+
+ type != 'normal' and isset($branchGroups[$product->id]);?>
+
+ id, "class='form-control chosen' onchange='loadBranches(this)' data-last='" . $product->id . "'");?>
+
+ id], $product->branch, "class='form-control chosen' onchange=\"loadPlans('#products{$i}', this.value)\"");?>
+
+
+
+
+
+
+ |
+
+
+ | project->linkPlan;?> |
+
+
+
+
+ id, array(0 => ''));?>
+ id . "]", $plans, $product->plan, "class='form-control chosen'");?>
+
+
+
+ |
+
| program->PRJPM;?> |
PM, "class='form-control chosen'");?> |
diff --git a/module/program/view/prjmanageproducts.html.php b/module/program/view/prjmanageproducts.html.php
new file mode 100644
index 0000000000..1d0858c175
--- /dev/null
+++ b/module/program/view/prjmanageproducts.html.php
@@ -0,0 +1,66 @@
+
+ * @package program
+ * @version $Id
+ * @link http://www.zentao.net
+ */
+?>
+
+
+
+ project->manageProducts;?>
+
+
+
+