This commit is contained in:
holan20180123
2021-08-13 08:12:17 +08:00
53 changed files with 532 additions and 132 deletions
+2
View File
@@ -1,2 +1,4 @@
ALTER TABLE `zt_testtask` ADD `realFinishedDate` datetime NOT NULL AFTER `end`;
ALTER TABLE `zt_doc` ADD `tempContent` longtext NOT NULL AFTER `views`;
ALTER TABLE `zt_release` ADD `mailto` text AFTER `desc`;
ALTER TABLE `zt_release` ADD `notify` varchar(255) AFTER `mailto`;
+2
View File
@@ -769,6 +769,8 @@ CREATE TABLE IF NOT EXISTS `zt_release` (
`bugs` text NOT NULL,
`leftBugs` text NOT NULL,
`desc` text NOT NULL,
`mailto` text,
`notify` varchar(255),
`status` varchar(20) NOT NULL default 'normal',
`subStatus` varchar(30) NOT NULL default '',
`deleted` enum('0','1') NOT NULL default '0',
+1
View File
@@ -310,6 +310,7 @@ $lang->action->dynamicAction->story['opened'] = 'Create Story';
$lang->action->dynamicAction->story['edited'] = 'Edit Story';
$lang->action->dynamicAction->story['activated'] = 'Activate Story';
$lang->action->dynamicAction->story['reviewed'] = 'Review Story';
$lang->action->dynamicAction->story['recalled'] = 'Revoke';
$lang->action->dynamicAction->story['closed'] = 'Close Story';
$lang->action->dynamicAction->story['assigned'] = 'Assign Story';
$lang->action->dynamicAction->story['changed'] = 'Change Story';
+1
View File
@@ -316,6 +316,7 @@ $lang->action->dynamicAction->story['opened'] = 'Create Story';
$lang->action->dynamicAction->story['edited'] = 'Edit Story';
$lang->action->dynamicAction->story['activated'] = 'Activate Story';
$lang->action->dynamicAction->story['reviewed'] = 'Review Story';
$lang->action->dynamicAction->story['recalled'] = 'Revoke';
$lang->action->dynamicAction->story['closed'] = 'Close Story';
$lang->action->dynamicAction->story['assigned'] = 'Assign Story';
$lang->action->dynamicAction->story['changed'] = 'Change Story';
+1
View File
@@ -310,6 +310,7 @@ $lang->action->dynamicAction->story['opened'] = 'Créer Story';
$lang->action->dynamicAction->story['edited'] = 'Editer Story';
$lang->action->dynamicAction->story['activated'] = 'Activer Story';
$lang->action->dynamicAction->story['reviewed'] = 'Consulter Story';
$lang->action->dynamicAction->story['recalled'] = 'Revoke';
$lang->action->dynamicAction->story['closed'] = 'Fermer Story';
$lang->action->dynamicAction->story['assigned'] = 'Assigner Story';
$lang->action->dynamicAction->story['changed'] = 'Changer Story';
+1
View File
@@ -310,6 +310,7 @@ $lang->action->dynamicAction->story['opened'] = 'Tạo câu chuy
$lang->action->dynamicAction->story['edited'] = 'Sửa câu chuyện';
$lang->action->dynamicAction->story['activated'] = 'Kích hoạt câu chuyện';
$lang->action->dynamicAction->story['reviewed'] = 'Duyệt câu chuyện';
$lang->action->dynamicAction->story['recalled'] = 'Revoke';
$lang->action->dynamicAction->story['closed'] = 'Đóng câu chuyện';
$lang->action->dynamicAction->story['assigned'] = 'Bàn giao câu chuyện';
$lang->action->dynamicAction->story['changed'] = 'Thay đổi câu chuyện';
+1
View File
@@ -316,6 +316,7 @@ $lang->action->dynamicAction->story['opened'] = "创建{$lang->SR
$lang->action->dynamicAction->story['edited'] = "编辑{$lang->SRCommon}";
$lang->action->dynamicAction->story['activated'] = "激活{$lang->SRCommon}";
$lang->action->dynamicAction->story['reviewed'] = "评审{$lang->SRCommon}";
$lang->action->dynamicAction->story['recalled'] = "撤销评审";
$lang->action->dynamicAction->story['closed'] = "关闭{$lang->SRCommon}";
$lang->action->dynamicAction->story['assigned'] = "指派{$lang->SRCommon}";
$lang->action->dynamicAction->story['changed'] = "变更{$lang->SRCommon}";
+1
View File
@@ -316,6 +316,7 @@ $lang->action->dynamicAction->story['opened'] = "創建{$lang->SR
$lang->action->dynamicAction->story['edited'] = "編輯{$lang->SRCommon}";
$lang->action->dynamicAction->story['activated'] = "激活{$lang->SRCommon}";
$lang->action->dynamicAction->story['reviewed'] = "評審{$lang->SRCommon}";
$lang->action->dynamicAction->story['recalled'] = '撤銷評審';
$lang->action->dynamicAction->story['closed'] = "關閉{$lang->SRCommon}";
$lang->action->dynamicAction->story['assigned'] = "指派{$lang->SRCommon}";
$lang->action->dynamicAction->story['changed'] = "變更{$lang->SRCommon}";
-1
View File
@@ -395,7 +395,6 @@ class buildModel extends model
$oldBuild = $this->dao->select('*')->from(TABLE_BUILD)->where('id')->eq($buildID)->fetch();
$build = fixer::input('post')->stripTags($this->config->build->editor->edit['id'], $this->config->allowedTags)
->setDefault('product', $oldBuild->product)
->setDefault('branch', $oldBuild->branch)
->cleanInt('product,branch,execution')
->remove('allchecker,resolvedBy,files,labels,uid')
->get();
+1 -1
View File
@@ -41,7 +41,7 @@ class execution extends control
$this->loadModel('project');
$this->executions = $this->execution->getPairs(0, 'all', 'nocode');
if(!in_array($this->methodName, array('computeburn', 'ajaxgetdropmenu', 'executionkanban')) and $this->app->openApp == 'execution')
if(!in_array($this->methodName, array('computeburn', 'ajaxgetdropmenu', 'executionkanban', 'ajaxgetteammembers')) and $this->app->openApp == 'execution')
{
if(!$this->executions and $this->methodName != 'index' and $this->methodName != 'create' and $this->app->getViewType() != 'mhtml') $this->locate($this->createLink('execution', 'create'));
}
+1 -1
View File
@@ -53,7 +53,7 @@ $(function()
});
})
$('#teams').change();
if(copyExecutionID != 0) $('#teams').change();
});
function showLifeTimeTips()
+1
View File
@@ -36,6 +36,7 @@
<?php js::set('errorSameProducts', $lang->execution->errorSameProducts);?>
<?php js::set('productID', empty($productID) ? 0 : $productID);?>
<?php js::set('isStage', false);?>
<?php js::set('copyExecutionID', $copyExecutionID);?>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
+40 -38
View File
@@ -424,26 +424,27 @@ $lang->branch->methodOrder[10] = 'delete';
/* Story. */
$lang->resource->story = new stdclass();
$lang->resource->story->create = 'create';
$lang->resource->story->batchCreate = 'batchCreate';
$lang->resource->story->edit = 'editAction';
$lang->resource->story->linkStory = 'linkStory';
$lang->resource->story->batchEdit = 'batchEdit';
$lang->resource->story->export = 'exportAction';
$lang->resource->story->delete = 'deleteAction';
$lang->resource->story->view = 'view';
$lang->resource->story->change = 'changeAction';
$lang->resource->story->review = 'reviewAction';
$lang->resource->story->batchReview = 'batchReview';
$lang->resource->story->assignTo = 'assignAction';
$lang->resource->story->close = 'closeAction';
$lang->resource->story->batchClose = 'batchClose';
$lang->resource->story->activate = 'activateAction';
$lang->resource->story->tasks = 'tasks';
$lang->resource->story->bugs = 'bugs';
$lang->resource->story->cases = 'cases';
$lang->resource->story->zeroCase = 'zeroCase';
$lang->resource->story->report = 'reportAction';
$lang->resource->story->create = 'create';
$lang->resource->story->batchCreate = 'batchCreate';
$lang->resource->story->edit = 'editAction';
$lang->resource->story->linkStory = 'linkStory';
$lang->resource->story->batchEdit = 'batchEdit';
$lang->resource->story->export = 'exportAction';
$lang->resource->story->delete = 'deleteAction';
$lang->resource->story->view = 'view';
$lang->resource->story->change = 'changeAction';
$lang->resource->story->review = 'reviewAction';
$lang->resource->story->batchReview = 'batchReview';
$lang->resource->story->recall = 'recall';
$lang->resource->story->assignTo = 'assignAction';
$lang->resource->story->close = 'closeAction';
$lang->resource->story->batchClose = 'batchClose';
$lang->resource->story->activate = 'activateAction';
$lang->resource->story->tasks = 'tasks';
$lang->resource->story->bugs = 'bugs';
$lang->resource->story->cases = 'cases';
$lang->resource->story->zeroCase = 'zeroCase';
$lang->resource->story->report = 'reportAction';
$lang->resource->story->batchChangePlan = 'batchChangePlan';
$lang->resource->story->batchChangeBranch = 'batchChangeBranch';
$lang->resource->story->batchChangeStage = 'batchChangeStage';
@@ -462,24 +463,25 @@ $lang->story->methodOrder[30] = 'view';
$lang->story->methodOrder[35] = 'change';
$lang->story->methodOrder[40] = 'review';
$lang->story->methodOrder[45] = 'batchReview';
$lang->story->methodOrder[50] = 'close';
$lang->story->methodOrder[55] = 'batchClose';
$lang->story->methodOrder[60] = 'batchChangePlan';
$lang->story->methodOrder[65] = 'batchChangeStage';
$lang->story->methodOrder[70] = 'assignTo';
$lang->story->methodOrder[75] = 'batchAssignTo';
$lang->story->methodOrder[80] = 'activate';
$lang->story->methodOrder[85] = 'tasks';
$lang->story->methodOrder[90] = 'bugs';
$lang->story->methodOrder[95] = 'cases';
$lang->story->methodOrder[100] = 'zeroCase';
$lang->story->methodOrder[105] = 'report';
$lang->story->methodOrder[110] = 'linkStory';
$lang->story->methodOrder[115] = 'batchChangeBranch';
$lang->story->methodOrder[120] = 'batchChangeModule';
$lang->story->methodOrder[125] = 'batchToTask';
$lang->story->methodOrder[130] = 'track';
$lang->story->methodOrder[135] = 'processStoryChange';
$lang->story->methodOrder[50] = 'recall';
$lang->story->methodOrder[55] = 'close';
$lang->story->methodOrder[60] = 'batchClose';
$lang->story->methodOrder[65] = 'batchChangePlan';
$lang->story->methodOrder[70] = 'batchChangeStage';
$lang->story->methodOrder[75] = 'assignTo';
$lang->story->methodOrder[80] = 'batchAssignTo';
$lang->story->methodOrder[85] = 'activate';
$lang->story->methodOrder[90] = 'tasks';
$lang->story->methodOrder[95] = 'bugs';
$lang->story->methodOrder[100] = 'cases';
$lang->story->methodOrder[105] = 'zeroCase';
$lang->story->methodOrder[110] = 'report';
$lang->story->methodOrder[115] = 'linkStory';
$lang->story->methodOrder[120] = 'batchChangeBranch';
$lang->story->methodOrder[125] = 'batchChangeModule';
$lang->story->methodOrder[130] = 'batchToTask';
$lang->story->methodOrder[135] = 'track';
$lang->story->methodOrder[140] = 'processStoryChange';
/* Product plan. */
$lang->resource->productplan = new stdclass();
+3
View File
@@ -10,6 +10,7 @@ $config->message->objectTypes['case'] = array('opened', 'edited', 'commen
$config->message->objectTypes['testtask'] = array('opened', 'edited', 'started', 'blocked', 'closed', 'activated');
$config->message->objectTypes['todo'] = array('opened', 'edited');
$config->message->objectTypes['doc'] = array('created', 'edited');
$config->message->objectTypes['release'] = array('opened', 'edited');
$config->message->available = array();
$config->message->available['mail']['story'] = $config->message->objectTypes['story'];
@@ -17,6 +18,7 @@ $config->message->available['mail']['task'] = $config->message->objectTypes[
$config->message->available['mail']['bug'] = $config->message->objectTypes['bug'];
$config->message->available['mail']['testtask'] = array('opened', 'edited', 'closed');
$config->message->available['mail']['doc'] = $config->message->objectTypes['doc'];
$config->message->available['mail']['release'] = $config->message->objectTypes['release'];
$config->message->available['webhook'] = $config->message->objectTypes;
@@ -26,6 +28,7 @@ $config->message->available['message']['task'] = $config->message->objectTyp
$config->message->available['message']['testtask'] = $config->message->objectTypes['testtask'];
$config->message->available['message']['todo'] = $config->message->objectTypes['todo'];
$config->message->available['message']['doc'] = $config->message->objectTypes['doc'];
$config->message->available['message']['release'] = $config->message->objectTypes['release'];
$config->message->typeLink = array();
$config->message->typeLink['mail'] = 'mail|index';
+11
View File
@@ -164,6 +164,17 @@ class messageModel extends model
if(empty($toList) and $objectType == 'todo') $toList = $object->account;
if(empty($toList) and $objectType == 'testtask') $toList = $object->owner;
if(empty($toList) and $objectType == 'meeting') $toList = $object->host . $object->participant;
if(empty($toList) and $objectType == 'release')
{
/* Get notifiy persons. */
$notifyPersons = array();
if(!empty($toList->notify)) $notifyPersons = $this->loadModel('release')->getNotifyPersons($object->notify, $object->product, $object->build);
foreach($notifyPersons as $account)
{
if(strpos($object->mailto . ',', ",{$account},") === false) $toList .= ',' . $account;
}
}
if($toList == 'closed') $toList = '';
return $toList;
+2 -3
View File
@@ -102,9 +102,8 @@ $lang->my->projectLinkList['project-index'] = 'By default, go to the most re
$lang->my->executionLinkList = array();
if($config->systemMode == 'new')
{
$lang->my->executionLinkList['execution-index'] = 'Enter the execution dashboard by default, you can understand all the execution statistics and overview';
$lang->my->executionLinkList['execution-all'] = 'Enter the execution list by default, you can view all executions';
$lang->my->executionLinkList['execution-task'] = 'By default, enter the list of the most recently executed task, and you can view the task information under the current iteration';
$lang->my->executionLinkList['execution-task'] = 'By default, enter the list of the most recently executed task, and you can view the task information under the current iteration';
$lang->my->executionLinkList['execution-executionkanban'] = 'By default, you can enter the execution Kanban to view the execution status of projects in progress';
}
if($config->systemMode == 'classic') $lang->my->executionLinkList['execution-task'] = "By default, enter the list of the most recently {$lang->executionCommon} task, and you can view the task information under the current {$lang->executionCommon}";
+2 -3
View File
@@ -109,9 +109,8 @@ $lang->my->projectLinkList['project-index'] = 'By default, go to the most re
$lang->my->executionLinkList = array();
if($config->systemMode == 'new')
{
$lang->my->executionLinkList['execution-index'] = 'Enter the execution dashboard by default, you can understand all the execution statistics and overview';
$lang->my->executionLinkList['execution-all'] = 'Enter the execution list by default, you can view all executions';
$lang->my->executionLinkList['execution-task'] = 'By default, enter the list of the most recently executed task, and you can view the task information under the current iteration';
$lang->my->executionLinkList['execution-task'] = 'By default, enter the list of the most recently executed task, and you can view the task information under the current iteration';
$lang->my->executionLinkList['execution-executionkanban'] = 'By default, you can enter the execution Kanban to view the execution status of projects in progress';
}
if($config->systemMode == 'classic') $lang->my->executionLinkList['execution-task'] = "By default, enter the list of the most recently {$lang->executionCommon} task, and you can view the task information under the current {$lang->executionCommon}";
+2 -3
View File
@@ -102,9 +102,8 @@ $lang->my->projectLinkList['project-index'] = 'By default, go to the most re
$lang->my->executionLinkList = array();
if($config->systemMode == 'new')
{
$lang->my->executionLinkList['execution-index'] = 'Enter the execution dashboard by default, you can understand all the execution statistics and overview';
$lang->my->executionLinkList['execution-all'] = 'Enter the execution list by default, you can view all executions';
$lang->my->executionLinkList['execution-task'] = 'By default, enter the list of the most recently executed task, and you can view the task information under the current iteration';
$lang->my->executionLinkList['execution-task'] = 'By default, enter the list of the most recently executed task, and you can view the task information under the current iteration';
$lang->my->executionLinkList['execution-executionkanban'] = 'By default, you can enter the execution Kanban to view the execution status of projects in progress';
}
if($config->systemMode == 'classic') $lang->my->executionLinkList['execution-task'] = "By default, enter the list of the most recently {$lang->executionCommon} task, and you can view the task information under the current {$lang->executionCommon}";
+2 -3
View File
@@ -102,9 +102,8 @@ $lang->my->projectLinkList['project-index'] = 'By default, go to the most re
$lang->my->executionLinkList = array();
if($config->systemMode == 'new')
{
$lang->my->executionLinkList['execution-index'] = 'Enter the execution dashboard by default, you can understand all the execution statistics and overview';
$lang->my->executionLinkList['execution-all'] = 'Enter the execution list by default, you can view all executions';
$lang->my->executionLinkList['execution-task'] = 'By default, enter the list of the most recently executed task, and you can view the task information under the current iteration';
$lang->my->executionLinkList['execution-task'] = 'By default, enter the list of the most recently executed task, and you can view the task information under the current iteration';
$lang->my->executionLinkList['execution-executionkanban'] = 'By default, you can enter the execution Kanban to view the execution status of projects in progress';
}
if($config->systemMode == 'classic') $lang->my->executionLinkList['execution-task'] = "By default, enter the list of the most recently {$lang->executionCommon} task, and you can view the task information under the current {$lang->executionCommon}";
+1 -1
View File
@@ -110,7 +110,7 @@ $lang->my->executionLinkList = array();
if($config->systemMode == 'new')
{
$lang->my->executionLinkList['execution-task'] = '默认进入最近一个执行的任务列表,可以查看当前迭代下的任务信息';
$lang->my->executionLinkList['execution-executionkanban'] = '默认进入执行看板,可以查看所有项目的执行情况';
$lang->my->executionLinkList['execution-executionkanban'] = '默认进入执行看板,可以查看进行中项目的执行情况';
}
if($config->systemMode == 'classic') $lang->my->executionLinkList['execution-task'] = "默认进入最近一个{$lang->executionCommon}的任务列表,可以查看当前{$lang->executionCommon}下的任务信息";
+2 -3
View File
@@ -109,9 +109,8 @@ $lang->my->projectLinkList['project-index'] = '預設進入最近一個項
$lang->my->executionLinkList = array();
if($config->systemMode == 'new')
{
$lang->my->executionLinkList['execution-task'] = '預設進入最近一個執行的任務列表,可以查看當前迭代下的任務信息';
$lang->my->executionLinkList['execution-index'] = '預設進入執行儀表盤,可以瞭解所有執行的統計數據和概況';
$lang->my->executionLinkList['execution-all'] = '預設進入執行列表,可以查看所有的執行';
$lang->my->executionLinkList['execution-task'] = '預設進入最近一個執行的任務列表,可以查看當前迭代下的任務信息';
$lang->my->executionLinkList['execution-executionkanban'] = '默認進入執行看板,可以查看進行中項目的執行情况';
}
if($config->systemMode == 'classic') $lang->my->executionLinkList['execution-task'] = "預設進入最近一個{$lang->executionCommon}的任務列表,可以查看當前{$lang->executionCommon}下的任務信息";
+6 -5
View File
@@ -65,7 +65,7 @@
<th class='c-hours'> <?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
<th class='c-status'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-stage'> <?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stageAB);?></th>
<th class='c-actions-5'> <?php echo $lang->actions;?></th>
<th class='c-actions-6'> <?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
@@ -99,10 +99,11 @@
if($canBeChanged)
{
$vars = "story={$story->id}";
echo common::buildIconButton('story', 'change', $vars, $story, 'list', 'alter', '', 'iframe', true);
echo common::buildIconButton('story', 'review', $vars, $story, 'list', 'search', '', 'iframe', true);
echo common::buildIconButton('story', 'close', $vars, $story, 'list', '', '', 'iframe', true);
echo common::buildIconButton('story', 'edit', $vars, $story, 'list', '', '', 'iframe', true, "data-width='95%'");
echo common::buildIconButton('story', 'change', $vars, $story, 'list', 'alter', '', 'iframe', true);
echo common::buildIconButton('story', 'review', $vars, $story, 'list', 'search', '', 'iframe', true);
echo common::buildIconButton('story', 'recall', $vars, $story, 'list', 'back', 'hiddenwin', '', '', '', $lang->story->recall);
echo common::buildIconButton('story', 'close', $vars, $story, 'list', '', '', 'iframe', true);
echo common::buildIconButton('story', 'edit', $vars, $story, 'list', '', '', 'iframe', true, "data-width='95%'");
}
?>
</td>
+6 -5
View File
@@ -66,7 +66,7 @@
<th class='c-hours'> <?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
<th class='c-status'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-stage'> <?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stageAB);?></th>
<th class='c-actions-5'> <?php echo $lang->actions;?></th>
<th class='c-actions-6'> <?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
@@ -101,10 +101,11 @@
if($canBeChanged)
{
$vars = "story={$story->id}";
echo common::buildIconButton('story', 'change', $vars, $story, 'list', 'alter', '', 'iframe', true);
echo common::buildIconButton('story', 'review', $vars, $story, 'list', 'search', '', 'iframe', true);
echo common::buildIconButton('story', 'close', $vars, $story, 'list', '', '', 'iframe', true);
echo common::buildIconButton('story', 'edit', $vars, $story, 'list', '', '', 'iframe', true, "data-width='95%'");
echo common::buildIconButton('story', 'change', $vars, $story, 'list', 'alter', '', 'iframe', true);
echo common::buildIconButton('story', 'review', $vars, $story, 'list', 'search', '', 'iframe', true);
echo common::buildIconButton('story', 'recall', $vars, $story, 'list', 'back', 'hiddenwin', '', '', '', $lang->story->recall);
echo common::buildIconButton('story', 'close', $vars, $story, 'list', '', '', 'iframe', true);
echo common::buildIconButton('story', 'edit', $vars, $story, 'list', '', '', 'iframe', true, "data-width='95%'");
echo common::buildIconButton('story', 'createCase', "productID=$story->product&branch=$story->branch&module=0&from=&param=0&$vars", $story, 'list', 'sitemap', '', 'iframe', true, "data-width='95%'");
}
?>
+1
View File
@@ -39,6 +39,7 @@ function addItem(obj)
*/
function deleteItem(obj)
{
if($('.table').find('.addedItem').length <= 1) return;
$(obj).closest('tr').remove();
}
+20 -7
View File
@@ -98,6 +98,8 @@ class projectrelease extends control
*/
public function create($projectID)
{
/* Load module and config. */
$this->loadModel('build');
$this->app->loadConfig('release');
$this->config->projectrelease->create = $this->config->release->create;
@@ -114,9 +116,7 @@ class projectrelease extends control
}
/* Get the builds that can select. */
$productPairs = $this->loadModel('product')->getProductPairsByProject($projectID);
$productIdList = array_keys($productPairs);
$builds = $this->loadModel('build')->getProductBuildPairs($productIdList, 0, 0, 'notrunk');
$builds = $this->build->getProjectBuildPairs($projectID, 0, 0, 'notrunk|withbranch');
$releaseBuilds = $this->projectrelease->getReleaseBuilds($projectID);
foreach($releaseBuilds as $build) unset($builds[$build]);
unset($builds['trunk']);
@@ -128,6 +128,7 @@ class projectrelease extends control
$this->view->position[] = $this->lang->release->create;
$this->view->builds = $builds;
$this->view->lastRelease = $this->projectrelease->getLast($projectID);
$this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed');
$this->display();
}
@@ -140,6 +141,10 @@ class projectrelease extends control
*/
public function edit($releaseID)
{
/* Load module and config. */
$this->loadModel('story');
$this->loadModel('bug');
$this->loadModel('build');
$this->app->loadConfig('release');
$this->config->projectrelease->create = $this->config->release->create;
@@ -158,15 +163,21 @@ class projectrelease extends control
$this->executeHooks($releaseID);
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('view', "releaseID=$releaseID")));
}
$this->loadModel('story');
$this->loadModel('bug');
$this->loadModel('build');
/* Get release and build. */
$release = $this->projectrelease->getById((int)$releaseID);
$this->commonAction($release->project, $release->product, $release->branch);
$build = $this->build->getById($release->build);
/* Get the builds that can select. */
$builds = $this->build->getProjectBuildPairs($release->project, $release->product, $release->branch, 'notrunk|withbranch');
$releaseBuilds = $this->projectrelease->getReleaseBuilds($release->project);
foreach($releaseBuilds as $releaseBuild)
{
if($releaseBuild != $build->id) unset($builds[$releaseBuild]);
}
unset($builds['trunk']);
/* Set project menu. */
$this->project->setMenu($release->project);
@@ -174,7 +185,9 @@ class projectrelease extends control
$this->view->position[] = $this->lang->release->edit;
$this->view->release = $release;
$this->view->build = $build;
$this->view->builds = $this->loadModel('build')->getProjectBuildPairs($release->project, $release->product, $release->branch, 'notrunk|withbranch');
$this->view->builds = $builds;
$this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed');
$this->display();
}
+1
View File
@@ -0,0 +1 @@
.checkbox-primary {display: inline-block; margin-left: 10px;}
+1
View File
@@ -1,3 +1,4 @@
.table-form > tbody > tr > td > .row > [class*="col-"] .panel-heading {line-height: 16px;}
.contentDiv {height: 190px; overflow-y: auto; margin-bottom: 10px !important;}
.contentDiv .panel-heading {line-height: 14px;}
.checkbox-primary {display: inline-block; margin-left: 10px;}
+20
View File
@@ -102,6 +102,7 @@ class projectreleaseModel extends model
*/
public function create()
{
/* Init vars. */
$productID = $this->post->product;
$branch = $this->post->branch;
$buildID = 0;
@@ -126,6 +127,8 @@ class projectreleaseModel extends model
->setDefault('stories', '')
->join('stories', ',')
->join('bugs', ',')
->join('mailto', ',')
->join('notify', ',')
->setIF($this->post->build == false, 'build', $buildID)
->setIF($productID, 'product', $productID)
->setIF($branch, 'branch', $branch)
@@ -213,16 +216,20 @@ class projectreleaseModel extends model
*/
public function update($releaseID)
{
/* Init vars. */
$releaseID = (int)$releaseID;
$oldRelease = $this->dao->select('*')->from(TABLE_RELEASE)->where('id')->eq($releaseID)->fetch();
$branch = $this->dao->select('branch')->from(TABLE_BUILD)->where('id')->eq((int)$this->post->build)->fetch('branch');
$release = fixer::input('post')->stripTags($this->config->release->editor->edit['id'], $this->config->allowedTags)
->add('branch', (int)$branch)
->join('mailto', ',')
->join('notify', ',')
->setIF(!$this->post->marker, 'marker', 0)
->cleanInt('product')
->remove('files,labels,allchecker,uid')
->get();
$release = $this->loadModel('file')->processImgURL($release, $this->config->release->editor->edit['id'], $this->post->uid);
$this->dao->update(TABLE_RELEASE)->data($release)
->autoCheck()
@@ -315,4 +322,17 @@ class projectreleaseModel extends model
$this->loadModel('action');
foreach($this->post->bugs as $bugID) $this->action->create('bug', $bugID, 'linked2release', '', $releaseID);
}
/**
* Send mail.
*
* @param int $releaseID
* @param int $actionID
* @access public
* @return void
*/
public function sendmail($releaseID, $actionID)
{
$this->loadModel('release')->sendmail($releaseID, $actionID);
}
}
@@ -59,6 +59,18 @@
<th><?php echo $lang->release->desc;?></th>
<td colspan='2'><?php echo html::textarea('desc', '', "rows='10' class='form-control kindeditor' hidefocus='true'");?></td>
</tr>
<tr>
<th><?php echo $lang->release->notify;?></th>
<td colspan='2'><?php echo html::checkbox('notify', $lang->release->notifyList);?></td>
</tr>
<tr>
<th><?php echo $lang->release->mailto;?></th>
<td colspan='2'>
<div class="input-group">
<?php echo html::select('mailto[]', $users, '', "class='form-control chosen' data-placeholder='{$lang->chooseUsersToMail}' multiple");?>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->files;?></th>
<td colspan='2'><?php echo $this->fetch('file', 'buildform');?></td>
+12
View File
@@ -52,6 +52,18 @@
<th><?php echo $lang->release->desc;?></th>
<td colspan='2'><?php echo html::textarea('desc', htmlspecialchars($release->desc), "rows=10 class='form-control kindeditor' hidefocus='true'");?></td>
</tr>
<tr>
<th><?php echo $lang->release->notify;?></th>
<td colspan='2'><?php echo html::checkbox('notify', $lang->release->notifyList, $release->notify);?></td>
</tr>
<tr>
<th><?php echo $lang->release->mailto;?></th>
<td colspan='2'>
<div class="input-group">
<?php echo html::select('mailto[]', $users, $release->mailto, "class='form-control chosen' data-placeholder='{$lang->chooseUsersToMail}' multiple");?>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->files;?></th>
<td colspan='2'><?php echo $this->fetch('file', 'buildform');?></td>
+12 -1
View File
@@ -85,7 +85,9 @@ class release extends control
$this->view->position[] = $this->lang->release->create;
$this->view->productID = $productID;
$this->view->builds = $builds;
$this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed');
$this->view->lastRelease = $this->release->getLast($productID, $branch);
$this->display();
}
@@ -122,11 +124,20 @@ class release extends control
$this->commonAction($release->product, $release->branch);
$build = $this->build->getById($release->build);
$builds = $this->loadModel('build')->getProductBuildPairs($release->product, $release->branch, 'notrunk|withbranch', false);
$releaseBuilds = $this->release->getReleaseBuilds($release->product, $release->branch);
foreach($releaseBuilds as $releaseBuild)
{
if($releaseBuild != $build->id) unset($builds[$releaseBuild]);
}
unset($builds['trunk']);
$this->view->title = $this->view->product->name . $this->lang->colon . $this->lang->release->edit;
$this->view->position[] = $this->lang->release->edit;
$this->view->release = $release;
$this->view->build = $build;
$this->view->builds = $this->loadModel('build')->getProductBuildPairs($release->product, $release->branch, 'notrunk|withbranch', false);
$this->view->builds = $builds;
$this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed');
$this->display();
}
+1
View File
@@ -0,0 +1 @@
.checkbox-primary {display: inline-block; margin-left: 10px;}
+1
View File
@@ -1,3 +1,4 @@
.table-form > tbody > tr > td > .row > [class*="col-"] .panel-heading {line-height: 16px;}
.contentDiv {height: 190px; overflow-y: auto; margin-bottom: 10px !important;}
.contentDiv .panel-heading {line-height: 14px;}
.checkbox-primary {display: inline-block; margin-left: 10px;}
+8
View File
@@ -56,6 +56,8 @@ $lang->release->createdBugs = 'Erstellte %s Bugs';
$lang->release->export = 'Export as HTML';
$lang->release->yesterday = 'Gestern veröffentlicht';
$lang->release->all = 'All';
$lang->release->notify = 'Notify';
$lang->release->mailto = 'Mailto';
$lang->release->filePath = 'Download : ';
$lang->release->scmPath = 'SCM Pfad : ';
@@ -74,3 +76,9 @@ $lang->release->changeStatusList['terminate'] = 'Terminiert';
$lang->release->action = new stdclass();
$lang->release->action->changestatus = array('main' => '$date, 由 <strong>$actor</strong> $extra。', 'extra' => 'changeStatusList');
$lang->release->notifyList['PO'] = "{$lang->productCommon} Owner";
$lang->release->notifyList['QD'] = 'QA Manager';
$lang->release->notifyList['SC'] = 'Story Creator';
$lang->release->notifyList['ET'] = "{$lang->execution->common} Team Members";
$lang->release->notifyList['PT'] = "Project Team Members";
+8
View File
@@ -56,6 +56,8 @@ $lang->release->createdBugs = 'Unresolved %s Bug';
$lang->release->export = 'Export as HTML';
$lang->release->yesterday = 'Released Yesterday';
$lang->release->all = 'All';
$lang->release->notify = 'Notify';
$lang->release->mailto = 'Mailto';
$lang->release->filePath = 'Download : ';
$lang->release->scmPath = 'SCM Path : ';
@@ -74,3 +76,9 @@ $lang->release->changeStatusList['terminate'] = 'Terminated';
$lang->release->action = new stdclass();
$lang->release->action->changestatus = array('main' => '$date, $extra by <strong>$actor</strong>', 'extra' => 'changeStatusList');
$lang->release->notifyList['PO'] = "{$lang->productCommon} Owner";
$lang->release->notifyList['QD'] = 'QA Manager';
$lang->release->notifyList['SC'] = 'Story Creator';
$lang->release->notifyList['ET'] = "{$lang->execution->common} Team Members";
$lang->release->notifyList['PT'] = "Project Team Members";
+8
View File
@@ -56,6 +56,8 @@ $lang->release->createdBugs = '%s Bugs non résolus';
$lang->release->export = 'Export HTML';
$lang->release->yesterday = 'Versionné Hier';
$lang->release->all = 'Tout';
$lang->release->notify = 'Notify';
$lang->release->mailto = 'Mailto';
$lang->release->filePath = 'Télecharger : ';
$lang->release->scmPath = 'SCM Path : ';
@@ -74,3 +76,9 @@ $lang->release->changeStatusList['terminate'] = 'Terminée';
$lang->release->action = new stdclass();
$lang->release->action->changestatus = array('main' => '$date, $extra par <strong>$actor</strong>', 'extra' => 'changeStatusList');
$lang->release->notifyList['PO'] = "{$lang->productCommon} Owner";
$lang->release->notifyList['QD'] = 'QA Manager';
$lang->release->notifyList['SC'] = 'Story Creator';
$lang->release->notifyList['ET'] = "{$lang->execution->common} Team Members";
$lang->release->notifyList['PT'] = "Project Team Members";
+8
View File
@@ -56,6 +56,8 @@ $lang->release->createdBugs = 'Bug %s chưa được giải quyết';
$lang->release->export = 'Xuất ra HTML';
$lang->release->yesterday = 'Phát hành hôm qua';
$lang->release->all = 'Tất cả';
$lang->release->notify = 'Notify';
$lang->release->mailto = 'Mailto';
$lang->release->filePath = 'Tải về : ';
$lang->release->scmPath = 'SCM Path : ';
@@ -74,3 +76,9 @@ $lang->release->changeStatusList['terminate'] = 'Hoàn thành';
$lang->release->action = new stdclass();
$lang->release->action->changestatus = array('main' => '$date, $extra bởi <strong>$actor</strong>', 'extra' => 'changeStatusList');
$lang->release->notifyList['PO'] = "{$lang->productCommon} Owner";
$lang->release->notifyList['QD'] = 'QA Manager';
$lang->release->notifyList['SC'] = 'Story Creator';
$lang->release->notifyList['ET'] = "{$lang->execution->common} Team Members";
$lang->release->notifyList['PT'] = "Project Team Members";
+8
View File
@@ -56,6 +56,8 @@ $lang->release->createdBugs = '本次共遗留 %s 个Bug';
$lang->release->export = '导出HTML';
$lang->release->yesterday = '昨日发布';
$lang->release->all = '所有';
$lang->release->notify = '通知人员';
$lang->release->mailto = '抄送给';
$lang->release->filePath = '下载地址:';
$lang->release->scmPath = '版本库地址:';
@@ -74,3 +76,9 @@ $lang->release->changeStatusList['terminate'] = '停止维护';
$lang->release->action = new stdclass();
$lang->release->action->changestatus = array('main' => '$date, 由 <strong>$actor</strong> $extra。', 'extra' => 'changeStatusList');
$lang->release->notifyList['PO'] = "{$lang->productCommon}负责人";
$lang->release->notifyList['QD'] = '测试负责人';
$lang->release->notifyList['SC'] = '需求提交人';
$lang->release->notifyList['ET'] = "所在{$lang->execution->common}团队成员";
$lang->release->notifyList['PT'] = "所在项目团队成员";
+158
View File
@@ -110,6 +110,7 @@ class releaseModel extends model
*/
public function create($productID, $branch = 0)
{
/* Init vars. */
$productID = (int)$productID;
$branch = (int)$branch;
$buildID = 0;
@@ -126,6 +127,8 @@ class releaseModel extends model
->setDefault('stories', '')
->join('stories', ',')
->join('bugs', ',')
->join('mailto', ',')
->join('notify', ',')
->setIF($this->post->build == false, 'build', $buildID)
->stripTags($this->config->release->editor->create['id'], $this->config->allowedTags)
->remove('allchecker,files,labels,uid')
@@ -216,16 +219,20 @@ class releaseModel extends model
*/
public function update($releaseID)
{
/* Init vars. */
$releaseID = (int)$releaseID;
$oldRelease = $this->dao->select('*')->from(TABLE_RELEASE)->where('id')->eq($releaseID)->fetch();
$branch = $this->dao->select('branch')->from(TABLE_BUILD)->where('id')->eq((int)$this->post->build)->fetch('branch');
$release = fixer::input('post')->stripTags($this->config->release->editor->edit['id'], $this->config->allowedTags)
->add('branch', (int)$branch)
->join('mailto', ',')
->join('notify', ',')
->setIF(!$this->post->marker, 'marker', 0)
->cleanInt('product')
->remove('files,labels,allchecker,uid')
->get();
$release = $this->loadModel('file')->processImgURL($release, $this->config->release->editor->edit['id'], $this->post->uid);
/* update release project and branch */
@@ -249,6 +256,67 @@ class releaseModel extends model
}
}
/**
* Get notify persons.
*
* @param string $notfiyList
* @param int $productID
* @param int $buildID
* @access public
* @return array
*/
public function getNotifyPersons($notifyList = '', $productID = 0, $buildID = 0)
{
if(empty($notifyList)) return array();
/* Init vars. */
$notifyPersons = array();
$managers = '';
$notifyList = explode($notifyList, ',');
foreach($notifyList as $notify)
{
if($notify == 'PO' or $notify == 'QD' or $notify == 'feedback')
{
$managers .= $notify . ',';
}
elseif($notify == 'SC' and !empty($buildID))
{
$stories = $this->dao->select('stories')->from(TABLE_BUILD)->where('id')->eq($buildID)->fetch('stories');
$stories = trim($stories, ',');
if(empty($stories)) continue;
$createUsers = $this->dao->select('openedBy')->from(TABLE_STORY)->where('id')->in($stories)->fetchPairs();
$notifyPersons += $createUsers;
}
elseif(($notify == 'ET' or $notify == 'PT') and !empty($buildID))
{
$type = $notify == 'ET' ? 'execution' : 'project';
$members = $this->dao->select('t2.account')->from(TABLE_BUILD)->alias('t1')
->leftJoin(TABLE_TEAM)->alias('t2')->on('t1.' . $type .'=t2.root')
->where('t2.type')->eq($type)
->fetchPairs();
if(empty($members)) continue;
$notifyPersons += $members;
}
}
if(!empty($managers))
{
$managers = trim($managers, ',');
$managerUsers = $this->dao->select($managers)->from(TABLE_PRODUCT)->where('id')->eq($productID)->fetch();
foreach($managerUsers as $account)
{
if(!isset($notifyPersons[$account])) $notifyPersons += array($account => $account);
}
}
return $notifyPersons;
}
/**
* Link stories
*
@@ -405,4 +473,94 @@ class releaseModel extends model
$this->dao->update(TABLE_RELEASE)->set('status')->eq($status)->where('id')->eq($releaseID)->exec();
return dao::isError();
}
/**
* Send mail.
*
* @param int $releaseID
* @param int $actionID
* @access public
* @return void
*/
public function sendmail($releaseID, $actionID)
{
$this->loadModel('mail');
$release = $this->getByID($releaseID);
$users = $this->loadModel('user')->getPairs('noletter');
/* Get action info. */
$action = $this->loadModel('action')->getById($actionID);
$history = $this->action->getHistory($actionID);
$action->history = isset($history[$actionID]) ? $history[$actionID] : array();
$action->appendLink = '';
/* Get mail content. */
$modulePath = $this->app->getModulePath($appName = '', 'release');
$oldcwd = getcwd();
$viewFile = $modulePath . 'view/sendmail.html.php';
chdir($modulePath . 'view');
if(file_exists($modulePath . 'ext/view/sendmail.html.php'))
{
$viewFile = $modulePath . 'ext/view/sendmail.html.php';
chdir($modulePath . 'ext/view');
}
ob_start();
include $viewFile;
foreach(glob($modulePath . 'ext/view/sendmail.*.html.hook.php') as $hookFile) include $hookFile;
$mailContent = ob_get_contents();
ob_end_clean();
chdir($oldcwd);
$sendUsers = $this->getToAndCcList($release);
if(!$sendUsers) return;
list($toList, $ccList) = $sendUsers;
$subject = 'RELEASE #' . $release->id . ' ' . $release->name;
/* Send it. */
$this->mail->send($toList, $subject, $mailContent, $ccList);
if($this->mail->isError()) error_log(join("\n", $this->mail->getError()));
}
/**
* Get toList and ccList.
*
* @param object $release
* @access public
* @return bool|array
*/
public function getToAndCcList($release)
{
/* Set toList and ccList. */
$toList = $this->app->user->account;
$ccList = $release->mailto . ',';
/* Get notifiy persons. */
$notifyPersons = array();
if(!empty($release->notify)) $notifyPersons = $this->getNotifyPersons($release->notify, $release->product, $release->build);
foreach($notifyPersons as $account)
{
if(strpos($ccList, ",{$account},") === false) $ccList .= $account . ',';
}
$ccList = trim($ccList, ',');
if(empty($toList))
{
if(empty($ccList)) return false;
if(strpos($ccList, ',') === false)
{
$toList = $ccList;
$ccList = '';
}
else
{
$commaPos = strpos($ccList, ',');
$toList = substr($ccList, 0, $commaPos);
$ccList = substr($ccList, $commaPos + 1);
}
}
return array($toList, $ccList);
}
}
+12
View File
@@ -49,6 +49,18 @@
<th><?php echo $lang->release->desc;?></th>
<td colspan='2'><?php echo html::textarea('desc', '', "rows='10' class='form-control kindeditor' hidefocus='true'");?></td>
</tr>
<tr>
<th><?php echo $lang->release->notify;?></th>
<td colspan='2'><?php echo html::checkbox('notify', $lang->release->notifyList);?></td>
</tr>
<tr>
<th><?php echo $lang->release->mailto;?></th>
<td colspan='2'>
<div class="input-group">
<?php echo html::select('mailto[]', $users, '', "class='form-control chosen' data-placeholder='{$lang->chooseUsersToMail}' multiple");?>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->files;?></th>
<td colspan='2'><?php echo $this->fetch('file', 'buildform');?></td>
+12
View File
@@ -52,6 +52,18 @@
<th><?php echo $lang->release->desc;?></th>
<td colspan='2'><?php echo html::textarea('desc', htmlspecialchars($release->desc), "rows=10 class='form-control kindeditor' hidefocus='true'");?></td>
</tr>
<tr>
<th><?php echo $lang->release->notify;?></th>
<td colspan='2'><?php echo html::checkbox('notify', $lang->release->notifyList, $release->notify);?></td>
</tr>
<tr>
<th><?php echo $lang->release->mailto;?></th>
<td colspan='2'>
<div class="input-group">
<?php echo html::select('mailto[]', $users, $release->mailto, "class='form-control chosen' data-placeholder='{$lang->chooseUsersToMail}' multiple");?>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->files;?></th>
<td colspan='2'><?php echo $this->fetch('file', 'buildform');?></td>
+35
View File
@@ -0,0 +1,35 @@
<?php
/**
* The mail file of release module of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package release
* @version $Id: sendmail.html.php 867 2021-08-12 13:37:58Z $
* @link http://www.zentao.net
*/
?>
<?php $mailTitle = 'RELEASE #' . $release->id . ' ' . $release->name;?>
<?php $module = $this->app->openApp == 'product' ? 'release' : 'projectrelease';?>
<?php include $this->app->getModuleRoot() . 'common/view/mail.header.html.php';?>
<tr>
<td>
<table cellpadding='0' cellspacing='0' width='600' style='border: none; border-collapse: collapse;'>
<tr>
<td style='padding: 10px; background-color: #F8FAFE; border: none; font-size: 14px; font-weight: 500; border-bottom: 1px solid #e5e5e5;'>
<?php echo html::a(zget($this->config->mail, 'domain', common::getSysURL()) . helper::createLink($module, 'view', "releaseID=$release->id", 'html'), $mailTitle, '', "text-decoration: underline;'");?>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style='padding: 10px; border: none;'>
<fieldset style='border: 1px solid #e5e5e5'>
<legend style='color: #114f8e'><?php echo $this->lang->release->desc;?></legend>
<div style='padding:5px;'><?php echo $release->desc;?></div>
</fieldset>
</td>
</tr>
<?php include $this->app->getModuleRoot() . 'common/view/mail.footer.html.php';?>
+1 -1
View File
@@ -199,5 +199,5 @@ $config->story->datatable->fieldList['caseCount']['name'] = $lang->story->ca
$config->story->datatable->fieldList['actions']['title'] = 'actions';
$config->story->datatable->fieldList['actions']['fixed'] = 'right';
$config->story->datatable->fieldList['actions']['width'] = $app->rawModule == 'projectstory' ? '200' : '180';
$config->story->datatable->fieldList['actions']['width'] = '200';
$config->story->datatable->fieldList['actions']['required'] = 'yes';
+15
View File
@@ -1103,6 +1103,21 @@ class story extends control
die(js::reload('parent'));
}
/**
* Recall the story review.
*
* @param int $storyID
* @access public
* @return void
*/
public function recall($storyID)
{
$this->story->recall($storyID);
$this->loadModel('action')->create('story', $storyID, 'Recalled');
die(js::locate('parent.parent'));
}
/**
* Close a story.
*
+2
View File
@@ -27,6 +27,7 @@ $lang->story->changed = 'Geändert';
$lang->story->assignTo = 'Assign';
$lang->story->assignAction = 'Assign Story';
$lang->story->review = 'Prüfen';
$lang->story->recall = 'Revoke';
$lang->story->reviewAction = 'Review Story';
$lang->story->needReview = 'Need Review';
$lang->story->batchReview = 'Mehere prüfen';
@@ -286,6 +287,7 @@ $lang->story->action->reviewed = array('main' => '$date, geprüft v
$lang->story->action->passreviewed = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>Pass</strong>.');
$lang->story->action->clarifyreviewed = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>Review Failed</strong>. Please re-initiate the review after changing.');
$lang->story->action->rejectreviewed = array('main' => '$date, geprüft von <strong>$actor</strong>. Das Ergebnis ist <strong>$extra</strong>, Der Grund ist <strong>$reason</strong>.', 'extra' => 'reviewResultList', 'reason' => 'reasonList');
$lang->story->action->recalled = array('main' => '$date, recalled by <strong>$actor</strong>.');
$lang->story->action->closed = array('main' => '$date, geschlossen von <strong>$actor</strong>. Der Grund ist <strong>$extra</strong> $appendLink.', 'extra' => 'reasonList');
$lang->story->action->reviewclosed = array('main' => '$date, closed by <strong>System</strong>. The reasion is <strong>Review Failed</strong>.');
$lang->story->action->linked2plan = array('main' => '$date, verknüpft von <strong>$actor</strong> mit Plan <strong>$extra</strong>');
+49 -47
View File
@@ -20,53 +20,54 @@ $lang->story->createStory = 'Create ' . $lang->story->story;
$lang->story->createRequirement = 'Create ' . $lang->story->requirement;
$lang->story->affectedStories = "Affected {$lang->story->story}";
$lang->story->batchCreate = "Batch Create";
$lang->story->change = "Change";
$lang->story->changed = 'Change';
$lang->story->assignTo = 'Assign';
$lang->story->review = 'Review';
$lang->story->needReview = 'Need Review';
$lang->story->batchReview = 'Batch Review';
$lang->story->edit = "Edit Story";
$lang->story->batchEdit = "Batch Edit";
$lang->story->subdivide = 'Decompose';
$lang->story->link = 'Link';
$lang->story->unlink = 'Unlink';
$lang->story->track = 'Track';
$lang->story->trackAB = 'Track';
$lang->story->processStoryChange= 'Process Story Change';
$lang->story->splitRequirent = 'Decompose';
$lang->story->close = 'Close';
$lang->story->batchClose = 'Batch Close';
$lang->story->activate = 'Activate';
$lang->story->delete = "Delete";
$lang->story->view = "Story Detail";
$lang->story->setting = "Settings";
$lang->story->tasks = "Linked Tasks";
$lang->story->bugs = "Linked Bugs";
$lang->story->cases = "Linked Cases";
$lang->story->taskCount = 'Tasks';
$lang->story->bugCount = 'Bugs';
$lang->story->caseCount = 'Cases';
$lang->story->taskCountAB = 'T';
$lang->story->bugCountAB = 'B';
$lang->story->caseCountAB = 'C';
$lang->story->linkStory = 'Link Story';
$lang->story->unlinkStory = 'UnLinked';
$lang->story->export = "Export Data";
$lang->story->zeroCase = "Stories without cases";
$lang->story->zeroTask = "Only list stories without tasks";
$lang->story->reportChart = "Report";
$lang->story->copyTitle = "Copy Title";
$lang->story->batchChangePlan = "Batch Change Plans";
$lang->story->batchChangeBranch = "Batch Change Branches";
$lang->story->batchChangeStage = "Batch Change Phases";
$lang->story->batchAssignTo = "Batch Assign";
$lang->story->batchChangeModule = "Batch Change Modules";
$lang->story->viewAll = "See All";
$lang->story->toTask = 'Convert to Task';
$lang->story->batchToTask = 'Batch Convert to Task';
$lang->story->convertRelations = 'Convert Relations';
$lang->story->batchCreate = "Batch Create";
$lang->story->change = "Change";
$lang->story->changed = 'Change';
$lang->story->assignTo = 'Assign';
$lang->story->review = 'Review';
$lang->story->recall = 'Revoke';
$lang->story->needReview = 'Need Review';
$lang->story->batchReview = 'Batch Review';
$lang->story->edit = "Edit Story";
$lang->story->batchEdit = "Batch Edit";
$lang->story->subdivide = 'Decompose';
$lang->story->link = 'Link';
$lang->story->unlink = 'Unlink';
$lang->story->track = 'Track';
$lang->story->trackAB = 'Track';
$lang->story->processStoryChange = 'Process Story Change';
$lang->story->splitRequirent = 'Decompose';
$lang->story->close = 'Close';
$lang->story->batchClose = 'Batch Close';
$lang->story->activate = 'Activate';
$lang->story->delete = "Delete";
$lang->story->view = "Story Detail";
$lang->story->setting = "Settings";
$lang->story->tasks = "Linked Tasks";
$lang->story->bugs = "Linked Bugs";
$lang->story->cases = "Linked Cases";
$lang->story->taskCount = 'Tasks';
$lang->story->bugCount = 'Bugs';
$lang->story->caseCount = 'Cases';
$lang->story->taskCountAB = 'T';
$lang->story->bugCountAB = 'B';
$lang->story->caseCountAB = 'C';
$lang->story->linkStory = 'Link Story';
$lang->story->unlinkStory = 'UnLinked';
$lang->story->export = "Export Data";
$lang->story->zeroCase = "Stories without cases";
$lang->story->zeroTask = "Only list stories without tasks";
$lang->story->reportChart = "Report";
$lang->story->copyTitle = "Copy Title";
$lang->story->batchChangePlan = "Batch Change Plans";
$lang->story->batchChangeBranch = "Batch Change Branches";
$lang->story->batchChangeStage = "Batch Change Phases";
$lang->story->batchAssignTo = "Batch Assign";
$lang->story->batchChangeModule = "Batch Change Modules";
$lang->story->viewAll = "See All";
$lang->story->toTask = 'Convert to Task';
$lang->story->batchToTask = 'Batch Convert to Task';
$lang->story->convertRelations = 'Convert Relations';
$lang->story->editAction = "Edit {$lang->SRCommon}";
$lang->story->changeAction = "Change {$lang->SRCommon}";
@@ -287,6 +288,7 @@ $lang->story->action->reviewed = array('main' => '$date, recorded b
$lang->story->action->passreviewed = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>Pass</strong>.');
$lang->story->action->clarifyreviewed = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>Review Failed</strong>. Please re-initiate the review after changing.');
$lang->story->action->rejectreviewed = array('main' => '$date, recorded by <strong>$actor</strong>. The result is <strong>$extra</strong>. The reasion is <strong>$reason</strong>.', 'extra' => 'reviewResultList', 'reason' => 'reasonList');
$lang->story->action->recalled = array('main' => '$date, recalled by <strong>$actor</strong>.');
$lang->story->action->closed = array('main' => '$date, closed by <strong>$actor</strong>. The reasion is <strong>$extra</strong> $appendLink.', 'extra' => 'reasonList');
$lang->story->action->reviewclosed = array('main' => '$date, closed by <strong>System</strong>. The reasion is <strong>Review Failed</strong>.');
$lang->story->action->linked2plan = array('main' => '$date, linked by <strong>$actor</strong> to Plan <strong>$extra</strong>');
+2
View File
@@ -27,6 +27,7 @@ $lang->story->changed = 'Changée';
$lang->story->assignTo = 'Affecter';
$lang->story->assignAction = 'Affecter Story';
$lang->story->review = 'Valider';
$lang->story->recall = 'Revoke';
$lang->story->reviewAction = 'Valider Story';
$lang->story->needReview = 'Validation requise';
$lang->story->batchReview = 'Validation par lot';
@@ -286,6 +287,7 @@ $lang->story->action->reviewed = array('main' => '$date, validée p
$lang->story->action->passreviewed = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>Pass</strong>.');
$lang->story->action->clarifyreviewed = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>Review Failed</strong>. Please re-initiate the review after changing.');
$lang->story->action->rejectreviewed = array('main' => '$date, validée par <strong>$actor</strong>. Le résultat est <strong>$extra</strong>. La raison est <strong>$reason</strong>.', 'extra' => 'reviewResultList', 'reason' => 'reasonList');
$lang->story->action->recalled = array('main' => '$date, recalled by <strong>$actor</strong>.');
$lang->story->action->closed = array('main' => '$date, Fermée par <strong>$actor</strong>. La raison est <strong>$extra</strong> $appendLink.', 'extra' => 'reasonList');
$lang->story->action->reviewclosed = array('main' => '$date, closed by <strong>System</strong>. The reasion is <strong>Review Failed</strong>.');
$lang->story->action->linked2plan = array('main' => '$date, planifiée par <strong>$actor</strong> au Plan <strong>$extra</strong>');
+2
View File
@@ -27,6 +27,7 @@ $lang->story->changed = "Đã đổi";
$lang->story->assignTo = 'Giao cho';
$lang->story->assignAction = 'Bàn giao câu chuyện';
$lang->story->review = 'Xét duyệt';
$lang->story->recall = 'Revoke';
$lang->story->reviewAction = 'Duyệt câu chuyện';
$lang->story->needReview = 'Duyệt nhu cầu';
$lang->story->batchReview = 'Duyệt hàng loạt';
@@ -286,6 +287,7 @@ $lang->story->action->reviewed = array('main' => '$date, ghi nhận
$lang->story->action->passreviewed = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>Pass</strong>.');
$lang->story->action->clarifyreviewed = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>Review Failed</strong>. Please re-initiate the review after changing.');
$lang->story->action->rejectreviewed = array('main' => '$date, ghi nhận bởi <strong>$actor</strong>. Kết quả là <strong>$extra</strong>. Lý do là <strong>$reason</strong>', 'extra' => 'reviewResultList', 'reason' => 'reasonList');
$lang->story->action->recalled = array('main' => '$date, recalled by <strong>$actor</strong>.');
$lang->story->action->closed = array('main' => '$date, được đóng bởi <strong>$actor</strong>. Lý do là <strong>$extra</strong> $appendLink.', 'extra' => 'reasonList');
$lang->story->action->reviewclosed = array('main' => '$date, closed by <strong>System</strong>. The reasion is <strong>Review Failed</strong>.');
$lang->story->action->linked2plan = array('main' => '$date, liên kết bởi <strong>$actor</strong> tới kế hoạch <strong>$extra</strong>');
+2
View File
@@ -25,6 +25,7 @@ $lang->story->change = "变更";
$lang->story->changed = "{$lang->SRCommon}变更";
$lang->story->assignTo = '指派';
$lang->story->review = '评审';
$lang->story->recall = '撤销评审';
$lang->story->needReview = '需要评审';
$lang->story->batchReview = '批量评审';
$lang->story->edit = "编辑";
@@ -287,6 +288,7 @@ $lang->story->action->reviewed = array('main' => '$date, 由 <stron
$lang->story->action->passreviewed = array('main' => '$date, 由 <strong>系统</strong> 判定,结果为 <strong>确认通过</strong>。');
$lang->story->action->clarifyreviewed = array('main' => '$date, 由 <strong>系统</strong> 判定,结果为 <strong>评审不通过</strong>,请变更后重新发起评审。');
$lang->story->action->rejectreviewed = array('main' => '$date, 由 <strong>$actor</strong> 记录评审结果,结果为 <strong>$extra</strong>,原因为 <strong>$reason</strong>。', 'extra' => 'reviewResultList', 'reason' => 'reasonList');
$lang->story->action->recalled = array('main' => '$date, 由 <strong>$actor</strong> 撤销评审。');
$lang->story->action->closed = array('main' => '$date, 由 <strong>$actor</strong> 关闭,原因为 <strong>$extra</strong> $appendLink。', 'extra' => 'reasonList');
$lang->story->action->reviewclosed = array('main' => '$date, 由 <strong>系统</strong> 关闭,原因为 <strong>评审失败</strong>。');
$lang->story->action->linked2plan = array('main' => '$date, 由 <strong>$actor</strong> 关联到计划 <strong>$extra</strong>。');
+2
View File
@@ -25,6 +25,7 @@ $lang->story->change = "變更";
$lang->story->changed = "{$lang->SRCommon}變更";
$lang->story->assignTo = '指派';
$lang->story->review = '評審';
$lang->story->recall = '撤銷評審';
$lang->story->needReview = '需要評審';
$lang->story->batchReview = '批量評審';
$lang->story->edit = "編輯";
@@ -287,6 +288,7 @@ $lang->story->action->reviewed = array('main' => '$date, 由 <stron
$lang->story->action->passreviewed = array('main' => '$date, 由 <strong>系統</strong> 判定,結果為 <strong>確認通過</strong>。');
$lang->story->action->clarifyreviewed = array('main' => '$date, 由 <strong>系統</strong> 判定,結果為 <strong>評審不通過</strong>,請變更後重新發起評審。');
$lang->story->action->rejectreviewed = array('main' => '$date, 由 <strong>$actor</strong> 記錄評審結果,結果為 <strong>$extra</strong>,原因為 <strong>$reason</strong>。', 'extra' => 'reviewResultList', 'reason' => 'reasonList');
$lang->story->action->recalled = array('main' => '$date, 由 <strong>$actor</strong> 撤銷評審。');
$lang->story->action->closed = array('main' => '$date, 由 <strong>$actor</strong> 關閉,原因為 <strong>$extra</strong> $appendLink。', 'extra' => 'reasonList');
$lang->story->action->reviewclosed = array('main' => '$date, 由 <strong>系統</strong> 關閉,原因為 <strong>評審失敗</strong>。');
$lang->story->action->linked2plan = array('main' => '$date, 由 <strong>$actor</strong> 關聯到計劃 <strong>$extra</strong>。');
+20 -1
View File
@@ -1398,6 +1398,20 @@ class storyModel extends model
return $actions;
}
/**
* Recall the story review.
*
* @param int $storyID
* @access public
* @return void
*/
public function recall($storyID)
{
$story = $this->getById($storyID);
$this->dao->update(TABLE_STORY)->set('status')->eq('draft')->where('id')->eq($storyID)->exec();
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($storyID)->andWhere('version')->eq($story->version)->exec();
}
/**
* Subdivide story
*
@@ -3377,6 +3391,7 @@ class storyModel extends model
if($action == 'change') return (count($story->reviewer) == 0 || count($story->notReview) == 0) and $story->status != 'closed';
if($action == 'review') return in_array($app->user->account, $story->notReview) and ($story->status == 'draft' or $story->status == 'changed');
if($action == 'recall') return empty($story->reviewedBy) and strpos('draft,changed', $story->status) !== false and !empty($story->reviewer);
if($action == 'close') return $story->status != 'closed';
if($action == 'activate') return $story->status == 'closed';
if($action == 'assignto') return $story->status != 'closed';
@@ -3499,7 +3514,10 @@ class storyModel extends model
}
}
$allReviewers = $this->dao->select('story,reviewer,result')->from(TABLE_STORYREVIEW)->where('story')->in($storyIdList)->orderBy('version')->fetchGroup('story', 'reviewer');
$allReviewers = $this->dao->select('story,reviewer,result')->from(TABLE_STORY)->alias('t1')
->leftJoin(TABLE_STORYREVIEW)->alias('t2')->on('t1.version=t2.version and t1.id=t2.story')
->where('story')->in($storyIdList)
->fetchGroup('story', 'reviewer');
foreach($allReviewers as $storyID => $reviewerList)
{
@@ -3782,6 +3800,7 @@ class storyModel extends model
common::printIcon('story', 'change', $vars . "&from=$story->from", $story, 'list', 'alter', '', '', false, "data-group=$story->from");
common::printIcon('story', 'review', $vars . "&from=$story->from", $story, 'list', 'search', '', '', false, "data-group=$story->from");
if($this->app->openApp != 'project') common::printIcon('story', 'recall', $vars, $story, 'list', 'back', 'hiddenwin', '', '', '', $this->lang->story->recall);
common::printIcon('story', 'close', $vars, $story, 'list', '', '', 'iframe', true);
common::printIcon('story', 'edit', $vars . "&from=$story->from", $story, 'list', '', '', '', false, "data-group=$story->from");
if($story->type != 'requirement') common::printIcon('story', 'createCase', "productID=$story->product&branch=$story->branch&module=0&from=&param=0&$vars", $story, 'list', 'sitemap', '', '', false, "data-app='qa'");
+3 -3
View File
File diff suppressed because one or more lines are too long
@@ -1,6 +1,7 @@
<?php
$config->message->available['xuanxuan']['story'] = $config->message->objectTypes['story'];
$config->message->available['xuanxuan']['task'] = $config->message->objectTypes['task'];
$config->message->available['xuanxuan']['bug'] = $config->message->objectTypes['bug'];
$config->message->available['xuanxuan']['todo'] = $config->message->objectTypes['todo'];
$config->message->setting['xuanxuan']['setting'] = $config->message->available['xuanxuan'];
$config->message->available['xuanxuan']['story'] = $config->message->objectTypes['story'];
$config->message->available['xuanxuan']['task'] = $config->message->objectTypes['task'];
$config->message->available['xuanxuan']['bug'] = $config->message->objectTypes['bug'];
$config->message->available['xuanxuan']['todo'] = $config->message->objectTypes['todo'];
$config->message->available['xuanxuan']['release'] = $config->message->objectTypes['release'];
$config->message->setting['xuanxuan']['setting'] = $config->message->available['xuanxuan'];