Merge branch 'master' into 'sprint/master_tanghucheng_fixbug'

# Conflicts:
#   module/user/js/batchcreate.js
#   module/user/view/batchcreate.html.php
This commit is contained in:
孙广明
2022-03-10 08:07:31 +00:00
96 changed files with 1878 additions and 176 deletions
+3 -3
View File
@@ -131,6 +131,8 @@ zentaoxx:
sed -i 's/commonModel::getLicensePropertyValue/extCommonModel::getLicensePropertyValue/g' zentaoxx/extension/xuan/im/control.php
sed -i 's/commonModel::getLicensePropertyValue/extCommonModel::getLicensePropertyValue/g' zentaoxx/extension/xuan/im/model/conference.php
sed -i 's/xxb_/zt_/g' zentaoxx/db/*.sql
sed -i "s#\$this->app->getModuleRoot() . 'im/apischeme.json'#\$this->app->getExtensionRoot() . 'xuan/im/apischeme.json'#g" zentaoxx/extension/xuan/im/model.php
sed -i "/getModuleExtPath(/ r tools/fixxuan" zentaoxx/framework/xuanxuan.class.php
echo "ALTER TABLE \`zt_user\` ADD \`pinyin\` varchar(255) NOT NULL DEFAULT '' AFTER \`realname\`;" >> zentaoxx/db/xuanxuan.sql
mkdir zentaoxx/tools; cp tools/cn2tw.php zentaoxx/tools; cd zentaoxx/tools; php cn2tw.php
cp tools/en2de.php zentaoxx/tools; cd zentaoxx/tools; php en2de.php ../
@@ -242,12 +244,10 @@ ci:
make package
zip -rq -9 ZenTaoPMS.$(VERSION).zip zentaopms
#make deb; make rpm; make en
rm -fr zentaopms zentaoxx zentaoxx.*.zip
make en
rm -fr zentaopms zentaoxx zentaoxx.*.zip
php tools/mergezentaopms.php $(VERSION)
rm zentaobiz*.zip zentaomax*.zip
rm -f zentaobiz*.zip zentaomax*.zip $(BUILD_PATH)/ZenTaoPMS.$(VERSION).zip $(RELEASE_PATH)/ZenTaoALM.$(VERSION)*.zip $(RELEASE_PATH)/ZenTaoPMS.$(VERSION)*.zip $(RELEASE_PATH)/*.deb $(RELEASE_PATH)/*.rpm
cp ZenTaoPMS.$(VERSION).zip $(BUILD_PATH)
rm -f $(RELEASE_PATH)/*.deb $(RELEASE_PATH)/*.rpm
mv *.zip *.deb *.rpm $(RELEASE_PATH)
+1
View File
@@ -246,6 +246,7 @@ $filter->program->ajaxgetdropmenu->cookie['showClosed'] = 'code';
$filter->project->default->cookie['lastProject'] = 'int';
$filter->project->default->cookie['lastPRJ'] = 'int';
$filter->project->default->cookie['projectMode'] = 'code';
$filter->project->default->cookie['kanbanview'] = 'code';
$filter->project->browse->cookie['involved'] = 'code';
$filter->project->browse->cookie['projectType'] = 'code';
$filter->project->story->cookie['storyModuleParam'] = 'int';
+1
View File
@@ -68,3 +68,4 @@ ALTER TABLE `zt_bug` ADD `entry` varchar(255) COLLATE 'utf8_general_ci' NOT NULL
ALTER TABLE `zt_repobranch` ADD INDEX `revision` (`revision`);
DELETE FROM `zt_grouppriv` WHERE `module` = 'api' AND `method` = 'sql';
REPLACE INTO `zt_config` set `owner` = 'system', `module` = 'common', `section` = 'global', `key` = 'showAnnual', `value` = '1';
+2
View File
@@ -29,3 +29,5 @@ INSERT INTO `zt_group` (`vision`, `name`, `role`, `desc`) VALUES
('lite', '迅捷版用户分组', 'liteUser', '迅捷版用户分组');
ALTER TABLE `zt_productplan` ADD `closedReason` varchar(20) NOT NULL AFTER `order`;
update zt_config set `value` = concat(`value`, ',visions') where module = 'user' and `key` = 'requiredFields' and section in ('create', 'edit');
@@ -12,6 +12,9 @@ class myExecution extends execution
$this->loadModel('project')->setMenu($execution->project);
$this->lang->kanban->menu->execution['subMenu'] = new stdClass();
$this->session->set('kanbanview', $currentMethod);
setcookie('kanbanview', $currentMethod, $this->config->cookieLife, $this->config->webRoot, '', false, true);
/* change subMenu to sub select menu */
$TRActions = $this->execution->getTRActions($currentMethod);
+17 -5
View File
@@ -29,8 +29,18 @@ public function setMenu($executionID, $buildID = 0, $extra = '')
}
$modulePageNav .= "</ul></div></div>";
if(in_array($this->app->rawMethod, array('task', 'calendar', 'gantt', 'tree', 'grouptask'))) $this->lang->TRActions = $this->getTRActions($this->app->rawMethod);
if(in_array($this->app->rawMethod, array('relation', 'maintainrelation'))) $this->lang->TRActions = $this->getTRActions('gantt');
$lowerModule = strtolower($this->app->rawModule);
$lowerMethod = strtolower($this->app->rawMethod);
if($lowerModule == 'execution' and strpos('|kanban|task|calendar|gantt|tree|grouptask|', "|{$lowerMethod}|") !== false)
{
$this->session->set('kanbanview', $lowerMethod);
setcookie('kanbanview', $lowerMethod, $this->config->cookieLife, $this->config->webRoot, '', false, true);
}
if(strpos('|task|calendar|gantt|tree|grouptask|', "|{$lowerMethod}|") !== false) $this->lang->TRActions = $this->getTRActions($lowerMethod);
if(strpos('|relation|maintainrelation|', "|{$lowerMethod}|") !== false) $this->lang->TRActions = $this->getTRActions('gantt');
if($lowerModule == 'task' || ($lowerModule == 'execution' and strpos('|kanban|task|calendar|gantt|tree|grouptask|', "|{$lowerMethod}|") === false)) $this->lang->TRActions = $this->getTRActions($this->session->kanbanview);
$this->lang->modulePageNav = $modulePageNav;
}
@@ -94,12 +104,14 @@ public function getTRActions($currentMethod)
}
$TRActions = '';
$TRActions .= "<div class='dropdown'>";
$TRActions .= html::a('javascript:;', "<i class='icon icon-" . $this->lang->execution->icons[$currentMethod]."'></i> " . $subMenu->{$currentMethod}['name'] . "<span class='caret'></span>", '', "data-toggle='dropdown' class='btn btn-link'");
$TRActions .= "<div class='btn-group dropdown'>";
$TRActions .= html::a(helper::createLink('execution', $subMenu->{$currentMethod}['method'], $subMenu->{$currentMethod}['vars']), "<i class='icon icon-" . $this->lang->execution->icons[$currentMethod]."'> </i>" . $subMenu->{$currentMethod}['name'], '', "class='btn btn-link'");
$TRActions .= "<button type='button' class='btn btn-link dropdown-toggle' data-toggle='dropdown'><span class='caret'></span></button>";
$TRActions .= "<ul class='dropdown-menu pull-right'>";
foreach($subMenu as $subKey => $subName)
{
$TRActions .= '<li>' . html::a(helper::createLink('execution', $subName['method'], $subName['vars']), "<i class='icon icon-" . $this->lang->execution->icons[$subName['method']] . "'></i> " . $subName['name']) . '</li>';
$active = $this->session->kanbanview == $subKey ? "class='active'" : '';
$TRActions .= "<li $active>" . html::a(helper::createLink('execution', $subName['method'], $subName['vars']), "<i class='icon icon-" . $this->lang->execution->icons[$subName['method']] . "'></i> " . $subName['name']) . '</li>';
}
$TRActions .= "</ul></div>";
@@ -1,2 +1,11 @@
<?php
include dirname(dirname(__FILE__)) . '/resource.php';
if($this->config->edition != 'open')
{
$lang->resource->company->todo = 'companyTodo';
$lang->resource->company->calendar = 'effortCalendar';
$lang->resource->company->allTodo = 'allTodo';
$lang->resource->company->effort = 'companyEffort';
$lang->resource->company->alleffort = 'allEffort';
}
@@ -1,2 +1,11 @@
<?php
include dirname(dirname(__FILE__)) . '/resource.php';
if($this->config->edition != 'open')
{
$lang->resource->company->todo = 'companyTodo';
$lang->resource->company->calendar = 'effortCalendar';
$lang->resource->company->allTodo = 'allTodo';
$lang->resource->company->effort = 'companyEffort';
$lang->resource->company->alleffort = 'allEffort';
}
@@ -38,7 +38,7 @@
<?php else:?>
<div class='kanban-cards'>
<?php foreach($kanbanList as $index => $kanban):?>
<div id="kanban-<?php echo $kanban->id;?>" class='kanban-card col' data-url='<?php echo $this->createLink('execution', 'kanban', "kanbanID=$kanban->id");?>'>
<div id="kanban-<?php echo $kanban->id;?>" class='kanban-card col' data-url='<?php echo $this->createLink('execution', $this->cookie->kanbanview ? $this->cookie->kanbanview : 'kanban', "kanbanID=$kanban->id");?>'>
<div class="panel">
<div class="panel-heading">
<span class="label kanban-status-<?php echo $kanban->status;?>"><?php echo zget($lang->execution->statusList, $kanban->status);?></span>
+1 -1
View File
@@ -95,7 +95,7 @@
<tr>
<th><?php echo $lang->task->story;?></th>
<td colspan='3'>
<span id='storyBox' class="<?php if(!empty($stories)) echo 'hidden';?> "><?php printf($lang->task->noticeLinkStory, html::a($this->createLink('execution', 'linkStory', "executionID=$execution->id"), $lang->execution->linkStory, '_blank', 'class="text-primary"'), html::a("javascript:loadStories($execution->id)", $lang->refresh, '', 'class="text-primary"'));?></span>
<span id='storyBox' class="<?php if(!empty($stories)) echo 'hidden';?> "><?php printf($lang->task->noticeLinkStory, html::a($this->createLink('execution', 'linkStory', "executionID=$execution->project"), $lang->execution->linkStory, '_blank', 'class="text-primary"'), html::a("javascript:loadStories($execution->id)", $lang->refresh, '', 'class="text-primary"'));?></span>
<div class='input-group <?php if(empty($stories)) echo "hidden";?>'>
<?php echo html::select('story', array($task->story => empty($stories) ? '': $stories[$task->story]), $task->story, "class='form-control chosen' onchange='setStoryRelated();'");?>
<span class='input-group-btn' id='preview'><a href='#' class='btn iframe'><?php echo $lang->preview;?></a></span>
+1 -1
View File
@@ -646,7 +646,7 @@ class gitlab
$param = new stdclass();
$param->path = urldecode($path);
$param->ref_name = $fromRevision ? $fromRevision : $this->branch;
$param->ref_name = ($toRevision != 'HEAD' and $toRevision) ? $toRevision : $this->branch;
$fromDate = $this->getCommittedDate($fromRevision);
$toDate = $this->getCommittedDate($toRevision);
+5 -3
View File
@@ -2236,15 +2236,17 @@ class bug extends control
* Ajax get project team members.
*
* @param int $projectID
* @param string $$selectedUser
* @access public
* @return void
* @return string
*/
public function ajaxGetProjectTeamMembers($projectID)
public function ajaxGetProjectTeamMembers($projectID, $selectedUser = '')
{
$users = $this->loadModel('user')->getPairs('noclosed');
$teamMembers = empty($projectID) ? array() : $this->loadModel('project')->getTeamMemberPairs($projectID);
foreach($teamMembers as $account => $member) $teamMembers[$account] = $users[$account];
return print(html::select('assignedTo', $teamMembers, '', 'class="form-control"'));
return print(html::select('assignedTo', $teamMembers, $selectedUser, 'class="form-control"'));
}
+2 -6
View File
@@ -29,11 +29,7 @@ $(function()
*/
function loadAll(productID)
{
if(page == 'create')
{
loadExecutionTeamMembers(productID);
setAssignedTo();
}
if(page == 'create') loadExecutionTeamMembers(productID, true);
if(typeof(changeProductConfirmed) != 'undefined' && !changeProductConfirmed)
{
@@ -485,7 +481,7 @@ function loadExecutionBuilds(executionID)
*/
function loadProjectTeamMembers(projectID)
{
link = createLink('bug', 'ajaxGetProjectTeamMembers', 'projectID=' + projectID);
link = createLink('bug', 'ajaxGetProjectTeamMembers', 'projectID=' + projectID + '&selectedUser=' + $('#assignedTo').val());
$.get(link, function(data)
{
if(!data) data = '<select id="assignedTo" name="assignedTo" class="form-control"></select>';
+3 -1
View File
@@ -25,10 +25,11 @@ function loadAllUsers()
* Load team members of the latest execution of a product as assignedTo list.
*
* @param int $productID
* @param bool $changeProduct
* @access public
* @return void
*/
function loadExecutionTeamMembers(productID)
function loadExecutionTeamMembers(productID, changeProduct)
{
var link = createLink('bug', 'ajaxLoadExecutionTeamMembers', 'productID=' + productID + '&selectedUser=' + $('#assignedTo').val());
$.post(link, function(data)
@@ -36,6 +37,7 @@ function loadExecutionTeamMembers(productID)
$('#assignedTo').replaceWith(data);
$('#assignedTo_chosen').remove();
$('#assignedTo').chosen();
if(typeof(changeProduct) != undefined && changeProduct) setAssignedTo();
})
}
+2
View File
@@ -124,7 +124,9 @@ if($this->app->tab == 'project') js::set('objectID', $projectID);
<div class='input-group' id='buildBox'>
<span class="input-group-addon"><?php echo $lang->bug->openedBuild?></span>
<?php echo html::select('openedBuild[]', $builds, empty($buildID) ? '' : $buildID, "multiple=multiple class='chosen form-control'");?>
<?php if(count($builds) < 2):?>
<span class='input-group-addon fix-border' id='buildBoxActions'></span>
<?php endif;?>
<div class='input-group-btn'><?php echo html::commonButton($lang->bug->allBuilds, "class='btn' id='all' data-toggle='tooltip' onclick='loadAllBuilds()'")?></div>
</div>
</td>
+2
View File
@@ -2205,6 +2205,8 @@ EOD;
if(isset($this->app->user))
{
if(in_array($module, $this->config->programPriv->waterfall) and $this->app->tab == 'project') return true;
$this->app->user = $this->session->user;
if(!commonModel::hasPriv($module, $method)) $this->deny($module, $method);
}
+1 -1
View File
@@ -163,7 +163,7 @@ class custom extends control
foreach($_POST['keys'] as $index => $key)
{
if(!empty($key)) $key = trim($key);
/* Invalid key. It should be numbers. (It includes severityList in bug module and priList in stroy, task, bug, testcasea, testtask and todo module.) */
/* Invalid key. It should be numbers. (It includes severityList in bug module and priList in story, task, bug, testcasea, testtask and todo module.) */
if($field == 'priList' or $field == 'severityList')
{
if(!is_numeric($key) or $key > 255) return $this->send(array('result' => 'fail', 'message' => $this->lang->custom->notice->invalidNumberKey));
+12
View File
@@ -244,6 +244,18 @@ class customModel extends model
$link = explode('|', $link);
list($label, $module, $method) = $link;
$hasPriv = commonModel::hasPriv($module, $method);
/* Fix bug #20464 */
if(!$hasPriv and is_array($item) and isset($item['subMenu']))
{
foreach($item['subMenu'] as $subMenu)
{
if(!isset($subMenu['link'])) continue;
list($subLabel, $module, $method) = explode('|', $subMenu['link']);
$hasPriv = commonModel::hasPriv($module, $method);
if($hasPriv) break;
}
}
if($module == 'execution' and $method == 'more') $hasPriv = true;
if($module == 'project' and $method == 'other') $hasPriv = true;
}
+19 -10
View File
@@ -84,18 +84,27 @@ class design extends control
$this->lang->TRActions .= html::a($this->createLink('design', 'submit', "productID=$productID", '', true), "<i class='icon-plus'></i> {$this->lang->design->submit}", '', "class='btn btn-secondary iframe'");
$this->lang->TRActions .= '</div>';
}
$this->lang->TRActions .= '<div class="btn-group dropdown">';
$this->lang->TRActions .= html::a(inlink('create', "projectID=$projectID&productID=$productID&type=$type"), "<i class='icon-plus'></i> {$this->lang->design->create}", '', "class='btn btn-primary'");
$this->lang->TRActions .= "<button type='button' class='btn btn-primary dropdown-toggle' data-toggle='dropdown'><span class='caret'></span>";
$this->lang->TRActions .= '</button>';
$this->lang->TRActions .= "<ul class='dropdown-menu pull-right' id='createActionMenu'>";
if(common::hasPriv('design', 'create')) $this->lang->TRActions .= '<li>' . html::a($this->createLink('design', 'create', "projectID=$projectID&productID=$productID&type=$type"), $this->lang->design->create, '', "class='btn btn-link'") . '</li>';
if(common::hasPriv('design', 'batchCreate')) $this->lang->TRActions .= '<li>' . html::a($this->createLink('design', 'batchCreate', "projectID=$projectID&productID=$productID&type=$type"), $this->lang->design->batchCreate, '', "class='btn btn-link'") . '</li>';
if(common::hasPriv('design', 'create') and common::hasPriv('design', 'batchCreate'))
{
$this->lang->TRActions .= '<div class="btn-group dropdown">';
$this->lang->TRActions .= html::a(inlink('create', "projectID=$projectID&productID=$productID&type=$type"), "<i class='icon-plus'></i> {$this->lang->design->create}", '', "class='btn btn-primary'");
$this->lang->TRActions .= "<button type='button' class='btn btn-primary dropdown-toggle' data-toggle='dropdown'><span class='caret'></span>";
$this->lang->TRActions .= '</button>';
$this->lang->TRActions .= "<ul class='dropdown-menu pull-right' id='createActionMenu'>";
$this->lang->TRActions .= '</ul>';
$this->lang->TRActions .= '</div>';
$this->lang->TRActions .= '</div>';
if(common::hasPriv('design', 'create')) $this->lang->TRActions .= '<li>' . html::a($this->createLink('design', 'create', "projectID=$projectID&productID=$productID&type=$type"), $this->lang->design->create, '', "class='btn btn-link'") . '</li>';
if(common::hasPriv('design', 'batchCreate')) $this->lang->TRActions .= '<li>' . html::a($this->createLink('design', 'batchCreate', "projectID=$projectID&productID=$productID&type=$type"), $this->lang->design->batchCreate, '', "class='btn btn-link'") . '</li>';
$this->lang->TRActions .= '</ul>';
$this->lang->TRActions .= '</div>';
$this->lang->TRActions .= '</div>';
}
else
{
if(common::hasPriv('design', 'create')) $this->lang->TRActions .= html::a(inlink('create', "projectID=$projectID&productID=$productID&type=$type"), "<i class='icon-plus'></i> {$this->lang->design->create}", '', "class='btn btn-primary'");
if(common::hasPriv('design', 'batchCreate')) $this->lang->TRActions .= html::a(inlink('batchCreate', "projectID=$projectID&productID=$productID&type=$type"), "<i class='icon-plus'></i> {$this->lang->design->batchCreate}", '', "class='btn btn-primary'");
}
/* Init pager and get designs. */
$this->app->loadClass('pager', $static = true);
+1 -1
View File
@@ -44,7 +44,7 @@
<tr>
<td calss="c-id"> <?php printf('%03d', $design->id);?></td>
<td class="c-type"> <?php echo zget($lang->design->typeList, $design->type);?></td>
<td class="c-name" title="<?php echo $design->name;?>"><?php echo html::a($this->createLink('design', 'view', "id={$design->id}"), $design->name);?></td>
<td class="c-name" title="<?php echo $design->name;?>"><?php echo common::hasPriv('design', 'view') ? html::a($this->createLink('design', 'view', "id={$design->id}"), $design->name) : $design->name;?></td>
<td class="c-createdBy"> <?php echo zget($users, $design->createdBy);?></td>
<td class="c-createdDate"><?php echo substr($design->createdDate, 0, 11);?></td>
<td class="c-assignedTo"> <?php echo $this->design->printAssignedHtml($design, $users);?></td>
+1
View File
@@ -1 +1,2 @@
.thWidth {width: 130px !important;}
td.flex span.project-type-label {min-width: 60px;}
+1
View File
@@ -792,6 +792,7 @@ function handleDropTask($element, event, kanban)
var newLane = $newCol.closest('.kanban-lane').data('lane');
var cardType = $card.find('.kanban-card').data('type');
if(!oldCol || !newCol || !newLane || !oldLane) return false;
if(oldCol.id === newCol.id && newLane.id === oldLane.id) return false;
var cardID = $card.data().id;
+7 -4
View File
@@ -73,7 +73,7 @@ function renderDeadline(deadline)
function renderStoryItem(item, $item, col)
{
var scaleSize = window.kanbanScaleSize;
if(+$item.attr('data-scale-size') !== scaleSize) $item.empty().attr('data-scale-size', scaleSize);
if($item.attr('data-scale-size') !== scaleSize) $item.empty().attr('data-scale-size', scaleSize);
if(scaleSize <= 3)
{
@@ -135,7 +135,7 @@ function renderStoryItem(item, $item, col)
function renderBugItem(item, $item, col)
{
var scaleSize = window.kanbanScaleSize;
if(+$item.attr('data-scale-size') !== scaleSize) $item.empty().attr('data-scale-size', scaleSize);
if($item.attr('data-scale-size') !== scaleSize) $item.empty().attr('data-scale-size', scaleSize);
if(scaleSize <= 3)
{
@@ -199,7 +199,7 @@ function renderBugItem(item, $item, col)
function renderTaskItem(item, $item, col)
{
var scaleSize = window.kanbanScaleSize;
if(+$item.attr('data-scale-size') !== scaleSize) $item.empty().attr('data-scale-size', scaleSize);
if($item.attr('data-scale-size') !== scaleSize) $item.empty().attr('data-scale-size', scaleSize);
if(scaleSize <= 3)
{
@@ -298,6 +298,8 @@ function renderColumnCount($count, count, col)
function renderHeaderCol($col, col, $header, kanban)
{
if(col.asParent) $col = $col.children('.kanban-header-col');
if($col.children('.actions').context != undefined) return;
var $actions = $('<div class="actions" />');
var printStoryButton = printTaskButton = printBugButton = false;
if(priv.canCreateStory || priv.canBatchCreateStory || priv.canLinkStory || priv.canLinkStoryByPlan) printStoryButton = true;
@@ -717,6 +719,7 @@ function handleDropTask($element, event, kanban)
var newLane = $newCol.closest('.kanban-lane').data('lane');
var cardType = $card.find('.kanban-card').data('type');
if(!oldCol || !newCol || !newLane || !oldLane) return false;
if(oldCol.id === newCol.id && newLane.id === oldLane.id) return false;
var cardID = $card.data().id;
@@ -796,7 +799,7 @@ function createColumnCreateMenu(options)
if(col.laneType == 'story')
{
if(priv.canCreateStory) items.push({label: storyLang.create, url: $.createLink('story', 'create', 'productID=' + productID, '', true), className: 'iframe'});
if(priv.canBatchCreateStory) items.push({label: executionLang.batchCreateStroy, url: $.createLink('story', 'batchcreate', 'productID=' + productID + '&branch=0&moduleID=0&storyID=0&executionID=' + executionID, '', true), className: 'iframe', attrs: {'data-width': '90%'}});
if(priv.canBatchCreateStory) items.push({label: executionLang.batchCreateStory, url: $.createLink('story', 'batchcreate', 'productID=' + productID + '&branch=0&moduleID=0&storyID=0&executionID=' + executionID, '', true), className: 'iframe', attrs: {'data-width': '90%'}});
if(priv.canLinkStory) items.push({label: executionLang.linkStory, url: $.createLink('execution', 'linkStory', 'executionID=' + executionID, '', true), className: 'iframe', attrs: {'data-width': '90%'}});
if(priv.canLinkStoryByPlan) items.push({label: executionLang.linkStoryByPlan, url: '#linkStoryByPlan', 'attrs' : {'data-toggle': 'modal'}});
}
+7 -5
View File
@@ -206,11 +206,13 @@ class install extends control
if($this->post->importDemoData) $this->install->importDemoData();
if(dao::isError()) echo js::alert($this->lang->install->errorImportDemoData);
$this->loadModel('setting')->updateVersion($this->config->version);
$this->loadModel('setting')->setItem('system.common.global.flow', $this->post->flow);
$this->loadModel('setting')->setItem('system.common.safe.mode', '1');
$this->loadModel('setting')->setItem('system.common.safe.changeWeak', '1');
$this->loadModel('setting')->setItem('system.common.global.cron', 1);
$this->loadModel('setting');
$this->setting->updateVersion($this->config->version);
$this->setting->setSN();
$this->setting->setItem('system.common.global.flow', $this->post->flow);
$this->setting->setItem('system.common.safe.mode', '1');
$this->setting->setItem('system.common.safe.changeWeak', '1');
$this->setting->setItem('system.common.global.cron', 1);
if(strpos($this->app->getClientLang(), 'zh') === 0) $this->loadModel('api')->createDemoData($this->lang->api->zentaoAPI, 'http://' . $_SERVER['HTTP_HOST'] . $this->app->config->webRoot . 'api.php/v1', '16.0');
return print(js::locate(inlink('step6'), 'parent'));
+2 -1
View File
@@ -976,6 +976,7 @@ function handleDropTask($element, event, kanban)
var regionID = $card.closest('.region').data('id');
var kanbanID = $card.closest('#kanban').data('id');
if(!oldCol || !newCol || !newLane || !oldLane) return false;
if(oldCol.id === newCol.id && newLane.id === oldLane.id) return false;
var cardID = $card.data().id;
@@ -1183,7 +1184,7 @@ function createColumnCreateMenu(options)
var laneID = col.$kanbanData.lanes[0].id ? col.$kanbanData.lanes[0].id : 0;
var columnID = col.id;
if(privs.includes('createCard')) items.push({label: kanbanLang.createCard, url: $.createLink('kanban', 'createCard', 'kanbanID=' + kanbanID + '&regionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID), className: 'iframe', attrs: {'data-toggle': 'modal'}});
if(privs.includes('createCard')) items.push({label: kanbanLang.createCard, url: $.createLink('kanban', 'createCard', 'kanbanID=' + kanbanID + '&regionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID, '', true), className: 'iframe', attrs: {'data-toggle': 'modal'}});
if(privs.includes('batchCreateCard')) items.push({label: kanbanLang.batchCreateCard, url: $.createLink('kanban', 'batchCreateCard', 'kanbanID=' + kanbanID + '&regionID=' + regionID + '&groupID=' + groupID + '&laneID=' + laneID + '&columnID=' + columnID), attrs: {'data-width': '80%'}});
if(privs.includes('import') && kanban.object.indexOf('cards') != -1) items.push({label: kanbanLang.importCard, url: $.createLink('kanban', 'importCard', 'kanbanID=' + kanbanID + '&regionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID), className: 'iframe', attrs: {'data-toggle': 'modal'}});
if(privs.includes('import') && kanban.object && kanban.object != 'cards') items.push({className: 'parentDivider'});
+2 -2
View File
@@ -1419,7 +1419,7 @@ class kanbanModel extends model
$lanes = $this->getLanes4Group($executionID, $browseType, $groupBy, $cardList);
if(empty($lanes)) return array();
$columns = $this->dao->select('t1.*, t2.`type` as columnType, t2.limit, t2.name as columnName')->from(TABLE_KANBANCELL)->alias('t1')
$columns = $this->dao->select('t1.*, t2.`type` as columnType, t2.limit, t2.name as columnName, t2.color')->from(TABLE_KANBANCELL)->alias('t1')
->leftJoin(TABLE_KANBANCOLUMN)->alias('t2')->on('t1.`column` = t2.id')
->where('t1.kanban')->eq($executionID)
->andWhere('t1.`type`')->eq($browseType)
@@ -1460,7 +1460,7 @@ class kanbanModel extends model
$columnData[$column->column]['id'] = $column->column;
$columnData[$column->column]['type'] = $column->columnType;
$columnData[$column->column]['name'] = $column->columnName;
$columnData[$column->column]['color'] = '#333';
$columnData[$column->column]['color'] = $column->color;
$columnData[$column->column]['limit'] = $column->limit;
$columnData[$column->column]['laneType'] = $browseType;
$columnData[$column->column]['asParent'] = in_array($column->columnType, array('develop', 'test', 'resolving')) ? true : false;
+1 -1
View File
@@ -499,7 +499,7 @@ EOF;
$this->view->position[] = $this->lang->my->bug;
$this->view->bugs = $bugs;
$this->view->users = $this->user->getPairs('noletter');
$this->view->memberPairs = $this->user->getPairs('noletter|nodeleted');
$this->view->memberPairs = $this->user->getPairs('noletter|nodeleted|noclosed');
$this->view->tabID = 'bug';
$this->view->type = $type;
$this->view->recTotal = $recTotal;
+2 -1
View File
@@ -17,8 +17,9 @@ if($contactLists)
}
else
{
$width = isonlybody() ? 'data-width=100%' : '';
echo '<span class="input-group-btn">';
echo '<a title="' . $lang->user->contacts->manage . '" href="' . $this->createLink('my', 'managecontacts', "listID=0&mode=new", '', true) . "\" target='_blank' data-icon='cog' data-title='{$lang->user->contacts->manage}' class='btn btn-icon iframe'><i class='icon icon-cog'></i></a>";
echo '<a title="' . $lang->user->contacts->manage . '" href="' . $this->createLink('my', 'managecontacts', "listID=0&mode=new", '', true) . "\" target='_blank' data-icon='cog' data-title='{$lang->user->contacts->manage}' class='btn btn-icon iframe' $width><i class='icon icon-cog'></i></a>";
echo '</span>';
echo '<span class="input-group-btn">';
echo '<button type="button" title="' . $lang->refresh . '" class="btn btn-icon"' . "onclick=\"ajaxGetContacts(this, '$dropdownName')\"" . '><i class="icon icon-refresh"></i></button>';
+1 -1
View File
@@ -20,7 +20,7 @@
<?php echo html::avatar($user, 50); ?>
<form method='post' class='form-ajax' action=<?php echo inlink('uploadAvatar');?> id='avatarForm' enctype='multipart/form-data'>
<input type="file" name="files" id="files" class="form-control hidden">
<?php echo html::a('javascript:void(0);', '<i class="icon icon-pencil icon-2x"></i>', '', "class='btn-avatar' id='avatarUploadBtn' data-toggle='tooltip' data-container='body' data-placement='bottom' title='{$lang->my->uploadAvatar}'");?>
<?php if(common::hasPriv('my', 'uploadAvatar')) echo html::a('javascript:void(0);', '<i class="icon icon-pencil icon-2x"></i>', '', "class='btn-avatar' id='avatarUploadBtn' data-toggle='tooltip' data-container='body' data-placement='bottom' title='{$lang->my->uploadAvatar}'");?>
</form>
</div>
<span class='user-name'><?php echo $user->realname;?></span>
+1 -1
View File
@@ -110,7 +110,7 @@ class projectStory extends control
* Batch unlink story.
*
* @param int $projectID
* @param string $stroyIdList
* @param string $storyIdList
* @access public
* @return string
*/
-2
View File
@@ -31,8 +31,6 @@ class score extends control
*/
public function rule()
{
$this->loadModel('my')->setMenu();
$this->view->title = $this->lang->my->scoreRule;
$this->view->position[] = $this->lang->my->scoreRule;
$this->display();
+10 -6
View File
@@ -1101,8 +1101,6 @@ class story extends control
/* Set the menu. */
$from = $this->app->tab;
$this->product->setMenu($story->product, $story->branch);
if($from == 'execution')
{
$this->execution->setMenu($param);
@@ -1116,6 +1114,10 @@ class story extends control
$products = $this->product->getProductPairsByProject(0, 'noclosed');
$this->loadModel('qa')->setMenu($products, $story->product);
}
else
{
$this->product->setMenu($story->product, $story->branch);
}
$reviewers = $this->story->getReviewerPairs($storyID, $story->version);
$checkSuperReviewed = strpos(',' . trim(zget($this->config->story, 'superReviewers', ''), ',') . ',', ',' . trim($story->reviewedBy, ',') . ',');
@@ -1468,7 +1470,6 @@ class story extends control
{
$this->lang->story->menu = $this->lang->my->menu;
$this->lang->story->menuOrder = $this->lang->my->menuOrder;
$this->loadModel('my')->setMenu();
if($from == 'work') $this->lang->my->menu->work['subModule'] = 'story';
if($from == 'contribute') $this->lang->my->menu->contribute['subModule'] = 'story';
@@ -1988,20 +1989,23 @@ class story extends control
*
* @param int $executionID
* @param int $productID
* @param int $branch
* @param int $moduleID
* @param int $storyID
* @param string $number
* @param string $type
* @param string $type full
* @param string $status all|unclosed
* @access public
* @return void
*/
public function ajaxGetExecutionStories($executionID, $productID = 0, $branch = 0, $moduleID = 0, $storyID = 0, $number = '', $type= 'full')
public function ajaxGetExecutionStories($executionID, $productID = 0, $branch = 0, $moduleID = 0, $storyID = 0, $number = '', $type = 'full', $status = 'all')
{
if($moduleID)
{
$moduleID = $this->loadModel('tree')->getStoryModule($moduleID);
$moduleID = $this->tree->getAllChildID($moduleID);
}
$stories = $this->story->getExecutionStoryPairs($executionID, $productID, $branch, $moduleID, $type);
$stories = $this->story->getExecutionStoryPairs($executionID, $productID, $branch, $moduleID, $type, $status);
if($this->app->getViewType() === 'json')
{
return print(json_encode($stories));
+3 -3
View File
@@ -647,9 +647,9 @@ class storyModel extends model
$story = fixer::input('post')->stripTags($this->config->story->editor->change['id'], $this->config->allowedTags)->get();
$oldStroyReviewers = $this->getReviewerPairs($storyID, $oldStory->version);
$oldStoryReviewers = $this->getReviewerPairs($storyID, $oldStory->version);
$_POST['reviewer'] = isset($_POST['reviewer']) ? $_POST['reviewer'] : array();
$reviewerHasChanged = (array_diff(array_keys($oldStroyReviewers), $_POST['reviewer']) or array_diff($_POST['reviewer'], array_keys($oldStroyReviewers)));
$reviewerHasChanged = (array_diff(array_keys($oldStoryReviewers), $_POST['reviewer']) or array_diff($_POST['reviewer'], array_keys($oldStoryReviewers)));
if($story->spec != $oldStory->spec or $story->verify != $oldStory->verify or $story->title != $oldStory->title or $this->loadModel('file')->getCount() or $reviewerHasChanged) $specChanged = true;
$now = helper::now();
@@ -3925,7 +3925,7 @@ class storyModel extends model
}
if($storyType == 'requirement') echo '<span class="label label-badge label-light">SR</span> ';
if($story->parent > 0 and isset($story->parentName)) $story->title = "{$story->parentName} / {$story->title}";
if(isset($branches[$story->branch]) and $showBranch) echo "<span class='label label-outline label-badge'>{$branches[$story->branch]}</span> ";
if(isset($branches[$story->branch]) and $showBranch and $this->config->vision == 'rnd') echo "<span class='label label-outline label-badge'>{$branches[$story->branch]}</span> ";
if($story->module and isset($modulePairs[$story->module])) echo "<span class='label label-gray label-badge'>{$modulePairs[$story->module]}</span> ";
if($story->parent > 0) echo '<span class="label label-badge label-light" title="' . $this->lang->story->children . '">' . $this->lang->story->childrenAB . '</span> ';
echo $canView ? html::a($storyLink, $story->title, '', "style='color: $story->color' data-app='$tab'") : "<span style='color: $story->color'>{$story->title}</span>";
+1 -1
View File
@@ -148,7 +148,7 @@ foreach(explode(',', $showFields) as $field)
<tr>
<td colspan='<?php echo count($visibleFields) + ($branchProduct ? 3 : 2);?>' class='text-center form-actions'>
<?php echo html::submitButton();?>
<?php echo $this->app->tab == 'product' ? html::a($this->session->storyList, $lang->goback, '', "class='btn btn-back btn-wide'") : html::backButton();?>
<?php echo ($this->app->tab == 'product' or $this->app->tab == 'execution') ? html::a($this->session->storyList, $lang->goback, '', "class='btn btn-back btn-wide'") : html::backButton();?>
</td>
</tr>
</tfoot>
+1 -1
View File
@@ -273,7 +273,7 @@ function loadModuleRelated()
/* Get select of stories.*/
function setStories(moduleID, executionID)
{
link = createLink('story', 'ajaxGetExecutionStories', 'executionID=' + executionID + '&productID=0&branch=all&moduleID=' + moduleID);
link = createLink('story', 'ajaxGetExecutionStories', 'executionID=' + executionID + '&productID=0&branch=all&moduleID=' + moduleID + '&storyID=0&number=&type=full&status=unclosed');
$.get(link, function(stories)
{
var storyID = $('#story').val();
+1 -1
View File
@@ -2171,7 +2171,7 @@ class taskModel extends model
$task->parentName = $parent->name;
}
}
}
}
return $this->processTasks($tasks);
}
-1
View File
@@ -23,7 +23,6 @@ class todo extends control
$this->app->loadClass('date');
$this->loadModel('task');
$this->loadModel('bug');
$this->loadModel('my')->setMenu();
}
/**
+1 -1
View File
@@ -221,7 +221,7 @@ $(function()
},
itemCreator: function($li, item)
{
var link = (item.id !== undefined && item.type != 'line') ? ('<a href="' + createLink('tree', 'browse', 'rootID=<?php echo $rootID ?>&viewType=<?php echo $viewType ?>&moduleID={0}&branch={1}&from=<?php echo $from;?>&projectID=<?php echo $projectID; ?>'.format(item.id, branch)) + '" data-app="' + tab + '">' + item.name + '</a>') : ('<span class="tree-toggle">' + item.name + '</span>');
var link = (item.id !== undefined && item.type != 'line') ? ('<a href="' + createLink('tree', 'browse', 'rootID=<?php echo $rootID ?>&viewType=<?php echo $viewType ?>&moduleID={0}&branch={1}&from=<?php echo $from;?>&projectID=<?php echo isset($projectID) ? $projectID : 0; ?>'.format(item.id, branch)) + '" data-app="' + tab + '">' + item.name + '</a>') : ('<span class="tree-toggle">' + item.name + '</span>');
var $toggle = $('<span class="module-name" data-id="' + item.id + '">' + link + '</span>');
if(item.type === 'bug') $toggle.append('&nbsp; <span class="text-muted">[B]</span>');
if(item.type === 'case') $toggle.append('&nbsp; <span class="text-muted">[C]</span>');
+1 -1
View File
@@ -721,7 +721,7 @@ class upgrade extends control
$this->view->title = $this->lang->upgrade->result;
$this->view->position[] = $this->lang->upgrade->common;
$needProcess = $this->upgrade->checkProcess($fromVersion);
$needProcess = $this->upgrade->checkProcess();
$this->view->needProcess = $needProcess;
$this->view->fromVersion = $fromVersion;
$this->display();
+1 -1
View File
@@ -27,7 +27,7 @@ $lang->upgrade->warnningContent = <<<EOT
2. Use mysqlCommand to backup.
$> mysqldump -u <span class='text-danger'>username</span> -p <span class='text-danger'>dbname</span> > <span class='text-danger'>filename</span>
Change the red text into corresponding Username and Database name.
e.g. mysqldump -u root -p zentao >zentao.bak
e.g. mysqldump -u root -p zentao > zentao.bak
</pre>
EOT;
+1 -1
View File
@@ -27,7 +27,7 @@ $lang->upgrade->warnningContent = <<<EOT
2. 使用mysql命令行的工具。
$> mysqldump -u <span class='text-danger'>username</span> -p <span class='text-danger'>dbname</span> > <span class='text-danger'>filename</span>
要将上面红色的部分分别替换成对应的用户名和禅道系统的数据库名。
比如: mysqldump -u root -p zentao >zentao.bak
比如: mysqldump -u root -p zentao > zentao.bak
</pre>
EOT;
+92 -68
View File
@@ -27,6 +27,49 @@ class upgradeModel extends model
$this->loadModel('setting');
}
/**
* Get versions to update
*
* @param mixed $openVersion
* @access public
* @return array
*/
public function getVersionsToUpdate($openVersion, $fromEdition)
{
$versions = array();
/* Always update open. */
foreach($this->lang->upgrade->fromVersions as $version => $versionName)
{
if(!is_numeric($version[0])) continue;
if(version_compare(str_replace('_', '.', $version), str_replace('_', '.', $openVersion)) < 0) continue;
$versions[$version] = array('pro' => array(), 'biz' => array(), 'max' => array());
}
if($fromEdition == 'open') return $versions;
/* Update to pro|biz|max. */
foreach($this->config->upgrade->proVersion as $pro => $open)
{
if(isset($versions[$open])) $versions[$open]['pro'][] = $pro;
}
if($fromEdition == 'pro') return $versions;
/* Update to biz|max. */
foreach($this->config->upgrade->bizVersion as $biz => $open)
{
if(isset($versions[$open])) $versions[$open]['biz'][] = $biz;
}
if($fromEdition == 'biz') return $versions;
/* Update to max. */
foreach($this->config->upgrade->maxVersion as $max => $open)
{
if(isset($versions[$open])) $versions[$open]['max'][] = $max;
}
return $versions;
}
/**
* The execute method. According to the $fromVersion call related methods.
*
@@ -38,81 +81,60 @@ class upgradeModel extends model
{
set_time_limit(0);
$editions = array('p' => 'proVersion', 'b' => 'bizVersion', 'm' => 'maxVersion');
$editions = array('p' => 'pro', 'b' => 'biz', 'm' => 'max');
$fromEdition = is_numeric($fromVersion[0]) ? 'open' : $editions[$fromVersion[0]];
$openVersion = is_numeric($fromVersion[0]) ? $fromVersion : $this->config->upgrade->{$fromEdition}[$fromVersion];
/* Get versions to be updated. */
$versions = array();
$edition = $this->config->edition;
foreach($this->lang->upgrade->fromVersions as $version => $versionName)
{
if(!is_numeric($version[0])) continue;
if(version_compare(str_replace('_', '.', $version), str_replace('_', '.', $openVersion)) < 0) continue;
$versions[$version] = array('pro' => array(), 'biz' => array(), 'max' => array());
}
foreach($this->config->upgrade->proVersion as $pro => $open)
{
if(!isset($versions[$open])) continue;
if(version_compare(str_replace('_', '.', $openVersion), '16.4', '>=') or $fromEdition == 'pro') $versions[$open]['pro'][] = $pro;
}
foreach($this->config->upgrade->bizVersion as $biz => $open)
{
if(!isset($versions[$open])) continue;
if(version_compare(str_replace('_', '.', $openVersion), '16.4', '>=') or $fromEdition == 'biz') $versions[$open]['biz'][] = $biz;
}
foreach($this->config->upgrade->maxVersion as $max => $open)
{
if(!isset($versions[$open])) continue;
if(version_compare(str_replace('_', '.', $openVersion), '16.4', '>=') or $fromEdition == 'max') $versions[$open]['max'][] = $max;
}
/* If the 'current openVersion' is not equal the 'from openVersion', must update structure. */
$currentVersion = str_replace('.', '_', $this->config->version);
$updateStructure = $openVersion != ($this->config->edition == 'open' ? $currentVersion : $this->config->upgrade->{$this->config->edition . 'Version'}[$currentVersion]);
/* Execute. */
$fromOpenVersion = is_numeric($fromVersion[0]) ? $fromVersion : $this->config->upgrade->{$fromEdition . 'Version'}[$fromVersion];
$versions = $this->getVersionsToUpdate($fromOpenVersion, $fromEdition);
foreach($versions as $openVersion => $chargedVersions)
{
$executeXuanxuan = false;
switch($fromEdition)
{
case 'open':
if(str_replace('_', '.', $openVersion) == '10.1') $executeXuanxuan = true;
$this->saveLogs("Execute $openVersion");
$this->execSQL($this->getUpgradeFile(str_replace('_', '.', $openVersion)));
$this->executeOpen($openVersion, $fromVersion, $executeXuanxuan);
case 'pro':
foreach($chargedVersions['pro'] as $proVersion)
{
$this->saveLogs("Execute $proVersion");
if($updateStructure) $this->execSQL($this->getUpgradeFile(str_replace('_', '.', $proVersion)));
if($this->config->edition != 'open') $this->executePro($proVersion);
}
case 'biz':
foreach($chargedVersions['biz'] as $bizVersion)
{
$this->saveLogs("Execute $bizVersion");
if($updateStructure) $this->execSQL($this->getUpgradeFile(str_replace('_', '.', $bizVersion)));
if($this->config->edition != 'open') $this->executeBiz($bizVersion, $executeXuanxuan);
}
case 'max':
foreach($chargedVersions['max'] as $maxVersion)
{
$maxVersion = array_search($openVersion, $this->config->upgrade->maxVersion);
$this->saveLogs("Execute $maxVersion");
if($updateStructure) $this->execSQL($this->getUpgradeFile(str_replace('_', '.', $maxVersion)));
}
/* Execute open. */
if(str_replace('_', '.', $openVersion) == '10.1') $executeXuanxuan = true;
$this->saveLogs("Execute $openVersion");
$this->execSQL($this->getUpgradeFile(str_replace('_', '.', $openVersion)));
$this->executeOpen($openVersion, $fromVersion, $executeXuanxuan);
/* Execute pro. */
foreach($chargedVersions['pro'] as $proVersion)
{
$this->saveLogs("Execute $proVersion");
$this->execSQL($this->getUpgradeFile(str_replace('_', '.', $proVersion)));
$this->executePro($proVersion);
}
/* Execute biz. */
foreach($chargedVersions['biz'] as $bizVersion)
{
$this->saveLogs("Execute $bizVersion");
$this->execSQL($this->getUpgradeFile(str_replace('_', '.', $bizVersion)));
$this->executeBiz($bizVersion, $executeXuanxuan);
}
/* Execute max. */
foreach($chargedVersions['max'] as $maxVersion)
{
$maxVersion = array_search($openVersion, $this->config->upgrade->maxVersion);
$this->saveLogs("Execute $maxVersion");
$this->execSQL($this->getUpgradeFile(str_replace('_', '.', $maxVersion)));
}
}
/* Means open source upgrade to biz or max. */
if($fromEdition == 'open' and $this->config->edition != 'open')
/* Means open source/pro upgrade to biz or max. */
if($this->config->edition != 'open')
{
$this->loadModel('effort')->convertEstToEffort();
$this->importBuildinModules();
$this->addSubStatus();
if($fromEdition == 'open') $this->loadModel('effort')->convertEstToEffort();
if($fromEdition == 'open' or $fromEdition == 'pro')
{
$this->importBuildinModules();
$this->addSubStatus();
}
}
}
@@ -334,7 +356,6 @@ class upgradeModel extends model
break;
case '11_7':
$this->adjustPriv12_0();
$this->loadModel('setting')->setItem('system.common.global.showAnnual', '1');
break;
case '12_0_1':
$this->importRepoFromConfig();
@@ -1108,18 +1129,21 @@ class upgradeModel extends model
public function checkConsistency($version = '')
{
if(empty($version)) $version = $this->config->installedVersion;
$editions = array('p' => 'proVersion', 'b' => 'bizVersion', 'm' => 'maxVersion');
$version = str_replace('.', '_', $version);
$fromEdition = is_numeric($version[0]) ? 'open' : $editions[$version[0]];
$openVersion = is_numeric($version[0]) ? $version : $this->config->upgrade->{$fromEdition}[$version];
$openVersion = str_replace('_', '.', $openVersion);
$alterSQL = '';
$standardSQL = $this->app->getAppRoot() . 'db' . DS . 'standard' . DS . 'zentao' . $version . '.sql';
$standardSQL = $this->app->getAppRoot() . 'db' . DS . 'standard' . DS . 'zentao' . $openVersion . '.sql';
if(!file_exists($standardSQL)) return $alterSQL;
$lines = file($standardSQL);
if(empty($this->config->isINT))
{
$xVersion = $version;
$version = str_replace('.', '_', $version);
if(strpos($version, 'pro') !== false and isset($this->config->upgrade->proVersion[$version])) $xVersion = str_replace('_', '.', $this->config->upgrade->proVersion[$version]);
if(strpos($version, 'biz') !== false and isset($this->config->upgrade->bizVersion[$version])) $xVersion = str_replace('_', '.', $this->config->upgrade->bizVersion[$version]);
$xVersion = $openVersion;
$xStandardSQL = $this->app->getAppRoot() . 'db' . DS . 'standard' . DS . 'xuanxuan' . $xVersion . '.sql';
if(file_exists($xStandardSQL))
{
+5
View File
@@ -46,6 +46,11 @@
</div>
</div>
<script>
$(function()
{
$.get('<?php echo inlink('afterExec', "fromVersion=$fromVersion&processed=yes")?>');
})
<?php
foreach($needProcess as $processKey => $value) echo 'var ' . $processKey . "Finish = false;\n";
if(isset($needProcess['updateFile'])):?>
+4 -1
View File
@@ -49,7 +49,10 @@ function toggleCheck(obj, i)
}
}
$(document).ready(removeDitto());//Remove 'ditto' in first row.
$(function()
{
removeDitto(); //Remove 'ditto' in first row.
})
$(document).on('click', '.chosen-with-drop', function()
{
+1 -1
View File
@@ -398,7 +398,7 @@ class userModel extends model
if(in_array($users->account[$i], $accounts)) helper::end(js::error(sprintf($this->lang->user->error->accountDupl, $i + 1)));
if(!validater::checkAccount($users->account[$i])) helper::end(js::error(sprintf($this->lang->user->error->account, $i + 1)));
if($users->realname[$i] == '') helper::end(js::error(sprintf($this->lang->user->error->realname, $i + 1)));
if($users->visions[$i] == '') helper::end(js::error(sprintf($this->lang->user->error->visions, $i + 1)));
if(empty($users->visions[$i])) helper::end(js::error(sprintf($this->lang->user->error->visions, $i + 1)));
if($users->email[$i] and !validater::checkEmail($users->email[$i])) helper::end(js::error(sprintf($this->lang->user->error->mail, $i + 1)));
$users->password[$i] = (isset($prev['password']) and $users->ditto[$i] == 'on' and !$this->post->password[$i]) ? $prev['password'] : $this->post->password[$i];
if(!validater::checkReg($users->password[$i], '|(.){6,}|')) helper::end(js::error(sprintf($this->lang->user->error->password, $i + 1)));
+1 -1
View File
@@ -63,7 +63,7 @@
<tr>
<th><?php echo $lang->user->visions;?></th>
<?php $visionList = $this->user->getVisionList();?>
<td><?php echo html::checkbox('visions', $visionList, key($visionList), "class='form-control'");?></td>
<td><?php echo html::checkbox('visions', $visionList, isset($visionList[$this->config->vision]) ? $this->config->vision : key($visionList), "class='form-control'");?></td>
</tr>
<tr>
<th><?php echo $lang->user->realname;?></th>
+112
View File
@@ -721,4 +721,116 @@ class executionTest
}
}
public function unlinkStoryTest($executionID, $count, $storyID, $param = array())
{
global $tester;
$stories = array();
$products = array();
$createFields = array('stories' => $stories, 'products' => $products);
foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
foreach($param as $key => $value) $_POST[$key] = $value;
$tester->dbh->query("delete from zt_projectstory where project = $executionID");
$this->objectModel->linkStory($executionID);
unset($_POST);
$this->objectModel->unlinkStory($executionID, $storyID);
if(dao::isError())
{
$error = dao::getError();
return $error;
}
elseif($count == "1")
{
$object = $tester->dbh->query("select * from zt_projectstory where project = $executionID")->fetchAll();
return count($object);
}
else
{
$object = $tester->dbh->query("select * from zt_projectstory where project = $executionID")->fetchAll();
if(isset($object))
{
return $object;
}
else
{
return "全部需求已解除";
}
}
}
public function unlinkCasesTest($executionID, $productID, $storyID)
{
global $tester;
$tester->dbh->query("delete from zt_projectcase where project = $executionID");
$this->objectModel->linkCases($executionID, $productID, $storyID);
$this->objectModel->unlinkCases($executionID, $storyID);
if(dao::isError())
{
$error = dao::getError();
return $error;
}
else
{
$object = $tester->dbh->query("select * from zt_projectcase where project = $executionID")->fetchAll();
return $object;
}
}
public function getTeamMembersTest($executionID, $count)
{
$object = $this->objectModel->getTeamMembers($executionID);
if(dao::isError())
{
$error = dao::getError();
return $error;
}
elseif($count == "1")
{
return count($object);
}
else
{
return $object;
}
}
public function getMembersByIdListTest($executionIdList, $count)
{
$object = $this->objectModel->getMembersByIdList($executionIdList);
if(dao::isError())
{
$error = dao::getError();
return $error;
}
elseif($count == "1")
{
return count($object);
}
else
{
return $object;
}
}
public function getTeamSkipTest($taskID, $begin, $end, $count)
{
global $tester;
$teams = $tester->dao->select('*')->from(TABLE_TEAM)->where('root')->eq($taskID)->andWhere('type')->eq('task')->orderBy('order')->fetchAll('account');
$object = $this->objectModel->getTeamSkip($teams, $begin, $end);
if(dao::isError())
{
$error = dao::getError();
return $error;
}
elseif($count == "1")
{
return count($object);
}
else
{
return $object;
}
}
}
+90
View File
@@ -532,4 +532,94 @@ class taskTest
return $object;
}
}
public function createTaskFromGitlabIssueTest($task, $executionID)
{
$objectID = $this->objectModel->createTaskFromGitlabIssue($task, $executionID);
if(dao::isError())
{
return dao::getError();
}
else
{
$object = $this->objectModel->getById($objectID);
return $object;
}
}
public function getProjectIDTest($executionID)
{
$object = $this->objectModel->getProjectID($executionID);
if(dao::isError())
{
return dao::getError();
}
else
{
return $object;
}
}
public function getStoryCommentsTest($storyID)
{
$object = $this->objectModel->getStoryComments($storyID);
if(dao::isError())
{
return dao::getError();
}
else
{
return $object;
}
}
public function computeWorkingHoursTest($taskID)
{
$result = $this->objectModel->computeWorkingHours($taskID);
if(dao::isError())
{
return dao::getError();
}
else
{
$object = $this->objectModel->getById($taskID);
if(!empty($object) and $object->parent > 0) $parentObject = $this->objectModel->getById($object->parent);
return isset($parentObject) ? $parentObject : $object;
}
}
public function computeBeginAndEndTest($taskID)
{
$result = $this->objectModel->computeBeginAndEnd($taskID);
if(dao::isError())
{
return dao::getError();
}
else
{
$object = $this->objectModel->getById($taskID);
if(!empty($object) and $object->parent > 0) $parentObject = $this->objectModel->getById($object->parent);
return isset($parentObject) ? $parentObject : $object;
}
}
public function computeHours4MultipleTest($oldTask, $task = null, $team = array(), $autoStatus = true)
{
$result = $this->objectModel->computeHours4Multiple($oldTask, $task, $team, $autoStatus);
if(dao::isError())
{
return dao::getError();
}
else
{
$object = $this->objectModel->getById($oldTask->id);
return !empty($team) ? $result : $object;
}
}
}
+1 -1
View File
@@ -55,7 +55,7 @@ fields:
format: ""
- field: comment
note: "备注"
range: "1-100000"
range: 1-100000
prefix: "这是一个系统日志测试备注"
postfix: ""
loop: 0
+54
View File
@@ -0,0 +1,54 @@
title: table zt_kanban
desc: "看板表"
author: automated export
version: "1.0"
fields:
- field: space
range: 1-50{2}
- field: name
fields:
- field: name1
range: 通用看板
- field: name2
range: 1-10000
- field: owner
range: admin
- field: team
range: ""
- field: desc
range: "看板详情"
- field: acl
range: extend,open
- field: whitelist
range: ""
- field: archived
range: "1"
- field: performable
range: "0"
- field: status
range: "active"
- field: order
range: 5-10000:5
- field: displayCards
range: "0"
- field: fluidBoard
range: "0"
- field: object
range: ""
- field: createdBy
range: "admin"
- field: createdDate
range: "(-1M)-(+M):1D"
type: timestamp
format: "YYYY-MM-DD"
prefix: "\t"
- field: lastEditedBy
range: ""
- field: lastEditedDate
range: ""
- field: closedBy
range: ""
- field: closedDate
range: ""
- field: deleted
range: "0"
+72
View File
@@ -0,0 +1,72 @@
title: table zt_kanbancard
desc: ""
author: automated export
version: "1.0"
fields:
- field: kanban
range: 1-100{8}
- field: region
range: 1-100{8}
- field: group
range: 1-100{8}
- field: fromID
range: "0"
- field: fromType
range: ""
- field: name
range: 1-1000000
prefix: "卡片"
- field: status
range: "doing"
- field: pri
range: "3"
- field: assignedTo
range: "admin"
- field: desc
range: ""
- field: begin
range: "(-2M)-(+M):1D"
type: timestamp
format: "YY/MM/DD"
postfix: "\t"
- field: end
range: "(+1w)-(+2M):1D"
type: timestamp
format: "YY/MM/DD"
postfix: "\t"
- field: estimate
range: "0"
- field: color
range: "#fff"
- field: acl
range: "open"
- field: whitelist
range: ""
- field: order
range: 1-2
- field: archived
range: "0"
- field: createdBy
range: "admin"
- field: createdDate
range: "(-2M)-(+M):1D"
type: timestamp
format: "YY/MM/DD"
postfix: "\t"
- field: lastEditedBy
range: ""
- field: lastEditedDate
range: ""
- field: archivedBy
range: ""
- field: archivedDate
range: ""
- field: assignedBy
range: ""
- field: assignedDate
range: "(-2M)-(+M):1D"
type: timestamp
format: "YY/MM/DD"
postfix: "\t"
- field: deleted
range: "0"
+22
View File
@@ -0,0 +1,22 @@
title: table zt_kanbancell
desc: ""
author: automated export
version: "1.0"
fields:
- field: kanban
range: 1-100{4}
- field: lane
range: 1-100{4}
- field: column
range: 1-400
- field: type
range: "common"
- field: cards
fields:
- field: card1
prefix: ","
postfix: ","
range: 1-800:2
- field: card2
postfix: ","
range: 2-800:2
+17
View File
@@ -0,0 +1,17 @@
title: table zt_kanbancell
desc: ""
author: automated export
version: "1.0"
fields:
- field: id
range: 401-10000
- field: kanban
range: 161-190{27},251-180{27},341-370{27},431-460{27},521-550{27},611-640{27}
- field: lane
range: 1-100{4}
- field: column
range: 401-5260
- field: type
range: story{11},bug{9},task{7}
- field: cards
range: ""
+30
View File
@@ -0,0 +1,30 @@
title: table zt_kanbancolumn
desc: ""
author: automated export
version: "1.0"
fields:
- field: lane
range: "0"
- field: parent
range: "0"
- field: type
range: 1-400
prefix: "column"
- field: region
range: 1-100{4}
- field: group
range: 1-100{4}
- field: name
range: 未开始,进行中,已完成,已关闭
- field: color
range: "#333"
- field: limit
range: ""
- field: order
range: 1-4
- field: cards
range: ""
- field: archived
range: "0"
- field: deleted
range: "0"
+31
View File
@@ -0,0 +1,31 @@
title: table zt_kanbancolumn
desc: ""
author: automated export
version: "1.0"
fields:
- field: id
range: 401-100000
- field: lane
range: "0"
- field: parent
range: "0"
- field: type
range: [backlog,ready,develop,developing,developed,test,testing,tested,verified,released,closed,unconfirmed,confirmed,resolving,fixing,fixed,test,testing,tested,closed,wait,develop,developing,developed,pause,canceled,closed]
- field: region
range: 101-280{27}
- field: group
range: "0"
- field: name
range: Backlog,准备好,开发,进行中,完成,测试,进行中,完成,已验收,已发布,已关闭,待确认,已确认,解决中,进行中,完成,测试,测试中,测试完毕,已关闭,未开始,开发,研发中,研发完毕,已暂停,已取消,已关闭
- field: color
range: "#333"
- field: limit
range: ""
- field: order
range: "0"
- field: cards
range: ""
- field: archived
range: "0"
- field: deleted
range: "0"
+11
View File
@@ -0,0 +1,11 @@
title: table zt_kanbangroup
desc: ""
author: automated export
version: "1.0"
fields:
- field: kanban
range: 1-100
- field: region
range: 1-100
- field: order
range: 5-100000:5
+13
View File
@@ -0,0 +1,13 @@
title: table zt_kanbangroup
desc: ""
author: automated export
version: "1.0"
fields:
- field: id
range: 101-10000
- field: kanban
range: 161-190,251-180,341-370,431-460,521-550,611-640
- field: region
range: 101-10000{3}
- field: order
range: 1-3
+27
View File
@@ -0,0 +1,27 @@
title: table zt_kanbanlane
desc: "看板泳道"
author: automated export
version: "1.0"
fields:
- field: execution
range: "0"
- field: type
range: "common"
- field: region
range: 1-100
- field: group
range: 1-100
- field: groupby
range: ""
- field: extra
range: ""
- field: name
range: "默认泳道"
- field: color
range: "#7ec5ff"
- field: order
range: 5-10000:5
- field: lastEditedTime
range: ""
- field: deleted
range: "0"
+27
View File
@@ -0,0 +1,27 @@
title: table zt_kanbanlane
desc: "看板泳道"
author: automated export
version: "1.0"
fields:
- field: execution
range: 161-190{3},251-180{3},341-370{3},431-460{3},521-550{3},611-640{3}
- field: type
range: story,bug,task
- field: region
range: 101-280{3}
- field: group
range: 101-640
- field: groupby
range: ""
- field: extra
range: ""
- field: name
range: 研发需求,Bug,任务
- field: color
range: [#7ec5ff,#333,#2b529c]
- field: order
range: 5-15:5
- field: lastEditedTime
range: ""
- field: deleted
range: "0"
+25
View File
@@ -0,0 +1,25 @@
title: table zt_kanbanregion
desc: ""
author: automated export
version: "1.0"
fields:
- field: space
range: 1-50{2}
- field: kanban
range: 1-100
- field: name
range: "默认区域"
- field: order
range: 5-10000:5
- field: createdDate
range: "(-1M)-(+M):1D"
type: timestamp
format: "YYYY-MM-DD"
- field: createdBy
range: "admin"
- field: lastEditedBy
range: ""
- field: lastEditedDate
range: ""
- field: deleted
range: "0"
+27
View File
@@ -0,0 +1,27 @@
title: table zt_kanbanregion
desc: ""
author: automated export
version: "1.0"
fields:
- field: id
range: 101-10000
- field: space
range: 0
- field: kanban
range: 161-190,251-180,341-370,431-460,521-550,611-640
- field: name
range: "默认区域"
- field: order
range: 1
- field: createdDate
range: "(-1M)-(+M):1D"
type: timestamp
format: "YYYY-MM-DD"
- field: createdBy
range: "admin"
- field: lastEditedBy
range: ""
- field: lastEditedDate
range: ""
- field: deleted
range: "0"
+67
View File
@@ -0,0 +1,67 @@
title: table zt_kanbanspace
desc: "看板空间"
author: automated export
version: "1.0"
fields:
- field: id
note: "ID"
fields:
range: 1-10000
prefix: ""
postfix: ""
format: ""
- field: type
note: "类型"
range: cooperation,private,public
prefix: ""
postfix: ""
format: ""
- field: team
note: "团队"
range: admin
prefix: ","
postfix: ""
format: ""
- field: owner
note: "所属者"
fields:
- field: account1
range: admin{10},user{10},test{10},pm{10},po{10}
- field: account2
range: [],3-100,1-100,1-100,1-100
prefix: ""
postfix: ""
- field: acl
note: "权限"
range: open,private
prefix: ""
postfix: ""
- field: createdBy
note: "创建者"
range: admin
prefix: ""
postfix: ""
loop: 0
format: ""
- field: createdDate
note: "创建日期"
range: "(-1M)-(+M):1D"
prefix: "\t"
type: timestamp
format: "YYYY-MM-DD"
- field: lastEditedDate
note: "最后编辑日期"
range: ""
prefix: ""
postfix: ""
tampoop: 0
- field: closedDate
note: "关闭时间"
range: ""
prefix: ""
postfix: ""
- field: deleted
note: ""
range: 0
prefix: ""
postfix: ""
+3 -2
View File
@@ -117,11 +117,12 @@ fields:
format: ""
- field: deadline
note: "截止日期"
range: "2022-02-27"
range: "(-1w)-(-1M):-1D"
prefix: ""
postfix: ""
loop: 0
format: ""
type: timestamp
format: "YY/MM/DD"
- field: status
note: "任务状态"
range: wait,doing,done,pause,cancel,closed
+12
View File
@@ -0,0 +1,12 @@
title: table zt_planstory
desc: "需求计划关联表"
author: sgm
version: "1.0"
fields:
- field: plan
range: 1-360:3{4}
- field: story
range: 1-400
- field: order
note: "排序"
range: 5-100000:5
+12 -12
View File
@@ -1,24 +1,24 @@
title: table zt_productplan
desc: "产品计划"
author: sgm
author: sgm
version: "1.0"
fields:
- field: id
note: "ID"
range: 1-10000
- field: product
- field: product
note: "所属产品"
range: 1-120{3}
- field: branch
range: 1-10{3}
- field: branch
note: "所属分支"
range: 0
- field: parent
- field: parent
note: "父计划"
range: 0
- field: title
- field: title
note: "名称"
range: [1.0,1.1,长名称好长好长好长好长好长好长好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好好长好长好长好长好长好的名字啊!@ase!!@#%@^&#!]
- field: desc
- field: desc
note: "描述"
range: <div>
<p>asdxxxfa阿萨德开机as家世界发卡机发设计费啥登记卡设计费卡加斯加附件阿峰</p>
@@ -27,19 +27,19 @@ fields:
<p>IUIG是DAU发加速度快哦哦阿萨德几年内发,,,奥斯丁,,,切,,,请问加十多年你</p>
<p>IU风格就叫阿萨德奥斯丁哦IG是DAU,,,奥斯丁,,,切,,,请问加十多年你</p>
</div>
- field: begin
- field: begin
note: "开始日期"
range: "(-10M)-(-7M):7D"
type: timestamp
format: "YYYY-MM-DD"
- field: end
- field: end
note: "结束日期"
range: "(-6M)-(+6M):7D"
type: timestamp
format: "YYYY-MM-DD"
- field: order
- field: order
note: "排序"
value: "$id * 5"
- field: deleted
- field: deleted
note: "是否删除"
range: 0{359},1
range: 0{359},1
+1 -1
View File
@@ -3,7 +3,7 @@ author: Zhu Jinyong
version: "1.0"
fields:
- field: project
range: 0
range: 1-10
- field: model
range: scrum{30},waterfall{30},kanban{30}
- field: name
+1 -1
View File
@@ -9,4 +9,4 @@ fields:
- field: branch
range: 0
- field: plan
range: 0
range: 1-360:3
+17 -9
View File
@@ -117,11 +117,12 @@ fields:
format: ""
- field: deadline
note: "截止日期"
range: "2022-02-27"
range: "(+1w)-(-1M):-1D"
prefix: ""
postfix: ""
loop: 0
format: ""
type: timestamp
format: "YY/MM/DD"
- field: status
note: "任务状态"
range: wait,doing,done,pause,cancel,closed
@@ -204,7 +205,8 @@ fields:
prefix: ""
postfix: ""
loop: 0
format: ""
type: timestamp
format: "YY/MM/DD"
- field: realStarted
note: "实际开始"
from: common.date.v1.yaml
@@ -212,7 +214,8 @@ fields:
prefix: ""
postfix: ""
loop: 0
format: ""
format: "YY/MM/DD"
type: timestamp
- field: finishedBy
note: "由谁完成"
from: common.user.v1.yaml
@@ -228,7 +231,8 @@ fields:
prefix: ""
postfix: ""
loop: 0
format: ""
format: "YY/MM/DD"
type: timestamp
- field: finishedList
note: "完成者列表"
from: common.user.v1.yaml
@@ -252,7 +256,8 @@ fields:
prefix: ""
postfix: ""
loop: 0
format: ""
format: "YY/MM/DD"
type: timestamp
- field: closedBy
note: "由谁关闭"
from: common.user.v1.yaml
@@ -268,7 +273,8 @@ fields:
prefix: ""
postfix: ""
loop: 0
format: ""
format: "YY/MM/DD"
type: timestamp
- field: realDuration
note: "实际持续时长"
range: 1
@@ -305,7 +311,8 @@ fields:
prefix: ""
postfix: ""
loop: 0
format: ""
format: "YY/MM/DD"
type: timestamp
- field: activatedDate
note: "重新激活日期"
from: common.date.v1.yaml
@@ -313,7 +320,8 @@ fields:
prefix: ""
postfix: ""
loop: 0
format: ""
format: "YY/MM/DD"
type: timestamp
- field: deleted
note: "是否删除"
range: 0
+326
View File
@@ -0,0 +1,326 @@
title: table zt_task
desc: "任务"
author: automated export
version: "1.0"
fields:
- field: id
note: "id"
range: 901-910
prefix: ""
postfix: ""
loop: 0
format: ""
- field: parent
note: "父任务"
range: 601-603
prefix: ""
postfix: ""
loop: 0
format: ""
- field: project
note: "所属项目"
range: 11
prefix: ""
postfix: ""
loop: 0
format: ""
- field: execution
note: "所属执行"
range: 101
- field: module
note: "所属模块"
range: 21
prefix: ""
postfix: ""
loop: 0
format: ""
- field: story
note: "相关需求"
range: 0
prefix: ""
postfix: ""
loop: 0
format: ""
- field: design
note: "相关设计"
range: 0
prefix: ""
postfix: ""
loop: 0
format: ""
- field: storyVersion
note: "需求版本"
range: 1
prefix: ""
postfix: ""
loop: 0
format: ""
- field: designVersion
note: "设计版本"
range: 0
prefix: ""
postfix: ""
loop: 0
format: ""
- field: fromBug
note: "来源Bug"
range: 0
prefix: ""
postfix: ""
loop: 0
format: ""
- field: name
note: "任务名称"
fields:
- field: name1
range: "子任务"
- field: name2
range: 1-10
prefix: ""
postfix: ""
loop: 0
format: ""
- field: type
note: "任务类型"
range: design,devel,test,study,discuss,ui,affair,misc
prefix: ""
postfix: ""
loop: 0
format: ""
- field: pri
note: "优先级"
range: 1-4
prefix: ""
postfix: ""
loop: 0
format: ""
- field: estimate
note: "最初预计"
range: 0-10
prefix: ""
postfix: ""
loop: 0
format: ""
- field: consumed
note: "总计消耗"
range: 3-12
prefix: ""
postfix: ""
loop: 0
format: ""
- field: left
note: "预计剩余"
range: 0-10
prefix: ""
postfix: ""
loop: 0
format: ""
- field: deadline
note: "截止日期"
range: "(-1w)-(-1M):-1D"
prefix: ""
postfix: ""
loop: 0
type: timestamp
format: "YY/MM/DD"
- field: status
note: "任务状态"
range: wait,doing,done,pause,cancel,closed
prefix: ""
postfix: ""
loop: 0
format: ""
- field: subStatus
note: "子状态"
range: 0
prefix: ""
postfix: ""
loop: 0
format: ""
- field: color
note: "标题颜色"
from: common.color.v1.yaml
use: color
prefix: ""
postfix: ""
loop: 0
format: ""
- field: mailto
note: "抄送给"
from: common.user.v1.yaml
use: user
prefix: ""
postfix: ""
loop: 0
format: ""
- field: desc
note: "任务描述"
range: 1-10000
prefix: "这里是任务描述"
postfix: ""
loop: 0
format: ""
- field: version
note: "版本号"
range: 1
prefix: ""
postfix: ""
loop: 0
format: ""
- field: openedBy
note: "由谁创建"
from: common.user.v1.yaml
use: user
prefix: ""
postfix: ""
loop: 0
format: ""
- field: openedDate
note: "创建日期"
from: common.date.v1.yaml
use: dateA
prefix: ""
postfix: ""
loop: 0
format: ""
- field: assignedTo
note: "指派给"
from: common.user.v1.yaml
use: user
prefix: ""
postfix: ""
loop: 0
format: ""
- field: assignedDate
note: "指派日期"
from: common.date.v1.yaml
use: dateA
prefix: ""
postfix: ""
loop: 0
format: ""
- field: estStarted
note: "预计开始"
range: "2022-01-27"
prefix: ""
postfix: ""
loop: 0
format: "YY/MM/DD"
type: timestamp
- field: realStarted
note: "实际开始"
from: common.date.v1.yaml
use: dateB
prefix: ""
postfix: ""
loop: 0
format: "YY/MM/DD"
type: timestamp
- field: finishedBy
note: "由谁完成"
from: common.user.v1.yaml
use: user
prefix: ""
postfix: ""
loop: 0
format: ""
- field: finishedDate
note: "完成日期"
from: common.date.v1.yaml
use: dateA
prefix: ""
postfix: ""
loop: 0
format: ""
- field: finishedList
note: "完成者列表"
from: common.user.v1.yaml
use: user
prefix: ""
postfix: ""
loop: 0
format: ""
- field: canceledBy
note: "由谁取消"
from: common.user.v1.yaml
use: user
prefix: ""
postfix: ""
loop: 0
format: ""
- field: canceledDate
note: "取消日期"
from: common.date.v1.yaml
use: dateA
prefix: ""
postfix: ""
loop: 0
format: ""
- field: closedBy
note: "由谁关闭"
from: common.user.v1.yaml
use: user
prefix: ""
postfix: ""
loop: 0
format: ""
- field: closedDate
note: "关闭日期"
from: common.date.v1.yaml
use: dateA
prefix: ""
postfix: ""
loop: 0
format: ""
- field: realDuration
note: "实际持续时长"
range: 1
prefix: ""
postfix: ""
loop: 0
format: ""
- field: planDuration
note: "计划持续时长"
range: 1
prefix: ""
postfix: ""
loop: 0
format: ""
- field: closedReason
note: "关闭原因"
range: ""
prefix: ""
postfix: ""
loop: 0
format: ""
- field: lastEditedBy
note: "最后修改者"
from: common.user.v1.yaml
use: user
prefix: ""
postfix: ""
loop: 0
format: ""
- field: lastEditedDate
note: "最后修改时间"
from: common.date.v1.yaml
use: dateA
prefix: ""
postfix: ""
loop: 0
format: ""
- field: activatedDate
note: "重新激活日期"
from: common.date.v1.yaml
use: dateB
prefix: ""
postfix: ""
loop: 0
format: ""
- field: deleted
note: "是否删除"
range: 0
prefix: ""
postfix: ""
loop: 0
format: ""
+99
View File
@@ -0,0 +1,99 @@
title: table zt_team
desc: "团队"
author: automated export
version: "1.0"
fields:
- field: id
note: "ID"
range: 911-1000
prefix: ""
postfix: ""
loop: 0
format: ""
- field: root
note: "任务ID"
range: 1,901-909
prefix: ""
postfix: ""
loop: 0
format: ""
- field: type
note: "项目类型"
range: 'task'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: account
note: "用户账号"
fields:
- field: account1
range: po,user,admin
- field: account2
range: 82,92,''
prefix: ""
postfix: ""
loop: 0
format: ""
- field: role
note: "角色"
range: 研发{99},测试{100},项目经理{100},产品经理{5}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: limited
note: "受限用户"
range: no
prefix: ""
postfix: ""
loop: 0
format: ""
- field: join
note: "加盟日"
range: Y-m-d
prefix: ""
type: timestamp
format: "YYYY-MM-DD"
- field: days
note: "可用工作日"
range: 1-50:R
prefix: ""
postfix: ""
loop: 0
format: ""
- field: hours
note: "可用工时/天"
range: 1-8:R
prefix: ""
postfix: ""
loop: 0
format: ""
- field: estimate
note: ""
range: 1-3
prefix: ""
postfix: ""
loop: 0
format: ""
- field: consumed
note: ""
range: 1-3
prefix: ""
postfix: ""
loop: 0
format: ""
- field: left
note: ""
range: 1-3
prefix: ""
postfix: ""
loop: 0
format: ""
- field: order
note: "排序"
range: 0
prefix: ""
postfix: ""
loop: 0
format: ""
+7
View File
@@ -135,6 +135,13 @@ fields:
postfix: ""
loop: 0
format: ""
- field: visions
note: "版本"
range: rnd
prefix: ""
postfix: ",lite"
loop: 0
format: ""
- field: ip
note: "最后IP"
format: ""
+21 -1
View File
@@ -4,6 +4,7 @@ $builder = new stdclass();
$builder->company = array('rows' => 1, 'extends' => array('company'));
$builder->user = array('rows' => 1000, 'extends' => array('user'));
$builder->dept = array('rows' => 100, 'extends' => array('dept'));
$builder->action = array('rows' => 100, 'extends' => array('action'));
$builder->program = array('rows' => 10, 'extends' => array('project', 'program'));
$builder->project = array('rows' => 90, 'extends' => array('project', 'project'));
@@ -11,21 +12,40 @@ $builder->sprint = array('rows' => 600, 'extends' => array('project', 'ex
$builder->story = array('rows' => 400, 'extends' => array('story'));
$builder->storymodule = array('rows' => 800, 'extends' => array('module','storymodule'));
$builder->storyplan = array('rows' => 400, 'extends' => array('planstory'));
$builder->task = array('rows' => 600, 'extends' => array('task','task'));
$builder->taskmore = array('rows' => 300, 'extends' => array('task','moretask'));
$builder->taskspec = array('rows' => 600, 'extends' => array('taskspec'));
$builder->taskmodule = array('rows' => 1800, 'extends' => array('module','taskmodule'));
$builder->taskestimate = array('rows' => 600, 'extends' => array('taskestimate'));
$builder->taskson = array('rows' => 10, 'extends' => array('task', 'taskson'));
$builder->case = array('rows' => 400, 'extends' => array('case'));
$builder->bug = array('rows' => 300, 'extends' => array('bug'));
$builder->product = array('rows' => 100, 'extends' => array('product'));
$builder->productline = array('rows' => 20, 'extends' => array('module', 'productline'));
$builder->productplan = array('rows' => 360, 'extends' => array('productplan'));
$builder->productplan = array('rows' => 30, 'extends' => array('productplan'));
$builder->branch = array('rows' => 240, 'extends' => array('branch'));
$builder->projectproduct = array('rows' => 200, 'extends' => array('projectproduct'));
$builder->kanbanspace = array('rows' => 50, 'extends' => array('kanbanspace'));
$builder->kanban = array('rows' => 100, 'extends' => array('kanban'));
$builder->kanbanregion = array('rows' => 100, 'extends' => array('kanbanregion','kanbanregion'));
$builder->kanbangroup = array('rows' => 100, 'extends' => array('kanbangroup','kanbangroup'));
$builder->kanbanlane = array('rows' => 100, 'extends' => array('kanbanlane','kanbanlane'));
$builder->kanbancolumn = array('rows' => 400, 'extends' => array('kanbancolumn','kanbancolumn'));
$builder->kanbancard = array('rows' => 800, 'extends' => array('kanbancard','kanbancard'));
$builder->kanbancell = array('rows' => 400, 'extends' => array('kanbancell','kanbancell'));
$builder->kanbanregionproject = array('rows' => 180, 'extends' => array('kanbanregion','kanbanregionproject'));
$builder->kanbangroupproject = array('rows' => 540, 'extends' => array('kanbangroup','kanbangroupproject'));
$builder->kanbanlaneproject = array('rows' => 540, 'extends' => array('kanbanlane','kanbanlaneproject'));
$builder->kanbancolumnproject = array('rows' => 4860, 'extends' => array('kanbancolumn','kanbancolumnproject'));
$builder->kanbancellproject = array('rows' => 4860, 'extends' => array('kanbancell','kanbancellproject'));
$builder->team = array('rows' => 400, 'extends' => array('team'));
$builder->teamtask = array('rows' => 20, 'extends' => array('team', 'teamtask'));
$builder->stakeholder = array('rows' => 1, 'extends' => array('stakeholder'));
$builder->stageson = array('rows' => 30, 'extends' => array('project', 'executionson'));
+68
View File
@@ -44,6 +44,7 @@ class Processor
$this->initRelease();
$this->initStakeholder();
$this->initUserquery();
$this->initUpdateKanban();
$this->dao->commit();
}
@@ -148,6 +149,11 @@ class Processor
*/
private function initTask()
{
$parentList = $this->dao->select('parent')->from(TABLE_TASK)->where('parent')->gt(0)->fetchAll('parent');
$parentIDList = array_keys($parentList);
$parentID = implode(',', $parentIDList);
$this->dao->update(TABLE_TASK)->set('parent')->eq(-1)->where('id')->in($parentID)->andWhere('deleted')->eq(0)->exec();
}
/**
@@ -229,4 +235,66 @@ class Processor
$this->dao->query("INSERT INTO `zt_userquery` (`id`, `account`, `module`, `title`, `form`, `sql`, `shortcut`) VALUES (1, 'admin', 'task', '任务查询测试条件', 'a:60:{s:9:\"fieldname\";s:0:\"\";s:11:\"fieldstatus\";s:0:\"\";s:9:\"fielddesc\";s:0:\"\";s:15:\"fieldassignedTo\";s:0:\"\";s:8:\"fieldpri\";s:1:\"0\";s:14:\"fieldexecution\";s:0:\"\";s:11:\"fieldmodule\";s:4:\"ZERO\";s:13:\"fieldestimate\";s:0:\"\";s:9:\"fieldleft\";s:0:\"\";s:13:\"fieldconsumed\";s:0:\"\";s:9:\"fieldtype\";s:0:\"\";s:12:\"fieldfromBug\";s:0:\"\";s:17:\"fieldclosedReason\";s:0:\"\";s:13:\"fieldopenedBy\";s:0:\"\";s:15:\"fieldfinishedBy\";s:0:\"\";s:13:\"fieldclosedBy\";s:0:\"\";s:13:\"fieldcancelBy\";s:1:\"0\";s:17:\"fieldlastEditedBy\";s:0:\"\";s:11:\"fieldmailto\";s:0:\"\";s:17:\"fieldfinishedList\";s:0:\"\";s:15:\"fieldopenedDate\";s:0:\"\";s:13:\"fielddeadline\";s:0:\"\";s:15:\"fieldestStarted\";s:0:\"\";s:16:\"fieldrealStarted\";s:0:\"\";s:17:\"fieldassignedDate\";s:0:\"\";s:17:\"fieldfinishedDate\";s:0:\"\";s:15:\"fieldclosedDate\";s:0:\"\";s:17:\"fieldcanceledDate\";s:0:\"\";s:19:\"fieldlastEditedDate\";s:0:\"\";s:7:\"fieldid\";s:0:\"\";s:15:\"fieldcanceledBy\";s:0:\"\";s:6:\"andOr1\";s:3:\"AND\";s:6:\"field1\";s:4:\"name\";s:9:\"operator1\";s:7:\"include\";s:6:\"value1\";s:2:\"aa\";s:6:\"andOr2\";s:3:\"and\";s:6:\"field2\";s:2:\"id\";s:9:\"operator2\";s:1:\"=\";s:6:\"value2\";s:0:\"\";s:6:\"andOr3\";s:3:\"and\";s:6:\"field3\";s:6:\"status\";s:9:\"operator3\";s:1:\"=\";s:6:\"value3\";s:0:\"\";s:10:\"groupAndOr\";s:3:\"and\";s:6:\"andOr4\";s:3:\"AND\";s:6:\"field4\";s:4:\"desc\";s:9:\"operator4\";s:7:\"include\";s:6:\"value4\";s:0:\"\";s:6:\"andOr5\";s:3:\"and\";s:6:\"field5\";s:10:\"assignedTo\";s:9:\"operator5\";s:1:\"=\";s:6:\"value5\";s:0:\"\";s:6:\"andOr6\";s:3:\"and\";s:6:\"field6\";s:3:\"pri\";s:9:\"operator6\";s:1:\"=\";s:6:\"value6\";s:1:\"0\";s:6:\"module\";s:4:\"task\";s:9:\"actionURL\";s:77:\"/index.php?m=execution&f=task&executionID=101&status=bySearch&param=myQueryID\";s:10:\"groupItems\";s:1:\"3\";s:8:\"formType\";s:4:\"lite\";}', '(( 1 AND `name` LIKE \'%11%\' ) AND ( 1 )) AND deleted = \'0\'', '0');");
$this->dao->query("INSERT INTO `zt_userquery` (`id`, `account`, `module`, `title`, `form`, `sql`, `shortcut`) VALUES (2, 'admin', 'executionStory', '需求查找条件', 'a:56:{s:10:\"fieldtitle\";s:0:\"\";s:13:\"fieldkeywords\";s:0:\"\";s:11:\"fieldstatus\";s:0:\"\";s:10:\"fieldstage\";s:0:\"\";s:8:\"fieldpri\";s:1:\"0\";s:12:\"fieldproduct\";s:1:\"0\";s:11:\"fieldbranch\";s:0:\"\";s:11:\"fieldmodule\";s:4:\"ZERO\";s:9:\"fieldplan\";s:0:\"\";s:13:\"fieldestimate\";s:0:\"\";s:11:\"fieldsource\";s:0:\"\";s:15:\"fieldsourceNote\";s:0:\"\";s:12:\"fieldfromBug\";s:0:\"\";s:13:\"fieldopenedBy\";s:0:\"\";s:15:\"fieldreviewedBy\";s:0:\"\";s:15:\"fieldassignedTo\";s:0:\"\";s:13:\"fieldclosedBy\";s:0:\"\";s:17:\"fieldlastEditedBy\";s:0:\"\";s:11:\"fieldmailto\";s:0:\"\";s:17:\"fieldclosedReason\";s:0:\"\";s:12:\"fieldversion\";s:0:\"\";s:15:\"fieldopenedDate\";s:0:\"\";s:17:\"fieldreviewedDate\";s:0:\"\";s:17:\"fieldassignedDate\";s:0:\"\";s:15:\"fieldclosedDate\";s:0:\"\";s:19:\"fieldlastEditedDate\";s:0:\"\";s:7:\"fieldid\";s:0:\"\";s:6:\"andOr1\";s:3:\"AND\";s:6:\"field1\";s:5:\"title\";s:9:\"operator1\";s:7:\"include\";s:6:\"value1\";s:3:\"362\";s:6:\"andOr2\";s:3:\"and\";s:6:\"field2\";s:2:\"id\";s:9:\"operator2\";s:1:\"=\";s:6:\"value2\";s:0:\"\";s:6:\"andOr3\";s:3:\"and\";s:6:\"field3\";s:8:\"keywords\";s:9:\"operator3\";s:7:\"include\";s:6:\"value3\";s:0:\"\";s:10:\"groupAndOr\";s:3:\"and\";s:6:\"andOr4\";s:3:\"AND\";s:6:\"field4\";s:5:\"stage\";s:9:\"operator4\";s:1:\"=\";s:6:\"value4\";s:0:\"\";s:6:\"andOr5\";s:3:\"and\";s:6:\"field5\";s:6:\"status\";s:9:\"operator5\";s:1:\"=\";s:6:\"value5\";s:0:\"\";s:6:\"andOr6\";s:3:\"and\";s:6:\"field6\";s:3:\"pri\";s:9:\"operator6\";s:1:\"=\";s:6:\"value6\";s:1:\"0\";s:6:\"module\";s:14:\"executionStory\";s:9:\"actionURL\";s:95:\"/index.php?m=execution&f=story&executionID=101&orderBy=pri_desc&type=bySearch&queryID=myQueryID\";s:10:\"groupItems\";s:1:\"3\";s:8:\"formType\";s:4:\"lite\";}', '(( 1 AND `title` LIKE \'%362%\' ) AND ( 1 ))', '0');");
}
/**
* Init initUpdateKanban.
*
* @access public
* @return void
*/
private function initUpdateKanban()
{
$this->dao->query("update zt_kanbancolumn set `limit` = '-1' where id >= 1 and id <= 400");
$kanban = $this->dao->select('id,type,region,name,color,`limit`,`order`')->from(TABLE_KANBANCOLUMN)->where('id')->gt('400')->fetchAll();
$group = 101;
foreach($kanban as $key => $value)
{
$id = $value->id;
$value->limit = '-1';
if(!isset($value->parent)) $value->parent = 0;
if(in_array($value->type, ['develop', 'test', 'resolving']))
{
$value->parent = '-1';
$kanban[$key+1]->parent = $value->id;
$kanban[$key+2]->parent = $value->id;
}
$value->group = $group;
if($value->type == 'closed')
{
$group++;
}
unset($value->id);
$this->dao->update(TABLE_KANBANCOLUMN)->data($value)->where('id')->eq($id)->exec();
}
$kanbancell = $this->dao->select('id,type')->from(TABLE_KANBANCELL)->where('id')->gt('400')->fetchAll();
$kanbanlane = 101;
foreach($kanbancell as $key => $value)
{
$id = $value->id;
$value->lane = $kanbanlane;
if($value->type == 'story' && isset($kanbancell[$key+1]) && $kanbancell[$key+1]->type == 'bug')
{
$kanbanlane++;
}
if($value->type == 'bug' && isset($kanbancell[$key+1]) && $kanbancell[$key+1]->type == 'task')
{
$kanbanlane++;
}
if($value->type == 'task' && isset($kanbancell[$key+1]) && $kanbancell[$key+1]->type == 'story')
{
$kanbanlane++;
}
unset($value->id);
$this->dao->update(TABLE_KANBANCELL)->data($value)->where('id')->eq($id)->exec();
}
$this->dao->query("update zt_kanbancell set `cards` = '' where id > 400");
}
}
+29
View File
@@ -0,0 +1,29 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
su('admin');
/**
title=测试executionModel->getMembersByIdListTest();
cid=1
pid=1
敏捷执行关联用例 >> 101,1,1
瀑布执行关联用例 >> 131,43,169
看板执行关联用例 >> 161,68,269
敏捷执行关联用例统计 >> 4
瀑布执行关联用例统计 >> 4
看板执行关联用例统计 >> 4
*/
$executionIDList = array('101', '131', '161');
$count = array('0','1');
$execution = new executionTest();
r($execution->getMembersByIdListTest($executionIDList, $count[0])[$executionIDList[0]]) && p('0:root,account,realname') && e('101,po82,研发主管82');// 批量查询敏捷执行team
r($execution->getMembersByIdListTest($executionIDList, $count[0])[$executionIDList[1]]) && p('0:root,account,realname') && e('131,test22,开发22'); // 批量查询瀑布执行team
r($execution->getMembersByIdListTest($executionIDList, $count[0])[$executionIDList[2]]) && p('0:root,account,realname') && e('161,test52,开发52'); // 批量查询看板执行team
r($execution->getMembersByIdListTest($executionIDList, $count[1])) && p() && e('3'); // 批量查询执行team统计
+31
View File
@@ -0,0 +1,31 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
su('admin');
/**
title=测试executionModel->getTeamMembersTest();
cid=1
pid=1
敏捷执行关联用例 >> 101,1,1
瀑布执行关联用例 >> 131,43,169
看板执行关联用例 >> 161,68,269
敏捷执行关联用例统计 >> 4
瀑布执行关联用例统计 >> 4
看板执行关联用例统计 >> 4
*/
$executionIDList = array('101', '131', '161');
$count = array('0','1');
$execution = new executionTest();
r($execution->getTeamMembersTest($executionIDList[0], $count[0])) && p('po82:root,type,userID') && e('101,execution,482'); // 敏捷执行查看team
r($execution->getTeamMembersTest($executionIDList[1], $count[0])) && p('test22:root,type,realname') && e('131,execution,开发22'); // 瀑布执行查看team
r($execution->getTeamMembersTest($executionIDList[2], $count[0])) && p('test52:root,type,realname') && e('161,execution,开发52'); // 看板执行查看team
r($execution->getTeamMembersTest($executionIDList[0], $count[1])) && p() && e('2'); // 敏捷执行team统计
r($execution->getTeamMembersTest($executionIDList[1], $count[1])) && p() && e('1'); // 瀑布执行team统计
r($execution->getTeamMembersTest($executionIDList[2], $count[1])) && p() && e('1'); // 看板执行team统计
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
su('admin');
/**
title=测试executionModel->getTeamSkipTest();
cid=1
pid=1
敏捷执行关联用例 >> 101,1,1
瀑布执行关联用例 >> 131,43,169
看板执行关联用例 >> 161,68,269
敏捷执行关联用例统计 >> 4
瀑布执行关联用例统计 >> 4
看板执行关联用例统计 >> 4
*/
$teamList = array('test2', 'test12', 'test15');
$begin = 'test2';
$end = 'test17';
$count = array('0','1');
$execution = new executionTest();
var_dump($execution->getTeamSkipTest($teamList, $teamList[0], $end, $count[0]));die;
r($execution->getTeamSkipTest($teamList, $begin, $end, $count[0])) && p('0:root,account,realname') && e('101,po82,研发主管82');// 批量查询敏捷执行team
r($execution->getTeamSkipTest($executionIDList, $count[0])[$executionIDList[1]]) && p('0:root,account,realname') && e('131,test22,开发22'); // 批量查询瀑布执行team
r($execution->getTeamSkipTest($executionIDList, $count[0])[$executionIDList[2]]) && p('0:root,account,realname') && e('161,test52,开发52'); // 批量查询看板执行team
r($execution->getTeamSkipTest($executionIDList, $count[1])) && p() && e('3'); // 批量查询执行team统计
+1 -1
View File
@@ -34,4 +34,4 @@ r($execution->linkStoryTest($executionIDList[0], $count[1], $story)) && p()
r($execution->linkStoryTest($executionIDList[1], $count[1], $story)) && p() && e('3'); // 瀑布执行关联需求统计
r($execution->linkStoryTest($executionIDList[2], $count[1], $story)) && p() && e('3'); // 看板执行关联需求统计
system("./ztest init");
system("./ztest init");
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
su('admin');
/**
title=测试executionModel->unlinkCasesTest();
cid=1
pid=1
敏捷执行关联用例 >> 101,1,1
瀑布执行关联用例 >> 131,43,169
看板执行关联用例 >> 161,68,269
敏捷执行关联用例统计 >> 4
瀑布执行关联用例统计 >> 4
看板执行关联用例统计 >> 4
*/
$executionIDList = array('101', '131', '161');
$products = array('1', '43', '68');
$stories = array('2', '170', '270');
$count = array('0','1');
$execution = new executionTest();
r($execution->unlinkCasesTest($executionIDList[0], $products[0], $stories[0])) && p() && e('0'); // 敏捷执行解除关联用例
r($execution->unlinkCasesTest($executionIDList[1], $products[1], $stories[1])) && p() && e('0'); // 瀑布执行解除关联用例
r($execution->unlinkCasesTest($executionIDList[2], $products[2], $stories[2])) && p() && e('0'); // 看板执行解除关联用例
system("./ztest init");
+37
View File
@@ -0,0 +1,37 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
su('admin');
/**
title=测试executionModel->unlinkStoryTest();
cid=1
pid=1
敏捷执行关联需求 >> 101,1,4
瀑布执行关联需求 >> 131,1,4
看板执行关联需求 >> 161,1,4
敏捷执行关联需求统计 >> 3
瀑布执行关联需求统计 >> 3
看板执行关联需求统计 >> 3
*/
$executionIDList = array('101', '131', '161');
$stories = array('4', '324', '364');
$products = array('4' => '1', '324' => '81', '364' => '91');
$count = array('0', '1');
$story = array('stories' => $stories, 'products' => $products);
$execution = new executionTest();
r($execution->unlinkStoryTest($executionIDList[0], $count[0], $stories[0], $story)) && p('0:project,product,story') && e('101,81,324'); // 敏捷执行解除关联需求
r($execution->unlinkStoryTest($executionIDList[1], $count[0], $stories[1], $story)) && p('0:project,product,story') && e('131,1,4'); // 瀑布执行解除关联需求
r($execution->unlinkStoryTest($executionIDList[2], $count[0], $stories[2], $story)) && p('0:project,product,story') && e('161,1,4'); // 看板执行解除关联需求
r($execution->unlinkStoryTest($executionIDList[0], $count[1], $stories[0], $story)) && p() && e('2'); // 敏捷执行关联需求统计
r($execution->unlinkStoryTest($executionIDList[1], $count[1], $stories[1], $story)) && p() && e('2'); // 瀑布执行关联需求统计
r($execution->unlinkStoryTest($executionIDList[2], $count[1], $stories[2], $story)) && p() && e('2'); // 看板执行关联需求统计
system("./ztest init");
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/task.class.php';
su('admin');
/**
title=taskModel->computeBeginAndEnd();
cid=1
pid=1
根据taskID计算没有父计划的开始结束时间 >> 1,2022-03-09,0000-00-00 00:00:00,2022-03-16
根据taskID计算有父计划的父开始结束时间 >> 601,,0000-00-00 00:00:00,2022-03-02
根据不存在的taskID计划开始结束时间 >> 0
*/
$taskIDList = array('1', '901', '100001');
$task = new taskTest();
r($task->computeBeginAndEndTest($taskIDList[0])) && p('id,estStarted,realStarted,deadline') && e('1,2022-03-09,0000-00-00 00:00:00,2022-03-16'); //根据taskID计算没有父计划的开始结束时间
r($task->computeBeginAndEndTest($taskIDList[1])) && p('id,estStarted,realStarted,deadline') && e('601,,0000-00-00 00:00:00,2022-03-02'); //根据taskID计算有父计划的父开始结束时间
r($task->computeBeginAndEndTest($taskIDList[2])) && p('id,estStarted,realStarted,deadline') && e('0'); //根据不存在的taskID计算开始结束时间
system("./ztest init");
+105
View File
@@ -0,0 +1,105 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/task.class.php';
su('admin');
/**
title=taskModel->computeHours4Multiple();
cid=1
pid=1
task状态为wait只有老task计算多人工时 >> 1,po82,wait,3,3,3
task状态为wait有新老task计算多人工时 >> 1,po82,wait,3,3,3
task状态为wait有新老task和团队计算多人工时 >> 1,po82,doing,3,3,3
task状态为done只有老task计算多人工时 >> 903,po82,done,3,3,3
task状态为done有新老task计算多人工时 >> 903,po82,done,3,3,3
task状态为done有新老task和团队计算多人工时 >> 903,po82,doing,3,3,3
task状态为pause只有老task计算多人工时 >> 910,,pause,9,12,9
task状态为pause有新老task计算多人工时 >> 910,,pause,9,12,9
task状态为pause只有老task计算多人工时 >> 910,po82,doing,3,3,3
老task不存在的情况有新老task和团队计算多人工时 >> 0
老task不存在的情况有新老task计算多人工时 >> 0
新task不存在的情况有新老task和团队计算多人工时 >> 10001,po82,doing,3,3,3
*/
$task1 = new stdclass();
$task1->id = 1;
$task1->status = 'wait';
$task1->assignedTo = '';
$task1->openedBy = '';
$task2 = new stdclass();
$task2->id = 1;
$task2->status = 'wait';
$task2->assignedTo = 'user92';
$task2->openedBy = '';
$task3 = new stdclass();
$task3->id = 903;
$task3->status = 'done';
$task3->assignedTo = '';
$task3->openedBy = '';
$task4 = new stdclass();
$task4->id = 903;
$task4->status = 'done';
$task4->assignedTo = 'po82';
$task4->openedBy = '';
$task5 = new stdclass();
$task5->id = 910;
$task5->status = 'pause';
$task5->assignedTo = '';
$task5->openedBy = '';
$task6 = new stdclass();
$task6->id = 910;
$task6->status = 'pause';
$task6->assignedTo = '';
$task6->openedBy = '';
$task7 = new stdclass();
$task7->id = 100001;
$task7->status = 'done';
$task7->assignedTo = '';
$task7->openedBy = '';
$task8 = new stdclass();
$task8->id = 10001;
$task8->status = 'wait';
$task8->assignedTo = '';
$task8->openedBy = '';
$user1 = new stdclass();
$user1->account = 'po82';
$user1->estimate = 1;
$user1->consumed = 1;
$user1->left = 1;
$user2 = new stdclass();
$user2->account = 'user93';
$user2->estimate = 2;
$user2->consumed = 2;
$user2->left = 2;
$team = array('po82' => $user1, 'user93' => $user2);
$autoStatusList = array(true, false);
$task = new taskTest();
r($task->computeHours4MultipleTest($task1)) && p('id,assignedTo,status,estimate,consumed,left') && e('1,po82,wait,3,3,3'); // task状态为wait只有老task计算多人工时
r($task->computeHours4MultipleTest($task1, $task2)) && p('id,assignedTo,status,estimate,consumed,left') && e('1,po82,wait,3,3,3'); // task状态为wait有新老task计算多人工时
r($task->computeHours4MultipleTest($task1, $task2, $team)) && p('id,assignedTo,status,estimate,consumed,left') && e('1,po82,doing,3,3,3'); // task状态为wait有新老task和团队计算多人工时
r($task->computeHours4MultipleTest($task3)) && p('id,assignedTo,status,estimate,consumed,left') && e('903,po82,done,3,3,3'); // task状态为done只有老task计算多人工时
r($task->computeHours4MultipleTest($task3, $task4)) && p('id,assignedTo,status,estimate,consumed,left') && e('903,po82,done,3,3,3'); // task状态为done有新老task计算多人工时
r($task->computeHours4MultipleTest($task3, $task4, $team)) && p('id,assignedTo,status,estimate,consumed,left') && e('903,po82,doing,3,3,3'); // task状态为done有新老task和团队计算多人工时
r($task->computeHours4MultipleTest($task5)) && p('id,assignedTo,status,estimate,consumed,left') && e('910,,pause,9,12,9'); // task状态为pause只有老task计算多人工时
r($task->computeHours4MultipleTest($task5, $task1, array(), false)) && p('id,assignedTo,status,estimate,consumed,left') && e('910,,pause,9,12,9'); // task状态为pause有新老task计算多人工时
r($task->computeHours4MultipleTest($task5, $task6, $team)) && p('id,assignedTo,status,estimate,consumed,left') && e('910,po82,doing,3,3,3'); // task状态为pause只有老task计算多人工时
r($task->computeHours4MultipleTest($task7)) && p('id,assignedTo,status,estimate,consumed,left') && e('0'); // 老task不存在的情况有新老task和团队计算多人工时
r($task->computeHours4MultipleTest($task7, $task8)) && p('id,assignedTo,status,estimate,consumed,left') && e('0'); // 老task不存在的情况有新老task计算多人工时
r($task->computeHours4MultipleTest($task1, $task8, $team)) && p('id,assignedTo,status,estimate,consumed,left') && e('10001,po82,doing,3,3,3'); // 新task不存在的情况有新老task和团队计算多人工时
system("./ztest init");
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/task.class.php';
su('admin');
/**
title=taskModel->computeWorkingHours();
cid=1
pid=1
根据taskID计算没有子任务的计划工时 >> 1,0,3,0
根据taskID计算有子任务的父任务工时 >> 601,18,30,18
根据不存在的taskID计算工时 >> 0
*/
$taskIDList = array('1', '601', '100001');
$task = new taskTest();
r($task->computeWorkingHoursTest($taskIDList[0])) && p('id,estimate,consumed,left') && e('1,0,3,0'); //根据taskID计算没有子任务的计划工时
r($task->computeWorkingHoursTest($taskIDList[1])) && p('id,estimate,consumed,left') && e('601,18,31,13'); //根据taskID计算有父任务的子任务工时
r($task->computeWorkingHoursTest($taskIDList[2])) && p('id,estimate,consumed,left') && e('0'); //根据不存在的taskID计算工时
system("./ztest init");
+49
View File
@@ -0,0 +1,49 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/task.class.php';
su('admin');
/**
title=taskModel->createTaskFromGitlabIssue();
cid=1
pid=1
测试正常的创建开发任务 >> gitlab中新建的问题01
测试正常的创建开发任务 >> 101
测试正常的创建开发任务 >> 11
测试不输入执行创建开务 >> 『所属执行』不能为空。
测试不输入名称创建任务 >> 『任务名称』不能为空。
*/
$executionID = 101;
$task1 = new stdclass();
$task1->name = 'gitlab中新建的问题01';
$task1->execution = $executionID;
$task2 = new stdclass();
$task2->name = 'gitlab中新建的问题02';
$task2->execution = $executionID;
$task3 = new stdclass();
$task3->name = 'gitlab中新建的问题03';
$task3->execution = $executionID;
$task4 = new stdclass();
$task4->name = 'gitlab中新建的问题04';
$task4->execution = '';
$task5 = new stdclass();
$task5->name = '';
$task5->execution = $executionID;
$task = new taskTest();
r($task->createTaskFromGitlabIssueTest($task1, $executionID)) && p('name') && e('gitlab中新建的问题01'); // 测试正常的创建开发任务
r($task->createTaskFromGitlabIssueTest($task2, $executionID)) && p('execution') && e('101'); // 测试正常的创建开发任务
r($task->createTaskFromGitlabIssueTest($task3, $executionID)) && p('project') && e('11'); // 测试正常的创建开发任务
r($task->createTaskFromGitlabIssueTest($task4, $executionID)) && p('execution:0') && e('『所属执行』不能为空。'); // 测试不输入执行创建任务
r($task->createTaskFromGitlabIssueTest($task5, $executionID)) && p('name:0') && e('『任务名称』不能为空。'); // 测试不输入名称创建任务
system("./ztest init");
+3 -3
View File
@@ -11,7 +11,7 @@ cid=1
pid=1
根据执行id获取任务列表 >> 开发任务11
根据执行id获取任务数量 >> 1
根据执行id获取任务数量 >> 4
*/
@@ -20,5 +20,5 @@ $count = array('0','1');
$task = new taskTest();
r($task->getExecutionTasksTest($executionID,$count[0])) && p('1:name') && e('开发任务11'); //根据执行id获取任务列表
r($task->getExecutionTasksTest($executionID,$count[1])) && p() && e('1'); //根据执行id获取任务数量
system("./ztest init");
r($task->getExecutionTasksTest($executionID,$count[1])) && p() && e('4'); //根据执行id获取任务数量
system("./ztest init");
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/task.class.php';
su('admin');
/**
title=taskModel->getProjectID();
cid=1
pid=1
根据executionID查找projectID >> 11
*/
$executionID = '101';
$task = new taskTest();
r($task->getProjectIDTest($executionID)) && p('project') && e('11'); //根据executionID查找projectID
system("./ztest init");
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/task.class.php';
su('admin');
/**
title=taskModel->getStoryComments();
cid=1
pid=1
根据storyID查找comment >> 这是一个系统日志测试备注2
根据storyID查找comment >> 0
*/
$storyIDList = array(2, 1000001);
$task = new taskTest();
r($task->getStoryCommentsTest($storyIDList[0])) && p('0:comment') && e('这是一个系统日志测试备注2'); //根据storyID查找comment
r($task->getStoryCommentsTest($storyIDList[1])) && p('0:comment') && e('0'); //根据不存在的storyID查找comment
system("./ztest init");
+4 -4
View File
@@ -10,7 +10,7 @@ title=taskModel->getTasksByModule();
cid=1
pid=1
根据模块获取任务列表 >> 开发任务11
根据模块获取任务列表 >> 子任务10
根据模块获取任务数量 >> 1
*/
@@ -21,6 +21,6 @@ $moduleIdList = '21';
$count = array('0','1');
$task = new taskTest();
r($task->getTasksByModuleTest($executionID,$moduleIdList,$count[0])) && p('0:name') && e('开发任务11'); //根据模块获取任务列表
r($task->getTasksByModuleTest($executionID,$moduleIdList,$count[1])) && p() && e('1'); //根据模块获取任务数量
system("./ztest init");
r($task->getTasksByModuleTest($executionID,$moduleIdList,$count[0])) && p('0:name') && e('子任务10'); //根据模块获取任务列表
r($task->getTasksByModuleTest($executionID,$moduleIdList,$count[1])) && p() && e('1'); //根据模块获取任务数量
system("./ztest init");
+1
View File
@@ -24,6 +24,7 @@ switch($argv[1])
break;
case 'task':
ztfRun('model/task');
break;
case 'execution':
ztfRun('model/execution');
break;
+13
View File
@@ -0,0 +1,13 @@
if(!empty($moduleExtPaths))
{
$extActionFile = $moduleExtPaths['common'] . $methodName . '.php';
if(file_exists($extActionFile))
{
$control = $extActionFile;
}
else
{
$extActionFile = $moduleExtPaths['xuan'] . $methodName . '.php';
if(file_exists($extActionFile)) $control = $extActionFile;
}
}
+3
View File
@@ -34,6 +34,7 @@ foreach(array('zh-cn', 'en') as $langType)
foreach(array('5.3_5.6', '7.0', '7.1', '7.2_7.4') as $phpVersion)
{
echo "zip $packPrefix.{$version}.php{$phpVersion}.zip\n";
`unzip $packPrefix.{$version}.zip`;
`unzip zentaobiz.php{$phpVersion}.zip`;
`unzip zentaomax.php{$phpVersion}.zip`;
@@ -52,6 +53,7 @@ foreach(array('zh-cn', 'en') as $langType)
//
// foreach(array('5.3_5.6', '7.0', '7.1', '7.2_7.4') as $phpVersion)
// {
// echo "dpkg {$packPrefix}_{$version}_{$phpVersion}_1_all.deb\n";
// `mkdir buildroot`;
// `cp -r build/debian/DEBIAN buildroot`;
// `sed -i '/^Version/cVersion: $version' buildroot/DEBIAN/control`;
@@ -74,6 +76,7 @@ foreach(array('zh-cn', 'en') as $langType)
//
// foreach(array('5.3_5.6', '7.0', '7.1', '7.2_7.4') as $phpVersion)
// {
// echo "rpmbuild {$dirName}-{$version}-php{$phpVersion}-1.noarch.rpm\n";
// `mkdir ~/rpmbuild/SPECS -p`;
// `mkdir ~/rpmbuild/SOURCES`;
// `mkdir ~/rpmbuild/SOURCES/etc/httpd/conf.d/ -p`;
@@ -1,4 +1,5 @@
<?php
helper::import('../../control.php');
class myClient extends client
{
public function create()
@@ -1,4 +1,5 @@
<?php
helper::import('../../control.php');
class myClient extends client
{
public function edit($clientID)
@@ -1,4 +1,5 @@
<?php
helper::import('../../control.php');
class myIm extends im
{
/**
@@ -1,4 +1,5 @@
<?php
helper::import('../../control.php');
class myIm extends im
{
public function downloadXxdPackage($xxdFileName)
@@ -1,5 +1,6 @@
<?php
class myIm extends im
helper::import('../../control.php');
class myIm extends im
{
/**
* Get serverInfo api.
@@ -1,5 +1,6 @@
<?php
class myIm extends im
helper::import('../../control.php');
class myIm extends im
{
public function userLogin($account = '', $password = '', $options = 0, $userID = 0, $version = '', $device = 'desktop')
{