Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,7 @@
|
||||
30043 实现执行看板设置泳道高度功能
|
||||
30053 实现研发看板设置泳道高度功能
|
||||
30068 通用看板中默认的模版横向不要有滚动条
|
||||
|
||||
2022-01-11 16.1
|
||||
46672 实现计划卡片的更多设置功能
|
||||
46671 计划看板中实现卡片的排序功能
|
||||
|
||||
+14
-6
@@ -352,14 +352,18 @@ class actionModel extends model
|
||||
}
|
||||
elseif($actionName == 'linked2execution')
|
||||
{
|
||||
$name = $this->dao->select('name')->from(TABLE_PROJECT)->where('id')->eq($action->extra)->fetch('name');
|
||||
if($name) $action->extra = common::hasPriv('execution', 'view') ? html::a(helper::createLink('execution', 'view', "executionID=$action->execution"), $name) : $name;
|
||||
$execution = $this->dao->select('name,type')->from(TABLE_PROJECT)->where('id')->eq($action->extra)->fetch();
|
||||
$name = $execution->name;
|
||||
$method = $execution->type == 'kanban' ? 'kanban' : 'view';
|
||||
if($name) $action->extra = common::hasPriv('execution', $method) ? html::a(helper::createLink('execution', $method, "executionID=$action->execution"), $name) : $name;
|
||||
}
|
||||
elseif($actionName == 'linked2project')
|
||||
{
|
||||
$name = $this->dao->select('name')->from(TABLE_PROJECT)->where('id')->eq($action->extra)->fetch('name');
|
||||
$project = $this->dao->select('name,model')->from(TABLE_PROJECT)->where('id')->eq($action->extra)->fetch();
|
||||
$productID = trim($action->product, ',');
|
||||
if($name) $action->extra = common::hasPriv('project', 'view') ? html::a(helper::createLink('project', 'view', "projectID=$action->project"), $name) : $name;
|
||||
$name = $project->name;
|
||||
$method = $project->model == 'kanban' ? 'index' : 'view';
|
||||
if($name) $action->extra = common::hasPriv('project', $method) ? html::a(helper::createLink('project', $method, "projectID=$action->project"), $name) : $name;
|
||||
}
|
||||
elseif($actionName == 'linked2plan')
|
||||
{
|
||||
@@ -1034,12 +1038,16 @@ class actionModel extends model
|
||||
{
|
||||
$action->objectName .= $this->lang->action->label->startProgram;
|
||||
}
|
||||
|
||||
if($action->objectType == 'branch' and $action->action == 'mergedbranch')
|
||||
elseif($action->objectType == 'branch' and $action->action == 'mergedbranch')
|
||||
{
|
||||
if($action->objectID == 0) $action->objectName = $this->lang->branch->main;
|
||||
$action->objectName = '"' . $action->extra . ' "' . $this->lang->action->to . ' "' . $action->objectName . '"';
|
||||
}
|
||||
elseif($action->objectType == 'user')
|
||||
{
|
||||
$user = $this->dao->select('id,realname')->from(TABLE_USER)->where('id')->eq($action->objectID)->fetch();
|
||||
if($user) $action->objectName = $user->realname;
|
||||
}
|
||||
|
||||
$projectID = isset($relatedProjects[$action->objectType][$action->objectID]) ? $relatedProjects[$action->objectType][$action->objectID] : 0;
|
||||
|
||||
|
||||
@@ -428,7 +428,7 @@ class bug extends control
|
||||
setcookie('bugModule', 0, 0, $this->config->webRoot, '', $this->config->cookieSecure, false);
|
||||
$location = $this->createLink('bug', 'browse', "productID={$this->post->product}&branch=$branch&browseType=byModule¶m={$this->post->module}&orderBy=id_desc");
|
||||
}
|
||||
if($this->app->getViewType() == 'xhtml') $location = $this->createLink('bug', 'view', "bugID=$bugID");
|
||||
if($this->app->getViewType() == 'xhtml') $location = $this->createLink('bug', 'view', "bugID=$bugID", 'html');
|
||||
$response['locate'] = $location;
|
||||
return $this->send($response);
|
||||
}
|
||||
@@ -599,6 +599,8 @@ class bug extends control
|
||||
/* Get executions. */
|
||||
$executions = array(0 => '');
|
||||
if(isset($projects[$projectID]) or $this->config->systemMode == 'classic') $executions += $this->product->getExecutionPairsByProduct($productID, $branch ? "0,$branch" : 0, 'id_desc', $projectID);
|
||||
$execution = $executionID ? $this->loadModel('execution')->getByID($executionID) : '';
|
||||
$executions = isset($executions[$executionID]) ? $executions : $executions + array($executionID => $execution->name);
|
||||
|
||||
/* Set custom. */
|
||||
foreach(explode(',', $this->config->bug->list->customCreateFields) as $field) $customFields[$field] = $this->lang->bug->$field;
|
||||
|
||||
@@ -121,8 +121,8 @@ $currentBrowseType = isset($lang->bug->mySelects[$browseType]) && in_array($brow
|
||||
}
|
||||
else
|
||||
{
|
||||
$branch = $branch != 'all' ? $branch : 0;
|
||||
$createBugLink = $this->createLink('bug', 'create', "productID=$productID&branch=$branch&extra=moduleID=$moduleID");
|
||||
$selectedBranch = $branch != 'all' ? $branch : 0;
|
||||
$createBugLink = $this->createLink('bug', 'create', "productID=$productID&branch=$selectedBranch&extra=moduleID=$moduleID");
|
||||
}
|
||||
$batchCreateLink = $this->createLink('bug', 'batchCreate', "productID=$productID&branch=$branch&executionID=0&moduleID=$moduleID");
|
||||
|
||||
|
||||
@@ -532,7 +532,7 @@ class commonModel extends model
|
||||
{
|
||||
$params = "programID=0©ProjectID=0&extra=from=global";
|
||||
$createMethod = 'createGuide';
|
||||
$attr = 'data-toggle="modal" data-target="#guideDialog"';
|
||||
$attr = 'data-toggle="modal"';
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -309,7 +309,7 @@ class doc extends control
|
||||
if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'id' => $docID));
|
||||
$objectID = zget($lib, $lib->type, '');
|
||||
$params = "type={$lib->type}&objectID=$objectID&libID={$lib->id}&docID=" . $docResult['id'];
|
||||
$link = isonlybody() ? 'parent' : $this->createLink('doc', 'objectLibs', $params);
|
||||
$link = isonlybody() ? 'parent' : $this->createLink('doc', 'objectLibs', $params, 'html');
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $link));
|
||||
}
|
||||
|
||||
|
||||
@@ -1335,9 +1335,9 @@ class docModel extends model
|
||||
/* Project permissions for DocLib whitelist. */
|
||||
if($this->app->tab == 'doc')
|
||||
{
|
||||
$myObjects = $this->dao->select('t2.id, t2.name')->from(TABLE_DOCLIB)->alias('t1')
|
||||
->leftjoin(TABLE_PROJECT)->alias('t2')->on('t1.project=t2.id')
|
||||
->where("CONCAT(',', t1.users, ',')")->like("%,{$this->app->user->account},%")
|
||||
$myObjects = $this->dao->select('t1.id, t1.name')->from(TABLE_PROJECT)->alias('t1')
|
||||
->leftjoin(TABLE_DOCLIB)->alias('t2')->on('t2.project=t1.id')
|
||||
->where("CONCAT(',', t2.users, ',')")->like("%,{$this->app->user->account},%")
|
||||
->fetchPairs();
|
||||
}
|
||||
|
||||
|
||||
@@ -123,12 +123,13 @@ class execution extends control
|
||||
/* Set browse type. */
|
||||
$browseType = strtolower($status);
|
||||
|
||||
/* Get products by execution. */
|
||||
$execution = $this->commonAction($executionID, $status);
|
||||
$execution = $this->commonAction($executionID, $status);
|
||||
$executionID = $execution->id;
|
||||
|
||||
if($execution->type == 'kanban') $this->locate($this->createLink('execution', 'kanban', "executionID=$executionID"));
|
||||
|
||||
$executionID = $execution->id;
|
||||
$products = $this->product->getProductPairsByProject($executionID);
|
||||
/* Get products by execution. */
|
||||
$products = $this->product->getProductPairsByProject($executionID);
|
||||
setcookie('preExecutionID', $executionID, $this->config->cookieLife, $this->config->webRoot, '', false, true);
|
||||
|
||||
/* Save the recently five executions visited in the cookie. */
|
||||
@@ -1978,11 +1979,12 @@ class execution extends control
|
||||
|
||||
$userList = array();
|
||||
$users = $this->loadModel('user')->getPairs('noletter|nodeleted');
|
||||
$avatarPairs = $this->dao->select('account, avatar')->from(TABLE_USER)->where('deleted')->eq(0)->fetchPairs();
|
||||
$avatarPairs = $this->user->getAvatarPairs();
|
||||
foreach($avatarPairs as $account => $avatar)
|
||||
{
|
||||
if(!$avatar) continue;
|
||||
$userList[$account]['avatar'] = $avatar;
|
||||
if(!isset($users[$account])) continue;
|
||||
$userList[$account]['realname'] = $users[$account];
|
||||
$userList[$account]['avatar'] = $avatar;
|
||||
}
|
||||
|
||||
/* Get execution's product. */
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
.region .kanban-item {position: relative}
|
||||
|
||||
.kanban-card {height: auto !important; padding: 8px 14px !important}
|
||||
.kanban-card {height: auto !important; padding: 8px 14px !important; min-height: 60px;}
|
||||
|
||||
.cardcolor {width:40px; height: 14px; float: left; margin-left: 5px; margin-right: 5px; margin-top: 2px; border-radius: 2px;}
|
||||
#cardcolormenu {padding:2px 2px; width: 100px;}
|
||||
@@ -103,3 +103,5 @@
|
||||
#kanban .kanban-card[data-scale-size="2"] > .infos {display: inline-block; height: 18px; vertical-align: top; margin: 0;}
|
||||
#kanban .kanban-card[data-scale-size="2"] > .infos > .info-pri {transform: scale(.8); vertical-align: top;}
|
||||
#kanban .kanban-card[data-scale-size="2"] > .infos > .avatar {display: inline-block; transform: scale(.8); position: relative; top: -2px; vertical-align: top; margin-right: -1px;}
|
||||
|
||||
#mainMenu .divider {margin: 10px}
|
||||
|
||||
@@ -299,6 +299,7 @@ function findDropColumns($element, $root)
|
||||
{
|
||||
if(!colRules) return false;
|
||||
if(colRules === true) return true;
|
||||
if($.cookie('isFullScreen') == 1) return false;
|
||||
|
||||
var $newCol = $(this);
|
||||
var newCol = $newCol.data();
|
||||
@@ -338,7 +339,7 @@ function renderUserAvatar(user, objectType, objectID, size)
|
||||
if(!user) return $('<a class="avatar has-text ' + avatarSizeClass + ' avatar-circle iframe" title="' + noAssigned + '" style="background: #ccc" href="' + link + '" data-toggle="modal" data-width="80%"><i class="icon icon-person"></i></a>');
|
||||
|
||||
if(typeof user === 'string') user = {account: user};
|
||||
if(!user.avatar && window.users && window.users[user.account]) user = {avatar: users[user.account].avatar, account: user.account, realname: users[user.account]};
|
||||
if(!user.avatar && window.userList && window.userList[user.account]) user = {avatar: userList[user.account].avatar, account: user.account, realname: userList[user.account].realname};
|
||||
|
||||
var $noPrivAvatar = $('<div class="avatar has-text ' + avatarSizeClass + ' avatar-circle" />').avatar({user: user});
|
||||
if(objectType == 'task' && !priv.canAssignTask) return $noPrivAvatar;
|
||||
@@ -605,11 +606,18 @@ function renderCount($count, count, column)
|
||||
function renderHeaderCol($column, column, $header, kanbanData)
|
||||
{
|
||||
if(groupBy != 'default') return;
|
||||
|
||||
/* Render group header. */
|
||||
var privs = kanbanData.actions;
|
||||
var columnPrivs = kanbanData.columns[0].actions;
|
||||
var $actions = $column.children('.actions');
|
||||
|
||||
if(column.parent == -1)
|
||||
{
|
||||
$column.append('<div class="actions"></div>');
|
||||
$actions = $column.children('.actions');
|
||||
}
|
||||
|
||||
if(privs.includes('sortGroup'))
|
||||
{
|
||||
var groups = regions[column.region].groups;
|
||||
@@ -786,7 +794,7 @@ function changeCardColType(cardID, fromColID, toColID, fromLaneID, toLaneID, car
|
||||
}
|
||||
else if(toColType == 'developing')
|
||||
{
|
||||
if((fromColType == 'pause' || fromColType == 'cancel' || fromColType == 'closed' || fromColType == 'developed') && priv.canActivateTask)
|
||||
if((fromColType == 'pause' || fromColType == 'canceled' || fromColType == 'closed' || fromColType == 'developed') && priv.canActivateTask)
|
||||
{
|
||||
var link = createLink('task', 'activate', 'taskID=' + objectID + '&extra=fromColID=' + fromColID + ',toColID=' + toColID + ',fromLaneID=' + fromLaneID + ',toLaneID=' + toLaneID, '', true);
|
||||
showIframe = true;
|
||||
@@ -860,7 +868,7 @@ function changeCardColType(cardID, fromColID, toColID, fromLaneID, toLaneID, car
|
||||
}
|
||||
}
|
||||
|
||||
if(moveCard)
|
||||
if(moveCard || (fromLaneID != toLaneID && fromColID == toColID))
|
||||
{
|
||||
var link = createLink('kanban', 'ajaxMoveCard', 'cardID=' + objectID + '&fromColID=' + fromColID + '&toColID=' + toColID + '&fromLaneID=' + fromLaneID + '&toLaneID=' + toLaneID + '&execitionID=' + executionID + '&browseType=' + browseType + '&groupBy=' + groupBy + '®ionID=' + regionID + '&orderBy=' + orderBy );
|
||||
$.ajax(
|
||||
@@ -964,7 +972,6 @@ function initKanban($kanban)
|
||||
displayCards: displayCards,
|
||||
createColumnText: kanbanLang.createColumn,
|
||||
addItemText: '',
|
||||
cardHeight: getCardHeight(),
|
||||
cardsPerRow: window.kanbanScaleSize,
|
||||
onAction: handleKanbanAction,
|
||||
onRenderLaneName: renderLaneName,
|
||||
|
||||
@@ -470,7 +470,7 @@ if(!window.kanbanDropRules)
|
||||
task:
|
||||
{
|
||||
'wait': ['developing', 'developed', 'canceled', 'closed'],
|
||||
'developing': ['developed', 'pause'],
|
||||
'developing': ['developed', 'pause', 'canceled'],
|
||||
'developed': ['canceled', 'closed'],
|
||||
'pause': ['developing'],
|
||||
'canceled': ['developing'],
|
||||
@@ -499,6 +499,7 @@ function findDropColumns($element, $root)
|
||||
{
|
||||
if(!colRules) return false;
|
||||
if(colRules === true) return true;
|
||||
if($.cookie('isFullScreen') == 1) return false;
|
||||
|
||||
var $newCol = $(this);
|
||||
var newCol = $newCol.data();
|
||||
@@ -553,7 +554,7 @@ function changeCardColType(cardID, fromColID, toColID, fromLaneID, toLaneID, car
|
||||
}
|
||||
else if(toColType == 'developing')
|
||||
{
|
||||
if((fromColType == 'pause' || fromColType == 'cancel' || fromColType == 'closed' || fromColType == 'developed') && priv.canActivateTask)
|
||||
if((fromColType == 'pause' || fromColType == 'canceled' || fromColType == 'closed' || fromColType == 'developed') && priv.canActivateTask)
|
||||
{
|
||||
var link = createLink('task', 'activate', 'taskID=' + objectID, '', true);
|
||||
showIframe = true;
|
||||
@@ -761,8 +762,8 @@ function createColumnMenu(options)
|
||||
var kanbanID = options.kanban;
|
||||
|
||||
var items = [];
|
||||
if(priv.canEditName) items.push({label: executionLang.editName, url: $.createLink('kanban', 'setColumn', 'col=' + col.columnID + '&executionID=' + executionID + '&from=execution'), className: 'iframe', attrs: {'data-width': '500px'}})
|
||||
if(priv.canSetWIP) items.push({label: executionLang.setWIP, url: $.createLink('kanban', 'setWIP', 'col=' + col.columnID + '&executionID=' + executionID + '&from=execution'), className: 'iframe', attrs: {'data-width': '500px'}})
|
||||
if(priv.canEditName) items.push({label: executionLang.editName, url: $.createLink('kanban', 'setColumn', 'col=' + col.id + '&executionID=' + executionID + '&from=execution'), className: 'iframe', attrs: {'data-width': '500px'}})
|
||||
if(priv.canSetWIP) items.push({label: executionLang.setWIP, url: $.createLink('kanban', 'setWIP', 'col=' + col.id + '&executionID=' + executionID + '&from=execution'), className: 'iframe', attrs: {'data-width': '500px'}})
|
||||
//if(priv.canSortCards) items.push({label: executionLang.sortColumn, items: ['按ID倒序', '按ID顺序'], className: 'iframe', onClick: handleSortColCards})
|
||||
return items;
|
||||
}
|
||||
@@ -786,13 +787,13 @@ function createColumnCreateMenu(options)
|
||||
}
|
||||
else if(col.laneType == 'bug')
|
||||
{
|
||||
if(priv.canCreateBug) items.push({label: bugLang.create, url: $.createLink('bug', 'create', 'productID=0&moduleID=0&extra=executionID=' + executionID, '', true), className: 'iframe'});
|
||||
if(priv.canBatchCreateBug) items.push({label: bugLang.batchCreate, url: $.createLink('bug', 'batchcreate', 'productID=' + productID + '&moduleID=0&executionID=' + executionID, '', true), className: 'iframe'});
|
||||
if(priv.canCreateBug) items.push({label: bugLang.create, url: $.createLink('bug', 'create', 'productID=0&moduleID=0&extra=executionID=' + executionID, '', true), className: 'iframe', attrs: {'data-width': '80%'}});
|
||||
if(priv.canBatchCreateBug) items.push({label: bugLang.batchCreate, url: $.createLink('bug', 'batchcreate', 'productID=' + productID + '&moduleID=0&executionID=' + executionID, '', true), className: 'iframe', attrs: {'data-width': '90%'}});
|
||||
}
|
||||
else
|
||||
{
|
||||
if(priv.canCreateTask) items.push({label: taskLang.create, url: $.createLink('task', 'create', 'executionID=' + executionID, '', true), className: 'iframe'});
|
||||
if(priv.canBatchCreateTask) items.push({label: taskLang.batchCreate, url: $.createLink('task', 'batchcreate', 'executionID=' + executionID, '', true), className: 'iframe'});
|
||||
if(priv.canCreateTask) items.push({label: taskLang.create, url: $.createLink('task', 'create', 'executionID=' + executionID, '', true), className: 'iframe', attrs: {'data-width': '80%'}});
|
||||
if(priv.canBatchCreateTask) items.push({label: taskLang.batchCreate, url: $.createLink('task', 'batchcreate', 'executionID=' + executionID, '', true), className: 'iframe', attrs: {'data-width': '80%'}});
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,13 @@ class executionModel extends model
|
||||
*/
|
||||
public function setMenu($executionID, $buildID = 0, $extra = '')
|
||||
{
|
||||
$execution = $this->getByID($executionID);
|
||||
if($execution and $execution->type == 'kanban')
|
||||
{
|
||||
$this->lang->execution->menu = new stdclass();
|
||||
$this->lang->execution->accessDenied = str_replace($this->lang->executionCommon, $this->lang->execution->kanban, $this->lang->execution->accessDenied);
|
||||
}
|
||||
|
||||
if(!$this->app->user->admin and strpos(",{$this->app->user->view->sprints},", ",$executionID,") === false and !defined('TUTORIAL') and $executionID != 0) die(js::error($this->lang->execution->accessDenied) . js::locate('back'));
|
||||
|
||||
$executions = $this->getPairs(0, 'all', 'nocode');
|
||||
@@ -71,9 +78,6 @@ class executionModel extends model
|
||||
$this->session->set('execution', $executionID);
|
||||
|
||||
/* Unset story, bug, build and testtask if type is ops. */
|
||||
$execution = $this->getByID($executionID);
|
||||
if($execution and $execution->type == 'kanban') $this->lang->execution->menu = new stdclass();
|
||||
|
||||
if($execution and $execution->type == 'stage' and $this->config->systemMode == 'new')
|
||||
{
|
||||
global $lang;
|
||||
@@ -523,7 +527,7 @@ class executionModel extends model
|
||||
->limit(1)
|
||||
->exec();
|
||||
|
||||
if($oldExecution->type == 'kanban') $this->dao->delete()->from(TABLE_TEAM)->where('root')->eq((int)$executionID)->andWhere('type')->eq('execution')->exec();
|
||||
if($oldExecution->type == 'kanban') $this->dao->delete()->from(TABLE_TEAM)->where('root')->eq((int)$executionID)->andWhere('type')->eq('execution')->andWhere('account')->ne($oldExecution->openedBy)->exec();
|
||||
|
||||
/* Get team and language item. */
|
||||
$this->lang->execution->team = $this->lang->execution->teamname;
|
||||
|
||||
@@ -175,6 +175,7 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php if(empty($project) or $project->model != 'kanban'):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->execution->teamname;?></th>
|
||||
<td><?php echo html::input('team', $team, "class='form-control'");?></td>
|
||||
@@ -184,6 +185,7 @@
|
||||
<th><?php echo $lang->execution->copyTeam;?></th>
|
||||
<td><?php echo html::select('teams', $teams, $copyExecutionID, "class='form-control chosen' data-placeholder='{$lang->execution->copyTeamTip}'"); ?></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr>
|
||||
<th rowspan='2'><?php echo $lang->execution->owner;?></th>
|
||||
<td>
|
||||
@@ -213,10 +215,12 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php if(empty($project) or $project->model != 'kanban'):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->execution->team;?></th>
|
||||
<td colspan='3'><?php echo html::select('teamMembers[]', $users, '', "class='form-control chosen' multiple"); ?></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr>
|
||||
<th><?php echo (($from == 'execution') and ($config->systemMode == 'new')) ? $lang->execution->execDesc : $lang->execution->desc;?></th>
|
||||
<td colspan='3'>
|
||||
|
||||
@@ -189,7 +189,7 @@ js::set('hasTaskButton', $hasTaskButton);
|
||||
</div>
|
||||
<?php else:?>
|
||||
<div class='panel' id='kanbanContainer'>
|
||||
<div class='panel-body'>
|
||||
<div class='panel-body region'>
|
||||
<div id='kanbans' class='kanban'></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -955,17 +955,10 @@ class kanban extends control
|
||||
*/
|
||||
public function setColumn($columnID, $executionID = 0, $from = 'kanban')
|
||||
{
|
||||
$column = $this->kanban->getColumnById($columnID);
|
||||
$column = $this->kanban->getColumnByID($columnID);
|
||||
|
||||
if($_POST)
|
||||
{
|
||||
/* Check lane column name is unique. */
|
||||
$exist = $this->kanban->getColumnByName($this->post->name, $column->lane);
|
||||
if($exist and $exist->id != $columnID and $from != 'kanban')
|
||||
{
|
||||
return $this->sendError($this->lang->kanban->noColumnUniqueName);
|
||||
}
|
||||
|
||||
$changes = $this->kanban->updateLaneColumn($columnID, $column);
|
||||
if(dao::isError()) return $this->sendError(dao::getError());
|
||||
if($changes)
|
||||
@@ -1072,7 +1065,7 @@ class kanban extends control
|
||||
->andWhere('`column`')->eq($toColID)
|
||||
->exec();
|
||||
|
||||
$kanbanGroup = $regionID == 0 ? $this->kanban->getExecutionKanban($executionID, $browseType, $groupBy) : $this->kanban->getRDKanban($executionID, $browseType, $orderBy, $groupBy, $regionID);
|
||||
$kanbanGroup = $regionID == 0 ? $this->kanban->getExecutionKanban($executionID, $browseType, $groupBy) : $this->kanban->getRDKanban($executionID, $browseType, $orderBy, $regionID, $groupBy);
|
||||
die(json_encode($kanbanGroup));
|
||||
}
|
||||
|
||||
|
||||
@@ -718,7 +718,7 @@ function createCardMenu(options)
|
||||
{
|
||||
if(moveColumns[i].parent > 0) parentColumns.push(moveColumns[i].parent);
|
||||
if(moveColumns[i].id == card.column || $.inArray(moveColumns[i].id, parentColumns) >= 0) continue;
|
||||
moveCardItems.push({label: moveColumns[i].name, onClick: function(){moveCard(card.id, moveColumns[i].id, card.lane, card.kanban, card.region);}});
|
||||
moveCardItems.push({label: moveColumns[i].name, onClick: function(){moveCard(card.id, card.column, moveColumns[i].id, card.lane, card.lane, card.kanban, card.region);}});
|
||||
}
|
||||
moveCardItems = moveCardItems.reverse();
|
||||
items.push({label: kanbanLang.moveCard, icon: 'move', items: moveCardItems});
|
||||
|
||||
@@ -140,7 +140,6 @@ $lang->kanban->laneColor = 'Lane Color';
|
||||
$lang->kanban->setColumn = 'Column Settings';
|
||||
$lang->kanban->columnName = 'Column Name';
|
||||
$lang->kanban->columnColor = 'Column Color';
|
||||
$lang->kanban->noColumnUniqueName = 'The Kanban column name already exists.';
|
||||
$lang->kanban->moveUp = 'Swimlane Up';
|
||||
$lang->kanban->moveDown = 'Swimlane Down';
|
||||
$lang->kanban->laneMove = 'Swimlane Move';
|
||||
@@ -263,7 +262,6 @@ $lang->kanbanlane->heightTypeList['custom'] = 'Custom (Customize lane height bas
|
||||
$lang->kanbanlane->error = new stdclass();
|
||||
$lang->kanbanlane->error->mustBeInt = 'The number of cards must be a positive integer greater than 2.';
|
||||
|
||||
|
||||
$lang->kanbanregion = new stdclass();
|
||||
$lang->kanbanregion->name = 'Region Name';
|
||||
$lang->kanbanregion->default = 'Default Region';
|
||||
|
||||
@@ -140,7 +140,6 @@ $lang->kanban->laneColor = '泳道颜色';
|
||||
$lang->kanban->setColumn = '看板列设置';
|
||||
$lang->kanban->columnName = '看板列名称';
|
||||
$lang->kanban->columnColor = '看板列颜色';
|
||||
$lang->kanban->noColumnUniqueName = '看板列名称已存在';
|
||||
$lang->kanban->moveUp = '泳道上移';
|
||||
$lang->kanban->moveDown = '泳道下移';
|
||||
$lang->kanban->laneMove = '泳道移动';
|
||||
|
||||
+36
-42
@@ -333,17 +333,16 @@ class kanbanModel extends model
|
||||
public function splitColumn($columnID)
|
||||
{
|
||||
$this->loadModel('action');
|
||||
$data = fixer::input('post')->get();
|
||||
$column = $this->getColumnByID($columnID);
|
||||
$maxOrder = $this->dao->select('MAX(`order`) AS maxOrder')->from(TABLE_KANBANCOLUMN)->where('`group`')->eq($column->group)->fetch('maxOrder');
|
||||
$order = $maxOrder ? $maxOrder + 1 : 1;
|
||||
$sumChildLimit = $this->dao->select('SUM(`limit`) AS sumChildLimit')->from(TABLE_KANBANCOLUMN)->where('parent')->eq($columnID)->fetch('sumChildLimit');
|
||||
$data = fixer::input('post')->get();
|
||||
$column = $this->getColumnByID($columnID);
|
||||
$maxOrder = $this->dao->select('MAX(`order`) AS maxOrder')->from(TABLE_KANBANCOLUMN)->where('`group`')->eq($column->group)->fetch('maxOrder');
|
||||
$order = $maxOrder ? $maxOrder + 1 : 1;
|
||||
$sumChildLimit = $this->dao->select('SUM(`limit`) AS sumChildLimit')->from(TABLE_KANBANCOLUMN)->where('parent')->eq($columnID)->fetch('sumChildLimit');
|
||||
|
||||
$childrenColumn = array();
|
||||
$childrenColumn = array();
|
||||
foreach($data->name as $i => $name)
|
||||
{
|
||||
$childColumn = new stdclass();
|
||||
$childColumn->lane = $column->lane;
|
||||
$childColumn->parent = $column->id;
|
||||
$childColumn->region = $column->region;
|
||||
$childColumn->group = $column->group;
|
||||
@@ -386,9 +385,22 @@ class kanbanModel extends model
|
||||
if(!dao::isError())
|
||||
{
|
||||
$childColumnID = $this->dao->lastInsertID();
|
||||
if($i == 1) $this->dao->update(TABLE_KANBANCARD)->set('`column`')->eq($childColumnID)->where('`column`')->eq($columnID)->exec();
|
||||
$this->dao->update(TABLE_KANBANCOLUMN)->set('type')->eq("column{$childColumnID}")->where('id')->eq($childColumnID)->exec();
|
||||
$this->action->create('kanbanColumn', $childColumnID, 'created');
|
||||
|
||||
$cellList = $this->dao->select('*')->from(TABLE_KANBANCELL)->where('`column`')->eq($column->id)->fetchAll();
|
||||
foreach($cellList as $cell)
|
||||
{
|
||||
$newCell = new stdclass();
|
||||
$newCell->kanban = $cell->kanban;
|
||||
$newCell->lane = $cell->lane;
|
||||
$newCell->column = $childColumnID;
|
||||
$newCell->type = 'common';
|
||||
$newCell->cards = $i == 1 ? $cell->cards : '';
|
||||
|
||||
$this->dao->insert(TABLE_KANBANCELL)->data($newCell)->exec();
|
||||
$this->dao->update(TABLE_KANBANCELL)->set('cards')->eq('')->where('id')->eq($cell->id)->exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -836,6 +848,7 @@ class kanbanModel extends model
|
||||
->andWhere("INSTR(t2.cards, CONCAT(',',t1.id,','))")->gt(0)
|
||||
->andWhere('archived')->eq(0)
|
||||
->andWhere('t2.kanban')->eq($kanbanID)
|
||||
->andWhere('t2.type')->eq('common')
|
||||
//->orderBy('`order` asc')
|
||||
->fetchAll('id');
|
||||
|
||||
@@ -938,7 +951,7 @@ class kanbanModel extends model
|
||||
->fetchgroup('lane', 'column');
|
||||
|
||||
/* Get group objects. */
|
||||
if($browseType == 'all' or $browseType == 'story') $objectGroup['story'] = $this->loadModel('story')->getExecutionStories($executionID);
|
||||
if($browseType == 'all' or $browseType == 'story') $objectGroup['story'] = $this->loadModel('story')->getExecutionStories($executionID, 0, 0, 't1.`order`_desc', 'allStory');
|
||||
if($browseType == 'all' or $browseType == 'bug') $objectGroup['bug'] = $this->loadModel('bug')->getExecutionBugs($executionID);
|
||||
if($browseType == 'all' or $browseType == 'task') $objectGroup['task'] = $this->loadModel('execution')->getKanbanTasks($executionID, "id");
|
||||
|
||||
@@ -1017,7 +1030,7 @@ class kanbanModel extends model
|
||||
->fetchGroup('lane', 'id');
|
||||
|
||||
/* Get group objects. */
|
||||
if($browseType == 'all' or $browseType == 'story') $objectGroup['story'] = $this->loadModel('story')->getExecutionStories($executionID);
|
||||
if($browseType == 'all' or $browseType == 'story') $objectGroup['story'] = $this->loadModel('story')->getExecutionStories($executionID, 0, 0, 't1.`order`_desc', 'allStory');
|
||||
if($browseType == 'all' or $browseType == 'bug') $objectGroup['bug'] = $this->loadModel('bug')->getExecutionBugs($executionID);
|
||||
if($browseType == 'all' or $browseType == 'task') $objectGroup['task'] = $this->loadModel('execution')->getKanbanTasks($executionID, "id");
|
||||
|
||||
@@ -1116,7 +1129,8 @@ class kanbanModel extends model
|
||||
public function getKanban4Group($executionID, $browseType, $groupBy)
|
||||
{
|
||||
/* Get card data. */
|
||||
if($browseType == 'story') $cardList = $this->loadModel('story')->getExecutionStories($executionID);
|
||||
$cardList = array();
|
||||
if($browseType == 'story') $cardList = $this->loadModel('story')->getExecutionStories($executionID, 0, 0, 't1.`order`_desc', 'allStory');
|
||||
if($browseType == 'bug') $cardList = $this->loadModel('bug')->getExecutionBugs($executionID);
|
||||
if($browseType == 'task') $cardList = $this->loadModel('execution')->getKanbanTasks($executionID, "id");
|
||||
|
||||
@@ -2083,19 +2097,16 @@ class kanbanModel extends model
|
||||
$execution = $this->loadModel('execution')->getByID($executionID);
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$regionIdList = $this->dao->select('id')->from(TABLE_KANBANREGION)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('kanban')->eq($executionID)
|
||||
->fetchPairs();
|
||||
|
||||
$lanes = $this->dao->select('t1.*')->from(TABLE_KANBANLANE)->alias('t1')
|
||||
->leftJoin(TABLE_KANBANCELL)->alias('t2')->on('t1.id=t2.lane')
|
||||
$lanes = $this->dao->select('t2.*')->from(TABLE_KANBANREGION)->alias('t1')
|
||||
->leftJoin(TABLE_KANBANLANE)->alias('t2')->on('t1.id=t2.region')
|
||||
->leftJoin(TABLE_KANBANCELL)->alias('t3')->on('t2.id=t3.lane')
|
||||
->where('t1.deleted')->eq(0)
|
||||
->andWhere('t1.execution')->eq($executionID)
|
||||
->andWhere('t1.type')->eq($laneType)
|
||||
->andWhere('t1.region')->in($regionIdList)
|
||||
->beginIF(!empty($cardID))->andWhere('t2.cards')->like("%,$cardID,%")->fi()
|
||||
->orderBy('t1.`order` asc')
|
||||
->andWhere('t2.deleted')->eq(0)
|
||||
->andWhere('t1.kanban')->eq($executionID)
|
||||
->andWhere('t2.execution')->eq($executionID)
|
||||
->andWhere('t2.type')->eq($laneType)
|
||||
->beginIF(!empty($cardID))->andWhere('t3.cards')->like("%,$cardID,%")->fi()
|
||||
->orderBy('t1.`order` asc, t2.`order` asc')
|
||||
->fetchAll('id');
|
||||
|
||||
if(count($lanes) > 1) $lanes = array_slice($lanes, 0, 1);
|
||||
@@ -2147,7 +2158,7 @@ class kanbanModel extends model
|
||||
|
||||
if($laneType == 'story')
|
||||
{
|
||||
$stories = $this->loadModel('story')->getExecutionStories($executionID, 0, 0, 't1.`order`_desc', 'byModule', 0, 'story', $otherCardList);
|
||||
$stories = $this->loadModel('story')->getExecutionStories($executionID, 0, 0, 't1.`order`_desc', 'allStory', 0, 'story', $otherCardList);
|
||||
foreach($stories as $storyID => $story)
|
||||
{
|
||||
foreach($this->config->kanban->storyColumnStageList as $colType => $stage)
|
||||
@@ -2791,7 +2802,7 @@ class kanbanModel extends model
|
||||
public function getColumnByID($columnID)
|
||||
{
|
||||
$column = $this->dao->select('t1.*, t2.type as laneType')->from(TABLE_KANBANCOLUMN)->alias('t1')
|
||||
->leftjoin(TABLE_KANBANLANE)->alias('t2')->on('t1.group=t2.id')
|
||||
->leftjoin(TABLE_KANBANCELL)->alias('t2')->on('t1.id=t2.column')
|
||||
->where('t1.id')->eq($columnID)
|
||||
->fetch();
|
||||
|
||||
@@ -2800,23 +2811,6 @@ class kanbanModel extends model
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Column by column name.
|
||||
*
|
||||
* @param string $name
|
||||
* @param int $laneID
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getColumnByName($name, $laneID)
|
||||
{
|
||||
return $this->dao->select('*')
|
||||
->from(TABLE_KANBANCOLUMN)
|
||||
->where('name')->eq($name)
|
||||
->andWhere('lane')->eq($laneID)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get columns by object id.
|
||||
*
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#archivedCards .kanban-item > .info > .user {position: absolute; right: 0; top: 0}
|
||||
#archivedCards .card-actions {position: relative; padding: 15px 10px; padding-top: 0px;}
|
||||
#archivedCards .card-actions > .btn {display: block;}
|
||||
[lang^='en'] #archivedCards .card-actions > .btn {width: 55px;}
|
||||
#archivedCards .card-actions > .btn + .btn {margin-top: 10px;}
|
||||
#archivedCards .info > .time {background-color: rgba(0, 0, 0, 0.15);}
|
||||
#archivedCards .info > .users > span {display: inline-block; color: transparent; width: 2px; height: 2px; background-color: #8990a2; position:sticky; top: 3px; margin: 0 7px; border-radius: 50%; line-height: 32px;}
|
||||
|
||||
@@ -356,7 +356,7 @@ class productModel extends model
|
||||
->beginIF(!$this->app->user->admin)->andWhere('t2.id')->in($this->app->user->view->products)->fi()
|
||||
->beginIF(strpos($status, 'noclosed') !== false)->andWhere('t2.status')->ne('closed')->fi()
|
||||
->orderBy($orderBy . 't2.order asc')
|
||||
->fetchAll();
|
||||
->fetchAll('id');
|
||||
|
||||
$products = array();
|
||||
foreach($projectProducts as $product)
|
||||
|
||||
@@ -18,7 +18,7 @@ td.c-branch {overflow: hidden; text-align: left !important; text-overflow: ellip
|
||||
.c-title {width: 160px;}
|
||||
.c-branch {width: 100px;}
|
||||
.c-story, .c-status {width: 80px;}
|
||||
.c-execution {width: 50px !important;}
|
||||
.c-execution {width: 100px !important;}
|
||||
.c-bug, .c-hour {width: 60px;}
|
||||
|
||||
.plan-name {position: relative; display: flex; align-items: center;}
|
||||
|
||||
@@ -155,8 +155,8 @@ $lang->project->etc = " , etc";
|
||||
$lang->project->product = 'Product';
|
||||
$lang->project->branch = 'Branch';
|
||||
$lang->project->plan = 'Plan';
|
||||
$lang->project->kanban = 'Kanban';
|
||||
$lang->project->createKanban = 'Create Kanban';
|
||||
$lang->project->kanban = 'Kanban';
|
||||
|
||||
/* Project Kanban. */
|
||||
$lang->project->typeList = array();
|
||||
|
||||
@@ -43,7 +43,11 @@
|
||||
<div class='panel' data-url='<?php echo $this->createLink('execution', 'kanban', "kanbanID=$kanbanID");?>'>
|
||||
<div class='panel-heading'>
|
||||
<div class='kanban-name'>
|
||||
<?php if($kanban->end < helper::today() and $kanban->status != 'done' and $kanban->status != 'closed' and $kanban->status != 'suspended'):?>
|
||||
<span class="label label-doing"><?php echo $lang->project->statusList['delay'];?></span>
|
||||
<?php else:?>
|
||||
<span class="label label-<?php echo $kanban->status;?>"><?php echo zget($lang->execution->statusList, $kanban->status);?></span>
|
||||
<?php endif;?>
|
||||
<strong title='<?php echo $kanban->name;?>'><?php echo $kanban->name;?></strong>
|
||||
</div>
|
||||
<?php
|
||||
@@ -86,14 +90,16 @@
|
||||
<div class='kanban-members pull-left'>
|
||||
<?php $count = 0;?>
|
||||
<?php foreach($members as $member):?>
|
||||
<?php if($count > 1) break;?>
|
||||
<?php if($count > 2) break;?>
|
||||
<?php $count ++;?>
|
||||
<div title="<?php echo $member->realname;?>">
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$member->account], 'account' => $member->account)); ?>
|
||||
</div>
|
||||
<?php endforeach;?>
|
||||
<?php if(count($members) > 3):?>
|
||||
<?php if(count($members) > 4):?>
|
||||
<?php echo '<span>…</span>';?>
|
||||
<?php endif;?>
|
||||
<?php if(count($members) > 3):?>
|
||||
<?php $lastMember = end($members);?>
|
||||
<div title="<?php echo $lastMember->realname;?>">
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$lastMember->account], 'account' => $lastMember->account)); ?>
|
||||
|
||||
@@ -105,19 +105,7 @@ class story extends control
|
||||
|
||||
$storyID = $storyResult['id'];
|
||||
$productID = $this->post->product ? $this->post->product : $productID;
|
||||
$execution = $this->dao->findById((int)$objectID)->from(TABLE_EXECUTION)->fetch();
|
||||
|
||||
if(!empty($execution) and $execution->type == 'kanban')
|
||||
{
|
||||
if(isset($output['laneID']) and isset($output['columnID']))
|
||||
{
|
||||
$this->loadModel('kanban')->addKanbanCell($objectID, $output['laneID'], $output['columnID'], 'story', $storyID);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->loadModel('kanban')->updateLane($objectID, 'story');
|
||||
}
|
||||
}
|
||||
if($storyResult['status'] == 'exists')
|
||||
{
|
||||
$response['message'] = sprintf($this->lang->duplicate, $this->lang->story->common);
|
||||
@@ -194,7 +182,7 @@ class story extends control
|
||||
$param = $execution->type == 'project' ? "projectID=$objectID&productID=$productID" : "executionID=$objectID&orderBy=id_desc&browseType=unclosed";
|
||||
$response['locate'] = $this->createLink($moduleName, 'story', $param);
|
||||
}
|
||||
if($this->app->getViewType() == 'xhtml') $response['locate'] = $this->createLink('story', 'view', "storyID=$storyID");
|
||||
if($this->app->getViewType() == 'xhtml') $response['locate'] = $this->createLink('story', 'view', "storyID=$storyID", 'html');
|
||||
return $this->send($response);
|
||||
}
|
||||
|
||||
@@ -795,7 +783,9 @@ class story extends control
|
||||
|
||||
$product = $this->product->getByID($productID);
|
||||
$branchProduct = $product->type == 'normal' ? false : true;
|
||||
$modules = array($productID => $this->tree->getOptionMenu($productID, 'story', 0, array_keys($branches)));
|
||||
$modulePairs = $this->tree->getOptionMenu($productID, 'story', 0, array_keys($branches));
|
||||
$branchModules = $branchProduct ? $modulePairs : array('0' => $modulePairs);
|
||||
$modules = array($productID => $branchModules);
|
||||
$plans = array($productID => $this->productplan->getBranchPlanPairs($productID, '', true));
|
||||
$products = array($productID => $product);
|
||||
$branchTagOption = array($productID => $branchTagOption);
|
||||
|
||||
+18
-3
@@ -1845,7 +1845,7 @@ class storyModel extends model
|
||||
|
||||
$task = new stdclass();
|
||||
$task->execution = $executionID;
|
||||
$task->project = $projectID;
|
||||
$task->project = $projectID ? $projectID : 0;
|
||||
$task->name = $story->title;
|
||||
$task->story = $story->id;
|
||||
$task->type = $data->type;
|
||||
@@ -1983,6 +1983,8 @@ class storyModel extends model
|
||||
*/
|
||||
public function setStage($storyID)
|
||||
{
|
||||
$this->loadModel('kanban');
|
||||
|
||||
$storyID = (int)$storyID;
|
||||
$account = $this->app->user->account;
|
||||
|
||||
@@ -2014,7 +2016,11 @@ class storyModel extends model
|
||||
{
|
||||
$this->dao->update(TABLE_STORY)->set('stage')->eq('closed')->where('id')->eq($storyID)->exec();
|
||||
foreach($stages as $branch => $stage) $this->dao->replace(TABLE_STORYSTAGE)->set('story')->eq($storyID)->set('branch')->eq($branch)->set('stage')->eq('closed')->exec();
|
||||
foreach($executions as $execution => $branch) $this->dao->replace(TABLE_STORYSTAGE)->set('story')->eq($storyID)->set('branch')->eq($branch)->set('stage')->eq('closed')->exec();
|
||||
foreach($executions as $execution => $branch)
|
||||
{
|
||||
$this->dao->replace(TABLE_STORYSTAGE)->set('story')->eq($storyID)->set('branch')->eq($branch)->set('stage')->eq('closed')->exec();
|
||||
$this->kanban->updateLane($execution, 'story', $storyID);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2075,7 +2081,7 @@ class storyModel extends model
|
||||
|
||||
/* Get current stage and set as default value. */
|
||||
$currentStage = $story->stage;
|
||||
$stage = $currentStage;
|
||||
$stage = $currentStage;
|
||||
|
||||
/* Cycle all tasks, get counts of every type and every status. */
|
||||
$branchStatusList = array();
|
||||
@@ -2167,6 +2173,15 @@ class storyModel extends model
|
||||
$this->dao->update(TABLE_STORY)->set('stage')->eq(current($stages))->where('id')->eq($storyID)->exec();
|
||||
}
|
||||
|
||||
$currentStory = $this->dao->findById($storyID)->from(TABLE_STORY)->fetch();
|
||||
if($story->stage != $currentStory->stage)
|
||||
{
|
||||
foreach($executions as $executionID => $branch)
|
||||
{
|
||||
$this->kanban->updateLane($executionID, 'story', $storyID);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ class task extends control
|
||||
/* Locate the browser. */
|
||||
if($this->app->getViewType() == 'xhtml')
|
||||
{
|
||||
$taskLink = $this->createLink('task', 'view', "taskID=$taskID");
|
||||
$taskLink = $this->createLink('task', 'view', "taskID=$taskID", 'html');
|
||||
$response['locate'] = $taskLink;
|
||||
return $this->send($response);
|
||||
}
|
||||
|
||||
@@ -458,7 +458,7 @@ class taskModel extends model
|
||||
if(!empty($changes)) $this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
|
||||
if(!isset($output['laneID']) or !isset($output['columnID'])) $this->kanban->updateLane($kanbanID, 'task');
|
||||
if(!isset($output['laneID']) or !isset($output['columnID'])) $this->kanban->updateLane($executionID, 'task');
|
||||
return $mails;
|
||||
}
|
||||
|
||||
@@ -1609,6 +1609,7 @@ class taskModel extends model
|
||||
|
||||
if($task->parent > 0) $this->updateParentStatus($task->id);
|
||||
if($task->story) $this->loadModel('story')->setStage($task->story);
|
||||
if(isset($data->status) and $task->status != $data->status) $this->loadModel('kanban')->updateLane($task->execution, 'task', $taskID);
|
||||
if($task->status == 'done' and !dao::isError()) $this->loadModel('score')->create('task', 'finish', $taskID);
|
||||
|
||||
return $changes;
|
||||
|
||||
@@ -207,7 +207,8 @@ js::set('suiteID', $suiteID);
|
||||
</div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<?php if($canBatchChangeModule and !empty($productID) and $branch !== 'all'):?>
|
||||
<?php if($canBatchChangeModule and !empty($productID)):?>
|
||||
<?php if($product->type == 'normal' or ($product->type != 'normal' and $branch !== 'all')):?>
|
||||
<div class="btn-group dropup">
|
||||
<button data-toggle="dropdown" type="button" class="btn"><?php echo $lang->story->moduleAB;?> <span class="caret"></span></button>
|
||||
<?php $withSearch = count($modules) > 6;?>
|
||||
@@ -235,6 +236,7 @@ js::set('suiteID', $suiteID);
|
||||
</div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<div class="table-statistic"><?php echo $summary;?></div>
|
||||
<?php $pager->show('right', 'pagerjs');?>
|
||||
|
||||
@@ -69,7 +69,7 @@ class todo extends control
|
||||
}
|
||||
|
||||
if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'id' => $todoID));
|
||||
if($this->viewType == 'xhtml') die(js::locate($this->createLink('todo', 'view', "todoID=$todoID"), 'parent'));
|
||||
if($this->viewType == 'xhtml') die(js::locate($this->createLink('todo', 'view', "todoID=$todoID", 'html'), 'parent'));
|
||||
if(isonlybody()) die(js::closeModal('parent.parent'));
|
||||
die(js::locate($this->createLink('my', 'todo', "type=all&userID=&status=all&orderBy=id_desc"), 'parent'));
|
||||
}
|
||||
|
||||
+30
-26
@@ -130,32 +130,35 @@ class tutorialModel extends model
|
||||
public function getProject()
|
||||
{
|
||||
$project = new stdclass();
|
||||
$project->id = 2;
|
||||
$project->project = 0;
|
||||
$project->model = 'scrum';
|
||||
$project->type = 'project';
|
||||
$project->name = 'Test Project';
|
||||
$project->code = '';
|
||||
$project->lifetime = '';
|
||||
$project->begin = date('Y-m-d', strtotime('-7 days'));
|
||||
$project->end = date('Y-m-d', strtotime('+7 days'));
|
||||
$project->realBegan = '';
|
||||
$project->realEnd = '';
|
||||
$project->days = 10;
|
||||
$project->status = 'wait';
|
||||
$project->pri = '1';
|
||||
$project->desc = '';
|
||||
$project->goal = '';
|
||||
$project->acl = 'open';
|
||||
$project->parent = 0;
|
||||
$project->path = ',2,';
|
||||
$project->grade = 1;
|
||||
$project->PM = $this->app->user->account;
|
||||
$project->PO = $this->app->user->account;
|
||||
$project->QD = $this->app->user->account;
|
||||
$project->RD = $this->app->user->account;
|
||||
$project->budget = 0;
|
||||
$project->deleted = '0';
|
||||
$project->id = 2;
|
||||
$project->project = 0;
|
||||
$project->model = 'scrum';
|
||||
$project->type = 'project';
|
||||
$project->name = 'Test Project';
|
||||
$project->code = '';
|
||||
$project->lifetime = '';
|
||||
$project->begin = date('Y-m-d', strtotime('-7 days'));
|
||||
$project->end = date('Y-m-d', strtotime('+7 days'));
|
||||
$project->realBegan = '';
|
||||
$project->realEnd = '';
|
||||
$project->days = 10;
|
||||
$project->status = 'wait';
|
||||
$project->pri = '1';
|
||||
$project->desc = '';
|
||||
$project->goal = '';
|
||||
$project->acl = 'open';
|
||||
$project->parent = 0;
|
||||
$project->path = ',2,';
|
||||
$project->grade = 1;
|
||||
$project->PM = $this->app->user->account;
|
||||
$project->PO = $this->app->user->account;
|
||||
$project->QD = $this->app->user->account;
|
||||
$project->RD = $this->app->user->account;
|
||||
$project->openedBy = $this->app->user->account;
|
||||
$project->whitelist = '';
|
||||
$project->budget = 0;
|
||||
$project->displayCards = 0;
|
||||
$project->deleted = '0';
|
||||
|
||||
return $project;
|
||||
}
|
||||
@@ -291,6 +294,7 @@ class tutorialModel extends model
|
||||
$execution->totalLeft = 0;
|
||||
$execution->totalHours = 0;
|
||||
$execution->totalEstimate = 0;
|
||||
$execution->displayCards = 0;
|
||||
return $execution;
|
||||
}
|
||||
|
||||
|
||||
@@ -5401,7 +5401,7 @@ class upgradeModel extends model
|
||||
$cell->kanban = $key[0];
|
||||
$cell->lane = $key[1];
|
||||
$cell->column = $key[2];
|
||||
$cell->type = 'card';
|
||||
$cell->type = 'common';
|
||||
$cell->cards = $cards;
|
||||
|
||||
$this->dao->insert(TABLE_KANBANCELL)->data($cell)->exec();
|
||||
|
||||
+2
-2
@@ -79,11 +79,11 @@ function p($keys = '', $delimiter = ',')
|
||||
|
||||
if(empty($_result)) return print(">> 0\n");
|
||||
|
||||
if(is_array($_result) and isset($_result['code']) and $_result['code'] == 'fail') return print(">> " . (string) $_result['message'] . "\n");
|
||||
|
||||
/* Print $_result. */
|
||||
if(!$keys or !is_array($_result) and !is_object($_result)) return print(">> " . (string) $_result . "\n");
|
||||
|
||||
if(is_array($_result) and isset($_result['code']) and $_result['code'] == 'fail') return print(">> " . (string) $_result['message'] . "\n");
|
||||
|
||||
$parts = explode(';', $keys);
|
||||
$values = array();
|
||||
foreach($parts as $part)
|
||||
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试productModel->create();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
$config = new stdClass();
|
||||
$config->createFields->product = array('program' => '', 'name' => '', 'code' => '', 'PO' => '', 'QD' => '', 'RD' => '', 'type' => 'normal', 'status' => 'normal', 'desc' => '', 'acl' => 'private');
|
||||
|
||||
function createObject($module = '', $param = array())
|
||||
{
|
||||
global $config;
|
||||
foreach($config->createFields->$module as $field => $defaultValue) $_POST[$field] = $defaultValue;
|
||||
|
||||
foreach($param as $key => $value) $_POST[$key] = $value;
|
||||
|
||||
global $tester;
|
||||
$objectModel = $tester->loadModel($module);
|
||||
$objectID = $objectModel->create();
|
||||
unset($_POST);
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
return dao::getError();
|
||||
}
|
||||
else
|
||||
{
|
||||
$object = $objectModel->getByID($objectID);
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
|
||||
$create1 = array('name' => 'case1', 'code' => 'testcase1');
|
||||
$create2 = array('name' => 'case2');
|
||||
$create3 = array('name' => 'case1', 'code' => 'testcase1');
|
||||
$create4 = array('code' => 'testcase1');
|
||||
$create5 = array('name' => 'case3', 'code' => 'testcase3');
|
||||
$create6 = array('program' => '3', 'name' => 'case4', 'code' => 'testcase4');
|
||||
$create7 = array('program' => '4', 'name' => 'case5', 'code' => 'testcase5', 'type' => 'branch', 'status' => 'closed');
|
||||
|
||||
r(createObject('product', $create1)) && p('name') && e('case1'); // 测试正常的创建
|
||||
r(createObject('product', $create2)) && p('code:0') && e('『code』不能为空。'); // 测试不填产品代号的情况
|
||||
r(createObject('product', $create3)) && p('code:0') && e('『code』已经有『testcase1』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); // 测试创建重复的产品
|
||||
r(createObject('product', $create4)) && p('name:0') && e('『name』不能为空。'); // 测试不填产品名称的情况
|
||||
r(createObject('product', $create5)) && p('name,code') && e('case3,testcase3'); // 测试传入name和code
|
||||
r(createObject('product', $create6)) && p('program,name,code') && e('3,case4,testcase4'); // 测试传入program、name、code
|
||||
r(createObject('product', $create7)) && p('program,type,status') && e('4,branch,closed'); // 测试传入program、name、code、type、status
|
||||
|
||||
system("./ztest init");
|
||||
Executable
+91
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=productModel->getList();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
su($user);
|
||||
$this->product = $tester->loadModel('product');
|
||||
}
|
||||
public function getAllProducts($programID)
|
||||
{
|
||||
return $this->product->getList($programID);
|
||||
}
|
||||
public function getAllProductsCount($programID)
|
||||
{
|
||||
return count($this->getAllProducts($programID));
|
||||
}
|
||||
|
||||
public function getNoclosedProducts($programID)
|
||||
{
|
||||
return $this->product->getList($programID, 'noclosed');
|
||||
}
|
||||
public function getNoclosedProductsCount($programID)
|
||||
{
|
||||
return count($this->getNoclosedProducts($programID));
|
||||
}
|
||||
|
||||
public function getClosedProducts($programID)
|
||||
{
|
||||
return $this->product->getList($programID, 'closed');
|
||||
}
|
||||
public function getClosedProductsCount($programID)
|
||||
{
|
||||
return count($this->getClosedProducts($programID));
|
||||
}
|
||||
|
||||
public function getInvolvedProducts($programID)
|
||||
{
|
||||
return $this->product->getList($programID, 'involved');
|
||||
}
|
||||
public function getInvolvedProductsCount($programID)
|
||||
{
|
||||
return count($this->getInvolvedProducts($programID));
|
||||
}
|
||||
|
||||
public function getProductsByLine($programID, $line = 0)
|
||||
{
|
||||
return $this->product->getList($programID, 'all', 0, $line);
|
||||
}
|
||||
public function countProductsByLine($programID, $line = 0)
|
||||
{
|
||||
return count($this->getProductsByLine($programID, $line));
|
||||
}
|
||||
|
||||
public function getProductList($programID, $status = 'all', $line = 0)
|
||||
{
|
||||
return $this->product->getList($programID, $status, 0, $line);
|
||||
}
|
||||
public function getProductCount($programID, $status = 'all', $line = 0)
|
||||
{
|
||||
return count($this->getProductList($programID, $status, $line));
|
||||
}
|
||||
}
|
||||
|
||||
$adminTester = new Tester('admin');
|
||||
|
||||
r($adminTester->getAllProductsCount(1)) && p() && e('9'); // 返回项目集1下的产品数量
|
||||
r($adminTester->getAllProductsCount(0)) && p() && e('100'); // 测试传入programID=0的情况
|
||||
r($adminTester->getAllProductsCount(11)) && p() && e('0'); // 传入不存在的项目集
|
||||
|
||||
r($adminTester->getNoclosedProductsCount(1)) && p() && e('5'); // 返回项目集1下的未关闭的产品数量
|
||||
r($adminTester->getNoclosedProductsCount(0)) && p() && e('60'); // 获取所有的未关闭的产品数量
|
||||
|
||||
r($adminTester->getClosedProductsCount(1)) && p() && e('4'); // 返回项目集1下的关闭了的产品数量
|
||||
r($adminTester->getClosedProductsCount(0)) && p() && e('40'); // 返回所有的未关闭的产品数量
|
||||
|
||||
r($adminTester->getInvolvedProductsCount(1)) && p() && e('0'); // 返回项目集1下的与当前用户有关系的产品数量
|
||||
|
||||
r($adminTester->countProductsByLine(1, 1)) && p() && e('9'); // 返回项目集1下产品线1的产品数量
|
||||
r($adminTester->countProductsByLine(1, 2)) && p() && e('0'); // 返回项目集1下产品线2的产品数量
|
||||
Executable
+86
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试productModel->getPairs();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user, $orderBy = 'id_desc')
|
||||
{
|
||||
global $tester;
|
||||
su($user);
|
||||
$this->product = $tester->loadModel('product');
|
||||
$this->config = new stdclass();
|
||||
$this->config->product->orderBy = $orderBy;
|
||||
}
|
||||
|
||||
public function getProductPairs($programID)
|
||||
{
|
||||
$pairs = $this->product->getPairs('', $programID);
|
||||
if($pairs == array()) return '没有数据';
|
||||
return $pairs;
|
||||
}
|
||||
public function getProductPairsCount($programID)
|
||||
{
|
||||
$pairsCount = count($this->getProductPairs($programID));
|
||||
if($pairsCount == '没有数据') return '0';
|
||||
return $pairsCount;
|
||||
}
|
||||
|
||||
public function getAllPairs($programID)
|
||||
{
|
||||
$pairs = $this->product->getPairs('all', $programID);
|
||||
if($pairs == array()) return '没有数据';
|
||||
return $pairs;
|
||||
}
|
||||
public function getAllPairsCount($programID)
|
||||
{
|
||||
$pairsCount = count($this->getAllPairs($programID));
|
||||
if($pairsCount == '没有数据') return '0';
|
||||
return $pairsCount;
|
||||
}
|
||||
|
||||
public function getNoclosedPairs($programID)
|
||||
{
|
||||
$pairs = $this->product->getPairs('noclosed', $programID);
|
||||
if($pairs == array()) return '没有数据';
|
||||
return $pairs;
|
||||
}
|
||||
public function getNoclosedPairsCount($programID)
|
||||
{
|
||||
$pairsCount = count($this->getNoclosedPairs($programID));
|
||||
if($pairsCount == '没有数据') return '0';
|
||||
return $pairsCount;
|
||||
}
|
||||
|
||||
public function getProductPairsByOrder($programID, $mode = '', $orderBy = 'id_desc')
|
||||
{
|
||||
$this->config->product->orderBy = $orderBy;
|
||||
$pairs = $this->product->getPairs($mode, $programID);
|
||||
return checkOrder($pairs, $orderBy);
|
||||
}
|
||||
}
|
||||
|
||||
$tester = new Tester('admin');
|
||||
|
||||
r($tester->getProductPairs(10)) && p('11') && e('正常产品11'); // 测试项目集10下的11号产品
|
||||
r($tester->getProductPairs(10)) && p('55') && e('多分支产品55'); // 测试项目集10下的55号产品
|
||||
r($tester->getProductPairs(10)) && p('99') && e('多平台产品99'); // 测试项目集10下的99号产品
|
||||
r($tester->getProductPairs(11)) && p() && e('没有数据'); // 测试不存在的项目集
|
||||
|
||||
r($tester->getProductPairsCount(0)) && p() && e('100'); // 返回所有产品的数量
|
||||
r($tester->getProductPairsCount(10)) && p() && e('9'); // 返回项目集10下的所有产品
|
||||
|
||||
r($tester->getNoclosedPairs(5)) && p('6') && e('正常产品6'); // 测试项目集10下的未关闭产品5
|
||||
r($tester->getNoclosedPairsCount(10)) && p() && e('5'); // 返回项目集10下的未关闭产品的数量
|
||||
|
||||
r($tester->getProductPairsByOrder(10, '', 'program_desc')) && p() && e('1'); // 测试顺序program_desc
|
||||
r($tester->getProductPairsByOrder(11, '', 'program_asc')) && p() && e('1'); // 测试顺序program_asc
|
||||
r($tester->getProductPairsByOrder(11, '', 'type_desc')) && p() && e('1'); // 测试顺序type_desc
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php'; su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试productModel->update();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
function updateObject($module, $objectID, $param = array())
|
||||
{
|
||||
global $tester;
|
||||
$objectModel = $tester->loadModel($module);
|
||||
|
||||
$object = $objectModel->getById($objectID);
|
||||
foreach($object as $field => $value)
|
||||
{
|
||||
if(in_array($field, array_keys($param)))
|
||||
{
|
||||
$_POST[$field] = $param[$field];
|
||||
}
|
||||
else
|
||||
{
|
||||
$_POST[$field] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$change = $objectModel->update($objectID);
|
||||
if($change == array()) $change = '没有数据更新';
|
||||
unset($_POST);
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
return dao::getError();
|
||||
}
|
||||
else
|
||||
{
|
||||
return $change;
|
||||
}
|
||||
}
|
||||
|
||||
$case1 = array('name' => 'john');
|
||||
$case2 = array('code' => 'newcode1');
|
||||
$case3 = array('name' => 'jack', 'code' => 'newcode2');
|
||||
$case4 = array('name' => 'jack');
|
||||
$case5 = array('code' => 'newcode2');
|
||||
$case6 = array('name' => 'jack');
|
||||
$case7 = array('code' => 'newcode2');
|
||||
|
||||
r(updateObject('product', 2, $case1)) && p('0:field,old,new') && e('name,正常产品2,john'); // 测试更新产品名称
|
||||
r(updateObject('product', 2, $case2)) && p('0:field,old,new') && e('code,code2,newcode1'); // 测试更新产品代号
|
||||
r(updateObject('product', 2, $case3)) && p('0:field,old,new;1:field,old,new') && e('name,john,jack;code,newcode1,newcode2'); // 测试更新产品名称和代号
|
||||
r(updateObject('product', 2, $case4)) && p() && e('没有数据更新'); // 测试不更改产品名称
|
||||
r(updateObject('product', 2, $case5)) && p() && e('没有数据更新'); // 测试不更改产品代号
|
||||
r(updateObject('product', 13, $case6)) && p('name:0') && e('『产品名称』已经有『jack』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); // 测试同一项目集下产品名称不能重复
|
||||
r(updateObject('product', 13, $case7)) && p('code:0') && e('『产品代号』已经有『newcode2』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); // 测试同一项目集下产品代号不能重复
|
||||
|
||||
system("./ztest init");
|
||||
Executable
+87
@@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::create();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
function create($data)
|
||||
{
|
||||
global $app;
|
||||
|
||||
$_POST = '';
|
||||
$_POST = $data;
|
||||
|
||||
$programID = $this->program->create();
|
||||
|
||||
if(dao::isError()) return array('message' => dao::getError());
|
||||
|
||||
$program = $this->program->getById($programID);
|
||||
|
||||
$app->dbh->query("DELETE FROM ". TABLE_PROGRAM ." where name = '" . $data['name']. "'");
|
||||
return $program;
|
||||
}
|
||||
|
||||
function createData($status)
|
||||
{
|
||||
$data = array(
|
||||
'parent' => 0,
|
||||
'name' => '测试新增项目集一',
|
||||
'budget' => '',
|
||||
'budgetUnit' => 'CNY',
|
||||
'begin' => '2022-01-12',
|
||||
'end' => '2022-02-12',
|
||||
'desc' => '测试项目集描述',
|
||||
'acl' => 'private'
|
||||
);
|
||||
|
||||
switch($status)
|
||||
{
|
||||
case '1': // 创建新项目集
|
||||
break;
|
||||
case '2': // 项目集名称为空时
|
||||
$data['name'] = '';
|
||||
break;
|
||||
case '3': // 项目集的开始时间为空
|
||||
$data['begin'] = '';
|
||||
break;
|
||||
case '4': // 项目集的完成时间为空
|
||||
$data['end'] = '';
|
||||
break;
|
||||
case '5': // 项目集的计划完成时间大于计划开始时间
|
||||
$data['end'] = '2022-01-10';
|
||||
break;
|
||||
case '6': // 项目集的完成日期大于父项目集的完成日期
|
||||
$data['parent'] = '1';
|
||||
$data['begin'] = '2018-01-01';
|
||||
$data['end'] = '2022-02-10';
|
||||
break;
|
||||
default:
|
||||
}
|
||||
return $this->create($data);
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
r($t->createData(1)) && p('name') && e('测试新增项目集一'); // 创建新项目集
|
||||
r($t->createData(2)) && p('message[name]:0') && e('『项目集名称』不能为空。'); // 项目集名称为空时
|
||||
r($t->createData(3)) && p('message[begin]:0') && e('『计划开始』不能为空。'); // 项目集的开始时间为空
|
||||
r($t->createData(4)) && p('message[end]:0') && e('『计划完成』不能为空。'); // 项目集的完成时间为空
|
||||
r($t->createData(5)) && p('message[end]:0') && e('『计划完成』应当大于『2022-01-12』。'); // 项目集的计划完成时间大于计划开始时间
|
||||
r($t->createData(6)) && p('message:begin;message:end') && e('父项目集的开始日期:2019-01-01,开始日期不能小于父项目集的开始日期;父项目集的完成日期:2019-01-01,完成日期不能大于父项目集的完成日期'); // 项目集的完成日期大于父项目集的完成日期
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::createStakeholder();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function createStakeholder($programID)
|
||||
{
|
||||
$_POST['accounts'] = array('dev1', 'dev2');
|
||||
$stakeHolder = $this->program->createStakeholder($programID);
|
||||
|
||||
return $this->program->getStakeholdersByPrograms($programID);
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/*CreateStakeholder($programID). */
|
||||
r($t->createStakeholder(1)) && p('0:account;1:account') && e('dev2;dev1'); // 创建id=1的项目集的干系人dev1,dev2并查看。
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::getBudgetLeft();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getBudgetLeft($programID)
|
||||
{
|
||||
$program = $this->program->getById(1);
|
||||
|
||||
return $this->program->getBudgetLeft($program);
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* GetBudgetLeft($program). */
|
||||
r($t->getBudgetLeft(1)) && p() && e('0'); // 查看父项目集id=1的预算剩余
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::getBudgetUnitList();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getBudgetUnitList()
|
||||
{
|
||||
global $app;
|
||||
$app->loadConfig('project');
|
||||
$app->loadLang('project');
|
||||
|
||||
return $this->program->getBudgetUnitList();
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* GetBudgetUnitList(). */
|
||||
r($t->getBudgetUnitList()) && p('CNY;USD') && e('人民币;美元'); //获取货币类型列表
|
||||
@@ -8,9 +8,33 @@ title=测试 programModel::getById();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
通过id字段获取存在的项目集 >> 测试项目集1
|
||||
|
||||
*/
|
||||
|
||||
$program = $tester->loadModel('program');
|
||||
r($program->getById(1)) && p('name') && e('测试项目集1'); // 通过id字段获取存在的项目集
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getById($programID)
|
||||
{
|
||||
if(empty($this->program->getById($programID)))
|
||||
{
|
||||
return array('code' => 'fail', 'message' => 'Not Found');
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->program->getById($programID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* GetById($programID). */
|
||||
r($t->getById(1)) && p('name') && e('项目集1'); // 通过id字段获取id=1的项目集并验证它的name。
|
||||
r($t->getById(1000)) && p('message') && e('Not Found'); // 通过id字段获取id=1000的项目集并验证它的name。
|
||||
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel:: getChildren();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getChildren($programID)
|
||||
{
|
||||
$programInfo = $this->program->getChildren($programID);
|
||||
if(empty($programInfo))
|
||||
{
|
||||
return array('code' => 'fail' , 'message' => 'Not Found');
|
||||
}
|
||||
else
|
||||
{
|
||||
return $programInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* GetChildren($programID). */
|
||||
r($t->getChildren(1)) && p() && e('9'); // 通过id查找id=1的子项目集个数
|
||||
r($t->getChildren(220)) && p() && e('5'); // 通过id查找id=220的子项目集个数
|
||||
r($t->getChildren(221)) && p('message') && e('Not Found'); // 通过id查找id=221的子项目集个数
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::getInvolvedPrograms();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getInvolvedPrograms($account)
|
||||
{
|
||||
return $this->program->getInvolvedPrograms($account);
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* GetInvolvedPrograms($account). */
|
||||
r($t->getInvolvedPrograms('admin')) && p('122') && e('122'); // 查看用户admin可以看到的项目和执行id列表
|
||||
r($t->getInvolvedPrograms('test2')) && p('1;122') && e('1;122'); // 查看用户test2可以看到的项目和执行id列表
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::getKanbanGroup();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
$program = $tester->loadModel('program');
|
||||
|
||||
$result = 'Not Found';
|
||||
r($program->getKanbanGroup()) && p() && e('');
|
||||
if(empty($program->getKanbanGroup()['my'])) r($result) && p() && e($result); // 获取我的看板组
|
||||
if(empty($program->getKanbanGroup()['other'])) r($result) && p() && e($result); // 获取其他看板组
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::getList();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getListByStatus($status)
|
||||
{
|
||||
$this->program->cookie->showClosed = ture;
|
||||
$programs = $this->program->getList($status);
|
||||
if(!$programs) return 0;
|
||||
foreach($programs as $program)
|
||||
{
|
||||
if($program->status != $status and $status != 'all') return 0;
|
||||
}
|
||||
return count($programs);
|
||||
}
|
||||
|
||||
public function getListByOrder($orderBy)
|
||||
{
|
||||
$programs = $this->program->getList('all', $orderBy);
|
||||
return checkOrder($programs, $orderBy);
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* GetList($status). */
|
||||
r($t->getListByStatus('all')) && p() && e('100'); // 查看所有项目和项目集的个数
|
||||
r($t->getListByStatus('wait')) && p() && e('34'); // 查看所有'wait'的项目和项目集的个数
|
||||
r($t->getListByStatus('doing')) && p() && e('44'); // 查看所有'doing'的项目和项目集的个数
|
||||
r($t->getListByStatus('suspended')) && p() && e('11'); // 查看所有'suspended'的项目和项目集的个数
|
||||
r($t->getListByStatus('closed')) && p() && e('11'); // 查看所有'closed'的项目和项目集的个数
|
||||
|
||||
/* GetList('all', $orderBy). */
|
||||
r($t->getListByOrder('name_desc')) && p() && e(1); // 按照项目和项目集名称倒序获取项目列表
|
||||
r($t->getListByOrder('id_asc')) && p() && e(1); // 按照ID正序获取项目和项目集列表
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::getPairs();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getPairs()
|
||||
{
|
||||
$programs = $this->program->getPairs();
|
||||
if(!$programs) return 0;
|
||||
return $programs;
|
||||
}
|
||||
|
||||
public function getCount()
|
||||
{
|
||||
return count($this->program->getPairs());
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* Count().*/
|
||||
r($t->getCount()) && p() && e('10'); // 获取项目集个数
|
||||
|
||||
/* GetPairs().*/
|
||||
r($t->getPairs()) && p('1') && e('项目集1'); // 获取项目集id/name 的关联数组
|
||||
r($t->getPairs()) && p('9') && e('项目集9'); // 获取项目集id/name 的关联数组
|
||||
r($t->getPairs()) && p('11') && e(''); // 获取不存在的项目集id/name 的关联数组
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::getPairsByList();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getPairsByList($programIDList = '')
|
||||
{
|
||||
if(empty($this->program->getPairsByList($programIDList)))
|
||||
{
|
||||
return array('code' => 'fail', 'message' => 'Not Found');
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->program->getPairsByList($programIDList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* GetPairsByList($programIDList). */
|
||||
r($t->getPairsByList('1')) && p('1') && e('项目集1'); // 通过字符串'1'获取项目集名称
|
||||
r($t->getPairsByList('1,2,3')) && p('1,2,3') && e('项目集1,项目集2,项目集3'); // 通过字符串'1,2,3'获取项目集名称
|
||||
r($t->getPairsByList(array(1))) && p('1') && e('项目集1');//通过数组array(1)获取项目集名称
|
||||
r($t->getPairsByList(array(1,2,3))) && p('1,2,3') && e('项目集1,项目集2,项目集3');//通过数组array(1,2,3)获取项目集名称
|
||||
r($t->getPairsByList()) && p('message') && e('Not Found');// 通过id为空获取项目集名称
|
||||
r($t->getPairsByList('0')) && p('message') && e('Not Found');// 通过id=0获取项目集名称
|
||||
r($t->getPairsByList('11')) && p('message') && e('Not Found');// 通过id=11获取项目集名称
|
||||
|
||||
Executable
+40
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::getParentPairs();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su(%$user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getParentPairs()
|
||||
{
|
||||
return $this->program->getParentPairs();
|
||||
}
|
||||
|
||||
public function getCount()
|
||||
{
|
||||
return count($this->program->getParentPairs());
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* Count(). */
|
||||
r($t->getCount()) && p() && e('11'); //
|
||||
|
||||
/* GetParentPairs(). */
|
||||
r($t->getParentPairs()) && p('1') && e(''); // 获取父项目集的id/name关联数组
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::getParentPM();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getParentPM($programIdList)
|
||||
{
|
||||
return $this->program->getParentPM($programIdList);
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* GetParentPM($programIdList). */
|
||||
r($t->getParentPM('1')) && p() && e('0'); //
|
||||
Executable
+60
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::getProductPairs();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getProductPairsByID($programID = 0)
|
||||
{
|
||||
$program = $this->program->getByID($programID);
|
||||
if(empty($program)) return array('message' => 'Not Found');
|
||||
return $this->program->getProductPairs($programID, 'assign', 'all');
|
||||
}
|
||||
|
||||
public function getProductPairsByMod($mode = 'assign')
|
||||
{
|
||||
return $this->program->getProductPairs(1, $mode, 'noclosed');
|
||||
}
|
||||
|
||||
public function getProductPairsByStatus($status = 'all')
|
||||
{
|
||||
return $this->program->getProductPairs(1, 'assign', $status);
|
||||
}
|
||||
|
||||
public function getCount($programID = 0, $mode = 'assign', $status = 'all')
|
||||
{
|
||||
return count($this->program->getProductPairs($programID, $mode, $status));
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* GetProductPairs($programID). */
|
||||
r($t->getProductPairsByID('1')) && p('23') && e('已关闭的正常产品23'); //根据项目或项目集ID获取关联产品详情
|
||||
r($t->getProductPairsByID('1000')) && p('message') && e('Not Found'); //获取不存在的项目或项目集
|
||||
|
||||
/* GetProductPairs('all', $mode, 'noclosed'). */
|
||||
r($t->getProductPairsByMod('all')) && p('1') && e('正常产品1'); // 根据项目或项目集指派情况获取关联产品详情
|
||||
|
||||
/* GetProductPairs('all', 'assign', $status). */
|
||||
r($t->getProductPairsByStatus('all')) && p('100') && e('多平台产品100'); //根据项目或项目集状态获取关联产品详情
|
||||
|
||||
/* Count().*/
|
||||
r($t->getCount('1', 'assign', 'all')) && p() && e('10'); //查看ID=1,有指派,所有状态的关联产品数量
|
||||
r($t->getCount('1', 'assign', 'noclosed')) && p() && e('6'); //查看ID=1,有指派,未关闭的关联产品数量
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModee::getProgressList();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getProgressList()
|
||||
{
|
||||
return $this->program->getProgressList();
|
||||
}
|
||||
|
||||
public function getCount()
|
||||
{
|
||||
return count($this->program->getProgressList());
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* Count(). */
|
||||
r($t->getCount()) && p() && e('100'); // 获取项目和项目集的个数
|
||||
|
||||
/* GetProgressList(). */
|
||||
r($t->getProgressList()) && p('1') && e('0'); // 获取id=1的项目的进度
|
||||
r($t->getProgressList()) && p('11') && e('0'); // 获取id=11的项目集的进度
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::getProjectList();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
$this->config->systemMode = 'new';
|
||||
}
|
||||
|
||||
public function getListByProgramID($programID = 0)
|
||||
{
|
||||
return count($this->program->getProjectList($programID));
|
||||
}
|
||||
|
||||
public function getListByStatus($browseType = 'all')
|
||||
{
|
||||
$projects = $this->program->getProjectList('0', $browseType);
|
||||
|
||||
if(!$projects) return 0;
|
||||
foreach($projects as $project)
|
||||
{
|
||||
if($project->status != $browseType and $browseType != 'all' and $browseType != 'undone') return 0;
|
||||
if($browseType == 'undone' and ($project->status != ('wait' or 'doing'))) return 0;
|
||||
}
|
||||
|
||||
return count($projects);
|
||||
}
|
||||
|
||||
public function getListByOrder($orderBy = 'id_desc')
|
||||
{
|
||||
$projects = $this->program->getProjectList('0', 'all', '0', $orderBy);
|
||||
|
||||
return checkOrder($projects, $orderBy);
|
||||
}
|
||||
|
||||
public function getListAddProgramTitle($programTitle = 0)
|
||||
{
|
||||
return $this->program->getProjectList('0', 'all', '0', 'id_desc', '', $programTitle);
|
||||
}
|
||||
|
||||
public function getListByInvolved($involved = 0, $count = '')
|
||||
{
|
||||
$projects = $this->program->getProjectList('0', 'all', '0', 'id_desc', '', '0', $involved);
|
||||
|
||||
if($count == 'count') return count($projects);
|
||||
return $projects;
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* GetProjectList($programID). */
|
||||
r($t->getListByProgramID(0)) && p() && e('90'); // 查看当前项目集下所有项目的个数
|
||||
|
||||
/* GetProjectList(0, $browseType). */
|
||||
r($t->getListByStatus('doing')) && p() && e('44'); // 查看当前项目集下所有状态为进行中的项目的个数
|
||||
|
||||
/* GetProjectList(0, 'all', 0, $orderBy). */
|
||||
r($t->getListByOrder('name_desc')) && p() && e('1'); // 根据name倒序查看所有项目
|
||||
r($t->getListByOrder('id_desc')) && p() && e('1'); // 根据id倒序查看所有项目的个数
|
||||
|
||||
/* GetProjectList(0, 'all', 0, 'id_desc', '', $programTitle). */
|
||||
r($t->getListAddProgramTitle(0)) && p('11:name') && e('项目1'); // 查看所有项目(包含所属项目集名称)
|
||||
|
||||
/* GetProjectList(0, 'all', 0, 'id_desc', '', 0, $involved). */
|
||||
r($t->getListByInvolved(1)) && p('11:name') && e('项目1'); // 查看当前用户参与的项目
|
||||
r($t->getListByInvolved(1, 'count')) && p() && e('1'); // 查看当前用户参与的项目的个数
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::getProjectStats();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getStatsByProgramID($programID = 0)
|
||||
{
|
||||
return count($this->program->getProjectStats($programID));
|
||||
}
|
||||
|
||||
public function getStatsByStatus($browseType = 'all')
|
||||
{
|
||||
$projects = $this->program->getProjectStats('0', $browseType);
|
||||
|
||||
if(!$projects) return 0;
|
||||
foreach($projects as $project)
|
||||
{
|
||||
if($project->status != $browseType and $browseType != 'all' and $browseType != 'undone') return 0;
|
||||
if($browseType == 'undone' and ($project->status != ('wait' or 'doing'))) return 0;
|
||||
}
|
||||
|
||||
return count($projects);
|
||||
}
|
||||
|
||||
public function getStatsByOrder($orderBy = 'id_desc')
|
||||
{
|
||||
$projects = $this->program->getProjectStats('0', 'all', '0', $orderBy);
|
||||
|
||||
return checkOrder($projects, $orderBy);
|
||||
}
|
||||
|
||||
public function getStatsAddProgramTitle($programTitle = 0)
|
||||
{
|
||||
return $this->program->getProjectStats('0', 'all', '0', 'id_desc', '', $programTitle);
|
||||
}
|
||||
|
||||
public function getStatsByInvolved($involved = 0, $count = '')
|
||||
{
|
||||
$projects = $this->program->getProjectStats('0', 'all', '0', 'id_desc', '', '0', $involved);
|
||||
|
||||
if($count == 'count') return count($projects);
|
||||
return $projects;
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* GetProjectStats($programID). */
|
||||
r($t->getStatsByProgramID(0)) && p() && e('68'); // 查看当前项目集下所有未开始和进行中的项目的个数
|
||||
|
||||
/* GetProjectStats(0, $browseType). */
|
||||
r($t->getStatsByStatus('doing')) && p() && e('44'); // 查看当前项目集下所有状态为进行中的项目的个数
|
||||
|
||||
/* GetProjectStats(0, 'all', 0, $orderBy). */
|
||||
r($t->getStatsByOrder('name_desc')) && p() && e('1'); // 根据name倒序查看所有项目
|
||||
r($t->getStatsByOrder('id_desc')) && p() && e('1'); // 根据id倒序查看所有项目的个数
|
||||
|
||||
/* GetProjectStats(0, 'all', 0, 'id_desc', '', $programTitle). */
|
||||
r($t->getStatsAddProgramTitle(0)) && p('11:name') && e('项目1'); // 查看所有项目(包含所属项目集名称)
|
||||
|
||||
/* GetProjectStats(0, 'all', 0, 'id_desc', '', 0, $involved). */
|
||||
r($t->getStatsByInvolved(1)) && p('11:name') && e('项目1'); // 查看当前用户参与的项目
|
||||
r($t->getStatsByInvolved(1, 'count')) && p() && e('1'); // 查看当前用户参与的项目的个数
|
||||
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::getStakeholders();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getByID($programID = 0)
|
||||
{
|
||||
$stakeholders = $this->program->getStakeholders($programID);
|
||||
|
||||
return $stakeholders;
|
||||
}
|
||||
|
||||
public function getByOrder($orderBy = 'id_desc')
|
||||
{
|
||||
$stakeholders = $this->program->getStakeholders(2, $orderBy);
|
||||
|
||||
return checkOrder($stakeholders, $orderBy);
|
||||
}
|
||||
|
||||
public function getCount($programID = 0)
|
||||
{
|
||||
$stakeholders = $this->program->getStakeholders($programID);
|
||||
|
||||
return count($stakeholders);
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* GetStakeholders($programID). */
|
||||
r($t->getByID(2)) && p() && e('0'); // 查看项目集2的干系人信息
|
||||
|
||||
/* GetStakeholders('2', $orderBy). */
|
||||
r($t->getByOrder('id_desc')) && p() && e('1'); // 根据干系人id倒序排序
|
||||
r($t->getByOrder('id_asc')) && p() && e('1'); // 根据干系人id正序排序
|
||||
|
||||
/* Count(). */
|
||||
r($t->getCount(2)) && p() && e('0'); // 查看项目集2的干系人个数
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::getStakeholdersByPrograms();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getByPrograms($programIdList = 0)
|
||||
{
|
||||
$stakeHolders = $this->program->getStakeholdersByPrograms($programIdList);
|
||||
|
||||
return $stakeHolders;
|
||||
}
|
||||
|
||||
public function getCount($programIdList = 0)
|
||||
{
|
||||
$stakeHolders = $this->program->getStakeholdersByPrograms($programIdList);
|
||||
|
||||
return count($stakeHolders);
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* GetStakeholdersByPrograms($programIdList). */
|
||||
r($t->getByPrograms('2')) && p() && e('0'); // 获取项目集2的干系人名单
|
||||
r($t->getByPrograms('2,3')) && p() && e('0'); // 获取项目集2和项目集3的干系人名单
|
||||
|
||||
/* Count(). */
|
||||
r($t->getCount('2')) && p() && e('0'); // 获取项目集2的干系人个数
|
||||
r($t->getCount('2,3')) && p() && e('0'); // 获取项目集2和项目集3的干系人个数
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::getTeamMemberPairs();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getById($programID)
|
||||
{
|
||||
if(empty($this->program->getTeamMemberPairs($programID)))
|
||||
{
|
||||
return array('code' => 'fail', 'message' => 'Not Found');
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->program->getTeamMemberPairs($programID);
|
||||
}
|
||||
}
|
||||
|
||||
public function getCount($programID)
|
||||
{
|
||||
return count($this->program->getTeamMemberPairs($programID));
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* GetTeamMemberPairs($programID). */
|
||||
r($t->getById(1)) && p('user89') && e('U:测试89'); //获取项目集下所有团队成员
|
||||
r($t->getCount(1)) && p() && e('181'); // 获取项目集下所有团队成员
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
su('dev1');
|
||||
/**
|
||||
|
||||
title=测试 programModel::getTopByID();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getById($programID = 0)
|
||||
{
|
||||
if(empty($this->program->getTopById($programID)))
|
||||
{
|
||||
return array('code' => 'fail', 'message' => 'Not Found');
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->program->getByTopId($programID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* GetTopById($programID). */
|
||||
r($t->getByID(1)) && p('message') && e('Not Found'); // 获取项目集1最上级的项目集id
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::getTopPairs();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getTopPairs($count = '')
|
||||
{
|
||||
if($count == 'count') return count($this->program->getTopPairs());
|
||||
return $this->program->getTopPairs();
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* getTopPairs(). */
|
||||
r($t->getTopPairs()) && p('1') && e('项目集1'); // 查看id=1的父项目集
|
||||
|
||||
/* Count(). */
|
||||
r($t->getTopPairs('count')) && p() && e('10'); // 查看父项目集的个数
|
||||
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::hasUnfinished();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function getUnfinished($programID)
|
||||
{
|
||||
$program = $this->program->getById($programID);
|
||||
|
||||
return $this->program->hasUnfinished($program);
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* HasUnfinished($program). */
|
||||
r($t->getUnfinished(1)) && p() && e('88'); // 获取项目集1下未完成的项目和项目集
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::processNode();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
$program = $tester->loadModel('program');
|
||||
r($program->processNode(1, 0, 1, 1)) && p() && e(''); //
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::setTreePath();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
public function setTreePath($programID)
|
||||
{
|
||||
$programPath = $this->program->setTreePath($programID);
|
||||
if($programPath)
|
||||
{
|
||||
return $this->program->getById($programID);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* SetTreePath($programID). */
|
||||
r($t->setTreePath(12)) && p('path') && e('12,'); // 查找id=11的项目集的path
|
||||
r($t->setTreePath(1000)) && p('path') && e('0'); // 查找不存在的id=1000的项目集的path
|
||||
Executable
+78
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 programModel::update($programID);
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->program = $tester->loadModel('program');
|
||||
}
|
||||
|
||||
function update($programID, $data)
|
||||
{
|
||||
global $app;
|
||||
|
||||
$_POST = $data;
|
||||
$result = $this->program->update(10);
|
||||
if(dao::isError()) return array('message' => dao::getError());
|
||||
|
||||
$app->dbh->query("UPDATE " . TABLE_PROGRAM . " SET name = '" . $result[0]['old']. "' where id = '" . $programID . "'");
|
||||
return $result;
|
||||
}
|
||||
|
||||
function updateProgram($programID, $status = 0)
|
||||
{
|
||||
$data = array(
|
||||
'parent' => '0',
|
||||
'name' => '测试更新项目集十',
|
||||
'begin' => '2020-10-10',
|
||||
'end' => '2020-10-11',
|
||||
'acl' => 'private',
|
||||
'budget' => '100',
|
||||
'budgetUnit' => 'CNY'
|
||||
);
|
||||
|
||||
switch($status)
|
||||
{
|
||||
case '1': // 项目集名称已经存在时
|
||||
$data['name'] = '项目集1';
|
||||
break;
|
||||
case '2': // 当计划开始为空时更新项目集信息
|
||||
$data['begin'] = '';
|
||||
break;
|
||||
case '3': // 当计划完成为空时更新项目集信息
|
||||
$data['end'] = '';
|
||||
break;
|
||||
case '4': // 当计划完成小于计划开始时
|
||||
$data['end'] = '2020-01-01';
|
||||
break;
|
||||
case '5': // 项目集开始时间小于父项目集时
|
||||
$data['parent'] = '9';
|
||||
$data['begin'] = '2019-01-01';
|
||||
break;
|
||||
default: // 更新id为10的项目集信息
|
||||
}
|
||||
return $this->update($programID, $data);
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
r($t->updateProgram(10)) && p('0:new') && e('测试更新项目集十');// 更新id为10的项目集信息
|
||||
r($t->updateProgram(10, 2)) && p('message[begin]:0') && e('『计划开始』不能为空。');// 当计划开始为空时更新项目集信息
|
||||
r($t->updateProgram(10, 3)) && p('message[end]:0') && e('『计划完成』不能为空。');// 当计划完成为空时更新项目集信息
|
||||
r($t->updateProgram(10, 4)) && p('message[end]:0') && e('『计划完成』应当大于『2020-10-10』。');// 当计划完成小于计划开始时
|
||||
r($t->updateProgram(10, 1)) && p('message[name]:0') && e('『项目集名称』已经有『项目集1』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。');// 项目集名称已经存在时
|
||||
r($t->updateProgram(10, 5)) && p('message:begin;message:end') && e('父项目集的开始日期:2019-09-09,开始日期不能小于父项目集的开始日期;父项目集的完成日期:2019-09-09,完成日期不能大于父项目集的完成日期');// 项目集开始时间小于父项目集时
|
||||
@@ -10,13 +10,95 @@ pid=1
|
||||
|
||||
*/
|
||||
|
||||
$project = $tester->loadModel('project');
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
r($project->getByID(11)) && p('code,type') && e('project1,project'); // 获取ID等于11的项目
|
||||
su($user);
|
||||
$this->project = $tester->loadModel('project');
|
||||
}
|
||||
|
||||
$result = empty($project->getByID(0)) ? 'No Data!' : '';
|
||||
r($result) && p() && e('No Data!'); // 获取ID等于0的项目
|
||||
/**
|
||||
* Get project by ID.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getProjectByID($projectID)
|
||||
{
|
||||
return $this->project->getByID($projectID);
|
||||
}
|
||||
|
||||
r($project->getByID(1, 'program')) && p('name,type') && e('项目集1,program'); // 获取ID等于0的项目集
|
||||
/**
|
||||
* Get program by ID.
|
||||
*
|
||||
* @param int $programID
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getProgramByID($programID)
|
||||
{
|
||||
return $this->project->getByID($programID, 'program');
|
||||
}
|
||||
|
||||
r($project->getByID(101, 'sprint')) && p('name,type') && e('迭代1,sprint'); // 获取ID等于101的迭代
|
||||
/**
|
||||
* Get sprint by ID.
|
||||
*
|
||||
* @param int $sprintID
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getSprintByID($sprintID)
|
||||
{
|
||||
return $this->project->getByID($sprintID, 'sprint');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stage by ID.
|
||||
*
|
||||
* @param int $stageID
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getStageByID($stageID)
|
||||
{
|
||||
return $this->project->getByID($stageID, 'stage');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Kanban by ID,
|
||||
*
|
||||
* @param int $kanbanID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getKanbanByID($kanbanID)
|
||||
{
|
||||
return $this->project->getByID($kanbanID, 'kanban');
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* Get project by ID. */
|
||||
r($t->getProjectByID(11)) && p('code,type') && e('project1,project'); //获取ID等于11的项目
|
||||
r($t->getProjectByID(0)) && p('code,type') && e('0'); //获取不存在的项目
|
||||
|
||||
/* Get program by ID. */
|
||||
r($t->getProgramByID(1)) && p('code,type') && e('program1,program'); //获取ID等于1的项目集
|
||||
r($t->getProgramByID(0)) && p('code,type') && e('0'); //获取不存在的项目集
|
||||
|
||||
/* Get sprint by ID. */
|
||||
r($t->getSprintByID(101)) && p('code,type') && e('project1,sprint'); //获取ID等于101的冲刺
|
||||
r($t->getSprintByID(0)) && p('code,type') && e('0'); //获取不存在的冲刺
|
||||
|
||||
/* Get stage by ID. */
|
||||
r($t->getStageByID(131)) && p('code,type') && e('project31,stage'); //获取ID等于131的阶段
|
||||
r($t->getStageByID(0)) && p('code,type') && e('0'); //获取不存在的阶段
|
||||
|
||||
/* Get Kanban by ID. */
|
||||
r($t->getKanbanByID(161)) && p('code,type') && e('project61,kanban'); //获取ID等于161的阶段
|
||||
r($t->getKanbanByID(0)) && p('code,type') && e('0'); //获取不存在的看板
|
||||
|
||||
@@ -23,9 +23,9 @@ class Tester
|
||||
|
||||
/**
|
||||
* Check projectList get from getByIdList.
|
||||
*
|
||||
* @param array $projectIdList
|
||||
* @param int $count
|
||||
*
|
||||
* @param array $projectIdList
|
||||
* @param int $count
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 projectModel::getOverviewList;
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
@@ -12,23 +20,62 @@ class Tester
|
||||
$this->project = $tester->loadModel('project');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get project by status.
|
||||
*
|
||||
* @param string $status
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function getBystatus($status)
|
||||
{
|
||||
$projects = $this->project->getOverviewList('byStatus', $status);
|
||||
if(!$projects) return 0;
|
||||
if(!$projects)
|
||||
{
|
||||
$result = array();
|
||||
$result['code'] = 'fail';
|
||||
$result['message'] = 'No data.';
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
if($status == 'undone') $status = 'wait,doing,suspended';
|
||||
|
||||
foreach($projects as $project)
|
||||
{
|
||||
if($project->status != $status) return 0;
|
||||
if(strpos(",$status,", $project->status) === false)
|
||||
{
|
||||
$result = array();
|
||||
$result['code'] = 'fail';
|
||||
$result['message'] = 'Error data.';
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
return count($projects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get project list by order.
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getListByOrder($orderBy)
|
||||
{
|
||||
$projects = $this->project->getOverviewList('byStatus', 'wait', $orderBy);
|
||||
return checkOrder($projects, $orderBy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get project by ID.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getByID($projectID)
|
||||
{
|
||||
return $this->project->getOverviewList('byID', $projectID);
|
||||
@@ -38,12 +85,13 @@ class Tester
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* GetOverviewList('byStatus'). */
|
||||
r($t->getByStatus('wait')) && p('') && e('15'); // 获取未开始的项目
|
||||
r($t->getByStatus('wait')) && p() && e('15'); // 获取未开始的项目
|
||||
r($t->getByStatus('undone')) && p() && e('15'); // 获取状态不为done和closed的项目
|
||||
|
||||
/* GetOverviewList('byID', $id). */
|
||||
r($t->getByID(11)) && p('11:id') && e('11'); // 根据项目ID获取项目详情
|
||||
r($t->getByID(10000)) && p('id') && e(''); // 获取不存在的项目
|
||||
r($t->getByID(10000)) && p('id') && e('0'); // 获取不存在的项目
|
||||
|
||||
/* GetOverviewList('byStatus', 'wait', $orderBy). */
|
||||
r($t->getListByOrder('id_asc')) && p() && e('true'); // 按照ID正序获取项目列表
|
||||
r($t->getListByOrder('name_desc')) && p() && e('true'); // 按照项目名称倒序获取项目列表
|
||||
r($t->getListByOrder('id_asc')) && p() && e('1'); //按照ID正序获取项目列表
|
||||
r($t->getListByOrder('name_desc')) && p() && e('1'); // 按照项目名称倒序获取项目列表
|
||||
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 projectModel::getPairsByIdList;
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->project = $tester->loadModel('project');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get project pairs by ID list.
|
||||
*
|
||||
* @param array $IDList
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function getByIdList($IDList)
|
||||
{
|
||||
$projects = $this->project->getPairsByIdList($IDList);
|
||||
if(empty($projects))
|
||||
{
|
||||
$result = array();
|
||||
$result['code'] = 'fail';
|
||||
$result['message'] = 'No data.';
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
foreach($projects as $projectID => $projectName)
|
||||
{
|
||||
if(!empty($IDList) and !in_array($projectID, $IDList))
|
||||
{
|
||||
$result = array();
|
||||
$result['code'] = 'fail';
|
||||
$result['message'] = 'Error Data.';
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
return count($projects);
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
r($t->getByIdList(array(0,11,12,13))) && p() && e('3'); //查找ID为0、11、12、13的项目
|
||||
r($t->getByIdList(array())) && p() && e('90'); //查找所有项目
|
||||
Executable
+93
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 projectModel::getPairsByProgram;
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
class Tester
|
||||
{
|
||||
public function __construct($user)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
su($user);
|
||||
$this->project = $tester->loadModel('project');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get project pairs by programID.
|
||||
*
|
||||
* @param int $programID
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function getByProgram($programID)
|
||||
{
|
||||
$projects = $this->project->getPairsByProgram($programID);
|
||||
if(empty($projects))
|
||||
{
|
||||
$result = array();
|
||||
$result['code'] = 'fail';
|
||||
$result['message'] = 'No data.';
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return count($projects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get project pairs by status.
|
||||
*
|
||||
* @param string $status
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function getByStatus($status)
|
||||
{
|
||||
$projects = $this->project->getPairsByProgram(2, $status);
|
||||
if(empty($projects))
|
||||
{
|
||||
$result = array();
|
||||
$result['code'] = 'fail';
|
||||
$result['message'] = 'No data.';
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return count($projects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get project list by order.
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function getListByOrder($orderBy)
|
||||
{
|
||||
$projects = $this->project->getPairsByProgram(3, 'doing', $orderBy);
|
||||
return checkOrder($projects, $orderBy);
|
||||
}
|
||||
}
|
||||
|
||||
$t = new Tester('admin');
|
||||
|
||||
/* Get project list by program ID. */
|
||||
r($t->getByProgram('')) && p() && e('90'); //查找管理员可查看的所有项目
|
||||
r($t->getByProgram(0)) && p() && e('No data.'); //查找独立项目
|
||||
r($t->getByProgram(1)) && p() && e('9'); //查找管理员可查看的所属项目集ID为1的项目
|
||||
|
||||
/* Get project list by status. */
|
||||
r($t->getByStatus('wait')) && p() && e('3'); //查找管理员可查看的所属项目集ID为1且状态为wait的项目
|
||||
r($t->getByStatus('noclosed')) && p() && e('7'); //查找管理员可查看的所属项目集ID为1且状态不为closed的项目
|
||||
|
||||
/* Get project list by order. */
|
||||
r($t->getListByOrder('id_desc')) && p() && e('1'); //按照ID降序排序查找项目
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 projectModel::getProjectsConsumed;
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
$project = $tester->loadModel('project');
|
||||
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 projectModel::checkHasContent;
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
$project = $tester->loadModel('project');
|
||||
@@ -12,7 +12,5 @@ pid=1
|
||||
|
||||
$project = $tester->loadModel('project');
|
||||
|
||||
$result = empty($project->getSwitcher(11, 'project', 'browse')) ? 'Return!' : '';
|
||||
r($result) && p() && e('Return'); // 获取项目下拉菜单,项目列表页面没有项目下拉菜单
|
||||
|
||||
r($project->getSwitcher(11, 'project', 'execution')) && p() && e("<span class='text'>项目1</span>"); // 获取项目ID为11的迭代列表页面的项目下拉菜单,查看是否包含项目ID为11的名称
|
||||
r($project->getSwitcher(11, 'project', 'browse')) && p() && e('0'); //获取项目下拉菜单,项目列表页面没有项目下拉菜单
|
||||
r($project->getSwitcher(11, 'project', 'execution')) && p() && e("<span class='text'>项目1</span>"); //获取项目ID为11的迭代列表页面的项目下拉菜单,查看是否包含项目ID为11的名称
|
||||
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 projectModel::getTotalBugByProject;
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
@@ -17,24 +17,28 @@ $doingProject = $projectModel->getByID(13);
|
||||
$suspendProject = $projectModel->getByID(17);
|
||||
$closedProject = $projectModel->getByID(18);
|
||||
|
||||
/* Check wait project. */
|
||||
r($projectModel->isClickable($waitProject, 'start')) && p() && e('1'); // 检查未开始项目的开始按钮
|
||||
r($projectModel->isClickable($waitProject, 'finish')) && p() && e('1'); // 检查未开始项目的完成按钮
|
||||
r($projectModel->isClickable($waitProject, 'close')) && p() && e('1'); // 检查未开始项目的关闭按钮
|
||||
r($projectModel->isClickable($waitProject, 'suspend')) && p() && e('1'); // 检查未开始项目的暂停按钮
|
||||
r($projectModel->isClickable($waitProject, 'activate')) && p() && e('0'); // 检查未开始项目的激活按钮
|
||||
|
||||
/* Check doing project. */
|
||||
r($projectModel->isClickable($doingProject, 'start')) && p() && e('0'); //检查进行中项目的开始按钮
|
||||
r($projectModel->isClickable($doingProject, 'finish')) && p() && e('1'); //检查进行中项目的完成按钮
|
||||
r($projectModel->isClickable($doingProject, 'close')) && p() && e('1'); //检查进行中项目的关闭按钮
|
||||
r($projectModel->isClickable($doingProject, 'suspend')) && p() && e('1'); //检查进行中项目的暂停按钮
|
||||
r($projectModel->isClickable($doingProject, 'activate')) && p() && e('0'); //检查进行中项目的激活按钮
|
||||
|
||||
/* Check suspend project. */
|
||||
r($projectModel->isClickable($suspendProject, 'start')) && p() && e('1'); //检查已暂停项目的开始按钮
|
||||
r($projectModel->isClickable($suspendProject, 'finish')) && p() && e('0'); //检查已暂停项目的完成按钮
|
||||
r($projectModel->isClickable($suspendProject, 'close')) && p() && e('1'); //检查已暂停项目的关闭按钮
|
||||
r($projectModel->isClickable($suspendProject, 'suspend')) && p() && e('0'); //检查已暂停项目的暂停按钮
|
||||
r($projectModel->isClickable($suspendProject, 'activate')) && p() && e('0'); //检查已暂停项目的激活按钮
|
||||
|
||||
/* Check closed project. */
|
||||
r($projectModel->isClickable($closedProject, 'start')) && p() && e('0'); //检查已关闭项目的开始按钮
|
||||
r($projectModel->isClickable($closedProject, 'finish')) && p() && e('0'); //检查已关闭项目的完成按钮
|
||||
r($projectModel->isClickable($closedProject, 'close')) && p() && e('0'); //检查已关闭项目的关闭按钮
|
||||
|
||||
@@ -19,6 +19,9 @@ switch($argv[1])
|
||||
case 'control':
|
||||
ztfRun('control');
|
||||
break;
|
||||
case 'program':
|
||||
ztfRun('model/program');
|
||||
break;
|
||||
case 'model':
|
||||
ztfRun('model');
|
||||
break;
|
||||
|
||||
@@ -25,17 +25,16 @@ class xuanxuanIm extends imModel
|
||||
$products = empty($products) ? array() : array_keys($products);
|
||||
$executions = empty($executions) ? array() : array_keys($executions);
|
||||
$libIdList = array_keys($this->loadModel('doc')->getLibs('all'));
|
||||
$productID = isset($products[0]) ? $products[0] : 1;
|
||||
$executionID = isset($executions[0]) ? $executions[0] : 1;
|
||||
$productID = isset($products[0]) ? $products[0] : 0;
|
||||
$executionID = isset($executions[0]) ? $executions[0] : 0;
|
||||
$libID = isset($libIdList[0]) ? $libIdList[0] : 1;
|
||||
|
||||
$actions = new stdclass();
|
||||
if(common::hasPriv('bug', 'create') and !empty($products)) $actions->createBug = array('title' => $this->lang->im->createBug, 'url' => $baseURL . str_replace('/x.php', '/index.php', helper::createLink('bug', 'create', "product=$productID", 'xhtml')), 'height' => "600px", 'width' => "1200px");
|
||||
if(common::hasPriv('story', 'create') and !empty($products)) $actions->createStory = array('title' => $this->lang->im->createStory, 'url' => $baseURL . str_replace('/x.php', '/index.php', helper::createLink('story', 'create', "product=$productID", 'xhtml')), 'height' => "600px", 'width' => "1200px");
|
||||
if(common::hasPriv('task', 'create') and !empty($executions))$actions->createTask = array('title' => $this->lang->im->createTask, 'url' => $baseURL . str_replace('/x.php', '/index.php', helper::createLink('task', 'create', "execution=$executionID", 'xhtml')), 'height' => "600px", 'width' => "1200px");
|
||||
if(common::hasPriv('doc', 'create') and !empty($libIdList)) $actions->createDoc = array('title' => $this->lang->im->createDoc, 'url' => $baseURL . str_replace('/x.php', '/index.php', helper::createLink('doc', 'create', "objectType=&objectID=0&libID=0", 'xhtml')), 'height' => "600px", 'width' => "1200px");
|
||||
if(common::hasPriv('todo', 'create')) $actions->createTodo = array('title' => $this->lang->im->createTodo, 'url' => $baseURL . str_replace('/x.php', '/index.php', helper::createLink('todo', 'create', '', 'xhtml')), 'height' => "600px", 'width' => "1200px");
|
||||
|
||||
if(common::hasPriv('bug', 'create')) $actions->createBug = array('title' => $this->lang->im->createBug, 'url' => $baseURL . str_replace('/x.php', '/index.php', helper::createLink('bug', 'create', "product=$productID", 'xhtml')), 'height' => "600px", 'width' => "1200px");
|
||||
if(common::hasPriv('story', 'create')) $actions->createStory = array('title' => $this->lang->im->createStory, 'url' => $baseURL . str_replace('/x.php', '/index.php', helper::createLink('story', 'create', "product=$productID", 'xhtml')), 'height' => "600px", 'width' => "1200px");
|
||||
if(common::hasPriv('task', 'create')) $actions->createTask = array('title' => $this->lang->im->createTask, 'url' => $baseURL . str_replace('/x.php', '/index.php', helper::createLink('task', 'create', "execution=$executionID", 'xhtml')), 'height' => "600px", 'width' => "1200px");
|
||||
if(common::hasPriv('doc', 'create')) $actions->createDoc = array('title' => $this->lang->im->createDoc, 'url' => $baseURL . str_replace('/x.php', '/index.php', helper::createLink('doc', 'create', "objectType=&objectID=0&libID=0", 'xhtml')), 'height' => "600px", 'width' => "1200px");
|
||||
if(common::hasPriv('todo', 'create')) $actions->createTodo = array('title' => $this->lang->im->createTodo, 'url' => $baseURL . str_replace('/x.php', '/index.php', helper::createLink('todo', 'create', '', 'xhtml')), 'height' => "600px", 'width' => "1200px");
|
||||
$urls = array();
|
||||
foreach($this->config->im->cards as $moduleName => $methods)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user