Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms into sprint/master_lanzongjun_fixbug
This commit is contained in:
@@ -34,7 +34,7 @@ class productIssueEntry extends entry
|
||||
{
|
||||
case 'story':
|
||||
$this->app->loadLang('story');
|
||||
$storyStatus = array('' => '', 'draft' => 'opened', 'active' => 'opened', 'changed' => 'opened', 'closed' => 'closed');
|
||||
$storyStatus = array('' => '', 'draft' => 'opened', 'reviewing' => 'opened', 'active' => 'opened', 'changing' => 'opened', 'closed' => 'closed');
|
||||
|
||||
$story = $this->dao->select('*')->from(TABLE_STORY)->where('id')->eq($id)->fetch();
|
||||
if(!$story) $this->send404();
|
||||
|
||||
@@ -30,7 +30,7 @@ class productIssuesEntry extends entry
|
||||
|
||||
$storyFields = 'id,status';
|
||||
$storyStatus = array('' => '');
|
||||
$storyStatus['opened'] = 'draft,active,changed';
|
||||
$storyStatus['opened'] = 'draft,reviewing,active,changing';
|
||||
$storyStatus['closed'] = 'closed';
|
||||
|
||||
$bugFields = 'id,status';
|
||||
|
||||
@@ -24,7 +24,7 @@ class productsEntry extends entry
|
||||
if(strpos(strtolower(",{$fields},"), ',dropmenu,') !== false) return $this->getDropMenu();
|
||||
|
||||
if(!$programID) $programID = $this->param('program', 0);
|
||||
$projectID = $this->param('project', 0);
|
||||
$projectID = $this->param('project', 0);
|
||||
$mergeChildren = $this->param('mergeChildren', '');
|
||||
|
||||
if($programID)
|
||||
@@ -55,7 +55,7 @@ class productsEntry extends entry
|
||||
else
|
||||
{
|
||||
$control = $this->loadController('product', 'all');
|
||||
$control->all($this->param('status', 'all'), $this->param('order', 'order_asc'), 0, 0, $this->param('limit', '20'), $this->param('page', '1') );
|
||||
$control->all($this->param('status', 'all'), $this->param('order', 'program_asc'), 0, 0, $this->param('limit', 100), $this->param('page', 1));
|
||||
|
||||
/* Response */
|
||||
$data = $this->getData();
|
||||
@@ -174,7 +174,7 @@ class productsEntry extends entry
|
||||
/**
|
||||
* Merge children products.
|
||||
*
|
||||
* @param array $products
|
||||
* @param array $products
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -192,12 +192,11 @@ class productsEntry extends entry
|
||||
}
|
||||
|
||||
$unclosedTotal = 0;
|
||||
foreach($program as $field => $value)
|
||||
foreach($program as $lineID => $value)
|
||||
{
|
||||
if(!isset($programs[$programID]->children)) $programs[$programID]->children = array();
|
||||
if(isset($value->products))
|
||||
{
|
||||
$lineID = $field;
|
||||
if(empty($lineID))
|
||||
{
|
||||
foreach($value->products as $product)
|
||||
|
||||
@@ -273,7 +273,7 @@ class reportsEntry extends entry
|
||||
}
|
||||
|
||||
/* Set story status statistics integrate into product. */
|
||||
$storyStatusList = array('draft' => array(), 'active' => array(), 'changed' => array(), 'closed' => array());
|
||||
$storyStatusList = array('draft' => array(), 'reviewing' => array(), 'active' => array(), 'changing' => array(), 'closed' => array());
|
||||
foreach($processedProducts as $productID => $product)
|
||||
{
|
||||
$product->storyStat = array();
|
||||
|
||||
+19
-4
@@ -64,12 +64,23 @@
|
||||
36189 Bug按照优先级或严重程度排序时,空值放最后
|
||||
36190 用例关联bug和用例页增加分页
|
||||
36522 注册系统管理员的密码规则同系统中中级密码强度
|
||||
14586 创建子任务时自动代入父任务的优先级
|
||||
29216 创建和编辑任务时,所属执行的下拉菜单过滤掉禁止修改的执行
|
||||
34642 地盘待处理中看板项目的任务详情以弹窗形式展示
|
||||
34709 研发需求搜索表单增加评审结果字段
|
||||
35043 补充执行版本详情页面的返回逻辑
|
||||
35604 批量编辑项目时,计划起止日期超出父项目集日期范围时,增加提示信息
|
||||
35795 给任务增加日志时,已有日志列表增加记录人和累积耗时字段
|
||||
35893 创建项目时,修改所属项目集后表单采用局部刷新
|
||||
35975 通过计划创建执行时,项目的下拉菜单过滤掉已关闭的项目
|
||||
35991 创建测试任务时,研发需求的日程规划和指派给字段增加同上选项
|
||||
36128 地盘日程日历中,表头居中显示
|
||||
36259 需求详情中的附件去掉删除操作
|
||||
36263 附件的操作按钮以图标样式进行显示
|
||||
36367 创建和编辑项目时,预算和时间范围的超出提示增加忽略操作
|
||||
企业版:
|
||||
28045 反馈关闭原因为重复时,增加重复反馈输入的选项
|
||||
30523 反馈转Bug时取消选择项目弹窗直接进入提Bug页面
|
||||
30912 地盘日志列表新建日志时可以搜索该用户参与的所有执行
|
||||
31984 反馈增加批量导入功能
|
||||
33940 反馈增加导出模板功能
|
||||
34296 提交反馈默认公开
|
||||
34844 组织日志菜单下增加增加未填写日志成员的选项
|
||||
34998 反馈导出时的时间支持精确到分秒
|
||||
@@ -77,11 +88,13 @@
|
||||
35083 执行甘特图支持在图上用连接的方式维护任务关系
|
||||
35861 甘特图全屏样式优化
|
||||
36185 执行甘特图查看任务关系维护按钮、设置按钮、甘特图按钮优化
|
||||
36581 任务工时明细表的横向滚动条置顶显示
|
||||
36618 有编辑他人反馈权限,可以批量编辑他人反馈
|
||||
旗舰版:
|
||||
30432 瀑布项目设计功能类型支持自定义功能
|
||||
34682 资产库可以排序
|
||||
禅道客户端:
|
||||
35639 客户端设置增加“初始化会议状态”的设置项,并自动初始化会议状态
|
||||
35658 去掉客户端设置中消息记录独立窗口的设置项,默认以独立窗口打开
|
||||
修复的Bug
|
||||
26232 执行软件需求列表简单表格下横向滚动条显示遮挡
|
||||
26272 地盘待处理/贡献研发需求列表中,子需求的名称和所属产品未显示title
|
||||
@@ -118,6 +131,8 @@
|
||||
26371 导出的需求,用户名的显示不一致
|
||||
26424 导入用例页面无影响,提示PHPExcel原因
|
||||
26657 不能批量编辑他人反馈
|
||||
25834 删除所有消息和群组后登录喧喧显示“服务器操作失败”
|
||||
25833 删除所有聊天消息和群组系统群仍然有消息
|
||||
|
||||
2022-08-11 17.5
|
||||
完成的需求
|
||||
|
||||
@@ -1463,7 +1463,7 @@ class baseRouter
|
||||
|
||||
/* Check file is encode by ioncube. */
|
||||
$isEncrypted = false;
|
||||
if($isExt)
|
||||
if(strpos($file2Included, 'extension' . DS . $this->config->edition . DS) !== false)
|
||||
{
|
||||
$fp = fopen($file2Included, 'r');
|
||||
$line1 = fgets($fp);
|
||||
|
||||
@@ -191,6 +191,7 @@ class blockModel extends model
|
||||
->leftJoin(TABLE_PRODUCT)->alias('t2')->on("t1.product = t2.id")
|
||||
->where('t1.assignedTo')->eq($this->app->user->account)
|
||||
->andWhere('t1.deleted')->eq(0)
|
||||
->andWhere('t1.status')->ne('closed')
|
||||
->andWhere('t2.deleted')->eq(0)
|
||||
->fetch('count');
|
||||
$data['stories'] = (int)$this->dao->select('count(*) AS count')->from(TABLE_STORY)->alias('t1')
|
||||
|
||||
@@ -7,3 +7,4 @@
|
||||
.select-project-modal .modal-body {right: 15px;}
|
||||
.osContent, .browserContent {margin: 0 0 5px;}
|
||||
.browserContent {margin-left: -4px;}
|
||||
.resolution {white-space: nowrap; overflow: hidden;}
|
||||
|
||||
@@ -1129,6 +1129,7 @@ class bugModel extends model
|
||||
->setDefault('assignedDate', $now)
|
||||
->setDefault('resolvedDate', $now)
|
||||
->setDefault('assignedTo', $oldBug->openedBy)
|
||||
->setDefault('duplicateBug', 0)
|
||||
->removeIF($this->post->resolution != 'duplicate', 'duplicateBug')
|
||||
->stripTags($this->config->bug->editor->resolve['id'], $this->config->allowedTags)
|
||||
->remove('files,labels')
|
||||
|
||||
@@ -265,7 +265,7 @@ if($this->app->tab == 'project') js::set('objectID', $bug->project);
|
||||
</tr>
|
||||
<tr id='duplicateBugBox' <?php if($bug->resolution != 'duplicate') echo "style='display:none'";?>>
|
||||
<th><?php echo $lang->bug->duplicateBug;?></th>
|
||||
<td><?php echo html::select('duplicateBug', $productBugs, $bug->duplicateBug, "class='form-control' placeholder='{$lang->bug->duplicateTip}'");?></td>
|
||||
<td class='required'><?php echo html::select('duplicateBug', $productBugs, $bug->duplicateBug, "class='form-control' placeholder='{$lang->bug->duplicateTip}'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->bug->closedBy;?></th>
|
||||
|
||||
@@ -355,10 +355,10 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->bug->resolution;?></th>
|
||||
<td>
|
||||
<td class='resolution'>
|
||||
<?php
|
||||
echo isset($lang->bug->resolutionList[$bug->resolution]) ? $lang->bug->resolutionList[$bug->resolution] : $bug->resolution;
|
||||
if(isset($bug->duplicateBugTitle)) echo " #$bug->duplicateBug:" . html::a($this->createLink('bug', 'view', "bugID=$bug->duplicateBug", '', true), $bug->duplicateBugTitle, '', "class='iframe' data-width='80%'");
|
||||
if(isset($bug->duplicateBugTitle)) echo " #$bug->duplicateBug:" . html::a($this->createLink('bug', 'view', "bugID=$bug->duplicateBug", '', true), $bug->duplicateBugTitle, '', "title='{$bug->duplicateBugTitle}' class='iframe' data-width='80%'");
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -42,7 +42,10 @@
|
||||
<div class='cell'><?php include '../../common/view/action.html.php';?></div>
|
||||
<div class='main-actions'>
|
||||
<div class="btn-toolbar">
|
||||
<?php common::printBack($this->session->designList);?>
|
||||
<?php
|
||||
$backLink = $this->createLink('design', 'browse', "projectID=$design->project");
|
||||
common::printBack($app->session->designList != false ? $app->session->designList : $backLink);
|
||||
?>
|
||||
<?php if(!isonlybody()) echo "<div class='divider'></div>";?>
|
||||
<?php if(!$design->deleted):?>
|
||||
<?php
|
||||
|
||||
@@ -960,7 +960,7 @@ class docModel extends model
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->config->doc->search['module'] = $queryName;
|
||||
if(isset($queryName)) $this->config->doc->search['module'] = $queryName;
|
||||
$products = $this->product->getPairs('nocode', $this->session->project);
|
||||
$this->config->doc->search['params']['execution']['values'] = array('' => '') + $this->loadModel('execution')->getPairs($this->session->project, 'all', 'noclosed') + array('all' => $this->lang->doc->allExecutions);
|
||||
$this->config->doc->search['params']['lib']['values'] = array('' => '', $libID => ($libID ? $libs[$libID] : 0), 'all' => $this->lang->doclib->all);
|
||||
|
||||
@@ -175,7 +175,7 @@ $config->execution->gantt->linkType['end']['end'] = 2;
|
||||
$config->execution->gantt->linkType['begin']['end'] = 3;
|
||||
|
||||
$config->execution->datatable = new stdclass();
|
||||
if(!isset($config->setCode) or $config->setCode == 1)
|
||||
if((!isset($config->setCode) or $config->setCode == 1) and $config->systemMode == 'new')
|
||||
{
|
||||
$config->execution->datatable->defaultField = array('id', 'name', 'code', 'project', 'PM', 'status', 'progress', 'begin', 'end', 'estimate', 'consumed', 'left', 'burn');
|
||||
}
|
||||
|
||||
@@ -1151,7 +1151,7 @@ class executionModel extends model
|
||||
}
|
||||
|
||||
/* The total workload of the first stage should not exceed 100%. */
|
||||
if($type == 'create' or $oldExecution->grade == 1)
|
||||
if($type == 'create' or (empty($oldExecution) and $oldExecution->grade == 1))
|
||||
{
|
||||
$oldPercentTotal = $this->dao->select('SUM(t2.percent) as total')->from(TABLE_PROJECTPRODUCT)->alias('t1')
|
||||
->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.project=t2.id')
|
||||
@@ -1198,6 +1198,7 @@ class executionModel extends model
|
||||
public function checkBeginAndEndDate($projectID, $begin, $end)
|
||||
{
|
||||
$project = $this->loadModel('project')->getByID($projectID);
|
||||
if(empty($project)) return;
|
||||
|
||||
if($begin < $project->begin) dao::$errors['begin'] = sprintf($this->lang->execution->errorCommonBegin, $project->begin);
|
||||
if($end > $project->end) dao::$errors['end'] = sprintf($this->lang->execution->errorCommonEnd, $project->end);
|
||||
@@ -1463,6 +1464,8 @@ class executionModel extends model
|
||||
*/
|
||||
public function getStatData($projectID = 0, $browseType = 'undone', $productID = 0, $branch = 0, $withTasks = false, $param = '', $orderBy = 'id_asc', $pager = null)
|
||||
{
|
||||
if($projectID) return array();
|
||||
|
||||
/* Construct the query SQL at search executions. */
|
||||
$executionQuery = '';
|
||||
if($browseType == 'bySearch')
|
||||
|
||||
@@ -103,6 +103,7 @@ $lang->misc->feature->themeDesc = '<p>ZenTao 15.0+ a new "Youth Blue" theme
|
||||
$lang->misc->feature->visionsDesc = "<p>The concept of interface has been added since 16.5. Users can deal with R & D affairs in <span style='color: #0c60e1'>[R&D]</span> and daily office affairs in <span style='color: #0c60e1'>[Lite]</span>.</p><p>You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.</p>";
|
||||
$lang->misc->feature->visionsImage = 'theme/default/images/main/visions_en.png';
|
||||
|
||||
$lang->misc->releaseDate['17.6'] = '2022-08-26';
|
||||
$lang->misc->releaseDate['17.5'] = '2022-08-11';
|
||||
$lang->misc->releaseDate['17.4'] = '2022-07-27';
|
||||
$lang->misc->releaseDate['17.3'] = '2022-07-13';
|
||||
@@ -187,6 +188,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
|
||||
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
|
||||
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
|
||||
|
||||
$lang->misc->feature->all['17.6'][] = array('title' => "The processing logic of requirements is optimized, and the permissions of user requirements and soft requirements are split. Gantt chart supports manual drag and drop to manage task relationship. Fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.5'][] = array('title' => "Provide efficient visual statistical tools. Optimize ZenTao performance, the database engine is adjusted from MyISAM to InnoDB. Gantt chart is optimized and upgraded, and the Copy items of the Max version can replicate more information. Fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.4'][] = array('title' => "Optimization of details Page visualization and jumping page logic. Improvement of Kanban function. Optimization of document creating and editing pages. Fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.3'][] = array('title' => "UI optimization of the modules such as statistics and background, the use case library will synchronize the function optimization information. Fix bugs.", 'desc' => '');
|
||||
|
||||
@@ -103,6 +103,7 @@ $lang->misc->feature->themeDesc = '<p>ZenTao 15.0+ a new "Youth Blue" theme
|
||||
$lang->misc->feature->visionsDesc = "<p>The concept of interface has been added since 16.5. Users can deal with R & D affairs in <span style='color: #0c60e1'>[R&D]</span> and daily office affairs in <span style='color: #0c60e1'>[Lite]</span>.</p><p>You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.</p>";
|
||||
$lang->misc->feature->visionsImage = 'theme/default/images/main/visions_en.png';
|
||||
|
||||
$lang->misc->releaseDate['17.6'] = '2022-08-26';
|
||||
$lang->misc->releaseDate['17.5'] = '2022-08-11';
|
||||
$lang->misc->releaseDate['17.4'] = '2022-07-27';
|
||||
$lang->misc->releaseDate['17.3'] = '2022-07-13';
|
||||
@@ -187,6 +188,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
|
||||
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
|
||||
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
|
||||
|
||||
$lang->misc->feature->all['17.6'][] = array('title' => "The processing logic of requirements is optimized, and the permissions of user requirements and soft requirements are split. Gantt chart supports manual drag and drop to manage task relationship. Fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.5'][] = array('title' => "Provide efficient visual statistical tools. Optimize ZenTao performance, the database engine is adjusted from MyISAM to InnoDB. Gantt chart is optimized and upgraded, and the Copy items of the Max version can replicate more information. Fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.4'][] = array('title' => "Optimization of details Page visualization and jumping page logic. Improvement of Kanban function. Optimization of document creating and editing pages. Fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.3'][] = array('title' => "UI optimization of the modules such as statistics and background, the use case library will synchronize the function optimization information. Fix bugs.", 'desc' => '');
|
||||
|
||||
@@ -103,6 +103,7 @@ $lang->misc->feature->themeDesc = '<p>ZenTao 15.0+ a new "Youth Blue" theme
|
||||
$lang->misc->feature->visionsDesc = "<p>The concept of interface has been added since 16.5. Users can deal with R & D affairs in <span style='color: #0c60e1'>[R&D]</span> and daily office affairs in <span style='color: #0c60e1'>[Lite]</span>.</p><p>You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.</p>";
|
||||
$lang->misc->feature->visionsImage = 'theme/default/images/main/visions_en.png';
|
||||
|
||||
$lang->misc->releaseDate['17.6'] = '2022-08-26';
|
||||
$lang->misc->releaseDate['17.5'] = '2022-08-11';
|
||||
$lang->misc->releaseDate['17.4'] = '2022-07-27';
|
||||
$lang->misc->releaseDate['17.3'] = '2022-07-13';
|
||||
@@ -187,6 +188,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
|
||||
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
|
||||
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
|
||||
|
||||
$lang->misc->feature->all['17.6'][] = array('title' => "The processing logic of requirements is optimized, and the permissions of user requirements and soft requirements are split. Gantt chart supports manual drag and drop to manage task relationship. Fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.5'][] = array('title' => "Provide efficient visual statistical tools. Optimize ZenTao performance, the database engine is adjusted from MyISAM to InnoDB. Gantt chart is optimized and upgraded, and the Copy items of the Max version can replicate more information. Fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.4'][] = array('title' => "Optimization of details Page visualization and jumping page logic. Improvement of Kanban function. Optimization of document creating and editing pages. Fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.3'][] = array('title' => "UI optimization of the modules such as statistics and background, the use case library will synchronize the function optimization information. Fix bugs.", 'desc' => '');
|
||||
|
||||
@@ -103,6 +103,7 @@ $lang->misc->feature->themeDesc = "<p>禅道15系列上线了全新的“
|
||||
$lang->misc->feature->visionsDesc = "<p>从16.5开始增加了界面概念,用户可以在<span style='color:#0c60e1'>[研发综合界面]</span>中处理研发事务、在<span style='color:#0c60e1'>[迅捷界面]</span>处理日常办公事务。</p><p>在头像右侧即可查看当前所处界面,点击当前界面名称可查看和切换其他的界面。</p>";
|
||||
$lang->misc->feature->visionsImage = 'theme/default/images/main/visions.png';
|
||||
|
||||
$lang->misc->releaseDate['17.6'] = '2022-08-26';
|
||||
$lang->misc->releaseDate['17.5'] = '2022-08-11';
|
||||
$lang->misc->releaseDate['17.4'] = '2022-07-27';
|
||||
$lang->misc->releaseDate['17.3'] = '2022-07-13';
|
||||
@@ -187,6 +188,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
|
||||
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
|
||||
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
|
||||
|
||||
$lang->misc->feature->all['17.6'][] = array('title' => '优化了需求的处理逻辑,拆分了用需和软需的权限。甘特图支持手动拖拽维护任务关系。修复Bug。', 'desc' => '');
|
||||
$lang->misc->feature->all['17.5'][] = array('title' => '提供高效的可视化统计工具。优化禅道性能,数据库引擎从MyISAM调整为InnoDB。甘特图优化升级,旗舰版的复制项目可以复制任务等更多信息。修复Bug。', 'desc' => '');
|
||||
$lang->misc->feature->all['17.4'][] = array('title' => '详情页面的视觉优化和部分页面跳转逻辑优化。看板功能完善。文档创建和编辑页面优化。修复Bug。', 'desc' => '');
|
||||
$lang->misc->feature->all['17.3'][] = array('title' => '统计、后台等模块的UI优化,用例库同步用例信息功能优化。修复Bug。', 'desc' => '');
|
||||
|
||||
@@ -8,3 +8,5 @@
|
||||
#switchButton {background: #fff !important;}
|
||||
.panel-actions {position: relative; padding: 0;}
|
||||
.panel-actions .btn-icon {padding-left: 7px;}
|
||||
[lang^=de] .c-pri {width: 69px;}
|
||||
[lang^=fr] .c-pri {width: 82px;}
|
||||
|
||||
@@ -458,7 +458,7 @@ $projectIDParam = $isProjectStory ? "projectID=$projectID&" : '';
|
||||
if($withSearch) echo "<div class='menu-search'><div class='input-group input-group-sm'><input type='text' class='form-control' placeholder=''><span class='input-group-addon'><i class='icon-search'></i></span></div></div>";
|
||||
echo '</div></li>';
|
||||
}
|
||||
else
|
||||
elseif($this->session->currentProductType and $this->session->currentProductType != 'normal' and $productID)
|
||||
{
|
||||
$class= "class='disabled'";
|
||||
echo "<li $class>" . html::a('javascript:;', $lang->product->branchName[$this->session->currentProductType], '', $class) . '</li>';
|
||||
|
||||
@@ -574,8 +574,8 @@ class programModel extends model
|
||||
->beginIF($browseType == 'bysearch')->andWhere($query)->fi()
|
||||
->beginIF($this->config->systemMode == 'new')->andWhere('t1.type')->eq('project')->fi()
|
||||
->beginIF($this->config->systemMode == 'new' and ($this->cookie->involved or $involved))->andWhere('t2.type')->eq('project')->fi()
|
||||
->beginIF(!in_array($browseType, array('all', 'undone', 'bysearch', 'review'), true))->andWhere('t1.status')->eq($browseType)->fi()
|
||||
->beginIF($browseType == 'undone')->andWhere('t1.status')->in('wait,doing')->fi()
|
||||
->beginIF(!in_array($browseType, array('all', 'undone', 'bysearch', 'review', 'unclosed'), true))->andWhere('t1.status')->eq($browseType)->fi()
|
||||
->beginIF($browseType == 'undone' or $browseType = 'unclosed')->andWhere('t1.status')->in('wait,doing')->fi()
|
||||
->beginIF($browseType == 'review')
|
||||
->andWhere("FIND_IN_SET('{$this->app->user->account}', t1.reviewers)")
|
||||
->andWhere('t1.reviewStatus')->eq('doing')
|
||||
@@ -1570,10 +1570,10 @@ class programModel extends model
|
||||
$menu .= "<div class='btn-group'>";
|
||||
$menu .= "<button type='button' class='btn dropdown-toggle' data-toggle='dropdown' title='{$this->lang->more}'><i class='icon-more-alt'></i></button>";
|
||||
$menu .= "<ul class='dropdown-menu pull-right text-center' role='menu'>";
|
||||
$menu .= $this->buildMenu('project', 'manageProducts', "$params&from=program", $program, $type, 'link', '', '', '', "data-app={$this->app->tab}");
|
||||
$menu .= $this->buildMenu('project', 'manageProducts', "$params&from=program", $program, $type, 'link', '', '', '', "data-app='project'");
|
||||
|
||||
$disabledWhitelist = $program->acl == 'open' ? " disabled='disabled' style='pointer-events: none;'" : '';
|
||||
$menu .= $this->buildMenu('project', 'whitelist', "$params&module=project&from=browse", $program, $type, 'shield-check', '', '', '', "data-app='project'" . $disabledWhitelist);
|
||||
$menu .= $this->buildMenu('project', 'whitelist', "$params&module=project&from=browse", $program, $type, 'shield-check', '', '', '', "data-app='project'" . $disabledWhitelist);
|
||||
if(common::hasPriv('project','delete'))
|
||||
{
|
||||
$menu .= $this->buildMenu("project", "delete", $params, $program, $type, 'trash', 'hiddenwin', '', '', "data-group='program'", $this->lang->delete);
|
||||
|
||||
+19
-21
@@ -363,28 +363,26 @@ class project extends control
|
||||
$programTitle = $this->loadModel('setting')->getItem('owner=' . $this->app->user->account . '&module=project&key=programTitle');
|
||||
$projectStats = $this->loadModel('program')->getProjectStats($programID, $browseType, $queryID, $orderBy, $pager, $programTitle);
|
||||
|
||||
$allProjectsNum = $this->loadModel('program')->getProjectStats($programID, 'all');
|
||||
$this->view->allProjectsNum = $allProjectsNum;
|
||||
$this->lang->project->statusList['delay'] = $this->lang->project->delay;
|
||||
|
||||
$this->view->title = $this->lang->project->browse;
|
||||
$this->view->position[] = $this->lang->project->browse;
|
||||
|
||||
$this->view->projectStats = $projectStats;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->programID = $programID;
|
||||
$this->view->program = $this->program->getByID($programID);
|
||||
$this->view->programTree = $this->project->getTreeMenu(0, array('projectmodel', 'createManageLink'), 0, 'list');
|
||||
$this->view->programs = array('0' => '') + $this->program->getParentPairs();
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter|pofirst|nodeleted');
|
||||
$this->view->userIdPairs = $this->loadModel('user')->getPairs('nodeleted|showid');
|
||||
$this->view->usersAvatar = $this->user->getAvatarPairs();
|
||||
$this->view->browseType = $browseType;
|
||||
$this->view->projectType = $projectType;
|
||||
$this->view->param = $param;
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->recTotal = $recTotal;
|
||||
$this->view->recPerPage = $recPerPage;
|
||||
$this->view->pageID = $pageID;
|
||||
$this->view->title = $this->lang->project->browse;
|
||||
$this->view->projectStats = $projectStats;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->programID = $programID;
|
||||
$this->view->program = $this->program->getByID($programID);
|
||||
$this->view->programTree = $this->project->getTreeMenu(0, array('projectmodel', 'createManageLink'), 0, 'list');
|
||||
$this->view->programs = array('0' => '') + $this->program->getParentPairs();
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter|pofirst|nodeleted');
|
||||
$this->view->userIdPairs = $this->loadModel('user')->getPairs('nodeleted|showid');
|
||||
$this->view->usersAvatar = $this->user->getAvatarPairs();
|
||||
$this->view->browseType = $browseType;
|
||||
$this->view->projectType = $projectType;
|
||||
$this->view->param = $param;
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->recTotal = $recTotal;
|
||||
$this->view->recPerPage = $recPerPage;
|
||||
$this->view->pageID = $pageID;
|
||||
$this->view->allProjectsNum = $this->loadModel('program')->getProjectStats($programID, 'all');
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ $lang->project->budgetNumber = '『Budget』must be numbers.';
|
||||
$lang->project->budgetGe0 = '『Budget』must be greater than or equal to 0.';
|
||||
$lang->project->allProjects = 'All Projects';
|
||||
$lang->project->ignore = 'Ignore';
|
||||
$lang->project->delay = 'Delayed';
|
||||
|
||||
/* Fields. */
|
||||
$lang->project->common = 'Project';
|
||||
@@ -278,7 +279,6 @@ $lang->project->statusList['wait'] = 'Waiting';
|
||||
$lang->project->statusList['doing'] = 'Doing';
|
||||
$lang->project->statusList['suspended'] = 'Suspended';
|
||||
$lang->project->statusList['closed'] = 'Closed';
|
||||
$lang->project->statusList['delay'] = 'Delayed';
|
||||
|
||||
$lang->project->endList[31] = 'One month';
|
||||
$lang->project->endList[93] = 'Trimester';
|
||||
|
||||
@@ -64,6 +64,7 @@ $lang->project->budgetNumber = '『Budget』must be numbers.';
|
||||
$lang->project->budgetGe0 = '『Budget』must be greater than or equal to 0.';
|
||||
$lang->project->allProjects = 'All Projects';
|
||||
$lang->project->ignore = 'Ignore';
|
||||
$lang->project->delay = 'Delayed';
|
||||
|
||||
/* Fields. */
|
||||
$lang->project->common = 'Project';
|
||||
@@ -278,7 +279,6 @@ $lang->project->statusList['wait'] = 'Waiting';
|
||||
$lang->project->statusList['doing'] = 'Doing';
|
||||
$lang->project->statusList['suspended'] = 'Suspended';
|
||||
$lang->project->statusList['closed'] = 'Closed';
|
||||
$lang->project->statusList['delay'] = 'Delayed';
|
||||
|
||||
$lang->project->endList[31] = 'One month';
|
||||
$lang->project->endList[93] = 'Trimester';
|
||||
|
||||
@@ -64,6 +64,7 @@ $lang->project->budgetNumber = '『Budget』must be numbers.';
|
||||
$lang->project->budgetGe0 = '『Budget』must be greater than or equal to 0.';
|
||||
$lang->project->allProjects = 'All Projects';
|
||||
$lang->project->ignore = 'Ignorer';
|
||||
$lang->project->delay = 'Delayed';
|
||||
|
||||
/* Fields. */
|
||||
$lang->project->common = 'Projets';
|
||||
@@ -278,7 +279,6 @@ $lang->project->statusList['wait'] = 'Waiting';
|
||||
$lang->project->statusList['doing'] = 'Doing';
|
||||
$lang->project->statusList['suspended'] = 'Suspended';
|
||||
$lang->project->statusList['closed'] = 'Closed';
|
||||
$lang->project->statusList['delay'] = 'Delayed';
|
||||
|
||||
$lang->project->endList[31] = 'One month';
|
||||
$lang->project->endList[93] = 'Trimester';
|
||||
|
||||
@@ -64,6 +64,7 @@ $lang->project->budgetNumber = '『预算』金额必须为数字。';
|
||||
$lang->project->budgetGe0 = '『预算』金额必须大于等于0。';
|
||||
$lang->project->allProjects = '所有项目';
|
||||
$lang->project->ignore = '忽略';
|
||||
$lang->project->delay = '已延期';
|
||||
|
||||
/* Fields. */
|
||||
$lang->project->common = '项目';
|
||||
@@ -278,7 +279,6 @@ $lang->project->statusList['wait'] = '未开始';
|
||||
$lang->project->statusList['doing'] = '进行中';
|
||||
$lang->project->statusList['suspended'] = '已挂起';
|
||||
$lang->project->statusList['closed'] = '已关闭';
|
||||
$lang->project->statusList['delay'] = '已延期';
|
||||
|
||||
$lang->project->endList[31] = '一个月';
|
||||
$lang->project->endList[93] = '三个月';
|
||||
|
||||
@@ -1046,7 +1046,7 @@ class story extends control
|
||||
{
|
||||
$storyProduct = $products[$story->product];
|
||||
$branch = $storyProduct->type == 'branch' ? ($story->branch > 0 ? $story->branch : '0') : 'all';
|
||||
if(!isset($productStoryList[$story->product][$story->branch])) $productStoryList[$story->product][$story->branch] = $this->story->getProductStoryPairs($story->product, $branch, 0, 'all', 'id_desc', 0, '');
|
||||
if(!isset($productStoryList[$story->product][$story->branch])) $productStoryList[$story->product][$story->branch] = $this->story->getProductStoryPairs($story->product, $branch, 0, 'all', 'id_desc', 0, '', $story->type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1243,7 +1243,6 @@ class story extends control
|
||||
$buildApp = $tab == 'product' ? 'project' : $tab;
|
||||
$releaseApp = $tab == 'execution' ? 'product' : $tab;
|
||||
$this->session->set('productList', $uri . "#app={$tab}", 'product');
|
||||
$this->session->set('releaseList', $uri, $releaseApp);
|
||||
$this->session->set('buildList', $uri, $buildApp);
|
||||
|
||||
$storyID = (int)$storyID;
|
||||
@@ -1483,7 +1482,7 @@ class story extends control
|
||||
$this->view->product = $product;
|
||||
$this->view->story = $story;
|
||||
$this->view->actions = $this->action->getList('story', $storyID);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('nodeleted|noletter', "$story->lastEditedBy,$story->openedBy");
|
||||
$this->view->users = $this->loadModel('user')->getPairs('nodeleted|noclosed', "$story->lastEditedBy,$story->openedBy");
|
||||
$this->view->reviewers = $reviewers;
|
||||
$this->view->isLastOne = count(array_diff(array_keys($reviewers), explode(',', $story->reviewedBy))) == 1 ? true : false;
|
||||
|
||||
@@ -1686,7 +1685,7 @@ class story extends control
|
||||
unset($reasonList['subdivided']);
|
||||
|
||||
$branch = $product->type == 'branch' ? ($story->branch > 0 ? $story->branch : '0') : 'all';
|
||||
$productStories = $this->story->getProductStoryPairs($story->product, $branch, 0, 'all', 'id_desc', 0, '');
|
||||
$productStories = $this->story->getProductStoryPairs($story->product, $branch, 0, 'all', 'id_desc', 0, '', $storyType);
|
||||
|
||||
$this->view->title = $this->lang->story->close . "STORY" . $this->lang->colon . $story->title;
|
||||
$this->view->position[] = html::a($this->createLink('product', 'browse', "product=$product->id&branch=$story->branch"), $product->name);
|
||||
@@ -1738,7 +1737,7 @@ class story extends control
|
||||
|
||||
$storyProduct = isset($productList[$story->product]) ? $productList[$story->product] : $this->product->getByID($story->product);
|
||||
$branch = $storyProduct->type == 'branch' ? ($story->branch > 0 ? $story->branch : '0') : 'all';
|
||||
if(!isset($productStoryList[$story->product][$story->branch])) $productStoryList[$story->product][$story->branch] = $this->story->getProductStoryPairs($story->product, $branch, 0, 'all', 'id_desc', 0, '');
|
||||
if(!isset($productStoryList[$story->product][$story->branch])) $productStoryList[$story->product][$story->branch] = $this->story->getProductStoryPairs($story->product, $branch, 0, 'all', 'id_desc', 0, '', $story->type);
|
||||
}
|
||||
|
||||
if($this->post->comments)
|
||||
@@ -1879,7 +1878,7 @@ class story extends control
|
||||
$storyGroup = array();
|
||||
foreach($stories as $story)
|
||||
{
|
||||
if(strpos('draft,closed', $story->status) !== false) continue;
|
||||
if(strpos('draft,reviewing,changing,closed', $story->status) !== false) continue;
|
||||
if(isset($storyGroup[$story->module])) continue;
|
||||
$storyGroup[$story->module] = $this->story->getExecutionStoryPairs($executionID, 0, 'all', $story->module, 'short', 'active');
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
.thWidth {width: 80px !important;}
|
||||
.thWidth {width: 95px !important;}
|
||||
|
||||
@@ -12,3 +12,4 @@
|
||||
.linkStoryTr > th {width: 90px;}
|
||||
.linkStoryTr > td {padding-left: 0px !important;}
|
||||
.removeButton {margin-left: -10px;}
|
||||
.resolution {white-space: nowrap; overflow: hidden;}
|
||||
|
||||
@@ -443,24 +443,19 @@ $lang->story->categoryList['experience'] = 'Experience';
|
||||
$lang->story->categoryList['improve'] = 'Improve';
|
||||
$lang->story->categoryList['other'] = 'Other';
|
||||
|
||||
$lang->story->changeTip = 'This Story is under review and cannot be changed.';
|
||||
$lang->story->changeTip = 'Only active can be changed.';
|
||||
|
||||
$lang->story->reviewTip = array();
|
||||
$lang->story->reviewTip['active'] = 'The Story is already active,no review requirements.';
|
||||
$lang->story->reviewTip['notReviewer'] = 'You are not the reviewer of this Story and cannot perform review operations.';
|
||||
$lang->story->reviewTip['reviewed'] = 'Reviewed';
|
||||
$lang->story->reviewTip['recalled'] = 'This Story has been withdrawn from review and cannot be reviewed.';
|
||||
|
||||
$lang->story->recallTip = array();
|
||||
$lang->story->recallTip['actived'] = 'The Story has not initiated a review process and no undo action is required.';
|
||||
$lang->story->recallTip['recalled'] = 'This Story has been withdrawn from review and cannot be cancelled.';
|
||||
$lang->story->recallTip['reviewed'] = 'The review process has been started and cannot be cancelled.';
|
||||
$lang->story->recallTip['notOpenedBy'] = 'You are not the Story creator and cannot cancel the operation.';
|
||||
$lang->story->recallTip['actived'] = 'The Story has not initiated a review process and no undo action is required.';
|
||||
|
||||
$lang->story->subDivideTip = array();
|
||||
$lang->story->subDivideTip['subStory'] = 'The Sub-stories cannot be subdivided.';
|
||||
$lang->story->subDivideTip['planned'] = 'The Story has been planned and cannot be subdivided.';
|
||||
$lang->story->subDivideTip['projected'] = 'The Story has been initiated and cannot be subdivided.';
|
||||
$lang->story->subDivideTip['notWait'] = 'The Story has been %s and cannot be subdivided.';
|
||||
$lang->story->subDivideTip['notActive'] = 'The Story is not active and cannot be subdivided.';
|
||||
|
||||
$lang->story->featureBar['browse']['all'] = $lang->all;
|
||||
|
||||
@@ -443,24 +443,19 @@ $lang->story->categoryList['experience'] = 'Experience';
|
||||
$lang->story->categoryList['improve'] = 'Improve';
|
||||
$lang->story->categoryList['other'] = 'Other';
|
||||
|
||||
$lang->story->changeTip = 'This Story is under review and cannot be changed.';
|
||||
$lang->story->changeTip = 'Only active can be changed.';
|
||||
|
||||
$lang->story->reviewTip = array();
|
||||
$lang->story->reviewTip['active'] = 'The Story is already active,no review requirements.';
|
||||
$lang->story->reviewTip['notReviewer'] = 'You are not the reviewer of this Story and cannot perform review operations.';
|
||||
$lang->story->reviewTip['reviewed'] = 'Reviewed';
|
||||
$lang->story->reviewTip['recalled'] = 'This Story has been withdrawn from review and cannot be reviewed.';
|
||||
|
||||
$lang->story->recallTip = array();
|
||||
$lang->story->recallTip['actived'] = 'The Story has not initiated a review process and no undo action is required.';
|
||||
$lang->story->recallTip['recalled'] = 'This Story has been withdrawn from review and cannot be cancelled.';
|
||||
$lang->story->recallTip['reviewed'] = 'The review process has been started and cannot be cancelled.';
|
||||
$lang->story->recallTip['notOpenedBy'] = 'You are not the Story creator and cannot cancel the operation.';
|
||||
$lang->story->recallTip['actived'] = 'The Story has not initiated a review process and no undo action is required.';
|
||||
|
||||
$lang->story->subDivideTip = array();
|
||||
$lang->story->subDivideTip['subStory'] = 'The Sub-stories cannot be subdivided.';
|
||||
$lang->story->subDivideTip['planned'] = 'The Story has been planned and cannot be subdivided.';
|
||||
$lang->story->subDivideTip['projected'] = 'The Story has been initiated and cannot be subdivided.';
|
||||
$lang->story->subDivideTip['notWait'] = 'The Story has been %s and cannot be subdivided.';
|
||||
$lang->story->subDivideTip['notActive'] = 'The Story is not active and cannot be subdivided.';
|
||||
|
||||
$lang->story->featureBar['browse']['all'] = $lang->all;
|
||||
|
||||
@@ -443,24 +443,19 @@ $lang->story->categoryList['experience'] = 'Experience';
|
||||
$lang->story->categoryList['improve'] = 'Improve';
|
||||
$lang->story->categoryList['other'] = 'Other';
|
||||
|
||||
$lang->story->changeTip = 'Cette Story est en cours de vérification et ne peut pas être modifiée.';
|
||||
$lang->story->changeTip = "Seules les exigences de l'état actif peuvent être modifiées.";
|
||||
|
||||
$lang->story->reviewTip = array();
|
||||
$lang->story->reviewTip['active'] = "Cette Story est déjà active, il n'y a pas de demande de révision.";
|
||||
$lang->story->reviewTip['notReviewer'] = "Vous n'êtes pas l'évaluateur de cette Story et ne pouvez pas effectuer d'opérations d'évaluation.";
|
||||
$lang->story->reviewTip['reviewed'] = "Révisé";
|
||||
$lang->story->reviewTip['recalled'] = "Cette Story a été retirée pour vérification, et l'opération de révision ne peut pas être effectuée.";
|
||||
|
||||
$lang->story->recallTip = array();
|
||||
$lang->story->recallTip['actived'] = "Aucun processus de révision n'a été lancé pour cette Story, et il n'est pas nécessaire de révoquer l'opération.";
|
||||
$lang->story->recallTip['recalled'] = "Cette Story a été retirée pour vérification, et l'opération ne peut pas être annulée.";
|
||||
$lang->story->recallTip['reviewed'] = "Il est entré dans le processus de révision, et l'opération ne peut pas être annulée.";
|
||||
$lang->story->recallTip['notOpenedBy'] = "Vous n'êtes pas l'initiateur de la révision et vous ne pouvez pas annuler l'opération.";
|
||||
$lang->story->recallTip['actived'] = "Aucun processus de révision n'a été lancé pour cette Story, et il n'est pas nécessaire de révoquer l'opération.";
|
||||
|
||||
$lang->story->subDivideTip = array();
|
||||
$lang->story->subDivideTip['subStory'] = 'Les sous-stories ne peuvent pas être décomposées.';
|
||||
$lang->story->subDivideTip['planned'] = 'Cette Story est planifiée et ne peut être subdivisée.';
|
||||
$lang->story->subDivideTip['projected'] = 'Cette Story a été créée et ne peut être subdivisée.';
|
||||
$lang->story->subDivideTip['notWait'] = "L'exigence %s ne peut pas être subdivisée.";
|
||||
$lang->story->subDivideTip['notActive'] = "Cette Story n'est pas active et ne peut être subdivisée.";
|
||||
|
||||
$lang->story->featureBar['browse']['all'] = $lang->all;
|
||||
|
||||
@@ -435,24 +435,19 @@ $lang->story->categoryList['experience'] = 'Experience';
|
||||
$lang->story->categoryList['improve'] = 'Improve';
|
||||
$lang->story->categoryList['other'] = 'Other';
|
||||
|
||||
$lang->story->changeTip = 'This Story is under review and cannot be changed.';
|
||||
$lang->story->changeTip = 'Only active can be changed.';
|
||||
|
||||
$lang->story->reviewTip = array();
|
||||
$lang->story->reviewTip['active'] = 'The Story is already active,no review requirements.';
|
||||
$lang->story->reviewTip['notReviewer'] = 'You are not the reviewer of this Story and cannot perform review operations.';
|
||||
$lang->story->reviewTip['reviewed'] = 'Reviewed';
|
||||
$lang->story->reviewTip['recalled'] = 'This Story has been withdrawn from review and cannot be reviewed.';
|
||||
|
||||
$lang->story->recallTip = array();
|
||||
$lang->story->recallTip['actived'] = 'The Story has not initiated a review process and no undo action is required.';
|
||||
$lang->story->recallTip['recalled'] = 'This Story has been withdrawn from review and cannot be cancelled.';
|
||||
$lang->story->recallTip['reviewed'] = 'The review process has been started and cannot be cancelled.';
|
||||
$lang->story->recallTip['notOpenedBy'] = 'You are not the Story creator and cannot cancel the operation.';
|
||||
$lang->story->recallTip['actived'] = 'The Story has not initiated a review process and no undo action is required.';
|
||||
|
||||
$lang->story->subDivideTip = array();
|
||||
$lang->story->subDivideTip['subStory'] = 'The Sub-stories cannot be subdivided.';
|
||||
$lang->story->subDivideTip['planned'] = 'The Story has been planned and cannot be subdivided.';
|
||||
$lang->story->subDivideTip['projected'] = 'The Story has been initiated and cannot be subdivided.';
|
||||
$lang->story->subDivideTip['notWait'] = 'The Story has been %s and cannot be subdivided.';
|
||||
$lang->story->subDivideTip['notActive'] = 'The Story is not active and cannot be subdivided.';
|
||||
|
||||
$lang->story->featureBar['browse']['all'] = $lang->all;
|
||||
|
||||
@@ -443,24 +443,19 @@ $lang->story->categoryList['experience'] = '体验';
|
||||
$lang->story->categoryList['improve'] = '改进';
|
||||
$lang->story->categoryList['other'] = '其他';
|
||||
|
||||
$lang->story->changeTip = '该需求正在评审中,无法进行变更';
|
||||
$lang->story->changeTip = '只有激活状态的需求,才能进行变更';
|
||||
|
||||
$lang->story->reviewTip = array();
|
||||
$lang->story->reviewTip['active'] = '该需求已是激活状态,无需评审';
|
||||
$lang->story->reviewTip['notReviewer'] = '您不是该需求的评审人员,无法进行评审操作';
|
||||
$lang->story->reviewTip['reviewed'] = '您已评审';
|
||||
$lang->story->reviewTip['recalled'] = '该需求已撤销评审,无法进行评审操作';
|
||||
|
||||
$lang->story->recallTip = array();
|
||||
$lang->story->recallTip['actived'] = '该需求未发起评审流程,无需撤销操作';
|
||||
$lang->story->recallTip['recalled'] = '该需求已经撤销评审,无法进行撤销操作';
|
||||
$lang->story->recallTip['reviewed'] = '已进入评审流程,无法进行撤销操作';
|
||||
$lang->story->recallTip['notOpenedBy'] = '您不是需求创建者,无法进行撤销操作';
|
||||
$lang->story->recallTip['actived'] = '该需求未发起评审流程,无需撤销操作';
|
||||
|
||||
$lang->story->subDivideTip = array();
|
||||
$lang->story->subDivideTip['subStory'] = '子需求无法细分';
|
||||
$lang->story->subDivideTip['planned'] = '该需求已计划,无法进行细分操作';
|
||||
$lang->story->subDivideTip['projected'] = '该需求已立项,无法进行细分操作';
|
||||
$lang->story->subDivideTip['notWait'] = '该需求%s,无法进行细分操作';
|
||||
$lang->story->subDivideTip['notActive'] = '需求不是激活状态,无法进行细分操作';
|
||||
|
||||
$lang->story->featureBar['browse']['all'] = $lang->all;
|
||||
|
||||
+12
-23
@@ -786,7 +786,7 @@ class storyModel extends model
|
||||
|
||||
if(strpos('draft,changing', $oldStory->status) !== false and $this->checkForceReview() and empty($_POST['reviewer']))
|
||||
{
|
||||
dao::$errors[] = $this->lang->story->errorEmptyReviewedBy;
|
||||
dao::$errors[] = $this->lang->story->notice->reviewerNotEmpty;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1744,6 +1744,7 @@ class storyModel extends model
|
||||
->setDefault('closedDate', $now)
|
||||
->setDefault('closedBy', $this->app->user->account)
|
||||
->setDefault('assignedDate', $now)
|
||||
->setDefault('duplicateStory', 0)
|
||||
->stripTags($this->config->story->editor->close['id'], $this->config->allowedTags)
|
||||
->removeIF($this->post->closedReason != 'duplicate', 'duplicateStory')
|
||||
->removeIF($this->post->closedReason != 'subdivided', 'childStories')
|
||||
@@ -3009,7 +3010,7 @@ class storyModel extends model
|
||||
if($excludeStories) $storyQuery = $storyQuery . ' AND `id` NOT ' . helper::dbIN($excludeStories);
|
||||
if($this->app->moduleName == 'productplan') $storyQuery .= " AND `status` NOT IN ('closed') AND `parent` >= 0 ";
|
||||
$allBranch = "`branch` = 'all'";
|
||||
if($executionID != '')
|
||||
if(!empty($executionID))
|
||||
{
|
||||
$normalProducts = array();
|
||||
$branchProducts = array();
|
||||
@@ -4209,7 +4210,7 @@ class storyModel extends model
|
||||
if($story->URChanged) return $this->buildMenu('story', 'processStoryChange', $params, $story, $type, 'ok', '', 'iframe', true, '', $this->lang->confirm);
|
||||
|
||||
$isClick = $this->isClickable($story, 'change');
|
||||
$title = (!$isClick and $story->status != 'closed' and $story->status != 'draft') ? $this->lang->story->changeTip : '';
|
||||
$title = $isClick ? '' : $this->lang->story->changeTip;
|
||||
$menu .= $this->buildMenu('story', 'change', $params . "&from=$story->from&storyType=$story->type", $story, $type, 'alter', '', 'showinonlybody', false, '', $title);
|
||||
|
||||
if(strpos('draft,changing', $story->status) !== false)
|
||||
@@ -4234,30 +4235,19 @@ class storyModel extends model
|
||||
{
|
||||
$title = $this->lang->story->reviewTip['notReviewer'];
|
||||
}
|
||||
elseif(empty($storyReviewer))
|
||||
{
|
||||
$title = $this->lang->story->reviewTip['recalled'];
|
||||
}
|
||||
}
|
||||
$menu .= $this->buildMenu('story', 'review', $params . "&from=$story->from&storyType=$story->type", $story, $type, 'search', '', 'showinonlybody', false, '', $title);
|
||||
}
|
||||
|
||||
$isClick = $this->isClickable($story, 'recall');
|
||||
$title = $story->status == 'changing' ? $this->lang->story->recallChange : $this->lang->story->recall;
|
||||
if(!$isClick and $story->status != 'closed')
|
||||
{
|
||||
if($story->status == 'draft' and empty($storyReviewer)) $title = $this->lang->story->recallTip['recalled'];
|
||||
if($story->status == 'draft' and !empty($storyReviewer)) $title = $this->lang->story->recallTip['reviewed'];
|
||||
if(empty($story->reviewedBy) and strpos('draft,changing', $story->status) !== false and !empty($story->reviewer) and $this->app->user->account != $story->openedBy) $title = $this->lang->story->recallTip['notOpenedBy'];
|
||||
if($story->status == 'active' and empty($story->reviewer)) $title = $this->lang->story->recallTip['actived'];
|
||||
}
|
||||
|
||||
$menu .= $this->buildMenu('story', 'recall', $params . "&from=list&confirm=no&storyType=$story->type", $story, $type, 'undo', 'hiddenwin', 'showinonlybody', false, '', $title);
|
||||
$title = $isClick ? $title : $this->lang->story->recallTip['actived'];
|
||||
$menu .= $this->buildMenu('story', 'recall', $params . "&from=list&confirm=no&storyType=$story->type", $story, $type, 'undo', 'hiddenwin', 'showinonlybody', false, '', $title);
|
||||
|
||||
$menu .= $this->buildMenu('story', 'close', $params . "&from=&storyType=$story->type", $story, $type, '', '', 'iframe', true);
|
||||
$menu .= $this->buildMenu('story', 'edit', $params . "&kanbanGroup=default&storyType=$story->type", $story, $type, '', '', 'showinonlybody');
|
||||
|
||||
$tab = $this->app->tab == 'project' ? 'project' : 'qa';
|
||||
$tab = $this->app->tab == 'project' ? 'project' : 'qa';
|
||||
if($story->type != 'requirement' and $this->config->vision != 'lite') $menu .= $this->buildMenu('story', 'createCase', "productID=$story->product&branch=$story->branch&module=0&from=¶m=0&$params", $story, $type, 'sitemap', '', 'showinonlybody', false, "data-app='$tab'");
|
||||
|
||||
if($this->app->rawModule != 'projectstory' OR $this->config->vision == 'lite')
|
||||
@@ -4273,8 +4263,7 @@ class storyModel extends model
|
||||
else
|
||||
{
|
||||
if($story->status != 'active') $title = $this->lang->story->subDivideTip['notActive'];
|
||||
if(!empty($story->plan)) $title = $this->lang->story->subDivideTip['planned'];
|
||||
if($story->stage == 'projected') $title = $this->lang->story->subDivideTip['projected'];
|
||||
if($story->status == 'active' and $story->stage != 'wait') $title = sprintf($this->lang->story->subDivideTip['notWait'], zget($this->lang->story->stageList, $story->stage));
|
||||
}
|
||||
}
|
||||
$menu .= $this->buildMenu('story', 'batchCreate', "productID=$story->product&branch=$story->branch&module=$story->module&$params&executionID=0&plan=0&storyType=story", $story, $type, 'split', '', 'showinonlybody', '', '', $title);
|
||||
@@ -4319,20 +4308,20 @@ class storyModel extends model
|
||||
|
||||
if(common::hasPriv('testcase', 'create', $story))
|
||||
{
|
||||
$link = helper::createLink('testcase', 'create', "productID=$story->product&branch=$story->branch&moduleID=0&from=¶m=0&$params", '', true);
|
||||
$link = helper::createLink('testcase', 'create', "productID=$story->product&branch=$story->branch&moduleID=0&from=¶m=0&$params", '', true);
|
||||
$menu .= "<li>" . html::a($link, $this->lang->testcase->create, '', $misc) . "</li>";
|
||||
}
|
||||
|
||||
if(common::hasPriv('testcase', 'batchCreate'))
|
||||
{
|
||||
$link = helper::createLink('testcase', 'batchCreate', "productID=$story->product&branch=$story->branch&moduleID=0&$params", '', true);
|
||||
$link = helper::createLink('testcase', 'batchCreate', "productID=$story->product&branch=$story->branch&moduleID=0&$params", '', true);
|
||||
$menu .= "<li>" . html::a($link, $this->lang->testcase->batchCreate, '', $misc) . "</li>";
|
||||
}
|
||||
|
||||
$menu .= "</ul></div>";
|
||||
}
|
||||
|
||||
if($this->app->tab == 'execution' and strpos('draft,closed', $story->status) === false) $menu .= $this->buildMenu('task', 'create', "execution={$this->session->execution}&{$params}&moduleID=$story->module", $story, $type, 'plus', '', 'showinonly body');
|
||||
if($this->app->tab == 'execution' and $story->status == 'active') $menu .= $this->buildMenu('task', 'create', "execution={$this->session->execution}&{$params}&moduleID=$story->module", $story, $type, 'plus', '', 'showinonlybody');
|
||||
|
||||
$menu .= "<div class='divider'></div>";
|
||||
$menu .= $this->buildFlowMenu('story', $story, $type, 'direct');
|
||||
@@ -4377,7 +4366,7 @@ class storyModel extends model
|
||||
}
|
||||
|
||||
$this->lang->task->create = $this->lang->execution->wbs;
|
||||
$toTaskDisabled = strpos('draft,closed', $story->status) !== false ? 'disabled' : '';
|
||||
$toTaskDisabled = $story->status == 'active' ? '' : 'disabled';
|
||||
if(commonModel::isTutorialMode())
|
||||
{
|
||||
$wizardParams = helper::safe64Encode($param);
|
||||
|
||||
@@ -377,12 +377,12 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->closedReason;?></th>
|
||||
<td>
|
||||
<td class='resolution'>
|
||||
<?php
|
||||
if($story->closedReason) echo $lang->story->reasonList[$story->closedReason];
|
||||
if(isset($story->extraStories[$story->duplicateStory]))
|
||||
{
|
||||
echo html::a(inlink('view', "storyID=$story->duplicateStory"), '#' . $story->duplicateStory . ' ' . $story->extraStories[$story->duplicateStory]);
|
||||
echo html::a(inlink('view', "storyID=$story->duplicateStory"), '#' . $story->duplicateStory . ' ' . $story->extraStories[$story->duplicateStory], '', "title='{$story->extraStories[$story->duplicateStory]}'");
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
|
||||
@@ -1344,7 +1344,6 @@ class task extends control
|
||||
$members = $task->team ? $this->task->getMemberPairs($task) : $this->loadModel('user')->getTeamMemberPairs($task->execution, 'execution', 'nodeleted');
|
||||
$task->nextBy = $task->openedBy;
|
||||
|
||||
$this->view->users = $members;
|
||||
if(!empty($task->team))
|
||||
{
|
||||
$teams = array_keys($task->team);
|
||||
@@ -1367,6 +1366,7 @@ class task extends control
|
||||
$this->view->title = $this->view->execution->name . $this->lang->colon .$this->lang->task->finish;
|
||||
$this->view->position[] = $this->lang->task->finish;
|
||||
$this->view->members = $members;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ foreach(explode(',', $config->task->edit->requiredFields) as $field)
|
||||
<th><?php echo $lang->task->mailto;?></th>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<?php echo html::select('mailto[]', $users, str_replace(' ' , '', $task->mailto), 'class="form-control picker-select" multiple data-drop-direction="bottom"');?>
|
||||
<?php echo html::select('mailto[]', $users, $task->mailto, 'class="form-control picker-select" multiple data-drop-direction="bottom"');?>
|
||||
<?php echo $this->fetch('my', 'buildContactLists');?>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@@ -299,14 +299,13 @@
|
||||
<th><?php echo $lang->task->mailto;?></th>
|
||||
<td>
|
||||
<?php
|
||||
$mailto = explode(',', str_replace(' ', '', $task->mailto));
|
||||
if(empty($mailto))
|
||||
if(empty($task->mailto))
|
||||
{
|
||||
echo $lang->noData;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($mailto as $account) echo ' ' . zget($users, $account, $account);
|
||||
foreach(explode(',', str_replace(' ', '', $task->mailto)) as $account) echo ' ' . zget($users, $account, $account);
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
|
||||
@@ -203,7 +203,7 @@ $config->testcase->datatable->fieldList['story']['fixed'] = 'no';
|
||||
$config->testcase->datatable->fieldList['story']['width'] = '90';
|
||||
$config->testcase->datatable->fieldList['story']['required'] = 'no';
|
||||
$config->testcase->datatable->fieldList['story']['control'] = 'select';
|
||||
$config->testcase->datatable->fieldList['story']['dataSource'] = array('module' => 'port', 'method' => 'getRelatedObjects', 'params' => 'testcase&story&id,title');
|
||||
$config->testcase->datatable->fieldList['story']['dataSource'] = array('module' => 'story', 'method' => 'getProductStoryPairs', 'params' => '$productID&$branch');
|
||||
|
||||
$config->testcase->datatable->fieldList['bugs']['title'] = 'B';
|
||||
$config->testcase->datatable->fieldList['bugs']['fixed'] = 'no';
|
||||
|
||||
@@ -13,6 +13,18 @@ class executionTest
|
||||
$this->objectModel = $tester->loadModel('execution');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the privilege.
|
||||
*
|
||||
* @param mixed $executionID
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function checkPrivTest($executionID)
|
||||
{
|
||||
return $this->objectModel->checkPriv($executionID);
|
||||
}
|
||||
|
||||
/**
|
||||
* get todate
|
||||
*
|
||||
@@ -351,6 +363,76 @@ class executionTest
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the workload format and total.
|
||||
*
|
||||
* @param int $executionID
|
||||
* @param string $type
|
||||
* @param int $percent
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function checkWorkloadTest($executionID = 0, $type = '', $percent = 0)
|
||||
{
|
||||
global $tester;
|
||||
$tester->app->loadLang('programplan');
|
||||
$_POST['products'] = array(1, 81, 91);
|
||||
$_POST['percent'] = $percent;
|
||||
$_POST['parent'] = 0;
|
||||
|
||||
$oldExecution = $executionID ? $this->objectModel->getByID($executionID) : '';
|
||||
if(!empty($oldExecution->parent)) $_POST['parent'] = $oldExecution->parent;
|
||||
|
||||
$result = $this->objectModel->checkWorkload($type, $percent, $oldExecution);
|
||||
if(dao::isError()) return dao::getError(true);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check begin and end date.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @param string $checkType empty|normal|gt|lt|eq
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function checkBeginAndEndDateTest($projectID, $checkType)
|
||||
{
|
||||
if($projectID) $project = $this->objectModel->getByID($projectID);
|
||||
switch($checkType)
|
||||
{
|
||||
case 'empty':
|
||||
$_POST['begin'] = '';
|
||||
$_POST['end'] = '';
|
||||
break;
|
||||
case 'normal':
|
||||
$_POST['begin'] = empty($project->begin) ? '' : date("Y-m-d",strtotime("+1 days",strtotime($project->begin)));
|
||||
$_POST['end'] = empty($project->end) ? '' : date("Y-m-d",strtotime("-1 days",strtotime($project->end)));
|
||||
break;
|
||||
case 'lt':
|
||||
$_POST['begin'] = empty($project->begin) ? '' : date("Y-m-d",strtotime("-1 days",strtotime($project->begin)));
|
||||
$_POST['end'] = empty($project->end) ? '' : date("Y-m-d",strtotime("-1 days",strtotime($project->end)));
|
||||
break;
|
||||
case 'gt':
|
||||
$_POST['begin'] = empty($project->begin) ? '' : date("Y-m-d",strtotime("+1 days",strtotime($project->begin)));
|
||||
$_POST['end'] = empty($project->end) ? '' : date("Y-m-d",strtotime("+1 days",strtotime($project->end)));
|
||||
break;
|
||||
case 'eq':
|
||||
$_POST['begin'] = empty($project->begin) ? '' : $project->begin;
|
||||
$_POST['end'] = empty($project->end) ? '' : $project->end;
|
||||
break;
|
||||
}
|
||||
|
||||
$begin = $_POST['begin'];
|
||||
$end = $_POST['end'];
|
||||
|
||||
$this->objectModel->checkBeginAndEndDate($projectID, $begin, $end);
|
||||
if(dao::isError()) return dao::getError(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* function getPairs test by execution
|
||||
*
|
||||
@@ -523,7 +605,6 @@ class executionTest
|
||||
{
|
||||
$object = $this->objectModel->getIdList($projectID);
|
||||
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
$error = dao::getError();
|
||||
@@ -539,6 +620,26 @@ class executionTest
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get execution stat data.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @param string $browseType
|
||||
* @param int $productID
|
||||
* @param int $branch
|
||||
* @param bool $withTasks
|
||||
* @param string $param
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function getStatDataTest($projectID = 0, $browseType = 'undone', $productID = 0, $branch = 0, $withTasks = false, $param = '', $orderBy = 'id_asc', $pager = null)
|
||||
{
|
||||
$objects = $this->objectModel->getStatData($projectID);
|
||||
return count($objects);
|
||||
}
|
||||
|
||||
/**
|
||||
* function getBranches test execution
|
||||
*
|
||||
@@ -2081,4 +2182,298 @@ class executionTest
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get execution burn data.
|
||||
*
|
||||
* @param array $executionIDList
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getBurnDataTest($executionIDList)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
$executions = $this->objectModel->getByIdList($executionIDList);
|
||||
$objects = $this->objectModel->getBurnData($executions);
|
||||
|
||||
$returns = array();
|
||||
foreach($objects as $executionID => $burnData)
|
||||
{
|
||||
$returns[$executionID] = '';
|
||||
foreach($burnData as $data) $returns[$executionID] .= ",$data->value";
|
||||
$returns[$executionID] = trim($returns[$executionID], ',');
|
||||
}
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
$error = dao::getError();
|
||||
return $error;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $returns;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get begin and end for CFD.
|
||||
*
|
||||
* @param int $executionID
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getBeginEnd4CFDTest($executionID)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
$execution = $this->objectModel->getByID($executionID);
|
||||
$object = $this->objectModel->getBeginEnd4CFD($execution);
|
||||
|
||||
$object[0] = $object[0] == date('Y-m-d', strtotime('-13 days', time())) ? 1 : 0;
|
||||
$object[1] = $object[1] == helper::today() ? 1 : 0;
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
$error = dao::getError();
|
||||
return $error;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get taskes by search.
|
||||
*
|
||||
* @param string $condition
|
||||
* @param int $recPerPage
|
||||
* @param string $orderBy
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getSearchTasksTest($condition, $recPerPage, $orderBy)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
/* Load pager. */
|
||||
$tester->app->loadClass('pager', $static = true);
|
||||
$pager = new pager(0, $recPerPage, 1);
|
||||
|
||||
$objects = $this->objectModel->getSearchTasks($condition, $pager, $orderBy);
|
||||
|
||||
$returns = '';
|
||||
foreach($objects as $object)
|
||||
{
|
||||
$returns .= "$object->id:name:$object->name";
|
||||
if(!empty($object->team))
|
||||
{
|
||||
$returns .= ',team:[';
|
||||
foreach($object->team as $team) $returns .= "$team->id,";
|
||||
$returns = trim($returns, ',');
|
||||
$returns .= ']';
|
||||
}
|
||||
$returns .= ';';
|
||||
}
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
$error = dao::getError();
|
||||
return $error;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $returns;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Get bugs by search in execution.
|
||||
*
|
||||
* @param array $products
|
||||
* @param int $executionID
|
||||
* @param string $sql
|
||||
* @param object $pager
|
||||
* @param string $orderBy
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getSearchBugsTest($products, $executionID, $sql, $pager = null, $orderBy = 'id_desc')
|
||||
{
|
||||
$object = $this->objectModel->getSearchBugs($products, $executionID, $sql, $pager, $orderBy);
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
$error = dao::getError();
|
||||
return $error;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Get kanban group data.
|
||||
*
|
||||
* @param array $stories
|
||||
* @param array $tasks
|
||||
* @param array $bugs
|
||||
* @param string $type
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getKanbanGroupDataTest($stories, $tasks, $bugs, $type = 'story')
|
||||
{
|
||||
$object = $this->objectModel->getKanbanGroupData($stories, $tasks, $bugs, $type);
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
$error = dao::getError();
|
||||
return $error;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(count((array)$object['closed']) == 0 and count((array)$object['nokey']) == 0) return 'empty';
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Get Prev Kanban.
|
||||
*
|
||||
* @param int $executionID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getPrevKanbanTest($executionID)
|
||||
{
|
||||
$result = $this->objectModel->getPrevKanban($executionID);
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
$error = dao::getError();
|
||||
return $error;
|
||||
}
|
||||
else
|
||||
{
|
||||
return !$result ? 'empty' : $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test save Kanban Data.
|
||||
*
|
||||
* @param int $executionID
|
||||
* @param array $kanbanDatas
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function saveKanbanDataTest($executionID, $kanbanDatas = '')
|
||||
{
|
||||
if($kanbanDatas === '')
|
||||
{
|
||||
global $tester;
|
||||
$contents = array('story', 'wait', 'doing', 'done', 'cancel');
|
||||
$stories = $tester->loadModel('story')->getExecutionStories($executionID, 0, 0, 'id_asc');
|
||||
$kanbanTasks = $this->objectModel->getKanbanTasks($executionID, "id");
|
||||
$kanbanBugs = $tester->loadModel('bug')->getExecutionBugs($executionID);
|
||||
$users = array();
|
||||
$taskAndBugs = array();
|
||||
foreach($kanbanTasks as $task)
|
||||
{
|
||||
$storyID = $task->storyID;
|
||||
$status = $task->status;
|
||||
$users[] = $task->assignedTo;
|
||||
|
||||
$taskAndBugs[$status]["task{$task->id}"] = $task;
|
||||
}
|
||||
foreach($kanbanBugs as $bug)
|
||||
{
|
||||
$storyID = $bug->story;
|
||||
$status = $bug->status;
|
||||
$status = $status == 'active' ? 'wait' : ($status == 'resolved' ? ($bug->resolution == 'postponed' ? 'cancel' : 'done') : $status);
|
||||
$users[] = $bug->assignedTo;
|
||||
|
||||
$taskAndBugs[$status]["bug{$bug->id}"] = $bug;
|
||||
}
|
||||
|
||||
$datas = array();
|
||||
foreach($contents as $content)
|
||||
{
|
||||
if($content != 'story' and !isset($taskAndBugs[$content])) continue;
|
||||
$datas[$content] = $content == 'story' ? $stories : $taskAndBugs[$content];
|
||||
}
|
||||
$kanbanDatas = $datas;
|
||||
}
|
||||
|
||||
$object = $this->objectModel->saveKanbanData($executionID, $kanbanDatas);
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
$error = dao::getError();
|
||||
return $error;
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = $this->objectModel->getPrevKanban($executionID);
|
||||
return !$result ? 'empty' : $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Get lifetime by id list.
|
||||
*
|
||||
* @param array $idList
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getLifetimeByIdListTest($idList = '')
|
||||
{
|
||||
$result = $this->objectModel->getLifetimeByIdList($idList);
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
$error = dao::getError();
|
||||
return $error;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!$result) return 'empty';
|
||||
|
||||
foreach($result as $id => $lifetime)
|
||||
{
|
||||
if(!$lifetime) $result[$id] = 'emptyLifetime';
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Update user view of execution and it's product.
|
||||
*
|
||||
* @param int $executionID
|
||||
* @param string $objectType
|
||||
* @param array $users
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function updateUserViewTest($executionID, $objectType = 'sprint', $users = array())
|
||||
{
|
||||
$this->objectModel->updateUserView($executionID, $objectType, $users);
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
$error = dao::getError();
|
||||
return $error;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(count($users) > 0) su($users[0]);
|
||||
|
||||
global $tester;
|
||||
return $tester->app->user->view->sprints;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 executionModel->checkBeginAndEndDate();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
测试传入空值 >> 1
|
||||
测试检查正常的日期 >> 1
|
||||
测试检查小于开始的日期 >> 迭代开始日期应大于等于项目的开始日期:2022-05-26。\n
|
||||
测试检查大于开始的日期 >> 迭代截止日期应小于等于项目的截止日期:2022-09-30。\n
|
||||
测试检查等于开始跟结束的日期 >> 1
|
||||
|
||||
*/
|
||||
|
||||
$projectIdList = array(0, 11);
|
||||
$checkType = array('empty', 'normal', 'lt', 'gt', 'eq');
|
||||
|
||||
$execution = new executionTest();
|
||||
|
||||
r($execution->checkBeginAndEndDateTest($projectIdList[0], $checkType[0])) && p() && e('1'); // 测试传入空值
|
||||
r($execution->checkBeginAndEndDateTest($projectIdList[1], $checkType[1])) && p() && e('1'); // 测试检查正常的日期
|
||||
r($execution->checkBeginAndEndDateTest($projectIdList[1], $checkType[2])) && p() && e('迭代开始日期应大于等于项目的开始日期:2022-05-26。\n'); // 测试检查小于开始的日期
|
||||
r($execution->checkBeginAndEndDateTest($projectIdList[1], $checkType[3])) && p() && e('迭代截止日期应小于等于项目的截止日期:2022-09-30。\n'); // 测试检查大于开始的日期
|
||||
r($execution->checkBeginAndEndDateTest($projectIdList[1], $checkType[4])) && p() && e('1'); // 测试检查等于开始跟结束的日期
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 executionModel->checkPriv();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
测试传入空值 >> 0
|
||||
测试传入0 >> 0
|
||||
测试传入正确的项目ID的权限判断 >> 1
|
||||
测试传入迭代ID的权限判断 >> 1
|
||||
测试传入阶段ID的权限判断 >> 1
|
||||
测试传入看板ID的权限判断 >> 1
|
||||
|
||||
*/
|
||||
|
||||
$executionIdList = array('', 0, 1, 101, 131, 161);
|
||||
|
||||
$execution = new executionTest();
|
||||
|
||||
r($execution->checkPrivTest($executionIdList[0])) && p() && e('0'); // 测试传入空值
|
||||
r($execution->checkPrivTest($executionIdList[1])) && p() && e('0'); // 测试传入0
|
||||
r($execution->checkPrivTest($executionIdList[2])) && p() && e('1'); // 测试传入正确的项目ID的权限判断
|
||||
r($execution->checkPrivTest($executionIdList[3])) && p() && e('1'); // 测试传入迭代ID的权限判断
|
||||
r($execution->checkPrivTest($executionIdList[4])) && p() && e('1'); // 测试传入阶段ID的权限判断
|
||||
r($execution->checkPrivTest($executionIdList[5])) && p() && e('1'); // 测试传入看板ID的权限判断
|
||||
Executable
+71
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 executionModel->checkWorkload();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
测试传入空数据 >> 0
|
||||
测试创建迭代的工作量 >> 0
|
||||
测试创建迭代的工作量 >> 工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n
|
||||
测试创建迭代的工作量 >> "工作量比例"必须为数字\n
|
||||
测试创建迭代的工作量 >> 0
|
||||
测试更新迭代的工作量 >> 0
|
||||
测试更新迭代的工作量 >> 工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n
|
||||
测试更新迭代的工作量 >> "工作量比例"必须为数字\n
|
||||
测试更新迭代的工作量 >> 0
|
||||
测试创建阶段的工作量 >> 0
|
||||
测试创建阶段的工作量 >> 工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n
|
||||
测试创建阶段的工作量 >> "工作量比例"必须为数字\n
|
||||
测试创建阶段的工作量 >> 0
|
||||
测试更新阶段的工作量 >> 0
|
||||
测试更新阶段的工作量 >> 工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n
|
||||
测试更新阶段的工作量 >> "工作量比例"必须为数字\n
|
||||
测试更新阶段的工作量 >> 0
|
||||
测试创建看板的工作量 >> 0
|
||||
测试创建看板的工作量 >> 工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n
|
||||
测试创建看板的工作量 >> "工作量比例"必须为数字\n
|
||||
测试创建看板的工作量 >> 0
|
||||
测试更新看板的工作量 >> 0
|
||||
测试更新看板的工作量 >> 工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n
|
||||
测试更新看板的工作量 >> "工作量比例"必须为数字\n
|
||||
测试更新看板的工作量 >> 0
|
||||
|
||||
*/
|
||||
|
||||
$executionIdList = array(0, 101, 131, 161);
|
||||
$typeList = array('', 'create', 'update');
|
||||
$percentList = array('0', '123', 'all', '10');
|
||||
|
||||
$execution = new executionTest();
|
||||
|
||||
r($execution->checkWorkloadTest($executionIdList[0], $typeList[0], $percentList[0])) && p() && e('0'); // 测试传入空数据
|
||||
r($execution->checkWorkloadTest($executionIdList[1], $typeList[1], $percentList[0])) && p() && e('0'); // 测试创建迭代的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[1], $typeList[1], $percentList[1])) && p() && e('工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n'); // 测试创建迭代的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[1], $typeList[1], $percentList[2])) && p() && e('"工作量比例"必须为数字\n'); // 测试创建迭代的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[1], $typeList[1], $percentList[3])) && p() && e('0'); // 测试创建迭代的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[1], $typeList[2], $percentList[0])) && p() && e('0'); // 测试更新迭代的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[1], $typeList[2], $percentList[1])) && p() && e('工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n'); // 测试更新迭代的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[1], $typeList[2], $percentList[2])) && p() && e('"工作量比例"必须为数字\n'); // 测试更新迭代的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[1], $typeList[2], $percentList[3])) && p() && e('0'); // 测试更新迭代的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[2], $typeList[1], $percentList[0])) && p() && e('0'); // 测试创建阶段的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[2], $typeList[1], $percentList[1])) && p() && e('工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n'); // 测试创建阶段的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[2], $typeList[1], $percentList[2])) && p() && e('"工作量比例"必须为数字\n'); // 测试创建阶段的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[2], $typeList[1], $percentList[3])) && p() && e('0'); // 测试创建阶段的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[2], $typeList[2], $percentList[0])) && p() && e('0'); // 测试更新阶段的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[2], $typeList[2], $percentList[1])) && p() && e('工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n'); // 测试更新阶段的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[2], $typeList[2], $percentList[2])) && p() && e('"工作量比例"必须为数字\n'); // 测试更新阶段的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[2], $typeList[2], $percentList[3])) && p() && e('0'); // 测试更新阶段的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[3], $typeList[1], $percentList[0])) && p() && e('0'); // 测试创建看板的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[3], $typeList[1], $percentList[1])) && p() && e('工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n'); // 测试创建看板的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[3], $typeList[1], $percentList[2])) && p() && e('"工作量比例"必须为数字\n'); // 测试创建看板的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[3], $typeList[1], $percentList[3])) && p() && e('0'); // 测试创建看板的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[3], $typeList[2], $percentList[0])) && p() && e('0'); // 测试更新看板的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[3], $typeList[2], $percentList[1])) && p() && e('工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n'); // 测试更新看板的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[3], $typeList[2], $percentList[2])) && p() && e('"工作量比例"必须为数字\n'); // 测试更新看板的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[3], $typeList[2], $percentList[3])) && p() && e('0'); // 测试更新看板的工作量
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=executionModel->getBeginEnd4CFD();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
ID 161 的专业研发看板累计流图默认开始和结束时间 是不是14天前和今天 >> 1,1
|
||||
ID 162 的专业研发看板累计流图默认开始和结束时间 是不是14天前和今天 >> 1,1
|
||||
ID 163 的专业研发看板累计流图默认开始和结束时间 是不是14天前和今天 >> 1,1
|
||||
ID 171 的专业研发看板累计流图默认开始和结束时间 是不是14天前和今天 >> 1,1
|
||||
ID 181 的专业研发看板累计流图默认开始和结束时间 是不是14天前和今天 >> 1,1
|
||||
ID 191 的专业研发看板累计流图默认开始和结束时间 是不是14天前和今天 >> 1,1
|
||||
|
||||
*/
|
||||
|
||||
$executionIDList = array(161, 162, 163, 171, 181, 191);
|
||||
|
||||
$execution = new executionTest();
|
||||
r($execution->getBeginEnd4CFDTest($executionIDList[0])) && p('0,1') && e('1,1'); // ID 161 的专业研发看板累计流图默认开始和结束时间 是不是14天前和今天
|
||||
r($execution->getBeginEnd4CFDTest($executionIDList[1])) && p('0,1') && e('1,1'); // ID 162 的专业研发看板累计流图默认开始和结束时间 是不是14天前和今天
|
||||
r($execution->getBeginEnd4CFDTest($executionIDList[2])) && p('0,1') && e('1,1'); // ID 163 的专业研发看板累计流图默认开始和结束时间 是不是14天前和今天
|
||||
r($execution->getBeginEnd4CFDTest($executionIDList[3])) && p('0,1') && e('1,1'); // ID 171 的专业研发看板累计流图默认开始和结束时间 是不是14天前和今天
|
||||
r($execution->getBeginEnd4CFDTest($executionIDList[4])) && p('0,1') && e('1,1'); // ID 181 的专业研发看板累计流图默认开始和结束时间 是不是14天前和今天
|
||||
r($execution->getBeginEnd4CFDTest($executionIDList[5])) && p('0,1') && e('1,1'); // ID 191 的专业研发看板累计流图默认开始和结束时间 是不是14天前和今天
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=executionModel->getBurnData();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
测试获取 执行ID 101 102 的燃尽图 >> 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,36,36,36,36,36,36,36,36,36,36,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,null
|
||||
测试获取 执行ID 101 103 111 的燃尽图 >> 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,36,36,36,36,36,36,36,36,36,36,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,23,23,23,23,23,23,23,23,23,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null
|
||||
测试获取 执行ID 111 121 131 的燃尽图 >> 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null;17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,null
|
||||
测试获取 执行ID 101 102 103 111 121 131 的燃尽图 >> 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,36,36,36,36,36,36,36,36,36,36,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,23,23,23,23,23,23,23,23,23,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null;17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,null
|
||||
|
||||
*/
|
||||
|
||||
$executionIDList = array(array(101, 102), array(101, 103, 111), array(111, 121, 131), array(101, 102, 103, 111, 121, 131));
|
||||
|
||||
$execution = new executionTest();
|
||||
r($execution->getBurnDataTest($executionIDList[0])) && p('101;102') && e('21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,36,36,36,36,36,36,36,36,36,36,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,null'); // 测试获取 执行ID 101 102 的燃尽图
|
||||
r($execution->getBurnDataTest($executionIDList[1])) && p('101;103;111') && e('21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,36,36,36,36,36,36,36,36,36,36,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,23,23,23,23,23,23,23,23,23,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null'); // 测试获取 执行ID 101 103 111 的燃尽图
|
||||
r($execution->getBurnDataTest($executionIDList[2])) && p('111;121;131') && e('0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null;17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,null'); // 测试获取 执行ID 111 121 131 的燃尽图
|
||||
r($execution->getBurnDataTest($executionIDList[3])) && p('101;102;103;111;121;131') && e('21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,36,36,36,36,36,36,36,36,36,36,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,23,23,23,23,23,23,23,23,23,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null;17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,null'); // 测试获取 执行ID 101 102 103 111 121 131 的燃尽图
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试executionModel->getKanbanGroupData();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
空数据查询 >> empty
|
||||
查询执行162需求 >> 软件需求246
|
||||
|
||||
*/
|
||||
|
||||
$execution = new executionTest();
|
||||
|
||||
$executionID = 162;
|
||||
$stories = $tester->loadModel('story')->getExecutionStories($executionID);
|
||||
$tasks = $execution->getKanbanTasksTest($executionID, false);
|
||||
$bugs = $tester->loadModel('bug')->getExecutionBugs($executionID);
|
||||
|
||||
r($execution->getKanbanGroupDataTest(array(), array(), array(), 'story')) && p('') && e('empty'); //空数据查询
|
||||
r($execution->getKanbanGroupDataTest($stories, $tasks, $bugs, 'story')) && p('246:title') && e('软件需求246'); // 查询执行162需求
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试executionModel->getLifetimeByIdList();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
查询执行103和161 lifetime >> emptyLifetime
|
||||
查询空执行 lifetime >> empty
|
||||
|
||||
*/
|
||||
|
||||
$executionIDList = array('103', '161');
|
||||
|
||||
$execution = new executionTest();
|
||||
r($execution->getLifetimeByIdListTest($executionIDList)) && p('103') && e('emptyLifetime'); // 查询执行103和161 lifetime
|
||||
r($execution->getLifetimeByIdListTest(array('0'))) && p('') && e('empty'); // 查询空执行 lifetime
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试executionModel->getPrevKanban();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
查询执行162数据 >> empty
|
||||
保存数据后查询执行162数据 >> 246
|
||||
|
||||
*/
|
||||
|
||||
$execution = new executionTest();
|
||||
|
||||
$emptyExecutionID = 163;
|
||||
$executionID = 162;
|
||||
|
||||
r($execution->getPrevKanbanTest($emptyExecutionID)) && p('') && e('empty'); //查询执行162数据
|
||||
$execution->saveKanbanDataTest($executionID);
|
||||
r($execution->getPrevKanbanTest($executionID)) && p('story:0') && e('246'); //保存数据后查询执行162数据
|
||||
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试executionModel->getSearchBugs();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
查询产品1bug >> 测试单转Bug1
|
||||
查询项目13bug优先级 >> 3
|
||||
|
||||
*/
|
||||
|
||||
$productIDList = array(1 => '正常产品1');
|
||||
$executionIDList = array('103');
|
||||
$sql = '1=1';
|
||||
|
||||
$execution = new executionTest();
|
||||
r($execution->getSearchBugsTest($productIDList, 0, $sql)) && p('301:title') && e('测试单转Bug1'); // 查询产品1bug
|
||||
r($execution->getSearchBugsTest(array(), $executionIDList[0], $sql)) && p('303:pri') && e(3); // 查询项目13bug优先级
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=executionModel->getSearchTasks();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
测试通过sql语句获取3个任务 id 倒序 execution = '101' and deleted = '0' and parent >= 0 >> 910:name:子任务10;909:name:子任务9,team:[930,920];908:name:子任务8,team:[919,929];
|
||||
测试通过sql语句获取3个任务 id 正序 execution = '101' and deleted = '0' and parent >= 0 >> 1:name:开发任务11,team:[911,921];901:name:子任务1,team:[922,912];902:name:子任务2,team:[923,913];
|
||||
测试通过sql语句获取5个任务 id 倒序 execution = '101' and deleted = '0' and parent >= 0 >> 910:name:子任务10;909:name:子任务9,team:[930,920];908:name:子任务8,team:[919,929];907:name:子任务7,team:[918,928];906:name:子任务6,team:[927,917];
|
||||
测试通过sql语句获取5个任务 id 正序 execution = '101' and deleted = '0' and parent >= 0 >> 1:name:开发任务11,team:[911,921];901:name:子任务1,team:[922,912];902:name:子任务2,team:[923,913];903:name:子任务3,team:[914,924];904:name:子任务4,team:[915,925];
|
||||
测试通过sql语句获取3个任务 id 倒序 type = 'devel' and fromBug != '0' and parent >= 0 >> 0
|
||||
测试通过sql语句获取3个任务 id 正序 type = 'devel' and fromBug != '0' and parent >= 0 >> 0
|
||||
测试通过sql语句获取5个任务 id 倒序 type = 'devel' and fromBug != '0' and parent >= 0 >> 0
|
||||
测试通过sql语句获取5个任务 id 正序 type = 'devel' and fromBug != '0' and parent >= 0 >> 0
|
||||
测试通过sql语句获取3个任务 id 倒序 execution = '101' and story != '0' and parent >= 0 >> 1:name:开发任务11,team:[911,921];
|
||||
测试通过sql语句获取3个任务 id 正序 execution = '101' and story != '0' and parent >= 0 >> 1:name:开发任务11,team:[911,921];
|
||||
测试通过sql语句获取5个任务 id 倒序 execution = '101' and story != '0' and parent >= 0 >> 1:name:开发任务11,team:[911,921];
|
||||
测试通过sql语句获取5个任务 id 正序 execution = '101' and story != '0' and parent >= 0 >> 1:name:开发任务11,team:[911,921];
|
||||
测试通过sql语句获取3个任务 id 倒序 module like '%2%' and type = 'design' and parent >= 0 >> 909:name:子任务9,team:[930,920];901:name:子任务1,team:[922,912];801:name:更多任务201;
|
||||
测试通过sql语句获取3个任务 id 正序 module like '%2%' and type = 'design' and parent >= 0 >> 1:name:开发任务11,team:[911,921];65:name:开发任务75;73:name:开发任务83;
|
||||
测试通过sql语句获取5个任务 id 倒序 module like '%2%' and type = 'design' and parent >= 0 >> 909:name:子任务9,team:[930,920];901:name:子任务1,team:[922,912];801:name:更多任务201;769:name:更多任务169;737:name:更多任务137;
|
||||
测试通过sql语句获取5个任务 id 正序 module like '%2%' and type = 'design' and parent >= 0 >> 1:name:开发任务11,team:[911,921];65:name:开发任务75;73:name:开发任务83;81:name:开发任务91;89:name:开发任务99;
|
||||
|
||||
*/
|
||||
|
||||
$condition = array();
|
||||
$condition[] = "execution = '101' and deleted = '0' and parent >= 0";
|
||||
$condition[] = "type = 'devel' and fromBug != '0' and parent >= 0";
|
||||
$condition[] = "execution = '101' and story != '0' and parent >= 0";
|
||||
$condition[] = "module like '%2%' and type = 'design' and parent >= 0";
|
||||
|
||||
$recPerPage = array('3', '5');
|
||||
$orderBy = array('id_desc', 'id_asc');
|
||||
|
||||
|
||||
$execution = new executionTest();
|
||||
r($execution->getSearchTasksTest($condition[0], $recPerPage[0], $orderBy[0])) && p() && e('910:name:子任务10;909:name:子任务9,team:[930,920];908:name:子任务8,team:[919,929];'); // 测试通过sql语句获取3个任务 id 倒序 execution = '101' and deleted = '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[0], $recPerPage[0], $orderBy[1])) && p() && e('1:name:开发任务11,team:[911,921];901:name:子任务1,team:[922,912];902:name:子任务2,team:[923,913];'); // 测试通过sql语句获取3个任务 id 正序 execution = '101' and deleted = '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[0], $recPerPage[1], $orderBy[0])) && p() && e('910:name:子任务10;909:name:子任务9,team:[930,920];908:name:子任务8,team:[919,929];907:name:子任务7,team:[918,928];906:name:子任务6,team:[927,917];'); // 测试通过sql语句获取5个任务 id 倒序 execution = '101' and deleted = '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[0], $recPerPage[1], $orderBy[1])) && p() && e('1:name:开发任务11,team:[911,921];901:name:子任务1,team:[922,912];902:name:子任务2,team:[923,913];903:name:子任务3,team:[914,924];904:name:子任务4,team:[915,925];'); // 测试通过sql语句获取5个任务 id 正序 execution = '101' and deleted = '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[1], $recPerPage[0], $orderBy[0])) && p() && e('0'); // 测试通过sql语句获取3个任务 id 倒序 type = 'devel' and fromBug != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[1], $recPerPage[0], $orderBy[1])) && p() && e('0'); // 测试通过sql语句获取3个任务 id 正序 type = 'devel' and fromBug != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[1], $recPerPage[1], $orderBy[0])) && p() && e('0'); // 测试通过sql语句获取5个任务 id 倒序 type = 'devel' and fromBug != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[1], $recPerPage[1], $orderBy[1])) && p() && e('0'); // 测试通过sql语句获取5个任务 id 正序 type = 'devel' and fromBug != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[2], $recPerPage[0], $orderBy[0])) && p() && e('1:name:开发任务11,team:[911,921];'); // 测试通过sql语句获取3个任务 id 倒序 execution = '101' and story != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[2], $recPerPage[0], $orderBy[1])) && p() && e('1:name:开发任务11,team:[911,921];'); // 测试通过sql语句获取3个任务 id 正序 execution = '101' and story != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[2], $recPerPage[1], $orderBy[0])) && p() && e('1:name:开发任务11,team:[911,921];'); // 测试通过sql语句获取5个任务 id 倒序 execution = '101' and story != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[2], $recPerPage[1], $orderBy[1])) && p() && e('1:name:开发任务11,team:[911,921];'); // 测试通过sql语句获取5个任务 id 正序 execution = '101' and story != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[3], $recPerPage[0], $orderBy[0])) && p() && e('909:name:子任务9,team:[930,920];901:name:子任务1,team:[922,912];801:name:更多任务201;'); // 测试通过sql语句获取3个任务 id 倒序 module like '%2%' and type = 'design' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[3], $recPerPage[0], $orderBy[1])) && p() && e('1:name:开发任务11,team:[911,921];65:name:开发任务75;73:name:开发任务83;'); // 测试通过sql语句获取3个任务 id 正序 module like '%2%' and type = 'design' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[3], $recPerPage[1], $orderBy[0])) && p() && e('909:name:子任务9,team:[930,920];901:name:子任务1,team:[922,912];801:name:更多任务201;769:name:更多任务169;737:name:更多任务137;'); // 测试通过sql语句获取5个任务 id 倒序 module like '%2%' and type = 'design' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[3], $recPerPage[1], $orderBy[1])) && p() && e('1:name:开发任务11,team:[911,921];65:name:开发任务75;73:name:开发任务83;81:name:开发任务91;89:name:开发任务99;'); // 测试通过sql语句获取5个任务 id 正序 module like '%2%' and type = 'design' and parent >= 0
|
||||
Executable
+76
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 executionModel->getStatData();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
测试默认值 >> 0
|
||||
测试传入空值 >> 0
|
||||
测试projectID为1的所有未关闭执行 >> 0
|
||||
测试projectID为1的所有执行 >> 0
|
||||
测试projectID为1的未开始执行 >> 0
|
||||
测试projectID为1的进行中执行 >> 0
|
||||
测试projectID为1的已挂起执行 >> 0
|
||||
测试projectID为1的已关闭执行 >> 0
|
||||
测试projectID为1的我参与执行 >> 0
|
||||
测试projectID为1的搜索出来的执行 >> 0
|
||||
测试projectID为1的评审执行 >> 0
|
||||
测试projectID为1, productID为1, branchID为0的所有执行 >> 0
|
||||
测试projectID为1, productID为1, branchID为0的所有执行和任务 >> 0
|
||||
测试projectID为1, productID为1, branchID为0的非父阶段 >> 0
|
||||
测试projectID为11的所有未关闭执行 >> 7
|
||||
测试projectID为11的所有执行 >> 7
|
||||
测试projectID为11的未开始执行 >> 7
|
||||
测试projectID为11的进行中执行 >> 7
|
||||
测试projectID为11的已挂起执行 >> 7
|
||||
测试projectID为11的已关闭执行 >> 7
|
||||
测试projectID为11的我参与执行 >> 7
|
||||
测试projectID为11的搜索出来的执行 >> 7
|
||||
测试projectID为11的评审执行 >> 7
|
||||
测试projectID为11, productID为1, branchID为0的所有执行 >> 7
|
||||
测试projectID为11, productID为1, branchID为0的所有执行和任务 >> 7
|
||||
测试projectID为11, productID为1, branchID为0的非父阶段 >> 7
|
||||
|
||||
*/
|
||||
|
||||
$projectIdList = array(0, 1, 11);
|
||||
$browseTypeList = array('all', 'wait', 'doing', 'suspended', 'closed', 'involved', 'bySearch', 'review');
|
||||
$productID = 1;
|
||||
$branchID = 0;
|
||||
$withTasksList = array(false, true);
|
||||
$param = 'skipParent';
|
||||
|
||||
$execution = new executionTest();
|
||||
|
||||
r($execution->getStatDataTest()) && p() && e('0'); // 测试默认值
|
||||
r($execution->getStatDataTest($projectIdList[0])) && p() && e('0'); // 测试传入空值
|
||||
r($execution->getStatDataTest($projectIdList[1])) && p() && e('0'); // 测试projectID为1的所有未关闭执行
|
||||
r($execution->getStatDataTest($projectIdList[1], $browseTypeList[0])) && p() && e('0'); // 测试projectID为1的所有执行
|
||||
r($execution->getStatDataTest($projectIdList[1], $browseTypeList[1])) && p() && e('0'); // 测试projectID为1的未开始执行
|
||||
r($execution->getStatDataTest($projectIdList[1], $browseTypeList[2])) && p() && e('0'); // 测试projectID为1的进行中执行
|
||||
r($execution->getStatDataTest($projectIdList[1], $browseTypeList[3])) && p() && e('0'); // 测试projectID为1的已挂起执行
|
||||
r($execution->getStatDataTest($projectIdList[1], $browseTypeList[4])) && p() && e('0'); // 测试projectID为1的已关闭执行
|
||||
r($execution->getStatDataTest($projectIdList[1], $browseTypeList[5])) && p() && e('0'); // 测试projectID为1的我参与执行
|
||||
r($execution->getStatDataTest($projectIdList[1], $browseTypeList[6])) && p() && e('0'); // 测试projectID为1的搜索出来的执行
|
||||
r($execution->getStatDataTest($projectIdList[1], $browseTypeList[7])) && p() && e('0'); // 测试projectID为1的评审执行
|
||||
r($execution->getStatDataTest($projectIdList[1], $browseTypeList[0], $productID, $branchID)) && p() && e('0'); // 测试projectID为1, productID为1, branchID为0的所有执行
|
||||
r($execution->getStatDataTest($projectIdList[1], $browseTypeList[0], $productID, $branchID), $withTasksList[1]) && p() && e('0'); // 测试projectID为1, productID为1, branchID为0的所有执行和任务
|
||||
r($execution->getStatDataTest($projectIdList[1], $browseTypeList[0], $productID, $branchID), $withTasksList[0], $param) && p() && e('0'); // 测试projectID为1, productID为1, branchID为0的非父阶段
|
||||
r($execution->getStatDataTest($projectIdList[2])) && p() && e('7'); // 测试projectID为11的所有未关闭执行
|
||||
r($execution->getStatDataTest($projectIdList[2], $browseTypeList[0])) && p() && e('7'); // 测试projectID为11的所有执行
|
||||
r($execution->getStatDataTest($projectIdList[2], $browseTypeList[1])) && p() && e('7'); // 测试projectID为11的未开始执行
|
||||
r($execution->getStatDataTest($projectIdList[2], $browseTypeList[2])) && p() && e('7'); // 测试projectID为11的进行中执行
|
||||
r($execution->getStatDataTest($projectIdList[2], $browseTypeList[3])) && p() && e('7'); // 测试projectID为11的已挂起执行
|
||||
r($execution->getStatDataTest($projectIdList[2], $browseTypeList[4])) && p() && e('7'); // 测试projectID为11的已关闭执行
|
||||
r($execution->getStatDataTest($projectIdList[2], $browseTypeList[5])) && p() && e('7'); // 测试projectID为11的我参与执行
|
||||
r($execution->getStatDataTest($projectIdList[2], $browseTypeList[6])) && p() && e('7'); // 测试projectID为11的搜索出来的执行
|
||||
r($execution->getStatDataTest($projectIdList[2], $browseTypeList[7])) && p() && e('7'); // 测试projectID为11的评审执行
|
||||
r($execution->getStatDataTest($projectIdList[2], $browseTypeList[0], $productID, $branchID)) && p() && e('7'); // 测试projectID为11, productID为1, branchID为0的所有执行
|
||||
r($execution->getStatDataTest($projectIdList[2], $browseTypeList[0], $productID, $branchID), $withTasksList[1]) && p() && e('7'); // 测试projectID为11, productID为1, branchID为0的所有执行和任务
|
||||
r($execution->getStatDataTest($projectIdList[2], $browseTypeList[0], $productID, $branchID), $withTasksList[0], $param) && p() && e('7'); // 测试projectID为11, productID为1, branchID为0的非父阶段
|
||||
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试executionModel->saveKanbanData();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
保存执行162看板数据 >> 246
|
||||
保存执行162看板空数据 >> empty
|
||||
|
||||
*/
|
||||
|
||||
$execution = new executionTest();
|
||||
|
||||
$executionID = 162;
|
||||
$emptyData = array();
|
||||
|
||||
r($execution->saveKanbanDataTest($executionID)) && p('story:0') && e('246'); //保存执行162看板数据
|
||||
r($execution->saveKanbanDataTest($executionID, $emptyData)) && p('') && e('empty'); //保存执行162看板空数据
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
$db->switchDB();
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试executionModel->updateUserView();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
默认情况下的用户是否有201权限 >> 400
|
||||
删除执行201后dev1用户是否有201权限 >> 0
|
||||
|
||||
*/
|
||||
|
||||
$executionID = 201;
|
||||
|
||||
$execution = new executionTest();
|
||||
r(strpos($execution->updateUserViewTest($executionID), '201,')) && p() && e('400'); // 默认情况下的用户是否有201权限
|
||||
$tester->dao->update(TABLE_EXECUTION)->set('deleted')->eq(1)->where('id')->eq($executionID)->exec();
|
||||
r(strpos($execution->updateUserViewTest($executionID, 'sprint', array('dev1')), '201,')) && p() && e('0'); // 删除执行201后dev1用户是否有201权限
|
||||
$db->restoreDB();
|
||||
@@ -187,6 +187,9 @@ switch($argv[1])
|
||||
case 'gitea':
|
||||
ztfRun('model/gitea');
|
||||
break;
|
||||
case 'webhook':
|
||||
ztfRun('model/webhook');
|
||||
break;
|
||||
|
||||
default:
|
||||
ztfExtract($argv[1]);
|
||||
|
||||
Reference in New Issue
Block a user