Merge branch 'release/21.7.5' into feature/workflowgroup
This commit is contained in:
@@ -63,7 +63,7 @@ class programplan extends control
|
||||
{
|
||||
$this->loadModel('doc');
|
||||
$projects = $this->loadModel('project')->getPairsByModel(array('ipd', 'waterfall', 'waterfallplus'));
|
||||
if(empty($projects)) return $this->send(array('result' => 'fail', 'message' => $this->lang->doc->tips->noProject));
|
||||
if(empty($projects)) return $this->send(array('result' => 'fail', 'message' => $this->lang->programplan->error->noProject));
|
||||
|
||||
if(!$projectID) $projectID = key($projects);
|
||||
$this->view->projects = $projects;
|
||||
|
||||
@@ -148,6 +148,7 @@ $lang->programplan->error->planDrag = 'The %s stage cannot be dragged';
|
||||
$lang->programplan->error->notStage = $lang->executionCommon . '/Kanban cannot create a sub stage.';
|
||||
$lang->programplan->error->sameType = 'Type of the stage must be as same as parent: "%s"';
|
||||
$lang->programplan->error->emptyParentName = "Contains sub stages, stage names cannot be empty.";
|
||||
$lang->programplan->error->noProject = "When there are no waterfall, waterfall plus, or IPD {$lang->projectCommon} in the system, Gantt charts cannot be added.";
|
||||
|
||||
$lang->programplan->ganttBrowseType['gantt'] = 'Group by Stage';
|
||||
$lang->programplan->ganttBrowseType['assignedTo'] = 'Group by AssignedTo';
|
||||
|
||||
@@ -148,6 +148,7 @@ $lang->programplan->error->planDrag = 'The %s stage cannot be dragged';
|
||||
$lang->programplan->error->notStage = $lang->executionCommon . '/Kanban cannot create a sub stage.';
|
||||
$lang->programplan->error->sameType = 'Type of the stage must be as same as parent: "%s"';
|
||||
$lang->programplan->error->emptyParentName = "Contains sub stages, stage names cannot be empty.";
|
||||
$lang->programplan->error->noProject = "When there are no waterfall, waterfall plus, or IPD {$lang->projectCommon} in the system, Gantt charts cannot be added.";
|
||||
|
||||
$lang->programplan->ganttBrowseType['gantt'] = 'Group by Stage';
|
||||
$lang->programplan->ganttBrowseType['assignedTo'] = 'Group by AssignedTo';
|
||||
|
||||
@@ -148,6 +148,7 @@ $lang->programplan->error->planDrag = 'The %s stage cannot be dragged';
|
||||
$lang->programplan->error->notStage = $lang->executionCommon . '/Kanban cannot create a sub stage.';
|
||||
$lang->programplan->error->sameType = 'Type of the stage must be as same as parent: "%s"';
|
||||
$lang->programplan->error->emptyParentName = "Contains sub stages, stage names cannot be empty.";
|
||||
$lang->programplan->error->noProject = "When there are no waterfall, waterfall plus, or IPD {$lang->projectCommon} in the system, Gantt charts cannot be added.";
|
||||
|
||||
$lang->programplan->ganttBrowseType['gantt'] = 'Group by Stage';
|
||||
$lang->programplan->ganttBrowseType['assignedTo'] = 'Group by AssignedTo';
|
||||
|
||||
@@ -148,6 +148,7 @@ $lang->programplan->error->planDrag = '%s的阶段不可以拖动';
|
||||
$lang->programplan->error->notStage = $lang->executionCommon . '/看板不支持创建子阶段';
|
||||
$lang->programplan->error->sameType = '父阶段类型为"%s",阶段类型需与父阶段一致';
|
||||
$lang->programplan->error->emptyParentName = "包含子阶段,阶段名称不能为空。";
|
||||
$lang->programplan->error->noProject = "系统中没有瀑布、融合瀑布、ipd{$lang->projectCommon}时,无法添加甘特图。";
|
||||
|
||||
$lang->programplan->ganttBrowseType['gantt'] = '按阶段分组';
|
||||
$lang->programplan->ganttBrowseType['assignedTo'] = '按指派给分组';
|
||||
|
||||
@@ -235,6 +235,7 @@ class programplanModel extends model
|
||||
$workingDays = $this->loadModel('holiday')->getActualWorkingDays($begin, $end);
|
||||
foreach($tasksGroup as $group => $tasks)
|
||||
{
|
||||
if(!$group) $group = '/'; // 未指派
|
||||
$groupID ++;
|
||||
$groupKey = $groupID . $group;
|
||||
$datas['data'][$groupKey] = $this->programplanTao->buildGroupDataForGantt($groupID, $group, $users);
|
||||
|
||||
@@ -572,6 +572,14 @@ class programplanTao extends programplanModel
|
||||
$this->setTreePath($stageID);
|
||||
$this->computeProgress($stageID, 'create');
|
||||
|
||||
/* Add the execution team members to parent executions. */
|
||||
$stagePath = $this->dao->findByID($stageID)->from(TABLE_PROJECT)->fetch('path');
|
||||
foreach(explode(',', $stagePath) as $stageParentID)
|
||||
{
|
||||
if(empty($stageParentID) || $stageParentID == $projectID) continue;
|
||||
$this->execution->addExecutionMembers((int)$stageParentID, array($plan->PM));
|
||||
}
|
||||
|
||||
return $stageID;
|
||||
}
|
||||
|
||||
@@ -733,7 +741,7 @@ class programplanTao extends programplanModel
|
||||
{
|
||||
$this->app->loadLang('task');
|
||||
$groupName = $group;
|
||||
$groupName = $group ? zget($users, $group) : $this->lang->task->noAssigned;
|
||||
$groupName = $group != '/' ? zget($users, $group) : $this->lang->task->noAssigned;
|
||||
|
||||
$dataGroup = new stdclass();
|
||||
$dataGroup->id = $groupID;
|
||||
|
||||
@@ -7,13 +7,13 @@ title=测试 programplanModel->getDataForGanttGroupByAssignedTo();
|
||||
timeout=0
|
||||
cid=0
|
||||
|
||||
- 测试获取阶段数据第0条的type属性 @task
|
||||
- 测试获取阶段数据第0条的type属性 @group
|
||||
- 测试获取任务数据
|
||||
- 第1条的id属性 @1-4
|
||||
- 第1条的id属性 @1-1
|
||||
- 第1条的type属性 @task
|
||||
- 测试获取阶段数据(JSON类型返回值)第2条的type属性 @task
|
||||
- 测试获取任务数据(JSON类型返回值)
|
||||
- 第3条的id属性 @1-8
|
||||
- 第3条的id属性 @1-5
|
||||
- 第3条的type属性 @task
|
||||
- 测试自定义参数为空的情况获取任务数据 @1
|
||||
|
||||
@@ -30,8 +30,8 @@ $programplan = new programplanTest();
|
||||
|
||||
$selectCustom = 'date,task';
|
||||
$selectNoneCustom = '';
|
||||
r($programplan->getDataForGanttGroupByAssignedToTest(1, 1, 0, $selectCustom, false)) && p('0:type') && e('task'); // 测试获取阶段数据
|
||||
r($programplan->getDataForGanttGroupByAssignedToTest(1, 1, 0, $selectCustom, false)) && p('1:id,type') && e('1-4,task'); // 测试获取任务数据
|
||||
r($programplan->getDataForGanttGroupByAssignedToTest(1, 1, 0, $selectCustom, false)) && p('0:type') && e('group'); // 测试获取阶段数据
|
||||
r($programplan->getDataForGanttGroupByAssignedToTest(1, 1, 0, $selectCustom, false)) && p('1:id,type') && e('1-1,task'); // 测试获取任务数据
|
||||
r($programplan->getDataForGanttGroupByAssignedToTest(1, 1, 0, $selectCustom, true)) && p('2:type') && e('task'); // 测试获取阶段数据(JSON类型返回值)
|
||||
r($programplan->getDataForGanttGroupByAssignedToTest(1, 1, 0, $selectCustom, true)) && p('3:id,type') && e('1-8,task'); // 测试获取任务数据(JSON类型返回值)
|
||||
r(count($programplan->getDataForGanttGroupByAssignedToTest(1, 1, 0, $selectNoneCustom, false))) && p() && e('1'); // 测试自定义参数为空的情况获取任务数据
|
||||
r($programplan->getDataForGanttGroupByAssignedToTest(1, 1, 0, $selectCustom, true)) && p('3:id,type') && e('1-5,task'); // 测试获取任务数据(JSON类型返回值)
|
||||
r(count($programplan->getDataForGanttGroupByAssignedToTest(1, 1, 0, $selectNoneCustom, false))) && p() && e('1'); // 测试自定义参数为空的情况获取任务数据
|
||||
Regular → Executable
+23
-1
@@ -4,6 +4,7 @@
|
||||
/**
|
||||
|
||||
title=测试 programplanModel->getGanttTasks();
|
||||
timeout=0
|
||||
cid=0
|
||||
|
||||
- 测试查询项目 11 执行 101 browseType 空 queryID 0 的甘特图任务 @1
|
||||
@@ -15,6 +16,27 @@ cid=0
|
||||
- 测试查询项目 12 执行 102 browseType bysearch queryID 0 的甘特图任务 @0
|
||||
- 测试查询项目 12 执行 102 browseType bysearch queryID 1 的甘特图任务 @0
|
||||
- 测试查询不存在的项目 101 执行 101 browseType 空 queryID 0 的甘特图任务 @0
|
||||
- 测试查询项目 11 执行 101 browseType 空 queryID 0 的甘特图任务
|
||||
- 第1条的storyVersion属性 @1
|
||||
- 第1条的storyStatus属性 @active
|
||||
- 第1条的needConfirm属性 @~~
|
||||
- 测试查询项目 11 执行 101 browseType 空 queryID 1 的甘特图任务
|
||||
- 第1条的storyVersion属性 @1
|
||||
- 第1条的storyStatus属性 @active
|
||||
- 第1条的needConfirm属性 @~~
|
||||
- 测试查询项目 11 执行 101 browseType bysearch queryID 0 的甘特图任务 @0
|
||||
- 测试查询项目 11 执行 101 browseType bysearch queryID 1 的甘特图任务 @0
|
||||
- 测试查询项目 12 执行 102 browseType 空 queryID 0 的甘特图任务
|
||||
- 第2条的storyVersion属性 @1
|
||||
- 第2条的storyStatus属性 @active
|
||||
- 第2条的needConfirm属性 @~~
|
||||
- 测试查询项目 12 执行 102 browseType 空 queryID 1 的甘特图任务
|
||||
- 第2条的storyVersion属性 @1
|
||||
- 第2条的storyStatus属性 @active
|
||||
- 第2条的needConfirm属性 @~~
|
||||
- 测试查询项目 12 执行 102 browseType bysearch queryID 0 的甘特图任务 @0
|
||||
- 测试查询项目 12 执行 102 browseType bysearch queryID 1 的甘特图任务 @0
|
||||
- 测试查询不存在的项目 101 执行 101 browseType 空 queryID 0 的甘特图任务 @0
|
||||
|
||||
*/
|
||||
include dirname(__FILE__, 5) . '/test/lib/init.php';
|
||||
@@ -58,4 +80,4 @@ r($programplan->getGanttTasksTest($projectID[1], $planIdList[1], $browseType[0],
|
||||
r($programplan->getGanttTasksTest($projectID[1], $planIdList[1], $browseType[0], $queryID[1], false)) && p('2:storyVersion,storyStatus,needConfirm') && e('1,active,~~'); // 测试查询项目 12 执行 102 browseType 空 queryID 1 的甘特图任务
|
||||
r($programplan->getGanttTasksTest($projectID[1], $planIdList[1], $browseType[1], $queryID[0], false)) && p() && e('0'); // 测试查询项目 12 执行 102 browseType bysearch queryID 0 的甘特图任务
|
||||
r($programplan->getGanttTasksTest($projectID[1], $planIdList[1], $browseType[1], $queryID[1], false)) && p() && e('0'); // 测试查询项目 12 执行 102 browseType bysearch queryID 1 的甘特图任务
|
||||
r($programplan->getGanttTasksTest($projectID[2], $planIdList[0], $browseType[0], $queryID[0], false)) && p() && e('0'); // 测试查询不存在的项目 101 执行 101 browseType 空 queryID 0 的甘特图任务
|
||||
r($programplan->getGanttTasksTest($projectID[2], $planIdList[0], $browseType[0], $queryID[0], false)) && p() && e('0'); // 测试查询不存在的项目 101 执行 101 browseType 空 queryID 0 的甘特图任务
|
||||
Regular → Executable
+5
-4
@@ -4,6 +4,7 @@
|
||||
/**
|
||||
|
||||
title=测试 loadModel->buildGroupDataForGantt()
|
||||
timeout=0
|
||||
cid=0
|
||||
|
||||
- 检查构建分组Gantt数据。
|
||||
@@ -17,12 +18,12 @@ cid=0
|
||||
- 检查空组构建情况。
|
||||
- 属性id @3
|
||||
- 属性type @group
|
||||
- 属性text @''
|
||||
- 属性text @未指派
|
||||
- 检查自定义组ID。
|
||||
- 属性id @99
|
||||
- 属性type @group
|
||||
- 属性text @产品
|
||||
- 检查无用户列表时。
|
||||
- 检查无用户列表。
|
||||
- 属性id @5
|
||||
- 属性type @group
|
||||
- 属性text @设计
|
||||
@@ -50,7 +51,7 @@ $group = '测试';
|
||||
r((array)$tester->programplan->buildGroupDataForGantt($groupID, $group, $users)) && p('id,type,text') && e("2,group,测试"); //检查另一个分组。
|
||||
|
||||
$groupID = 3;
|
||||
$group = '';
|
||||
$group = '/';
|
||||
r((array)$tester->programplan->buildGroupDataForGantt($groupID, $group, $users)) && p('id,type,text') && e("3,group,未指派"); //检查空组构建情况。
|
||||
|
||||
$groupID = 99;
|
||||
@@ -59,4 +60,4 @@ r((array)$tester->programplan->buildGroupDataForGantt($groupID, $group, $users))
|
||||
|
||||
$groupID = 5;
|
||||
$group = '设计';
|
||||
r((array)$tester->programplan->buildGroupDataForGantt($groupID, $group, $emptyUsers)) && p('id,type,text') && e("5,group,设计"); //检查无用户列表。
|
||||
r((array)$tester->programplan->buildGroupDataForGantt($groupID, $group, $emptyUsers)) && p('id,type,text') && e("5,group,设计"); //检查无用户列表。
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
|
||||
title=测试 loadModel->checkLegallyDate()
|
||||
timeout=0
|
||||
cid=0
|
||||
|
||||
- 不能超过项目的起止日期属性end[0] @阶段的结束时间不能大于所属项目的结束时间2025-02-01
|
||||
- 没有错误 @0
|
||||
- 不能超过父阶段起止日期属性end[0] @子阶段计划完成不能超过父阶段的计划完成时间 2025-01-15
|
||||
- 不能超过父阶段起止日期属性begin[0] @子阶段计划开始不能小于父阶段的计划开始时间 2025-01-02
|
||||
- 模板类型的项目没有错误 @0
|
||||
|
||||
*/
|
||||
|
||||
include dirname(__FILE__, 5). '/test/lib/init.php';
|
||||
su('admin');
|
||||
|
||||
$project = new stdclass();
|
||||
$project->begin = '2025-01-01';
|
||||
$project->end = '2025-02-01';
|
||||
|
||||
$plan = new stdclass();
|
||||
$plan->begin = '2025-01-01';
|
||||
$plan->end = '2025-02-02';
|
||||
|
||||
global $tester;
|
||||
$zen = initReference('programplan');
|
||||
$func = $zen->getMethod('checkLegallyDate');
|
||||
$func->invokeArgs($zen->newInstance(), [$plan, $project, null, 0]);
|
||||
|
||||
r(dao::getError()) && p('end[0]') && e('阶段的结束时间不能大于所属项目的结束时间2025-02-01'); // 不能超过项目的起止日期
|
||||
|
||||
dao::$errors = array();
|
||||
|
||||
$project = new stdclass();
|
||||
$project->begin = '2025-01-01';
|
||||
$project->end = '2025-02-01';
|
||||
|
||||
$plan = new stdclass();
|
||||
$plan->begin = '2025-01-01';
|
||||
$plan->end = '2025-02-01';
|
||||
|
||||
$func->invokeArgs($zen->newInstance(), [$plan, $project, null, 0]);
|
||||
|
||||
r(dao::getError()) && p('') && e('0'); // 没有错误
|
||||
|
||||
dao::$errors = array();
|
||||
|
||||
$parent = new stdclass();
|
||||
$parent->begin = '2025-01-01';
|
||||
$parent->end = '2025-01-15';
|
||||
|
||||
$func->invokeArgs($zen->newInstance(), [$plan, $project, $parent, 0]);
|
||||
|
||||
r(dao::getError()) && p('end[0]') && e('子阶段计划完成不能超过父阶段的计划完成时间 2025-01-15'); // 不能超过父阶段起止日期
|
||||
|
||||
dao::$errors = array();
|
||||
|
||||
$parent = new stdclass();
|
||||
$parent->begin = '2025-01-02';
|
||||
$parent->end = '2025-02-15';
|
||||
|
||||
$func->invokeArgs($zen->newInstance(), [$plan, $project, $parent, 0]);
|
||||
|
||||
r(dao::getError()) && p('begin[0]') && e('子阶段计划开始不能小于父阶段的计划开始时间 2025-01-02'); // 不能超过父阶段起止日期
|
||||
|
||||
dao::$errors = array();
|
||||
|
||||
$project->isTpl = '1';
|
||||
|
||||
$func->invokeArgs($zen->newInstance(), [$plan, $project, $parent, 0]);
|
||||
|
||||
r(dao::getError()) && p('') && e('0'); // 模板类型的项目没有错误
|
||||
@@ -22,6 +22,7 @@ class programplanZen extends programplan
|
||||
private function checkLegallyDate(object $plan, object $project, object|null $parent, int $rowID): void
|
||||
{
|
||||
if(isset($plan->enabled) && $plan->enabled == 'off') return;
|
||||
if(!empty($project->isTpl)) return; // 模板不校验日期
|
||||
|
||||
$beginIsZeroDate = helper::isZeroDate($plan->begin);
|
||||
$endIsZeroDate = helper::isZeroDate($plan->end);
|
||||
@@ -441,12 +442,9 @@ class programplanZen extends programplan
|
||||
if($hasSearch)
|
||||
{
|
||||
/* Build the search form. */
|
||||
$this->config->execution->search['module'] = 'projectTask';
|
||||
|
||||
$actionURL = $this->createLink('programplan', 'browse', "projectID=$projectID&productID=$productID&type=$type&orderBy=$orderBy&baselineID=$baselineID&browseType=bysearch&queryID=myQueryID");
|
||||
unset($this->config->execution->search['fields']['project']);
|
||||
$actionURL = $this->createLink('programplan', 'browse', "projectID=$projectID&productID=$productID&type=$type&orderBy=$orderBy&baselineID=$baselineID&browseType=bysearch&queryID=myQueryID");
|
||||
$executions = $this->programplan->getPairs($projectID, $productID, 'all');
|
||||
$this->loadModel('execution')->buildTaskSearchForm($projectID, $executions, $queryID, $actionURL);
|
||||
$this->loadModel('execution')->buildTaskSearchForm($projectID, $executions, $queryID, $actionURL, 'projectTask');
|
||||
}
|
||||
|
||||
$this->view->title = $this->lang->programplan->browse;
|
||||
|
||||
Reference in New Issue
Block a user