Merge branch 'master' of https://github.com/easysoft/zentaopms
This commit is contained in:
@@ -451,7 +451,7 @@ class bug extends control
|
||||
$this->view->productName = $this->products[$productID];
|
||||
$this->view->moduleOptionMenu = $moduleOptionMenu;
|
||||
$this->view->stories = $stories;
|
||||
$this->view->projects = $this->product->getExecutionPairsByProduct($productID, $branch ? "0,$branch" : 0, $params = 'nodeleted');
|
||||
$this->view->projects = $this->product->getExecutionPairsByProduct($productID, $branch ? "0,$branch" : 0);
|
||||
$this->view->builds = $builds;
|
||||
$this->view->moduleID = (int)$moduleID;
|
||||
$this->view->projectID = $projectID;
|
||||
@@ -554,7 +554,7 @@ class bug extends control
|
||||
$this->view->stories = $stories;
|
||||
$this->view->builds = $builds;
|
||||
$this->view->users = $this->user->getPairs('devfirst|nodeleted');
|
||||
$this->view->projects = $this->product->getExecutionPairsByProduct($productID, $branch ? "0,$branch" : 0, 'nodeleted');
|
||||
$this->view->projects = $this->product->getExecutionPairsByProduct($productID, $branch ? "0,$branch" : 0);
|
||||
$this->view->projectID = $projectID;
|
||||
$this->view->moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0, $branch);
|
||||
$this->view->moduleID = $moduleID;
|
||||
@@ -727,7 +727,7 @@ class bug extends control
|
||||
$this->view->plans = $this->loadModel('productplan')->getPairs($productID, $bug->branch);
|
||||
$this->view->moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0, $bug->branch);
|
||||
$this->view->currentModuleID = $currentModuleID;
|
||||
$this->view->projects = $this->product->getExecutionPairsByProduct($bug->product, $bug->branch ? "0,{$bug->branch}" : 0, 'nodeleted');
|
||||
$this->view->projects = $this->product->getExecutionPairsByProduct($bug->product, $bug->branch ? "0,{$bug->branch}" : 0);
|
||||
$this->view->stories = $bug->project ? $this->story->getProjectStoryPairs($bug->project) : $this->story->getProductStoryPairs($bug->product, $bug->branch);
|
||||
$this->view->branches = $this->session->currentProductType == 'normal' ? array() : $this->loadModel('branch')->getPairs($bug->product);
|
||||
$this->view->tasks = $this->task->getProjectTaskPairs($bug->project);
|
||||
@@ -1100,7 +1100,7 @@ class bug extends control
|
||||
$this->view->bug = $bug;
|
||||
$this->view->users = $users;
|
||||
$this->view->assignedTo = $assignedTo;
|
||||
$this->view->projects = $this->loadModel('product')->getExecutionPairsByProduct($productID, $bug->branch ? "0,{$bug->branch}" : 0, 'nodeleted');
|
||||
$this->view->projects = $this->loadModel('product')->getExecutionPairsByProduct($productID, $bug->branch ? "0,{$bug->branch}" : 0);
|
||||
$this->view->builds = $this->loadModel('build')->getProductBuildPairs($productID, $branch = $bug->branch, 'all');
|
||||
$this->view->actions = $this->action->getList('bug', $bugID);
|
||||
$this->display();
|
||||
|
||||
@@ -115,7 +115,7 @@ class build extends control
|
||||
$execution->name = '';
|
||||
}
|
||||
|
||||
$executions = $this->loadModel('product')->getExecutionPairsByProduct($build->product, $build->branch, 'nodeleted');
|
||||
$executions = $this->loadModel('product')->getExecutionPairsByProduct($build->product, $build->branch);
|
||||
if(!isset($executions[$build->project])) $executions[$build->project] = $execution->name;
|
||||
|
||||
$productGroups = $this->project->getProducts($build->project);
|
||||
|
||||
@@ -6,17 +6,18 @@ $lang->waterfall->menuOrder[15] = 'project';
|
||||
$lang->waterfall->menuOrder[20] = 'weekly';
|
||||
$lang->waterfall->menuOrder[25] = 'review';
|
||||
$lang->waterfall->menuOrder[30] = 'doc';
|
||||
$lang->waterfall->menuOrder[35] = 'product';
|
||||
$lang->waterfall->menuOrder[40] = 'design';
|
||||
$lang->waterfall->menuOrder[45] = 'ci';
|
||||
$lang->waterfall->menuOrder[50] = 'qa';
|
||||
$lang->waterfall->menuOrder[55] = 'release';
|
||||
$lang->waterfall->menuOrder[60] = 'issue';
|
||||
$lang->waterfall->menuOrder[65] = 'risk';
|
||||
$lang->waterfall->menuOrder[70] = 'report';
|
||||
$lang->waterfall->menuOrder[75] = 'auditplan';
|
||||
$lang->waterfall->menuOrder[80] = 'cm';
|
||||
$lang->waterfall->menuOrder[85] = 'list';
|
||||
$lang->waterfall->menuOrder[35] = 'projectstory';
|
||||
$lang->waterfall->menuOrder[40] = 'product';
|
||||
$lang->waterfall->menuOrder[45] = 'design';
|
||||
$lang->waterfall->menuOrder[50] = 'ci';
|
||||
$lang->waterfall->menuOrder[55] = 'qa';
|
||||
$lang->waterfall->menuOrder[60] = 'release';
|
||||
$lang->waterfall->menuOrder[65] = 'issue';
|
||||
$lang->waterfall->menuOrder[70] = 'risk';
|
||||
$lang->waterfall->menuOrder[75] = 'report';
|
||||
$lang->waterfall->menuOrder[80] = 'auditplan';
|
||||
$lang->waterfall->menuOrder[85] = 'cm';
|
||||
$lang->waterfall->menuOrder[90] = 'list';
|
||||
|
||||
$lang->scrum->menuOrder[5] = 'program';
|
||||
$lang->scrum->menuOrder[10] = 'product';
|
||||
|
||||
@@ -869,6 +869,7 @@ $lang->menu->waterfall->programplan = array('link' => '计划|programplan|brows
|
||||
$lang->menu->waterfall->project = array('link' => $lang->projectCommon . '|project|task|projectID={PROJECT}', 'subModule' => ',project,task,');
|
||||
$lang->menu->waterfall->weekly = array('link' => '报告|weekly|index|program={PROGRAM}', 'subModule' => ',milestone,');
|
||||
$lang->menu->waterfall->doc = array('link' => '文档|doc|index|program={PROGRAM}');
|
||||
$lang->menu->waterfall->projectstory = array('link' => '需求|projectstory|requirement|product={PRODUCT}', 'subModule' => 'requirement,story,');
|
||||
//$lang->menu->waterfall->product = array('link' => '需求|product|browse|product={PRODUCT}', 'subModule' => ',story,');
|
||||
$lang->menu->waterfall->design = '设计|design|browse|product={PRODUCT}';
|
||||
$lang->menu->waterfall->ci = '代码|repo|browse|';
|
||||
|
||||
@@ -120,7 +120,7 @@ class doc extends control
|
||||
$this->lang->navGroup->doc = 'project';
|
||||
$this->lang->doc->menu = $this->lang->project->menu;
|
||||
$this->lang->doc->menuOrder = $this->lang->project->menuOrder;
|
||||
$this->project->setMenu($this->project->getExecutionPairs($this->session->PRJ, 'all', 'nocode'), $lib->project);
|
||||
$this->project->setMenu($this->project->getExecutionsByProject($this->session->PRJ, 'all', 0, true), $lib->project);
|
||||
$this->lang->set('menugroup.doc', 'project');
|
||||
}
|
||||
else
|
||||
@@ -226,7 +226,7 @@ class doc extends control
|
||||
|
||||
$projectID = $this->session->PRJ;
|
||||
$products = $this->product->getProductPairsByProject($projectID, 'noclosed');
|
||||
$projects = $this->project->getExecutionPairs($projectID, 'all', 'noclosed');
|
||||
$projects = $this->project->getExecutionsByProject($projectID, 'all', 0, true);
|
||||
|
||||
$libTypeList = $this->lang->doc->libTypeList;
|
||||
if(empty($products)) unset($libTypeList['product']);
|
||||
@@ -355,7 +355,7 @@ class doc extends control
|
||||
$this->lang->navGroup->doc = 'program';
|
||||
$this->lang->doc->menu = $this->lang->project->menu;
|
||||
$this->lang->doc->menuOrder = $this->lang->project->menuOrder;
|
||||
$this->project->setMenu($this->project->getExecutionPairs($this->session->PRJ, 'all', 'nocode'), $lib->project);
|
||||
$this->project->setMenu($this->project->getExecutionsByProject($this->session->PRJ, 'all', 0, true), $lib->project);
|
||||
$this->lang->set('menugroup.doc', 'project');
|
||||
|
||||
$this->lang->TRActions = common::hasPriv('doc', 'createLib') ? html::a(helper::createLink('doc', 'createLib'), "<i class='icon icon-plus'></i> " . $this->lang->doc->createLib, '', "class='btn btn-secondary iframe' data-width='70%'") : '';
|
||||
@@ -721,7 +721,7 @@ class doc extends control
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$libs = $this->doc->getAllLibsByType($type, $pager, $product);
|
||||
$libs = $this->doc->getAllLibsByType($type, $pager);
|
||||
$subLibs = array();
|
||||
if($type == 'product' or $type == 'project')
|
||||
{
|
||||
@@ -776,7 +776,7 @@ class doc extends control
|
||||
$this->lang->navGroup->doc = 'program';
|
||||
$this->lang->doc->menu = $this->lang->project->menu;
|
||||
$this->lang->doc->menuOrder = $this->lang->project->menuOrder;
|
||||
$this->project->setMenu($this->project->getExecutionPairs($this->session->PRJ, 'all', 'nocode'), $objectID);
|
||||
$this->project->setMenu($this->project->getExecutionsByProject($this->session->PRJ, 'all', 0, true), $objectID);
|
||||
$this->lang->set('menugroup.doc', 'project');
|
||||
}
|
||||
else
|
||||
@@ -872,7 +872,7 @@ class doc extends control
|
||||
$this->lang->navGroup->doc = 'project';
|
||||
$this->lang->doc->menu = $this->lang->project->menu;
|
||||
$this->lang->doc->menuOrder = $this->lang->project->menuOrder;
|
||||
$this->project->setMenu($this->project->getExecutionPairs($this->session->PRJ, 'all', 'nocode'), $objectID);
|
||||
$this->project->setMenu($this->project->getExecutionsByProject($this->session->PRJ, 'all', 0, true), $objectID);
|
||||
$this->lang->set('menugroup.doc', 'project');
|
||||
}
|
||||
else
|
||||
|
||||
@@ -640,7 +640,7 @@ class product extends control
|
||||
}
|
||||
else
|
||||
{
|
||||
$projects = $this->product->getExecutionPairsByProduct($productID, $branch ? "0,$branch" : $branch, 'nodeleted');
|
||||
$projects = $this->product->getExecutionPairsByProduct($productID, $branch ? "0,$branch" : $branch);
|
||||
}
|
||||
if($this->app->getViewType() == 'json') die(json_encode($projects));
|
||||
|
||||
|
||||
@@ -758,26 +758,38 @@ class productModel extends model
|
||||
*
|
||||
* @param int $productID
|
||||
* @param int $branch
|
||||
* @param string $status all|nodeleted
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getExecutionPairsByProduct($productID, $branch = 0, $status = 'all')
|
||||
public function getExecutionPairsByProduct($productID, $branch = 0)
|
||||
{
|
||||
if(!$this->session->PRJ || !$productID) return array();
|
||||
|
||||
$executions = $this->dao->select('t2.id, t2.name')->from(TABLE_PROJECTPRODUCT)
|
||||
->alias('t1')->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
|
||||
$executions = $this->dao->select('t2.id,t2.name,t2.grade,t2.parent')->from(TABLE_PROJECTPRODUCT)->alias('t1')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
|
||||
->where('t1.product')->eq($productID)
|
||||
->andWhere('t2.project')->eq($this->session->PRJ)
|
||||
->beginIF($branch)->andWhere('t1.branch')->in($branch)->fi()
|
||||
->beginIF(!$this->app->user->admin)->andWhere('t2.id')->in($this->app->user->view->sprints)->fi()
|
||||
->beginIF($status == 'nodeleted')->andWhere('t2.deleted')->eq('0')->fi()
|
||||
->orderBy('t2.begin asc')
|
||||
->fetchPairs();
|
||||
->andWhere('t2.deleted')->eq('0')
|
||||
->orderBy('t2.path_asc')
|
||||
->fetchAll('id');
|
||||
|
||||
$executions = array('0' => '') + $executions;
|
||||
return $executions;
|
||||
/* The waterfall project needs to show the hierarchy and remove the parent stage. */
|
||||
$project = $this->loadModel('program')->getPRJByID($this->session->PRJ);
|
||||
if($project->model == 'waterfall')
|
||||
{
|
||||
foreach($executions as $execution)
|
||||
{
|
||||
if($execution->parent and isset($executions[$execution->parent])) $executions[$execution->id]->name = $executions[$execution->parent]->name . '/' . $execution->name;
|
||||
}
|
||||
|
||||
foreach($executions as $execution) if($execution->grade == 2) unset($executions[$execution->parent]);
|
||||
}
|
||||
|
||||
$executionList = array('0' => '');
|
||||
foreach($executions as $execution) $executionList[$execution->id] = $execution->name;
|
||||
return $executionList;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,7 +36,7 @@ $lang->program->errorSameProducts = 'Project cannot be associated with multip
|
||||
$lang->program->errorNoProducts = 'At least one product is linked with the project.';
|
||||
$lang->program->copyNoProject = 'There are no items available to copy.';
|
||||
$lang->program->PRJSource = 'Project source:';
|
||||
$lang->program->PRJStandalone = 'Standalone Projects';
|
||||
$lang->program->PRJStandalone = 'Projects that do not belong to a program.';
|
||||
$lang->program->tips = 'Note';
|
||||
$lang->program->setTeam = 'Set Team';
|
||||
$lang->program->goback = 'Go Back';
|
||||
|
||||
@@ -36,7 +36,7 @@ $lang->program->errorSameProducts = 'Project cannot be associated with multip
|
||||
$lang->program->errorNoProducts = 'At least one product is linked with the project.';
|
||||
$lang->program->copyNoProject = 'There are no items available to copy.';
|
||||
$lang->program->PRJSource = 'Project source:';
|
||||
$lang->program->PRJStandalone = 'Standalone Projects';
|
||||
$lang->program->PRJStandalone = 'Projects that do not belong to a program.';
|
||||
$lang->program->tips = 'Note';
|
||||
$lang->program->setTeam = 'Set Team';
|
||||
$lang->program->goback = 'Go Back';
|
||||
|
||||
@@ -36,7 +36,7 @@ $lang->program->errorSameProducts = 'Project cannot be associated with multip
|
||||
$lang->program->errorNoProducts = 'At least one product is linked with the project.';
|
||||
$lang->program->copyNoProject = 'There are no items available to copy.';
|
||||
$lang->program->PRJSource = 'Project source:';
|
||||
$lang->program->PRJStandalone = 'Standalone Projects';
|
||||
$lang->program->PRJStandalone = 'Projects that do not belong to a program.';
|
||||
$lang->program->tips = 'Note';
|
||||
$lang->program->setTeam = 'Set Team';
|
||||
$lang->program->goback = 'Go Back';
|
||||
|
||||
@@ -36,7 +36,7 @@ $lang->program->errorSameProducts = 'Project cannot be associated with multip
|
||||
$lang->program->errorNoProducts = 'At least one product is linked with the project.';
|
||||
$lang->program->copyNoProject = 'There are no items available to copy.';
|
||||
$lang->program->PRJSource = 'Project source:';
|
||||
$lang->program->PRJStandalone = 'Standalone Projects';
|
||||
$lang->program->PRJStandalone = 'Projects that do not belong to a program.';
|
||||
$lang->program->tips = 'Note';
|
||||
$lang->program->setTeam = 'Set Team';
|
||||
$lang->program->goback = 'Go Back';
|
||||
|
||||
@@ -36,7 +36,7 @@ $lang->program->errorSameProducts = '项目不能关联多个相同的产品
|
||||
$lang->program->errorNoProducts = '项目最少关联一个产品。';
|
||||
$lang->program->copyNoProject = '没有可用的项目来复制';
|
||||
$lang->program->PRJSource = '项目来源:';
|
||||
$lang->program->PRJStandalone = '独立项目';
|
||||
$lang->program->PRJStandalone = '没有所属项目集的项目';
|
||||
$lang->program->tips = '提示';
|
||||
$lang->program->setTeam = '设置团队';
|
||||
$lang->program->goback = '返回项目列表';
|
||||
|
||||
@@ -23,22 +23,27 @@ $lang->program->PRJManagePriv = '項目維護權限';
|
||||
$lang->program->PRJManageMembers = '項目團隊';
|
||||
$lang->program->export = '導出';
|
||||
$lang->program->PRJManageGroupMember = '維護分組用戶';
|
||||
$lang->program->PRJModuleSetting = '項目集設置';
|
||||
$lang->program->PRJModuleSetting = '列表設置';
|
||||
$lang->program->PRJModuleOpen = '顯示項目集名';
|
||||
$lang->program->PRJUpdateOrder = '排序';
|
||||
$lang->program->PRJSort = '項目排序';
|
||||
$lang->program->PRJWhitelist = '項目白名單';
|
||||
$lang->program->PRJAddWhitelist = '項目添加白名單';
|
||||
$lang->program->unbindWhielist = '項目刪除白名單';
|
||||
$lang->program->PRJManageProducts = '項目關聯產品';
|
||||
$lang->program->PRJManageProducts = '關聯產品';
|
||||
$lang->program->copyTitle = '請選擇一個項目來複制';
|
||||
$lang->program->errorSameProducts = '項目不能關聯多個相同的產品。';
|
||||
$lang->program->errorNoProducts = '項目最少關聯一個產品。';
|
||||
$lang->program->copyNoProject = '沒有可用的項目來複制';
|
||||
$lang->program->PRJSource = '項目來源:';
|
||||
$lang->program->PRJStandalone = '獨立項目';
|
||||
$lang->program->PRJStandalone = '沒有所屬項目集的項目';
|
||||
$lang->program->tips = '提示';
|
||||
$lang->program->setTeam = '設置團隊';
|
||||
$lang->program->goback = '返回項目列表';
|
||||
|
||||
/* Fields. */
|
||||
$lang->program->common = '項目集';
|
||||
$lang->program->project = '項目';
|
||||
$lang->program->stage = '階段';
|
||||
$lang->program->PRJName = '項目名稱';
|
||||
$lang->program->PRJModel = '管理類型';
|
||||
@@ -148,6 +153,7 @@ $lang->program->cannotCancelCat = "該項目下已經有子項目,無法取
|
||||
$lang->program->parentBeginEnd = "父項目起止時間:%s ~ %s";
|
||||
$lang->program->childLongTime = "子項目中有長期項目,父項目也應該是長期項目";
|
||||
$lang->program->readjustTime = '重新調整項目起止時間';
|
||||
$lang->program->afterInfo = "項目添加成功,您現在可以進行以下操作:";
|
||||
|
||||
$lang->program->PRJProgramTitle['0'] = '不顯示';
|
||||
$lang->program->PRJProgramTitle['base'] = '只顯示一級項目集';
|
||||
@@ -220,12 +226,12 @@ $lang->program->PGMShowClosed = '顯示已關閉';
|
||||
$lang->program->PGMTips = '修改父項目集,可關聯產品也會發生變化,並且變為必填,如果未選擇任何項目集,則系統會預設創建一個和該項目同名的產品並關聯到該項目。';
|
||||
$lang->program->PGMChangeTips = '修改父項目集後,項目已關聯的產品會被清空,並且項目下的需求、bug等數據也會受影響,是否修改?';
|
||||
|
||||
$lang->program->PGMAclList['open'] = "公開(有項目集視圖權限,即可訪問)";
|
||||
$lang->program->PGMAclList['private'] = "私有(項目集負責人和干係人可訪問)";
|
||||
$lang->program->PGMAclList['open'] = "公開(有項目集視圖權限,即可訪問)";
|
||||
|
||||
$lang->program->subPGMAclList['private'] = "私有(本項目集負責人和干係人可訪問)";
|
||||
$lang->program->subPGMAclList['open'] = "全部公開(有項目集視圖權限,即可訪問)";
|
||||
$lang->program->subPGMAclList['program'] = "項目集內公開 (所有上級項目集負責人和干係人、本項目集負責人和干係人可訪問)";
|
||||
$lang->program->subPGMAclList['private'] = "私有(本項目集負責人和干係人可訪問)";
|
||||
|
||||
$lang->program->PGMAuthList['extend'] = '繼承(取項目權限與組織權限的並集)';
|
||||
$lang->program->PGMAuthList['reset'] = '重新定義(只取項目權限)';
|
||||
|
||||
@@ -52,15 +52,16 @@ class programplanModel extends model
|
||||
*/
|
||||
public function getStage($projectID = 0, $productID = 0, $browseType = 'all', $orderBy = 'id_asc')
|
||||
{
|
||||
$executions = empty($projectID) ? array() : $this->loadModel('product')->getExecutionPairsByProduct($productID);
|
||||
if(empty($projectID) || empty($productID)) return array();
|
||||
|
||||
$plans = $this->dao->select('*')->from(TABLE_PROJECT)
|
||||
->where('type')->eq('stage')
|
||||
->beginIF($browseType == 'all')->andWhere('project')->eq($projectID)->fi()
|
||||
->beginIF($browseType == 'parent')->andWhere('parent')->eq($projectID)->fi()
|
||||
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->sprints)->fi()
|
||||
->beginIF($productID)->andWhere('id')->in(array_keys($executions))->fi()
|
||||
->andWhere('deleted')->eq(0)
|
||||
$plans = $this->dao->select('t2.*')->from(TABLE_PROJECTPRODUCT)->alias('t1')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
|
||||
->where('t1.product')->eq($productID)
|
||||
->andWhere('t2.type')->eq('stage')
|
||||
->beginIF($browseType == 'all')->andWhere('t2.project')->eq($projectID)->fi()
|
||||
->beginIF($browseType == 'parent')->andWhere('t2.parent')->eq($projectID)->fi()
|
||||
->beginIF(!$this->app->user->admin)->andWhere('t2.id')->in($this->app->user->view->sprints)->fi()
|
||||
->andWhere('t2.deleted')->eq('0')
|
||||
->orderBy($orderBy)
|
||||
->fetchAll('id');
|
||||
|
||||
@@ -663,6 +664,8 @@ class programplanModel extends model
|
||||
|
||||
$childrenTotalPercent = $this->getTotalPercent($parentPlan, true);
|
||||
$childrenTotalPercent = $plan->parent == $oldPlan->parent ? ($childrenTotalPercent - $oldPlan->percent + $plan->percent) : ($childrenTotalPercent + $plan->percent);
|
||||
|
||||
/* The sum of the workload of the child phases cannot be greater than that of the parent phase. */
|
||||
if($childrenTotalPercent > $parentPercent)
|
||||
{
|
||||
dao::$errors['message'][] = sprintf($this->lang->programplan->error->parentWorkload, $parentPercent . '%');
|
||||
@@ -672,12 +675,15 @@ class programplanModel extends model
|
||||
/* If child plan has milestone, update parent plan set milestone eq 0 . */
|
||||
if($plan->milestone and $parentPlan->milestone) $this->dao->update(TABLE_PROJECT)->set('milestone')->eq(0)->where('id')->eq($oldPlan->parent)->exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The workload of the parent plan cannot exceed 100%. */
|
||||
$oldPlan->parent = $plan->parent;
|
||||
$totalPercent = $this->getTotalPercent($oldPlan);
|
||||
$totalPercent = $totalPercent + $plan->percent;
|
||||
if($totalPercent > 100) return dao::$errors['percent'][] = $this->lang->programplan->error->percentOver;
|
||||
}
|
||||
|
||||
/* The workload of the parent plan cannot exceed 100%. */
|
||||
$oldPlan->parent = $plan->parent;
|
||||
$totalPercent = $this->getTotalPercent($oldPlan);
|
||||
$totalPercent = $totalPercent + $plan->percent;
|
||||
if($totalPercent > 100) return dao::$errors['percent'][] = $this->lang->programplan->error->percentOver;
|
||||
|
||||
/* Set planDuration and realDuration. */
|
||||
$plan->planDuration = $this->getDuration($plan->begin, $plan->end);
|
||||
|
||||
@@ -1084,6 +1084,8 @@ class project extends control
|
||||
public function create($productID = '', $projectID = '', $copyProjectID = '', $planID = 0, $confirm = 'no')
|
||||
{
|
||||
$this->app->loadLang('program');
|
||||
$this->app->loadLang('stage');
|
||||
$this->app->loadLang('programplan');
|
||||
if($projectID)
|
||||
{
|
||||
if(!empty($planID))
|
||||
@@ -1204,6 +1206,7 @@ class project extends control
|
||||
$this->view->copyProjectID = $copyProjectID;
|
||||
$this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products));
|
||||
$this->view->users = $this->loadModel('user')->getPairs('nodeleted|noclosed');
|
||||
$this->view->isStage = $project->model == 'waterfall' ? true : false;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
@@ -1220,6 +1223,8 @@ class project extends control
|
||||
public function edit($projectID, $action = 'edit', $extra = '')
|
||||
{
|
||||
$this->app->loadLang('program');
|
||||
$this->app->loadLang('stage');
|
||||
$this->app->loadLang('programplan');
|
||||
$browseProjectLink = $this->createLink('project', 'browse', "projectID=$projectID");
|
||||
if(!empty($_POST))
|
||||
{
|
||||
@@ -1323,6 +1328,7 @@ class project extends control
|
||||
$this->view->linkedProducts = $linkedProducts;
|
||||
$this->view->productPlans = $productPlans;
|
||||
$this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($linkedProducts), '', $linkedBranches);
|
||||
$this->view->isStage = $PRJData->model == 'waterfall' ? true : false;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
@@ -1335,6 +1341,8 @@ class project extends control
|
||||
*/
|
||||
public function batchEdit($projectID = 0)
|
||||
{
|
||||
$this->app->loadLang('stage');
|
||||
|
||||
if($this->post->names)
|
||||
{
|
||||
$allChanges = $this->project->batchUpdate();
|
||||
@@ -1383,6 +1391,8 @@ class project extends control
|
||||
$rdUsers = $this->user->getPairs('noclosed|nodeleted|devfirst', $appendRdUsers, $this->config->maxCount);
|
||||
if(!empty($this->config->user->moreLink)) $this->config->moreLinks["RD"] = $this->config->user->moreLink;
|
||||
|
||||
$PRJData = $this->project->getById($this->session->PRJ);
|
||||
|
||||
$this->view->title = $this->lang->project->batchEdit;
|
||||
$this->view->position[] = $this->lang->project->batchEdit;
|
||||
$this->view->projectIDList = $projectIDList;
|
||||
@@ -1391,6 +1401,7 @@ class project extends control
|
||||
$this->view->poUsers = $poUsers;
|
||||
$this->view->qdUsers = $qdUsers;
|
||||
$this->view->rdUsers = $rdUsers;
|
||||
$this->view->isStage = $PRJData->model == 'waterfall' ? true : false;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
+62
-16
@@ -332,6 +332,24 @@ class projectModel extends model
|
||||
->remove('products, workDays, delta, branch, uid, plans')
|
||||
->get();
|
||||
|
||||
/* Check the workload format and total. */
|
||||
if(!empty($sprint->percent))
|
||||
{
|
||||
if(!preg_match("/^[0-9]+(.[0-9]{1,3})?$/", $sprint->percent))
|
||||
{
|
||||
dao::$errors['percent'] = $this->lang->programplan->error->percentNumber;
|
||||
return false;
|
||||
}
|
||||
|
||||
$percentTotal = $this->dao->select('SUM(percent) as percent')->from(TABLE_PROJECT)->where('project')->eq($project->id)->andWhere('type')->eq('stage')->andWhere('deleted')->eq('0')->fetch('percent');
|
||||
$percentTotal += $sprint->percent;
|
||||
if($percentTotal > 100) return dao::$errors['percent'] = $this->lang->programplan->error->percentOver;
|
||||
}
|
||||
|
||||
/* Set planDuration and realDuration. */
|
||||
$sprint->planDuration = $this->loadModel('programplan')->getDuration($sprint->begin, $sprint->end);
|
||||
if(!empty($sprint->realBegan) and !empty($sprint->realEnd)) $sprint->realDuration = $this->loadModel('programplan')->getDuration($sprint->realBegan, $sprint->realEnd);
|
||||
|
||||
$sprint = $this->loadModel('file')->processImgURL($sprint, $this->config->project->editor->create['id'], $this->post->uid);
|
||||
$this->dao->insert(TABLE_PROJECT)->data($sprint)
|
||||
->autoCheck($skipFields = 'begin,end')
|
||||
@@ -433,6 +451,24 @@ class projectModel extends model
|
||||
->get();
|
||||
|
||||
$project = $this->loadModel('file')->processImgURL($project, $this->config->project->editor->edit['id'], $this->post->uid);
|
||||
|
||||
/* Check the workload format and total. */
|
||||
if(!empty($project->percent))
|
||||
{
|
||||
if(!preg_match("/^[0-9]+(.[0-9]{1,3})?$/", $project->percent))
|
||||
{
|
||||
dao::$errors['percent'] = $this->lang->programplan->error->percentNumber;
|
||||
return false;
|
||||
}
|
||||
|
||||
$percentTotal = $this->dao->select('SUM(percent) as percent')->from(TABLE_PROJECT)->where('project')->eq($this->session->PRJ)->andWhere('type')->eq('stage')->andWhere('deleted')->eq('0')->fetch('percent');
|
||||
if($percentTotal > 100) return dao::$errors['percent'] = $this->lang->programplan->error->percentOver;
|
||||
}
|
||||
|
||||
/* Set planDuration and realDuration. */
|
||||
$project->planDuration = $this->loadModel('programplan')->getDuration($project->begin, $project->end);
|
||||
if(!empty($project->realBegan) and !empty($project->realEnd)) $project->realDuration = $this->loadModel('programplan')->getDuration($project->realBegan, $project->realEnd);
|
||||
|
||||
$this->dao->update(TABLE_PROJECT)->data($project)
|
||||
->autoCheck($skipFields = 'begin,end')
|
||||
->batchcheck($this->config->project->edit->requiredFields, 'notempty')
|
||||
@@ -502,20 +538,21 @@ class projectModel extends model
|
||||
|
||||
$projectID = (int)$projectID;
|
||||
$projects[$projectID] = new stdClass();
|
||||
$projects[$projectID]->name = $projectName;
|
||||
$projects[$projectID]->code = $projectCode;
|
||||
$projects[$projectID]->PM = $data->PMs[$projectID];
|
||||
$projects[$projectID]->PO = $data->POs[$projectID];
|
||||
$projects[$projectID]->QD = $data->QDs[$projectID];
|
||||
$projects[$projectID]->RD = $data->RDs[$projectID];
|
||||
$projects[$projectID]->lifetime = $data->lifetimes[$projectID];
|
||||
$projects[$projectID]->status = $data->statuses[$projectID];
|
||||
$projects[$projectID]->begin = $data->begins[$projectID];
|
||||
$projects[$projectID]->end = $data->ends[$projectID];
|
||||
$projects[$projectID]->team = $data->teams[$projectID];
|
||||
$projects[$projectID]->desc = htmlspecialchars_decode($data->descs[$projectID]);
|
||||
$projects[$projectID]->days = $data->dayses[$projectID];
|
||||
$projects[$projectID]->order = $data->orders[$projectID];
|
||||
$projects[$projectID]->name = $projectName;
|
||||
$projects[$projectID]->code = $projectCode;
|
||||
$projects[$projectID]->PM = $data->PMs[$projectID];
|
||||
$projects[$projectID]->PO = $data->POs[$projectID];
|
||||
$projects[$projectID]->QD = $data->QDs[$projectID];
|
||||
$projects[$projectID]->RD = $data->RDs[$projectID];
|
||||
$projects[$projectID]->lifetime = $data->lifetimes[$projectID];
|
||||
$projects[$projectID]->attribute = $data->attributes[$projectID];
|
||||
$projects[$projectID]->status = $data->statuses[$projectID];
|
||||
$projects[$projectID]->begin = $data->begins[$projectID];
|
||||
$projects[$projectID]->end = $data->ends[$projectID];
|
||||
$projects[$projectID]->team = $data->teams[$projectID];
|
||||
$projects[$projectID]->desc = htmlspecialchars_decode($data->descs[$projectID]);
|
||||
$projects[$projectID]->days = $data->dayses[$projectID];
|
||||
$projects[$projectID]->order = $data->orders[$projectID];
|
||||
|
||||
/* Check unique name for edited projects. */
|
||||
if(isset($nameList[$projectName])) dao::$errors['name'][] = 'project#' . $projectID . sprintf($this->lang->error->unique, $this->lang->project->name, $projectName);
|
||||
@@ -911,10 +948,11 @@ class projectModel extends model
|
||||
* @param int $projectID
|
||||
* @param string $status
|
||||
* @param int $limit
|
||||
* @param string $pairs
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getExecutionsByProject($projectID, $status = 'all', $limit = 0)
|
||||
public function getExecutionsByProject($projectID, $status = 'all', $limit = 0, $pairs = false)
|
||||
{
|
||||
if(!$projectID) return array();
|
||||
|
||||
@@ -924,7 +962,7 @@ class projectModel extends model
|
||||
->beginIF($status == 'undone')->andWhere('status')->notIN('done,closed')->fi()
|
||||
->beginIF($status != 'all' and $status != 'undone')->andWhere('status')->in($status)->fi()
|
||||
->andWhere('deleted')->eq('0')
|
||||
->orderBy('begin_asc')
|
||||
->orderBy('path_asc')
|
||||
->beginIF($limit)->limit($limit)->fi()
|
||||
->fetchAll('id');
|
||||
|
||||
@@ -935,9 +973,17 @@ class projectModel extends model
|
||||
{
|
||||
if($execution->parent and isset($executions[$execution->parent])) $executions[$execution->id]->name = $executions[$execution->parent]->name . '/' . $execution->name;
|
||||
}
|
||||
|
||||
foreach($executions as $execution) if($execution->grade == 2) unset($executions[$execution->parent]);
|
||||
}
|
||||
|
||||
if($pairs)
|
||||
{
|
||||
$executionPairs = array();
|
||||
foreach($executions as $execution) $executionPairs[$execution->id] = $execution->name;
|
||||
$executions = $executionPairs;
|
||||
}
|
||||
|
||||
return $executions;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,18 @@
|
||||
<td class='text-left<?php echo zget($visibleFields, 'PO', ' hidden')?>' style='overflow:visible'><?php echo html::select("POs[$projectID]", $poUsers, $projects[$projectID]->PO, "class='form-control chosen'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'QD', ' hidden')?>' style='overflow:visible'><?php echo html::select("QDs[$projectID]", $qdUsers, $projects[$projectID]->QD, "class='form-control chosen'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'RD', ' hidden')?>' style='overflow:visible'><?php echo html::select("RDs[$projectID]", $rdUsers, $projects[$projectID]->RD, "class='form-control chosen'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'type', 'hidden')?>'><?php echo html::select("lifetimes[$projectID]", $lang->program->PRJLifeTimeList, $projects[$projectID]->type, 'class=form-control');?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'type', 'hidden')?>'>
|
||||
<?php
|
||||
if($isStage)
|
||||
{
|
||||
echo html::select("attributes[$projectID]", $lang->stage->typeList, $projects[$projectID]->attribute, 'class=form-control');
|
||||
}
|
||||
else
|
||||
{
|
||||
echo html::select("lifetimes[$projectID]", $lang->program->PRJLifeTimeList, $projects[$projectID]->lifetime, 'class=form-control');
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td class='<?php echo zget($visibleFields, 'status', 'hidden')?>'><?php echo html::select("statuses[$projectID]", $lang->project->statusList, $projects[$projectID]->status, 'class=form-control');?></td>
|
||||
<td><?php echo html::input("begins[$projectID]", $projects[$projectID]->begin, "class='form-control form-date' onchange='computeWorkDays(this.id)'");?></td>
|
||||
<td><?php echo html::input("ends[$projectID]", $projects[$projectID]->end, "class='form-control form-date' onchange='computeWorkDays(this.id)'");?></td>
|
||||
|
||||
@@ -81,10 +81,32 @@
|
||||
<?php if(!$isSprint):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->project->type;?></th>
|
||||
<td><?php echo html::select('lifetime', $lang->program->PRJLifeTimeList, '', "class='form-control' onchange='showLifeTimeTips()'");?></td>
|
||||
<td>
|
||||
<?php
|
||||
if($isStage)
|
||||
{
|
||||
echo html::select('attribute', $lang->stage->typeList, '', "class='form-control'");
|
||||
}
|
||||
else
|
||||
{
|
||||
echo html::select('lifetime', $lang->program->PRJLifeTimeList, '', "class='form-control' onchange='showLifeTimeTips()'");
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td class='muted' colspan='2'><div id='lifeTimeTips'><?php echo $lang->project->typeDesc;?></div></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<?php if($isStage):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->programplan->percent;?></th>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<?php echo html::input('percent', '', "class='form-control'");?>
|
||||
<span class='input-group-addon'>%</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr class='hide'>
|
||||
<th><?php echo $lang->project->status;?></th>
|
||||
<td><?php echo html::hidden('status', 'wait');?></td>
|
||||
|
||||
@@ -63,7 +63,29 @@
|
||||
<?php if(!$isSprint):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->project->type;?></th>
|
||||
<td><?php echo html::select('lifetime', $lang->program->PRJLifeTimeList, $project->type, "class='form-control'");?></td>
|
||||
<td>
|
||||
<?php
|
||||
if($isStage)
|
||||
{
|
||||
echo html::select('attribute', $lang->stage->typeList, $project->attribute, "class='form-control'");
|
||||
}
|
||||
else
|
||||
{
|
||||
echo html::select('lifetime', $lang->program->PRJLifeTimeList, $project->lifetime, "class='form-control' onchange='showLifeTimeTips()'");
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<?php if($isStage):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->programplan->percent;?></th>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<?php echo html::input('percent', $project->percent, "class='form-control'");?>
|
||||
<span class='input-group-addon'>%</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr>
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/**
|
||||
* The control file of projectStory module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
|
||||
* @package projectStory
|
||||
* @version $Id: control.php 5094 2013-07-10 08:46:15Z chencongzhi520@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
class projectStory extends control
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/**
|
||||
* The model file of projectStory module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
|
||||
* @package projectStory
|
||||
* @version $Id: model.php 5118 2013-07-12 07:41:41Z chencongzhi520@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
class projectStory extends model()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -164,7 +164,7 @@ class testtask extends control
|
||||
|
||||
/* Create testtask from testtask of test.*/
|
||||
$productID = $productID ? $productID : key($this->products);
|
||||
$projects = empty($productID) ? array() : $this->product->getExecutionPairsByProduct($productID, 0, $params = 'nodeleted');
|
||||
$projects = empty($productID) ? array() : $this->product->getExecutionPairsByProduct($productID);
|
||||
$builds = empty($productID) ? array() : $this->loadModel('build')->getProductBuildPairs($productID, 0, 'notrunk', true);
|
||||
|
||||
/* Set menu. */
|
||||
@@ -592,7 +592,7 @@ class testtask extends control
|
||||
|
||||
/* Create testtask from testtask of test.*/
|
||||
$productID = $productID ? $productID : key($this->products);
|
||||
$projects = empty($productID) ? array() : $this->product->getExecutionPairsByProduct($productID, 0, $params = 'nodeleted');
|
||||
$projects = empty($productID) ? array() : $this->product->getExecutionPairsByProduct($productID);
|
||||
$builds = empty($productID) ? array() : $this->loadModel('build')->getProductBuildPairs($productID, 0, 'notrunk', true);
|
||||
|
||||
$this->view->task = $task;
|
||||
@@ -1162,7 +1162,7 @@ class testtask extends control
|
||||
$this->app->loadLang('job');
|
||||
|
||||
$productID = $productID ? $productID : key($this->products);
|
||||
$projects = empty($productID) ? array() : $this->product->getExecutionPairsByProduct($productID, 0, $params = 'nodeleted');
|
||||
$projects = empty($productID) ? array() : $this->product->getExecutionPairsByProduct($productID);
|
||||
$builds = empty($productID) ? array() : $this->loadModel('build')->getProductBuildPairs($productID, 0, 'notrunk');
|
||||
|
||||
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testtask->importUnitResult;
|
||||
|
||||
Reference in New Issue
Block a user