Merge branch 'master' into 'autotest_ly'
# Conflicts: # test/ztest
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* The bug close entry point of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
|
||||
* @package entries
|
||||
* @version 1
|
||||
* @link http://www.zentao.net
|
||||
**/
|
||||
class bugCloseEntry extends Entry
|
||||
{
|
||||
/**
|
||||
* POST method.
|
||||
*
|
||||
* @param int $bugID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function post($bugID)
|
||||
{
|
||||
$story = $this->loadModel('bug')->getByID($bugID);
|
||||
|
||||
$fields = 'comment';
|
||||
$this->batchSetPost($fields);
|
||||
|
||||
$control = $this->loadController('bug', 'close');
|
||||
$control->close($bugID);
|
||||
|
||||
$data = $this->getData();
|
||||
if(!$data) return $this->send400('error');
|
||||
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
|
||||
|
||||
$bug = $this->bug->getByID($bugID);
|
||||
|
||||
$this->send(200, $this->format($bug, 'openedBy:user,openedDate:time,assignedTo:user,assignedDate:time,reviewedBy:user,reviewedDate:time,lastEditedBy:user,lastEditedDate:time,closedBy:user,closedDate:time,deleted:bool,mailto:userList'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* The bug confirm entry point of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
|
||||
* @package entries
|
||||
* @version 1
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
class bugConfirmEntry extends Entry
|
||||
{
|
||||
/**
|
||||
* POST method.
|
||||
*
|
||||
* @param int $bugID
|
||||
* @access public
|
||||
* @return void
|
||||
**/
|
||||
public function post($bugID)
|
||||
{
|
||||
$bug = $this->loadModel('bug')->getById($bugID);
|
||||
|
||||
$fields = 'assignedTo,mailto,comment,pri,type';
|
||||
$this->batchSetPost($fields);
|
||||
|
||||
$control = $this->loadController('bug', 'confirmBug');
|
||||
$control->confirmBug($bugID);
|
||||
|
||||
$data = $this->getData();
|
||||
if(!$data) return $this->send400('error');
|
||||
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
|
||||
|
||||
$bug = $this->bug->getById($bugID);
|
||||
|
||||
$this->send(200, $this->format($story, 'openedBy:user,openedDate:time,assignedTo:user,assignedDate:time,reviewedBy:user,reviewedDate:time,lastEditedBy:user,lastEditedDate:time,closedBy:user,closedDate:time,deleted:bool,mailto:userList'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,18 +53,16 @@ class storyEntry extends Entry
|
||||
}
|
||||
$story->moduleTitle = $moduleTitle;
|
||||
|
||||
$users = $this->loadModel('user')->getList();
|
||||
|
||||
$storyTasks = array();
|
||||
foreach($story->tasks as $executionTasks)
|
||||
{
|
||||
foreach($executionTasks as $task)
|
||||
{
|
||||
if(!isset($data->data->executions->{$task->execution})) continue;
|
||||
$storyTasks[] = $this->filterFields($task, 'id,name,type,status');
|
||||
$storyTasks[] = $this->filterFields($task, 'id,name,type,status,assignedTo');
|
||||
}
|
||||
}
|
||||
$story->tasks = $storyTasks;
|
||||
$story->tasks = $this->format($storyTasks, 'assignedTo:user');
|
||||
|
||||
$story->bugs = array();
|
||||
foreach($data->data->bugs as $bug) $story->bugs[] = $this->filterFields($bug, 'id,title,status,pri,severity');
|
||||
|
||||
@@ -20,7 +20,7 @@ class storyAssignToEntry extends Entry
|
||||
*/
|
||||
public function post($storyID)
|
||||
{
|
||||
$task = $this->loadModel('story')->getByID($storyID);
|
||||
$story = $this->loadModel('story')->getByID($storyID);
|
||||
|
||||
$fields = 'assignedTo';
|
||||
$this->batchSetPost($fields);
|
||||
|
||||
@@ -60,6 +60,9 @@ $routes['/projects/:id/bugs'] = 'projectBugs';
|
||||
$routes['/executions/:id/bugs'] = 'executionBugs';
|
||||
$routes['/bugs'] = 'bugs';
|
||||
$routes['/bugs/:id'] = 'bug';
|
||||
$routes['/bugs/:id/close'] = 'bugClose';
|
||||
$routes['/bugs/:id/assign'] = 'bugAssign';
|
||||
$routes['/bugs/:id/confirm'] = 'bugConfirm';
|
||||
|
||||
$routes['/programs/:id/projects'] = 'projects';
|
||||
$routes['/products/:id/projects'] = 'productProjects';
|
||||
|
||||
+69
-69
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
a:1:{i:0;O:8:"stdClass":12:{s:2:"id";s:1:"1";s:3:"lib";s:3:"102";s:4:"name";s:4:"user";s:4:"type";s:4:"json";s:4:"desc";s:0:"";s:7:"version";s:1:"2";s:9:"attribute";s:537:"[{"field":"id","paramsType":"int","required":"","desc":"","structType":"json","sub":1,"key":"kwoq04srulxevt93a3h","children":[]},{"field":"account","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0a387on1wpuwntd","children":[]},{"field":"realname","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0i4g80qyu8lqp28","children":[]},{"field":"avatar","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0le57o2p6vxc8ov","children":[]}]";s:7:"addedBy";s:5:"admin";s:9:"addedDate";s:19:"2022-02-28 11:26:30";s:8:"editedBy";s:5:"admin";s:10:"editedDate";s:19:"2022-02-28 11:26:30";s:7:"deleted";s:1:"0";}}
|
||||
a:2:{i:0;O:8:"stdClass":12:{s:2:"id";s:1:"1";s:3:"lib";s:1:"0";s:4:"name";s:3:"aaa";s:4:"type";s:8:"formData";s:4:"desc";s:0:"";s:7:"version";s:1:"1";s:9:"attribute";s:137:"[{"field":"aaa","paramsType":"object","required":"","desc":"","structType":"formData","sub":1,"key":"l11gznwwu2chih9mc28","children":[]}]";s:7:"addedBy";s:5:"admin";s:9:"addedDate";s:19:"2022-03-22 09:40:40";s:8:"editedBy";s:5:"admin";s:10:"editedDate";s:19:"2022-03-22 09:40:40";s:7:"deleted";s:1:"0";}i:1;O:8:"stdClass":12:{s:2:"id";s:1:"2";s:3:"lib";s:2:"10";s:4:"name";s:4:"user";s:4:"type";s:4:"json";s:4:"desc";s:0:"";s:7:"version";s:1:"2";s:9:"attribute";s:537:"[{"field":"id","paramsType":"int","required":"","desc":"","structType":"json","sub":1,"key":"kwoq04srulxevt93a3h","children":[]},{"field":"account","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0a387on1wpuwntd","children":[]},{"field":"realname","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0i4g80qyu8lqp28","children":[]},{"field":"avatar","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0le57o2p6vxc8ov","children":[]}]";s:7:"addedBy";s:5:"admin";s:9:"addedDate";s:19:"2022-03-29 09:22:00";s:8:"editedBy";s:5:"admin";s:10:"editedDate";s:19:"2022-03-29 09:22:00";s:7:"deleted";s:1:"0";}}
|
||||
@@ -1 +1 @@
|
||||
a:2:{i:0;O:8:"stdClass":8:{s:2:"id";s:1:"1";s:4:"name";s:4:"user";s:4:"type";s:4:"json";s:4:"desc";s:0:"";s:9:"attribute";s:537:"[{"field":"id","paramsType":"int","required":"","desc":"","structType":"json","sub":1,"key":"kwoq04srulxevt93a3h","children":[]},{"field":"account","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0a387on1wpuwntd","children":[]},{"field":"realname","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0i4g80qyu8lqp28","children":[]},{"field":"avatar","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0le57o2p6vxc8ov","children":[]}]";s:7:"version";s:1:"1";s:7:"addedBy";s:5:"admin";s:9:"addedDate";s:19:"2022-02-28 11:26:30";}i:1;O:8:"stdClass":8:{s:2:"id";s:1:"2";s:4:"name";s:4:"user";s:4:"type";s:4:"json";s:4:"desc";s:0:"";s:9:"attribute";s:537:"[{"field":"id","paramsType":"int","required":"","desc":"","structType":"json","sub":1,"key":"kwoq04srulxevt93a3h","children":[]},{"field":"account","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0a387on1wpuwntd","children":[]},{"field":"realname","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0i4g80qyu8lqp28","children":[]},{"field":"avatar","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0le57o2p6vxc8ov","children":[]}]";s:7:"version";s:1:"2";s:7:"addedBy";s:5:"admin";s:9:"addedDate";s:19:"2022-02-28 11:26:30";}}
|
||||
a:3:{i:0;O:8:"stdClass":8:{s:2:"id";s:1:"1";s:4:"name";s:3:"aaa";s:4:"type";s:8:"formData";s:4:"desc";s:0:"";s:9:"attribute";s:137:"[{"field":"aaa","paramsType":"object","required":"","desc":"","structType":"formData","sub":1,"key":"l11gznwwu2chih9mc28","children":[]}]";s:7:"version";s:1:"1";s:7:"addedBy";s:5:"admin";s:9:"addedDate";s:19:"2022-03-22 09:40:40";}i:1;O:8:"stdClass":8:{s:2:"id";s:1:"2";s:4:"name";s:4:"user";s:4:"type";s:4:"json";s:4:"desc";s:0:"";s:9:"attribute";s:537:"[{"field":"id","paramsType":"int","required":"","desc":"","structType":"json","sub":1,"key":"kwoq04srulxevt93a3h","children":[]},{"field":"account","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0a387on1wpuwntd","children":[]},{"field":"realname","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0i4g80qyu8lqp28","children":[]},{"field":"avatar","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0le57o2p6vxc8ov","children":[]}]";s:7:"version";s:1:"1";s:7:"addedBy";s:5:"admin";s:9:"addedDate";s:19:"2022-03-29 09:22:00";}i:2;O:8:"stdClass":8:{s:2:"id";s:1:"3";s:4:"name";s:4:"user";s:4:"type";s:4:"json";s:4:"desc";s:0:"";s:9:"attribute";s:537:"[{"field":"id","paramsType":"int","required":"","desc":"","structType":"json","sub":1,"key":"kwoq04srulxevt93a3h","children":[]},{"field":"account","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0a387on1wpuwntd","children":[]},{"field":"realname","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0i4g80qyu8lqp28","children":[]},{"field":"avatar","paramsType":"string","required":"","desc":"","structType":"json","sub":1,"key":"kwoq0le57o2p6vxc8ov","children":[]}]";s:7:"version";s:1:"2";s:7:"addedBy";s:5:"admin";s:9:"addedDate";s:19:"2022-03-29 09:22:00";}}
|
||||
+1
-1
@@ -1 +1 @@
|
||||
a:14:{i:0;O:8:"stdClass":13:{s:2:"id";s:2:"80";s:4:"root";s:3:"102";s:6:"branch";s:1:"0";s:4:"name";s:6:"用户";s:6:"parent";s:1:"0";s:4:"path";s:4:",80,";s:5:"grade";s:1:"1";s:5:"order";s:2:"20";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:1;O:8:"stdClass":13:{s:2:"id";s:2:"79";s:4:"root";s:3:"102";s:6:"branch";s:1:"0";s:4:"name";s:6:"版本";s:6:"parent";s:1:"0";s:4:"path";s:4:",79,";s:5:"grade";s:1:"1";s:5:"order";s:2:"90";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:2;O:8:"stdClass":13:{s:2:"id";s:2:"78";s:4:"root";s:3:"102";s:6:"branch";s:1:"0";s:4:"name";s:9:"测试单";s:6:"parent";s:1:"0";s:4:"path";s:4:",78,";s:5:"grade";s:1:"1";s:5:"order";s:3:"140";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:3;O:8:"stdClass":13:{s:2:"id";s:2:"77";s:4:"root";s:3:"102";s:6:"branch";s:1:"0";s:4:"name";s:6:"发布";s:6:"parent";s:1:"0";s:4:"path";s:4:",77,";s:5:"grade";s:1:"1";s:5:"order";s:2:"60";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:4;O:8:"stdClass":13:{s:2:"id";s:2:"76";s:4:"root";s:3:"102";s:6:"branch";s:1:"0";s:4:"name";s:12:"产品计划";s:6:"parent";s:1:"0";s:4:"path";s:4:",76,";s:5:"grade";s:1:"1";s:5:"order";s:2:"50";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:5;O:8:"stdClass":13:{s:2:"id";s:2:"75";s:4:"root";s:3:"102";s:6:"branch";s:1:"0";s:4:"name";s:6:"用例";s:6:"parent";s:1:"0";s:4:"path";s:4:",75,";s:5:"grade";s:1:"1";s:5:"order";s:3:"130";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:6;O:8:"stdClass":13:{s:2:"id";s:2:"74";s:4:"root";s:3:"102";s:6:"branch";s:1:"0";s:4:"name";s:3:"Bug";s:6:"parent";s:1:"0";s:4:"path";s:4:",74,";s:5:"grade";s:1:"1";s:5:"order";s:3:"120";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:7;O:8:"stdClass":13:{s:2:"id";s:2:"73";s:4:"root";s:3:"102";s:6:"branch";s:1:"0";s:4:"name";s:6:"任务";s:6:"parent";s:1:"0";s:4:"path";s:4:",73,";s:5:"grade";s:1:"1";s:5:"order";s:3:"110";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:8;O:8:"stdClass":13:{s:2:"id";s:2:"72";s:4:"root";s:3:"102";s:6:"branch";s:1:"0";s:4:"name";s:6:"需求";s:6:"parent";s:1:"0";s:4:"path";s:4:",72,";s:5:"grade";s:1:"1";s:5:"order";s:2:"70";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:9;O:8:"stdClass":13:{s:2:"id";s:2:"71";s:4:"root";s:3:"102";s:6:"branch";s:1:"0";s:4:"name";s:6:"执行";s:6:"parent";s:1:"0";s:4:"path";s:4:",71,";s:5:"grade";s:1:"1";s:5:"order";s:3:"100";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:10;O:8:"stdClass":13:{s:2:"id";s:2:"70";s:4:"root";s:3:"102";s:6:"branch";s:1:"0";s:4:"name";s:6:"项目";s:6:"parent";s:1:"0";s:4:"path";s:4:",70,";s:5:"grade";s:1:"1";s:5:"order";s:2:"80";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:11;O:8:"stdClass":13:{s:2:"id";s:2:"69";s:4:"root";s:3:"102";s:6:"branch";s:1:"0";s:4:"name";s:6:"产品";s:6:"parent";s:1:"0";s:4:"path";s:4:",69,";s:5:"grade";s:1:"1";s:5:"order";s:2:"40";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:12;O:8:"stdClass":13:{s:2:"id";s:2:"68";s:4:"root";s:3:"102";s:6:"branch";s:1:"0";s:4:"name";s:9:"项目集";s:6:"parent";s:1:"0";s:4:"path";s:4:",68,";s:5:"grade";s:1:"1";s:5:"order";s:2:"30";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:13;O:8:"stdClass":13:{s:2:"id";s:2:"67";s:4:"root";s:3:"102";s:6:"branch";s:1:"0";s:4:"name";s:5:"Token";s:6:"parent";s:1:"0";s:4:"path";s:4:",67,";s:5:"grade";s:1:"1";s:5:"order";s:2:"10";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}}
|
||||
a:14:{i:0;O:8:"stdClass":13:{s:2:"id";s:2:"19";s:4:"root";s:2:"10";s:6:"branch";s:1:"0";s:4:"name";s:6:"需求";s:6:"parent";s:1:"0";s:4:"path";s:4:",19,";s:5:"grade";s:1:"1";s:5:"order";s:2:"70";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:1;O:8:"stdClass":13:{s:2:"id";s:2:"18";s:4:"root";s:2:"10";s:6:"branch";s:1:"0";s:4:"name";s:6:"任务";s:6:"parent";s:1:"0";s:4:"path";s:4:",18,";s:5:"grade";s:1:"1";s:5:"order";s:3:"110";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:2;O:8:"stdClass":13:{s:2:"id";s:2:"17";s:4:"root";s:2:"10";s:6:"branch";s:1:"0";s:4:"name";s:3:"Bug";s:6:"parent";s:1:"0";s:4:"path";s:4:",17,";s:5:"grade";s:1:"1";s:5:"order";s:3:"120";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:3;O:8:"stdClass":13:{s:2:"id";s:2:"16";s:4:"root";s:2:"10";s:6:"branch";s:1:"0";s:4:"name";s:6:"用例";s:6:"parent";s:1:"0";s:4:"path";s:4:",16,";s:5:"grade";s:1:"1";s:5:"order";s:3:"130";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:4;O:8:"stdClass":13:{s:2:"id";s:2:"15";s:4:"root";s:2:"10";s:6:"branch";s:1:"0";s:4:"name";s:12:"产品计划";s:6:"parent";s:1:"0";s:4:"path";s:4:",15,";s:5:"grade";s:1:"1";s:5:"order";s:2:"50";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:5;O:8:"stdClass":13:{s:2:"id";s:2:"14";s:4:"root";s:2:"10";s:6:"branch";s:1:"0";s:4:"name";s:6:"发布";s:6:"parent";s:1:"0";s:4:"path";s:4:",14,";s:5:"grade";s:1:"1";s:5:"order";s:2:"60";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:6;O:8:"stdClass":13:{s:2:"id";s:2:"13";s:4:"root";s:2:"10";s:6:"branch";s:1:"0";s:4:"name";s:9:"测试单";s:6:"parent";s:1:"0";s:4:"path";s:4:",13,";s:5:"grade";s:1:"1";s:5:"order";s:3:"140";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:7;O:8:"stdClass":13:{s:2:"id";s:2:"12";s:4:"root";s:2:"10";s:6:"branch";s:1:"0";s:4:"name";s:6:"版本";s:6:"parent";s:1:"0";s:4:"path";s:4:",12,";s:5:"grade";s:1:"1";s:5:"order";s:2:"90";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:8;O:8:"stdClass":13:{s:2:"id";s:2:"11";s:4:"root";s:2:"10";s:6:"branch";s:1:"0";s:4:"name";s:6:"用户";s:6:"parent";s:1:"0";s:4:"path";s:4:",11,";s:5:"grade";s:1:"1";s:5:"order";s:2:"20";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:9;O:8:"stdClass":13:{s:2:"id";s:2:"20";s:4:"root";s:2:"10";s:6:"branch";s:1:"0";s:4:"name";s:6:"执行";s:6:"parent";s:1:"0";s:4:"path";s:4:",20,";s:5:"grade";s:1:"1";s:5:"order";s:3:"100";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:10;O:8:"stdClass":13:{s:2:"id";s:2:"21";s:4:"root";s:2:"10";s:6:"branch";s:1:"0";s:4:"name";s:6:"项目";s:6:"parent";s:1:"0";s:4:"path";s:4:",21,";s:5:"grade";s:1:"1";s:5:"order";s:2:"80";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:11;O:8:"stdClass":13:{s:2:"id";s:2:"22";s:4:"root";s:2:"10";s:6:"branch";s:1:"0";s:4:"name";s:6:"产品";s:6:"parent";s:1:"0";s:4:"path";s:4:",22,";s:5:"grade";s:1:"1";s:5:"order";s:2:"40";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:12;O:8:"stdClass":13:{s:2:"id";s:2:"23";s:4:"root";s:2:"10";s:6:"branch";s:1:"0";s:4:"name";s:9:"项目集";s:6:"parent";s:1:"0";s:4:"path";s:4:",23,";s:5:"grade";s:1:"1";s:5:"order";s:2:"30";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}i:13;O:8:"stdClass":13:{s:2:"id";s:2:"24";s:4:"root";s:2:"10";s:6:"branch";s:1:"0";s:4:"name";s:5:"Token";s:6:"parent";s:1:"0";s:4:"path";s:4:",24,";s:5:"grade";s:1:"1";s:5:"order";s:2:"10";s:4:"type";s:3:"api";s:5:"owner";s:0:"";s:9:"collector";s:0:"";s:5:"short";s:0:"";s:7:"deleted";s:1:"0";}}
|
||||
@@ -6,7 +6,6 @@ $lang->custom->notice->readOnlyOfExecution = "If Change Forbidden, any change on
|
||||
$lang->custom->moduleName['execution'] = $lang->custom->execution;
|
||||
|
||||
$lang->custom->object = array();
|
||||
$lang->custom->object['project'] = 'Project';
|
||||
$lang->custom->object['execution'] = $lang->custom->execution;
|
||||
$lang->custom->object['story'] = $lang->SRCommon;
|
||||
$lang->custom->object['task'] = 'Task';
|
||||
@@ -15,7 +14,8 @@ $lang->custom->object['user'] = 'User';
|
||||
$lang->custom->object['block'] = 'Block';
|
||||
|
||||
$lang->custom->task = new stdClass();
|
||||
$lang->custom->task->fields['priList'] = 'Priority';
|
||||
$lang->custom->task->fields['priList'] = 'Priority';
|
||||
$lang->custom->task->fields['typeList'] = 'Type';
|
||||
|
||||
$lang->custom->story = new stdClass();
|
||||
$lang->custom->story->fields['priList'] = 'Priority';
|
||||
|
||||
@@ -6,7 +6,6 @@ $lang->custom->notice->readOnlyOfExecution = "禁止修改后,已关闭{$lang-
|
||||
$lang->custom->moduleName['execution'] = $lang->custom->execution;
|
||||
|
||||
$lang->custom->object = array();
|
||||
$lang->custom->object['project'] = '项目';
|
||||
$lang->custom->object['execution'] = $lang->custom->execution;
|
||||
$lang->custom->object['story'] = $lang->SRCommon;
|
||||
$lang->custom->object['task'] = '任务';
|
||||
|
||||
@@ -2405,6 +2405,7 @@ class baseRouter
|
||||
$view->systemMode = $this->config->systemMode;
|
||||
$view->sprintConcept = zget($this->config->custom, 'sprintConcept', '0');
|
||||
$view->URAndSR = zget($this->config->custom, 'URAndSR', '0');
|
||||
$view->maxUploadSize = strtoupper(ini_get('upload_max_filesize'));
|
||||
|
||||
$this->session->set('random', mt_rand(0, 10000));
|
||||
$view->sessionName = session_name();
|
||||
|
||||
@@ -90,10 +90,11 @@ class pager extends basePager
|
||||
*
|
||||
* @param string $align
|
||||
* @param string $type
|
||||
* @param int $maxRecPerPage
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function show($align = 'right', $type = 'full')
|
||||
public function show($align = 'right', $type = 'full', $maxRecPerPage = 0)
|
||||
{
|
||||
if($type == 'pagerjs')
|
||||
{
|
||||
@@ -110,7 +111,26 @@ class pager extends basePager
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "<ul class='pager' data-page-cookie='{$this->pageCookie}' data-ride='pager' data-rec-total='{$this->recTotal}' data-rec-per-page='{$this->recPerPage}' data-page='{$this->pageID}' data-link-creator='" . helper::createLink($this->moduleName, $this->methodName, $params) . "'></ul>";
|
||||
$pageSizeOptions = '';
|
||||
if($maxRecPerPage)
|
||||
{
|
||||
/* Set record per page. */
|
||||
for($i = 5; $i <= 50; $i += 5) $options[] = $i;
|
||||
$options = array_merge($options, array(100, 200, 500, 1000, 2000));
|
||||
|
||||
$pageSizeOptions = 'data-page-size-options="';
|
||||
foreach($options as $option)
|
||||
{
|
||||
$pageSizeOptions .= "$option,";
|
||||
if($option >= $maxRecPerPage)
|
||||
{
|
||||
$pageSizeOptions = trim($pageSizeOptions, ',') . '"';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo "<ul class='pager' $pageSizeOptions data-page-cookie='{$this->pageCookie}' data-ride='pager' data-rec-total='{$this->recTotal}' data-rec-per-page='{$this->recPerPage}' data-page='{$this->pageID}' data-link-creator='" . helper::createLink($this->moduleName, $this->methodName, $params) . "'></ul>";
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1259,7 +1259,14 @@ class bug extends control
|
||||
return print(js::closeModal('parent.parent'));
|
||||
}
|
||||
}
|
||||
return print(js::locate($this->createLink('bug', 'view', "bugID=$bugID"), 'parent'));
|
||||
if(defined('RUN_MODE') && RUN_MODE == 'api')
|
||||
{
|
||||
return $this->send(array('status' => 'success', 'data' => $bugID));
|
||||
}
|
||||
else
|
||||
{
|
||||
return print(js::locate($this->createLink('bug', 'view', "bugID=$bugID"), 'parent'));
|
||||
}
|
||||
}
|
||||
|
||||
if($this->app->tab == 'project')
|
||||
@@ -1711,7 +1718,7 @@ class bug extends control
|
||||
}
|
||||
if(defined('RUN_MODE') && RUN_MODE == 'api')
|
||||
{
|
||||
return print(array('status' => 'success', 'data' => $bugID));
|
||||
return $this->send(array('status' => 'success', 'data' => $bugID));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -504,7 +504,9 @@ function setStories(moduleID, productID, storyID)
|
||||
{
|
||||
var branch = $('#branch').val();
|
||||
if(typeof(branch) == 'undefined') branch = 0;
|
||||
link = createLink('story', 'ajaxGetProductStories', 'productID=' + productID + '&branch=' + branch + '&moduleID=' + moduleID + '&storyID=' + storyID);
|
||||
var executionID = $('#execution').val();
|
||||
if(typeof(executionID) == 'undefined') executionID = 0;
|
||||
link = createLink('story', 'ajaxGetProductStories', 'productID=' + productID + '&branch=' + branch + '&moduleID=' + moduleID + '&storyID=' + storyID + '&onlyOption=false&status=&limit=0&type=full&hasParent=1&executionID=' + executionID);
|
||||
$.get(link, function(stories)
|
||||
{
|
||||
if(!stories) stories = '<select id="story" name="story" class="form-control"></select>';
|
||||
|
||||
@@ -240,14 +240,14 @@ class build extends control
|
||||
|
||||
/* Get stories and stages. */
|
||||
$storyPager = new pager($type == 'story' ? $recTotal : 0, $recPerPage, $type == 'story' ? $pageID : 1);
|
||||
$stories = $this->dao->select('*')->from(TABLE_STORY)->where('id')->in($build->stories)->andWhere('deleted')->eq(0)
|
||||
->beginIF($type == 'story')->orderBy($orderBy)->fi()
|
||||
$stories = $this->dao->select('t1.*, t2.stage')->from(TABLE_STORY)->alias('t1')
|
||||
->leftJoin(TABLE_STORYSTAGE)->alias('t2')->on('t1.id = t2.story')
|
||||
->where('t1.id')->in($build->stories)
|
||||
->andWhere('t1.deleted')->eq(0)
|
||||
->beginIF($type == 'story')->orderBy("t1.$orderBy")->fi()
|
||||
->page($storyPager)
|
||||
->fetchAll('id');
|
||||
|
||||
$stages = $this->dao->select('*')->from(TABLE_STORYSTAGE)->where('story')->in($build->stories)->andWhere('branch')->eq($build->branch)->fetchPairs('story', 'stage');
|
||||
foreach($stages as $storyID => $stage) $stories[$storyID]->stage = $stage;
|
||||
|
||||
/* Set menu. */
|
||||
if($this->app->tab == 'project')
|
||||
{
|
||||
|
||||
+11
-1
@@ -2244,7 +2244,7 @@ EOD;
|
||||
*/
|
||||
public function checkIframe()
|
||||
{
|
||||
if($this->app->getViewType() != 'html' || helper::isAjaxRequest()) return;
|
||||
if($this->app->getViewType() != 'html' || helper::isAjaxRequest() || isset($_GET['_single'])) return;
|
||||
|
||||
if(isset($_SERVER['HTTP_SEC_FETCH_DEST']))
|
||||
{
|
||||
@@ -2279,6 +2279,16 @@ EOD;
|
||||
$module = strtolower($module);
|
||||
$method = strtolower($method);
|
||||
|
||||
/* If the user is doing a tutorial, have all tutorial privs. */
|
||||
if(defined('TUTORIAL'))
|
||||
{
|
||||
$app->loadLang('tutorial');
|
||||
foreach($lang->tutorial->tasks as $task)
|
||||
{
|
||||
if($task['nav']['module'] == $module and $task['nav']['method'] = $method) return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the parent object is closed. */
|
||||
if(!empty($method) and strpos('close|batchclose', $method) === false and !commonModel::canBeChanged($module, $object)) return false;
|
||||
|
||||
|
||||
@@ -33,7 +33,10 @@
|
||||
#kanbanList .no-flex .kanban-lane > .kanban-sub-lanes[data-sub-lanes-count="2"] > .kanban-sub-lane {min-height: 45px;}
|
||||
|
||||
.kanban-affixed {padding-top: 72px;}
|
||||
.kanban-affixed > .kanban-header {position: fixed!important; top: 0; background: rgba(80,80,80,.9); color: #fff; z-index: 100;}
|
||||
.kanban-affixed > .kanban-header {position: fixed!important; top: 0; color: #fff; z-index: 100; overflow: hidden; min-width: 0; background: none;}
|
||||
.kanban-affixed > .kanban-header > .kanban-header-cols {position: absolute; height: 100%; top: 0; background: rgba(80,80,80,.9);}
|
||||
.kanban-affixed > .kanban-header > .kanban-group-header {display: none;}
|
||||
.kanban-affixed > .kanban-header > .kanban-header-cols:before {display: block; content: ' '; position: absolute; left: -20px; top: 0; bottom: 0; background-color: inherit; width: 20px;}
|
||||
|
||||
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-item {padding: 0;}
|
||||
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-lane-items {height: 100%; display: flex; flex-direction: column; justify-content: center; padding: 0; overflow: hidden;}
|
||||
@@ -60,6 +63,10 @@
|
||||
#kanbanList .kanban-item-span + .kanban-item-span > .project-row {border-top: 2px solid #fff;}
|
||||
#kanbanList .project-row > .project-col {float: left; width: 50%; padding: 10px;}
|
||||
#kanbanList .project-row > .execution-item {position: absolute!important; left: 100%; top: 0}
|
||||
|
||||
.region-affixed-scrollbar {position: fixed; bottom: 0; overflow-x: auto; z-index: 100; background-color: rgba(255,255,255,.85); display: none;}
|
||||
.has-affixed-region .region-affixed-scrollbar {display: block;}
|
||||
.region-affixed-holder {height: 1px;}
|
||||
</style>
|
||||
<script>
|
||||
/**
|
||||
@@ -376,20 +383,46 @@ function renderKanbanItem(item, $item, col, lane, kanban)
|
||||
function affixKanbanHeader($kanbanBoard, affixed)
|
||||
{
|
||||
var $header = $kanbanBoard.children('.kanban-header');
|
||||
var headerStyle = {width: '', left: ''};
|
||||
var $headerCols = $header.children('.kanban-header-cols');
|
||||
var headerStyle = {width: '', left: 0};
|
||||
var headerColsStyle = {width: '', marginLeft: ''};
|
||||
if(affixed)
|
||||
{
|
||||
headerStyle.width = $kanbanBoard.width();
|
||||
if($kanbanBoard[0].getBoundingClientRect)
|
||||
{
|
||||
headerStyle.left = $kanbanBoard[0].getBoundingClientRect().left;
|
||||
}
|
||||
var $kanban = $kanbanBoard.closest('.kanban');
|
||||
var kanbanBounding = $kanban[0].getBoundingClientRect();
|
||||
var kanbanBoardBounding = $kanbanBoard[0].getBoundingClientRect();
|
||||
var laneNameWidth = +$headerCols.css('left').replace('px', '');
|
||||
headerStyle.width = kanbanBounding.width;
|
||||
headerStyle.left = kanbanBounding.left;
|
||||
headerColsStyle.width = kanbanBoardBounding.width - laneNameWidth;
|
||||
headerColsStyle.marginLeft = kanbanBoardBounding.left - kanbanBounding.left;
|
||||
}
|
||||
$header.css(headerStyle);
|
||||
$headerCols.css(headerColsStyle);
|
||||
$kanbanBoard.toggleClass('kanban-affixed', !!affixed);
|
||||
$kanbanBoard.css('padding-top', affixed ? $header.outerHeight() : '');
|
||||
}
|
||||
|
||||
function affixRegionScrollbar($region)
|
||||
{
|
||||
$region.addClass('region-affixed');
|
||||
var $container = $region.parent();
|
||||
var $scrollbar = $container.find('.region-affixed-scrollbar');
|
||||
|
||||
if(!$scrollbar.length)
|
||||
{
|
||||
$scrollbar = $('<div class="region-affixed-scrollbar"><div class="region-affixed-holder"></div></div>').css('height', $.zui.getScrollbarSize() + 1).appendTo($container).on('scroll', function()
|
||||
{
|
||||
$('#kanban .region-affixed .kanban').scrollLeft($scrollbar.scrollLeft());
|
||||
});
|
||||
}
|
||||
var $kanban = $region.find('.kanban');
|
||||
$scrollbar.width($region.outerWidth());
|
||||
$scrollbar.find('.region-affixed-holder').width($kanban[0].scrollWidth);
|
||||
var scrollLeft = $kanban.scrollLeft();
|
||||
if(scrollLeft !== $scrollbar.scrollLeft()) $scrollbar.scrollLeft(scrollLeft);
|
||||
}
|
||||
|
||||
/** Update kanban affix state for all boards in page */
|
||||
function updateKanbanAffixState()
|
||||
{
|
||||
@@ -398,7 +431,7 @@ function updateKanbanAffixState()
|
||||
var containerTop = window.kanbanAffixContainer ? $(window.kanbanAffixContainer)[0].getBoundingClientRect().top : 0;
|
||||
var $currentAffixedBoard;
|
||||
|
||||
$('.kanban-board').each(function()
|
||||
$boards.each(function()
|
||||
{
|
||||
var $board = $(this);
|
||||
var bounds = $board[0].getBoundingClientRect();
|
||||
@@ -414,6 +447,28 @@ function updateKanbanAffixState()
|
||||
}
|
||||
|
||||
if($currentAffixedBoard) affixKanbanHeader($currentAffixedBoard, true);
|
||||
|
||||
|
||||
var $kanban = $('#kanban');
|
||||
var $regions = $kanban.children('.region');
|
||||
if(!$regions.length) return;
|
||||
var $lastAffixedRegion = $regions.filter('.region-affixed');
|
||||
var $currentAffixedRegion = [];
|
||||
var winHeight = $(window).height();
|
||||
$regions.each(function()
|
||||
{
|
||||
var $region = $(this);
|
||||
var bounds = this.getBoundingClientRect();
|
||||
if(bounds.bottom > winHeight && bounds.top < (winHeight - 64))
|
||||
{
|
||||
$currentAffixedRegion = $region;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
$kanban.toggleClass('has-affixed-region', !!$currentAffixedRegion.length);
|
||||
if($lastAffixedRegion.length && $currentAffixedRegion[0] !== $lastAffixedRegion[0]) $lastAffixedRegion.removeClass('region-affixed');
|
||||
if($currentAffixedRegion.length) affixRegionScrollbar($currentAffixedRegion);
|
||||
}
|
||||
|
||||
/** Try to update kanban affix state */
|
||||
|
||||
@@ -63,7 +63,8 @@ $(function()
|
||||
element: $('#' + markdownEditorID)[0],
|
||||
status: false,
|
||||
spellChecker: false,
|
||||
forceSync: true
|
||||
forceSync: true,
|
||||
renderingConfig: {markedOptions: {smartLists: false}}
|
||||
};
|
||||
var markdown = new SimpleMDE(options);
|
||||
if(!window.markdownEditor) window.markdownEditor = {};
|
||||
|
||||
@@ -19,6 +19,8 @@ class custom extends control
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
if($this->config->vision == 'lite') return print(js::locate(inlink('execution')));
|
||||
|
||||
if(($this->config->systemMode == 'new') and common::hasPriv('custom', 'set'))
|
||||
{
|
||||
return print(js::locate(inlink('set', "module=project&field=" . key($this->lang->custom->project->fields))));
|
||||
|
||||
@@ -1230,6 +1230,8 @@ class execution extends control
|
||||
*/
|
||||
public function team($executionID = 0)
|
||||
{
|
||||
$this->app->session->set('teamList', $this->app->getURI(true), 'execution');
|
||||
|
||||
$execution = $this->commonAction($executionID);
|
||||
$executionID = $execution->id;
|
||||
|
||||
@@ -1976,6 +1978,8 @@ class execution extends control
|
||||
*/
|
||||
public function view($executionID)
|
||||
{
|
||||
$this->app->session->set('teamList', $this->app->getURI(true), 'execution');
|
||||
|
||||
$executionID = $this->execution->saveState((int)$executionID, $this->executions);
|
||||
$execution = $this->execution->getById($executionID, true);
|
||||
$type = $this->config->vision == 'lite' ? 'kanban' : 'stage,sprint,kanban';
|
||||
@@ -2639,7 +2643,8 @@ class execution extends control
|
||||
{
|
||||
$this->execution->manageMembers($executionID);
|
||||
$this->loadModel('action')->create('team', $executionID, 'managedTeam');
|
||||
return print(js::locate($this->createLink('execution', 'team', "executionID=$executionID"), 'parent'));
|
||||
$link = $this->session->teamList ? $this->session->teamList : $this->createLink('execution', 'team', "executionID=$executionID");
|
||||
return print(js::locate($link, 'parent'));
|
||||
}
|
||||
|
||||
/* Load model. */
|
||||
@@ -3129,6 +3134,7 @@ class execution extends control
|
||||
foreach($projects as $project)
|
||||
{
|
||||
$executions = zget($executionGroups, $project->id, array());
|
||||
if(isset($project->model) and $project->model == 'waterfall') ksort($executions);
|
||||
|
||||
foreach($executions as $execution)
|
||||
{
|
||||
@@ -3285,9 +3291,11 @@ class execution extends control
|
||||
{
|
||||
$projects = $this->project->getPairsByProgram();
|
||||
$projectID = $this->project->saveState($projectID, $projects);
|
||||
$project = $this->loadModel('project')->getByID($projectID);
|
||||
$project = $this->loadModel('project')->getByID($projectID);
|
||||
$this->view->project = $project;
|
||||
$this->project->setMenu($projectID);
|
||||
|
||||
if(!empty($project->model) and $project->model == 'kanban' and !(defined('RUN_MODE') and RUN_MODE == 'api')) return $this->locate($this->createLink('project', 'index', "projectID=$projectID"));
|
||||
}
|
||||
|
||||
if($this->app->viewType == 'mhtml')
|
||||
|
||||
@@ -60,3 +60,4 @@
|
||||
|
||||
.createButton {margin-right: 5px;}
|
||||
.headerTop {top: 0px !important;}
|
||||
.kanban-header-col>.actions>a {padding: 0px !important;}
|
||||
|
||||
@@ -988,6 +988,30 @@ function changeKanbanScaleSize(newScaleSize)
|
||||
return newScaleSize;
|
||||
}
|
||||
|
||||
/** Affix kanban board header */
|
||||
window.affixKanbanHeader = function($kanbanBoard, affixed)
|
||||
{
|
||||
var $header = $kanbanBoard.children('.kanban-header');
|
||||
var $headerCols = $header.children('.kanban-header-cols');
|
||||
var headerStyle = {width: '', left: 0};
|
||||
var headerColsStyle = {width: '', marginLeft: ''};
|
||||
if(affixed)
|
||||
{
|
||||
var $kanban = $('#kanbanContainer');
|
||||
var kanbanBounding = $kanban[0].getBoundingClientRect();
|
||||
var kanbanBoardBounding = $kanbanBoard[0].getBoundingClientRect();
|
||||
var laneNameWidth = +$headerCols.css('left').replace('px', '');
|
||||
headerStyle.width = kanbanBounding.width;
|
||||
headerStyle.left = kanbanBounding.left;
|
||||
headerColsStyle.width = kanbanBoardBounding.width - laneNameWidth;
|
||||
headerColsStyle.marginLeft = kanbanBoardBounding.left - kanbanBounding.left;
|
||||
}
|
||||
$header.css(headerStyle);
|
||||
$headerCols.css(headerColsStyle);
|
||||
$kanbanBoard.toggleClass('kanban-affixed', !!affixed);
|
||||
$kanbanBoard.css('padding-top', affixed ? $header.outerHeight() : '');
|
||||
}
|
||||
|
||||
/* Example code: */
|
||||
$(function()
|
||||
{
|
||||
|
||||
@@ -316,6 +316,14 @@ class executionModel extends model
|
||||
$this->config->execution->create->requiredFields .= ',project';
|
||||
}
|
||||
|
||||
/* Judge workdays is legitimate. */
|
||||
$workdays = helper::diffDate($_POST['end'], $_POST['begin']) + 1;
|
||||
if(isset($_POST['days']) and $_POST['days'] > $workdays)
|
||||
{
|
||||
dao::$errors['days'] = sprintf($this->lang->project->workdaysExceed, $workdays);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Get the data from the post. */
|
||||
$sprint = fixer::input('post')
|
||||
->setDefault('status', 'wait')
|
||||
@@ -452,6 +460,14 @@ class executionModel extends model
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Judge workdays is legitimate. */
|
||||
$this->app->loadLang('project');
|
||||
$workdays = helper::diffDate($_POST['end'], $_POST['begin']) + 1;
|
||||
if(isset($_POST['days']) and $_POST['days'] > $workdays)
|
||||
{
|
||||
dao::$errors['days'] = sprintf($this->lang->project->workdaysExceed, $workdays);
|
||||
return false;
|
||||
}
|
||||
$products = array_filter($this->post->products);
|
||||
$noLinkTip = $oldExecution->type != 'kanban' ? $this->lang->execution->noLinkProduct : $this->lang->execution->kanbanNoLinkProduct;
|
||||
if(empty($products))
|
||||
@@ -645,6 +661,15 @@ class executionModel extends model
|
||||
$codeList[$executionCode] = $executionCode;
|
||||
}
|
||||
|
||||
/* Judge workdays is legitimate. */
|
||||
$workdays = helper::diffDate($data->ends[$executionID], $data->begins[$executionID]) + 1;
|
||||
if(isset($data->dayses[$executionID]) and $data->dayses[$executionID] > $workdays)
|
||||
{
|
||||
$this->app->loadLang('project');
|
||||
dao::$errors['days'][] = 'execution#' . $executionID . sprintf($this->lang->project->workdaysExceed, $workdays);
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach($extendFields as $extendField)
|
||||
{
|
||||
$executions[$executionID]->{$extendField->field} = $this->post->{$extendField->field}[$executionID];
|
||||
|
||||
@@ -335,7 +335,7 @@
|
||||
$actionLink = $this->createLink('story', 'batchEdit', "productID=0&executionID=$execution->id");
|
||||
echo html::commonButton($lang->edit, "data-form-action='$actionLink' $disabled");
|
||||
?>
|
||||
<button type='button' class='btn dropdown-toggle' data-toggle='dropdown'><span class='caret'></span></button>
|
||||
<button type='button' <?php echo $canBatchToTask ? '' : "disabled='disabled'";?> class='btn dropdown-toggle' data-toggle='dropdown'><span class='caret'></span></button>
|
||||
<ul class='dropdown-menu'>
|
||||
<?php
|
||||
$class = $canBatchToTask ? '' : "class='hidden'";
|
||||
|
||||
@@ -94,7 +94,6 @@
|
||||
<div class="col-xs-6"><i class="icon icon-person icon-sm text-muted"></i> <?php echo zget($users, $execution->RD);?> <span class="text-muted">(<?php echo $lang->execution->RD;?>)</span></div>
|
||||
<?php endif;?>
|
||||
|
||||
<?php if(common::hasPriv('execution', 'team')):?>
|
||||
<?php foreach($teamMembers as $teamMember):?>
|
||||
<?php if($j > $i) break;?>
|
||||
<div class="col-xs-6"><i class="icon icon-person icon-sm text-muted"></i> <?php echo zget($users, $teamMember->account);?></div>
|
||||
@@ -103,7 +102,6 @@
|
||||
<div class="col-xs-6">
|
||||
<?php if($canBeChanged) common::printLink('execution', 'manageMembers', "executionID=$execution->id", "<i class='icon icon-plus hl-primary text-primary'></i> " . $lang->execution->manageMembers, '', "class='text-muted'");?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -77,6 +77,7 @@ $lang->gitlab->createSuccess = "Create success";
|
||||
$lang->gitlab->mustBindUser = 'You have not registered the GitLab account, please contact the administrator to register.';
|
||||
$lang->gitlab->noAccess = 'Permission denied';
|
||||
$lang->gitlab->notCompatible = 'The current GitLab version is not compatible with ZenTao, please upgrade the GitLab version and try again';
|
||||
$lang->gitlab->deleted = 'Deleted';
|
||||
|
||||
$lang->gitlab->placeholder = new stdclass;
|
||||
$lang->gitlab->placeholder->name = '';
|
||||
|
||||
@@ -77,6 +77,7 @@ $lang->gitlab->createSuccess = "创建成功";
|
||||
$lang->gitlab->mustBindUser = '您还未绑定GitLab用户,请联系管理员进行绑定';
|
||||
$lang->gitlab->noAccess = '权限不足';
|
||||
$lang->gitlab->notCompatible = '当前GitLab版本与禅道不兼容,请升级GitLab版本后重试';
|
||||
$lang->gitlab->deleted = '已删除';
|
||||
|
||||
$lang->gitlab->placeholder = new stdclass;
|
||||
$lang->gitlab->placeholder->name = '';
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<?php if($gitlabProjectList):?>
|
||||
<div class='table-footer'><?php $pager->show('right', 'pagerjs');?></div>
|
||||
<div class='table-footer'><?php $pager->show('right', 'pagerjs', 100);?></div>
|
||||
<?php endif;?>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
<div class="page-title">
|
||||
<span class="label label-id"><?php echo $gitlab->id?></span>
|
||||
<span class="text" title="<?php echo $gitlab->name;?>" style='color: #3c4354'><?php echo $gitlab->name;?></span>
|
||||
<?php if($gitlab->deleted):?>
|
||||
<span class='label label-danger'><?php echo $lang->gitlab->deleted;?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1450,6 +1450,8 @@ function initSortable()
|
||||
},
|
||||
finish: function(e)
|
||||
{
|
||||
if(!e.changed) return;
|
||||
|
||||
var url = '';
|
||||
var orders = [];
|
||||
var regionID = '';
|
||||
|
||||
@@ -4,6 +4,7 @@ function addItem(obj)
|
||||
var $newRow = $('#insertItemBox').children('.row-module').clone().insertAfter($inputRow).addClass('highlight');
|
||||
$newRow.find("input[type!='hidden']").val('');
|
||||
$newRow.find("select[name^='programs']").chosen();
|
||||
$newRow.find('div[class="table-col col-programs"]').addClass('required');
|
||||
setTimeout(function()
|
||||
{
|
||||
$newRow.removeClass('highlight');
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
<?php endif;?>
|
||||
<td class="c-name text-left table-nest-title" title='<?php echo $product->name?>'>
|
||||
<?php
|
||||
$productLink = html::a($this->createLink('product', 'browse', 'product=' . $product->id), $product->name);
|
||||
$productLink = html::a($this->createLink('product', 'browse', 'productID=' . $product->id), $product->name);
|
||||
echo "<span class='table-nest-icon icon icon-product'></span>" . $productLink;
|
||||
?>
|
||||
</td>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<div class="table-row row-module">
|
||||
<div class="table-col col-module"><?php echo html::input("modules[id$line->id]", $line->name, 'class="form-control"');?></div>
|
||||
<?php if($this->config->systemMode == 'new'):?>
|
||||
<div class="table-col col-programs"><?php echo html::select("programs[id$line->id]", $programs, $line->root, "class='form-control chosen'");?></div>
|
||||
<div class="table-col col-programs"><?php echo html::select("programs[id$line->id]", $programs, $line->root, "class='form-control chosen' required");?></div>
|
||||
<?php endif;?>
|
||||
<div class="table-col col-actions"> </div>
|
||||
</div>
|
||||
@@ -52,7 +52,7 @@
|
||||
<div class="table-row row-module row-module-new">
|
||||
<div class="table-col col-module"><?php echo html::input("modules[]", '', "class='form-control'");?></div>
|
||||
<?php if($this->config->systemMode == 'new'):?>
|
||||
<div class="table-col col-programs"><?php echo html::select("programs[]", $programs, '', "class='form-control chosen'");?></div>
|
||||
<div class="table-col col-programs"><?php echo html::select("programs[]", $programs, '', "class='form-control chosen' required");?></div>
|
||||
<?php endif;?>
|
||||
<div class="table-col col-actions">
|
||||
<button type="button" class="btn btn-link btn-icon btn-add" onclick="addItem(this)"><i class="icon icon-plus"></i></button>
|
||||
@@ -60,12 +60,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<?php endfor;?>
|
||||
</div>
|
||||
</div>
|
||||
<div id="insertItemBox" class="template">
|
||||
<div class="table-row row-module row-module-new">
|
||||
<div class="table-col col-module"><?php echo html::input("modules[]", '', "class='form-control'");?></div>
|
||||
<?php if($this->config->systemMode == 'new'):?>
|
||||
<div class="table-col col-programs"><?php echo html::select("programs[]", $programs, '', "class='form-control chosen'");?></div>
|
||||
<div class="table-col col-programs"><?php echo html::select("programs[]", $programs, '', "class='form-control chosen' required");?></div>
|
||||
<?php endif;?>
|
||||
<div class="table-col col-actions">
|
||||
<button type="button" class="btn btn-link btn-icon btn-add" onclick="addItem(this)"><i class="icon icon-plus"></i></button>
|
||||
|
||||
@@ -60,7 +60,7 @@ class program extends control
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->users = $this->user->getPairs('noletter');
|
||||
$this->view->userIdPairs = $this->user->getPairs('noletter|showid');
|
||||
$this->view->usersAvatar = $this->user->getAvatarPairs();
|
||||
$this->view->usersAvatar = $this->user->getAvatarPairs('');
|
||||
$this->view->programType = $programType;
|
||||
$this->view->PMList = $PMList;
|
||||
$this->view->progressList = $this->program->getProgressList();
|
||||
|
||||
@@ -621,7 +621,7 @@ class programModel extends model
|
||||
|
||||
/* The budget of a child program cannot beyond the remaining budget of the parent program. */
|
||||
$program->budgetUnit = $parentProgram->budgetUnit;
|
||||
if(isset($program->budget) and $parentProgram->budget != 0)
|
||||
if(isset($program->budget))
|
||||
{
|
||||
$availableBudget = $this->getBudgetLeft($parentProgram);
|
||||
if($program->budget > $availableBudget) dao::$errors['budget'] = $this->lang->program->beyondParentBudget;
|
||||
@@ -722,7 +722,7 @@ class programModel extends model
|
||||
|
||||
/* The budget of a child program cannot beyond the remaining budget of the parent program. */
|
||||
$program->budgetUnit = $parentProgram->budgetUnit;
|
||||
if($program->budget != 0 and $parentProgram->budget != 0)
|
||||
if($program->budget != 0)
|
||||
{
|
||||
$availableBudget = $this->getBudgetLeft($parentProgram);
|
||||
if($program->budget > $availableBudget + $oldProgram->budget) dao::$errors['budget'] = $this->lang->program->beyondParentBudget;
|
||||
@@ -1090,21 +1090,33 @@ class programModel extends model
|
||||
/**
|
||||
* Get budget left.
|
||||
*
|
||||
* @param object $parentProgram
|
||||
* @param int $parentProgram
|
||||
* @param int $leftBudget
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function getBudgetLeft($parentProgram)
|
||||
public function getBudgetLeft($parentProgram, $leftBudget = 0)
|
||||
{
|
||||
if(empty($parentProgram)) return;
|
||||
if(empty($parentProgram->id)) return;
|
||||
|
||||
$childGrade = $parentProgram->grade + 1;
|
||||
$childSumBudget = $this->dao->select("sum(budget) as sumBudget")->from(TABLE_PROGRAM)
|
||||
->where('path')->like("%{$parentProgram->id}%")
|
||||
->andWhere('grade')->eq($childGrade)
|
||||
->andWhere('deleted')->eq('0')
|
||||
->fetch('sumBudget');
|
||||
|
||||
return (float)$parentProgram->budget - (float)$childSumBudget;
|
||||
$leftBudget += (float)$parentProgram->budget - (float)$childSumBudget;
|
||||
|
||||
if($parentProgram->budget == 0 and $parentProgram->parent)
|
||||
{
|
||||
$parentParent = $this->getById($parentProgram->parent);
|
||||
return $this->getBudgetLeft($parentParent, $leftBudget);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $leftBudget;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -61,7 +61,7 @@ a.programName:focus, a.programName:hover {background: #0c64eb; color: #fff !impo
|
||||
$('#programTree').tree();
|
||||
$(function()
|
||||
{
|
||||
$(document).on('change', 'input[name^="showClosed"]', function()
|
||||
$("input[name^='showClosed']").change(function()
|
||||
{
|
||||
var showClosed = $(this).is(':checked') ? 1 : 0;
|
||||
$.cookie('showClosed', showClosed, {expires:config.cookieLife, path:config.webRoot});
|
||||
|
||||
@@ -119,15 +119,15 @@
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<?php $class = $program->model == 'kanban' ? 'disabled' : '';?>
|
||||
<?php common::printIcon('project', 'edit', "projectID=$program->id", $program, 'list', 'edit', '', 'iframe', true, '', '', $program->id);?>
|
||||
<?php common::printIcon('project', 'manageMembers', "projectID=$program->id", $program, 'list', 'group', '', "$class", '', 'data-app="project"', '', $program->id);?>
|
||||
<?php common::printIcon('project', 'group', "projectID=$program->id", $program, 'list', 'lock', '', "$class", '', 'data-app="project"', '', $program->id);?>
|
||||
<?php common::printIcon('project', 'edit', "projectID=$program->id", $program, 'list', 'edit', '', 'iframe', true);?>
|
||||
<?php common::printIcon('project', 'team', "projectID=$program->id", $program, 'list', 'group', '', "$class", '', 'data-app="project"');?>
|
||||
<?php common::printIcon('project', 'group', "projectID=$program->id", $program, 'list', 'lock', '', "$class", '', 'data-app="project"');?>
|
||||
<?php if(common::hasPriv('project', 'manageProducts') || common::hasPriv('project', 'whitelist') || common::hasPriv('project', 'delete')):?>
|
||||
<div class='btn-group'>
|
||||
<button type='button' class='btn dropdown-toggle' data-toggle='dropdown' title="<?php echo $this->lang->more;?>"><i class='icon-more-alt'></i></button>
|
||||
<ul class='dropdown-menu pull-right text-center' role='menu'>
|
||||
<?php common::printIcon('project', 'manageProducts', "projectID=$program->id&from=browse", $program, 'list', 'link', '', "$class", '', "data-app='project'", '', $program->id);?>
|
||||
<?php common::printIcon('project', 'whitelist', "projectID=$program->id&module=project&from=browse", $program, 'list', 'shield-check', '', "$class", '', "data-app='project'", '', $program->id);?>
|
||||
<?php common::printIcon('project', 'manageProducts', "projectID=$program->id&from=browse", $program, 'list', 'link', '', "$class", '', "data-app='project'");?>
|
||||
<?php common::printIcon('project', 'whitelist', "projectID=$program->id&module=project&from=browse", $program, 'list', 'shield-check', '', "$class", '', "data-app='project'");?>
|
||||
<?php if(common::hasPriv('project','delete')) echo html::a($this->createLink("project", "delete", "projectID=$program->id"), "<i class='icon-trash'></i>", 'hiddenwin', "class='btn' title='{$this->lang->delete}' data-group='program'");?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
<th><?php echo $lang->program->budget;?></th>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<?php $placeholder = ($parentProgram and $parentProgram->budget != 0) ? 'placeholder=' . $lang->program->parentBudget . zget($lang->project->currencySymbol, $parentProgram->budgetUnit) . $budgetLeft : '';?>
|
||||
<?php $placeholder = $parentProgram ? 'placeholder=' . $lang->program->parentBudget . zget($lang->project->currencySymbol, $parentProgram->budgetUnit) . $budgetLeft : '';?>
|
||||
<?php echo html::input('budget', '', "class='form-control' maxlength='10' " . (strpos($requiredFields, 'budget') !== false ? 'required ' : '') . $placeholder);?>
|
||||
<?php if($parentProgram):?>
|
||||
<span class='input-group-addon fix-border'><?php echo zget($budgetUnitList, $parentProgram->budgetUnit);?></span>
|
||||
|
||||
@@ -482,6 +482,12 @@ class project extends control
|
||||
|
||||
$topProgramID = $this->program->getTopByID($programID);
|
||||
|
||||
if($model == 'kanban')
|
||||
{
|
||||
$this->lang->project->aclList = $this->lang->project->kanbanAclList;
|
||||
$this->lang->project->subAclList = $this->lang->project->kanbanSubAclList;
|
||||
}
|
||||
|
||||
$this->view->title = $this->lang->project->create;
|
||||
$this->view->position[] = $this->lang->project->create;
|
||||
|
||||
@@ -534,7 +540,12 @@ class project extends control
|
||||
$project = $this->project->getByID($projectID);
|
||||
$programID = $project->parent;
|
||||
$this->project->setMenu($projectID);
|
||||
if($project->model == 'kanban') unset($this->lang->project->authList['reset']);
|
||||
if($project->model == 'kanban')
|
||||
{
|
||||
unset($this->lang->project->authList['reset']);
|
||||
$this->lang->project->aclList = $this->lang->project->kanbanAclList;
|
||||
$this->lang->project->subAclList = $this->lang->project->kanbanSubAclList;
|
||||
}
|
||||
|
||||
if($_POST)
|
||||
{
|
||||
@@ -707,6 +718,8 @@ class project extends control
|
||||
{
|
||||
if(!defined('RUN_MODE') || RUN_MODE != 'api') $projectID = $this->project->saveState((int)$projectID, $this->project->getPairsByProgram());
|
||||
|
||||
$this->session->set('teamList', $this->app->getURI(true), 'project');
|
||||
|
||||
$project = $this->project->getById($projectID);
|
||||
if(empty($project) || strpos('scrum,waterfall,kanban', $project->model) === false)
|
||||
{
|
||||
@@ -1271,6 +1284,8 @@ class project extends control
|
||||
*/
|
||||
public function team($projectID = 0)
|
||||
{
|
||||
$this->session->set('teamList', $this->app->getURI(true), 'project');
|
||||
|
||||
$this->app->loadLang('execution');
|
||||
$this->project->setMenu($projectID);
|
||||
|
||||
@@ -1347,7 +1362,7 @@ class project extends control
|
||||
|
||||
$this->loadModel('action')->create('team', $projectID, 'ManagedTeam');
|
||||
|
||||
$link = $this->createLink('project', 'team', "projectID=$projectID");
|
||||
$link = $this->session->teamList ? $this->session->teamList : $this->createLink('project', 'team', "projectID=$projectID");
|
||||
return $this->send(array('message' => $this->lang->saveSuccess, 'result' => 'success', 'locate' => $link));
|
||||
}
|
||||
|
||||
|
||||
@@ -7,3 +7,4 @@
|
||||
#productsBox .product.has-branch > .chosen-container {position: absolute; width: 40% !important; right: 3px; top: 3px;}
|
||||
#productsBox .product.has-branch > .chosen-container > .chosen-single {background: rgba(0,0,0,.05);}
|
||||
#productsBox .product.has-branch > .chosen-container > .chosen-single:hover {background: #fff;}
|
||||
#productsBox .chosen-container .chosen-results{max-height: 180px;}
|
||||
|
||||
@@ -113,9 +113,11 @@ function computeEndDate(delta)
|
||||
if(delta == 999)
|
||||
{
|
||||
$('#end').val(longTime);
|
||||
$('#daysBox').addClass('hidden');
|
||||
$('#days').val(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#daysBox').removeClass('hidden');
|
||||
beginDate = convertStringToDate(beginDate);
|
||||
if((delta == 7 || delta == 14) && (beginDate.getDay() == 1))
|
||||
{
|
||||
|
||||
@@ -58,6 +58,7 @@ $lang->project->unlinkMember = 'Remove Member';
|
||||
$lang->project->copyTeamTitle = 'Select a project team to copy';
|
||||
$lang->project->daysGreaterProject = 'Days cannot be greater than days of project『%s』';
|
||||
$lang->project->errorHours = 'Hours/Day cannot be greater than『24』';
|
||||
$lang->project->workdaysExceed = 'No more than『%s』working days';
|
||||
|
||||
/* Fields. */
|
||||
$lang->project->common = 'Project';
|
||||
@@ -243,6 +244,13 @@ $lang->project->subAclList['private'] = "Private (Only the project leader, team
|
||||
$lang->project->subAclList['open'] = "Open (accessible with project view permissions)";
|
||||
$lang->project->subAclList['program'] = 'Open in the program (all upper-level program team leaders and stakeholders, the project leader, team members and stakeholders can access)';
|
||||
|
||||
$lang->project->kanbanAclList['private'] = 'Private (For the project leader, team members only)';
|
||||
$lang->project->kanbanAclList['open'] = "Open (accessible with project view permissions)";
|
||||
|
||||
$lang->project->kanbanSubAclList['private'] = "Private (Only the project leader, team members can access)";
|
||||
$lang->project->kanbanSubAclList['open'] = "Open (accessible with project view permissions)";
|
||||
$lang->project->kanbanSubAclList['program'] = 'Open in the program (all upper-level program team leaders and stakeholders, the project leader, team members can access)';
|
||||
|
||||
$lang->project->authList['extend'] = 'Inherit (system privilege and project privilege)';
|
||||
$lang->project->authList['reset'] = 'Reset (project privilege only)';
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ $lang->project->unlinkMember = '移除成员';
|
||||
$lang->project->copyTeamTitle = '选择一个项目团队来复制';
|
||||
$lang->project->daysGreaterProject = '可用工日不能大于项目的可用工日『%s』';
|
||||
$lang->project->errorHours = '可用工时/天不能大于『24』';
|
||||
$lang->project->workdaysExceed = '可用工作日不能超过『%s』天';
|
||||
|
||||
/* Fields. */
|
||||
$lang->project->common = '项目';
|
||||
@@ -243,6 +244,13 @@ $lang->project->subAclList['private'] = "私有 (只有项目负责人、团队
|
||||
$lang->project->subAclList['open'] = "公开 (有项目视图权限即可访问)";
|
||||
$lang->project->subAclList['program'] = '项目集内公开(所有上级项目集负责人和干系人、项目负责人、团队成员和干系人可访问)';
|
||||
|
||||
$lang->project->kanbanAclList['private'] = "私有 (只有项目负责人、团队成员可访问)";
|
||||
$lang->project->kanbanAclList['open'] = "公开 (有项目视图权限即可访问)";
|
||||
|
||||
$lang->project->kanbanSubAclList['private'] = "私有 (只有项目负责人、团队成员可访问)";
|
||||
$lang->project->kanbanSubAclList['open'] = "公开 (有项目视图权限即可访问)";
|
||||
$lang->project->kanbanSubAclList['program'] = '项目集内公开(所有上级项目集负责人和干系人、项目负责人、团队成员可访问)';
|
||||
|
||||
$lang->project->authList['extend'] = '继承 (取系统权限与项目权限的合集)';
|
||||
$lang->project->authList['reset'] = '重新定义 (只取项目权限)';
|
||||
|
||||
|
||||
@@ -853,6 +853,14 @@ class projectModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
/* Judge workdays is legitimate. */
|
||||
$workdays = helper::diffDate($project->end, $project->begin) + 1;
|
||||
if(isset($project->days) and $project->days > $workdays)
|
||||
{
|
||||
dao::$errors['days'] = sprintf($this->lang->project->workdaysExceed, $workdays);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* When select create new product, product name cannot be empty and duplicate. */
|
||||
if(isset($_POST['newProduct']))
|
||||
{
|
||||
@@ -1094,6 +1102,14 @@ class projectModel extends model
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Judge workdays is legitimate. */
|
||||
$workdays = helper::diffDate($project->end, $project->begin) + 1;
|
||||
if(isset($project->days) and $project->days > $workdays)
|
||||
{
|
||||
dao::$errors['days'] = sprintf($this->lang->project->workdaysExceed, $workdays);
|
||||
return false;
|
||||
}
|
||||
|
||||
$project = $this->loadModel('file')->processImgURL($project, $this->config->project->editor->edit['id'], $this->post->uid);
|
||||
|
||||
$requiredFields = $this->config->project->edit->requiredFields;
|
||||
@@ -1745,7 +1761,7 @@ class projectModel extends model
|
||||
|
||||
if($this->config->vision != 'lite')
|
||||
{
|
||||
common::printIcon($moduleName, 'manageMembers', "projectID=$project->id", $project, 'list', 'group', '', '', '', $dataApp . $attr, $this->lang->execution->team);
|
||||
common::printIcon($moduleName, 'team', "projectID=$project->id", $project, 'list', 'group', '', '', '', $dataApp . $attr, $this->lang->execution->team);
|
||||
if($this->config->systemMode == 'new') common::printIcon('project', 'group', "projectID=$project->id&programID=$programID", $project, 'list', 'lock', '', '', '', $dataApp . $attr);
|
||||
|
||||
if(common::hasPriv($moduleName, 'manageProducts') || common::hasPriv($moduleName, 'whitelist') || common::hasPriv($moduleName, 'delete'))
|
||||
@@ -1762,7 +1778,7 @@ class projectModel extends model
|
||||
}
|
||||
else
|
||||
{
|
||||
common::printIcon($moduleName, 'manageMembers', "projectID=$project->id", $project, 'list', 'group', '', '', '', $dataApp, $this->lang->execution->team);
|
||||
common::printIcon($moduleName, 'team', "projectID=$project->id", $project, 'list', 'group', '', '', '', $dataApp, $this->lang->execution->team);
|
||||
if($this->config->systemMode == 'new') common::printIcon('project', 'whitelist', "projectID=$project->id&module=project&from=$from", $project, 'list', 'shield-check', '', 'btn-action', '', $dataApp);
|
||||
if(common::hasPriv($moduleName, 'delete')) echo html::a(helper::createLink($moduleName, "delete", "projectID=$project->id"), "<i class='icon-trash'></i>", 'hiddenwin', "class='btn btn-action' title='{$this->lang->project->delete}'");
|
||||
}
|
||||
|
||||
@@ -14,14 +14,14 @@
|
||||
.project-type-label.label-outline {width: 50px; min-width: 50px;}
|
||||
.project-type-label.label {overflow: unset !important; text-overflow: unset !important; white-space: unset !important;}
|
||||
|
||||
#projectTableList .project-name {position: relative; display: flex; align-items: center;}
|
||||
#projectTableList .project-name > span,
|
||||
#projectTableList .project-name > span {flex: none;}
|
||||
#projectTableList .project-name > a {color: #0c60e1; display: inline-block; max-width: calc(100% - 50px);}
|
||||
#projectTableList .project-name.has-prefix > a,
|
||||
#projectTableList .project-name.has-suffix > a {max-width: calc(100% - 100px);}
|
||||
#projectTableList .project-name.has-prefix > a {padding-left: 5px;}
|
||||
#projectTableList .project-name.has-suffix > a {padding-right: 5px;}
|
||||
.project-name {position: relative; display: flex; align-items: center;}
|
||||
.project-name > span,
|
||||
.project-name > span {flex: none;}
|
||||
.project-name > a {color: #0c60e1; display: inline-block; max-width: calc(100% - 50px);}
|
||||
.project-name.has-prefix > a,
|
||||
.project-name.has-suffix > a {max-width: calc(100% - 100px);}
|
||||
.project-name.has-prefix > a {padding-left: 5px;}
|
||||
.project-name.has-suffix > a {padding-right: 5px;}
|
||||
.table-footer {z-index: 1;}
|
||||
</style>
|
||||
<div id="mainMenu" class="clearfix">
|
||||
@@ -109,7 +109,7 @@
|
||||
?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="sortable" id='projectTableList'>
|
||||
<tbody class="sortable">
|
||||
<?php foreach($projectStats as $project):?>
|
||||
<?php $project->from = 'project';?>
|
||||
<tr data-id="<?php echo $project->id;?>">
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<?php echo "<input type='checkbox' name='products[$i]' value='$productID' $checked id='products{$productID}' $isDisabled>";?>
|
||||
<label class='text-ellipsis checkbox-inline' for='<?php echo 'products' . $productID;?>' title='<?php echo $productName;?>'><?php echo $productName;?></label>
|
||||
</div>
|
||||
<?php if(isset($allBranches[$productID][$branchID])) echo html::select("branch[$i]", $allBranches[$productID], $branchID, "class='form-control chosen' disabled='disabled'");?>
|
||||
<?php if(isset($allBranches[$productID][$branchID])) echo html::select("branch[$i]", $allBranches[$productID], $branchID, "class='form-control chosen' data-drop_direction='down' disabled='disabled'");?>
|
||||
</div>
|
||||
</div>
|
||||
<?php if(!empty($isDisabled)) echo html::hidden("products[$i]", $productID);?>
|
||||
@@ -61,7 +61,7 @@
|
||||
<?php echo "<input type='checkbox' name='products[$i]' value='$productID' id='products{$productID}'>";?>
|
||||
<label class='text-ellipsis checkbox-inline' for='<?php echo 'products' . $productID;?>'><?php echo $productName;?></label>
|
||||
</div>
|
||||
<?php if(isset($branchGroups[$productID])) echo html::select("branch[$i]", $branchGroups[$productID], '', "class='form-control chosen'");?>
|
||||
<?php if(isset($branchGroups[$productID])) echo html::select("branch[$i]", $branchGroups[$productID], '', "class='form-control chosen' data-drop_direction='down'");?>
|
||||
</div>
|
||||
</div>
|
||||
<?php $i++;?>
|
||||
|
||||
@@ -105,7 +105,7 @@ class projectrelease extends control
|
||||
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$releaseID = $this->projectrelease->create($projectID);
|
||||
$releaseID = $this->release->create(0, 0, $projectID);
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
$this->loadModel('action')->create('release', $releaseID, 'opened');
|
||||
|
||||
@@ -225,14 +225,15 @@ class projectrelease extends control
|
||||
}
|
||||
|
||||
$storyPager = new pager($type == 'story' ? $recTotal : 0, $recPerPage, $type == 'story' ? $pageID : 1);
|
||||
$stories = $this->dao->select('*')->from(TABLE_STORY)->where('id')->in($release->stories)->andWhere('deleted')->eq(0)
|
||||
->beginIF($type == 'story')->orderBy($orderBy)->fi()
|
||||
->page($storyPager)
|
||||
->fetchAll('id');
|
||||
$stories = $this->dao->select('t1.*, t2.stage')->from(TABLE_STORY)->alias('t1')
|
||||
->leftJoin(TABLE_STORYSTAGE)->alias('t2')->on('t1.id = t2.story')
|
||||
->where('t1.id')->in($release->stories)
|
||||
->andWhere('t1.deleted')->eq(0)
|
||||
->beginIF($type == 'story')->orderBy("t1.$orderBy")->fi()
|
||||
->page($storyPager)
|
||||
->fetchAll('id');
|
||||
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'story');
|
||||
$stages = $this->dao->select('*')->from(TABLE_STORYSTAGE)->where('story')->in($release->stories)->andWhere('branch')->eq($release->branch)->fetchPairs('story', 'stage');
|
||||
foreach($stages as $storyID => $stage)$stories[$storyID]->stage = $stage;
|
||||
|
||||
$bugPager = new pager($type == 'bug' ? $recTotal : 0, $recPerPage, $type == 'bug' ? $pageID : 1);
|
||||
$bugs = $this->dao->select('*')->from(TABLE_BUG)->where('id')->in($release->bugs)->andWhere('deleted')->eq(0)
|
||||
|
||||
@@ -3,7 +3,8 @@ $('#submit').click(function()
|
||||
var dateFormat = new RegExp(/^\d{4}\-\d{2}\-\d{2}$/);
|
||||
var name = $('#name').val();
|
||||
var date = $('#date').val();
|
||||
if(name && dateFormat.test(date))
|
||||
var build = $('#build').val();
|
||||
if(name && build && dateFormat.test(date))
|
||||
{
|
||||
var result = confirm(confirmLink) ? true : false;
|
||||
$('#sync').val(result);
|
||||
|
||||
@@ -95,143 +95,6 @@ class projectreleaseModel extends model
|
||||
return array_keys($releases);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a release.
|
||||
*
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function create($projectID = 0)
|
||||
{
|
||||
/* Init vars. */
|
||||
$productID = $this->post->product;
|
||||
$branch = $this->post->branch;
|
||||
$buildID = 0;
|
||||
$projectID = $projectID ? $projectID : $this->session->project;
|
||||
|
||||
/* Check build if build is required. */
|
||||
if(strpos($this->config->release->create->requiredFields, 'build') !== false and $this->post->build == false) return dao::$errors[] = sprintf($this->lang->error->notempty, $this->lang->release->build);
|
||||
|
||||
/* Check date must be not more than today. */
|
||||
if($this->post->date > date('Y-m-d')) return dao::$errors[] = $this->lang->release->errorDate;
|
||||
|
||||
if($this->post->build)
|
||||
{
|
||||
$build = $this->loadModel('build')->getByID($this->post->build);
|
||||
$productID = $build->product;
|
||||
$branch = $build->branch;
|
||||
}
|
||||
|
||||
$release = fixer::input('post')
|
||||
->add('project', $projectID)
|
||||
->add('product', (int)$productID)
|
||||
->add('branch', (int)$branch)
|
||||
->setDefault('stories', '')
|
||||
->join('stories', ',')
|
||||
->join('bugs', ',')
|
||||
->join('mailto', ',')
|
||||
->setIF($this->post->build == false, 'build', $buildID)
|
||||
->setIF($productID, 'product', $productID)
|
||||
->setIF($branch, 'branch', $branch)
|
||||
->stripTags($this->config->release->editor->create['id'], $this->config->allowedTags)
|
||||
->remove('allchecker,files,labels,uid,sync')
|
||||
->get();
|
||||
|
||||
/* Auto create build when release is not link build. */
|
||||
if(empty($release->build) and $release->name)
|
||||
{
|
||||
$build = $this->dao->select('*')->from(TABLE_BUILD)
|
||||
->where('deleted')->eq('0')
|
||||
->andWhere('name')->eq($release->name)
|
||||
->andWhere('product')->eq($productID)
|
||||
->andWhere('branch')->eq($branch)
|
||||
->fetch();
|
||||
if($build)
|
||||
{
|
||||
return dao::$errors['build'] = sprintf($this->lang->release->existBuild, $release->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
$build = new stdclass();
|
||||
$build->project = $projectID;
|
||||
$build->product = (int)$productID;
|
||||
$build->branch = (int)$branch;
|
||||
$build->name = $release->name;
|
||||
$build->date = $release->date;
|
||||
$build->builder = $this->app->user->account;
|
||||
$build->desc = $release->desc;
|
||||
$build->execution = 0;
|
||||
|
||||
$build = $this->loadModel('file')->processImgURL($build, $this->config->release->editor->create['id']);
|
||||
$this->dao->insert(TABLE_BUILD)->data($build)
|
||||
->autoCheck()
|
||||
->check('name', 'unique', "product = '{$productID}' AND branch = '{$branch}' AND deleted = '0'")
|
||||
->batchCheck('name', 'notempty')
|
||||
->exec();
|
||||
if(dao::isError()) return false;
|
||||
|
||||
$buildID = $this->dao->lastInsertID();
|
||||
$release->build = $buildID;
|
||||
}
|
||||
}
|
||||
|
||||
if($release->build)
|
||||
{
|
||||
$buildInfo = $this->dao->select('branch, stories, bugs')->from(TABLE_BUILD)->where('id')->eq($release->build)->fetch();
|
||||
$release->branch = $buildInfo->branch;
|
||||
if($this->post->sync == 'true')
|
||||
{
|
||||
$release->stories = $buildInfo->stories;
|
||||
$release->bugs = $buildInfo->bugs;
|
||||
}
|
||||
}
|
||||
|
||||
$release = $this->loadModel('file')->processImgURL($release, $this->config->release->editor->create['id'], $this->post->uid);
|
||||
$this->dao->insert(TABLE_RELEASE)->data($release)
|
||||
->autoCheck()
|
||||
->batchCheck($this->config->release->create->requiredFields, 'notempty')
|
||||
->check('name', 'unique', "product = {$release->product} AND branch = {$release->branch} AND deleted = '0'");
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
if(!empty($buildID)) $this->dao->delete()->from(TABLE_BUILD)->where('id')->eq($buildID)->exec();
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->dao->exec();
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
if(!empty($buildID)) $this->dao->delete()->from(TABLE_BUILD)->where('id')->eq($buildID)->exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
$releaseID = $this->dao->lastInsertID();
|
||||
$this->file->updateObjectID($this->post->uid, $releaseID, 'release');
|
||||
$this->file->saveUpload('release', $releaseID);
|
||||
$this->loadModel('score')->create('release', 'create', $releaseID);
|
||||
|
||||
/* Set stage to released. */
|
||||
if($release->stories)
|
||||
{
|
||||
$this->loadModel('story');
|
||||
$this->loadModel('action');
|
||||
|
||||
$storyIDList = array_filter(explode(',', $release->stories));
|
||||
foreach($storyIDList as $storyID)
|
||||
{
|
||||
$this->story->setStage($storyID);
|
||||
|
||||
$this->action->create('story', $storyID, 'linked2release', '', $releaseID);
|
||||
}
|
||||
}
|
||||
|
||||
return $releaseID;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a release.
|
||||
*
|
||||
|
||||
@@ -3,7 +3,8 @@ $('#submit').click(function()
|
||||
var dateFormat = new RegExp(/^\d{4}\-\d{2}\-\d{2}$/);
|
||||
var name = $('#name').val();
|
||||
var date = $('#date').val();
|
||||
if(name && dateFormat.test(date))
|
||||
var build = $('#build').val();
|
||||
if(name && build && dateFormat.test(date))
|
||||
{
|
||||
var result = confirm(confirmLink) ? true : false;
|
||||
$('#sync').val(result);
|
||||
|
||||
@@ -24,7 +24,7 @@ $lang->release->batchUnlinkStory = "批量移除{$lang->SRCommon}";
|
||||
$lang->release->batchUnlinkBug = "批量移除Bug";
|
||||
|
||||
$lang->release->confirmDelete = "您确认删除该发布吗?";
|
||||
$lang->release->confirmLink = "是否将版本中完成的{$lang->SRCommon}和已解决的bug关联到发布下?";
|
||||
$lang->release->confirmLink = "是否将版本中完成的{$lang->SRCommon}和已解决的Bug关联到发布下?";
|
||||
$lang->release->confirmUnlinkStory = "您确认移除该{$lang->SRCommon}吗?";
|
||||
$lang->release->confirmUnlinkBug = "您确认移除该Bug吗?";
|
||||
$lang->release->existBuild = '『版本』已经有『%s』这条记录了。您可以更改『发布名称』或者选择一个『版本』。';
|
||||
|
||||
@@ -108,15 +108,15 @@ class releaseModel extends model
|
||||
*
|
||||
* @param int $productID
|
||||
* @param int $branch
|
||||
* @param int $projectID
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function create($productID, $branch = 0)
|
||||
public function create($productID = 0, $branch = 0, $projectID = 0)
|
||||
{
|
||||
/* Init vars. */
|
||||
$productID = (int)$productID;
|
||||
$branch = (int)$branch;
|
||||
$buildID = 0;
|
||||
$productID = $this->post->product ? $this->post->product : (int)$productID;
|
||||
$branch = $this->post->branch ? $this->post->branch : (int)$branch;
|
||||
|
||||
/* Check build if build is required. */
|
||||
if(strpos($this->config->release->create->requiredFields, 'build') !== false and $this->post->build == false) return dao::$errors[] = sprintf($this->lang->error->notempty, $this->lang->release->build);
|
||||
@@ -127,11 +127,12 @@ class releaseModel extends model
|
||||
$release = fixer::input('post')
|
||||
->add('product', (int)$productID)
|
||||
->add('branch', (int)$branch)
|
||||
->setIF($projectID, 'project', $projectID)
|
||||
->setIF($this->post->build == false, 'build', 0)
|
||||
->setDefault('stories', '')
|
||||
->join('stories', ',')
|
||||
->join('bugs', ',')
|
||||
->join('mailto', ',')
|
||||
->setIF($this->post->build == false, 'build', $buildID)
|
||||
->stripTags($this->config->release->editor->create['id'], $this->config->allowedTags)
|
||||
->remove('allchecker,files,labels,uid,sync')
|
||||
->get();
|
||||
@@ -152,6 +153,7 @@ class releaseModel extends model
|
||||
else
|
||||
{
|
||||
$build = new stdclass();
|
||||
$build->project = $projectID;
|
||||
$build->product = (int)$productID;
|
||||
$build->branch = (int)$branch;
|
||||
$build->name = $release->name;
|
||||
|
||||
@@ -1151,6 +1151,12 @@ class repoModel extends model
|
||||
if(!$this->config->features->checkClient) return true;
|
||||
if(!$this->post->client) return true;
|
||||
|
||||
if(strpos($this->post->client, ' '))
|
||||
{
|
||||
dao::$errors['client'] = $this->lang->repo->error->clientPath;
|
||||
return false;
|
||||
}
|
||||
|
||||
$clientVersionFile = $this->session->clientVersionFile;
|
||||
if(empty($clientVersionFile))
|
||||
{
|
||||
|
||||
@@ -1124,7 +1124,7 @@ class story extends control
|
||||
$plan = $this->dao->findById($story->plan)->from(TABLE_PRODUCTPLAN)->fetch('title');
|
||||
$bugs = $this->dao->select('id,title,status,pri,severity')->from(TABLE_BUG)->where('story')->eq($storyID)->andWhere('deleted')->eq(0)->fetchAll();
|
||||
$fromBug = $this->dao->select('id,title')->from(TABLE_BUG)->where('toStory')->eq($storyID)->fetch();
|
||||
$cases = $this->dao->select('id,title')->from(TABLE_CASE)->where('story')->eq($storyID)->andWhere('deleted')->eq(0)->fetchAll();
|
||||
$cases = $this->dao->select('id,title,status,pri')->from(TABLE_CASE)->where('story')->eq($storyID)->andWhere('deleted')->eq(0)->fetchAll();
|
||||
$linkedMRs = $this->loadModel('mr')->getLinkedMRPairs($storyID, 'story');
|
||||
$modulePath = $this->tree->getParents($story->module);
|
||||
$storyModule = empty($story->module) ? '' : $this->tree->getById($story->module);
|
||||
@@ -1374,7 +1374,8 @@ class story extends control
|
||||
$execution = $this->execution->getByID($this->session->execution);
|
||||
if($this->app->tab == 'execution' and $execution->type == 'kanban' and $this->app->tab == 'execution')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all');
|
||||
$this->loadModel('kanban')->updateLane($this->session->execution, 'story', $storyID);
|
||||
$kanbanData = $this->kanban->getRDKanban($this->session->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all');
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
@@ -2098,7 +2099,7 @@ class story extends control
|
||||
$stories = $this->story->getProductStoryPairs($productID, $branch, $moduleID, $storyStatus, 'id_desc', $limit, $type, 'story', $hasParent);
|
||||
}
|
||||
|
||||
if(empty($stories)) $stories = $this->story->getProductStoryPairs($productID, $branch, 0, $storyStatus, 'id_desc', $limit, $type, 'story', $hasParent);
|
||||
if(!in_array($this->app->tab, array('execution', 'project')) and empty($stories)) $stories = $this->story->getProductStoryPairs($productID, $branch, 0, $storyStatus, 'id_desc', $limit, $type, 'story', $hasParent);
|
||||
|
||||
$storyID = isset($stories[$storyID]) ? $storyID : 0;
|
||||
$select = html::select('story' . $number, empty($stories) ? array('' => '') : $stories, $storyID, "class='form-control'");
|
||||
|
||||
@@ -156,3 +156,57 @@ $(document).ready(function()
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$('#confirmButton').click(function()
|
||||
{
|
||||
/* Unique team. */
|
||||
$('select[name^=team]').each(function(i)
|
||||
{
|
||||
value = $(this).val();
|
||||
if(value == '') return;
|
||||
$('select[name^=team]').each(function(j)
|
||||
{
|
||||
if(i <= j) return;
|
||||
if(value == $(this).val()) $(this).closest('tr').addClass('hidden');
|
||||
})
|
||||
})
|
||||
$('select[name^=team]').closest('tr.hidden').remove();
|
||||
|
||||
var memberCount = '';
|
||||
var assignedTo = '';
|
||||
var totalEstimate = 0;
|
||||
var totalConsumed = 0;
|
||||
var totalLeft = 0;
|
||||
$('select[name^=team]').each(function()
|
||||
{
|
||||
if($(this).find('option:selected').text() == '') return;
|
||||
|
||||
var account = $(this).find('option:selected').val();
|
||||
var realName = $(this).find('option:selected').text();
|
||||
assignedTo += "<option value='" + account + "' title='" + realName + "'>" + realName + "</option>";
|
||||
memberCount++;
|
||||
|
||||
estimate = parseFloat($(this).parents('td').next('td').find('[name^=teamEstimate]').val());
|
||||
if(!isNaN(estimate)) totalEstimate += estimate;
|
||||
|
||||
consumed = parseFloat($(this).parents('td').next('td').find('[name^=teamConsumed]').val());
|
||||
if(!isNaN(consumed)) totalConsumed += consumed;
|
||||
|
||||
left = parseFloat($(this).parents('td').next('td').find('[name^=teamLeft]').val());
|
||||
if(!isNaN(left)) totalLeft += left;
|
||||
})
|
||||
$('#estimate').val(totalEstimate);
|
||||
$('#consumedSpan').html(totalConsumed);
|
||||
$('#left').val(totalLeft);
|
||||
$('#assignedTo').html(assignedTo);
|
||||
$('#assignedTo').trigger('chosen:updated');
|
||||
|
||||
if(memberCount < 2)
|
||||
{
|
||||
alert(teamMemberError);
|
||||
}
|
||||
else
|
||||
{
|
||||
$('.close').click();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<?php js::set('confirmChangeExecution', $lang->task->confirmChangeExecution);?>
|
||||
<?php js::set('changeExecutionConfirmed', false);?>
|
||||
<?php js::set('newRowCount', count($task->team) < 6 ? 6 - count($task->team) : 1);?>
|
||||
<?php js::set('teamMemberError', $lang->task->error->teamMember);?>
|
||||
<div class='main-content' id='mainContent'>
|
||||
<form method='post' enctype='multipart/form-data' target='hiddenwin' id='dataform'>
|
||||
<div class='main-header'>
|
||||
@@ -191,7 +192,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->task->consumed;?></th>
|
||||
<td><?php echo $task->consumed . ' '; common::printIcon('task', 'recordEstimate', "taskID=$task->id", $task, 'list', '', '', 'record-estimate-toggle btn-link', true);?></td>
|
||||
<td><?php echo '<span id=consumedSpan>' . $task->consumed . '</span> '; common::printIcon('task', 'recordEstimate', "taskID=$task->id", $task, 'list', '', '', 'record-estimate-toggle btn-link', true);?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->task->left;?></th>
|
||||
@@ -298,7 +299,7 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr><td colspan='3' class='text-center form-actions'><?php echo html::a('javascript:void(0)', $lang->confirm, '', "class='btn btn-primary btn-wide' data-dismiss='modal'");?></td></tr>
|
||||
<tr><td colspan='3' class='text-center form-actions'><?php echo html::a('javascript:void(0)', $lang->confirm, '', "id='confirmButton' class='btn btn-primary btn-wide'");?></td></tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -1406,8 +1406,8 @@ class testtask extends control
|
||||
$this->app->rawModule = 'testcase';
|
||||
|
||||
$projectID = $this->app->tab == 'qa' ? 0 : $this->session->project;
|
||||
$executions = empty($productID) ? array() : $this->loadModel('product')->getExecutionPairsByProduct($productID, 0, 'id_desc', $projectID);
|
||||
$builds = empty($productID) ? array() : $this->loadModel('build')->getBuildPairs($productID, 0, 'notrunk');
|
||||
$executions = empty($productID) ? array() : $this->loadModel('product')->getExecutionPairsByProduct($productID, '', 'id_desc', $projectID);
|
||||
$builds = empty($productID) ? array() : $this->loadModel('build')->getBuildPairs($productID, 'all', 'notrunk');
|
||||
|
||||
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testtask->importUnitResult;
|
||||
$this->view->position[] = html::a($this->createLink('testtask', 'browse', "productID=$productID"), $this->products[$productID]);
|
||||
|
||||
@@ -95,9 +95,10 @@ function loadExecutionRelated(executionID)
|
||||
*/
|
||||
function loadExecutionBuilds(executionID, selected)
|
||||
{
|
||||
selectedBuild = $('#build').val();
|
||||
var selectedBuild = $('#build').val();
|
||||
|
||||
if(!selectedBuild) selectedBuild = 0;
|
||||
link = createLink('build', 'ajaxGetExecutionBuilds', 'executionID=' + executionID + '&productID=' + $('#product').val() + '&varName=testTaskBuild&build=' + selectedBuild, '', '', executionID);
|
||||
var link = createLink('build', 'ajaxGetExecutionBuilds', 'executionID=' + executionID + '&productID=' + $('#product').val() + '&varName=testTaskBuild&build=' + selectedBuild);
|
||||
if(executionID == 0) link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + $('#product').val() + '&varName=resolvedBuild&build=' + selectedBuild);
|
||||
$('#buildBox').load(link, function()
|
||||
{
|
||||
|
||||
@@ -168,6 +168,8 @@ $(function()
|
||||
container = null;
|
||||
}
|
||||
|
||||
if($(ele).hasClass('create-bug-btn') || $(ele).hasClass('create-story-btn')) container = '#mainMenu'; // Fix bug #21092.
|
||||
|
||||
$e.closest('body').find('.tooltip-tutorial').tooltip('destroy');
|
||||
var offset = $e.offset();
|
||||
var winWidth = $(window).width();
|
||||
|
||||
@@ -76,7 +76,6 @@
|
||||
<?php
|
||||
if(isset($task['mode']) && $task['mode'] != $mode) continue;
|
||||
$nav = $task['nav'];
|
||||
if(!commonModel::hasPriv($nav['module'], $nav['method'])) continue;
|
||||
$task['name'] = $name;
|
||||
$task['id'] = ++ $idx;
|
||||
$task['url'] = helper::createLink($nav['module'], $nav['method'], isset($nav['vars']) ? $nav['vars'] : '', 'tutorial');
|
||||
|
||||
@@ -125,6 +125,7 @@ class upgradeModel extends model
|
||||
$maxVersion = array_search($openVersion, $this->config->upgrade->maxVersion);
|
||||
$this->saveLogs("Execute $maxVersion");
|
||||
$this->execSQL($this->getUpgradeFile(str_replace('_', '.', $maxVersion)));
|
||||
$this->executeMax($maxVersion);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,6 +443,9 @@ class upgradeModel extends model
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '15_5':
|
||||
$this->addDefaultKanbanPri();
|
||||
break;
|
||||
case '15_7_1':
|
||||
$this->updateObjectBranch();
|
||||
$this->updateProjectStories();
|
||||
@@ -532,6 +536,9 @@ class upgradeModel extends model
|
||||
case 'pro10_0_2':
|
||||
$this->fixReportLang();
|
||||
break;
|
||||
case 'pro10_2':
|
||||
$this->addDefaultKanbanPri();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -615,6 +622,9 @@ class upgradeModel extends model
|
||||
case 'biz5_0_1':
|
||||
$this->updateWorkflow4Execution();
|
||||
break;
|
||||
case 'biz5_2':
|
||||
$this->addDefaultKanbanPri();
|
||||
break;
|
||||
case 'biz5_3_1':
|
||||
$this->processFeedbackField();
|
||||
$this->addFileFields();
|
||||
@@ -626,6 +636,23 @@ class upgradeModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process data for max.
|
||||
*
|
||||
* @param int $maxVersion
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function executeMax($maxVersion)
|
||||
{
|
||||
switch($maxVersion)
|
||||
{
|
||||
case 'max2_2':
|
||||
$this->addDefaultKanbanPri();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the confirm contents.
|
||||
*
|
||||
@@ -6068,4 +6095,36 @@ class upgradeModel extends model
|
||||
}
|
||||
file_put_contents($filePath, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add groups default kanban private
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function addDefaultKanbanPri()
|
||||
{
|
||||
/* Fix bug #17954. */
|
||||
$hasKanbanPri = $this->dao->select('*')->from(TABLE_GROUPPRIV)->where('module')->eq('kanban')->fetch();
|
||||
if(!$hasKanbanPri)
|
||||
{
|
||||
$this->app->loadLang('group');
|
||||
$groups = $this->dao->select('id')->from(TABLE_GROUP)->where('role')->in('admin,pm,po')->fetchPairs('id');
|
||||
foreach($groups as $groupID)
|
||||
{
|
||||
foreach($this->lang->resource->kanban as $method => $name)
|
||||
{
|
||||
if(stripos($method, 'delete') === false)
|
||||
{
|
||||
$groupPriv = new stdclass();
|
||||
$groupPriv->group = $groupID;
|
||||
$groupPriv->module = 'kanban';
|
||||
$groupPriv->method = $method;
|
||||
|
||||
$this->dao->insert(TABLE_GROUPPRIV)->data($groupPriv)->exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,11 +37,11 @@ class userModel extends model
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getList()
|
||||
public function getList($params = 'nodeleted')
|
||||
{
|
||||
return $this->dao->select('*')->from(TABLE_USER)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('type')->eq('inside')
|
||||
->where('type')->eq('inside')
|
||||
->beginIF(strpos($params, 'nodeleted') !== false)->andWhere('deleted')->eq(0)->fi()
|
||||
->orderBy('account')
|
||||
->fetchAll();
|
||||
}
|
||||
@@ -102,7 +102,7 @@ class userModel extends model
|
||||
->beginIF(strpos($params, 'nodeleted') !== false or empty($this->config->user->showDeleted))->andWhere('deleted')->eq('0')->fi()
|
||||
->beginIF(strpos($params, 'all') === false)->andWhere('type')->eq($type)->fi()
|
||||
->beginIF($accounts)->andWhere('account')->in($accounts)->fi()
|
||||
->beginIF($this->config->vision)->andWhere("CONCAT(',', visions, ',')")->like("%,{$this->config->vision},%")->fi()
|
||||
->beginIF($this->config->vision and $this->app->rawModule !== 'kanban')->andWhere("CONCAT(',', visions, ',')")->like("%,{$this->config->vision},%")->fi()
|
||||
->orderBy($orderBy)
|
||||
->beginIF($maxCount)->limit($maxCount)->fi()
|
||||
->fetchAll($keyField);
|
||||
@@ -146,10 +146,10 @@ class userModel extends model
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getAvatarPairs()
|
||||
public function getAvatarPairs($params = 'nodeleted')
|
||||
{
|
||||
$avatarPairs = array();
|
||||
$userList = $this->getList();
|
||||
$userList = $this->getList($params);
|
||||
foreach($userList as $user) $avatarPairs[$user->account] = $user->avatar;
|
||||
|
||||
return $avatarPairs;
|
||||
@@ -1269,7 +1269,7 @@ class userModel extends model
|
||||
$sessionFails = (int)$this->session->loginFails;
|
||||
$sessionFails += 1;
|
||||
$this->session->set('loginFails', $sessionFails);
|
||||
if($sessionFails >= $this->config->user->failTimes) $this->session->set('loginLocked', date('Y-m-d H:i:s'));
|
||||
if($sessionFails >= $this->config->user->failTimes) $this->session->set("{$account}.loginLocked", date('Y-m-d H:i:s'));
|
||||
|
||||
$user = $this->dao->select('fails')->from(TABLE_USER)->where('account')->eq($account)->fetch();
|
||||
if(empty($user)) return 0;
|
||||
@@ -1300,7 +1300,7 @@ class userModel extends model
|
||||
*/
|
||||
public function checkLocked($account)
|
||||
{
|
||||
if($this->session->loginLocked and (time() - strtotime($this->session->loginLocked)) <= $this->config->user->lockMinutes * 60) return true;
|
||||
if($this->session->{"{$account}.loginLocked"} and (time() - strtotime($this->session->{"{$account}.loginLocked"})) <= $this->config->user->lockMinutes * 60) return true;
|
||||
|
||||
$user = $this->dao->select('locked')->from(TABLE_USER)->where('account')->eq($account)->fetch();
|
||||
if(empty($user)) return false;
|
||||
@@ -1321,7 +1321,7 @@ class userModel extends model
|
||||
$this->dao->update(TABLE_USER)->set('fails')->eq(0)->set('locked')->eq('0000-00-00 00:00:00')->where('account')->eq($account)->exec();
|
||||
|
||||
unset($_SESSION['loginFails']);
|
||||
unset($_SESSION['loginLocked']);
|
||||
unset($_SESSION["{$account}.loginLocked"]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,953 @@
|
||||
<?php
|
||||
class kanbanTest
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
global $tester;
|
||||
$this->objectModel = $tester->loadModel('kanban');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create a kanban group.
|
||||
*
|
||||
* @param int $kanbanID
|
||||
* @param int $regionID
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function createGroupTest($kanbanID, $regionID)
|
||||
{
|
||||
$objectID = $this->objectModel->createGroup($kanbanID, $regionID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
global $tester;
|
||||
$object = $tester->dao->findByID($objectID)->from(TABLE_KANBANGROUP)->fetch();
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create a default kanban region.
|
||||
*
|
||||
* @param int $kanbanID
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function createDefaultRegionTest($kanban)
|
||||
{
|
||||
$objectID = $this->objectModel->createDefaultRegion($kanban);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
$object = $this->objectModel->getRegionByID($objectID);
|
||||
return $object;
|
||||
}
|
||||
|
||||
public function createRegionTest($kanban, $region = null, $copyRegionID = 0, $from = 'kanban')
|
||||
{
|
||||
$objects = $this->objectModel->createRegion($kanban, $region = null, $copyRegionID = 0, $from = 'kanban');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create default kanban lanes.
|
||||
*
|
||||
* @param int $regionID
|
||||
* @param int $groupID
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function createDefaultLaneTest($regionID, $groupID)
|
||||
{
|
||||
$objectID = $this->objectModel->createDefaultLane(null, $regionID, $groupID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
$object = $this->objectModel->getLaneByID($objectID);
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create default kanban columns.
|
||||
*
|
||||
* @param int $regionID
|
||||
* @param int $groupID
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function createDefaultColumnsTest($regionID, $groupID)
|
||||
{
|
||||
$this->objectModel->createDefaultColumns(null, $regionID, $groupID);
|
||||
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
global $tester;
|
||||
$objects = $tester->dao->select('*')->from(TABLE_KANBANCOLUMN)->where('`region`')->eq($regionID)->andWhere('`group`')->eq($groupID)->andWhere('`type`')->like('column%')->fetchAll();
|
||||
return count($objects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create a column.
|
||||
*
|
||||
* @param object $param
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function createColumnTest($param)
|
||||
{
|
||||
$regionID = 1;
|
||||
|
||||
foreach($param as $key => $value) $_POST[$key] = $value;
|
||||
|
||||
$objectID = $this->objectModel->createColumn($regionID, null, 0, $param->parent);
|
||||
|
||||
unset($_POST);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
$object = $this->objectModel->getColumnByID($objectID);
|
||||
return $object;
|
||||
}
|
||||
|
||||
public function splitColumnTest($columnID)
|
||||
{
|
||||
$objects = $this->objectModel->splitColumn($columnID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create a card.
|
||||
*
|
||||
* @param array $param
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function createCardTest($param)
|
||||
{
|
||||
$kanbanID = 1;
|
||||
$regionID = 1;
|
||||
$groupID = 1;
|
||||
$columnID = 1;
|
||||
|
||||
$_POST['lane'] = 1;
|
||||
$_POST['begin'] = date('Y-m-d', strtotime("-3 day"));
|
||||
$_POST['end'] = date('Y-m-d', strtotime("+3 day"));
|
||||
foreach($param as $key => $value) $_POST[$key] = $value;
|
||||
|
||||
$objectID = $this->objectModel->createCard($kanbanID, $regionID, $groupID, $columnID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
$object = $this->objectModel->getCardByID($objectID);
|
||||
return $object;
|
||||
}
|
||||
|
||||
public function importCardTest($kanbanID, $regionID, $groupID, $columnID)
|
||||
{
|
||||
$objects = $this->objectModel->importCard($kanbanID, $regionID, $groupID, $columnID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function importObjectTest($kanbanID, $regionID, $groupID, $columnID, $objectType)
|
||||
{
|
||||
$objects = $this->objectModel->importObject($kanbanID, $regionID, $groupID, $columnID, $objectType);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test batch create kanban cards.
|
||||
*
|
||||
* @param array $param
|
||||
* @param bool $endLtBegin
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function batchCreateCardTest($param = array(), $endLtBegin = false)
|
||||
{
|
||||
$kanbanID = 1;
|
||||
$regionID = 1;
|
||||
$groupID = 1;
|
||||
$columnID = 1;
|
||||
$batchCreateFields['name'] = array('0' => '批量创建卡片1', '1' => '批量创建卡片2', '2' => '批量创建卡片3', '3' => '批量创建卡片4');
|
||||
$batchCreateFields['lane'] = array('0' => '1', '1' => 'ditto', '2' => 'ditto', '3' => 'ditto');
|
||||
$batchCreateFields['assignedTo'] = array();
|
||||
$batchCreateFields['estimate'] = array('0' => '1', '1' => '2', '2' => '3', '3' => '4');
|
||||
$batchCreateFields['begin'] = array('0' => date('Y-m-d', time()), '1' => date('Y-m-d', time()), '2' => '', '3' => '');
|
||||
$batchCreateFields['end'] = !$endLtBegin ? array('0' => date('Y-m-d', time()), '1' => '', '2' => '', '3' => '') : array('0' => date('Y-m-d', strtotime("-1 day")), '1' => date('Y-m-d', strtotime("-1 day")), '2' => date('Y-m-d', strtotime("-2 day")), '3' => date('Y-m-d', strtotime("-3 day")));
|
||||
$batchCreateFields['desc'] = array('0' => '描述1', '1' => '描述2', '2' => '描述3', '3' => '描述4');
|
||||
$batchCreateFields['pri'] = array('0' => '1', '1' => '2', '2' => '3', '3' => '4');
|
||||
$batchCreateFields['beginDitto'] = array('1' => 'on', '2' => 'on', '3' => 'on', '4' => 'on');
|
||||
$batchCreateFields['endDitto'] = array('1' => 'on', '2' => 'on', '3' => 'on', '4' => 'on');
|
||||
|
||||
foreach($batchCreateFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
|
||||
|
||||
foreach($param as $key => $value) $_POST[$key] = $value;
|
||||
|
||||
$this->objectModel->batchCreateCard($kanbanID, $regionID, $groupID, $columnID);
|
||||
|
||||
global $tester;
|
||||
$object = $tester->dao->select('*')->from(TABLE_KANBANCELL)->where('kanban')->eq($kanbanID)->andWhere('lane')->eq(1)->andWhere('`column`')->eq($columnID)->andWhere('type')->eq('common')->fetch();
|
||||
|
||||
unset($_POST);
|
||||
|
||||
if(dao::isError()) return dao::getError()[0];
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
public function getByIDTest($kanbanID)
|
||||
{
|
||||
$objects = $this->objectModel->getByID($kanbanID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getKanbanDataTest($kanbanID)
|
||||
{
|
||||
$objects = $this->objectModel->getKanbanData($kanbanID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getPlanKanbanTest($product, $branchID = 0, $planGroup = '')
|
||||
{
|
||||
$objects = $this->objectModel->getPlanKanban($product, $branchID = 0, $planGroup = '');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getRDKanbanTest($executionID, $browseType = 'all', $orderBy = 'id_desc', $regionID = 0, $groupBy = 'default')
|
||||
{
|
||||
$objects = $this->objectModel->getRDKanban($executionID, $browseType = 'all', $orderBy = 'id_desc', $regionID = 0, $groupBy = 'default');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getRegionByIDTest($regionID)
|
||||
{
|
||||
$objects = $this->objectModel->getRegionByID($regionID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getRegionPairsTest($kanbanID, $regionID = 0, $from = 'kanban')
|
||||
{
|
||||
$objects = $this->objectModel->getRegionPairs($kanbanID, $regionID = 0, $from = 'kanban');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getKanbanIDByRegionTest($regionID)
|
||||
{
|
||||
$objects = $this->objectModel->getKanbanIDByRegion($regionID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getGroupGroupByRegionsTest($regions)
|
||||
{
|
||||
$objects = $this->objectModel->getGroupGroupByRegions($regions);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getLaneGroupByRegionsTest($regions, $browseType = 'all')
|
||||
{
|
||||
$objects = $this->objectModel->getLaneGroupByRegions($regions, $browseType = 'all');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getLanePairsByGroupTest($groupID, $orderBy = '`order`_asc')
|
||||
{
|
||||
$objects = $this->objectModel->getLanePairsByGroup($groupID, $orderBy = '`order`_asc');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getColumnGroupByRegionsTest($regions, $order = 'order')
|
||||
{
|
||||
$objects = $this->objectModel->getColumnGroupByRegions($regions, $order = 'order');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getCardGroupByKanbanTest($kanbanID)
|
||||
{
|
||||
$objects = $this->objectModel->getCardGroupByKanban($kanbanID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getImportedCardsTest($kanbanID, $cards, $fromType)
|
||||
{
|
||||
$objects = $this->objectModel->getImportedCards($kanbanID, $cards, $fromType);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getRDColumnGroupByRegionsTest($regions, $groupIDList = array())
|
||||
{
|
||||
$objects = $this->objectModel->getRDColumnGroupByRegions($regions, $groupIDList = array());
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getCardGroupByExecutionTest($executionID, $browseType = 'all', $orderBy = 'id_asc')
|
||||
{
|
||||
$objects = $this->objectModel->getCardGroupByExecution($executionID, $browseType = 'all', $orderBy = 'id_asc');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getExecutionKanbanTest($executionID, $browseType = 'all', $groupBy = 'default')
|
||||
{
|
||||
$objects = $this->objectModel->getExecutionKanban($executionID, $browseType = 'all', $groupBy = 'default');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getKanban4GroupTest($executionID, $browseType, $groupBy)
|
||||
{
|
||||
$objects = $this->objectModel->getKanban4Group($executionID, $browseType, $groupBy);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getLanes4GroupTest($executionID, $browseType, $groupBy, $cardList)
|
||||
{
|
||||
$objects = $this->objectModel->getLanes4Group($executionID, $browseType, $groupBy, $cardList);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getSpaceListTest($browseType, $pager = null)
|
||||
{
|
||||
$objects = $this->objectModel->getSpaceList($browseType, $pager = null);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getSpacePairsTest($browseType = 'private')
|
||||
{
|
||||
$objects = $this->objectModel->getSpacePairs($browseType = 'private');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getKanbanPairsTest()
|
||||
{
|
||||
$objects = $this->objectModel->getKanbanPairs();
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getCanViewObjectsTest($objectType = 'kanban', $param = '')
|
||||
{
|
||||
$objects = $this->objectModel->getCanViewObjects($objectType = 'kanban', $param = '');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function createSpaceTest()
|
||||
{
|
||||
$objects = $this->objectModel->createSpace();
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function updateSpaceTest($spaceID, $type = '')
|
||||
{
|
||||
$objects = $this->objectModel->updateSpace($spaceID, $type = '');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getLanePairsByRegionTest($regionID, $type = 'all')
|
||||
{
|
||||
$objects = $this->objectModel->getLanePairsByRegion($regionID, $type = 'all');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getLaneGroupByRegionTest($regionID, $type = 'all')
|
||||
{
|
||||
$objects = $this->objectModel->getLaneGroupByRegion($regionID, $type = 'all');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function createLaneTest($kanbanID, $regionID, $lane = null)
|
||||
{
|
||||
$objects = $this->objectModel->createLane($kanbanID, $regionID, $lane = null);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create a kanban.
|
||||
*
|
||||
* @param array $param
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function createTest($param = array())
|
||||
{
|
||||
foreach($param as $key => $value) $_POST[$key] = $value;
|
||||
|
||||
$objectID = $this->objectModel->create();
|
||||
|
||||
unset($_POST);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
$object = $this->objectModel->getByID($objectID);
|
||||
return $object;
|
||||
}
|
||||
|
||||
public function updateTest($kanbanID)
|
||||
{
|
||||
$objects = $this->objectModel->update($kanbanID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test add execution Kanban lanes and columns.
|
||||
*
|
||||
* @param int $executionID
|
||||
* @param string $type
|
||||
* @param string $groupBy
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function createExecutionLaneTest($executionID, $type = 'all', $groupBy = 'default')
|
||||
{
|
||||
$this->objectModel->createExecutionLane($executionID, $type, $groupBy);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
global $tester;
|
||||
$objects = $tester->dao->select('*')->from(TABLE_KANBANLANE)
|
||||
->where('execution')->eq($executionID)
|
||||
->beginIF($type != 'all')->andWhere('type')->eq($type)->fi()
|
||||
->fetchAll();
|
||||
return count($objects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create execution columns.
|
||||
*
|
||||
* @param int $laneID
|
||||
* @param string $type
|
||||
* @param int $executionID
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function createExecutionColumnsTest($laneID, $type, $executionID)
|
||||
{
|
||||
$this->objectModel->createExecutionColumns($laneID, $type, $executionID);
|
||||
|
||||
global $tester;
|
||||
$objects = $tester->dao->select('*')->from(TABLE_KANBANCELL)
|
||||
->where('kanban')->eq($executionID)
|
||||
->andWhere('lane')->eq($laneID)
|
||||
->andWhere('type')->eq($type)
|
||||
->fetchAll();
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return count($objects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test add kanban cell.
|
||||
*
|
||||
* @param int $kanbanID
|
||||
* @param int $laneID
|
||||
* @param int $colID
|
||||
* @param int $type
|
||||
* @param int $cardID
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function addKanbanCellTest($kanbanID, $laneID, $colID, $type, $cardID = 0)
|
||||
{
|
||||
$this->objectModel->addKanbanCell($kanbanID, $laneID, $colID, $type, $cardID);
|
||||
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
global $tester;
|
||||
$object = $tester->dao->select('*')->from(TABLE_KANBANCELL)->where('kanban')->eq($kanbanID)->andWhere('lane')->eq($laneID)->andWhere('`column`')->eq($colID)->andWhere('type')->eq($type)->fetch();
|
||||
return $object;
|
||||
}
|
||||
|
||||
public function removeKanbanCellTest($type, $removeCardID, $kanbanList)
|
||||
{
|
||||
$objects = $this->objectModel->removeKanbanCell($type, $removeCardID, $kanbanList);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function createRDKanbanTest($execution)
|
||||
{
|
||||
$objects = $this->objectModel->createRDKanban($execution);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function createRDRegionTest($execution)
|
||||
{
|
||||
$objects = $this->objectModel->createRDRegion($execution);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function createRDLaneTest($executionID, $regionID)
|
||||
{
|
||||
$objects = $this->objectModel->createRDLane($executionID, $regionID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function createRDColumnTest($regionID, $groupID, $laneID, $laneType, $executionID)
|
||||
{
|
||||
$objects = $this->objectModel->createRDColumn($regionID, $groupID, $laneID, $laneType, $executionID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function updateRegionTest($regionID)
|
||||
{
|
||||
$objects = $this->objectModel->updateRegion($regionID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function updateLaneTest($executionID, $laneType, $cardID = 0)
|
||||
{
|
||||
$objects = $this->objectModel->updateLane($executionID, $laneType, $cardID = 0);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function refreshCardsTest($lane)
|
||||
{
|
||||
$objects = $this->objectModel->refreshCards($lane);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function updateLaneColumnTest($columnID, $column)
|
||||
{
|
||||
$objects = $this->objectModel->updateLaneColumn($columnID, $column);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function updateLaneOrderTest($executionID, $currentType, $targetType)
|
||||
{
|
||||
$objects = $this->objectModel->updateLaneOrder($executionID, $currentType, $targetType);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test activate a card.
|
||||
*
|
||||
* @param int $cardID
|
||||
* @param int $progress
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function activateCardTest($cardID, $progress)
|
||||
{
|
||||
global $tester;
|
||||
$tester->post->progress = $progress;
|
||||
|
||||
$this->objectModel->activateCard($cardID);
|
||||
|
||||
unset($this->post);
|
||||
|
||||
if(dao::isError()) return dao::getError()[0];
|
||||
|
||||
$object = $this->objectModel->getCardByID($cardID);
|
||||
return $object;
|
||||
}
|
||||
|
||||
public function updateCardTest($cardID)
|
||||
{
|
||||
$objects = $this->objectModel->updateCard($cardID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function setWIPTest($columnID)
|
||||
{
|
||||
$objects = $this->objectModel->setWIP($columnID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function setLaneTest($laneID)
|
||||
{
|
||||
$objects = $this->objectModel->setLane($laneID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function setLaneHeightTest($kanbanID, $from = 'kanban')
|
||||
{
|
||||
$objects = $this->objectModel->setLaneHeight($kanbanID, $from = 'kanban');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function setColumnWidthTest($kanbanID, $from = 'kanban')
|
||||
{
|
||||
$objects = $this->objectModel->setColumnWidth($kanbanID, $from = 'kanban');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function setHeaderActionsTest($kanban)
|
||||
{
|
||||
$objects = $this->objectModel->setHeaderActions($kanban);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function setSwitcherTest($kanban)
|
||||
{
|
||||
$objects = $this->objectModel->setSwitcher($kanban);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function sortGroupTest($region, $groups)
|
||||
{
|
||||
$objects = $this->objectModel->sortGroup($region, $groups);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function moveCardTest($cardID, $fromColID, $toColID, $fromLaneID, $toLaneID, $kanbanID = 0)
|
||||
{
|
||||
$objects = $this->objectModel->moveCard($cardID, $fromColID, $toColID, $fromLaneID, $toLaneID, $kanbanID = 0);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function updateCardColorTest($cardID, $color)
|
||||
{
|
||||
$objects = $this->objectModel->updateCardColor($cardID, $color);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function resetLaneOrderTest($executionID, $type, $groupBy)
|
||||
{
|
||||
$objects = $this->objectModel->resetLaneOrder($executionID, $type, $groupBy);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test archive a column.
|
||||
*
|
||||
* @param int $columnID
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function archiveColumnTest($columnID)
|
||||
{
|
||||
$this->objectModel->archiveColumn($columnID);
|
||||
|
||||
$object = $this->objectModel->getColumnByID($columnID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
public function restoreColumnTest($columnID)
|
||||
{
|
||||
$objects = $this->objectModel->restoreColumn($columnID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test archive a card.
|
||||
*
|
||||
* @param int $cardID
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function archiveCardTest($cardID)
|
||||
{
|
||||
$changes = $this->objectModel->archiveCard($cardID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $changes;
|
||||
}
|
||||
|
||||
public function restoreCardTest($cardID)
|
||||
{
|
||||
$objects = $this->objectModel->restoreCard($cardID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function processCardsTest($column)
|
||||
{
|
||||
$objects = $this->objectModel->processCards($column);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getSpaceByIdTest($spaceID)
|
||||
{
|
||||
$objects = $this->objectModel->getSpaceById($spaceID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getGroupBySpaceListTest($spaceIdList, $kanbanIdList = '')
|
||||
{
|
||||
$objects = $this->objectModel->getGroupBySpaceList($spaceIdList, $kanbanIdList = '');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getGroupListTest($region)
|
||||
{
|
||||
$objects = $this->objectModel->getGroupList($region);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getColumnByIDTest($columnID)
|
||||
{
|
||||
$objects = $this->objectModel->getColumnByID($columnID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getColumnsByObjectTest($objectType = '', $objectID = 0, $archived = 0, $deleted = '0')
|
||||
{
|
||||
$objects = $this->objectModel->getColumnsByObject($objectType = '', $objectID = 0, $archived = 0, $deleted = '0');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getColumnIDByLaneIDTest($laneID, $columnType)
|
||||
{
|
||||
$objects = $this->objectModel->getColumnIDByLaneID($laneID, $columnType);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getLaneByIdTest($laneID)
|
||||
{
|
||||
$objects = $this->objectModel->getLaneById($laneID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getObjectGroupTest($executionID, $type, $groupBy)
|
||||
{
|
||||
$objects = $this->objectModel->getObjectGroup($executionID, $type, $groupBy);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getCardByIDTest($cardID)
|
||||
{
|
||||
$objects = $this->objectModel->getCardByID($cardID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getCardsByObjectTest($objectType = '', $objectID = 0, $archived = '0', $deleted = '0')
|
||||
{
|
||||
$objects = $this->objectModel->getCardsByObject($objectType = '', $objectID = 0, $archived = '0', $deleted = '0');
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getCards2ImportTest($kanbanID = 0, $excludedID = 0, $pager = null)
|
||||
{
|
||||
$objects = $this->objectModel->getCards2Import($kanbanID = 0, $excludedID = 0, $pager = null);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getKanbanCardMenuTest($executionID, $objects, $objecType)
|
||||
{
|
||||
$objects = $this->objectModel->getKanbanCardMenu($executionID, $objects, $objecType);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function isClickableTest($object, $action)
|
||||
{
|
||||
$objects = $this->objectModel->isClickable($object, $action);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function importTest($kanbanID)
|
||||
{
|
||||
$objects = $this->objectModel->import($kanbanID);
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $objects;
|
||||
}
|
||||
}
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/kanban.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 kanbanModel->activateCard();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
$cardIDList = array('1', '2', '3', '4', '5', '100001');
|
||||
$progressList = array('0', '50', '100', '101', '-1');
|
||||
|
||||
$kanban = new kanbanTest();
|
||||
|
||||
r($kanban->activateCardTest($cardIDList[0], $progressList[0])) && p('id,name,status,progress') && e('1,卡片1,doing,0'); // 测试激活卡片1,进度0
|
||||
r($kanban->activateCardTest($cardIDList[0], $progressList[1])) && p('id,name,status,progress') && e('1,卡片1,doing,50'); // 测试激活卡片1,进度50
|
||||
r($kanban->activateCardTest($cardIDList[0], $progressList[2])) && p('0:') && e('请输入正确的进度'); // 测试激活卡片1,进度100
|
||||
r($kanban->activateCardTest($cardIDList[0], $progressList[3])) && p('0:') && e('请输入正确的进度'); // 测试激活卡片1,进度101
|
||||
r($kanban->activateCardTest($cardIDList[0], $progressList[4])) && p('0:') && e('请输入正确的进度'); // 测试激活卡片1,进度-1
|
||||
r($kanban->activateCardTest($cardIDList[1], $progressList[0])) && p('id,name,status,progress') && e('2,卡片2,doing,0'); // 测试激活卡片2,进度0
|
||||
r($kanban->activateCardTest($cardIDList[2], $progressList[1])) && p('id,name,status,progress') && e('3,卡片3,doing,50'); // 测试激活卡片3,进度0
|
||||
r($kanban->activateCardTest($cardIDList[3], $progressList[0])) && p('id,name,status,progress') && e('4,卡片4,doing,0'); // 测试激活卡片4,进度0
|
||||
r($kanban->activateCardTest($cardIDList[4], $progressList[1])) && p('id,name,status,progress') && e('5,卡片5,doing,50'); // 测试激活卡片5,进度0
|
||||
r($kanban->activateCardTest($cardIDList[5], $progressList[0])) && p('id,name,status,progress') && e('0'); // 测试激活不存在的卡片,进度0
|
||||
system("./ztest init");
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/kanban.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 kanbanModel->addKanbanCell();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
$kanban = new kanbanTest();
|
||||
|
||||
$kanbanIDList = array('1', '161');
|
||||
$laneIDList = array('1', '101', '102', '103');
|
||||
$columnIDList = array('1', '408', '412', '421');
|
||||
$typeList = array('common', 'story', 'bug', 'task');
|
||||
$cardID = '3';
|
||||
|
||||
r($kanban->addKanbanCellTest($kanbanIDList[0], $laneIDList[0], $columnIDList[0], $typeList[0])) && p('type,cards') && e('common,,0,1,2,'); // 更新类型为common的kanbancell
|
||||
r($kanban->addKanbanCellTest($kanbanIDList[0], $laneIDList[0], $columnIDList[0], $typeList[0], $cardID)) && p('type,cards') && e('common,,3,0,1,2,'); // 更新类型为common的kanbancell 有cardID
|
||||
r($kanban->addKanbanCellTest($kanbanIDList[0], $laneIDList[1], $columnIDList[0], $typeList[0])) && p('type,cards') && e('common,'); // 插入类型为common的kanbancell
|
||||
r($kanban->addKanbanCellTest($kanbanIDList[0], $laneIDList[1], $columnIDList[0], $typeList[0], $cardID)) && p('type,cards') && e('common,,3,'); // 插入类型为common的kanbancell 有cardID
|
||||
r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[1], $columnIDList[1], $typeList[1])) && p('type,cards') && e('story,,0,'); // 更新类型为story的kanbancell
|
||||
r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[1], $columnIDList[1], $typeList[1], $cardID)) && p('type,cards') && e('story,,3,0,'); // 更新类型为story的kanbancell 有cardID
|
||||
r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[1], $columnIDList[2], $typeList[1])) && p('type,cards') && e('story,'); // 插入类型为story的kanbancell
|
||||
r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[1], $columnIDList[2], $typeList[1], $cardID)) && p('type,cards') && e('story,,3,'); // 插入类型为story的kanbancell 有cardID
|
||||
r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[2], $columnIDList[2], $typeList[2])) && p('type,cards') && e('bug,,0,'); // 更新类型为bug的kanbancell
|
||||
r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[2], $columnIDList[2], $typeList[2], $cardID)) && p('type,cards') && e('bug,,3,0,'); // 更新类型为bug的kanbancell 有cardID
|
||||
r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[2], $columnIDList[3], $typeList[2])) && p('type,cards') && e('bug,'); // 插入类型为bug的kanbancell
|
||||
r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[2], $columnIDList[3], $typeList[2], $cardID)) && p('type,cards') && e('bug,,3,'); // 插入类型为bug的kanbancell 有cardID
|
||||
r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[3], $columnIDList[3], $typeList[3])) && p('type,cards') && e('task,,0,'); // 更新类型为task的kanbancell
|
||||
r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[3], $columnIDList[3], $typeList[3], $cardID)) && p('type,cards') && e('task,,3,0,'); // 更新类型为task的kanbancell 有cardID
|
||||
r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[3], $columnIDList[0], $typeList[3])) && p('type,cards') && e('task,'); // 插入类型为task的kanbancell
|
||||
r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[3], $columnIDList[0], $typeList[3], $cardID)) && p('type,cards') && e('task,,3,'); // 插入类型为task的kanbancell 有cardID
|
||||
system("./ztest init");
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/kanban.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 kanbanModel->archiveCard();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
$cardIDList = array('1', '2', '3', '4', '5');
|
||||
|
||||
$kanban = new kanbanTest();
|
||||
|
||||
r($kanban->archiveCardTest($cardIDList[0])) && p('0:field,old,new') && e('archived,0,1'); // 测试归档卡片1
|
||||
r($kanban->archiveCardTest($cardIDList[1])) && p('0:field,old,new') && e('archived,0,1'); // 测试归档卡片2
|
||||
r($kanban->archiveCardTest($cardIDList[2])) && p('0:field,old,new') && e('archived,0,1'); // 测试归档卡片3
|
||||
r($kanban->archiveCardTest($cardIDList[3])) && p('0:field,old,new') && e('archived,0,1'); // 测试归档卡片4
|
||||
r($kanban->archiveCardTest($cardIDList[4])) && p('0:field,old,new') && e('archived,0,1'); // 测试归档卡片5
|
||||
system("./ztest init");
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/kanban.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 kanbanModel->archiveColumn();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
$columnIDList = array('1', '2', '3', '4', '5', '1000001');
|
||||
|
||||
$kanban = new kanbanTest();
|
||||
|
||||
r($kanban->archiveColumnTest($columnIDList[0])) && p('id,archived') && e('1,1'); // 测试归档列1
|
||||
r($kanban->archiveColumnTest($columnIDList[1])) && p('id,archived') && e('2,1'); // 测试归档列2
|
||||
r($kanban->archiveColumnTest($columnIDList[2])) && p('id,archived') && e('3,1'); // 测试归档列3
|
||||
r($kanban->archiveColumnTest($columnIDList[3])) && p('id,archived') && e('4,1'); // 测试归档列4
|
||||
r($kanban->archiveColumnTest($columnIDList[4])) && p('id,archived') && e('5,1'); // 测试归档列5
|
||||
r($kanban->archiveColumnTest($columnIDList[5])) && p() && e('0'); // 测试归档不存在的列
|
||||
system("./ztest init");
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/kanban.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 kanbanModel->batchCreateCard();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
$no_name = array('0' => '', '1' => '批量创建的卡片2', '2' => '批量创建的卡片3', '3' => '批量创建的卡片4');
|
||||
$estimate = array('0' => '1', '1' => '-1', '2' => '-2', '3' => '-3');
|
||||
$endDitto = array('1' => 'off', '2' => 'off', '3' => 'off', '4' => 'off');
|
||||
|
||||
$kanban = new kanbanTest();
|
||||
|
||||
r($kanban->batchCreateCardTest(array('name' => $no_name))) && p('kanban,column,lane,type,cards') && e('1,1,1,common,,803,802,801,1,2,'); // 批量创建卡片 其中一个没有名称
|
||||
r($kanban->batchCreateCardTest(array('estimate' => $estimate))) && p() && e('预计不能为负数!'); // 批量创建卡片 预计为负数
|
||||
r($kanban->batchCreateCardTest(array(), true)) && p() && e('"截止日期"不能小于"预计开始"!'); // 批量创建看板 截止日期小于开始日期
|
||||
r($kanban->batchCreateCardTest()) && p('kanban,column,lane,type,cards') && e('1,1,1,common,,810,809,808,807,804,803,802,801,1,2,'); // 批量创建看板
|
||||
system("./ztest init");
|
||||
Executable
+71
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/kanban.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 kanbanModel->create();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
$kanban1 = new stdclass();
|
||||
$kanban1->type = 'cooperation';
|
||||
$kanban1->space = 1;
|
||||
$kanban1->name = '测试创建协作看板';
|
||||
$kanban1->owner = 'po15';
|
||||
$kanban1->team = array('', 'user3');
|
||||
$kanban1->desc = '测试创建协作看板的描述';
|
||||
|
||||
$kanban2 = new stdclass();
|
||||
$kanban2->type = 'private';
|
||||
$kanban2->space = 2;
|
||||
$kanban2->name = '测试创建私人看板';
|
||||
$kanban2->owner = 'po16';
|
||||
$kanban2->whitelist = array('', 'user4');
|
||||
$kanban2->desc = '测试创建私人看板的描述';
|
||||
|
||||
$kanban3 = new stdclass();
|
||||
$kanban3->type = 'open';
|
||||
$kanban3->space = 3;
|
||||
$kanban3->name = '测试创建公共看板';
|
||||
$kanban3->owner = 'po17';
|
||||
$kanban3->team = array('', 'user5');
|
||||
$kanban3->desc = '测试创建公共看板的描述';
|
||||
|
||||
$kanban4 = new stdclass();
|
||||
$kanban4->type = 'open';
|
||||
$kanban4->space = 3;
|
||||
$kanban4->name = '';
|
||||
$kanban4->owner = 'po17';
|
||||
$kanban4->team = array('', 'user5');
|
||||
$kanban4->desc = '测试创建没有名字看板的描述';
|
||||
|
||||
$kanban5 = new stdclass();
|
||||
$kanban5->type = 'open';
|
||||
$kanban5->space = 0;
|
||||
$kanban5->name = '测试创建没有空间的公共看板';
|
||||
$kanban5->owner = 'po17';
|
||||
$kanban5->team = array('', 'user5');
|
||||
$kanban5->desc = '测试创建没有空间的公共看板的描述';
|
||||
|
||||
$kanban6 = new stdclass();
|
||||
$kanban6->type = 'open';
|
||||
$kanban6->space = 3;
|
||||
$kanban6->name = '测试创建公共看板';
|
||||
$kanban6->owner = 'po17';
|
||||
$kanban6->team = array('', 'user5');
|
||||
$kanban6->desc = '测试创建重名的公共看板的描述';
|
||||
|
||||
$kanban = new kanbanTest();
|
||||
|
||||
r($kanban->createTest($kanban1)) && p('name,space,type,owner,whitelist') && e('测试创建协作看板,1,,po15,'); // 创建协同空间
|
||||
r($kanban->createTest($kanban2)) && p('name,space,type,owner,whitelist') && e('测试创建私人看板,2,,admin,,user4'); // 创建私人空间
|
||||
r($kanban->createTest($kanban3)) && p('name,space,type,owner,whitelist') && e('测试创建公共看板,3,,po17,'); // 创建公共空间
|
||||
r($kanban->createTest($kanban4)) && p('name:0') && e('『看板名称』不能为空。'); // 创建没有名字的公共空间
|
||||
r($kanban->createTest($kanban5)) && p('space:0') && e('『所属空间』不能为空。'); // 创建没有空间公共空间
|
||||
r($kanban->createTest($kanban6)) && p('name:0') && e('『看板名称』已经有『测试创建公共看板』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); // 创建重名公共空间
|
||||
system("./ztest init");
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/kanban.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 kanbanModel->createCard();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
$card1 = new stdclass();
|
||||
$card1->name = '测试创建卡片1';
|
||||
$card1->pri = '1';
|
||||
$card1->estimate = '1';
|
||||
$card1->assignedTo = array('po15', 'user3');
|
||||
$card1->desc = '测试创建卡片1的卡片描述';
|
||||
|
||||
$card2 = new stdclass();
|
||||
$card2->name = '测试创建卡片2';
|
||||
$card2->pri = '2';
|
||||
$card2->estimate = '2';
|
||||
$card2->assignedTo = array('user3');
|
||||
$card2->desc = '测试创建卡片2的卡片描述';
|
||||
|
||||
$card3 = new stdclass();
|
||||
$card3->name = '测试创建预计小于0的卡片';
|
||||
$card3->pri = '3';
|
||||
$card3->estimate = '-1';
|
||||
$card3->assignedTo = array('po15');
|
||||
$card3->desc = '测试创建预计小于0的卡片的描述';
|
||||
|
||||
$card4 = new stdclass();
|
||||
$card4->name = '测试创建结束小于开始日期的卡片';
|
||||
$card4->pri = '4';
|
||||
$card4->estimate = '4';
|
||||
$card4->assignedTo = array('user3');
|
||||
$card4->begin = '2022-03-29';
|
||||
$card4->end = '2022-03-20';
|
||||
$card4->desc = '测试创建结束小于开始日期的卡片的描述';
|
||||
|
||||
$card5 = new stdclass();
|
||||
$card5->name = '';
|
||||
$card5->pri = '1';
|
||||
$card5->estimate = '5';
|
||||
$card5->assignedTo = array('po15');
|
||||
$card5->desc = '测试不填写名称的卡片的卡片描述';
|
||||
|
||||
$kanban = new kanbanTest();
|
||||
|
||||
r($kanban->createCardTest($card1)) && p('name,pri,estimate,desc') && e('测试创建卡片1,1,1,测试创建卡片1的卡片描述'); // 测试创建卡片1
|
||||
r($kanban->createCardTest($card2)) && p('name,pri,estimate,desc') && e('测试创建卡片2,2,2,测试创建卡片2的卡片描述'); // 测试创建卡片2
|
||||
r($kanban->createCardTest($card3)) && p('estimate') && e('预计不能为负数!'); // 测试创建预计小于0的卡片
|
||||
r($kanban->createCardTest($card4)) && p('end') && e('"截止日期"不能小于"预计开始"!'); // 测试创建结束小于开始日期的卡片
|
||||
r($kanban->createCardTest($card5)) && p('name:0') && e('『卡片名称』不能为空。'); // 测试创建没有名字的卡片
|
||||
system("./ztest init");
|
||||
Executable
+89
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/kanban.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 kanbanModel->createColumn();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
$column1 = new stdclass();
|
||||
$column1->name = '测试创建不限制看板列';
|
||||
$column1->limit = '-1';
|
||||
$column1->noLimit = '-1';
|
||||
$column1->color = '#333';
|
||||
$column1->group = '1';
|
||||
$column1->parent = '0';
|
||||
|
||||
$column2 = new stdclass();
|
||||
$column2->name = '测试创建不限制子看板列';
|
||||
$column2->limit = '-1';
|
||||
$column2->noLimit = '-1';
|
||||
$column2->color = '#333';
|
||||
$column2->group = '1';
|
||||
$column2->parent = '1';
|
||||
|
||||
$column3 = new stdclass();
|
||||
$column3->name = '测试创建限制父看板列';
|
||||
$column3->WIPCount = '111';
|
||||
$column3->limit = '111';
|
||||
$column3->color = '#333';
|
||||
$column3->group = '1';
|
||||
$column3->parent = '-1';
|
||||
|
||||
$column4 = new stdclass();
|
||||
$column4->name = '测试创建限制子看板列';
|
||||
$column4->WIPCount = '11';
|
||||
$column4->limit = '11';
|
||||
$column4->color = '#333';
|
||||
$column4->group = '1';
|
||||
$column4->parent = '5263';
|
||||
|
||||
$column5 = new stdclass();
|
||||
$column5->name = '';
|
||||
$column5->limit = '-1';
|
||||
$column5->noLimit = '-1';
|
||||
$column5->color = '#333';
|
||||
$column5->group = '1';
|
||||
$column5->parent = '0';
|
||||
|
||||
$column6 = new stdclass();
|
||||
$column6->name = '测试创建不填写在制品数量的看板列';
|
||||
$column6->WIPCount = '';
|
||||
$column6->limit = '';
|
||||
$column6->color = '#333';
|
||||
$column6->group = '1';
|
||||
$column6->parent = '0';
|
||||
|
||||
$column7 = new stdclass();
|
||||
$column7->name = '测试创建在制品数量为0的看板列';
|
||||
$column7->WIPCount = 0;
|
||||
$column7->limit = 0;
|
||||
$column7->color = '#333';
|
||||
$column7->group = '1';
|
||||
$column7->parent = '0';
|
||||
|
||||
$column8 = new stdclass();
|
||||
$column8->name = '测试创建在制品数量超出限制的子看板列';
|
||||
$column8->WIPCount = '111';
|
||||
$column8->limit = '111';
|
||||
$column8->color = '#333';
|
||||
$column8->group = '1';
|
||||
$column8->parent = '5263';
|
||||
|
||||
$kanban = new kanbanTest();
|
||||
|
||||
r($kanban->createColumnTest($column1)) && p('name,limit,color,parent,group') && e('测试创建不限制看板列,-1,#333,0,1'); // 创建没有在制品限制的看板列
|
||||
r($kanban->createColumnTest($column2)) && p('name,limit,color,parent,group') && e('测试创建不限制子看板列,-1,#333,1,1'); // 创建没有在制品限制的看板列
|
||||
r($kanban->createColumnTest($column3)) && p('name,limit,color,parent,group') && e('测试创建限制父看板列,111,#333,-1,1'); // 创建有在制品限制的看板列
|
||||
r($kanban->createColumnTest($column4)) && p('name,limit,color,parent,group') && e('测试创建限制子看板列,11,#333,5263,1'); // 创建有在制品限制的子看板列
|
||||
r($kanban->createColumnTest($column5)) && p('name:0') && e('『看板列名称』不能为空。'); // 创建没有名称的看板列
|
||||
r($kanban->createColumnTest($column6)) && p('limit') && e('在制品数量必须是正整数。'); // 创建没有填写在制品限制的看板列
|
||||
r($kanban->createColumnTest($column7)) && p('limit') && e('在制品数量必须是正整数。'); // 创建在制品数量为0的看板列
|
||||
r($kanban->createColumnTest($column8)) && p('limit:0') && e('父列的在制品数量不能小于子列在制品数量之和'); // 创建在制品数量超出限制的子看板列
|
||||
system("./ztest init");
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/kanban.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 kanbanModel->createDefaultColumns();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
$kanban = new kanbanTest();
|
||||
|
||||
$regionIDList = array('1', '2', '3', '4', '5');
|
||||
$groupIDList = array('1', '2', '3', '4', '5');
|
||||
|
||||
r($kanban->createDefaultColumnsTest($regionIDList[0], $groupIDList[0])) && p() && e('8'); // 创建region 1 group 1的默认泳道列
|
||||
r($kanban->createDefaultColumnsTest($regionIDList[1], $groupIDList[1])) && p() && e('8'); // 创建region 2 group 2的默认泳道列
|
||||
r($kanban->createDefaultColumnsTest($regionIDList[2], $groupIDList[2])) && p() && e('8'); // 创建region 3 group 3的默认泳道列
|
||||
r($kanban->createDefaultColumnsTest($regionIDList[3], $groupIDList[3])) && p() && e('8'); // 创建region 4 group 4的默认泳道列
|
||||
r($kanban->createDefaultColumnsTest($regionIDList[4], $groupIDList[4])) && p() && e('8'); // 创建region 5 group 5的默认泳道列
|
||||
r($kanban->createDefaultColumnsTest($regionIDList[0], $groupIDList[0])) && p() && e('12'); // 重复创建region 1 group 1的默认泳道列
|
||||
system("./ztest init");
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/kanban.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 kanbanModel->createDefaultLane();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
$kanban = new kanbanTest();
|
||||
|
||||
$regionIDList = array('1', '2', '3', '4', '5');
|
||||
$groupIDList = array('1', '2', '3', '4', '5');
|
||||
|
||||
r($kanban->createDefaultLaneTest($regionIDList[0], $groupIDList[0])) && p('name,group,region,type') && e('默认泳道,1,1,common'); // 创建region 1 group 1的默认泳道
|
||||
r($kanban->createDefaultLaneTest($regionIDList[1], $groupIDList[1])) && p('name,group,region,type') && e('默认泳道,2,2,common'); // 创建region 2 group 2的默认泳道
|
||||
r($kanban->createDefaultLaneTest($regionIDList[2], $groupIDList[2])) && p('name,group,region,type') && e('默认泳道,3,3,common'); // 创建region 3 group 3的默认泳道
|
||||
r($kanban->createDefaultLaneTest($regionIDList[3], $groupIDList[3])) && p('name,group,region,type') && e('默认泳道,4,4,common'); // 创建region 4 group 4的默认泳道
|
||||
r($kanban->createDefaultLaneTest($regionIDList[4], $groupIDList[4])) && p('name,group,region,type') && e('默认泳道,5,5,common'); // 创建region 5 group 5的默认泳道
|
||||
system("./ztest init");
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/kanban.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 kanbanModel->createDefaultRegion();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
$kanban1 = new stdclass();
|
||||
$kanban1->id = 10001;
|
||||
$kanban1->space = 10001;
|
||||
|
||||
$kanban2 = new stdclass();
|
||||
$kanban2->id = 10002;
|
||||
$kanban2->space = 10002;
|
||||
|
||||
$kanban3 = new stdclass();
|
||||
$kanban3->id = 10003;
|
||||
$kanban3->space = 10003;
|
||||
|
||||
$kanban4 = new stdclass();
|
||||
$kanban4->id = 10004;
|
||||
$kanban4->space = 10004;
|
||||
|
||||
$kanban5 = new stdclass();
|
||||
$kanban5->id = 1;
|
||||
$kanban5->space = 1;
|
||||
|
||||
$kanban = new kanbanTest();
|
||||
|
||||
r($kanban->createDefaultRegionTest($kanban1)) && p('space,kanban,name') && e('10001,10001,默认区域'); // 创建看板10001的默认区域
|
||||
r($kanban->createDefaultRegionTest($kanban2)) && p('space,kanban,name') && e('10002,10002,默认区域'); // 创建看板10002的默认区域
|
||||
r($kanban->createDefaultRegionTest($kanban3)) && p('space,kanban,name') && e('10003,10003,默认区域'); // 创建看板10003的默认区域
|
||||
r($kanban->createDefaultRegionTest($kanban4)) && p('space,kanban,name') && e('10004,10004,默认区域'); // 创建看板10004的默认区域
|
||||
r($kanban->createDefaultRegionTest($kanban5)) && p('name:0') && e('『区域名称』已经有『默认区域』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); // 重复创建看板1的默认区域
|
||||
system("./ztest init");
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/kanban.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 kanbanModel->createExecutionColumns();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
$laneIDList = array('100001', '100002', '100003', '10004', '10005');
|
||||
$executionIDList = array('101', '102', '103', '104', '105');
|
||||
$typeList = array('story', 'task', 'bug');
|
||||
|
||||
$kanban = new kanbanTest();
|
||||
|
||||
r($kanban->createExecutionColumnsTest($laneIDList[0], $typeList[0], $executionIDList[0])) && p() && e('11'); // 创建泳道 100001 执行101 需求的看板列
|
||||
r($kanban->createExecutionColumnsTest($laneIDList[0], $typeList[1], $executionIDList[0])) && p() && e('7'); // 创建泳道 100001 执行101 任务的看板列
|
||||
r($kanban->createExecutionColumnsTest($laneIDList[0], $typeList[2], $executionIDList[0])) && p() && e('9'); // 创建泳道 100001 执行101 bug 的看板列
|
||||
r($kanban->createExecutionColumnsTest($laneIDList[1], $typeList[0], $executionIDList[1])) && p() && e('11'); // 创建泳道 100002 执行102 需求的看板列
|
||||
r($kanban->createExecutionColumnsTest($laneIDList[1], $typeList[1], $executionIDList[1])) && p() && e('7'); // 创建泳道 100002 执行102 任务的看板列
|
||||
r($kanban->createExecutionColumnsTest($laneIDList[1], $typeList[1], $executionIDList[1])) && p() && e('14'); // 创建泳道 100002 执行102 bug 的看板列
|
||||
r($kanban->createExecutionColumnsTest($laneIDList[2], $typeList[0], $executionIDList[2])) && p() && e('11'); // 创建泳道 100003 执行103 需求的看板列
|
||||
r($kanban->createExecutionColumnsTest($laneIDList[2], $typeList[1], $executionIDList[2])) && p() && e('7'); // 创建泳道 100003 执行103 任务的看板列
|
||||
r($kanban->createExecutionColumnsTest($laneIDList[2], $typeList[2], $executionIDList[2])) && p() && e('9'); // 创建泳道 100003 执行103 bug 的看板列
|
||||
r($kanban->createExecutionColumnsTest($laneIDList[3], $typeList[0], $executionIDList[3])) && p() && e('11'); // 创建泳道 100004 执行104 需求的看板列
|
||||
r($kanban->createExecutionColumnsTest($laneIDList[3], $typeList[1], $executionIDList[3])) && p() && e('7'); // 创建泳道 100004 执行104 任务的看板列
|
||||
r($kanban->createExecutionColumnsTest($laneIDList[3], $typeList[2], $executionIDList[3])) && p() && e('9'); // 创建泳道 100004 执行104 bug 的看板列
|
||||
r($kanban->createExecutionColumnsTest($laneIDList[4], $typeList[0], $executionIDList[4])) && p() && e('11'); // 创建泳道 100005 执行105 需求的看板列
|
||||
r($kanban->createExecutionColumnsTest($laneIDList[4], $typeList[1], $executionIDList[4])) && p() && e('7'); // 创建泳道 100005 执行105 任务的看板列
|
||||
r($kanban->createExecutionColumnsTest($laneIDList[4], $typeList[2], $executionIDList[4])) && p() && e('9'); // 创建泳道 100005 执行105 bug 的看板列
|
||||
system("./ztest init");
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/kanban.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 kanbanModel->createExecutionLane();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
$executionIDList = array('101', '102', '103', '104', '105');
|
||||
$typeIDList = array('all', 'story', 'task', 'bug');
|
||||
$groupByIDList = array('default', 'pri', 'category', 'module', 'source', 'assignedTo', 'story', 'severity');
|
||||
|
||||
$kanban = new kanbanTest();
|
||||
|
||||
r($kanban->createExecutionLaneTest($executionIDList[0])) && p() && e('3'); // 创建执行101的泳道
|
||||
r($kanban->createExecutionLaneTest($executionIDList[0], $typeIDList[1])) && p() && e('2'); // 创建执行101 需求的泳道
|
||||
r($kanban->createExecutionLaneTest($executionIDList[0], $typeIDList[1], $groupByIDList[2])) && p() && e('3'); // 创建执行101 需求 按类别分组的泳道
|
||||
r($kanban->createExecutionLaneTest($executionIDList[1])) && p() && e('3'); // 创建执行101的泳道
|
||||
r($kanban->createExecutionLaneTest($executionIDList[1], $typeIDList[1], $groupByIDList[4])) && p() && e('3'); // 创建执行102 需求 按来源分组的泳道
|
||||
r($kanban->createExecutionLaneTest($executionIDList[1], $typeIDList[2], $groupByIDList[1])) && p() && e('4'); // 创建执行102 任务 按优先级分组的泳道
|
||||
r($kanban->createExecutionLaneTest($executionIDList[1], $typeIDList[2], $groupByIDList[6])) && p() && e('7'); // 创建执行102 任务 按需求分组的泳道
|
||||
r($kanban->createExecutionLaneTest($executionIDList[2])) && p() && e('3'); // 创建执行103的泳道
|
||||
r($kanban->createExecutionLaneTest($executionIDList[2], $typeIDList[3], $groupByIDList[7])) && p() && e('4'); // 创建执行103 bug 按严重程度分组的泳道
|
||||
r($kanban->createExecutionLaneTest($executionIDList[2], $typeIDList[3], $groupByIDList[3])) && p() && e('8'); // 创建执行103 bug 按模块分组的泳道
|
||||
r($kanban->createExecutionLaneTest($executionIDList[2], $typeIDList[3], $groupByIDList[5])) && p() && e('10'); // 创建执行103 bug 按指派给分组的泳道
|
||||
r($kanban->createExecutionLaneTest($executionIDList[3])) && p() && e('3'); // 创建执行104的泳道
|
||||
r($kanban->createExecutionLaneTest($executionIDList[4])) && p() && e('3'); // 创建执行105的泳道
|
||||
system("./ztest init");
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/kanban.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 kanbanModel->createGroup();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
*/
|
||||
|
||||
$kanbanIDList = array('1', '2', '3', '4', '5');
|
||||
$regionIDList = array('1', '2', '3', '4', '5');
|
||||
|
||||
$kanban = new kanbanTest();
|
||||
|
||||
r($kanban->createGroupTest($kanbanIDList[0], $regionIDList[0])) && p('kanaban,region,orde') && e(',1,'); // 测试创建看板1 区域1的看板组
|
||||
r($kanban->createGroupTest($kanbanIDList[1], $regionIDList[1])) && p('kanaban,region,orde') && e(',2,'); // 测试创建看板2 区域2的看板组
|
||||
r($kanban->createGroupTest($kanbanIDList[2], $regionIDList[2])) && p('kanaban,region,orde') && e(',3,'); // 测试创建看板3 区域3的看板组
|
||||
r($kanban->createGroupTest($kanbanIDList[3], $regionIDList[3])) && p('kanaban,region,orde') && e(',4,'); // 测试创建看板4 区域4的看板组
|
||||
r($kanban->createGroupTest($kanbanIDList[4], $regionIDList[4])) && p('kanaban,region,orde') && e(',5,'); // 测试创建看板5 区域5的看板组
|
||||
system("./ztest init");
|
||||
@@ -52,6 +52,9 @@ switch($argv[1])
|
||||
case 'build':
|
||||
ztfRun('model/build');
|
||||
break;
|
||||
case 'kanban':
|
||||
ztfRun('model/kanban');
|
||||
break;
|
||||
case 'model':
|
||||
ztfRun('model');
|
||||
break;
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+2
-2
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user