Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms into zentaoipd

This commit is contained in:
tanghucheng
2023-03-16 10:19:13 +08:00
102 changed files with 4355 additions and 271 deletions
+1 -1
View File
@@ -1 +1 @@
18.2
18.3
+1 -1
View File
@@ -24,7 +24,7 @@ class executionStoriesEntry extends entry
if(empty($executionID)) return $this->sendError(400, 'Need execution id.');
$control = $this->loadController('execution', 'story');
$control->story($executionID, $this->param('order', 'id_desc'), $this->param('status', 'all'), 0, 0, $this->param('limit', 20), $this->param('page', 1));
$control->story($executionID, $this->param('storyType', 'story'), $this->param('order', 'id_desc'), $this->param('status', 'all'), 0, 0, $this->param('limit', 20), $this->param('page', 1));
$data = $this->getData();
if(isset($data->status) and $data->status == 'success')
+1 -1
View File
@@ -16,7 +16,7 @@ if(!class_exists('config')){class config{}}
if(!function_exists('getWebRoot')){function getWebRoot(){}}
/* 基本设置。Basic settings. */
$config->version = '18.2'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
$config->version = '18.3'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
$config->liteVersion = '1.2'; // 迅捷版版本。 The version of Lite.
$config->charset = 'UTF-8'; // ZenTaoPHP的编码。 The encoding of ZenTaoPHP.
$config->cookieLife = time() + 2592000; // Cookie的生存时间。The cookie life time.
File diff suppressed because it is too large Load Diff
+1
View File
@@ -1,3 +1,4 @@
ALTER TABLE `zt_lang` MODIFY COLUMN `section` varchar(50) NOT NULL;
DELETE FROM `zt_grouppriv` WHERE `module` = 'dev' AND `method` = 'editor';
REPLACE INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system','common','','setPercent','1');
DROP TABLE IF EXISTS `zt_dimension`;
+27
View File
@@ -1,3 +1,30 @@
2023-03-15 18.3
完成的需求
开源版:
41800 后台二次开发中的语言项增加三级菜单自定义
41846 后台二次开发中语言项自定义支持切换多种语言
42518 表单填写过程中,未保存退出时支持已填内容存储
41798 后台二次开发中的语言项增加一级菜单自定义
41799 后台二次开发中的语言项增加二级菜单自定义
41800 后台二次开发中的语言项增加三级菜单自定义
41801 后台二次开发中的语言项增加检索标签自定义
41844 后台二次开发中的语言项增加公共语言项自定义
41846 后台二次开发中语言项自定义支持切换多种语言
41847 后台二次开发中自定义的语言项支持自动引用菜单配置
42519 二次开发编辑器代码内嵌,增加开关
42518 表单填写过程中,未保存退出时支持已填内容存储
42568 修改需求列表中细分按钮的title提示语
40806 欢迎总览页面中支持试用的版本类型调整
42812 发布的需求列表下方统计增加故事点统计和用例覆盖率
41739 无迭代项目下的研发需求详情页面增加建任务按钮
42042 需要后台设置需求验收标准为必填项
42353 全局设置中增加是否启用百分比的设置功能
42361 开启或关闭百分比功能后项目中的处理规则
修复的Bug
开源版:
32514 初始快照创建中时,还能点击创建快照按钮
32515 创建快照时点击导出镜像按钮,执行节点无法启动
2023-02-27 18.2
完成的需求
开源版:
+2 -2
View File
@@ -30,7 +30,7 @@ if($config->edition != 'open')
/* Menu order. */
$lang->mainNav->menuOrder = array();
$lang->mainNav->menuOrder[5] = 'my';
$lang->mainNav->menuOrder[10] = $lang->projectCommon;
$lang->mainNav->menuOrder[10] = 'project';
$lang->mainNav->menuOrder[15] = 'kanban';
$lang->mainNav->menuOrder[35] = 'doc';
$lang->mainNav->menuOrder[45] = 'system';
@@ -137,7 +137,7 @@ $lang->doc->menuOrder[5] = 'dashboard';
$lang->doc->menuOrder[10] = 'recent';
$lang->doc->menuOrder[15] = 'my';
$lang->doc->menuOrder[20] = 'collect';
$lang->doc->menuOrder[25] = $lang->projectCommon;
$lang->doc->menuOrder[25] = 'product';
$lang->doc->menuOrder[30] = 'custom';
$lang->doc->menu->project['subMenu'] = new stdclass();
+2 -2
View File
@@ -30,7 +30,7 @@ if($config->edition != 'open')
/* Menu order. */
$lang->mainNav->menuOrder = array();
$lang->mainNav->menuOrder[5] = 'my';
$lang->mainNav->menuOrder[10] = $lang->projectCommon;
$lang->mainNav->menuOrder[10] = 'project';
$lang->mainNav->menuOrder[15] = 'kanban';
$lang->mainNav->menuOrder[35] = 'doc';
$lang->mainNav->menuOrder[45] = 'system';
@@ -137,7 +137,7 @@ $lang->doc->menuOrder[5] = 'dashboard';
$lang->doc->menuOrder[10] = 'recent';
$lang->doc->menuOrder[15] = 'my';
$lang->doc->menuOrder[20] = 'collect';
$lang->doc->menuOrder[25] = $lang->projectCommon;
$lang->doc->menuOrder[25] = 'project';
$lang->doc->menuOrder[30] = 'custom';
$lang->doc->menu->project['subMenu'] = new stdclass();
+2 -2
View File
@@ -30,7 +30,7 @@ if($config->edition != 'open')
/* Menu order. */
$lang->mainNav->menuOrder = array();
$lang->mainNav->menuOrder[5] = 'my';
$lang->mainNav->menuOrder[10] = $lang->projectCommon;
$lang->mainNav->menuOrder[10] = 'project';
$lang->mainNav->menuOrder[15] = 'kanban';
$lang->mainNav->menuOrder[35] = 'doc';
$lang->mainNav->menuOrder[45] = 'system';
@@ -137,7 +137,7 @@ $lang->doc->menuOrder[5] = 'dashboard';
$lang->doc->menuOrder[10] = 'recent';
$lang->doc->menuOrder[15] = 'my';
$lang->doc->menuOrder[20] = 'collect';
$lang->doc->menuOrder[25] = $lang->projectCommon;
$lang->doc->menuOrder[25] = 'project';
$lang->doc->menuOrder[30] = 'custom';
$lang->doc->menu->project['subMenu'] = new stdclass();
+1 -1
View File
@@ -109,7 +109,7 @@ class router extends baseRouter
parent::loadLang($moduleName, $appName);
/* Replace main nav lang. */
if($moduleName == 'common' and $this->dbh and !empty($this->config->db->name))
if($moduleName == 'common' and $this->dbh and !empty($this->config->db->name) and !defined('IN_UPGRADE'))
{
$customMenus = $this->dbh->query('SELECT * FROM' . TABLE_LANG . "WHERE `module`='common' AND `section`='mainNav' AND `lang`='{$this->clientLang}' AND `vision`='{$this->config->vision}'")->fetchAll();
foreach($customMenus as $menu)
+1 -1
View File
@@ -11,7 +11,7 @@ $config->admin->menuGroup['system'] = array('custom|mode', 'backup', 'cron',
$config->admin->menuGroup['company'] = array('dept', 'company', 'user', 'group', 'tutorial');
$config->admin->menuGroup['switch'] = array('admin|setmodule');
$config->admin->menuGroup['model'] = array('auditcl', 'stage', 'design', 'cmcl', 'reviewcl', 'custom|required', 'custom|set', 'custom|flow', 'custom|code', 'custom|percent','custom|estimate', 'custom|hours', 'subject', 'process', 'activity', 'zoutput', 'classify', 'holiday', 'reviewsetting');
$config->admin->menuGroup['feature'] = array('custom|set', 'custom|product', 'custom|execution', 'custom|required', 'custom|kanban', 'approvalflow', 'measurement', 'meetingroom', 'custom|browsestoryconcept', 'custom|kanban', 'sqlbuilder', 'report');
$config->admin->menuGroup['feature'] = array('custom|set', 'custom|product', 'custom|execution', 'custom|required', 'custom|kanban', 'approvalflow', 'measurement', 'meetingroom', 'custom|browsestoryconcept', 'custom|kanban', 'sqlbuilder', 'report', 'custom|limittaskdate');
$config->admin->menuGroup['template'] = array('custom|set', 'baseline');
$config->admin->menuGroup['message'] = array('mail', 'webhook', 'sms', 'message');
$config->admin->menuGroup['dev'] = array('dev', 'entry', 'editor');
+2 -2
View File
@@ -106,7 +106,7 @@ if(helper::hasFeature('waterfallplus')) $lang->admin->menuList->model['tabMenu']
$lang->admin->menuList->feature['subMenu']['my'] = array('link' => "{$lang->my->common}|custom|set|module=todo&field=priList", 'exclude' => 'set,required');
$lang->admin->menuList->feature['subMenu']['product'] = array('link' => "{$lang->productCommon}|custom|required|module=product", 'exclude' => 'set,required', 'alias' => 'browsestoryconcept,product');
$lang->admin->menuList->feature['subMenu']['execution'] = array('link' => "{$lang->execution->common}|custom|required|module=execution", 'exclude' => 'required,set', 'alias' => 'execution');
$lang->admin->menuList->feature['subMenu']['execution'] = array('link' => "{$lang->execution->common}|custom|required|module=execution", 'exclude' => 'required,set', 'alias' => 'execution,limittaskdate');
$lang->admin->menuList->feature['subMenu']['qa'] = array('link' => "{$lang->qa->common}|custom|required|module=bug", 'exclude' => 'set,required');
$lang->admin->menuList->feature['subMenu']['kanban'] = array('link' => "{$lang->kanban->common}|custom|kanban|");
$lang->admin->menuList->feature['subMenu']['doc'] = array('link' => "{$lang->doc->common}|custom|required|module=doc", 'exclude' => 'required');
@@ -121,7 +121,7 @@ $lang->admin->menuList->feature['tabMenu']['product']['productplan'] = array('li
$lang->admin->menuList->feature['tabMenu']['product']['release'] = array('link' => "{$lang->release->common}|custom|required|module=release", 'exclude' => 'custom-required');
$lang->admin->menuList->feature['tabMenu']['execution']['execution'] = array('link' => "{$lang->execution->common}|custom|required|module=execution", 'links' => array("custom|execution|"), 'alias' => 'execution', 'exclude' => 'custom-required');
$lang->admin->menuList->feature['tabMenu']['execution']['task'] = array('link' => "{$lang->task->common}|custom|required|module=task", 'links' => array('custom|set|module=task&field=priList'), 'exclude' => 'custom-required');
$lang->admin->menuList->feature['tabMenu']['execution']['task'] = array('link' => "{$lang->task->common}|custom|required|module=task", 'links' => array('custom|set|module=task&field=priList', 'custom|limittaskdate|'), 'alias' => 'limittaskdate','exclude' => 'custom-required');
$lang->admin->menuList->feature['tabMenu']['qa']['bug'] = array('link' => "{$lang->bug->common}|custom|required|module=bug", 'links' => array("custom|set|module=bug&field=priList"), 'exclude' => 'custom-required,custom-set');
$lang->admin->menuList->feature['tabMenu']['qa']['testcase'] = array('link' => "{$lang->testcase->common}|custom|required|module=testcase", 'links' => array("custom|set|module=testcase&field=priList"), 'exclude' => 'custom-required,custom-set');
+3 -3
View File
@@ -803,15 +803,15 @@ EOT;
{
$result = $this->api->request($method->className, $method->methodName, $action);
$content = json_decode($result['content']);
$status = $content->status;
$data = json_decode($content->data);
$status = zget($content, 'status', '');
$data = isset($content->data) ? json_decode($content->data) : '';
$data = '<xmp>' . print_r($data, true) . '</xmp>';
$response['result'] = 'success';
$response['status'] = $status;
$response['url'] = $result['url'];
$response['data'] = $data;
$this->send($response);
return print(json_encode($response));
}
$this->view->method = $method;
+1 -1
View File
@@ -1,6 +1,6 @@
$(document).ready(function()
{
var options =
var options =
{
target : null,
timeout : 30000,
+2 -2
View File
@@ -21,12 +21,12 @@ $productsHtml = (count($products) > 1 and strpos(',zeroCase,browseUnits,groupC
foreach($products as $product)
{
$selected = $product->id == $productID ? 'selected' : '';
$selected = $product->id == $productID ? 'selected' : 'text-primary';
$productName = ($product->program and $this->config->systemMode == 'ALM') ? zget($programs, $product->program, '') . '/' : '';
$productName .= ($this->config->systemMode == 'ALM' and $product->line) ? zget($lines, $product->line, '') . '/' . $product->name : $product->name;
$objectID = ($product->type != 'platform' && $module == 'branch' && $method == 'manage') ? $productID : $product->id;
$linkHtml = $this->product->setParamsForLink($module, $link, $projectID, $product->id);
$productsHtml .= html::a($linkHtml, $productName, '', "class='text-primary $selected' title='{$productName}' data-key='" . zget($productsPinYin, $product->name, '') . "' data-app='{$this->app->tab}'");
$productsHtml .= html::a($linkHtml, $productName, '', "class='$selected' title='{$productName}' data-key='" . zget($productsPinYin, $product->name, '') . "' data-app='{$this->app->tab}'");
}
?>
<div class="table-row">
+1 -1
View File
@@ -161,7 +161,7 @@
<th><?php echo $lang->bug->fromCase;?></th>
<td><?php if($bug->case) echo html::a(helper::createLink('testcase', 'view', "caseID=$bug->case&version=$bug->caseVersion", '', true), "<i class='icon icon-sitemap'></i> {$lang->bug->fromCase}$lang->colon$bug->case", '', isonlybody() ? '' : "data-toggle='modal' data-type='iframe' data-width='80%'");?></td>
</tr>
<tr valign='middle' class='<?php if($product->shadow and isset($project) and !$project->multiple) echo 'hide'?>'>
<tr valign='middle' class='<?php if($product->shadow and isset($project) and !empty($project->multiple)) echo 'hide'?>'>
<th><?php echo $lang->bug->productplan;?></th>
<td><?php if(!$bug->plan or !common::printLink('productplan', 'view', "planID=$bug->plan&type=bug", $bug->planName)) echo $bug->planName;?></td>
</tr>
+1 -1
View File
@@ -71,7 +71,7 @@ $config->custom->fieldList['doc'] = 'keywords,content';
$config->custom->fieldList['user']['create'] = 'dept,role,email,commiter';
$config->custom->fieldList['user']['edit'] = 'dept,role,email,commiter,skype,qq,mobile,phone,address,zipcode,dingding,slack,whatsapp,weixin';
$config->custom->notSetMethods = array('required', 'browsestoryconcept', 'product', 'role', 'execution');
$config->custom->notSetMethods = array('required', 'browsestoryconcept', 'product', 'role', 'execution', 'limitTaskDate');
global $lang;
$config->custom->commonLang = array('$URCOMMON' => $lang->URCommon, '$SRCOMMON' => $lang->SRCommon, '$PRODUCTCOMMON' => $lang->productCommon, '$PROJECTCOMMON' => $lang->projectCommon, '$EXECUTIONCOMMON' => $lang->executionCommon);
+22
View File
@@ -914,4 +914,26 @@ class custom extends control
$this->view->restDay = zget($this->config->execution, 'restDay', 0);
$this->display();
}
/**
* Set whether the task begin and end date is limited to the execution begin and end date.
*
* @access public
* @return void
*/
public function limitTaskDate()
{
if($_POST)
{
$this->loadModel('setting')->setItem('system.common.limitTaskDate', $this->post->limitTaskDate);
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'reload'));
}
$this->view->title = $this->lang->custom->beginAndEndDate;
$this->view->position[] = $this->lang->custom->common;
$this->view->position[] = $this->view->title;
$this->view->module = 'task';
$this->display();
}
}
+2
View File
@@ -0,0 +1,2 @@
#limitTaskDateForm .c-name {width: 120px;}
#limitTaskDateForm .c-select {width: 350px;}
+2
View File
@@ -0,0 +1,2 @@
#limitTaskDateForm .c-name {width: 180px;}
#limitTaskDateForm .c-select {width: 440px;}
+14 -8
View File
@@ -9,8 +9,8 @@ $lang->custom->restore = 'Reset to Default';
$lang->custom->key = 'Key';
$lang->custom->value = 'Value';
$lang->custom->working = 'WorkStyle';
$lang->custom->select = 'Select Concept';
$lang->custom->hours = 'Hours';
$lang->custom->select = 'Select Concept';
$lang->custom->branch = 'Multi Branch';
$lang->custom->owner = 'Owner';
$lang->custom->module = 'Module';
@@ -61,6 +61,8 @@ $lang->custom->defaultProgram = 'Default program';
$lang->custom->modeManagement = 'Mode Management';
$lang->custom->percent = $lang->stage->percent;
$lang->custom->setPercent = "Enable or Disable {$lang->stage->percent}";
$lang->custom->beginAndEndDate = 'Begin & End';
$lang->custom->beginAndEndDateRange = 'The Range Of Begin & End';
$lang->custom->unitList['efficiency'] = 'Working Hours/';
$lang->custom->unitList['manhour'] = 'Man-hour/';
@@ -122,11 +124,12 @@ $lang->custom->story->fields['reviewResultList'] = 'Review Result';
$lang->custom->story->fields['review'] = 'Review Required';
$lang->custom->task = new stdClass();
$lang->custom->task->fields['required'] = $lang->custom->required;
$lang->custom->task->fields['priList'] = 'Priority';
$lang->custom->task->fields['typeList'] = 'Type';
$lang->custom->task->fields['reasonList'] = 'Close Reason';
$lang->custom->task->fields['statusList'] = 'Status';
$lang->custom->task->fields['required'] = $lang->custom->required;
$lang->custom->task->fields['priList'] = 'Priority';
$lang->custom->task->fields['typeList'] = 'Type';
$lang->custom->task->fields['reasonList'] = 'Close Reason';
$lang->custom->task->fields['statusList'] = 'Status';
$lang->custom->task->fields['limitTaskDate'] = 'Begin & End';
$lang->custom->bug = new stdClass();
$lang->custom->bug->fields['required'] = $lang->custom->required;
@@ -233,8 +236,8 @@ $lang->custom->restDayList[6] = 'Saturday rest';
$lang->custom->restDayList[0] = 'Sunday rest';
global $config;
$lang->custom->sprintConceptList[0] = 'Program Product Iteration';
$lang->custom->sprintConceptList[1] = 'Program Product Sprint';
$lang->custom->sprintConceptList[0] = 'Project Product Iteration';
$lang->custom->sprintConceptList[1] = 'Project Product Sprint';
$lang->custom->workingList['full'] = 'Full Management of Dev';
@@ -324,3 +327,6 @@ $lang->custom->scrum->setConcept = 'Set concept';
$lang->custom->reviewRules['allpass'] = 'All passed';
$lang->custom->reviewRules['halfpass'] = 'More than half passed';
$lang->custom->limitTaskDate['0'] = 'Unlimited';
$lang->custom->limitTaskDate['1'] = 'Limited to the execution begin and end date range';
+14 -8
View File
@@ -9,8 +9,8 @@ $lang->custom->restore = 'Reset';
$lang->custom->key = 'Key';
$lang->custom->value = 'Value';
$lang->custom->working = 'Mode';
$lang->custom->select = 'Select Concept';
$lang->custom->hours = 'Hours';
$lang->custom->select = 'Select Concept';
$lang->custom->branch = 'Multi-Branch';
$lang->custom->owner = 'Owner';
$lang->custom->module = 'Module';
@@ -61,6 +61,8 @@ $lang->custom->defaultProgram = 'Default program';
$lang->custom->modeManagement = 'Mode Management';
$lang->custom->percent = $lang->stage->percent;
$lang->custom->setPercent = "Enable or Disable {$lang->stage->percent}";
$lang->custom->beginAndEndDate = 'Begin & End';
$lang->custom->beginAndEndDateRange = 'The Range Of Begin & End';
$lang->custom->unitList['efficiency'] = 'Working Hours/';
$lang->custom->unitList['manhour'] = 'Man-hour/';
@@ -122,11 +124,12 @@ $lang->custom->story->fields['reviewResultList'] = 'Review Result';
$lang->custom->story->fields['review'] = 'Need Review';
$lang->custom->task = new stdClass();
$lang->custom->task->fields['required'] = $lang->custom->required;
$lang->custom->task->fields['priList'] = 'Priority';
$lang->custom->task->fields['typeList'] = 'Type';
$lang->custom->task->fields['reasonList'] = 'Close Reason';
$lang->custom->task->fields['statusList'] = 'Status';
$lang->custom->task->fields['required'] = $lang->custom->required;
$lang->custom->task->fields['priList'] = 'Priority';
$lang->custom->task->fields['typeList'] = 'Type';
$lang->custom->task->fields['reasonList'] = 'Close Reason';
$lang->custom->task->fields['statusList'] = 'Status';
$lang->custom->task->fields['limitTaskDate'] = 'Begin & End';
$lang->custom->bug = new stdClass();
$lang->custom->bug->fields['required'] = $lang->custom->required;
@@ -233,8 +236,8 @@ $lang->custom->restDayList[6] = 'Saturday rest';
$lang->custom->restDayList[0] = 'Sunday rest';
global $config;
$lang->custom->sprintConceptList[0] = 'Program Product Iteration';
$lang->custom->sprintConceptList[1] = 'Program Product Sprint';
$lang->custom->sprintConceptList[0] = 'Project Product Iteration';
$lang->custom->sprintConceptList[1] = 'Project Product Sprint';
$lang->custom->workingList['full'] = 'Application Lifecycle Management';
@@ -324,3 +327,6 @@ $lang->custom->scrum->setConcept = 'Set concept';
$lang->custom->reviewRules['allpass'] = 'All passed';
$lang->custom->reviewRules['halfpass'] = 'More than half passed';
$lang->custom->limitTaskDate['0'] = 'Unlimited';
$lang->custom->limitTaskDate['1'] = 'Limited to the execution begin and end date range';
+14 -8
View File
@@ -9,8 +9,8 @@ $lang->custom->restore = 'Réinitialiser';
$lang->custom->key = 'Clé';
$lang->custom->value = 'Valeur';
$lang->custom->working = 'Mode';
$lang->custom->select = 'Choix du Concept';
$lang->custom->hours = 'Hours';
$lang->custom->select = 'Choix du Concept';
$lang->custom->branch = 'Multi-Branches';
$lang->custom->owner = 'Propriétaire';
$lang->custom->module = 'Module';
@@ -61,6 +61,8 @@ $lang->custom->defaultProgram = 'Default program';
$lang->custom->modeManagement = 'Mode Management';
$lang->custom->percent = $lang->stage->percent;
$lang->custom->setPercent = "Enable or Disable {$lang->stage->percent}";
$lang->custom->beginAndEndDate = 'Begin & End';
$lang->custom->beginAndEndDateRange = 'The Range Of Begin & End';
$lang->custom->unitList['efficiency'] = 'Working Hours/';
$lang->custom->unitList['manhour'] = 'Man-hour/';
@@ -122,11 +124,12 @@ $lang->custom->story->fields['reviewResultList'] = 'Valider Résultats';
$lang->custom->story->fields['review'] = 'Validation Requise';
$lang->custom->task = new stdClass();
$lang->custom->task->fields['required'] = $lang->custom->required;
$lang->custom->task->fields['priList'] = 'Priorité';
$lang->custom->task->fields['typeList'] = 'Type';
$lang->custom->task->fields['reasonList'] = 'Raison Fermeture';
$lang->custom->task->fields['statusList'] = 'Statut';
$lang->custom->task->fields['required'] = $lang->custom->required;
$lang->custom->task->fields['priList'] = 'Priorité';
$lang->custom->task->fields['typeList'] = 'Type';
$lang->custom->task->fields['reasonList'] = 'Raison Fermeture';
$lang->custom->task->fields['statusList'] = 'Statut';
$lang->custom->task->fields['limitTaskDate'] = 'Begin & End';
$lang->custom->bug = new stdClass();
$lang->custom->bug->fields['required'] = $lang->custom->required;
@@ -233,8 +236,8 @@ $lang->custom->restDayList[6] = 'Saturday rest';
$lang->custom->restDayList[0] = 'Sunday rest';
global $config;
$lang->custom->sprintConceptList[0] = 'Program Product Iteration';
$lang->custom->sprintConceptList[1] = 'Program Product Sprint';
$lang->custom->sprintConceptList[0] = 'Project Product Iteration';
$lang->custom->sprintConceptList[1] = 'Project Product Sprint';
$lang->custom->workingList['full'] = 'Application Lifecycle Management';
@@ -324,3 +327,6 @@ $lang->custom->scrum->setConcept = 'Set concept';
$lang->custom->reviewRules['allpass'] = 'All passed';
$lang->custom->reviewRules['halfpass'] = 'More than half passed';
$lang->custom->limitTaskDate['0'] = 'Unlimited';
$lang->custom->limitTaskDate['1'] = 'Limited to the execution begin and end date range';
+24 -18
View File
@@ -61,6 +61,8 @@ $lang->custom->defaultProgram = '默认项目集';
$lang->custom->modeManagement = '模式管理';
$lang->custom->percent = $lang->stage->percent;
$lang->custom->setPercent = "是否启用{$lang->stage->percent}";
$lang->custom->beginAndEndDate = '起止日期';
$lang->custom->beginAndEndDateRange = '起止日期范围';
$lang->custom->unitList['efficiency'] = '工时/';
$lang->custom->unitList['manhour'] = '人时/';
@@ -122,11 +124,12 @@ $lang->custom->story->fields['reviewResultList'] = '评审结果';
$lang->custom->story->fields['review'] = '评审流程';
$lang->custom->task = new stdClass();
$lang->custom->task->fields['required'] = $lang->custom->required;
$lang->custom->task->fields['priList'] = '优先级';
$lang->custom->task->fields['typeList'] = '类型';
$lang->custom->task->fields['reasonList'] = '关闭原因';
$lang->custom->task->fields['statusList'] = '状态';
$lang->custom->task->fields['required'] = $lang->custom->required;
$lang->custom->task->fields['priList'] = '优先级';
$lang->custom->task->fields['typeList'] = '类型';
$lang->custom->task->fields['reasonList'] = '关闭原因';
$lang->custom->task->fields['statusList'] = '状态';
$lang->custom->task->fields['limitTaskDate'] = '起止日期';
$lang->custom->bug = new stdClass();
$lang->custom->bug->fields['required'] = $lang->custom->required;
@@ -233,8 +236,8 @@ $lang->custom->restDayList[6] = '周六休息';
$lang->custom->restDayList[0] = '周天休息';
global $config;
$lang->custom->sprintConceptList[0] = "{$lang->projectCommon} 产品 迭代";
$lang->custom->sprintConceptList[1] = "{$lang->projectCommon} 产品 冲刺";
$lang->custom->sprintConceptList[0] = "项目 产品 迭代";
$lang->custom->sprintConceptList[1] = "项目 产品 冲刺";
$lang->custom->workingList['full'] = '完整研发管理工具';
@@ -252,18 +255,18 @@ $lang->custom->selectProgramTips = "切换到轻量管理模式后,为确保
$lang->custom->modeList['light'] = '轻量级管理模式';
$lang->custom->modeList['ALM'] = '全生命周期管理模式';
$lang->custom->modeIntroductionList["light"] = "提供了{$lang->projectCommon}管理的核心功能,适用于小型研发团队";
$lang->custom->modeIntroductionList['light'] = "提供了{$lang->projectCommon}管理的核心功能,适用于小型研发团队";
$lang->custom->modeIntroductionList['ALM'] = '概念更加完整、严谨,功能更加丰富,适用于中大型研发团队';
$lang->custom->features['program'] = '项目集';
$lang->custom->features["productRR"] = "{$lang->productCommon}-研发需求";
$lang->custom->features["productUR"] = "{$lang->productCommon}-用户需求";
$lang->custom->features["productLine"] = "{$lang->productCommon}-{$lang->productCommon}线";
$lang->custom->features["projectScrum"] = "{$lang->projectCommon}-敏捷模型";
$lang->custom->features["projectWaterfall"] = "{$lang->projectCommon}-瀑布模型";
$lang->custom->features["projectKanban"] = "{$lang->projectCommon}-看板模型";
$lang->custom->features["projectAgileplus"] = "{$lang->projectCommon}-融合敏捷模型";
$lang->custom->features["projectWaterfallplus"] = "{$lang->projectCommon}-融合瀑布模型";
$lang->custom->features['productRR'] = "{$lang->productCommon}-研发需求";
$lang->custom->features['productUR'] = "{$lang->productCommon}-用户需求";
$lang->custom->features['productLine'] = "{$lang->productCommon}-产品线";
$lang->custom->features['projectScrum'] = "{$lang->projectCommon}-敏捷模型";
$lang->custom->features['projectWaterfall'] = "{$lang->projectCommon}-瀑布模型";
$lang->custom->features['projectKanban'] = "{$lang->projectCommon}-看板模型";
$lang->custom->features['projectAgileplus'] = "{$lang->projectCommon}-融合敏捷模型";
$lang->custom->features['projectWaterfallplus'] = "{$lang->projectCommon}-融合瀑布模型";
$lang->custom->features['execution'] = '执行';
$lang->custom->features['qa'] = '测试';
$lang->custom->features['devops'] = 'DevOps';
@@ -280,8 +283,8 @@ $lang->custom->features['workflow'] = '工作流';
$lang->custom->features['admin'] = '后台';
$lang->custom->features['vision'] = '研发综合界面、运营管理界面';
$lang->custom->needClosedFunctions["waterfall"] = "瀑布{$lang->projectCommon}";
$lang->custom->needClosedFunctions["waterfallplus"] = "融合瀑布{$lang->projectCommon}";
$lang->custom->needClosedFunctions['waterfall'] = "瀑布{$lang->projectCommon}";
$lang->custom->needClosedFunctions['waterfallplus'] = "融合瀑布{$lang->projectCommon}";
$lang->custom->needClosedFunctions['URStory'] = '用户需求';
if($config->edition == 'max') $lang->custom->needClosedFunctions['assetLib'] = '资产库';
@@ -324,3 +327,6 @@ $lang->custom->scrum->setConcept = "设置{$lang->projectCommon}概念";
$lang->custom->reviewRules['allpass'] = '全部通过通过';
$lang->custom->reviewRules['halfpass'] = '半数以上通过通过';
$lang->custom->limitTaskDate['0'] = '不限制';
$lang->custom->limitTaskDate['1'] = '限定在所属执行起止日期范围内';
+48
View File
@@ -0,0 +1,48 @@
<?php
/**
* The limittaskdate view file of custom module of ZenTaoPMS.
* @copyright Copyright 2009-2020 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Liyuchun <liyuchun@cnezsoft.com>
* @package custom
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include $app->getModuleRoot() . 'common/view/header.html.php';?>
<div id='mainContent' class='main-row'>
<?php include 'sidebar.html.php';?>
<div class='main-col main-content'>
<form class="load-indicator main-form form-ajax" method='post' id='limitTaskDateForm'>
<div class='main-header'>
<div class='heading'>
<strong><?php echo $lang->custom->$module->fields['limitTaskDate'];?></strong>
</div>
</div>
<table class='table table-form'>
<tr>
<th class='c-name'><?php echo $lang->custom->beginAndEndDateRange;?></th>
<td class='c-select text-left'>
<?php $checkedKey = isset($config->limitTaskDate) ? $config->limitTaskDate : 0;?>
<?php foreach($lang->custom->limitTaskDate as $key => $value):?>
<label class="radio-inline"><input type="radio" name="limitTaskDate" value="<?php echo $key?>"<?php echo $key == $checkedKey ? " checked='checked'" : ''?> id="limitTaskDate<?php echo $key;?>"><?php echo $value;?></label>
<?php endforeach;?>
</td>
<td></td>
</tr>
<tr>
<td colspan='2' class='form-actions text-center'>
<?php echo html::submitButton();?>
</td>
</tr>
</table>
</form>
</div>
</div>
<script>
$(function()
{
$('#mainMenu #taskTab').addClass('btn-active-text');
})
</script>
<?php include '../../common/view/footer.html.php';?>
+1 -1
View File
@@ -8,7 +8,7 @@
$currentModule = 'custom';
$method = $key;
$params = $key == 'required' ? "module=$module" : '';
$active = $app->rawMethod == $key ? 'active' : '';
$active = $app->rawMethod == strtolower($key) ? 'active' : '';
if(!in_array($key, $config->custom->notSetMethods))
{
$params = "module=$module&field=$key";
+1 -1
View File
@@ -18,7 +18,7 @@ $lang->dev->paramRange = 'Parameter Range: %s';
$lang->dev->paramDate = 'Date format: YY-mm-dd, e.g 2019-01-01';
$lang->dev->paramColor = 'Color format: #RGB, e.g. #3da7f5';
$lang->dev->paramMailto = "User account. Separate accounts by ','.";
$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of the <a href='https://www.zentao.net/extension-viewExt-150.html' target='_blank'>editor</a>.";
$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, Please turn on.";
$lang->dev->noteTranslate = "The translation is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of <a href='https://www.zentao.net/extension-viewExt-151.html' target='_blank'>translation</a>.";
$lang->dev->confirmRestore = 'Do you want to reset?';
+1 -1
View File
@@ -18,7 +18,7 @@ $lang->dev->paramRange = 'Parameter Range: %s';
$lang->dev->paramDate = 'Date format: YY-mm-dd, e.g 2019-01-01';
$lang->dev->paramColor = 'Color format: #RGB, e.g. #3da7f5';
$lang->dev->paramMailto = "User account. Separate accounts by ','.";
$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of the <a href='https://www.zentao.net/extension-viewExt-150.html' target='_blank'>editor</a>.";
$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, Please turn on.";
$lang->dev->noteTranslate = "The translation is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of <a href='https://www.zentao.net/extension-viewExt-151.html' target='_blank'>translation</a>.";
$lang->dev->confirmRestore = 'Do you want to reset?';
+1 -1
View File
@@ -18,7 +18,7 @@ $lang->dev->paramRange = 'Parameter Range: %s';
$lang->dev->paramDate = 'Date format: YY-mm-dd, e.g 2019-01-01';
$lang->dev->paramColor = 'Color format: #RGB, e.g. #3da7f5';
$lang->dev->paramMailto = "User account. Separate accounts by ','.";
$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of the <a href='https://www.zentao.net/extension-viewExt-150.html' target='_blank'>editor</a>.";
$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, Please turn on.";
$lang->dev->noteTranslate = "The translation is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of <a href='https://www.zentao.net/extension-viewExt-151.html' target='_blank'>translation</a>.";
$lang->dev->confirmRestore = 'Do you want to reset?';
+3 -2
View File
@@ -1099,10 +1099,11 @@ class devModel extends model
$module->children = array();
foreach($objects[$moduleKey] as $objectKey => $objectName)
{
$defaultValue = $type == 'module' ? $objectName : '';
if($type == 'table' and !isset($this->lang->dev->tableList[$objectKey])) continue;
$object = new stdclass();
$object->key = $objectName;
$object->title = zget($this->lang->dev->tableList, $objectKey, $defaultValue);
$object->title = zget($this->lang->dev->tableList, $objectKey, $objectName);
$object->active = $objectName == $currentObject ? 1 : 0;
if($object->active) $module->active = 1;
+1 -1
View File
@@ -19,7 +19,7 @@
<div class='main-header'>
<h2><?php echo $lang->doc->createLib;?></h2>
</div>
<form method='post' target='hiddenwin'>
<form method='post' target='hiddenwin' class='no-stash'>
<table class='table table-form'>
<tr>
<th class='w-110px'><?php echo $lang->doc->libType?></th>
+1
View File
@@ -12,3 +12,4 @@
.m-editor-extend .main-header {padding: 10px 20px; }
.m-editor-extend .main-content {padding: 0px; padding-top: 10px; box-shadow: none;}
#extendTree li a {white-space: nowrap;}
#extendTree span {padding: 0 4px;}
+3 -1
View File
@@ -34,7 +34,8 @@ $lang->editor->noticeOkFile = 'Aus Sicherheitsgründen muss Ihr Adminkonto best
$lang->editor->editFileError = 'Sie können nur ZenTao Dateien verändern!';
$lang->editor->turnOff = "If you don't use the editor function, you can turn it off here.";
$lang->editor->notWritable = "Nicht beschreibbar. Berechtigung erforderlich. Bitte versuchen Sie chmod 777 -R ";
$lang->editor->notExists = "Not exists. Please create it. Try mkdir -p %s";
$lang->editor->notWritable = "Nicht beschreibbar. Berechtigung erforderlich. Bitte versuchen Sie chmod 777 -R %s";
$lang->editor->notDelete = 'Kann nicht gelöscht werden. Bitte prüfen Sie Ihre Berechtigungen!';
$lang->editor->emptyFileName = 'Bitte geben Sie einen Dateinamen an!';
$lang->editor->onlyLocalVisit = "This feature only works when the IP is 127.0.0.1. <a href='https://api.zentao.pm/goto.php?item=howtodevelop&from=en' target='_blank'>Help</a>";
@@ -63,6 +64,7 @@ $lang->editor->modules['my'] = 'Dashboard';
$lang->editor->modules['product'] = $lang->productCommon;
$lang->editor->modules['productplan'] = 'Plan';
$lang->editor->modules['project'] = $lang->projectCommon;
$lang->editor->modules['execution'] = $lang->executionCommon;
$lang->editor->modules['qa'] = 'QA';
$lang->editor->modules['release'] = 'Release';
$lang->editor->modules['report'] = 'Berichte';
+2 -1
View File
@@ -34,7 +34,8 @@ $lang->editor->noticeOkFile = 'For security reasons, your Admin account has to
$lang->editor->editFileError = 'You can only modify ZenTao files!';
$lang->editor->turnOff = "If you don't use the editor function, you can turn it off here.";
$lang->editor->notWritable = "Not wirtable. Permission is required. Please try chmod 777 -R ";
$lang->editor->notExists = "Not exists. Please create it. Try mkdir -p %s";
$lang->editor->notWritable = "Not wirtable. Permission is required. Please try chmod 777 -R %s";
$lang->editor->notDelete = 'Cannot be deleted. Please check your permissions!';
$lang->editor->emptyFileName = 'Please enter a File Name!';
$lang->editor->onlyLocalVisit = "This feature only works when the IP is 127.0.0.1 for security. <a href='https://api.zentao.pm/goto.php?item=howtodevelop&from=en' target='_blank'>Help</a>";
+3 -1
View File
@@ -34,7 +34,8 @@ $lang->editor->noticeOkFile = 'Pour des raisons de s?curit?, votre compte admin
$lang->editor->editFileError = 'Vous pouvez seulement modifier les fichiers ZenTao !';
$lang->editor->turnOff = "If you don't use the editor function, you can turn it off here.";
$lang->editor->notWritable = "Non inscriptible. Permission requise. Essayez chmod 777 -R ";
$lang->editor->notExists = "Not exists. Please create it. Try mkdir -p %s";
$lang->editor->notWritable = "Non inscriptible. Permission requise. Essayez chmod 777 -R %s";
$lang->editor->notDelete = 'Ne peut pas ?tre supprim?. V?rifiez les permissions !';
$lang->editor->emptyFileName = 'Entrez un nom de fichier !';
$lang->editor->onlyLocalVisit = "Cette fonctionnalit? ne fonctionne que pour une IP 127.0.0.1. <a href='https://api.zentao.pm/goto.php?item=howtodevelop&from=en' target='_blank'>Aide</a>";
@@ -63,6 +64,7 @@ $lang->editor->modules['my'] = 'Dashboard';
$lang->editor->modules['product'] = $lang->productCommon;
$lang->editor->modules['productplan'] = 'Plan';
$lang->editor->modules['project'] = $lang->projectCommon;
$lang->editor->modules['execution'] = $lang->executionCommon;
$lang->editor->modules['qa'] = 'QA';
$lang->editor->modules['release'] = 'Release';
$lang->editor->modules['report'] = 'Rapport';
+2 -1
View File
@@ -34,7 +34,8 @@ $lang->editor->noticeOkFile = '为了安全起见,系统需要确认您的管
$lang->editor->editFileError = '只能修改禅道文件!';
$lang->editor->turnOff = '如不使用编辑器功能,可在此关闭。';
$lang->editor->notWritable = "无法写入,可能没有权限。请尝试执行 chmod 777 -R ";
$lang->editor->notExists = "不存在该目录,请先创建。请尝试执行 mkdir -p %s";
$lang->editor->notWritable = "无法写入,可能没有权限。请尝试执行 chmod 777 -R %s";
$lang->editor->notDelete = '无法删除,请检查权限!';
$lang->editor->emptyFileName = '请写入一个文件名!';
$lang->editor->onlyLocalVisit = "该功能只能在IP:127.0.0.1下访问。<a href='https://api.zentao.net/goto.php?item=howtodevelop' target='_blank'>说明文档</a>";
+14 -9
View File
@@ -320,23 +320,20 @@ class editorModel extends model
*
* @param string $filePath
* @access public
* @return bool
* @return string
*/
public function save($filePath)
{
/* Reduce expiration time for check safe file. */
$this->config->safeFileTimeout = 15 * 60;
$statusFile = $this->loadModel('common')->checkSafeFile();
if($statusFile)
{
print(js::alert(sprintf($this->lang->editor->noticeOkFile, str_replace('\\', '/', $statusFile))));
return false;
}
if($statusFile) return print(js::alert(sprintf($this->lang->editor->noticeOkFile, str_replace('\\', '/', $statusFile))));
$dirPath = dirname($filePath);
$extFilePath = substr($filePath, 0, strpos($filePath, DS . 'ext' . DS) + 4);
if(!is_dir($dirPath) and is_writable($extFilePath)) mkdir($dirPath, 0777, true);
if(!is_dir($dirPath) or !is_writable($dirPath)) return print(js::alert($this->lang->editor->notWritable . $extFilePath));
if(!is_dir($dirPath)) return print(js::alert(sprintf($this->lang->editor->notExists, $extFilePath)));
if(!is_writable($dirPath)) return print(js::alert(sprintf($this->lang->editor->notWritable, $extFilePath)));
if(strpos(strtolower(realpath($dirPath)), strtolower($this->app->getBasePath())) !== 0) return print(js::alert($this->lang->editor->editFileError));
$fileContent = $this->post->fileContent;
@@ -454,8 +451,16 @@ EOD;
if($param->isOptional())
{
$defaultParam = $param->getDefaultValue();
if(is_string($defaultParam)) $methodParam .= "='$defaultParam', ";
else $methodParam .= "=$defaultParam, ";
if(is_string($defaultParam))
{
$methodParam .= "='$defaultParam', ";
}
else
{
if(is_array($defaultParam) and empty($defaultParam)) $defaultParam = 'array()';
if(is_null($defaultParam)) $defaultParam = 'null';
$methodParam .= "=$defaultParam, ";
}
}
else
{
+1
View File
@@ -2177,6 +2177,7 @@ class execution extends control
$allProjects = $this->project->getPairsByModel($project->model, 0, 'noclosed', isset($projectID) ? $projectID : 0);
$this->project->setMenu($projectID);
$this->view->project = $project;
if($project->model == 'waterfall' or $project->model == 'waterfallplus') $this->lang->execution->common = $this->lang->execution->stage;
}
else
{
+1 -1
View File
@@ -151,7 +151,7 @@ $lang->execution->left = 'Left';
$lang->execution->copyTeamTip = "copy {$lang->projectCommon}/{$lang->execution->common} team members";
$lang->execution->daysGreaterProject = 'Days cannot be greater than days of execution 『%s』';
$lang->execution->errorHours = 'Hours/Day cannot be greater than『24』';
$lang->execution->agileplusMethodTip = "When creating executions in an Agile Plus {$lang->projectCommon}, both Iteration and Kanban management methods are supported.";
$lang->execution->agileplusMethodTip = "When creating executions in an Agile Plus {$lang->projectCommon}, both {$lang->executionCommon} and Kanban management methods are supported.";
$lang->execution->typeTip = "The sub-stages of other types can be created under the parent stage of the 'mix' type, while the type of other parent-child levels is consistent.";
$lang->execution->waterfallTip = "In the Waterfall {$lang->projectCommon} or in the Waterfall + {$lang->projectCommon},";
+1 -1
View File
@@ -151,7 +151,7 @@ $lang->execution->left = 'Left';
$lang->execution->copyTeamTip = "copy {$lang->projectCommon}/{$lang->execution->common} team members";
$lang->execution->daysGreaterProject = 'Days cannot be greater than days of execution 『%s』';
$lang->execution->errorHours = 'Hours/Day cannot be greater than『24』';
$lang->execution->agileplusMethodTip = "When creating executions in an Agile Plus {$lang->projectCommon}, both Iteration and Kanban management methods are supported.";
$lang->execution->agileplusMethodTip = "When creating executions in an Agile Plus {$lang->projectCommon}, both {$lang->executionCommon} and Kanban management methods are supported.";
$lang->execution->typeTip = "The sub-stages of other types can be created under the parent stage of the 'mix' type, while the type of other parent-child levels is consistent.";
$lang->execution->waterfallTip = "In the Waterfall {$lang->projectCommon} or in the Waterfall + {$lang->projectCommon},";
+1 -1
View File
@@ -151,7 +151,7 @@ $lang->execution->left = 'Left';
$lang->execution->copyTeamTip = "copy {$lang->projectCommon}/{$lang->execution->common} team members";
$lang->execution->daysGreaterProject = 'Days cannot be greater than days of execution 『%s』';
$lang->execution->errorHours = 'Hours/Day cannot be greater than『24』';
$lang->execution->agileplusMethodTip = "When creating executions in an Agile Plus {$lang->projectCommon}, both Iteration and Kanban management methods are supported.";
$lang->execution->agileplusMethodTip = "When creating executions in an Agile Plus {$lang->projectCommon}, both {$lang->executionCommon} and Kanban management methods are supported.";
$lang->execution->typeTip = "The sub-stages of other types can be created under the parent stage of the 'mix' type, while the type of other parent-child levels is consistent.";
$lang->execution->waterfallTip = "In the Waterfall {$lang->projectCommon} or in the Waterfall + {$lang->projectCommon},";
+1 -1
View File
@@ -151,7 +151,7 @@ $lang->execution->left = '剩余';
$lang->execution->copyTeamTip = "可以选择复制{$lang->projectCommon}或{$lang->execution->common}团队的成员";
$lang->execution->daysGreaterProject = '可用工日不能大于执行的可用工日『%s』';
$lang->execution->errorHours = '可用工时/天不能大于『24』';
$lang->execution->agileplusMethodTip = "融合敏捷{$lang->projectCommon}创建执行时,支持迭代和看板两种管理方法。";
$lang->execution->agileplusMethodTip = "融合敏捷{$lang->projectCommon}创建执行时,支持{$lang->executionCommon}和看板两种管理方法。";
$lang->execution->typeTip = '“综合”类型的父阶段可以创建其它类型的子级,其它父子层级的类型均一致。';
$lang->execution->waterfallTip = "瀑布{$lang->projectCommon}和融合瀑布{$lang->projectCommon}中,";
+23 -3
View File
@@ -390,11 +390,11 @@ class executionModel extends model
$type = 'sprint';
if($project) $type = zget($this->config->execution->modelList, $project->model, 'sprint');
if(($project->model == 'waterfall' or $project->model == 'waterfallplus') and isset($this->config->setPercent) and $this->config->setPercent == 1)
if($project->model == 'waterfall' or $project->model == 'waterfallplus')
{
$_POST['products'] = array_filter($_POST['products']);
if(empty($_POST['products'])) dao::$errors['products0'] = $this->lang->project->errorNoProducts;
$this->checkWorkload('create', $_POST['percent'], $project);
if(isset($this->config->setPercent) and $this->config->setPercent == 1) $this->checkWorkload('create', $_POST['percent'], $project);
if(dao::isError()) return false;
}
@@ -2864,10 +2864,11 @@ class executionModel extends model
{
$this->loadModel('task');
$dateExceed = '';
$taskStories = array();
$parents = array();
$execution = $this->getByID($executionID);
$tasks = $this->dao->select('id,execution,assignedTo,story,consumed,status,parent')->from(TABLE_TASK)->where('id')->in($this->post->tasks)->fetchAll('id');
$tasks = $this->dao->select('id,execution,assignedTo,story,consumed,status,parent,estStarted,deadline')->from(TABLE_TASK)->where('id')->in($this->post->tasks)->fetchAll('id');
foreach($tasks as $task)
{
/* Save the assignedToes and stories, should linked to execution. */
@@ -2887,6 +2888,13 @@ class executionModel extends model
$data->canceledDate = null;
}
if(!empty($this->config->limitTaskDate))
{
if($task->estStarted < $execution->begin or $task->estStarted > $execution->end or $task->deadline > $execution->end or $task->deadline < $execution->begin) $dateExceed .= "#{$task->id},";
if($task->estStarted < $execution->begin or $task->estStarted > $execution->end) $data->estStarted = $execution->begin;
if($task->deadline > $execution->end or $task->deadline < $execution->begin) $data->deadline = $execution->end;
}
/* Update tasks. */
$this->dao->update(TABLE_TASK)->data($data)->where('id')->eq($task->id)->exec();
unset($data->status);
@@ -2895,6 +2903,12 @@ class executionModel extends model
$this->loadModel('action')->create('task', $task->id, 'moved', '', $task->execution);
}
if(!empty($dateExceed))
{
$dateExceed = trim($dateExceed, ',');
echo js::alert(sprintf($this->lang->task->error->dateExceed, $dateExceed));
}
/* Get stories of children task. */
if(!empty($parents))
{
@@ -3045,6 +3059,12 @@ class executionModel extends model
return false;
}
if(!empty($this->config->limitTaskDate))
{
$this->task->checkEstStartedAndDeadline($executionID, $task->estStarted, $task->deadline);
if(dao::isError()) return false;
}
$tasks[$key] = $task;
}
+2
View File
@@ -1447,6 +1447,7 @@ $lang->resource->custom->kanban = 'kanban';
$lang->resource->custom->code = 'code';
$lang->resource->custom->hours = 'hours';
$lang->resource->custom->percent = 'percent';
$lang->resource->custom->limitTaskDate = 'beginAndEndDate';
$lang->custom->methodOrder[5] = 'index';
$lang->custom->methodOrder[10] = 'set';
@@ -1466,6 +1467,7 @@ $lang->custom->methodOrder[75] = 'kanban';
$lang->custom->methodOrder[80] = 'code';
$lang->custom->methodOrder[85] = 'hours';
$lang->custom->methodOrder[90] = 'percent';
$lang->custom->methodOrder[95] = 'limitTaskDate';
$lang->resource->datatable = new stdclass();
$lang->resource->datatable->setGlobal = 'setGlobal';
-11
View File
@@ -62,17 +62,6 @@ class index extends control
$this->display();
}
/**
* Just test the extension engine.
*
* @access public
* @return void
*/
public function testext()
{
echo $this->fetch('misc', 'getsid');
}
/**
* ajaxClearObjectSession
*
+1
View File
@@ -100,6 +100,7 @@ $lang->job->pipelineVariables = "Variables";
$lang->job->pipelineVariablesKeyPlaceHolder = "Input variable key";
$lang->job->pipelineVariablesValuePlaceHolder = "Input variable value";
$lang->job->pipelineVariablesTips = "Specify variable values to be used in this run. The values specified in CI/CD settings will be used by default.";
$lang->job->setReferenceTips = "Before performing a build, please set up the branch information of the code base.";
$lang->job->featureBar['browse']['job'] = 'List';
$lang->job->featureBar['browse']['compile'] = 'History';
+1
View File
@@ -100,6 +100,7 @@ $lang->job->pipelineVariables = "Variables";
$lang->job->pipelineVariablesKeyPlaceHolder = "Input variable key";
$lang->job->pipelineVariablesValuePlaceHolder = "Input variable value";
$lang->job->pipelineVariablesTips = "Specify variable values to be used in this run. The values specified in CI/CD settings will be used by default.";
$lang->job->setReferenceTips = "Before performing a build, please set up the branch information of the code base.";
$lang->job->featureBar['browse']['job'] = 'List';
$lang->job->featureBar['browse']['compile'] = 'History';
+1
View File
@@ -100,6 +100,7 @@ $lang->job->pipelineVariables = "Variables";
$lang->job->pipelineVariablesKeyPlaceHolder = "Input variable key";
$lang->job->pipelineVariablesValuePlaceHolder = "Input variable value";
$lang->job->pipelineVariablesTips = "Specify variable values to be used in this run. The values specified in CI/CD settings will be used by default.";
$lang->job->setReferenceTips = "Before performing a build, please set up the branch information of the code base.";
$lang->job->featureBar['browse']['job'] = 'List';
$lang->job->featureBar['browse']['compile'] = 'History';
+2
View File
@@ -104,6 +104,7 @@ $lang->misc->feature->visionsDesc = "<p>The concept of interface has been add
$lang->misc->feature->visionsImage = 'theme/default/images/main/visions_en.png';
/* Release Date. */
$lang->misc->releaseDate['18.3'] = '2023-03-15';
$lang->misc->releaseDate['18.2'] = '2023-02-27';
$lang->misc->releaseDate['18.1'] = '2023-02-08';
$lang->misc->releaseDate['18.0'] = '2023-01-03';
@@ -200,6 +201,7 @@ $lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
/* Release Detail. */
$lang->misc->feature->all['18.3'][] = array('title' => 'Language item customization is added in secondary development, which supports the definition of language items for menus and search tags; Editor functionality is added in the secondary development, which allows users to turn it on and off on demand; The forms could be saved temporarily when users exits unexpectedly, and the unsaved information will be filled automatically the next time you enter.', 'desc' => '');
$lang->misc->feature->all['18.2'][] = array('title' => 'Agile Plus and Waterfall Plus management models are newly added. Support for unlimited splitting of waterfall project stages. The UI of Admin is completely upgraded and redesigned. Fix bugs.', 'desc' => '');
$lang->misc->feature->all['18.1'][] = array('title' => 'The automation testing solution interaction is optimized, while a new snapshot management function is newly added. ZenTao IM implemented online collaboration of PPT documents.Fix bugs.', 'desc' => '');
$lang->misc->feature->all['18.0'][] = array('title' => "Automated test solutions are proposed. Work order related functions are added to the Operation Management Interface. Approval workflow support for adding all types of notifications. And at the same time, we have further improved the earned value calculation rules.", 'desc' => '');
+2
View File
@@ -104,6 +104,7 @@ $lang->misc->feature->visionsDesc = "<p>The concept of interface has been add
$lang->misc->feature->visionsImage = 'theme/default/images/main/visions_en.png';
/* Release Date. */
$lang->misc->releaseDate['18.3'] = '2023-03-15';
$lang->misc->releaseDate['18.2'] = '2023-02-27';
$lang->misc->releaseDate['18.1'] = '2023-02-08';
$lang->misc->releaseDate['18.0'] = '2023-01-03';
@@ -200,6 +201,7 @@ $lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
/* Release Detail. */
$lang->misc->feature->all['18.3'][] = array('title' => 'Language item customization is added in secondary development, which supports the definition of language items for menus and search tags; Editor functionality is added in the secondary development, which allows users to turn it on and off on demand; The forms could be saved temporarily when users exits unexpectedly, and the unsaved information will be filled automatically the next time you enter.', 'desc' => '');
$lang->misc->feature->all['18.2'][] = array('title' => 'Agile Plus and Waterfall Plus management models are newly added. Support for unlimited splitting of waterfall project stages. The UI of Admin is completely upgraded and redesigned. Fix bugs.', 'desc' => '');
$lang->misc->feature->all['18.1'][] = array('title' => 'The automation testing solution interaction is optimized, while a new snapshot management function is newly added. ZenTao IM implemented online collaboration of PPT documents.Fix bugs.', 'desc' => '');
$lang->misc->feature->all['18.0'][] = array('title' => "Automated test solutions are proposed. Work order related functions are added to the Operation Management Interface. Approval workflow support for adding all types of notifications. And at the same time, we have further improved the earned value calculation rules.", 'desc' => '');
+2
View File
@@ -104,6 +104,7 @@ $lang->misc->feature->visionsDesc = "<p>The concept of interface has been add
$lang->misc->feature->visionsImage = 'theme/default/images/main/visions_en.png';
/* Release Date. */
$lang->misc->releaseDate['18.3'] = '2023-03-15';
$lang->misc->releaseDate['18.2'] = '2023-02-27';
$lang->misc->releaseDate['18.1'] = '2023-02-08';
$lang->misc->releaseDate['18.0'] = '2023-01-03';
@@ -200,6 +201,7 @@ $lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
/* Release Detail. */
$lang->misc->feature->all['18.3'][] = array('title' => 'Language item customization is added in secondary development, which supports the definition of language items for menus and search tags; Editor functionality is added in the secondary development, which allows users to turn it on and off on demand; The forms could be saved temporarily when users exits unexpectedly, and the unsaved information will be filled automatically the next time you enter.', 'desc' => '');
$lang->misc->feature->all['18.2'][] = array('title' => 'Agile Plus and Waterfall Plus management models are newly added. Support for unlimited splitting of waterfall project stages. The UI of Admin is completely upgraded and redesigned. Fix bugs.', 'desc' => '');
$lang->misc->feature->all['18.1'][] = array('title' => 'The automation testing solution interaction is optimized, while a new snapshot management function is newly added. ZenTao IM implemented online collaboration of PPT documents.Fix bugs.', 'desc' => '');
$lang->misc->feature->all['18.0'][] = array('title' => "Automated test solutions are proposed. Work order related functions are added to the Operation Management Interface. Approval workflow support for adding all types of notifications. And at the same time, we have further improved the earned value calculation rules.", 'desc' => '');
+2
View File
@@ -104,6 +104,7 @@ $lang->misc->feature->visionsDesc = "<p>从16.5开始增加了界面概念,
$lang->misc->feature->visionsImage = 'theme/default/images/main/visions.png';
/* Release Date. */
$lang->misc->releaseDate['18.3'] = '2023-03-15';
$lang->misc->releaseDate['18.2'] = '2023-02-27';
$lang->misc->releaseDate['18.1'] = '2023-02-08';
$lang->misc->releaseDate['18.0'] = '2023-01-03';
@@ -200,6 +201,7 @@ $lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
/* Release Detail. */
$lang->misc->feature->all['18.3'][] = array('title' => '二次开发增加语言项自定义,支持对菜单和检索标签的语言项进行定义;二次开发增加编辑器功能,支持用户按需开启和关闭;表单意外退出支持表单暂存,下次进入自动代入填写的未保存信息。', 'desc' => '');
$lang->misc->feature->all['18.2'][] = array('title' => '新增融合敏捷、融合瀑布管理模型,瀑布项目阶段支持无限级拆分,后台进行全新UI改版。修复Bug。', 'desc' => '');
$lang->misc->feature->all['18.1'][] = array('title' => '自动化测试解决方案交互优化、新增快照管理功能。禅道客户端实现了 PPT文档在线协作。修复Bug。', 'desc' => '');
$lang->misc->feature->all['18.0'][] = array('title' => '推出自动化测试解决方案;运营管理界面增加工单功能;审批流支持增加所有类型的通知以及挣值计算规则完善。', 'desc' => '');
+1 -1
View File
@@ -103,7 +103,7 @@ $lang->my->executionLink = 'Execution Default Page';
$lang->my->programLinkList = array();
$lang->my->programLinkList['program-browse'] = 'Project Set List/View all project sets';
$lang->my->programLinkList['program-kanban'] = 'Project Set Kanban/You can visually view the progress of all project sets';
$lang->my->programLinkList['program-project'] = "{$lang->projectCommon} list of the most recent {$lang->projectCommon} set/You can view all items under the current {$lang->projectCommon} set";
$lang->my->programLinkList['program-project'] = "{$lang->projectCommon} list of the most recent program/You can view all items under the current program";
$lang->my->productLinkList = array();
$lang->my->productLinkList['product-all'] = "{$lang->productCommon} List/Can view all {$lang->productCommon}s";
+1 -1
View File
@@ -103,7 +103,7 @@ $lang->my->executionLink = 'Execution Default Page';
$lang->my->programLinkList = array();
$lang->my->programLinkList['program-browse'] = 'Project Set List/View all project sets';
$lang->my->programLinkList['program-kanban'] = 'Project Set Kanban/You can visually view the progress of all project sets';
$lang->my->programLinkList['program-project'] = "{$lang->projectCommon} list of the most recent {$lang->projectCommon} set/You can view all items under the current {$lang->projectCommon} set";
$lang->my->programLinkList['program-project'] = "{$lang->projectCommon} list of the most recent program/You can view all items under the current program";
$lang->my->productLinkList = array();
$lang->my->productLinkList['product-all'] = "{$lang->productCommon} List/Can view all {$lang->productCommon}s";
+1 -1
View File
@@ -103,7 +103,7 @@ $lang->my->executionLink = 'Execution Default Page';
$lang->my->programLinkList = array();
$lang->my->programLinkList['program-browse'] = 'Project Set List/View all project sets';
$lang->my->programLinkList['program-kanban'] = 'Project Set Kanban/You can visually view the progress of all project sets';
$lang->my->programLinkList['program-project'] = "{$lang->projectCommon} list of the most recent {$lang->projectCommon} set/You can view all items under the current {$lang->projectCommon} set";
$lang->my->programLinkList['program-project'] = "{$lang->projectCommon} list of the most recent program/You can view all items under the current program";
$lang->my->productLinkList = array();
$lang->my->productLinkList['product-all'] = "{$lang->productCommon} List/Can view all {$lang->productCommon}s";
+1 -1
View File
@@ -19,7 +19,7 @@
<div class='main-header'>
<h2><i class='icon-key'></i> <?php echo $lang->my->preference;?></h2>
</div>
<form method='post' target='hiddenwin'>
<form method='post' target='hiddenwin' class='no-stash'>
<table align='center' class='table table-form w-320px'>
<tr>
<th class='w-140px'><?php echo $lang->my->storyConcept;?></th>
+17 -16
View File
@@ -27,8 +27,8 @@ $lang->product->closed = 'Geschlossen';
$lang->product->closedProduct = "Closed {$lang->productCommon}";
$lang->product->updateOrder = 'Ranking';
$lang->product->all = "{$lang->productCommon} List";
$lang->product->manageLine = "Manage {$lang->productCommon} Line";
$lang->product->newLine = "Create {$lang->productCommon} Line";
$lang->product->manageLine = "Manage Product Line";
$lang->product->newLine = "Create Product Line";
$lang->product->export = 'Exportiere Daten';
$lang->product->dashboard = 'Dashboard';
$lang->product->changeProgram = "{$lang->productCommon} confirmation of the scope of influence of adjustment of the program set";
@@ -93,14 +93,15 @@ $lang->product->unfoldClosed = 'Unfold Closed';
$lang->product->confirmDelete = " Möchten Sie {$lang->productCommon} löschen?";
$lang->product->errorNoProduct = "Kein {$lang->productCommon} erstellt!";
$lang->product->accessDenied = "Sie haben keinen Zugriff auf {$lang->productCommon}.";
$lang->product->notExists = "{$lang->productCommon} is not exists!";
$lang->product->programChangeTip = "The {$lang->projectCommon}s linked with this {$lang->productCommon}: %s will be transferred to the modified program set together.";
$lang->product->notChangeProgramTip = "The {$lang->SRCommon} of {$lang->productCommon} has been linked to the following {$lang->projectCommon}s, please cancel the link before proceeding";
$lang->product->confirmChangeProgram = "The {$lang->projectCommon}s linked with this {$lang->productCommon}: %s is also linked with other {$lang->productCommon}s, whether to transfer {$lang->projectCommon}s to the modified program set.";
$lang->product->changeProgramError = "The {$lang->SRCommon} of this {$lang->productCommon} has been linked to the {$lang->projectCommon}, please unlink it before proceeding";
$lang->product->changeLineError = "{$lang->productCommon}s already exist under the {$lang->productCommon} line, so the program within them cannot be modified.";
$lang->product->changeLineError = "{$lang->productCommon}s already exist under the product line, so the program within them cannot be modified.";
$lang->product->programEmpty = 'Program should not be empty!';
$lang->product->nameIsDuplicate = "『%s』 {$lang->productCommon} line already exists, please reset!";
$lang->product->nameIsDuplicated = "{$lang->productCommon} Line『%s』 exists. Go to Admin->System->Data->Recycle Bin to restore it, if you are sure it is deleted.";
$lang->product->nameIsDuplicate = "『%s』 product line already exists, please reset!";
$lang->product->nameIsDuplicated = "Product Line『%s』 exists. Go to Admin->System->Data->Recycle Bin to restore it, if you are sure it is deleted.";
$lang->product->reviewStory = 'You are not a reviewer for needs "%s" , and cannot review. This operation has been filtered';
$lang->product->id = 'ID';
@@ -108,8 +109,8 @@ $lang->product->program = "Program";
$lang->product->name = 'Name';
$lang->product->code = 'Alias';
$lang->product->shadow = "Shadow {$lang->productCommon}";
$lang->product->line = "{$lang->productCommon} Line";
$lang->product->lineName = "{$lang->productCommon} Line Name";
$lang->product->line = "Product Line";
$lang->product->lineName = "Product Line Name";
$lang->product->order = 'Sortierung';
$lang->product->bind = 'In/Depedent';
$lang->product->type = 'Typ';
@@ -232,15 +233,15 @@ $lang->product->featureBar['project']['doing'] = 'In Arbeit';
$lang->product->featureBar['project']['suspended'] = 'Ausgesetzt';
$lang->product->featureBar['project']['closed'] = 'Geschlossen';
$lang->product->moreSelects['more']['openedbyme'] = $lang->product->openedByMe;
$lang->product->moreSelects['more']['reviewedbyme'] = $lang->product->reviewedByMe;
$lang->product->moreSelects['more']['assignedbyme'] = $lang->product->assignedByMe;
$lang->product->moreSelects['more']['closedbyme'] = $lang->product->closedByMe;
$lang->product->moreSelects['more']['activestory'] = $lang->product->activeStory;
$lang->product->moreSelects['more']['changingstory'] = $lang->product->changingStory;
$lang->product->moreSelects['more']['reviewingstory'] = $lang->product->reviewingStory;
$lang->product->moreSelects['more']['willclose'] = $lang->product->willClose;
$lang->product->moreSelects['more']['closedstory'] = $lang->product->closedStory;
$lang->product->moreSelects['browse']['more']['openedbyme'] = $lang->product->openedByMe;
$lang->product->moreSelects['browse']['more']['reviewedbyme'] = $lang->product->reviewedByMe;
$lang->product->moreSelects['browse']['more']['assignedbyme'] = $lang->product->assignedByMe;
$lang->product->moreSelects['browse']['more']['closedbyme'] = $lang->product->closedByMe;
$lang->product->moreSelects['browse']['more']['activestory'] = $lang->product->activeStory;
$lang->product->moreSelects['browse']['more']['changingstory'] = $lang->product->changingStory;
$lang->product->moreSelects['browse']['more']['reviewingstory'] = $lang->product->reviewingStory;
$lang->product->moreSelects['browse']['more']['willclose'] = $lang->product->willClose;
$lang->product->moreSelects['browse']['more']['closedstory'] = $lang->product->closedStory;
$lang->product->featureBar['dynamic']['all'] = 'All';
$lang->product->featureBar['dynamic']['today'] = 'Today';
+17 -16
View File
@@ -27,8 +27,8 @@ $lang->product->closed = 'Closed';
$lang->product->closedProduct = "Closed {$lang->productCommon}";
$lang->product->updateOrder = 'Order';
$lang->product->all = "{$lang->productCommon} List";
$lang->product->manageLine = "Manage {$lang->productCommon} Line";
$lang->product->newLine = "Create {$lang->productCommon} Line";
$lang->product->manageLine = "Manage Product Line";
$lang->product->newLine = "Create Product Line";
$lang->product->export = 'Export';
$lang->product->dashboard = "Dashboard";
$lang->product->changeProgram = "{$lang->productCommon} confirmation of the scope of influence of adjustment of the program set";
@@ -93,14 +93,15 @@ $lang->product->unfoldClosed = 'Unfold Closed';
$lang->product->confirmDelete = " Do you want to delete the {$lang->productCommon}?";
$lang->product->errorNoProduct = "No {$lang->productCommon} is created yet!";
$lang->product->accessDenied = "You have no access to the {$lang->productCommon}.";
$lang->product->notExists = "{$lang->productCommon} is not exists!";
$lang->product->programChangeTip = "The {$lang->projectCommon}s linked with this {$lang->productCommon}: %s will be transferred to the modified program set together.";
$lang->product->notChangeProgramTip = "The {$lang->SRCommon} of {$lang->productCommon} has been linked to the following {$lang->projectCommon}s, please cancel the link before proceeding";
$lang->product->confirmChangeProgram = "The {$lang->projectCommon}s linked with this {$lang->productCommon}: %s is also linked with other {$lang->productCommon}s, whether to transfer {$lang->projectCommon}s to the modified program set.";
$lang->product->changeProgramError = "The {$lang->SRCommon} of this {$lang->productCommon} has been linked to the {$lang->projectCommon}, please unlink it before proceeding";
$lang->product->changeLineError = "{$lang->productCommon}s already exist under the {$lang->productCommon} line, so the program within them cannot be modified.";
$lang->product->changeLineError = "{$lang->productCommon}s already exist under the product line, so the program within them cannot be modified.";
$lang->product->programEmpty = 'Program should not be empty!';
$lang->product->nameIsDuplicate = "『%s』 {$lang->productCommon} line already exists, please reset!";
$lang->product->nameIsDuplicated = "{$lang->productCommon} Line『%s』 exists. Go to Admin->System->Data->Recycle Bin to restore it, if you are sure it is deleted.";
$lang->product->nameIsDuplicate = "『%s』 product line already exists, please reset!";
$lang->product->nameIsDuplicated = "Product Line『%s』 exists. Go to Admin->System->Data->Recycle Bin to restore it, if you are sure it is deleted.";
$lang->product->reviewStory = 'You are not a reviewer for needs "%s" , and cannot review. This operation has been filtered';
$lang->product->id = 'ID';
@@ -108,8 +109,8 @@ $lang->product->program = "Program";
$lang->product->name = "{$lang->productCommon} Name";
$lang->product->code = 'Code';
$lang->product->shadow = "Shadow {$lang->productCommon}";
$lang->product->line = "{$lang->productCommon} Line";
$lang->product->lineName = "{$lang->productCommon} Line Name";
$lang->product->line = "Product Line";
$lang->product->lineName = "Product Line Name";
$lang->product->order = 'Rank';
$lang->product->bind = 'In/Depedent';
$lang->product->type = 'Type';
@@ -232,15 +233,15 @@ $lang->product->featureBar['project']['doing'] = 'Doing';
$lang->product->featureBar['project']['suspended'] = 'Suspended';
$lang->product->featureBar['project']['closed'] = 'Closed';
$lang->product->moreSelects['openedbyme'] = $lang->product->openedByMe;
$lang->product->moreSelects['reviewedbyme'] = $lang->product->reviewedByMe;
$lang->product->moreSelects['assignedbyme'] = $lang->product->assignedByMe;
$lang->product->moreSelects['closedbyme'] = $lang->product->closedByMe;
$lang->product->moreSelects['activestory'] = $lang->product->activeStory;
$lang->product->moreSelects['changingstory'] = $lang->product->changingStory;
$lang->product->moreSelects['reviewingstory'] = $lang->product->reviewingStory;
$lang->product->moreSelects['willclose'] = $lang->product->willClose;
$lang->product->moreSelects['closedstory'] = $lang->product->closedStory;
$lang->product->moreSelects['browse']['more']['openedbyme'] = $lang->product->openedByMe;
$lang->product->moreSelects['browse']['more']['reviewedbyme'] = $lang->product->reviewedByMe;
$lang->product->moreSelects['browse']['more']['assignedbyme'] = $lang->product->assignedByMe;
$lang->product->moreSelects['browse']['more']['closedbyme'] = $lang->product->closedByMe;
$lang->product->moreSelects['browse']['more']['activestory'] = $lang->product->activeStory;
$lang->product->moreSelects['browse']['more']['changingstory'] = $lang->product->changingStory;
$lang->product->moreSelects['browse']['more']['reviewingstory'] = $lang->product->reviewingStory;
$lang->product->moreSelects['browse']['more']['willclose'] = $lang->product->willClose;
$lang->product->moreSelects['browse']['more']['closedstory'] = $lang->product->closedStory;
$lang->product->featureBar['dynamic']['all'] = 'All';
$lang->product->featureBar['dynamic']['today'] = 'Today';
+17 -16
View File
@@ -27,8 +27,8 @@ $lang->product->closed = 'Fermés';
$lang->product->closedProduct = "Closed {$lang->productCommon}";
$lang->product->updateOrder = 'Ordre';
$lang->product->all = "{$lang->productCommon} List";
$lang->product->manageLine = "Manage {$lang->productCommon} Line";
$lang->product->newLine = "Create {$lang->productCommon} Line";
$lang->product->manageLine = "Manage Product Line";
$lang->product->newLine = "Create Product Line";
$lang->product->export = 'Export';
$lang->product->dashboard = "Dashboard";
$lang->product->changeProgram = "{$lang->productCommon} confirmation of the scope of influence of adjustment of the program set";
@@ -93,14 +93,15 @@ $lang->product->unfoldClosed = 'Unfold Closed';
$lang->product->confirmDelete = "Voulez-vous vraiment supprimer le {$lang->productCommon} ?";
$lang->product->errorNoProduct = "Aucun {$lang->productCommon} n'est créé pour l'instant !";
$lang->product->accessDenied = "Vous n'avez pas accès au {$lang->productCommon}.";
$lang->product->notExists = "{$lang->productCommon} is not exists!";
$lang->product->programChangeTip = "The {$lang->projectCommon}s linked with this {$lang->productCommon}: %s will be transferred to the modified program set together.";
$lang->product->notChangeProgramTip = "The {$lang->SRCommon} of {$lang->productCommon} has been linked to the following {$lang->projectCommon}s, please cancel the link before proceeding";
$lang->product->confirmChangeProgram = "The {$lang->projectCommon}s linked with this {$lang->productCommon}: %s is also linked with other {$lang->productCommon}s, whether to transfer {$lang->projectCommon}s to the modified program set.";
$lang->product->changeProgramError = "The {$lang->SRCommon} of this {$lang->productCommon} has been linked to the {$lang->projectCommon}, please unlink it before proceeding";
$lang->product->changeLineError = "{$lang->productCommon}s already exist under the {$lang->productCommon} line, so the program within them cannot be modified.";
$lang->product->changeLineError = "{$lang->productCommon}s already exist under the product line, so the program within them cannot be modified.";
$lang->product->programEmpty = 'Program should not be empty!';
$lang->product->nameIsDuplicate = "『%s』 {$lang->productCommon} line already exists, please reset!";
$lang->product->nameIsDuplicated = "{$lang->productCommon} Line『%s』 exists. Go to Admin->System->Data->Recycle Bin to restore it, if you are sure it is deleted.";
$lang->product->nameIsDuplicate = "『%s』 product line already exists, please reset!";
$lang->product->nameIsDuplicated = "Product Line『%s』 exists. Go to Admin->System->Data->Recycle Bin to restore it, if you are sure it is deleted.";
$lang->product->reviewStory = 'You are not a reviewer for needs "%s" , and cannot review. This operation has been filtered';
$lang->product->id = 'ID';
@@ -108,8 +109,8 @@ $lang->product->program = "Program";
$lang->product->name = "Nom du {$lang->productCommon}";
$lang->product->code = 'Code';
$lang->product->shadow = "Shadow {$lang->productCommon}";
$lang->product->line = "{$lang->productCommon} Line";
$lang->product->lineName = "{$lang->productCommon} Line Name";
$lang->product->line = "Product Line";
$lang->product->lineName = "Product Line Name";
$lang->product->order = 'Rang';
$lang->product->bind = 'In/Depedent';
$lang->product->type = 'Type';
@@ -232,15 +233,15 @@ $lang->product->featureBar['project']['doing'] = 'En cours';
$lang->product->featureBar['project']['suspended'] = 'Suspendu';
$lang->product->featureBar['project']['closed'] = 'Fermé';
$lang->product->moreSelects['more']['openedbyme'] = $lang->product->openedByMe;
$lang->product->moreSelects['more']['reviewedbyme'] = $lang->product->reviewedByMe;
$lang->product->moreSelects['more']['assignedbyme'] = $lang->product->assignedByMe;
$lang->product->moreSelects['more']['closedbyme'] = $lang->product->closedByMe;
$lang->product->moreSelects['more']['activestory'] = $lang->product->activeStory;
$lang->product->moreSelects['more']['changingstory'] = $lang->product->changingStory;
$lang->product->moreSelects['more']['reviewingstory'] = $lang->product->reviewingStory;
$lang->product->moreSelects['more']['willclose'] = $lang->product->willClose;
$lang->product->moreSelects['more']['closedstory'] = $lang->product->closedStory;
$lang->product->moreSelects['browse']['more']['openedbyme'] = $lang->product->openedByMe;
$lang->product->moreSelects['browse']['more']['reviewedbyme'] = $lang->product->reviewedByMe;
$lang->product->moreSelects['browse']['more']['assignedbyme'] = $lang->product->assignedByMe;
$lang->product->moreSelects['browse']['more']['closedbyme'] = $lang->product->closedByMe;
$lang->product->moreSelects['browse']['more']['activestory'] = $lang->product->activeStory;
$lang->product->moreSelects['browse']['more']['changingstory'] = $lang->product->changingStory;
$lang->product->moreSelects['browse']['more']['reviewingstory'] = $lang->product->reviewingStory;
$lang->product->moreSelects['browse']['more']['willclose'] = $lang->product->willClose;
$lang->product->moreSelects['browse']['more']['closedstory'] = $lang->product->closedStory;
$lang->product->featureBar['dynamic']['all'] = 'All';
$lang->product->featureBar['dynamic']['today'] = 'Today';
+11 -10
View File
@@ -27,8 +27,8 @@ $lang->product->closed = '已关闭';
$lang->product->closedProduct = "已关闭的{$lang->productCommon}";
$lang->product->updateOrder = '排序';
$lang->product->all = "所有{$lang->productCommon}";
$lang->product->manageLine = "维护{$lang->productCommon}线";
$lang->product->newLine = "新建{$lang->productCommon}线";
$lang->product->manageLine = "维护产品线";
$lang->product->newLine = "新建产品线";
$lang->product->export = '导出数据';
$lang->product->dashboard = "{$lang->productCommon}仪表盘";
$lang->product->changeProgram = "{$lang->productCommon}调整所属项目集影响范围确认";
@@ -93,14 +93,15 @@ $lang->product->unfoldClosed = '展开已关闭';
$lang->product->confirmDelete = " 您确定删除该{$lang->productCommon}吗?";
$lang->product->errorNoProduct = "还没有创建{$lang->productCommon}!";
$lang->product->accessDenied = "您无权访问该{$lang->productCommon}";
$lang->product->programChangeTip = "如下{$lang->projectCommon}只关联了该{$lang->productCommon}, 将直接转移至新{$lang->projectCommon}集下。";
$lang->product->notExists = "该{$lang->productCommon}不存在!";
$lang->product->programChangeTip = "如下{$lang->projectCommon}只关联了该{$lang->productCommon}, 将直接转移至新项目集下。";
$lang->product->notChangeProgramTip = "该{$lang->productCommon}的{$lang->SRCommon}已经关联到如下{$lang->projectCommon},请点击{$lang->projectCommon}名称进入{$lang->SRCommon}列表取消关联后再操作";
$lang->product->confirmChangeProgram = "如下{$lang->projectCommon}既关联了该{$lang->productCommon}又关联了其他{$lang->productCommon},请确认是否继续关联该{$lang->productCommon},勾选后将取消与其他{$lang->productCommon}的关联关系,同时转移至新{$lang->projectCommon}集下。";
$lang->product->confirmChangeProgram = "如下{$lang->projectCommon}既关联了该{$lang->productCommon}又关联了其他{$lang->productCommon},请确认是否继续关联该{$lang->productCommon},勾选后将取消与其他{$lang->productCommon}的关联关系,同时转移至新项目集下。";
$lang->product->changeProgramError = "该{$lang->productCommon}的{$lang->SRCommon}已经关联到{$lang->projectCommon},请取消关联后再操作";
$lang->product->changeLineError = "{$lang->productCommon}线下已有{$lang->productCommon},不可修改所属{$lang->projectCommon}集。";
$lang->product->programEmpty = '{$lang->projectCommon}集不能为空';
$lang->product->nameIsDuplicate = "『%s』{$lang->productCommon}线已经存在,请重新设置!";
$lang->product->nameIsDuplicated = "{$lang->productCommon}线已经有『%s』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。";
$lang->product->changeLineError = "产品线下已有{$lang->productCommon},不可修改所属项目集。";
$lang->product->programEmpty = '项目集不能为空';
$lang->product->nameIsDuplicate = "『%s』产品线已经存在,请重新设置!";
$lang->product->nameIsDuplicated = "产品线已经有『%s』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。";
$lang->product->reviewStory = '您不是研发需求 "%s" 的评审人,无法评审,本次操作已被过滤。';
$lang->product->id = '编号';
@@ -108,8 +109,8 @@ $lang->product->program = "所属项目集";
$lang->product->name = "{$lang->productCommon}名称";
$lang->product->code = "{$lang->productCommon}代号";
$lang->product->shadow = "是否影子{$lang->productCommon}";
$lang->product->line = "{$lang->productCommon}线";
$lang->product->lineName = "{$lang->productCommon}线名称";
$lang->product->line = "产品线";
$lang->product->lineName = "产品线名称";
$lang->product->order = '排序';
$lang->product->bind = "是否独立{$lang->productCommon}";
$lang->product->type = "{$lang->productCommon}类型";
+9 -4
View File
@@ -177,13 +177,14 @@ class productModel extends model
if(!isset($products[$this->session->product]))
{
$product = $this->getById($productID);
if(empty($product) or $product->deleted == 1) $productID = key($products);
$this->session->set('product', (int)$productID, $this->app->tab);
if($productID && strpos(",{$this->app->user->view->products},", ",{$productID},") === false)
{
$productID = key($products);
$this->session->set('product', (int)$productID, $this->app->tab);
$this->accessDenied();
$this->accessDenied($this->lang->product->accessDenied);
}
}
@@ -216,14 +217,15 @@ class productModel extends model
/**
* Show accessDenied response.
*
* @param string $tips
* @access private
* @return void
*/
public function accessDenied()
public function accessDenied($tips)
{
if(defined('TUTORIAL')) return true;
echo(js::alert($this->lang->product->accessDenied));
echo(js::alert($tips));
if(!$this->server->http_referer) return print(js::locate(helper::createLink('product', 'index')));
@@ -1485,6 +1487,7 @@ class productModel extends model
$executionName = $projectID != 0 ? '' : $execution->projectName;
foreach($paths as $path)
{
if(!isset($allExecutions[$path])) continue;
$executionName .= '/' . $allExecutions[$path]->name;
}
@@ -2580,9 +2583,11 @@ class productModel extends model
*/
public function setMenu($productID, $branch = '', $module = 0, $moduleType = '', $extra = '')
{
if(!$this->app->user->admin and strpos(",{$this->app->user->view->products},", ",$productID,") === false and $productID != 0 and !defined('TUTORIAL')) return $this->accessDenied();
if(!$this->app->user->admin and strpos(",{$this->app->user->view->products},", ",$productID,") === false and $productID != 0 and !defined('TUTORIAL')) return $this->accessDenied($this->lang->product->accessDenied);
$product = $this->getByID($productID);
if(!empty($product) and $product->shadow) $this->accessDenied($this->lang->product->notExists);
$params = array('branch' => $branch);
common::setMenuVars('product', $productID, $params);
if(!$product) return;
+24 -6
View File
@@ -874,8 +874,8 @@ class programModel extends model
$this->loadModel('user');
if($program->acl != 'open') $this->user->updateUserView($programID, 'program');
/* If the program changes, the authorities of programs and projects under the program should be refreshed. */
$children = $this->dao->select('id, type')->from(TABLE_PROGRAM)->where('path')->like("%,{$programID},%")->andWhere('id')->ne($programID)->andWhere('acl')->eq('program')->fetchPairs('id', 'type');
/* If the program changes, the authorities of programs and projects under the program should be refreshed. */
$children = $this->dao->select('id, type')->from(TABLE_PROGRAM)->where('path')->like("%,{$programID},%")->andWhere('id')->ne($programID)->andWhere('acl')->eq('program')->fetchPairs('id', 'type');
foreach($children as $id => $type) $this->user->updateUserView($id, $type);
if(isset($program->PM) and $program->PM != $oldProgram->PM)
{
@@ -888,11 +888,29 @@ class programModel extends model
$this->processNode($programID, $program->parent, $oldProgram->path, $oldProgram->grade);
/* Move product to new top program. */
if($oldProgram->parent == 0)
$oldTopProgram = $this->getTopByPath($oldProgram->path);
$newTopProgram = $this->getTopByID($programID);
if($oldTopProgram != $newTopProgram)
{
$oldTopProgram = $this->getTopByPath($oldProgram->path);
$newTopProgram = $this->getTopByID($programID);
if($oldTopProgram != $newTopProgram) $this->dao->update(TABLE_PRODUCT)->set('program')->eq($newTopProgram)->where('program')->eq($oldTopProgram)->exec();
if($oldProgram->parent == 0)
{
$this->dao->update(TABLE_PRODUCT)->set('program')->eq($newTopProgram)->where('program')->eq($oldTopProgram)->exec();
}
else
{
/* Get the shadow products that produced by the program's no product projects. */
$shadowProducts = $this->dao->select('t1.id')->from(TABLE_PRODUCT)->alias('t1')
->leftJoin(TABLE_PROJECTPRODUCT)->alias('t2')->on('t1.id=t2.product')
->leftJoin(TABLE_PROJECT)->alias('t3')->on('t2.project=t3.id')
->where('t3.path')->like("%,$programID,%")
->andWhere('t3.type')->eq('project')
->andWhere('t3.hasProduct')->eq('0')
->andWhere('t1.shadow')->eq('1')
->fetchPairs();
$this->dao->update(TABLE_PRODUCT)->set('program')->eq($newTopProgram)->where('id')->in($shadowProducts)->exec();
}
}
}
+1 -1
View File
@@ -61,7 +61,7 @@
&nbsp;<span class="icon icon-cards-view" style="color: #888fa1;"></span>
<?php echo ($app->user->admin or strpos(",{$app->user->view->programs},", ",$program->id,") !== false) ? html::a($this->createLink('program', 'product', "programID=$program->id"), $program->name) : $program->name;?>
<?php else:?>
<?php echo html::a($this->createLink('project', 'index', "projectID=$program->id", '', '', $program->id), $program->name, '', "class='text-ellipsis text-primary' title='{$program->name}'");?>
<?php echo html::a($this->createLink('project', 'index', "projectID=$program->id", '', '', $program->id), $program->name, '', "class='text-ellipsis' title='{$program->name}'");?>
<?php
if($program->status != 'done' and $program->status != 'closed' and $program->status != 'suspended')
{
+1
View File
@@ -1,3 +1,4 @@
#planForm tr td {vertical-align: top;}
#mainContent .methodTitle, #mainContent .methodTip {display: inline-block; vertical-align: middle;}
.type-list-radio {display: inline-block; padding: 10px 5px;}
#planForm .c-attribute {width: 110px;}
+1 -1
View File
@@ -73,7 +73,7 @@ $lang->programplan->emptyBegin = '『Begin』should not be blank';
$lang->programplan->emptyEnd = '『End』should not be blank';
$lang->programplan->checkBegin = '『Begin』should be valid date';
$lang->programplan->checkEnd = '『End』should be valid date';
$lang->programplan->methodTip = "You can choose to continue creating stages or Iterations/Kanban for work in this stage. It's not supported to further split the Iteration/Kanban.";
$lang->programplan->methodTip = "You can choose to continue creating stages or {$lang->executionCommon}/Kanban for work in this stage. It's not supported to further split the {$lang->executionCommon}/Kanban.";
$lang->programplan->milestoneList[1] = 'Yes';
$lang->programplan->milestoneList[0] = 'No';
+1 -1
View File
@@ -73,7 +73,7 @@ $lang->programplan->emptyBegin = '『Begin』should not be blank';
$lang->programplan->emptyEnd = '『End』should not be blank';
$lang->programplan->checkBegin = '『Begin』should be valid date';
$lang->programplan->checkEnd = '『End』should be valid date';
$lang->programplan->methodTip = "You can choose to continue creating stages or Iterations/Kanban for work in this stage. It's not supported to further split the Iteration/Kanban.";
$lang->programplan->methodTip = "You can choose to continue creating stages or {$lang->executionCommon}/Kanban for work in this stage. It's not supported to further split the {$lang->executionCommon}/Kanban.";
$lang->programplan->milestoneList[1] = 'Yes';
$lang->programplan->milestoneList[0] = 'No';
+1 -1
View File
@@ -73,7 +73,7 @@ $lang->programplan->emptyBegin = '『Begin』should not be blank';
$lang->programplan->emptyEnd = '『End』should not be blank';
$lang->programplan->checkBegin = '『Begin』should be valid date';
$lang->programplan->checkEnd = '『End』should be valid date';
$lang->programplan->methodTip = "You can choose to continue creating stages or Iterations/Kanban for work in this stage. It's not supported to further split the Iteration/Kanban.";
$lang->programplan->methodTip = "You can choose to continue creating stages or {$lang->executionCommon}/Kanban for work in this stage. It's not supported to further split the {$lang->executionCommon}/Kanban.";
$lang->programplan->milestoneList[1] = 'Yes';
$lang->programplan->milestoneList[0] = 'No';
+1 -1
View File
@@ -73,7 +73,7 @@ $lang->programplan->emptyBegin = '『计划开始』日期不能为空';
$lang->programplan->emptyEnd = '『计划完成』日期不能为空';
$lang->programplan->checkBegin = '『计划开始』应当为合法的日期';
$lang->programplan->checkEnd = '『计划完成』应当为合法的日期';
$lang->programplan->methodTip = '您可以在该阶段下选择继续创建阶段或创建迭代/看板进行工作。迭代/看板不支持继续拆分。';
$lang->programplan->methodTip = "您可以在该阶段下选择继续创建阶段或创建{$lang->executionCommon}/看板进行工作。{$lang->executionCommon}/看板不支持继续拆分。";
$lang->programplan->milestoneList[1] = '是';
$lang->programplan->milestoneList[0] = '否';
+6
View File
@@ -745,6 +745,12 @@ class programplanModel extends model
$datas[] = $plan;
}
if(empty($datas))
{
dao::$errors['message'][] = sprintf($this->lang->error->notempty, $this->lang->programplan->name);
return false;
}
$totalPercent = 0;
$totalDevType = 0;
+2 -2
View File
@@ -308,8 +308,8 @@ $lang->project->featureBar['testcase']['autocase'] = 'Automated';
$lang->project->featureBar['build']['all'] = 'Build List';
$lang->project->aclList["private"] = "Private (For the {$lang->projectCommon} leader, team members and stakeholders only)";
$lang->project->aclList["open"] = "Open (accessible with {$lang->projectCommon} view permissions)";
$lang->project->aclList['private'] = "Private (For the {$lang->projectCommon} leader, team members and stakeholders only)";
$lang->project->aclList['open'] = "Open (accessible with {$lang->projectCommon} view permissions)";
$lang->project->multipleList['1'] = 'Yes';
$lang->project->multipleList['0'] = 'No';
+2 -2
View File
@@ -308,8 +308,8 @@ $lang->project->featureBar['testcase']['autocase'] = 'Automated';
$lang->project->featureBar['build']['all'] = 'Build List';
$lang->project->aclList["private"] = "Private (For the {$lang->projectCommon} leader, team members and stakeholders only)";
$lang->project->aclList["open"] = "Open (accessible with {$lang->projectCommon} view permissions)";
$lang->project->aclList['private'] = "Private (For the {$lang->projectCommon} leader, team members and stakeholders only)";
$lang->project->aclList['open'] = "Open (accessible with {$lang->projectCommon} view permissions)";
$lang->project->multipleList['1'] = 'Yes';
$lang->project->multipleList['0'] = 'No';
+2 -2
View File
@@ -308,8 +308,8 @@ $lang->project->featureBar['testcase']['autocase'] = 'Automated';
$lang->project->featureBar['build']['all'] = 'Build List';
$lang->project->aclList["private"] = "Private (For the {$lang->projectCommon} leader, team members and stakeholders only)";
$lang->project->aclList["open"] = "Open (accessible with {$lang->projectCommon} view permissions)";
$lang->project->aclList['private'] = "Private (For the {$lang->projectCommon} leader, team members and stakeholders only)";
$lang->project->aclList['open'] = "Open (accessible with {$lang->projectCommon} view permissions)";
$lang->project->multipleList['1'] = 'Yes';
$lang->project->multipleList['0'] = 'No';
+1 -1
View File
@@ -2303,7 +2303,7 @@ class projectModel extends model
if(!empty($suffix) or !empty($prefix)) echo '<div class="project-name' . (empty($prefix) ? '' : ' has-prefix') . (empty($suffix) ? '' : ' has-suffix') . '">';
if(!empty($prefix)) echo $prefix;
if($this->config->vision == 'rnd') $projectIcon = "<i class='text-muted icon icon-{$projectType}'></i> ";
echo html::a($projectLink, $projectIcon . $project->name, '', "class='text-ellipsis text-primary'");
echo html::a($projectLink, $projectIcon . $project->name, '', "class='text-ellipsis'");
if(!empty($suffix)) echo $suffix;
if(!empty($suffix) or !empty($prefix)) echo '</div>';
break;
+11 -21
View File
@@ -326,7 +326,8 @@ class projectrelease extends control
$this->view->bugPager = $bugPager;
$this->view->leftBugPager = $leftBugPager;
$this->view->builds = $this->loadModel('build')->getBuildPairs($release->product, 'all', 'withbranch|hasproject', 0, 'execution', '', false);
$this->view->summary = $this->product->summary($stories);
$this->view->summary = $this->product->summary($stories);
$this->view->storyCases = $this->loadModel('testcase')->getStoryCaseCounts(array_keys($stories));
if($this->app->getViewType() == 'json')
{
@@ -446,9 +447,7 @@ class projectrelease extends control
$html .= "<h3>{$this->lang->release->stories}</h3>";
$this->loadModel('story');
$stories = $this->dao->select('id, title')->from(TABLE_STORY)->where($this->session->storyQueryCondition)
->beginIF($this->session->storyOrderBy != false)->orderBy($this->session->storyOrderBy)->fi()
->fetchAll('id');
$stories = $this->dbh->query($this->session->storyQueryCondition . " ORDER BY " . strtr($this->session->storyOrderBy, '_', ' '))->fetchAll();
foreach($stories as $story) $story->title = "<a href='" . common::getSysURL() . $this->createLink('story', 'view', "storyID=$story->id") . "' target='_blank'>$story->title</a>";
@@ -640,26 +639,17 @@ class projectrelease extends control
* @access public
* @return void
*/
public function unlinkStory($releaseID, $storyID)
public function unlinkStory($releaseID, $storyID, $confirm = 'no')
{
$this->projectrelease->unlinkStory($releaseID, $storyID);
/* if ajax request, send result. */
if($this->server->ajax)
if($confirm == 'no')
{
if(dao::isError())
{
$response['result'] = 'fail';
$response['message'] = dao::getError();
}
else
{
$response['result'] = 'success';
$response['message'] = '';
}
return $this->send($response);
return print(js::confirm($this->lang->release->confirmUnlinkStory, inlink('unlinkstory', "releaseID=$releaseID&storyID=$storyID&confirm=yes")));
}
else
{
$this->projectrelease->unlinkStory($releaseID, $storyID);
return print(js::reload('parent'));
}
return print(js::reload('parent'));
}
/**
+45 -3
View File
@@ -10,9 +10,9 @@ function showLink(releaseID, type, param)
/**
* Load URL.
*
* @param string $url
* @param string$type
*
* @param string $url
* @param string$type
* @access public
* @return void
*/
@@ -69,4 +69,46 @@ $(function()
infoShowed = true;
}
});
$('.table-story').table(
{
statisticCreator: function(table)
{
var $checkedRows = table.getTable().find(table.isDataTable ? '.datatable-row-left.checked' : 'tbody>tr.checked');
var $originTable = table.isDataTable ? table.$.find('.datatable-origin') : null;
var checkedTotal = $checkedRows.length;
if(!checkedTotal) return;
var checkedEstimate = 0;
var checkedCase = 0;
var rateCount = checkedTotal;
$checkedRows.each(function()
{
var $row = $(this);
if($originTable)
{
$row = $originTable.find('tbody>tr[data-id="' + $row.data('id') + '"]');
}
var data = $row.data();
checkedEstimate += data.estimate;
if(data.cases > 0)
{
checkedCase += 1;
}
else if(data.children != undefined && data.children > 0)
{
rateCount -= 1;
}
});
var rate = '0%';
if(rateCount) rate = Math.round(checkedCase / rateCount * 100) + '%';
if(checkedTotal == 0) return storySummary;
return checkedSummary.replace('%total%', checkedTotal)
.replace('%estimate%', checkedEstimate.toFixed(1))
.replace('%rate%', rate);
}
});
})
+8 -3
View File
@@ -14,6 +14,9 @@
<?php include '../../common/view/tablesorter.html.php';?>
<?php js::set('confirmUnlinkStory', $lang->release->confirmUnlinkStory)?>
<?php js::set('confirmUnlinkBug', $lang->release->confirmUnlinkBug)?>
<?php js::set('storySummary', $summary);?>
<?php js::set('storyCommon', $lang->SRCommon);?>
<?php js::set('checkedSummary', str_replace('%storyCommon%', $lang->SRCommon, $lang->product->checkedSummary));?>
<div id='mainMenu' class='clearfix'>
<div class='btn-toolbar pull-left'>
<?php $browseLink = $this->session->releaseList ? $this->session->releaseList : inlink('browse', "productID=$release->product");?>
@@ -52,7 +55,7 @@
<div class='actions'><?php echo html::a("javascript:showLink({$release->id}, \"story\")", '<i class="icon-link"></i> ' . $lang->release->linkStory, '', "class='btn btn-primary'");?></div>
<div class='linkBox cell hidden'></div>
<?php endif;?>
<form class='main-table table-story' method='post' id='linkedStoriesForm' data-ride="table">
<form class='main-table table-story' method='post' id='linkedStoriesForm' data-ride="">
<table class='table has-sort-head' id='storyList'>
<?php
$canBatchUnlink = common::hasPriv('projectrelease', 'batchUnlinkStory');
@@ -82,7 +85,7 @@
<tbody class='text-center'>
<?php foreach($stories as $storyID => $story):?>
<?php $storyLink = $this->createLink('story', 'view', "storyID=$story->id&version=0&param={$this->session->project}", '', true);?>
<tr>
<tr data-id='<?php echo $story->id;?>' data-estimate='<?php echo $story->estimate?>' <?php if(!empty($story->children)) echo "data-children=" . count($story->children);?> data-cases='<?php echo zget($storyCases, $story->id, 0);?>'>
<td class='c-id text-left'>
<?php if(($canBatchUnlink or $canBatchClose) and $canBeChanged):?>
<div class="checkbox-primary">
@@ -111,7 +114,7 @@
if(common::hasPriv('projectrelease', 'unlinkStory') and $canBeChanged)
{
$unlinkURL = $this->createLink('projectrelease', 'unlinkStory', "releaseID=$release->id&story=$story->id");
echo html::a("javascript:ajaxDelete(\"$unlinkURL\", \"storyList\", confirmUnlinkStory)", '<i class="icon-unlink"></i>', '', "class='btn' title='{$lang->release->unlinkStory}'");
echo html::a($unlinkURL, '<i class="icon-unlink"></i>', 'hiddenwin', "class='btn' title='{$lang->release->unlinkStory}'");
}
?>
</td>
@@ -137,6 +140,8 @@
}
?>
</div>
<?php endif;?>
<?php if($this->app->getViewType() != 'xhtml'):?>
<div class='table-statistic'><?php echo $summary;?></div>
<?php endif;?>
<?php
+11 -20
View File
@@ -255,6 +255,7 @@ class release extends control
$this->view->leftBugPager = $leftBugPager;
$this->view->builds = $this->loadModel('build')->getBuildPairs($release->product, 'all', 'withbranch|hasproject', 0, 'execution', '', false);
$this->view->summary = $this->product->summary($stories);
$this->view->storyCases = $this->loadModel('testcase')->getStoryCaseCounts(array_keys($stories));
if($this->app->getViewType() == 'json')
{
@@ -367,9 +368,7 @@ class release extends control
$html .= "<h3>{$this->lang->release->stories}</h3>";
$this->loadModel('story');
$stories = $this->dao->select('id, title')->from(TABLE_STORY)->where($this->session->storyQueryCondition)
->beginIF($this->session->storyOrderBy != false)->orderBy($this->session->storyOrderBy)->fi()
->fetchAll('id');
$stories = $this->dbh->query($this->session->storyQueryCondition . " ORDER BY " . strtr($this->session->storyOrderBy, '_', ' '))->fetchAll();
foreach($stories as $story) $story->title = "<a href='" . common::getSysURL() . $this->createLink('story', 'view', "storyID=$story->id") . "' target='_blank'>$story->title</a>";
@@ -562,26 +561,18 @@ class release extends control
* @access public
* @return void
*/
public function unlinkStory($releaseID, $storyID)
public function unlinkStory($releaseID, $storyID, $confirm = 'no')
{
$this->release->unlinkStory($releaseID, $storyID);
/* if ajax request, send result. */
if($this->server->ajax)
if($confirm == 'no')
{
if(dao::isError())
{
$response['result'] = 'fail';
$response['message'] = dao::getError();
}
else
{
$response['result'] = 'success';
$response['message'] = '';
}
return $this->send($response);
return print(js::confirm($this->lang->release->confirmUnlinkStory, inlink('unlinkstory', "releaseID=$releaseID&storyID=$storyID&confirm=yes")));
}
else
{
$this->release->unlinkStory($releaseID, $storyID);
return print(js::reload('parent'));
}
echo js::reload('parent');
}
/**
+42
View File
@@ -69,4 +69,46 @@ $(function()
infoShowed = true;
}
});
$('.table-story').table(
{
statisticCreator: function(table)
{
var $checkedRows = table.getTable().find(table.isDataTable ? '.datatable-row-left.checked' : 'tbody>tr.checked');
var $originTable = table.isDataTable ? table.$.find('.datatable-origin') : null;
var checkedTotal = $checkedRows.length;
if(!checkedTotal) return;
var checkedEstimate = 0;
var checkedCase = 0;
var rateCount = checkedTotal;
$checkedRows.each(function()
{
var $row = $(this);
if($originTable)
{
$row = $originTable.find('tbody>tr[data-id="' + $row.data('id') + '"]');
}
var data = $row.data();
checkedEstimate += data.estimate;
if(data.cases > 0)
{
checkedCase += 1;
}
else if(data.children != undefined && data.children > 0)
{
rateCount -= 1;
}
});
var rate = '0%';
if(rateCount) rate = Math.round(checkedCase / rateCount * 100) + '%';
if(checkedTotal == 0) return storySummary;
return checkedSummary.replace('%total%', checkedTotal)
.replace('%estimate%', checkedEstimate.toFixed(1))
.replace('%rate%', rate);
}
});
})
+8 -3
View File
@@ -14,6 +14,9 @@
<?php include '../../common/view/tablesorter.html.php';?>
<?php js::set('confirmUnlinkStory', $lang->release->confirmUnlinkStory)?>
<?php js::set('confirmUnlinkBug', $lang->release->confirmUnlinkBug)?>
<?php js::set('storySummary', $summary);?>
<?php js::set('storyCommon', $lang->SRCommon);?>
<?php js::set('checkedSummary', str_replace('%storyCommon%', $lang->SRCommon, $lang->product->checkedSummary));?>
<?php $canBeChanged = common::canBeChanged('release', $release);?>
<div id='mainMenu' class='clearfix'>
<div class='btn-toolbar pull-left'>
@@ -54,7 +57,7 @@
<div class='actions'><?php echo html::a("javascript:showLink({$release->id}, \"story\")", '<i class="icon-link"></i> ' . $lang->release->linkStory, '', "class='btn btn-primary'");?></div>
<div class='linkBox cell hidden'></div>
<?php endif;?>
<form class='main-table table-story no-stash<?php if($link === 'true' and $type == 'story') echo " hidden";?>' method='post' id='linkedStoriesForm' data-ride="table">
<form class='main-table table-story no-stash<?php if($link === 'true' and $type == 'story') echo " hidden";?>' method='post' id='linkedStoriesForm' data-ride="">
<table class='table has-sort-head' id='storyList'>
<?php
$canBatchUnlink = common::hasPriv('release', 'batchUnlinkStory');
@@ -84,7 +87,7 @@
<tbody class='text-center'>
<?php foreach($stories as $storyID => $story):?>
<?php $storyLink = $this->createLink('story', 'view', "storyID=$story->id", '', true);?>
<tr>
<tr data-id='<?php echo $story->id;?>' data-estimate='<?php echo $story->estimate?>' <?php if(!empty($story->children)) echo "data-children=" . count($story->children);?> data-cases='<?php echo zget($storyCases, $story->id, 0);?>'>
<td class='c-id text-left'>
<?php if(($canBatchUnlink or $canBatchClose) and $canBeChanged):?>
<div class="checkbox-primary">
@@ -113,7 +116,7 @@
if(common::hasPriv('release', 'unlinkStory') and $canBeChanged)
{
$unlinkURL = $this->createLink('release', 'unlinkStory', "releaseID=$release->id&story=$story->id");
echo html::a("javascript:ajaxDelete(\"$unlinkURL\", \"storyList\", confirmUnlinkStory)", '<i class="icon-unlink"></i>', '', "class='btn' title='{$lang->release->unlinkStory}'");
echo html::a($unlinkURL, '<i class="icon-unlink"></i>', 'hiddenwin', "class='btn' title='{$lang->release->unlinkStory}'");
}
?>
</td>
@@ -139,6 +142,8 @@
}
?>
</div>
<?php endif;?>
<?php if($this->app->getViewType() != 'xhtml'):?>
<div class='table-statistic'><?php echo $summary;?></div>
<?php endif;?>
<?php
+4 -3
View File
@@ -2945,10 +2945,11 @@ class repoModel extends model
{
if($deletedBranch == 'master') continue;
$revisionIds = $this->dao->select('revision')->from(TABLE_REPOBRANCH)->where('repo')->eq($repoID)->andWhere('branch')->eq($deletedBranch)->fetchPairs('revision');
$fileIds = $this->dao->select('id')->from(TABLE_REPOFILES)->where('revision')->in($revisionIds)->fetchPairs('id');
$revisionIds = $this->dao->select('revision')->from(TABLE_REPOBRANCH)->where('repo')->eq($repoID)->andWhere('branch')->eq($deletedBranch)->fetchPairs('revision');
$branchRevisionIds = $this->dao->select('revision,count(branch) as count')->from(TABLE_REPOBRANCH)->where('revision')->in($revisionIds)->groupBy('revision')->having('count')->eq(1)->fetchPairs('revision', 'revision');
$fileIds = $this->dao->select('id')->from(TABLE_REPOFILES)->where('revision')->in($branchRevisionIds)->fetchPairs('id');
$this->dao->delete()->from(TABLE_REPOHISTORY)->where('id')->in($revisionIds)->exec();
$this->dao->delete()->from(TABLE_REPOHISTORY)->where('id')->in($branchRevisionIds)->exec();
$this->dao->delete()->from(TABLE_REPOFILES)->where('id')->in($fileIds)->exec();
$this->dao->delete()->from(TABLE_REPOBRANCH)->where('repo')->eq($repoID)->andWhere('branch')->eq($deletedBranch)->exec();
}
+1
View File
@@ -2107,6 +2107,7 @@ class story extends control
public function batchToTask($executionID = 0, $projectID = 0)
{
if($this->app->tab == 'execution' and $executionID) $this->loadModel('execution')->setMenu($executionID);
if($this->app->tab == 'project' and $executionID) $this->loadModel('execution')->setMenu($executionID);
if(!empty($_POST['name']))
{
+8 -1
View File
@@ -2489,6 +2489,13 @@ class storyModel extends model
dao::$errors['message'][] = sprintf($this->lang->error->notempty, $this->lang->task->$field);
return false;
}
if(!empty($this->config->limitTaskDate))
{
$this->task->checkEstStartedAndDeadline($executionID, $task->estStarted, $task->deadline);
if(dao::isError()) return false;
}
if($task->estimate) $task->estimate = (float)$task->estimate;
}
@@ -4678,7 +4685,7 @@ class storyModel extends model
$menu .= "</ul></div>";
}
if(($this->app->tab == 'execution' || (!empty($execution) and $execution->multiple === '0')) and $story->status == 'active') $menu .= $this->buildMenu('task', 'create', "execution={$this->session->execution}&{$params}&moduleID=$story->module", $story, $type, 'plus', '', 'showinonlybody');
if(($this->app->tab == 'execution' or (!empty($execution) and $execution->multiple === '0')) and $story->status == 'active' and $story->type == 'story') $menu .= $this->buildMenu('task', 'create', "execution={$this->session->execution}&{$params}&moduleID=$story->module", $story, $type, 'plus', '', 'showinonlybody');
$menu .= "<div class='divider'></div>";
$menu .= $this->buildFlowMenu('story', $story, $type, 'direct');
+5
View File
@@ -294,6 +294,11 @@ $lang->task->error->leftEmptyAB = 'When the task status is %s, "Hours Left
$lang->task->error->leftEmpty = 'Task#%sWhen the task status is %s, "Left" cannot be 0';
$lang->task->error->notempty = '%s must be > 0.';
$lang->task->error->teamLeftEmpty = 'Please maintain team hours.';
$lang->task->error->beginLtExecution = "The 'StartDate' of the task must be greater than or equal the 'Planned Begin' of %s to %s.";
$lang->task->error->beginGtExecution = "The 'StartDate' of the task must be less than or equal the 'Planned End' of %s to %s.";
$lang->task->error->endGtExecution = "The 'Deadline' of the task must be less than or equal the 'Planned End' of %s to %s.";
$lang->task->error->endLtExecution = "The 'Deadline' of the task must be greater than or equal the 'Planned Begin' of %s to %s.";
$lang->task->error->dateExceed = "Because the scheduled date of task %s exceeds the scheduled date of {$lang->execution->common}, it is automatically changed to the scheduled date of {$lang->execution->common}";
/* Report. */
$lang->task->report = new stdclass();
+5
View File
@@ -294,6 +294,11 @@ $lang->task->error->leftEmptyAB = 'When the task status is %s, "Hours Left
$lang->task->error->leftEmpty = 'Task#%sWhen the task status is %s, "Left" cannot be 0';
$lang->task->error->notempty = '%s must be > 0.';
$lang->task->error->teamLeftEmpty = 'Please maintain team hours.';
$lang->task->error->beginLtExecution = "The 'StartDate' of the task must be greater than or equal the 'Planned Begin' of %s to %s.";
$lang->task->error->beginGtExecution = "The 'StartDate' of the task must be less than or equal the 'Planned End' of %s to %s.";
$lang->task->error->endGtExecution = "The 'Deadline' of the task must be less than or equal the 'Planned End' of %s to %s.";
$lang->task->error->endLtExecution = "The 'Deadline' of the task must be greater than or equal the 'Planned Begin' of %s to %s.";
$lang->task->error->dateExceed = "Because the scheduled date of task %s exceeds the scheduled date of {$lang->execution->common}, it is automatically changed to the scheduled date of {$lang->execution->common}";
/* Report. */
$lang->task->report = new stdclass();
+5
View File
@@ -294,6 +294,11 @@ $lang->task->error->leftEmptyAB = 'When the task status is %s, "Hours Left
$lang->task->error->leftEmpty = 'Task#%sWhen the task status is %s, "Left" cannot be 0';
$lang->task->error->notempty = '%s must be > 0.';
$lang->task->error->teamLeftEmpty = 'Please maintain team hours.';
$lang->task->error->beginLtExecution = "The 'StartDate' of the task must be greater than or equal the 'Planned Begin' of %s to %s.";
$lang->task->error->beginGtExecution = "The 'StartDate' of the task must be less than or equal the 'Planned End' of %s to %s.";
$lang->task->error->endGtExecution = "The 'Deadline' of the task must be less than or equal the 'Planned End' of %s to %s.";
$lang->task->error->endLtExecution = "The 'Deadline' of the task must be greater than or equal the 'Planned Begin' of %s to %s.";
$lang->task->error->dateExceed = "Because the scheduled date of task %s exceeds the scheduled date of {$lang->execution->common}, it is automatically changed to the scheduled date of {$lang->execution->common}";
/* Report. */
$lang->task->report = new stdclass();
+5
View File
@@ -294,6 +294,11 @@ $lang->task->error->leftEmptyAB = '任务状态为%s时,预计剩余不
$lang->task->error->leftEmpty = 'Task#%s任务状态为%s时,剩余不能为0';
$lang->task->error->notempty = '%s必须大于0。';
$lang->task->error->teamLeftEmpty = '请维护团队工时。';
$lang->task->error->beginLtExecution = "任务开始日期应大于等于%s的开始日期:%s。";
$lang->task->error->beginGtExecution = "任务开始日期应小于等于%s的结束日期:%s。";
$lang->task->error->endGtExecution = "任务截止日期应小于等于%s的结束日期:%s。";
$lang->task->error->endLtExecution = "任务截止日期应大于等于%s的开始日期:%s。";
$lang->task->error->dateExceed = "任务%s的计划日期超过该{$lang->execution->common}计划日期,将自动改为{$lang->execution->common}的计划日期。";
/* Report. */
$lang->task->report = new stdclass();
+59
View File
@@ -28,6 +28,12 @@ class taskModel extends model
return false;
}
if(!empty($this->config->limitTaskDate))
{
$this->checkEstStartedAndDeadline($executionID, $this->post->estStarted, $this->post->deadline);
if(dao::isError()) return false;
}
$executionID = (int)$executionID;
$estStarted = '0000-00-00';
$deadline = '0000-00-00';
@@ -52,6 +58,19 @@ class taskModel extends model
$deadline = (!isset($this->post->testDeadline[$i]) or (isset($this->post->deadlineDitto[$i]) and $this->post->deadlineDitto[$i] == 'on')) ? $deadline : $this->post->testDeadline[$i];
$assignedTo = (!isset($this->post->testAssignedTo[$i]) or $this->post->testAssignedTo[$i] == 'ditto') ? $assignedTo : $this->post->testAssignedTo[$i];
if(!empty($this->config->limitTaskDate))
{
$this->checkEstStartedAndDeadline($executionID, $estStarted, $deadline);
if(dao::isError())
{
foreach(dao::getError() as $field => $error)
{
dao::$errors[] = $error;
return false;
}
}
}
if($estStarted > $deadline)
{
dao::$errors[] = "ID: $storyID {$this->lang->task->error->deadlineSmall}";
@@ -402,6 +421,12 @@ class taskModel extends model
/* check data. */
foreach($data as $i => $task)
{
if(!empty($this->config->limitTaskDate))
{
$this->checkEstStartedAndDeadline($executionID, $task->estStarted, $task->deadline);
if(dao::isError()) return false;
}
if(!helper::isZeroDate($task->deadline) and $task->deadline < $task->estStarted)
{
dao::$errors['message'][] = $this->lang->task->error->deadlineSmall;
@@ -1063,6 +1088,12 @@ class taskModel extends model
return false;
}
if(!empty($this->config->limitTaskDate))
{
$this->checkEstStartedAndDeadline($oldTask->execution, $this->post->estStarted, $this->post->deadline);
if(dao::isError()) return false;
}
if(!empty($_POST['lastEditedDate']) and $oldTask->lastEditedDate != $this->post->lastEditedDate)
{
dao::$errors[] = $this->lang->error->editedByOther;
@@ -1369,6 +1400,12 @@ class taskModel extends model
return false;
}
if(!empty($this->config->limitTaskDate))
{
$this->checkEstStartedAndDeadline($oldTask->execution, $task->estStarted, $task->deadline, "task:{$taskID} ");
if(dao::isError()) return false;
}
if(empty($task->closedReason) and $task->status == 'closed')
{
if($oldTask->status == 'done') $task->closedReason = 'done';
@@ -4451,4 +4488,26 @@ class taskModel extends model
$teamMembers = $this->dao->select('account')->from(TABLE_TASKTEAM)->where('task')->eq($taskID)->fetchPairs();
return empty($teamMembers) ? $teamMembers : array_keys($teamMembers);
}
/**
* Check estStarted and deadline date.
*
* @param int $executionID
* @param string $estStarted
* @param string $deadline
* @param string $pre
* @access public
* @return void
*/
public function checkEstStartedAndDeadline($executionID, $estStarted, $deadline, $pre = '')
{
$execution = $this->loadModel('execution')->getByID($executionID);
if(empty($execution) or empty($this->config->limitTaskDate)) return false;
if(empty($execution->multiple)) $this->lang->execution->common = $this->lang->project->common;
if(!empty($estStarted) and !helper::isZeroDate($estStarted) and $estStarted < $execution->begin) dao::$errors['estStarted'][] = $pre . sprintf($this->lang->task->error->beginLtExecution, $this->lang->execution->common, $execution->begin);
if(!empty($estStarted) and !helper::isZeroDate($estStarted) and $estStarted > $execution->end) dao::$errors['estStarted'][] = $pre . sprintf($this->lang->task->error->beginGtExecution, $this->lang->execution->common, $execution->end);
if(!empty($deadline) and !helper::isZeroDate($deadline) and $deadline > $execution->end) dao::$errors['deadline'][] = $pre . sprintf($this->lang->task->error->endGtExecution, $this->lang->execution->common, $execution->end);
if(!empty($deadline) and !helper::isZeroDate($deadline) and $deadline < $execution->begin) dao::$errors['deadline'][] = $pre . sprintf($this->lang->task->error->endLtExecution, $this->lang->execution->common, $execution->begin);
}
}
+1 -1
View File
@@ -389,7 +389,7 @@ class todo extends control
$todo = $this->todo->getById($todoID, true);
if(!$todo)
{
if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'fail', 'message' => '404 Not found'));
if((defined('RUN_MODE') && RUN_MODE == 'api') or $this->app->viewType == 'json') return $this->send(array('status' => 'fail', 'message' => '404 Not found'));
return print(js::error($this->lang->notFound) . js::locate('back'));
}
+4 -4
View File
@@ -19,7 +19,7 @@ $lang->tree->manage = 'Modul verwalten';
$lang->tree->fix = 'Fix';
$lang->tree->manageProduct = "Verwalte {$lang->productCommon}";
$lang->tree->manageExecution = "Verwalte {$lang->executionCommon}";
$lang->tree->manageLine = "Manage {$lang->productCommon} Line";
$lang->tree->manageLine = "Manage Product Line";
$lang->tree->manageBug = 'Verwalte Bugs';
$lang->tree->manageCase = 'Verwalte Fälle';
$lang->tree->manageCaseLib = 'Verwalte Bibliothek';
@@ -42,7 +42,7 @@ $lang->tree->addChild = "Hinzufügen";
$lang->tree->confirmDelete = 'Do you want to delete this module and its child modules?';
$lang->tree->confirmDeleteMenu = 'Do you want to delete this menu and its child menus?';
$lang->tree->confirmDelCategory = 'Möchten Sie diese Kategorie und ihre Kinderkategorien löschen?';
$lang->tree->confirmDeleteLine = "Do you want to delete this {$lang->productCommon} line?";
$lang->tree->confirmDeleteLine = "Do you want to delete this product line?";
$lang->tree->confirmDeleteGroup = 'Do you want to delete this group and its child groups?';
$lang->tree->confirmRoot = "Any changes to the {$lang->productCommon} will change the stories, bugs, cases of {$lang->productCommon} it belongs to, as well as the linkage of {$lang->executionCommon} and {$lang->productCommon}, which is dangerous. Do you want to change it?";
$lang->tree->confirmRoot4Doc = "Any changes to the library will change the document of library it belongs to, which is dangerous. Do you want to change it?";
@@ -56,7 +56,7 @@ $lang->tree->syncProductModule = 'Sync Module';
$lang->tree->module = 'Modul';
$lang->tree->name = 'Name';
$lang->tree->wordName = 'Name';
$lang->tree->line = "{$lang->productCommon} Line";
$lang->tree->line = "Product Line";
$lang->tree->cate = 'Kategorie Name';
$lang->tree->dir = 'Directory';
$lang->tree->root = 'Root';
@@ -69,7 +69,7 @@ $lang->tree->child = 'Untergeordnet';
$lang->tree->subCategory = 'SubCategory';
$lang->tree->editCategory = 'Kategorie bearbeiten';
$lang->tree->delCategory = 'Kategorie löschen';
$lang->tree->lineChild = "Child {$lang->productCommon} Line";
$lang->tree->lineChild = "Child Product Line";
$lang->tree->owner = 'Besitzer';
$lang->tree->order = 'Reihenfolge';
$lang->tree->short = 'Sortierung';
+5 -5
View File
@@ -19,7 +19,7 @@ $lang->tree->manage = 'Manage Module';
$lang->tree->fix = 'Fix Module';
$lang->tree->manageProduct = "Manage {$lang->productCommon} Modules";
$lang->tree->manageExecution = "Manage {$lang->execution->common} Modules";
$lang->tree->manageLine = "Manage {$lang->productCommon} Line";
$lang->tree->manageLine = "Manage Product Line";
$lang->tree->manageBug = 'Manage Bug';
$lang->tree->manageCase = 'Manage Case';
$lang->tree->manageCaseLib = 'Manage Library';
@@ -28,7 +28,7 @@ $lang->tree->manageApiChild = 'Manage API Directory';
$lang->tree->updateOrder = 'Rank Module';
$lang->tree->manageChild = 'Manage Child Modules';
$lang->tree->manageStoryChild = 'Manage Child Modules';
$lang->tree->manageLineChild = "Manage {$lang->productCommon} Line";
$lang->tree->manageLineChild = "Manage Product Line";
$lang->tree->manageBugChild = 'Manage Child Modules of Bugs';
$lang->tree->manageCaseChild = 'Manage Child Cases';
$lang->tree->manageCaselibChild = 'Manage Child Libraries';
@@ -42,7 +42,7 @@ $lang->tree->addChild = "Add Child Module";
$lang->tree->confirmDelete = 'Do you want to delete this module and its child modules?';
$lang->tree->confirmDeleteMenu = 'Do you want to delete this menu and its child menus?';
$lang->tree->confirmDelCategory = 'Do you want to delete this category and its child categories?';
$lang->tree->confirmDeleteLine = "Do you want to delete this {$lang->productCommon} line?";
$lang->tree->confirmDeleteLine = "Do you want to delete this product line?";
$lang->tree->confirmDeleteGroup = 'Do you want to delete this group and its child groups?';
$lang->tree->confirmRoot = "Any changes to the {$lang->productCommon} will change the stories, bugs, cases of {$lang->productCommon} it belongs to, as well as the linkage of {$lang->executionCommon} and {$lang->productCommon}, which is dangerous. Do you want to change it?";
$lang->tree->confirmRoot4Doc = "Any changes to the library will change the document of library it belongs to, which is dangerous. Do you want to change it?";
@@ -56,7 +56,7 @@ $lang->tree->syncProductModule = 'Sync Module';
$lang->tree->module = 'Module';
$lang->tree->name = 'Module Name';
$lang->tree->wordName = 'Name';
$lang->tree->line = "{$lang->productCommon} Line";
$lang->tree->line = "Product Line";
$lang->tree->cate = 'Category';
$lang->tree->dir = 'Directory';
$lang->tree->root = 'Root';
@@ -69,7 +69,7 @@ $lang->tree->child = 'Children';
$lang->tree->subCategory = 'SubCategory';
$lang->tree->editCategory = 'Edit Category';
$lang->tree->delCategory = 'Delete Category';
$lang->tree->lineChild = "Child {$lang->productCommon} Line";
$lang->tree->lineChild = "Child Product Line";
$lang->tree->owner = 'Owner';
$lang->tree->order = 'Order';
$lang->tree->short = 'Abbr.';
+5 -5
View File
@@ -19,7 +19,7 @@ $lang->tree->manage = '维护模块';
$lang->tree->fix = '修正数据';
$lang->tree->manageProduct = "维护{$lang->productCommon}视图模块";
$lang->tree->manageExecution = "维护{$lang->execution->common}视图模块";
$lang->tree->manageLine = "维护{$lang->productCommon}线";
$lang->tree->manageLine = "维护产品线";
$lang->tree->manageBug = '维护测试视图模块';
$lang->tree->manageCase = '维护用例视图模块';
$lang->tree->manageCaseLib = '维护用例库模块';
@@ -28,7 +28,7 @@ $lang->tree->manageApiChild = '维护接口库目录';
$lang->tree->updateOrder = '更新排序';
$lang->tree->manageChild = '维护子模块';
$lang->tree->manageStoryChild = '维护子模块';
$lang->tree->manageLineChild = "维护{$lang->productCommon}线";
$lang->tree->manageLineChild = "维护产品线";
$lang->tree->manageBugChild = '维护Bug子模块';
$lang->tree->manageCaseChild = '维护用例子模块';
$lang->tree->manageCaselibChild = '维护用例库子模块';
@@ -42,7 +42,7 @@ $lang->tree->addChild = "增加子模块";
$lang->tree->confirmDelete = '该模块及其子模块都会被删除,您确定删除吗?';
$lang->tree->confirmDeleteMenu = '该目录及其子目录都会被删除,您确定删除吗?';
$lang->tree->confirmDelCategory = '该分类及其子分类都会被删除,您确定删除吗?';
$lang->tree->confirmDeleteLine = "您确定删除该{$lang->productCommon}线吗?";
$lang->tree->confirmDeleteLine = "您确定删除该产品线吗?";
$lang->tree->confirmDeleteGroup = '该分组及其子分组都会被删除,您确定删除吗?';
$lang->tree->confirmRoot = "模块的所属{$lang->productCommon}修改,会关联修改该模块下的{$lang->SRCommon}、Bug、用例的所属{$lang->productCommon},以及{$lang->executionCommon}和{$lang->productCommon}的关联关系。该操作比较危险,请谨慎操作。是否确认修改?";
$lang->tree->confirmRoot4Doc = "修改所属文档库,会同时修改该分类下文档的关联关系。该操作比较危险,请谨慎操作。是否确认修改?";
@@ -56,7 +56,7 @@ $lang->tree->syncProductModule = "同步{$lang->productCommon}模块";
$lang->tree->module = '模块';
$lang->tree->name = '模块名称';
$lang->tree->wordName = '名称';
$lang->tree->line = "{$lang->productCommon}线名称";
$lang->tree->line = "产品线名称";
$lang->tree->cate = '分类名称';
$lang->tree->dir = '目录名称';
$lang->tree->root = "所属{$lang->productCommon}";
@@ -69,7 +69,7 @@ $lang->tree->child = '子模块';
$lang->tree->subCategory = '子分类';
$lang->tree->editCategory = '编辑分类';
$lang->tree->delCategory = '删除分类';
$lang->tree->lineChild = "子{$lang->productCommon}线";
$lang->tree->lineChild = "子产品线";
$lang->tree->owner = '负责人';
$lang->tree->order = '排序';
$lang->tree->short = '简称';
+5 -3
View File
@@ -33,7 +33,8 @@ $config->upgrade->maxVersion['max4_0_beta2'] = '18_0_beta2';
$config->upgrade->maxVersion['max4_0_beta3'] = '18_0_beta3';
$config->upgrade->maxVersion['max4_0'] = '18_0';
$config->upgrade->maxVersion['max4_1'] = '18_1';
$config->upgrade->maxVersion['max4_2'] = '18_2'; // max insert position.
$config->upgrade->maxVersion['max4_2'] = '18_2';
$config->upgrade->maxVersion['max4_3'] = '18_3'; // max insert position.
$config->upgrade->bizVersion = array();
$config->upgrade->bizVersion['biz1_0'] = '9_5_1';
@@ -105,7 +106,8 @@ $config->upgrade->bizVersion['biz8_0_beta2'] = '18_0_beta2';
$config->upgrade->bizVersion['biz8_0_beta3'] = '18_0_beta3';
$config->upgrade->bizVersion['biz8_0'] = '18_0';
$config->upgrade->bizVersion['biz8_1'] = '18_1';
$config->upgrade->bizVersion['biz8_2'] = '18_2'; // biz insert position.
$config->upgrade->bizVersion['biz8_2'] = '18_2';
$config->upgrade->bizVersion['biz8_3'] = '18_3'; // biz insert position.
$config->upgrade->proVersion = array();
$config->upgrade->proVersion['pro1_0'] = '3_1';
@@ -427,7 +429,7 @@ $config->delete['18_0'][] = 'extension/max/repo/ext/control/ajaxgetbranchesandta
$config->delete['18_0'][] = 'extension/max/repo/ext/control/editbug.php';
$config->delete['18_0'][] = 'extension/max/repo/ext/view/ajaxgetcommitinfo.html.php';
$config->upgrade->openModules = array('action', 'admin', 'api', 'automation', 'backup', 'block', 'branch', 'budget', 'bug', 'build', 'caselib', 'ci', 'client', 'common', 'company', 'compile', 'convert', 'cron', 'custom', 'datatable', 'dept', 'design', 'dev', 'doc', 'durationestimation', 'entry', 'execution', 'extension', 'file', 'git', 'gitlab', 'group', 'holiday', 'im', 'index', 'index.html', 'install', 'issue', 'jenkins', 'job', 'kanban', 'license', 'mail', 'message', 'misc', 'mr', 'my', 'personnel', 'pipeline', 'product', 'productplan', 'productset', 'program', 'programplan', 'project', 'projectbuild', 'projectplan', 'projectrelease', 'projectstory', 'qa', 'release', 'repo', 'report', 'risk', 'score', 'screen', 'search', 'setting', 'sonarqube', 'sso', 'stage', 'stakeholder', 'story', 'subject', 'svn', 'task', 'testcase', 'testreport', 'testsuite', 'testtask', 'todo', 'tree', 'tutorial', 'upgrade', 'user', 'webhook', 'weekly', 'workestimation', 'gitea', 'gogs', 'transfer', 'zahost', 'zanode');
$config->upgrade->openModules = array('action', 'admin', 'api', 'automation', 'backup', 'block', 'branch', 'budget', 'bug', 'build', 'caselib', 'ci', 'client', 'common', 'company', 'compile', 'convert', 'cron', 'custom', 'datatable', 'dept', 'design', 'dev', 'doc', 'durationestimation', 'entry', 'execution', 'extension', 'file', 'git', 'gitlab', 'group', 'holiday', 'im', 'index', 'index.html', 'install', 'issue', 'jenkins', 'job', 'kanban', 'license', 'mail', 'message', 'misc', 'mr', 'my', 'personnel', 'pipeline', 'product', 'productplan', 'productset', 'program', 'programplan', 'project', 'projectbuild', 'projectplan', 'projectrelease', 'projectstory', 'qa', 'release', 'repo', 'report', 'risk', 'score', 'screen', 'search', 'setting', 'sonarqube', 'sso', 'stage', 'stakeholder', 'story', 'subject', 'svn', 'task', 'testcase', 'testreport', 'testsuite', 'testtask', 'todo', 'tree', 'tutorial', 'upgrade', 'user', 'webhook', 'weekly', 'workestimation', 'gitea', 'gogs', 'transfer', 'zahost', 'zanode', 'editor');
$config->upgrade->unsetModules = array('design', 'program', 'programplan', 'projectbuild', 'projectrelease', 'stage', 'stakeholder', 'product', 'branch', 'productplan', 'release', 'build', 'qa', 'bug', 'testcase', 'testtask', 'testreport', 'testsuite', 'caselib', 'automation', 'repo', 'ci', 'compile', 'jenkins', 'job', 'svn', 'gitlab', 'sonarqube', 'mr', 'git', 'report', 'sqlbuilder', 'feedback', 'faq', 'attend', 'holiday', 'leave', 'makeup', 'overtime', 'lieu', 'ops', 'host', 'serverroom', 'account', 'domain', 'service', 'deploy', 'conference', 'traincourse', 'pssp', 'baseline', 'classify', 'cm', 'cmcl', 'auditcl', 'reviewcl', 'process', 'activity', 'zoutput', 'auditplan', 'nc', 'subject', 'weekly', 'workestimation', 'issue', 'durationestimation', 'risk', 'opportunity', 'trainplan', 'gapanalysis', 'researchplan', 'researchreport', 'meeting', 'meetingroom', 'budget', 'reviewissue', 'reviewsetting', 'review', 'milestone', 'measurement', 'measrecord', 'assetlib', 'setting', 'im', 'client', 'ldap', 'dev', 'api', 'gitea', 'gogs', 'zanode', 'zahost');
+2 -2
View File
@@ -52,7 +52,7 @@ $lang->upgrade->upgradingTips = 'The upgrade is in progress, please be patient.
$lang->upgrade->forbiddenExt = 'Die Erweiterung ist nicht kompatibel mit der Upgradeversion. Sie wurde deaktiviert:';
$lang->upgrade->updateFile = 'Updateinformation wurden hinzugefügt.';
$lang->upgrade->noticeSQL = 'Your database is inconsistent with the standard and it failed to fix it. Please run the following SQL and refresh.';
$lang->upgrade->afterExec = 'Please modify the database manually according to the above error information, and refresh after the modification!';
$lang->upgrade->afterDeleted = 'Please modify the database manually according to the above error information, and refresh after the modification!';
$lang->upgrade->afterExec = 'Please manually modify the database according to the above error information, and refresh after modifiy!';
$lang->upgrade->mergeProgram = 'Data Merge';
$lang->upgrade->mergeTips = 'Data Migration Tips';
@@ -66,7 +66,7 @@ $lang->upgrade->allLines = "All Product Lines";
$lang->upgrade->program = 'Merge Project';
$lang->upgrade->existProgram = 'Existing programs';
$lang->upgrade->existProject = 'Existing projects';
$lang->upgrade->existLine = 'Existing' . $lang->productCommon . ' lines';
$lang->upgrade->existLine = 'Existing product lines';
$lang->upgrade->product = $lang->productCommon;
$lang->upgrade->project = 'Iteration';
$lang->upgrade->repo = 'Repo';
+1 -1
View File
@@ -66,7 +66,7 @@ $lang->upgrade->allLines = "All Product Lines";
$lang->upgrade->program = 'Merge Project';
$lang->upgrade->existProgram = 'Existing programs';
$lang->upgrade->existProject = 'Existing projects';
$lang->upgrade->existLine = 'Existing' . $lang->productCommon . ' lines';
$lang->upgrade->existLine = 'Existing product lines';
$lang->upgrade->product = $lang->productCommon;
$lang->upgrade->project = 'Iteration';
$lang->upgrade->repo = 'Repo';
+1 -1
View File
@@ -66,7 +66,7 @@ $lang->upgrade->allLines = "All Product Lines";
$lang->upgrade->program = 'Merge Project';
$lang->upgrade->existProgram = 'Existing programs';
$lang->upgrade->existProject = 'Existing projects';
$lang->upgrade->existLine = 'Existing' . $lang->productCommon . ' lines';
$lang->upgrade->existLine = 'Existing product lines';
$lang->upgrade->product = $lang->productCommon;
$lang->upgrade->project = 'Iteration';
$lang->upgrade->repo = 'Repo';
+6 -3
View File
@@ -174,7 +174,8 @@ $lang->upgrade->fromVersions['18_0_beta2'] = '18.0.beta2';
$lang->upgrade->fromVersions['18_0_beta3'] = '18.0.beta3';
$lang->upgrade->fromVersions['18_0'] = '18.0';
$lang->upgrade->fromVersions['18_1'] = '18.1';
$lang->upgrade->fromVersions['18_2'] = '18.2'; // pms insert position.
$lang->upgrade->fromVersions['18_2'] = '18.2';
$lang->upgrade->fromVersions['18_3'] = '18.3'; // pms insert position.
global $config;
/* Lite. */
@@ -353,7 +354,8 @@ $lang->upgrade->fromVersions['biz8_0_beta2'] = 'Biz8.0.beta2';
$lang->upgrade->fromVersions['biz8_0_beta3'] = 'Biz8.0.beta3';
$lang->upgrade->fromVersions['biz8_0'] = 'Biz8.0';
$lang->upgrade->fromVersions['biz8_1'] = 'Biz8.1';
$lang->upgrade->fromVersions['biz8_2'] = 'Biz8.2'; // biz insert position.
$lang->upgrade->fromVersions['biz8_2'] = 'Biz8.2';
$lang->upgrade->fromVersions['biz8_3'] = 'Biz8.3'; // biz insert position.
/* Max. */
$lang->upgrade->fromVersions['max2_0_beta4'] = 'Max2.0.beta4';
@@ -388,4 +390,5 @@ $lang->upgrade->fromVersions['max4_0_beta1'] = 'Max4.0.beta1';
$lang->upgrade->fromVersions['max4_0_beta2'] = 'Max4.0.beta2';
$lang->upgrade->fromVersions['max4_0_beta3'] = 'Max4.0.beta3';
$lang->upgrade->fromVersions['max4_0'] = 'Max4.0';
$lang->upgrade->fromVersions['max4_1'] = 'Max4.1'; // max insert position.
$lang->upgrade->fromVersions['max4_1'] = 'Max4.1';
$lang->upgrade->fromVersions['max4_2'] = 'Max4.2'; // max insert position.
+2 -2
View File
@@ -62,11 +62,11 @@ $lang->upgrade->toBIZ5Guide = '禅道企业版5版本升级';
$lang->upgrade->toMAXGuide = '禅道旗舰版版本升级';
$lang->upgrade->line = '产品线';
$lang->upgrade->allLines = "所有{$lang->productCommon}线";
$lang->upgrade->allLines = "所有产品线";
$lang->upgrade->program = '目标项目集和项目';
$lang->upgrade->existProgram = '已有项目集';
$lang->upgrade->existProject = '已有项目';
$lang->upgrade->existLine = '已有' . $lang->productCommon . '线';
$lang->upgrade->existLine = '已有产品线';
$lang->upgrade->product = $lang->productCommon;
$lang->upgrade->project = '迭代';
$lang->upgrade->repo = '版本库';
+3 -1
View File
@@ -1090,7 +1090,9 @@ class upgradeModel extends model
case '18_0':
$confirmContent .= file_get_contents($this->getUpgradeFile('18.0'));
case '18_1':
$confirmContent .= file_get_contents($this->getUpgradeFile('18.1')); // confirm insert position.
$confirmContent .= file_get_contents($this->getUpgradeFile('18.1'));
case '18_2':
$confirmContent .= file_get_contents($this->getUpgradeFile('18.2')); // confirm insert position.
}
return $confirmContent;
+18
View File
@@ -1490,4 +1490,22 @@ class taskTest
return $object;
}
/**
* Get the users who finished the multiple task.
* @param int $executionID
* @param string $estStarted
* @param string $deadline
*
* @access public
* @return array
*/
public function checkEstStartedAndDeadlineTest($executionID, $estStarted, $deadline)
{
$object = $this->objectModel->checkEstStartedAndDeadline($executionID, $estStarted, $deadline);
if(dao::isError()) return dao::getError();
return $object;
}
}
@@ -0,0 +1,62 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/task.class.php';
su('admin');
$execution = zdTable('project');
$execution->id->range('1-11');
$execution->name->setFields(array(
array('field' => 'name1', 'range' => '项目{2},执行{3},迭代{2},阶段{2},看板{2}'),
array('field' => 'name2', 'range' => '1-3'),
));
$execution->code->setFields(array(
array('field' => 'name1', 'range' => '项目{2},执行{3},迭代{2},阶段{2},看板{2}'),
array('field' => 'name2', 'range' => '1-3'),
));
$execution->type->range('project{2},sprint{5},waterfall{2},kanban{2}');
$execution->status->range('doing{11}');
$execution->parent->range('0');
$execution->begin->range('20230102 000000:0')->type('timestamp')->format('YY/MM/DD');
$execution->end->range('20230212 000000:0')->type('timestamp')->format('YY/MM/DD');
$execution->gen(5);
/**
title=测试 taskModel->checkEstStartedAndDeadline();
cid=1
pid=1
测试获取执行4 任务开始日期 2000-01-02 结束日期 2040-01-02 是否可以保存 >> 任务开始日期应大于等于迭代的开始日期:2023-01-02。,任务结束日期应小于等于迭代的结束日期:2023-02-12。
测试获取执行4 任务开始日期 2000-01-02 结束日期 空 是否可以保存 >> 任务开始日期应大于等于迭代的开始日期:2023-01-02。,
测试获取执行4 任务开始日期 2000-01-02 结束日期 2023-01-15 是否可以保存 >> 任务开始日期应大于等于迭代的开始日期:2023-01-02。,
测试获取执行4 任务开始日期 空 结束日期 2040-01-02 是否可以保存 >> ,任务结束日期应小于等于迭代的结束日期:2023-02-12。
测试获取执行4 任务开始日期 空 结束日期 空 是否可以保存 >> 0
测试获取执行4 任务开始日期 空 结束日期 2023-01-15 是否可以保存 >> 0
测试获取执行4 任务开始日期 2023-01-15 结束日期 2040-01-02 是否可以保存 >> ,任务结束日期应小于等于迭代的结束日期:2023-02-12。
测试获取执行4 任务开始日期 2023-01-15 结束日期 空 是否可以保存 >> 0
测试获取执行4 任务开始日期 2023-01-15 结束日期 2023-01-15 是否可以保存 >> 0
*/
$executionID = '4';
$estStarted = array('2000-01-02', '', '2023-01-15');
$deadline = array('2040-01-02', '', '2023-01-15');
$task = new taskTest();
global $tester;
$tester->loadModel('setting')->setItem('system.common.limitTaskDate', 1);
r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[0], $deadline[0])) && p('estStarted,deadline') && e('任务开始日期应大于等于迭代的开始日期:2023-01-02。,任务结束日期应小于等于迭代的结束日期:2023-02-12。'); // 测试获取执行4 任务开始日期 2000-01-02 结束日期 2040-01-02 是否可以保存
r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[0], $deadline[1])) && p('estStarted,deadline') && e('任务开始日期应大于等于迭代的开始日期:2023-01-02。,'); // 测试获取执行4 任务开始日期 2000-01-02 结束日期 空 是否可以保存
r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[0], $deadline[2])) && p('estStarted,deadline') && e('任务开始日期应大于等于迭代的开始日期:2023-01-02。,'); // 测试获取执行4 任务开始日期 2000-01-02 结束日期 2023-01-15 是否可以保存
r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[1], $deadline[0])) && p('estStarted,deadline') && e(',任务结束日期应小于等于迭代的结束日期:2023-02-12。'); // 测试获取执行4 任务开始日期 空 结束日期 2040-01-02 是否可以保存
r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[1], $deadline[1])) && p('estStarted,deadline') && e(0); // 测试获取执行4 任务开始日期 空 结束日期 空 是否可以保存
r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[1], $deadline[2])) && p('estStarted,deadline') && e(0); // 测试获取执行4 任务开始日期 空 结束日期 2023-01-15 是否可以保存
r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[2], $deadline[0])) && p('estStarted,deadline') && e(',任务结束日期应小于等于迭代的结束日期:2023-02-12。'); // 测试获取执行4 任务开始日期 2023-01-15 结束日期 2040-01-02 是否可以保存
r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[2], $deadline[1])) && p('estStarted,deadline') && e(0); // 测试获取执行4 任务开始日期 2023-01-15 结束日期 空 是否可以保存
r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[2], $deadline[2])) && p('estStarted,deadline') && e(0); // 测试获取执行4 任务开始日期 2023-01-15 结束日期 2023-01-15 是否可以保存
$tester->setting->setItem('system.common.limitTaskDate', 0);

Some files were not shown because too many files have changed in this diff Show More