Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms into zentaopms_289

This commit is contained in:
guofeilong
2023-02-24 13:47:19 +08:00
39 changed files with 615 additions and 169 deletions
+34
View File
@@ -28,3 +28,37 @@ UPDATE `zt_activity` SET `order` = `id` * 5 WHERE `order` = '0';
ALTER table `zt_cmcl` ADD `projectType` varchar(255) NOT NULL DEFAULT '' AFTER `type`;
UPDATE `zt_cmcl` SET `projectType` = 'waterfall' WHERE `projectType` = '';
REPLACE INTO `zt_process` (`model`, `name`, `type`, `abbr`, `desc`, `assignedTo`, `status`, `order`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `assignedBy`, `assignedDate`, `deleted`) VALUES
('waterfallplus', '立项管理', 'project', 'PIM', '', '', '', 55, 'admin', '2020-01-09 10:29:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '项目规划', 'project', 'PP', '', '', '', 60, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '项目监控', 'project', 'PMC', '', '', '', 65, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '风险管理', 'project', 'RSKM', '', '', '', 70, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '结项管理', 'project', 'PCM', '', '', '', 75, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '量化项目管理', 'project', 'QPM', '', '', '', 80, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '需求开发', 'engineering', 'RDM', '', '', '', 85, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '设计开发', 'engineering', '', '', '', '', 90, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '实现与测试', 'engineering', 'EMBEDDED', '', '', '', 95, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '系统测试', 'engineering', 'ST', '', '', '', 100, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '客户验收', 'engineering', 'CA', '', '', '', 105, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '质量保证', 'support', 'QA', '', '', '', 110, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '配置管理', 'support', 'CM', '', '', '', 115, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '度量分析', 'support', 'MA', '', '', '', 120, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '原因分析与解决', 'support', 'CAR', '', '', '', 125, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '决策分析', 'support', 'DAR', '', '', '', 130, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '立项管理', 'project', 'PIM', '', '', '', 55, 'admin', '2020-01-09 10:29:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '项目规划', 'project', 'PP', '', '', '', 60, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '项目监控', 'project', 'PMC', '', '', '', 65, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '风险管理', 'project', 'RSKM', '', '', '', 70, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '结项管理', 'project', 'PCM', '', '', '', 75, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '量化项目管理', 'project', 'QPM', '', '', '', 80, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '需求开发', 'engineering', 'RDM', '', '', '', 85, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '设计开发', 'engineering', '', '', '', '', 90, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '实现与测试', 'engineering', 'EMBEDDED', '', '', '', 95, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '系统测试', 'engineering', 'ST', '', '', '', 100, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '客户验收', 'engineering', 'CA', '', '', '', 105, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '质量保证', 'support', 'QA', '', '', '', 110, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '配置管理', 'support', 'CM', '', '', '', 115, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '度量分析', 'support', 'MA', '', '', '', 120, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '原因分析与解决', 'support', 'CAR', '', '', '', 125, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '决策分析', 'support', 'DAR', '', '', '', 130, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0');
+33 -1
View File
@@ -13305,7 +13305,39 @@ REPLACE INTO `zt_process` (`id`, `model`, `name`, `type`, `abbr`, `desc`, `assig
(29, 'scrum', '项目监控', 'project', 'PMC', '', '', '', 65, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(28, 'scrum', '项目规划', 'project', 'PP', '', '', '', 60, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(27, 'scrum', '立项管理', 'project', 'PIM', '', '', '', 55, 'admin', '2020-01-09 10:29:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(42, 'scrum', '决策分析', 'support', 'DAR', '', '', '', 130, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0');
(42, 'scrum', '决策分析', 'support', 'DAR', '', '', '', 130, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(43, 'waterfallplus', '立项管理', 'project', 'PIM', '', '', '', 55, 'admin', '2020-01-09 10:29:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(44, 'waterfallplus', '项目规划', 'project', 'PP', '', '', '', 60, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(45, 'waterfallplus', '项目监控', 'project', 'PMC', '', '', '', 65, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(46, 'waterfallplus', '风险管理', 'project', 'RSKM', '', '', '', 70, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(47, 'waterfallplus', '结项管理', 'project', 'PCM', '', '', '', 75, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(48, 'waterfallplus', '量化项目管理', 'project', 'QPM', '', '', '', 80, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(49, 'waterfallplus', '需求开发', 'engineering', 'RDM', '', '', '', 85, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(50, 'waterfallplus', '设计开发', 'engineering', '', '', '', '', 90, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(51, 'waterfallplus', '实现与测试', 'engineering', 'EMBEDDED', '', '', '', 95, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(52, 'waterfallplus', '系统测试', 'engineering', 'ST', '', '', '', 100, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(53, 'waterfallplus', '客户验收', 'engineering', 'CA', '', '', '', 105, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(54, 'waterfallplus', '质量保证', 'support', 'QA', '', '', '', 110, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(55, 'waterfallplus', '配置管理', 'support', 'CM', '', '', '', 115, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(56, 'waterfallplus', '度量分析', 'support', 'MA', '', '', '', 120, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(57, 'waterfallplus', '原因分析与解决', 'support', 'CAR', '', '', '', 125, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(58, 'waterfallplus', '决策分析', 'support', 'DAR', '', '', '', 130, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(59, 'agileplus', '立项管理', 'project', 'PIM', '', '', '', 55, 'admin', '2020-01-09 10:29:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(60, 'agileplus', '项目规划', 'project', 'PP', '', '', '', 60, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(61, 'agileplus', '项目监控', 'project', 'PMC', '', '', '', 65, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(62, 'agileplus', '风险管理', 'project', 'RSKM', '', '', '', 70, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(63, 'agileplus', '结项管理', 'project', 'PCM', '', '', '', 75, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(64, 'agileplus', '量化项目管理', 'project', 'QPM', '', '', '', 80, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(65, 'agileplus', '需求开发', 'engineering', 'RDM', '', '', '', 85, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(66, 'agileplus', '设计开发', 'engineering', '', '', '', '', 90, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(67, 'agileplus', '实现与测试', 'engineering', 'EMBEDDED', '', '', '', 95, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(68, 'agileplus', '系统测试', 'engineering', 'ST', '', '', '', 100, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(69, 'agileplus', '客户验收', 'engineering', 'CA', '', '', '', 105, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(70, 'agileplus', '质量保证', 'support', 'QA', '', '', '', 110, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(71, 'agileplus', '配置管理', 'support', 'CM', '', '', '', 115, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(72, 'agileplus', '度量分析', 'support', 'MA', '', '', '', 120, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(73, 'agileplus', '原因分析与解决', 'support', 'CAR', '', '', '', 125, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(74, 'agileplus', '决策分析', 'support', 'DAR', '', '', '', 130, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0');
REPLACE INTO `zt_activity` (`id`, `process`, `name`, `optional`, `tailorNorm`, `content`, `assignedTo`, `status`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `assignedBy`, `assignedDate`, `order`, `deleted`) VALUES
+5
View File
@@ -3704,6 +3704,11 @@ class bugModel extends model
if($type == 'view' && $this->app->tab != 'product')
{
$tab = $this->app->tab == 'qa' ? 'product' : $this->app->tab;
if($tab == 'product')
{
$product = $this->loadModel('product')->getByID($bug->product);
if(!empty($product->shadow)) $tab = 'project';
}
$menu .= $this->buildMenu('bug', 'toStory', $toStoryParams, $bug, $type, $this->lang->icons['story'], '', '', '', "data-app='$tab' id='tostory'", $this->lang->bug->toStory);
if(common::hasPriv('task', 'create') and !isonlybody()) $menu .= html::a('#toTask', "<i class='icon icon-check'></i><span class='text'>{$this->lang->bug->toTask}</span>", '', "data-app='qa' data-toggle='modal' class='btn btn-link'");
$menu .= $this->buildMenu('bug', 'createCase', $convertParams, $bug, $type, 'sitemap');
+5 -1
View File
@@ -1796,8 +1796,12 @@ EOD;
$executionPairs = array();
$userCondition = !$app->user->admin ? " AND `id` " . helper::dbIN($app->user->view->sprints) : '';
$orderBy = $object->type == 'stage' ? 'ORDER BY `id` ASC' : 'ORDER BY `id` DESC';
$executionList = $app->dbh->query("SELECT id,name,parent,project FROM " . TABLE_EXECUTION . " WHERE `project` = '{$object->project}' AND `deleted` = '0' $userCondition $orderBy")->fetchAll();
$executionList = $app->control->loadModel('execution')->resetExecutionSorts($executionList);
$executions = array();
foreach($executionList as $execution) $executions[$execution->id] = $execution;
$executionList = $app->control->loadModel('execution')->resetExecutionSorts($executions);
foreach($executionList as $execution)
{
if(isset($executionPairs[$execution->parent])) unset($executionPairs[$execution->parent]);
+20 -8
View File
@@ -2615,19 +2615,26 @@ class execution extends control
$execution = $this->commonAction($executionID);
if($execution->type != 'kanban') return print(js::locate(inlink('view', "executionID=$executionID")));
if($execution->lifetime == 'ops' or in_array($execution->attribute, array('request', 'review')))
{
$browseType = 'task';
unset($this->lang->kanban->group->task['story']);
}
/* Set Session. */
$this->session->set('execGroupBy', $groupBy);
$this->session->set('storyList', $this->app->getURI(true), 'execution');
$this->session->set('rdSearchValue', '');
$this->session->set('execLaneType', $browseType);
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $browseType, $orderBy, 0, $groupBy);
$features = $this->execution->getExecutionFeatures($execution);
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $browseType, $orderBy, 0, $groupBy);
/* Remove lanes if no feature. */
foreach($kanbanData as $regionID => $region)
{
foreach($region->groups as $groupID => $group)
{
if(!$features['story'] and $group->lanes[0]->type == 'story') unset($kanbanData[$regionID]->groups[$groupID]);
if(!$features['qa'] and $group->lanes[0]->type == 'bug') unset($kanbanData[$regionID]->groups[$groupID]);
}
$kanbanData[$regionID]->groups = array_values($kanbanData[$regionID]->groups);
}
$executionActions = array();
foreach($this->config->execution->statusActions as $action)
{
@@ -2688,6 +2695,7 @@ class execution extends control
$this->view->projectID = $projectID;
$this->view->project = $this->loadModel('project')->getByID($projectID);
$this->view->allPlans = $allPlans;
$this->view->features = $features;
$this->view->kanbanData = $kanbanData;
$this->view->executionActions = $executionActions;
$this->view->kanban = $this->lang->execution->kanban;
@@ -2744,7 +2752,7 @@ class execution extends control
/* Show lanes of the attribute: no story&bug in request, no bug in design. */
if(!isset($this->lang->execution->menu->story)) unset($kanbanGroup['story']);
if(!isset($this->lang->execution->menu->qa)) unset($kanbanGroup['bug']);
if(!isset($this->lang->execution->menu->qa)) unset($kanbanGroup['bug']);
/* Determines whether an object is editable. */
$canBeChanged = common::canModify('execution', $execution);
@@ -2783,6 +2791,7 @@ class execution extends control
$this->view->productNum = count($products);
$this->view->allPlans = $allPlans;
$this->view->browseType = $browseType;
$this->view->features = $this->execution->getExecutionFeatures($execution);
$this->view->kanbanGroup = $kanbanGroup;
$this->view->execution = $execution;
$this->view->groupBy = $groupBy;
@@ -3179,6 +3188,9 @@ class execution extends control
$this->loadModel('product');
$execution = $this->execution->getById($executionID);
$project = $this->loadModel('project')->getByID($execution->project);
if(!$project->hasProduct) return print(js::error($this->lang->project->cannotManageProducts) . js::locate('back'));
if($project->model == 'waterfall' or $project->model == 'waterfallplus') return print(js::error(sprintf($this->lang->execution->cannotManageProducts, zget($this->lang->project->modelList, $project->model))) . js::locate('back'));
if(!empty($_POST))
{
+1 -1
View File
@@ -1,7 +1,7 @@
.c-id {width: 50px;}
.c-team-name {width: 120px;}
.c-project, .c-user, .c-code, .c-desc, .c-days {width: 150px;}
.c-method {width: 45px;}
.c-method {width: 70px;}
.c-type > .icon-help {vertical-align: text-top;}
.c-type > .popover .popover-content {font-weight: 400;}
#executionForm tbody td {vertical-align: top;}
+1 -1
View File
@@ -1,4 +1,4 @@
.c-user {width: 150px !important;}
.c-date {width: 125px;}
.c-method {width: 60px;}
.c-method {width: 145px;}
.c-type {width: 130px;}
+2
View File
@@ -9,3 +9,5 @@
.form-date {min-width: 90px;}
.productsBox div[id^='branch'].chosen-disabled {pointer-events: none;}
#dataform th.c-name, #dataform th.c-projectName, #dataform th.c-method {width: 120px;}
+1
View File
@@ -0,0 +1 @@
#dataform th.c-method {width: 150px;}
+3 -2
View File
@@ -139,7 +139,7 @@ $lang->execution->kanbanNoLinkProduct = "Kanban not linked {$lang->productCommon
$lang->execution->myTask = "My Task";
$lang->execution->list = "{$lang->executionCommon} List";
$lang->execution->allProject = 'All';
$lang->execution->method = 'Method';
$lang->execution->method = 'Management Method';
$lang->execution->sameAsParent = "Same as parent";
/* Fields of zt_team. */
@@ -398,7 +398,7 @@ $lang->execution->errorCommonBegin = 'The start date of ' . $lang->e
$lang->execution->errorCommonEnd = 'The deadline of ' . $lang->executionCommon . ' should be ≤ the deadline of project : %s.';
$lang->execution->errorLetterParent = 'The begin cannot be less than the begin of the parent stage to which it belongs: %s.';
$lang->execution->errorGreaterParent = 'The end cannot be greater than the end of the parent stage to which it belongs:%s.';
$lang->execution->errorNameRepeat = 'Child stages of the same parent stage cannot have the same name.';
$lang->execution->errorNameRepeat = "Child %s of the same parent stage cannot have the same name.";
$lang->execution->errorAttrMatch = "Parent stage's attribute is [%s], the attribute needs to be consistent with the parent stage.";
$lang->execution->errorLetterPlan = "『%s』cannot be less than the plan start time『%s』。";
$lang->execution->accessDenied = "Zugriff zu {$lang->executionCommon} verweigert!";
@@ -430,6 +430,7 @@ $lang->execution->hasStartedTaskOrSubStage = "Tasks or subphases under %s %s
$lang->execution->hasSuspendedOrClosedChildren = "The sub-stages under stage %s are not all suspended or closed, cannot be modified, and have been filtered.";
$lang->execution->hasNotClosedChildren = "The sub-stages under stage %s are not all closed, cannot be modified, and have been filtered.";
$lang->execution->hasStartedTask = "The task under %s %s has already started, cannot be modified, and has been filtered.";
$lang->execution->cannotManageProducts = 'The ' . strtolower($lang->project->common). ' model of this ' . strtolower($lang->execution->common) . " is %s and this " . strtolower($lang->execution->common) . ' cannot be associated with products.';
/* Statistics. */
$lang->execution->charts = new stdclass();
+3 -2
View File
@@ -139,7 +139,7 @@ $lang->execution->kanbanNoLinkProduct = "Kanban not linked {$lang->productCommon
$lang->execution->myTask = "My Task";
$lang->execution->list = 'List';
$lang->execution->allProject = 'All';
$lang->execution->method = 'Method';
$lang->execution->method = 'Management Method';
$lang->execution->sameAsParent = "Same as parent";
/* Fields of zt_team. */
@@ -398,7 +398,7 @@ $lang->execution->errorCommonBegin = 'The start date of ' . $lang->e
$lang->execution->errorCommonEnd = 'The deadline of ' . $lang->executionCommon . ' should be ≤ the deadline of project : %s.';
$lang->execution->errorLetterParent = 'The begin cannot be less than the begin of the parent stage to which it belongs: %s.';
$lang->execution->errorGreaterParent = 'The end cannot be greater than the end of the parent stage to which it belongs:%s.';
$lang->execution->errorNameRepeat = 'Child stages of the same parent stage cannot have the same name.';
$lang->execution->errorNameRepeat = "Child %s of the same parent stage cannot have the same name.";
$lang->execution->errorAttrMatch = "Parent stage's attribute is [%s], the attribute needs to be consistent with the parent stage.";
$lang->execution->errorLetterPlan = "『%s』cannot be less than the plan start time『%s』。";
$lang->execution->accessDenied = "Your access to {$lang->executionCommon} is denied!";
@@ -430,6 +430,7 @@ $lang->execution->hasStartedTaskOrSubStage = "Tasks or subphases under %s %s
$lang->execution->hasSuspendedOrClosedChildren = "The sub-stages under stage %s are not all suspended or closed, cannot be modified, and have been filtered.";
$lang->execution->hasNotClosedChildren = "The sub-stages under stage %s are not all closed, cannot be modified, and have been filtered.";
$lang->execution->hasStartedTask = "The task under %s %s has already started, cannot be modified, and has been filtered.";
$lang->execution->cannotManageProducts = 'The ' . strtolower($lang->project->common). ' model of this ' . strtolower($lang->execution->common) . " is %s and this " . strtolower($lang->execution->common) . ' cannot be associated with products.';
/* Statistics. */
$lang->execution->charts = new stdclass();
+3 -2
View File
@@ -139,7 +139,7 @@ $lang->execution->kanbanNoLinkProduct = "Kanban not linked {$lang->productCommon
$lang->execution->myTask = "My Task";
$lang->execution->list = "{$lang->executionCommon} List";
$lang->execution->allProject = 'Tous';
$lang->execution->method = 'Method';
$lang->execution->method = 'Management Method';
$lang->execution->sameAsParent = "Same as parent";
/* Fields of zt_team. */
@@ -398,7 +398,7 @@ $lang->execution->errorCommonBegin = 'The start date of ' . $lang->e
$lang->execution->errorCommonEnd = 'The deadline of ' . $lang->executionCommon . ' should be ≤ the deadline of project : %s.';
$lang->execution->errorLetterParent = 'The begin cannot be less than the begin of the parent stage to which it belongs: %s.';
$lang->execution->errorGreaterParent = 'The end cannot be greater than the end of the parent stage to which it belongs:%s.';
$lang->execution->errorNameRepeat = 'Child stages of the same parent stage cannot have the same name.';
$lang->execution->errorNameRepeat = "Child %s of the same parent stage cannot have the same name.";
$lang->execution->errorAttrMatch = "Parent stage's attribute is [%s], the attribute needs to be consistent with the parent stage.";
$lang->execution->errorLetterPlan = "『%s』cannot be less than the plan start time『%s』。";
$lang->execution->accessDenied = "Votre accès au {$lang->executionCommon} est refusé ! Désolé.";
@@ -430,6 +430,7 @@ $lang->execution->hasStartedTaskOrSubStage = "Tasks or subphases under %s %s
$lang->execution->hasSuspendedOrClosedChildren = "The sub-stages under stage %s are not all suspended or closed, cannot be modified, and have been filtered.";
$lang->execution->hasNotClosedChildren = "The sub-stages under stage %s are not all closed, cannot be modified, and have been filtered.";
$lang->execution->hasStartedTask = "The task under %s %s has already started, cannot be modified, and has been filtered.";
$lang->execution->cannotManageProducts = 'The ' . strtolower($lang->project->common). ' model of this ' . strtolower($lang->execution->common) . " is %s and this " . strtolower($lang->execution->common) . ' cannot be associated with products.';
/* Statistics. */
$lang->execution->charts = new stdclass();
+3 -2
View File
@@ -139,7 +139,7 @@ $lang->execution->kanbanNoLinkProduct = "看板没有关联{$lang->productCommon
$lang->execution->myTask = "我的任务";
$lang->execution->list = '列表';
$lang->execution->allProject = '全部项目';
$lang->execution->method = '方法';
$lang->execution->method = '管理方法';
$lang->execution->sameAsParent = "同父阶段";
/* Fields of zt_team. */
@@ -398,7 +398,7 @@ $lang->execution->errorCommonBegin = $lang->executionCommon . '开
$lang->execution->errorCommonEnd = $lang->executionCommon . '截止日期应小于等于项目的截止日期:%s。';
$lang->execution->errorLetterParent = '计划开始时间不能小于所属父阶段的计划开始时间:%s。';
$lang->execution->errorGreaterParent = '计划完成时间不能大于所属父阶段的计划完成时间:%s。';
$lang->execution->errorNameRepeat = '相同父阶段的子阶段名称不能相同';
$lang->execution->errorNameRepeat = "相同父阶段的子%s名称不能相同";
$lang->execution->errorAttrMatch = "父阶段类型为[%s],阶段类型需与父阶段一致";
$lang->execution->errorLetterPlan = "『%s』应当不小于计划开始时间『%s』。";
$lang->execution->accessDenied = "您无权访问该{$lang->executionCommon}!";
@@ -430,6 +430,7 @@ $lang->execution->hasStartedTaskOrSubStage = "%s%s下的任务或子阶段
$lang->execution->hasSuspendedOrClosedChildren = "阶段%s下的子阶段未全部挂起或关闭,无法修改,已过滤。";
$lang->execution->hasNotClosedChildren = "阶段%s下的子阶段未全部关闭,无法修改,已过滤。";
$lang->execution->hasStartedTask = "%s%s下的任务已经开始,无法修改,已过滤。";
$lang->execution->cannotManageProducts = "当前{$lang->execution->common}的{$lang->project->common}为%s{$lang->project->common},不能关联产品。";
/* 统计。*/
$lang->execution->charts = new stdclass();
+64 -31
View File
@@ -50,6 +50,44 @@ class executionModel extends model
return print(js::locate(helper::createLink('execution', 'all')));
}
/**
* Get features of execution.
*
* @param object $execution
* @access public
* @return array
*/
public function getExecutionFeatures($execution)
{
$features = array('story' => true, 'task' => true, 'qa' => true, 'devops' => true, 'burn' => true, 'build' => true, 'other' => true);
/* Unset story, bug, build and testtask if type is ops. */
if($execution->lifetime == 'ops')
{
$features['story'] = false;
$features['qa'] = false;
$features['build'] = false;
$features['burn'] = false;
}
elseif(!empty($execution->attribute))
{
$features['other'] = false;
if(in_array($execution->attribute, array('request', 'design', 'review')))
{
$features['qa'] = false;
$features['devops'] = false;
$features['build'] = false;
if(in_array($execution->attribute, array('request', 'review')))
{
$features['story'] = false;
}
}
}
return $features;
}
/**
* Set menu.
*
@@ -105,30 +143,16 @@ class executionModel extends model
if(isset($execution->acl) and $execution->acl != 'private') unset($this->lang->execution->menu->settings['subMenu']->whitelist);
/* Unset story, bug, build and testtask if type is ops. */
if($execution and $execution->lifetime == 'ops')
{
unset($this->lang->execution->menu->story);
unset($this->lang->execution->menu->qa);
unset($this->lang->execution->menu->build);
unset($this->lang->execution->menu->burn);
}
$stageFilter = array('request', 'design', 'review');
if(isset($execution->attribute) and in_array($execution->attribute, $stageFilter))
{
if(in_array($execution->attribute, array('request', 'review')))
{
unset($this->lang->execution->menu->story);
unset($this->lang->execution->menu->view['subMenu']->groupTask);
unset($this->lang->execution->menu->view['subMenu']->tree);
unset($this->lang->execution->menu->other);
}
unset($this->lang->execution->menu->devops);
unset($this->lang->execution->menu->qa);
unset($this->lang->execution->menu->build);
}
/* Redjust menus. */
$features = $this->getExecutionFeatures($execution);
if(!$features['story']) unset($this->lang->execution->menu->story);
if(!$features['story']) unset($this->lang->execution->menu->view['subMenu']->groupTask);
if(!$features['story']) unset($this->lang->execution->menu->view['subMenu']->tree);
if(!$features['qa']) unset($this->lang->execution->menu->qa);
if(!$features['devops']) unset($this->lang->execution->menu->devops);
if(!$features['build']) unset($this->lang->execution->menu->build);
if(!$features['burn']) unset($this->lang->execution->menu->burn);
if(!$features['other']) unset($this->lang->execution->menu->other);
if($executions and (!isset($executions[$executionID]) or !$this->checkPriv($executionID))) $this->accessDenied();
@@ -383,6 +407,7 @@ class executionModel extends model
->setDefault('openedVersion', $this->config->version)
->setDefault('lastEditedBy', $this->app->user->account)
->setDefault('lastEditedDate', helper::now())
->setDefault('days', '0')
->setDefault('team', $this->post->name)
->setDefault('parent', $this->post->project)
->setIF($this->post->parent, 'parent', $this->post->parent)
@@ -448,7 +473,7 @@ class executionModel extends model
->checkIF($sprint->end != '', 'end', 'ge', $sprint->begin)
->checkFlow()
->exec();
/* Add the creater to the team. */
if(!dao::isError())
{
@@ -573,6 +598,7 @@ class executionModel extends model
->setIF($this->post->status == 'closed' and $oldExecution->status != 'closed', 'closedDate', helper::now())
->setIF($this->post->status == 'suspended' and $oldExecution->status != 'suspended', 'suspendedDate', helper::today())
->setIF($oldExecution->type == 'stage', 'project', $oldExecution->project)
->setDefault('days', '0')
->setDefault('team', $this->post->name)
->join('whitelist', ',')
->stripTags($this->config->execution->editor->edit['id'], $this->config->allowedTags)
@@ -719,6 +745,7 @@ class executionModel extends model
{
$this->loadModel('user');
$this->loadModel('project');
$this->app->loadLang('programplan');
$executions = array();
$allChanges = array();
@@ -770,10 +797,10 @@ class executionModel extends model
$executions[$executionID]->lastEditedBy = $this->app->user->account;
$executions[$executionID]->lastEditedDate = helper::now();
if(isset($data->codes)) $executions[$executionID]->code = $executionCode;
if(isset($data->projects)) $executions[$executionID]->project = zget($data->projects, $executionID, 0);
if(isset($data->attributes)) $executions[$executionID]->attribute = zget($data->attributes, $executionID, '');
if(isset($data->lifetimes)) $executions[$executionID]->lifetime = $data->lifetimes[$executionID];
if(isset($data->codes)) $executions[$executionID]->code = $executionCode;
if(isset($data->projects)) $executions[$executionID]->project = zget($data->projects, $executionID, 0);
if(isset($data->attributes[$executionID])) $executions[$executionID]->attribute = zget($data->attributes, $executionID, '');
if(isset($data->lifetimes[$executionID])) $executions[$executionID]->lifetime = $data->lifetimes[$executionID];
$oldExecution = $oldExecutions[$executionID];
$projectID = isset($executions[$executionID]->project) ? $executions[$executionID]->project : $oldExecution->project;
@@ -801,7 +828,8 @@ class executionModel extends model
{
if($parentID == $parents[$repeatID])
{
dao::$errors["names$executionID"][] = $this->lang->execution->errorNameRepeat;
$type = $oldExecution->type == 'stage' ? 'stage' : 'agileplus';
dao::$errors["names$executionID"][] = sprintf($this->lang->execution->errorNameRepeat, strtolower(zget($this->lang->programplan->typeList, $type)));
break;
}
}
@@ -1991,10 +2019,15 @@ class executionModel extends model
if($execution->parent) $parentList[$execution->parent] = $execution->parent;
if($execution->projectName) $execution->name = $execution->projectName . ' / ' . $execution->name;
}
elseif($param === 'hasParentName')
elseif(strpos($param, 'hasParentName') !== false)
{
$parentExecutions = $this->dao->select('id,name')->from(TABLE_EXECUTION)->where('id')->in(trim($execution->path, ','))->andWhere('type')->in('stage,kanban,sprint')->orderBy('grade')->fetchPairs();
$executions[$execution->id]->title = implode('/', $parentExecutions);
if(strpos($param, 'skipParent') !== false)
{
$children = $this->getChildExecutions($execution->id);
if(count($children) > 0) $parentList[$execution->id] = $execution->id;
}
}
elseif(isset($executions[$execution->parent]))
{
+2 -1
View File
@@ -59,7 +59,8 @@
<form class='form-indicator main-form form-ajax' method='post' target='hiddenwin' id='dataform'>
<table class='table table-form'>
<tr>
<th class='w-120px'><?php echo $lang->execution->projectName;?></th>
<?php $width = (strpos($app->getClientLang(), 'zh-') === false and !empty($project->model) and $project->model == 'agileplus') ? 'w-150px' : 'w-120px';?>
<th class='<?php echo $width;?>'><?php echo $lang->execution->projectName;?></th>
<td class="col-main"><?php echo html::select("project", $allProjects, $projectID, "class='form-control chosen' required onchange='refreshPage(this.value)'");?></td>
<td colspan='2'></td>
</tr>
+3 -3
View File
@@ -33,14 +33,14 @@
<?php if(isset($project)):?>
<?php if($project->model == 'scrum'):?>
<tr>
<th class='w-120px'><?php echo $lang->execution->projectName;?></th>
<th class='c-projectName'><?php echo $lang->execution->projectName;?></th>
<td><?php echo html::select('project', $allProjects, $execution->project, "class='form-control chosen' onchange='changeProject(this.value)' required");?></td><td></td>
</tr>
<?php elseif($project->model == 'kanban'):?>
<?php echo html::hidden('project', $project->id);?>
<?php elseif($project->model == 'agileplus'):?>
<tr>
<th class='w-120px'><?php echo $lang->execution->method;?></th>
<th class='c-method'><?php echo $lang->execution->method;?></th>
<td><?php echo zget($lang->execution->typeList, $execution->type);?></td><td></td>
</tr>
<?php elseif($app->tab == 'project' and $project->model == 'waterfallplus'):?>
@@ -51,7 +51,7 @@
<?php endif;?>
<?php endif;?>
<tr>
<th class='w-120px'><?php echo $lang->execution->name;?></th>
<th class='c-name'><?php echo $lang->execution->name;?></th>
<td><?php echo html::input('name', $execution->name, "class='form-control' required");?></td><td></td>
</tr>
<?php if(isset($config->setCode) and $config->setCode == 1):?>
+26 -34
View File
@@ -61,40 +61,27 @@ js::set('rdSearchValue', '');
js::set('defaultMinColWidth', $this->config->minColWidth);
js::set('defaultMaxColWidth', $this->config->maxColWidth);
$canSortRegion = (commonModel::hasPriv('kanban', 'sortRegion') and count($regions) > 1);
$canCreateRegion = (common::hasPriv('kanban', 'createRegion') and $groupBy == 'default');
$canSortRegion = commonModel::hasPriv('kanban', 'sortRegion') && count($regions) > 1;
$canCreateRegion = common::hasPriv('kanban', 'createRegion') && $groupBy == 'default';
$canEditRegion = commonModel::hasPriv('kanban', 'editRegion');
$canDeleteRegion = commonModel::hasPriv('kanban', 'deleteRegion');
$canCreateLane = commonModel::hasPriv('kanban', 'createLane');
$canCreateTask = common::hasPriv('task', 'create');
$canBatchCreateTask = common::hasPriv('task', 'batchCreate');
$canImportTask = (common::hasPriv('execution', 'importTask') and $execution->multiple);
$canImportTask = common::hasPriv('execution', 'importTask') && $execution->multiple;
if($execution->lifetime != 'ops' and !in_array($execution->attribute, array('request', 'review')))
{
$canCreateBug = ($productID and common::hasPriv('bug', 'create'));
$canBatchCreateBug = ($productID and common::hasPriv('bug', 'batchCreate') and $execution->multiple);
$canImportBug = ($productID and common::hasPriv('execution', 'importBug'));
$canCreateStory = ($productID and common::hasPriv('story', 'create'));
$canBatchCreateStory = ($productID and common::hasPriv('story', 'batchCreate'));
$canLinkStory = ($productID and common::hasPriv('execution', 'linkStory') and !empty($execution->hasProduct));
$canLinkStoryByPlan = ($productID and common::hasPriv('execution', 'importplanstories') and !empty($project->hasProduct));
$hasStoryButton = ($canCreateStory or $canBatchCreateStory or $canLinkStory or $canLinkStoryByPlan);
$hasBugButton = ($canCreateBug or $canBatchCreateBug);
}
else
{
$canCreateBug = false;
$canBatchCreateBug = false;
$canImportBug = false;
$canCreateStory = false;
$canBatchCreateStory = false;
$canLinkStory = false;
$canLinkStoryByPlan = false;
$hasStoryButton = false;
$hasBugButton = false;
}
$hasTaskButton = ($canCreateTask or $canBatchCreateTask or $canImportBug);
$canCreateBug = $features['qa'] && $productID && common::hasPriv('bug', 'create');
$canBatchCreateBug = $features['qa'] && $productID && common::hasPriv('bug', 'batchCreate') && $execution->multiple;
$canImportBug = $features['qa'] && $productID && common::hasPriv('execution', 'importBug');
$hasBugButton = $features['qa'] && ($canCreateBug || $canBatchCreateBug);
$canCreateStory = $features['story'] && $productID && common::hasPriv('story', 'create');
$canBatchCreateStory = $features['story'] && $productID && common::hasPriv('story', 'batchCreate');
$canLinkStory = $features['story'] && $productID && common::hasPriv('execution', 'linkStory') && !empty($execution->hasProduct);
$canLinkStoryByPlan = $features['story'] && $productID && common::hasPriv('execution', 'importplanstories') && !empty($project->hasProduct);
$hasStoryButton = $features['story'] && ($canCreateStory || $canBatchCreateStory || $canLinkStory || $canLinkStoryByPlan);
$hasTaskButton = $canCreateTask || $canBatchCreateTask || $canImportBug;
js::set('priv',
array(
@@ -134,7 +121,7 @@ js::set('priv',
'canDeleteStory' => common::hasPriv('story', 'delete'),
'canChangeStory' => common::hasPriv('story', 'change'),
'canCloseStory' => common::hasPriv('story', 'close'),
'canUnlinkStory' => (common::hasPriv('execution', 'unlinkStory') and !empty($execution->hasProduct)),
'canUnlinkStory' => (common::hasPriv('execution', 'unlinkStory') && !empty($execution->hasProduct)),
'canViewStory' => common::hasPriv('execution', 'storyView'),
)
);
@@ -142,13 +129,17 @@ js::set('priv',
<?php if($groupBy == 'story' and $browseType == 'task'):?>
<style>.kanban-cols {left: 0px !important;}</style>
<?php endif;?>
<?php if($execution->lifetime == 'ops' or in_array($execution->attribute, array('request', 'review'))):?>
<?php if(!($features['story'] or $features['qa'])):?>
<style>#mainMenu .c-group{margin-left: 0px;}</style>
<?php endif;?>
<div id='mainMenu' class='clearfix'>
<div class='btn-toolbar pull-left'>
<?php if($execution->lifetime != 'ops' and !in_array($execution->attribute, array('request', 'review'))):?>
<?php if($features['story'] or $features['qa']):?>
<div class="input-control space c-type">
<?php
if(!$features['story']) unset($lang->kanban->type['story']);
if(!$features['qa']) unset($lang->kanban->type['bug']);
?>
<?php echo html::select('type', $lang->kanban->type, $browseType, 'class="form-control chosen" data-max_drop_width="215"');?>
</div>
<?php endif;?>
@@ -226,13 +217,14 @@ js::set('priv',
<?php if($canLinkStoryByPlan) echo '<li>' . html::a('#linkStoryByPlan', $lang->execution->linkStoryByPlan, '', 'data-toggle="modal"') . '</li>';?>
<?php if($hasStoryButton and $hasBugButton) echo '<li class="divider"></li>';?>
<?php if($canCreateBug) echo '<li>' . html::a(helper::createLink('bug', 'create', "productID=$productID&branch=0&extra=executionID=$execution->id", '', true), $lang->bug->create, '', "class='iframe'") . '</li>';?>
<?php if($canBatchCreateBug)
<?php
if($canBatchCreateBug)
{
$batchCreateBugLink = '<li>' . html::a(helper::createLink('bug', 'batchCreate', "productID=$productID&branch=$branchID&executionID=$execution->id", '', true), $lang->bug->batchCreate, '', "class='iframe'") . '</li>';
if($productNum > 1) $batchCreateBugLink = '<li>' . html::a('#batchCreateBug', $lang->bug->batchCreate, '', "data-toggle='modal'") . '</li>';
echo $batchCreateBugLink;
}?>
}
?>
<?php if(($hasStoryButton or $hasBugButton) and $hasTaskButton) echo '<li class="divider"></li>';?>
<?php if($canCreateTask) echo '<li>' . html::a(helper::createLink('task', 'create', "execution=$execution->id", '', true), $lang->task->create, '', "class='iframe'") . '</li>';?>
<?php if($canImportBug) echo '<li>' . html::a(helper::createLink('execution', 'importBug', "executionID=$execution->id", '', true), $lang->execution->importBug, '', "class='iframe' data-width=90%") . '</li>';?>
+5 -5
View File
@@ -17,7 +17,7 @@
<?php endif;?>
<div id='mainMenu' class='clearfix'>
<div class='btn-toolbar pull-left'>
<?php if(isset($lang->execution->menu->qa)):?>
<?php if($features['qa']):?>
<div class="input-control space c-type">
<?php echo html::select('type', $lang->kanban->type, $browseType, 'class="form-control chosen" data-max_drop_width="215"');?>
</div>
@@ -62,7 +62,7 @@
$link = common::hasPriv('execution', 'importTask') ? $this->createLink('execution', 'importTask', "execution=$execution->id") : '#';
echo "<li $misc>" . html::a($link, $lang->execution->importTask, '', $misc) . "</li>";
if(isset($lang->execution->menu->qa))
if($features['qa'])
{
$misc = common::hasPriv('execution', 'importBug') ? '' : "class=disabled";
$link = common::hasPriv('execution', 'importBug') ? $this->createLink('execution', 'importBug', "execution=$execution->id") : '#';
@@ -103,14 +103,14 @@
<button class='btn btn-primary' type='button' data-toggle='dropdown'><i class='icon icon-plus'></i> <?php echo $this->lang->create;?> <span class='caret'></span></button>
<ul class='dropdown-menu pull-right'>
<?php $showDivider = false;?>
<?php if(isset($lang->execution->menu->story) and $hasStoryButton):?>
<?php if($features['story'] and $hasStoryButton):?>
<?php if($canCreateStory) echo '<li>' . html::a(helper::createLink('story', 'create', "productID=$productID&branch=0&moduleID=0&story=0&execution=$execution->id", '', true), $lang->execution->createStory, '', "class='iframe' data-width='80%'") . '</li>';?>
<?php if($canBatchCreateStory) echo '<li>' . html::a(helper::createLink('story', 'batchCreate', "productID=$productID&branch=0&moduleID=0&story=0&execution=$execution->id", '', true), $lang->execution->batchCreateStory, '', "class='iframe' data-width='90%'") . '</li>';?>
<?php if($canLinkStory) echo '<li>' . html::a(helper::createLink('execution', 'linkStory', "execution=$execution->id", '', true), $lang->execution->linkStory, '', "class='iframe' data-width='90%'") . '</li>';?>
<?php if($canLinkStoryByPlan) echo '<li>' . html::a('#linkStoryByPlan', $lang->execution->linkStoryByPlan, '', 'data-toggle="modal"') . '</li>';?>
<?php $showDivider = true;?>
<?php endif;?>
<?php if(isset($lang->execution->menu->qa)):?>
<?php if($features['qa']):?>
<?php if($showDivider) echo '<li class="divider"></li>';?>
<?php if($canCreateBug) echo '<li>' . html::a(helper::createLink('bug', 'create', "productID=$productID&branch=0&extra=executionID=$execution->id", '', true), $lang->bug->create, '', "class='iframe'") . '</li>';?>
<?php if($canBatchCreateBug)
@@ -238,6 +238,6 @@ js::set('priv',
<?php js::set('defaultMinColWidth', $this->config->minColWidth);?>
<?php js::set('defaultMaxColWidth', $this->config->maxColWidth);?>
<?php js::set('teamWords', $lang->execution->teamWords);?>
<?php js::set('canImportBug', isset($lang->execution->menu->qa));?>
<?php js::set('canImportBug', $features['qa']);?>
<?php include '../../common/view/footer.html.php';?>
+1
View File
@@ -1,2 +1,3 @@
#planForm tr td {vertical-align: top;}
#mainContent .methodTitle, #mainContent .methodTip {display: inline-block; vertical-align: middle;}
.type-list-radio {display: inline-block; padding: 10px 5px;}
+12 -8
View File
@@ -46,17 +46,21 @@
<?php if(!empty($planID) and $project->model == 'waterfallplus'):?>
<div class="pull-left">
<div class='methodTitle'><strong><?php echo $lang->programplan->subPlanManage . ':'?></strong></div>
<div class='btn-group'>
<a href='javascript:;' class='btn btn-link btn-limit' data-toggle='dropdown'><span class='text' title='<?php echo zget($lang->programplan->typeList, $executionType);?>'><?php echo zget($lang->programplan->typeList, $executionType);?></span> <span class='caret'></span></a>
<ul class='dropdown-menu' style='max-height:240px; max-width: 300px; overflow-y:auto'>
<?php
<div class='type-list-radio'>
<?php
if(count($lang->programplan->typeList) > 1)
{
foreach($lang->programplan->typeList as $key => $value)
{
$class = $executionType == $key ? 'class="active"' : '';
echo "<li $class>" . html::a($this->createLink('programplan', 'create', "projectID=$project->id&productID=$productID&planID=$planID&type=$key"), $value) . "</li>";
$label = "<label class='radio-inline'><input type='radio' name='executionType' value='{$key}'" . ($key == $executionType ? " checked='checked'" : '') . ">{$value}</label>";
echo html::a($this->createLink('programplan', 'create', "projectID=$project->id&productID=$productID&planID=$planID&type=$key"), $label);
}
?>
</ul>
}
else
{
echo zget($lang->programplan->typeList, $executionType);
}
?>
</div>
<div class='methodTip'><icon class='icon icon-help' data-toggle='popover' data-trigger='focus hover' data-placement='right' data-tip-class='text-muted popover-sm' data-content="<?php echo $lang->programplan->methodTip;?>"></icon></div>
</div>
-1
View File
@@ -84,7 +84,6 @@ class project extends control
$project->PM = zget($users, $project->PM);
$project->status = $this->processStatus('project', $project);
$project->model = zget($projectLang->modelList, $project->model);
$project->budget = $project->budget . zget($projectLang->unitList, $project->budgetUnit);
$project->budget = $project->budget != 0 ? $project->budget . zget($projectLang->unitList, $project->budgetUnit) : $this->lang->project->future;
$project->parent = $project->parentName;
$project->hasProduct = zget($projectLang->projectTypeList, $project->hasProduct);
+1 -1
View File
@@ -2624,7 +2624,7 @@ class projectModel extends model
$this->loadModel('program');
$projects = $this->program->getProjectStats(0, 'all', 0, 'order_asc');
$executions = $this->loadModel('execution')->getStatData(0, 'doing');
$executions = $this->loadModel('execution')->getStatData(0, 'doing', 0, 0, false, 'hasParentName|skipParent');
$doingExecutions = array();
$latestExecutions = array();
+5 -1
View File
@@ -922,7 +922,11 @@ class story extends control
$this->view->hiddenParent = true;
if($project->model !== 'scrum') $this->view->hiddenPlan = true;
if(!$project->multiple) $this->view->hiddenPlan = true;
if(!$project->multiple)
{
$this->view->hiddenPlan = true;
unset($this->lang->story->stageList[''], $this->lang->story->stageList['wait'], $this->lang->story->stageList['planned']);
}
if($project->model === 'kanban') $this->view->hiddenURS = true;
}
+49
View File
@@ -336,4 +336,53 @@ class programplanTest
return implode(',', $objects);
}
/**
* Test get parent stage's children types.
*
* @param int $parentID
* @access public
* @return string
*/
public function getParentChildrenTypesTest($parentID)
{
$objects = $this->objectModel->getParentChildrenTypes($parentID);
if(dao::isError()) return dao::getError();
return $objects;
}
/**
* Test check code unique.
*
* @param array $codes
* @param array $planIDList
* @access public
* @return string
*/
public function checkCodeUniqueTest($codes, $planIDList = array())
{
$objects = $this->objectModel->checkCodeUnique($codes, $planIDList);
if(dao::isError()) return dao::getError();
return $objects;
}
/**
* Test check name unique.
*
* @param array $names
* @access public
* @return string
*/
public function checkNameUniqueTest($names)
{
$objects = $this->objectModel->checkNameUnique($names);
if(dao::isError()) return dao::getError();
return $objects;
}
}
+24 -6
View File
@@ -11,20 +11,21 @@ class stageTest
* Test create a stage.
*
* @param object $stage
* @param string $type
* @access public
* @return object
*/
public function createTest($stage)
public function createTest($stage, $type = 'waterfall')
{
foreach($stage as $key => $value) $_POST[$key] = $value;
$objectID = $this->objectModel->create();
$objectID = $this->objectModel->create($type);
unset($_POST);
if(dao::isError()) return dao::getError();
$object = $this->objectModel->getByID($objectID);
$object = $this->objectModel->getByID($objectID, $type);
return $object;
}
@@ -32,20 +33,21 @@ class stageTest
* Test batch create stages.
*
* @param array $param
* @param string $type
* @access public
* @return int
*/
public function batchCreateTest($param)
public function batchCreateTest($param ,$type = 'waterfall')
{
foreach($param as $key => $value) $_POST[$key] = $value;
$this->objectModel->batchCreate();
$this->objectModel->batchCreate($type);
unset($_POST);
if(dao::isError()) return dao::getError();
$objects = $this->objectModel->getStages();
$objects = $this->objectModel->getStages('id_desc', 0, $type);
return count($objects);
}
@@ -116,4 +118,20 @@ class stageTest
return $object;
}
/**
* Test get a stage by id.
*
* @param string $projectType
* @access public
* @return object
*/
public function getTotalPercentTest($projectType)
{
$object = $this->objectModel->getTotalPercent($projectType);
if(dao::isError()) return dao::getError();
return $object;
}
}
@@ -0,0 +1,41 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/programplan.class.php';
su('admin');
$programplan = zdTable('project');
$programplan->id->range('10-15');
$programplan->code->range('1-5')->prefix('code');
$programplan->deleted->range('0-1');
$programplan->gen(5);
/**
title=测试 programplanModel->checkCodeUnique();
cid=1
pid=1
检查'code1', 'code2', 'code3', 'code4', 'code5' 在未删除的数据内编号是否唯一 code1 >> code1
检查'code1', 'code2', 'code3', 'code4', 'code5' 在未删除的数据内编号是否唯一 code3 >> code3
检查'code1', 'code2', 'code3', 'code4', 'code5' 在未删除的数据内编号是否唯一 code5 >> code5
检查'code1', 'code2', 'code3', 'code4', 'code5' 在除了id为'10', '11', '12', '13', '14'外的未删除数据编号是否唯一 >> 1
检查'code6', 'code7' 在未删除的数据内编号是否唯一 >> 1
检查'code2', 'code4' 在未删除的数据内编号是否唯一 >> 1
*/
$codes = array();
$codes[] = array('code1', 'code2', 'code3', 'code4', 'code5');
$codes[] = array('code6', 'code7');
$codes[] = array('code2', 'code4');
$exclude = array('10', '11', '12', '13', '14');
$programplan = new programplanTest();
r($programplan->checkCodeUniqueTest($codes[0])) && p('code1') && e('code1'); // 检查'code1', 'code2', 'code3', 'code4', 'code5' 在未删除的数据内编号是否唯一 code1
r($programplan->checkCodeUniqueTest($codes[0])) && p('code3') && e('code3'); // 检查'code1', 'code2', 'code3', 'code4', 'code5' 在未删除的数据内编号是否唯一 code3
r($programplan->checkCodeUniqueTest($codes[0])) && p('code5') && e('code5'); // 检查'code1', 'code2', 'code3', 'code4', 'code5' 在未删除的数据内编号是否唯一 code5
r($programplan->checkCodeUniqueTest($codes[0], $exclude)) && p() && e('1'); // 检查'code1', 'code2', 'code3', 'code4', 'code5' 在除了id为'10', '11', '12', '13', '14'外的未删除数据编号是否唯一
r($programplan->checkCodeUniqueTest($codes[1])) && p() && e('1'); // 检查'code6', 'code7' 在未删除的数据内编号是否唯一
r($programplan->checkCodeUniqueTest($codes[2])) && p() && e('1'); // 检查'code2', 'code4' 在未删除的数据内编号是否唯一
@@ -0,0 +1,34 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/programplan.class.php';
su('admin');
$programplan = zdTable('project');
$programplan->id->range('10-15');
$programplan->name->range('1-5')->prefix('name');
$programplan->deleted->range('0-1');
$programplan->gen(5);
/**
title=测试 programplanModel->checkNameUnique();
cid=1
pid=1
检查'name1', 'name2', 'name1', 'name3', 'name5' 数组的值是否唯一 >> 0
检查'name6', 'name7' 数组的值是否唯一 >> 1
检查'name2', 'name2' 数组的值是否唯一 >> 0
*/
$names = array();
$names[] = array('name1', 'name2', 'name1', 'name3', 'name5');
$names[] = array('name6', 'name7');
$names[] = array('name2', 'name2');
$programplan = new programplanTest();
r($programplan->checkNameUniqueTest($names[0])) && p() && e('0'); // 检查'name1', 'name2', 'name1', 'name3', 'name5' 数组的值是否唯一
r($programplan->checkNameUniqueTest($names[1])) && p() && e('1'); // 检查'name6', 'name7' 数组的值是否唯一
r($programplan->checkNameUniqueTest($names[2])) && p() && e('0'); // 检查'name2', 'name2' 数组的值是否唯一
+54
View File
@@ -0,0 +1,54 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/programplan.class.php';
su('admin');
$programplan = zdTable('project');
$programplan->id->range('10-20');
$programplan->parent->range('1-3');
$programplan->type->range('stage{3},sprint{2},kanban{2},stage{1},sprint{2}');
$programplan->deleted->range('0-1');
$programplan->gen(10);
/**
title=测试 programplanModel->getParentChildrenTypes();
cid=1
pid=1
查找父ID为 1 未删除的阶段类型 stage >> stage
查找父ID为 1 未删除的阶段类型 kanban >> kanban
查找父ID为 1 未删除的阶段类型数量 >> 2
查找父ID为 2 未删除的阶段类型 sprint >> sprint
查找父ID为 2 未删除的阶段类型数量 >> 1
查找父ID为 3 未删除的阶段类型 stage >> stage
查找父ID为 3 未删除的阶段类型 sprint >> sprint
查找父ID为 3 未删除的阶段类型数量 >> 2
查找父ID为 1 未删除的阶段类型 stage >> 0
查找父ID为 1 未删除的阶段类型 sprint >> 0
查找父ID为 1 未删除的阶段类型 kanban >> 0
查找父ID为 1 未删除的阶段类型数量 >> 0
*/
$parentIDList = array(1, 2, 3, 4);
$programplan = new programplanTest();
r($programplan->getParentChildrenTypesTest($parentIDList[0])) && p('stage') && e('stage'); // 查找父ID为 1 未删除的阶段类型 stage
r($programplan->getParentChildrenTypesTest($parentIDList[0])) && p('sprint') && e(''); // 查找父ID为 1 未删除的阶段类型 sprint
r($programplan->getParentChildrenTypesTest($parentIDList[0])) && p('kanban') && e('kanban'); // 查找父ID为 1 未删除的阶段类型 kanban
r(count($programplan->getParentChildrenTypesTest($parentIDList[0]))) && p() && e('2'); // 查找父ID为 1 未删除的阶段类型数量
r($programplan->getParentChildrenTypesTest($parentIDList[1])) && p('stage') && e(''); // 查找父ID为 2 未删除的阶段类型 stage
r($programplan->getParentChildrenTypesTest($parentIDList[1])) && p('sprint') && e('sprint'); // 查找父ID为 2 未删除的阶段类型 sprint
r($programplan->getParentChildrenTypesTest($parentIDList[1])) && p('kanban') && e(''); // 查找父ID为 2 未删除的阶段类型 kanban
r(count($programplan->getParentChildrenTypesTest($parentIDList[1]))) && p() && e('1'); // 查找父ID为 2 未删除的阶段类型数量
r($programplan->getParentChildrenTypesTest($parentIDList[2])) && p('stage') && e('stage'); // 查找父ID为 3 未删除的阶段类型 stage
r($programplan->getParentChildrenTypesTest($parentIDList[2])) && p('sprint') && e('sprint'); // 查找父ID为 3 未删除的阶段类型 sprint
r($programplan->getParentChildrenTypesTest($parentIDList[2])) && p('kanban') && e(''); // 查找父ID为 3 未删除的阶段类型 kanban
r(count($programplan->getParentChildrenTypesTest($parentIDList[2]))) && p() && e('2'); // 查找父ID为 3 未删除的阶段类型数量
r($programplan->getParentChildrenTypesTest($parentIDList[3])) && p('stage') && e('0'); // 查找父ID为 1 未删除的阶段类型 stage
r($programplan->getParentChildrenTypesTest($parentIDList[3])) && p('sprint') && e('0'); // 查找父ID为 1 未删除的阶段类型 sprint
r($programplan->getParentChildrenTypesTest($parentIDList[3])) && p('kanban') && e('0'); // 查找父ID为 1 未删除的阶段类型 kanban
r(count($programplan->getParentChildrenTypesTest($parentIDList[3]))) && p() && e('0'); // 查找父ID为 1 未删除的阶段类型数量
+49 -14
View File
@@ -2,19 +2,32 @@
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/stage.class.php';
$db->switchDB();
su('admin');
zdTable('stage')->gen(0);
/**
title=测试 stageModel->batchCreate();
cid=1
pid=1
测试批量创建阶段 1 >> 8
测试批量创建阶段 2 >> 10
测试批量创建阶段 3 >> 12
测试批量创建阶段 4 >> 13
测试批量创建瀑布项目的阶段 1 >> 2
测试批量创建瀑布项目的阶段 2 >> 4
测试批量创建瀑布项目的阶段 3 >> 6
测试批量创建瀑布项目的阶段 4 >> 7
测试批量创建瀑布项目的百分比为空的阶段 >> 『工作量占比』不能为空。
测试批量创建瀑布项目的类型为空的阶段 >> 『阶段类型』不能为空。
测试批量创建瀑布项目的百分比非法的阶段 >> 工作量占比应当是数字,可以是小数。
测试批量创建瀑布项目的百分比超出100的阶段 >> 工作量占比累计不应当超过100%
测试批量创建融合瀑布项目的阶段 1 >> 2
测试批量创建融合瀑布项目的阶段 2 >> 4
测试批量创建融合瀑布项目的阶段 3 >> 6
测试批量创建融合瀑布项目的阶段 4 >> 7
测试批量创建融合瀑布项目的百分比为空的阶段 >> 『工作量占比』不能为空。
测试批量创建融合瀑布项目的类型为空的阶段 >> 『阶段类型』不能为空。
测试批量创建融合瀑布项目的百分比非法的阶段 >> 工作量占比应当是数字,可以是小数。
测试批量创建融合瀑布项目的百分比超出100的阶段 >> 工作量占比累计不应当超过100%
*/
$name1 = array('1' => '批量创建的需求', '2' => '批量创建的设计', '3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
@@ -33,15 +46,37 @@ $name4 = array('1' => '', '2' => '批量创建的其他', '3' => '', '4' => '
$percent4 = array('1' => '1', '2' => '7', '3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
$type4 = array('1' => 'request', '2' => 'other', '3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
$param1 = array('name' => $name1, 'percent' => $percent1, 'type' => $type1);
$param2 = array('name' => $name2, 'percent' => $percent2, 'type' => $type2);
$param3 = array('name' => $name3, 'percent' => $percent3, 'type' => $type3);
$param4 = array('name' => $name4, 'percent' => $percent4, 'type' => $type4);
$emptyPercent = array('1' => '', '2' => '','3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
$emptyType = array('1' => '', '2' => '','3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
$IllegalPercent = array('1' => 'a', '2' => 'b','3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
$percentOver = array('1' => '111', '2' => '2','3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
$param1 = array('name' => $name1, 'percent' => $percent1, 'type' => $type1);
$param2 = array('name' => $name2, 'percent' => $percent2, 'type' => $type2);
$param3 = array('name' => $name3, 'percent' => $percent3, 'type' => $type3);
$param4 = array('name' => $name4, 'percent' => $percent4, 'type' => $type4);
$param5 = array('name' => $name1, 'percent' => $emptyPercent, 'type' => $type1);
$param6 = array('name' => $name1, 'percent' => $percent1, 'type' => $emptyType);
$param7 = array('name' => $name1, 'percent' => $IllegalPercent, 'type' => $type1);
$param8 = array('name' => $name1, 'percent' => $percentOver, 'type' => $type1);
$stage = new stageTest();
r($stage->batchCreateTest($param1)) && p() && e('8'); // 测试批量创建阶段 1
r($stage->batchCreateTest($param2)) && p() && e('10'); // 测试批量创建阶段 2
r($stage->batchCreateTest($param3)) && p() && e('12'); // 测试批量创建阶段 3
r($stage->batchCreateTest($param4)) && p() && e('13'); // 测试批量创建阶段 4
$db->restoreDB();
r($stage->batchCreateTest($param1)) && p() && e('2'); // 测试批量创建瀑布项目的阶段 1
r($stage->batchCreateTest($param2)) && p() && e('4'); // 测试批量创建瀑布项目的阶段 2
r($stage->batchCreateTest($param3)) && p() && e('6'); // 测试批量创建瀑布项目的阶段 3
r($stage->batchCreateTest($param4)) && p() && e('7'); // 测试批量创建瀑布项目的阶段 4
r($stage->batchCreateTest($param5)) && p('percent:0') && e('『工作量占比』不能为空。'); // 测试批量创建瀑布项目的百分比为空的阶段
r($stage->batchCreateTest($param6)) && p('type:0') && e('『阶段类型』不能为空。'); // 测试批量创建瀑布项目的类型为空的阶段
r($stage->batchCreateTest($param7)) && p('percent:0') && e('工作量占比应当是数字,可以是小数。'); // 测试批量创建瀑布项目的百分比非法的阶段
r($stage->batchCreateTest($param8)) && p('message:0') && e('工作量占比累计不应当超过100%'); // 测试批量创建瀑布项目的百分比超出100的阶段
r($stage->batchCreateTest($param1, 'waterfallplus')) && p() && e('2'); // 测试批量创建融合瀑布项目的阶段 1
r($stage->batchCreateTest($param2, 'waterfallplus')) && p() && e('4'); // 测试批量创建融合瀑布项目的阶段 2
r($stage->batchCreateTest($param3, 'waterfallplus')) && p() && e('6'); // 测试批量创建融合瀑布项目的阶段 3
r($stage->batchCreateTest($param4, 'waterfallplus')) && p() && e('7'); // 测试批量创建融合瀑布项目的阶段 4
r($stage->batchCreateTest($param5, 'waterfallplus')) && p('percent:0') && e('『工作量占比』不能为空。'); // 测试批量创建融合瀑布项目的百分比为空的阶段
r($stage->batchCreateTest($param6, 'waterfallplus')) && p('type:0') && e('『阶段类型』不能为空。'); // 测试批量创建融合瀑布项目的类型为空的阶段
r($stage->batchCreateTest($param7, 'waterfallplus')) && p('percent:0') && e('工作量占比应当是数字,可以是小数。'); // 测试批量创建融合瀑布项目的百分比非法的阶段
r($stage->batchCreateTest($param8, 'waterfallplus')) && p('message:0') && e('工作量占比累计不应当超过100%'); // 测试批量创建融合瀑布项目的百分比超出100的阶段
+82 -23
View File
@@ -2,67 +2,126 @@
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/stage.class.php';
$db->switchDB();
su('admin');
zdTable('stage')->gen(0);
/**
title=测试 stageModel->create();
cid=1
pid=1
测试新建一个需求阶段 >> 新建的需求,1,request
测试新建一个设计阶段 >> 新建的设计,2,design
测试新建一个开发阶段 >> 新建的开发,3,dev
测试新建一个测试阶段 >> 新建的测试,4,qa
测试新建一个发布阶段 >> 新建的发布,5,release
测试新建一个总结评审阶段 >> 新建的总结评审,6,review
测试新建一个其他阶段 >> 新建的其他,7,other
测试新建瀑布项目一个需求阶段 >> 新建的需求,1,request
测试新建瀑布项目一个设计阶段 >> 新建的设计,2,design
测试新建瀑布项目一个开发阶段 >> 新建的开发,3,dev
测试新建瀑布项目一个测试阶段 >> 新建的测试,4,qa
测试新建瀑布项目一个发布阶段 >> 新建的发布,5,release
测试新建瀑布项目一个总结评审阶段 >> 新建的总结评审,6,review
测试新建瀑布项目一个其他阶段 >> 新建的其他,7,other
测试新建瀑布项目名称为空 >> 『阶段名称』不能为空。
测试新建瀑布项目类型为空 >> 『工作量占比』不能为空。
测试新建瀑布项目百分比为空 >> 『阶段类型』不能为空。
测试新建瀑布项目非数字的百分比 >> 工作量占比应当是数字
测试新建瀑布项目总百分比超过100 >> 工作量占比累计不应当超过100%
测试新建融合瀑布项目一个需求阶段 >> 新建的需求,1,request
测试新建融合瀑布项目一个设计阶段 >> 新建的设计,2,design
测试新建融合瀑布项目一个开发阶段 >> 新建的开发,3,dev
测试新建融合瀑布项目一个测试阶段 >> 新建的测试,4,qa
测试新建融合瀑布项目一个发布阶段 >> 新建的发布,5,release
测试新建融合瀑布项目一个总结评审阶段 >> 新建的总结评审,6,review
测试新建融合瀑布项目一个其他阶段 >> 新建的其他,7,other
测试新建融合瀑布项目名称为空 >> 『阶段名称』不能为空。
测试新建融合瀑布项目类型为空 >> 『工作量占比』不能为空。
测试新建融合瀑布项目百分比为空 >> 『阶段类型』不能为空。
测试新建融合瀑布项目非数字的百分比 >> 工作量占比应当是数字
测试新建融合瀑布项目总百分比超过100 >> 工作量占比累计不应当超过100%
*/
$stage1 = new stdclass();
$stage1->name = '新建的需求';
$stage1->name = '新建的需求';
$stage1->percent = 1;
$stage1->type = 'request';
$stage2 = new stdclass();
$stage2->name = '新建的设计';
$stage2->name = '新建的设计';
$stage2->percent = 2;
$stage2->type = 'design';
$stage3 = new stdclass();
$stage3->name = '新建的开发';
$stage3->name = '新建的开发';
$stage3->percent = 3;
$stage3->type = 'dev';
$stage4 = new stdclass();
$stage4->name = '新建的测试';
$stage4->name = '新建的测试';
$stage4->percent = 4;
$stage4->type = 'qa';
$stage5 = new stdclass();
$stage5->name = '新建的发布';
$stage5->name = '新建的发布';
$stage5->percent = 5;
$stage5->type = 'release';
$stage6 = new stdclass();
$stage6->name = '新建的总结评审';
$stage6->name = '新建的总结评审';
$stage6->percent = 6;
$stage6->type = 'review';
$stage7 = new stdclass();
$stage7->name = '新建的其他';
$stage7->name = '新建的其他';
$stage7->percent = 7;
$stage7->type = 'other';
$emptyName = new stdclass();
$emptyName->name = '';
$emptyName->percent = 7;
$emptyName->type = 'other';
$emptyPercent = new stdclass();
$emptyPercent->name = '1';
$emptyPercent->percent = 0;
$emptyPercent->type = 'other';
$emptyType = new stdclass();
$emptyType->name = '1';
$emptyType->percent = 7;
$emptyType->type = '';
$IllegalPercent = new stdclass();
$IllegalPercent->name = '一个名称';
$IllegalPercent->percent = 'a';
$IllegalPercent->type = 'other';
$percentOver = new stdclass();
$percentOver->name = '一个名称';
$percentOver->percent = 101;
$percentOver->type = 'other';
$stage = new stageTest();
r($stage->createTest($stage1)) && p('name,percent,type') && e('新建的需求,1,request'); // 测试新建一个需求阶段
r($stage->createTest($stage2)) && p('name,percent,type') && e('新建的设计,2,design'); // 测试新建一个设计阶段
r($stage->createTest($stage3)) && p('name,percent,type') && e('新建的开发,3,dev'); // 测试新建一个开发阶段
r($stage->createTest($stage4)) && p('name,percent,type') && e('新建的测试,4,qa'); // 测试新建一个测试阶段
r($stage->createTest($stage5)) && p('name,percent,type') && e('新建的发布,5,release'); // 测试新建一个发布阶段
r($stage->createTest($stage6)) && p('name,percent,type') && e('新建的总结评审,6,review'); // 测试新建一个总结评审阶段
r($stage->createTest($stage7)) && p('name,percent,type') && e('新建的其他,7,other'); // 测试新建一个其他阶段
$db->restoreDB();
r($stage->createTest($stage1)) && p('name,percent,type') && e('新建的需求,1,request'); // 测试新建瀑布项目一个需求阶段
r($stage->createTest($stage2)) && p('name,percent,type') && e('新建的设计,2,design'); // 测试新建瀑布项目一个设计阶段
r($stage->createTest($stage3)) && p('name,percent,type') && e('新建的开发,3,dev'); // 测试新建瀑布项目一个开发阶段
r($stage->createTest($stage4)) && p('name,percent,type') && e('新建的测试,4,qa'); // 测试新建瀑布项目一个测试阶段
r($stage->createTest($stage5)) && p('name,percent,type') && e('新建的发布,5,release'); // 测试新建瀑布项目一个发布阶段
r($stage->createTest($stage6)) && p('name,percent,type') && e('新建的总结评审,6,review'); // 测试新建瀑布项目一个总结评审阶段
r($stage->createTest($stage7)) && p('name,percent,type') && e('新建的其他,7,other'); // 测试新建瀑布项目一个其他阶段
r($stage->createTest($emptyName)) && p('name:0') && e('『阶段名称』不能为空。'); // 测试新建瀑布项目名称为空
r($stage->createTest($emptyPercent)) && p('percent:0') && e('『工作量占比』不能为空。'); // 测试新建瀑布项目类型为空
r($stage->createTest($emptyType)) && p('type:0') && e('『阶段类型』不能为空。'); // 测试新建瀑布项目百分比为空
r($stage->createTest($IllegalPercent)) && p('message:0') && e('工作量占比应当是数字'); // 测试新建瀑布项目非数字的百分比
r($stage->createTest($percentOver)) && p('message:0') && e('工作量占比累计不应当超过100%'); // 测试新建瀑布项目总百分比超过100
r($stage->createTest($stage1, 'waterfallplus')) && p('name,percent,type') && e('新建的需求,1,request'); // 测试新建融合瀑布项目一个需求阶段
r($stage->createTest($stage2, 'waterfallplus')) && p('name,percent,type') && e('新建的设计,2,design'); // 测试新建融合瀑布项目一个设计阶段
r($stage->createTest($stage3, 'waterfallplus')) && p('name,percent,type') && e('新建的开发,3,dev'); // 测试新建融合瀑布项目一个开发阶段
r($stage->createTest($stage4, 'waterfallplus')) && p('name,percent,type') && e('新建的测试,4,qa'); // 测试新建融合瀑布项目一个测试阶段
r($stage->createTest($stage5, 'waterfallplus')) && p('name,percent,type') && e('新建的发布,5,release'); // 测试新建融合瀑布项目一个发布阶段
r($stage->createTest($stage6, 'waterfallplus')) && p('name,percent,type') && e('新建的总结评审,6,review'); // 测试新建融合瀑布项目一个总结评审阶段
r($stage->createTest($stage7, 'waterfallplus')) && p('name,percent,type') && e('新建的其他,7,other'); // 测试新建融合瀑布项目一个其他阶段
r($stage->createTest($emptyName, 'waterfallplus')) && p('name:0') && e('『阶段名称』不能为空。'); // 测试新建融合瀑布项目名称为空
r($stage->createTest($emptyPercent, 'waterfallplus')) && p('percent:0') && e('『工作量占比』不能为空。'); // 测试新建融合瀑布项目类型为空
r($stage->createTest($emptyType, 'waterfallplus')) && p('type:0') && e('『阶段类型』不能为空。'); // 测试新建融合瀑布项目百分比为空
r($stage->createTest($IllegalPercent, 'waterfallplus')) && p('message:0') && e('工作量占比应当是数字'); // 测试新建融合瀑布项目非数字的百分比
r($stage->createTest($percentOver, 'waterfallplus')) && p('message:0') && e('工作量占比累计不应当超过100%'); // 测试新建融合瀑布项目总百分比超过100
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/stage.class.php';
su('admin');
$stage = zdTable('stage');
$stage->id->range('1-10');
$stage->percent->range('10-20');
$stage->projectType->range('waterfall{5}, waterfallplus{5}');
$stage->deleted->range('0-1');
$stage->gen(10);
/**
title=测试 stageModel->getTotalPercent();
cid=1
pid=1
测试获取瀑布项目的总百分比 >> 36
测试获取融合瀑布项目的总百分比 >> 34
*/
$stage = new stageTest();
r($stage->getTotalPercentTest('waterfall')) && p() && e('36'); // 测试获取瀑布项目的总百分比
r($stage->getTotalPercentTest('waterfallplus')) && p() && e('34'); // 测试获取融合瀑布项目的总百分比
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long