Merge branch 'zenops_46' into 'zenops_46_tanghucheng'

# Conflicts:
#   module/zanode/view/view.html.php
This commit is contained in:
唐胡成
2022-11-29 01:38:30 +00:00
480 changed files with 11124 additions and 3301 deletions
+1 -1
View File
@@ -1 +1 @@
17.8
18.0.beta1
+40 -3
View File
@@ -60,18 +60,24 @@ class testresultsEntry extends entry
$case = $this->loadModel('testcase')->getByID($caseID);
$runID = $this->param('runID', 0);
$version = $this->param('version', $case->version);
$steps = $this->getStepIDList($runID, $caseID, $version);
$this->setPost('case', $caseID);
$this->setPost('version', $version);
/* Set steps and expects. */
if(isset($this->requestBody->steps))
{
$results = array();
$reals = array();
foreach($this->requestBody->steps as $step)
foreach($this->requestBody->steps as $index => $step)
{
$results[] = $step->result;
$reals[] = $step->real;
/* When post data more than case steps, break after take useful data. */
if($index + 1 > count($steps)) break;
$stepID = $steps[$index];
$results[$stepID] = $step->result;
$reals[$stepID] = $step->real;
}
$this->setPost('steps', $results);
$this->setPost('reals', $reals);
@@ -85,4 +91,35 @@ class testresultsEntry extends entry
return $this->send(200, array());
}
/**
* Get steps key.
*
* @param int $runID
* @access public
* @return array
*/
public function getStepIDList($runID, $caseID, $version)
{
if($runID)
{
$run = $this->testtask->getRunById($runID);
}
else
{
$run = new stdclass();
$run->case = $this->loadModel('testcase')->getById($caseID, $version);
}
foreach($run->case->steps as $key => $step)
{
/* Unset step if step is a group. */
if($step->type == 'group')
{
unset($run->case->steps[$key]);
}
}
return array_keys($run->case->steps);
}
}
+6 -2
View File
@@ -408,8 +408,12 @@ class userEntry extends entry
$this->setPost('gender', $gender);
$password = $this->request('password', zget($_POST, 'password', ''));
$this->setPost('password1', md5($password));
$this->setPost('password2', md5($password));
if($password)
{
$this->setPost('password1', md5($password));
$this->setPost('password2', md5($password));
$this->setPost('passwordStrength', 2);
}
$this->setPost('verifyPassword', md5($this->app->user->password . $this->app->session->rand));
$control = $this->loadController('user', 'edit');
+2 -2
View File
@@ -16,7 +16,7 @@ if(!class_exists('config')){class config{}}
if(!function_exists('getWebRoot')){function getWebRoot(){}}
/* 基本设置。Basic settings. */
$config->version = '17.8'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
$config->version = '18.0.beta1'; // 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.
@@ -24,7 +24,7 @@ $config->timezone = 'Asia/Shanghai'; // 时区设置。 The tim
$config->webRoot = ''; // URL根目录。 The root path of the url.
$config->customSession = false; // 是否开启自定义session的存储路径。Whether custom the session save path.
$config->edition = 'open'; // 设置系统的edition,可选值:open|biz|max。Set edition, optional: open|biz|max.
$config->tabSession = true; // 是否开启浏览器新标签独立session.
$config->tabSession = false; // 是否开启浏览器新标签独立session.
/* 框架路由相关设置。Routing settings. */
$config->requestType = 'PATH_INFO'; // 请求类型:PATH_INFO|PATHINFO2|GET。 The request type: PATH_INFO|PATH_INFO2|GET.
+3 -3
View File
@@ -406,7 +406,7 @@ $config->pipelineTypeList = array('gitlab', 'gogs', 'gitea', 'jenkins', 'sonarqu
/* Program privs.*/
$config->programPriv = new stdclass();
$config->programPriv->noSprint = array('task', 'story', 'tree', 'project', 'execution', 'build', 'bug', 'testcase', 'testreport', 'doc', 'repo', 'stakeholder');
$config->programPriv->noSprint = array('task', 'story', 'tree', 'project', 'execution', 'build', 'bug', 'testcase', 'testreport', 'doc', 'repo', 'stakeholder', 'projectrelease', 'requirement');
$config->programPriv->scrum = array('story', 'requirement', 'productplan', 'tree', 'projectplan', 'projectstory', 'projectrelease', 'project', 'execution', 'build', 'bug', 'testcase', 'testreport', 'doc', 'repo', 'meeting', 'stakeholder', 'testtask');
$config->programPriv->waterfall = array_merge($config->programPriv->scrum, array('task', 'workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'cm', 'milestone', 'design', 'issue', 'risk', 'opportunity', 'measrecord', 'auditplan', 'trainplan', 'gapanalysis', 'pssp', 'researchplan', 'researchreport'));
@@ -418,8 +418,8 @@ $config->maxPriValue = '256';
$config->importWhiteList = array('user', 'task', 'story', 'bug', 'testcase', 'feedback', 'ticket');
$config->featureGroup = new stdclass();
$config->featureGroup->product = array('roadmap', 'track', 'URStory');
$config->featureGroup->product = array('roadmap', 'track', 'UR');
$config->featureGroup->scrum = array();
$config->featureGroup->waterfall = array('track');
$config->featureGroup->waterfall = array();
$config->featureGroup->assetlib = array();
$config->featureGroup->other = array('devops', 'kanban');
+4 -4
View File
@@ -383,10 +383,10 @@ INSERT INTO `zt_product` (`id`, `program`, `name`, `code`, `bind`, `line`, `type
INSERT INTO `zt_productplan` (`id`, `product`, `branch`, `parent`, `title`, `desc`, `begin`, `end`, `order`, `deleted`) VALUES
(1, 1, 0, 0, '1.0版本', '开发出企业网站1.0版本。<br />', '2020-06-05', '2021-06-04', '', '0');
INSERT INTO `zt_project` (`id`, `project`, `model`, `type`, `lifetime`, `budget`, `budgetUnit`, `attribute`, `percent`, `milestone`, `output`, `auth`, `parent`, `path`, `grade`, `name`, `code`, `begin`, `end`, `realBegan`, `realEnd`, `days`, `status`, `subStatus`, `pri`, `desc`, `version`, `parentVersion`, `planDuration`, `realDuration`, `openedBy`, `openedDate`, `openedVersion`, `lastEditedBy`, `lastEditedDate`, `closedBy`, `closedDate`, `canceledBy`, `canceledDate`, `PO`, `PM`, `QD`, `RD`, `team`, `acl`, `whitelist`, `order`, `deleted`) VALUES
(1, 7, '', 'sprint', 'sprint', '0', 'CNY', '', 0, '0', '', '', 7, ',7,1,', 1, '企业网站第一期', 'coWeb1', '2020-06-05', '2021-12-04', '0000-00-00', '0000-00-00', 391, 'doing', '', '1', '开发企业网站的基本雏形。<br />', 0, 0, 0, 0, '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 'productManager', 'projectManager', 'testManager', 'productManager', '公司开发团队', 'open', '', 5, '0'),
(2, 7, '', 'sprint', 'sprint', '0', 'CNY', '', 0, '0', '', '', 7, ',7,2,', 1, '企业网站第二期', 'coWebsite2', '2021-06-05', '2022-06-04', '0000-00-00', '0000-00-00', 260, 'wait', '', '1', '', 0, 0, 0, 0, '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 'productManager', 'projectManager', 'testManager', 'productManager', '公司开发团队', 'open', '', 10, '0'),
(7, 0, 'scrum', 'project', 'sprint', '0', 'CNY', '', 0, '0', '', 'extend', 6, ',6,7,', 2, '企业管理系统', '', '2021-06-05', '2022-06-04', '0000-00-00', '0000-00-00', 0, 'doing', '', '1', '', 0, 0, 0, 0, 'admin', '2021-04-28 11:22:04', '15.0.rc3', 'admin', '2021-04-28 11:22:04', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', 'projectManager', '', '', '', 'open', ',tester3,admin', 35, '0'),
(6, 0, '', 'program', 'sprint', '0', 'CNY', '', 0, '0', '', '', 0, ',6,', 1, '企业管理', '', '2021-06-05', '2022-06-04', '0000-00-00', '0000-00-00', 0, 'doing', '', '1', '', 0, 0, 0, 0, 'admin', '2021-04-28 11:22:04', '15.0.rc3', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '', '', '', '', 'open', '', 30, '0');
(1, 7, '', 'sprint', 'long', '0', 'CNY', '', 0, '0', '', '', 7, ',7,1,', 1, '企业网站第一期', 'coWeb1', '2020-06-05', '2021-12-04', '0000-00-00', '0000-00-00', 391, 'doing', '', '1', '开发企业网站的基本雏形。<br />', 0, 0, 0, 0, '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 'productManager', 'projectManager', 'testManager', 'productManager', '公司开发团队', 'open', '', 5, '0'),
(2, 7, '', 'sprint', 'long', '0', 'CNY', '', 0, '0', '', '', 7, ',7,2,', 1, '企业网站第二期', 'coWebsite2', '2021-06-05', '2022-06-04', '0000-00-00', '0000-00-00', 260, 'wait', '', '1', '', 0, 0, 0, 0, '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 'productManager', 'projectManager', 'testManager', 'productManager', '公司开发团队', 'open', '', 10, '0'),
(7, 0, 'scrum', 'project', '', '0', 'CNY', '', 0, '0', '', 'extend', 6, ',6,7,', 2, '企业管理系统', '', '2021-06-05', '2022-06-04', '0000-00-00', '0000-00-00', 0, 'doing', '', '1', '', 0, 0, 0, 0, 'admin', '2021-04-28 11:22:04', '15.0.rc3', 'admin', '2021-04-28 11:22:04', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', 'projectManager', '', '', '', 'open', ',tester3,admin', 35, '0'),
(6, 0, '', 'program', '', '0', 'CNY', '', 0, '0', '', '', 0, ',6,', 1, '企业管理', '', '2021-06-05', '2022-06-04', '0000-00-00', '0000-00-00', 0, 'doing', '', '1', '', 0, 0, 0, 0, 'admin', '2021-04-28 11:22:04', '15.0.rc3', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '', '', '', '', 'open', '', 30, '0');
INSERT INTO `zt_projectcase` (`project`, `product`, `case`, `count`, `version`, `order`) VALUES
(1, 1, 2, 1, 1, 4),
(7, 1, 1, 1, 1, 5),
+2 -2
View File
@@ -1489,7 +1489,7 @@ CREATE TABLE `zt_kanban` (
`showWIP` enum('0','1') NOT NULL DEFAULT '1',
`fluidBoard` enum('0','1') NOT NULL DEFAULT '0',
`colWidth` smallint(4) NOT NULL DEFAULT '264',
`minColWidth` smallint(4) NOT NULL DEFAULT '180',
`minColWidth` smallint(4) NOT NULL DEFAULT '200',
`maxColWidth` smallint(4) NOT NULL DEFAULT '384',
`object` varchar(255) NOT NULL,
`alignment` varchar(10) NOT NULL DEFAULT 'center',
@@ -2187,7 +2187,7 @@ CREATE TABLE `zt_project` (
`displayCards` smallint(6) NOT NULL DEFAULT '0',
`fluidBoard` enum('0','1') NOT NULL DEFAULT '0',
`colWidth` smallint(4) NOT NULL DEFAULT '264',
`minColWidth` smallint(4) NOT NULL DEFAULT '180',
`minColWidth` smallint(4) NOT NULL DEFAULT '200',
`maxColWidth` smallint(4) NOT NULL DEFAULT '384',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
+2 -2
View File
@@ -1489,7 +1489,7 @@ CREATE TABLE `zt_kanban` (
`showWIP` enum('0','1') NOT NULL DEFAULT '1',
`fluidBoard` enum('0','1') NOT NULL DEFAULT '0',
`colWidth` smallint(4) NOT NULL DEFAULT '264',
`minColWidth` smallint(4) NOT NULL DEFAULT '180',
`minColWidth` smallint(4) NOT NULL DEFAULT '200',
`maxColWidth` smallint(4) NOT NULL DEFAULT '384',
`object` varchar(255) NOT NULL,
`alignment` varchar(10) NOT NULL DEFAULT 'center',
@@ -2187,7 +2187,7 @@ CREATE TABLE `zt_project` (
`displayCards` smallint(6) NOT NULL DEFAULT '0',
`fluidBoard` enum('0','1') NOT NULL DEFAULT '0',
`colWidth` smallint(4) NOT NULL DEFAULT '264',
`minColWidth` smallint(4) NOT NULL DEFAULT '180',
`minColWidth` smallint(4) NOT NULL DEFAULT '200',
`maxColWidth` smallint(4) NOT NULL DEFAULT '384',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -21,8 +21,8 @@ UPDATE `zt_workflowfield` SET `options`=(SELECT id FROM `zt_workflowdatasource`
UPDATE `zt_project` SET `closedDate`='' AND `closedBy`='' WHERE `status` != 'closed';
UPDATE `zt_grouppriv` SET `method`='exportTemplate' WHERE `method` = 'exportTemplet';
INSERT INTO `zt_grouppriv` (SELECT `group`,`module`,'reply' FROM `zt_grouppriv` WHERE `module` = 'feedback' AND `method` = 'comment');
INSERT INTO `zt_grouppriv` (SELECT `group`,`module`,'ask' FROM `zt_grouppriv` WHERE `module` = 'feedback' AND `method` = 'comment');
REPLACE INTO `zt_grouppriv` (SELECT `group`,`module`,'reply' FROM `zt_grouppriv` WHERE `module` = 'feedback' AND `method` = 'comment');
REPLACE INTO `zt_grouppriv` (SELECT `group`,`module`,'ask' FROM `zt_grouppriv` WHERE `module` = 'feedback' AND `method` = 'comment');
CREATE TABLE `zt_chart` (
`id` mediumint NOT NULL AUTO_INCREMENT,
+2 -2
View File
@@ -62,10 +62,10 @@ CREATE TABLE `zt_ticketrelation` (
ALTER TABLE `zt_product` ADD `ticket` varchar(30) NOT NULL AFTER `feedback`;
ALTER TABLE `zt_kanban` ADD `colWidth` smallint(4) NOT NULL DEFAULT '264' AFTER `fluidBoard`;
ALTER TABLE `zt_kanban` ADD `minColWidth` smallint(4) NOT NULL DEFAULT '180' AFTER `colWidth`;
ALTER TABLE `zt_kanban` ADD `minColWidth` smallint(4) NOT NULL DEFAULT '200' AFTER `colWidth`;
ALTER TABLE `zt_kanban` ADD `maxColWidth` smallint(4) NOT NULL DEFAULT '384' AFTER `minColWidth`;
ALTER TABLE `zt_project` ADD `colWidth` smallint(4) NOT NULL DEFAULT '264' AFTER `fluidBoard`;
ALTER TABLE `zt_project` ADD `minColWidth` smallint(4) NOT NULL DEFAULT '180' AFTER `colWidth`;
ALTER TABLE `zt_project` ADD `minColWidth` smallint(4) NOT NULL DEFAULT '200' AFTER `colWidth`;
ALTER TABLE `zt_project` ADD `maxColWidth` smallint(4) NOT NULL DEFAULT '384' AFTER `minColWidth`;
REPLACE INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'common', 'global', 'syncProduct', '{"feedback":{},"ticket":{}}');
+23 -13
View File
@@ -1,7 +1,11 @@
ALTER TABLE `zt_product` ADD `shadow` tinyint(1) unsigned NOT NULL AFTER `code`;
ALTER TABLE `zt_project` ADD `hasProduct` tinyint(1) unsigned NOT NULL DEFAULT 1 AFTER `code`;
ALTER table `zt_project` ADD `multiple` enum('0', '1') NOT NULL DEFAULT '1';
ALTER table `zt_project` ADD `multiple` enum('0', '1') NOT NULL DEFAULT '1' AFTER `fluidBoard`;
ALTER TABLE `zt_repo` ADD `projects` varchar(255) NOT NULL AFTER `product`;
ALTER TABLE `zt_release` CHANGE `project` `project` varchar(255) NOT NULL;
ALTER TABLE `zt_release` CHANGE `branch` `branch` varchar(255) NOT NULL;
ALTER TABLE `zt_release` CHANGE `build` `build` varchar(255) NOT NULL;
ALTER TABLE `zt_release` ADD `shadow` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `branch`;
ALTER TABLE `zt_host`
DROP COLUMN `cabinet`,
@@ -64,7 +68,7 @@ h.`deleted` = a.`deleted`
WHERE
h.`assetID` = a.`id`;
ALTER TABLE `zt_host` DROP COLUMN `assetID`,
ALTER TABLE `zt_host` DROP COLUMN `assetID`;
DROP TABLE IF EXISTS `zt_asset`;
DROP TABLE IF EXISTS `zt_baseimagebrowser`;
@@ -94,11 +98,10 @@ CREATE TABLE `zt_image` (
CREATE OR REPLACE VIEW `ztv_normalproduct` AS SELECT * FROM `zt_product` WHERE `shadow` = 0;
REPLACE INTO `zt_report` (`code`, `name`, `module`, `sql`, `vars`, `langs`, `params`, `step`, `desc`, `addedBy`, `addedDate`) VALUES
('product-invest', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u6295\\u5165\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u6295\\u5165\\u8868\",\"en\":\"Product Investment\"}', ',product', 'select t1.id,t1.name,1 as projects, round(t3.consumed,2) as consumed from TABLE_PRODUCT as t1\r\n left join TABLE_PROJECTPRODUCT as t2 on t1.id=t2.product\r\n left join ztv_projectsummary as t3 on t2.project=t3.project\r\n left join TABLE_PROJECT as t4 on t2.project=t4.id\r\n left join TABLE_PROGRAM as t5 on t1.program=t5.id\r\n where t1.deleted=\'0\' and t4.deleted=\'0\' and t4.type=\'project\'\r\norder by t5.`order` asc, t1.line desc, t1.`order` asc', '', '{\"projects\":{\"zh-cn\":\"\\u9879\\u76ee\\u6570\",\"zh-tw\":\"\\u9879\\u76ee\\u6570\",\"en\":\"Projects\"},\"consumed\":{\"zh-cn\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"zh-tw\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"en\":\"Cost(h)\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"projects\",\"consumed\"],\"reportType\":[\"sum\",\"sum\"],\"sumAppend\":[\"projects\",\"consumed\"]}', 2, '{\"zh-cn\":\"\\u5217\\u51fa\\u6bcf\\u4e2a\\u4ea7\\u54c1\\u7684\\u9879\\u76ee\\u603b\\u6570\\uff0c\\u5df2\\u7ecf\\u6d88\\u8017\\u7684\\u5de5\\u65f6\\u3002\",\"zh-tw\":\"\\u5217\\u51fa\\u6bcf\\u500b\\u7522\\u54c1\\u7684\\u9805\\u76ee\\u7e3d\\u6578\\uff0c\\u5df2\\u7d93\\u6d88\\u8017\\u7684\\u5de5\\u6642\\u3002\",\"en\":\"Number of projects and consumed hours.\"}', 'admin', '2015-07-20 14:21:30'),
('product-progress', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u5b8c\\u6210\\u5ea6\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u5b8c\\u6210\\u5ea6\\u7d71\\u8a08\\u8868\",\"en\":\"Product Progress\"}', ',product', 'select t1.*,t2.name, (case when t1.status = \'closed\' or t1.stage = \'released\' then 1 else 0 end) as done, 1 as count from TABLE_STORY as t1 \r\nleft join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"count\",\"done\"],\"reportType\":[\"sum\",\"sum\"],\"sumAppend\":[\"count\",\"done\"],\"percent\":{\"1\":\"1\"},\"contrast\":{\"1\":\"count\"},\"showAlone\":{\"1\":\"1\"}}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u603b\\u6570\\uff0c\\u5b8c\\u6210\\u7684\\u603b\\u6570(\\u72b6\\u6001\\u662f\\u5173\\u95ed\\uff0c\\u6216\\u8005\\u7814\\u53d1\\u9636\\u6bb5\\u662f\\u53d1\\u5e03)\\uff0c\\u5b8c\\u6210\\u7684\\u767e\\u5206\\u6bd4\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u7e3d\\u6578\\uff0c\\u5b8c\\u6210\\u7684\\u7e3d\\u6578(\\u72c0\\u614b\\u662f\\u95dc\\u9589\\uff0c\\u6216\\u8005\\u7814\\u767c\\u968e\\u6bb5\\u662f\\u767c\\u5e03)\\uff0c\\u5b8c\\u6210\\u7684\\u767e\\u5206\\u6bd4\\u3002\",\"en\":\"Number of total stories,done stories(state is closed, or stage is released), percent of completion.\"}', 'admin', '2015-07-21 15:07:48'),
('story-status', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u9700\\u6c42\\u72b6\\u6001\\u5206\\u5e03\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u9700\\u6c42\\u72c0\\u614b\\u5206\\u5e03\\u8868\",\"en\":\"Story Status\"}', ',product', 'select t1.*,t2.name from TABLE_STORY as t1\r\n left join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"status\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u603b\\u6570\\uff0c\\u72b6\\u6001\\u7684\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u7e3d\\u6578\\uff0c\\u72c0\\u614b\\u7684\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"Total number and status distribution of stories.\"}', 'admin', '2015-07-21 15:35:38'),
('story-stage', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u9700\\u6c42\\u9636\\u6bb5\\u5206\\u5e03\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u9700\\u6c42\\u968e\\u6bb5\\u5206\\u5e03\\u8868\",\"en\":\"Story Stage\"}', ',product', 'select t1.*,t2.name from TABLE_STORY as t1\r\n left join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"stage\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u603b\\u6570\\uff0c\\u7814\\u53d1\\u9636\\u6bb5\\u7684\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u7e3d\\u6578\\uff0c\\u7814\\u767c\\u968e\\u6bb5\\u7684\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"Total number and stage distribution of stories \"}', 'admin', '2015-07-21 15:38:34'),
('product-release', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u53d1\\u5e03\\u6570\\u91cf\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u767c\\u5e03\\u6578\\u91cf\\u7d71\\u8a08\\u8868\",\"en\":\"Product Release\"}', ',product', 'select t2.name, 1 as releases from TABLE_RELEASE as t1 \r\nleft join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"releases\"],\"reportType\":[\"sum\"],\"sumAppend\":[\"releases\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u53d1\\u5e03\\u7684\\u6570\\u91cf\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u767c\\u5e03\\u7684\\u6578\\u91cf\\u3002\",\"en\":\"Product Release.\"}', 'admin', '2015-07-21 16:00:52'),
('product-progress', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u5b8c\\u6210\\u5ea6\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u5b8c\\u6210\\u5ea6\\u7d71\\u8a08\\u8868\",\"en\":\"Product Progress\",\"de\":\"Product Progress\",\"fr\":\"Product Progress\"}', ',product', 'select t1.*,t2.name, (case when t1.status = \'closed\' or t1.stage = \'released\' then 1 else 0 end) as done, 1 as count from TABLE_STORY as t1 \r\nleft join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"count\",\"done\"],\"reportType\":[\"sum\",\"sum\"],\"sumAppend\":[\"count\",\"done\"],\"percent\":{\"1\":\"1\"},\"contrast\":{\"1\":\"count\"},\"showAlone\":{\"1\":\"1\"}}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u603b\\u6570\\uff0c\\u5b8c\\u6210\\u7684\\u603b\\u6570(\\u72b6\\u6001\\u662f\\u5173\\u95ed\\uff0c\\u6216\\u8005\\u7814\\u53d1\\u9636\\u6bb5\\u662f\\u53d1\\u5e03)\\uff0c\\u5b8c\\u6210\\u7684\\u767e\\u5206\\u6bd4\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u7e3d\\u6578\\uff0c\\u5b8c\\u6210\\u7684\\u7e3d\\u6578(\\u72c0\\u614b\\u662f\\u95dc\\u9589\\uff0c\\u6216\\u8005\\u7814\\u767c\\u968e\\u6bb5\\u662f\\u767c\\u5e03)\\uff0c\\u5b8c\\u6210\\u7684\\u767e\\u5206\\u6bd4\\u3002\",\"en\":\"Number of total stories,done stories(state is closed, or stage is released), percent of completion.\",\"de\":\"Number of total stories,done stories(state is closed, or stage is released), percent of completion.\",\"fr\":\"Number of total stories,done stories(state is closed, or stage is released), percent of completion.\"}', 'admin', '2015-07-21 15:07:48'),
('story-status', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u9700\\u6c42\\u72b6\\u6001\\u5206\\u5e03\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u9700\\u6c42\\u72c0\\u614b\\u5206\\u5e03\\u8868\",\"en\":\"Story Status\",\"de\":\"Story Status\",\"fr\":\"Story Status\"}', ',product', 'select t1.*,t2.name from TABLE_STORY as t1\r\n left join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"status\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u603b\\u6570\\uff0c\\u72b6\\u6001\\u7684\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u7e3d\\u6578\\uff0c\\u72c0\\u614b\\u7684\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"Total number and status distribution of stories.\",\"de\":\"Total number and status distribution of stories.\",\"fr\":\"Total number and status distribution of stories.\"}', 'admin', '2015-07-21 15:35:38'),
('story-stage', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u9700\\u6c42\\u9636\\u6bb5\\u5206\\u5e03\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u9700\\u6c42\\u968e\\u6bb5\\u5206\\u5e03\\u8868\",\"en\":\"Story Stage\",\"de\":\"Story Stage\",\"fr\":\"Story Stage\"}', ',product', 'select t1.*,t2.name from TABLE_STORY as t1\r\n left join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"stage\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u603b\\u6570\\uff0c\\u7814\\u53d1\\u9636\\u6bb5\\u7684\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u7e3d\\u6578\\uff0c\\u7814\\u767c\\u968e\\u6bb5\\u7684\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"Total number and stage distribution of stories \",\"de\":\"Total number and stage distribution of stories \",\"fr\":\"Total number and stage distribution of stories \"}', 'admin', '2015-07-21 15:38:34'),
('product-release', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u53d1\\u5e03\\u6570\\u91cf\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u767c\\u5e03\\u6578\\u91cf\\u7d71\\u8a08\\u8868\",\"en\":\"Product Release\",\"de\":\"Product Release\",\"fr\":\"Product Release\"}', ',product', 'select t2.name, 1 as releases from TABLE_RELEASE as t1 \r\nleft join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"releases\"],\"reportType\":[\"sum\"],\"sumAppend\":[\"releases\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u53d1\\u5e03\\u7684\\u6570\\u91cf\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u767c\\u5e03\\u7684\\u6578\\u91cf\\u3002\",\"en\":\"Product Release.\",\"de\":\"Product Release.\",\"fr\":\"Product Release.\"}', 'admin', '2015-07-21 16:00:52'),
('task-status', '{\"zh-cn\":\"\\u4efb\\u52a1\\u72b6\\u6001\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u4efb\\u52d9\\u72c0\\u614b\\u7d71\\u8a08\\u8868\",\"en\":\"Task Status Report\",\"de\":\"Task Status Report\",\"fr\":\"Task Status Report\",\"vi\":\"Task Status Report\",\"ja\":\"Task Status Report\"}', ',project', 'select t1.id,t3.name as project,t1.name,t2.status,IF(t3.multiple="1",t1.name,"") as execution,t2.id as taskID, t1.status as projectstatus, (case when t2.deadline < CURDATE() and t2.deadline != \'0000-00-00\' and t2.status != \'closed\' and t2.status != \'done\' and t2.status != \'cancel\' then 1 else 0 end) as timeout from TABLE_EXECUTION as t1\r\n left join TABLE_TASK as t2 on t1.id=t2.execution\r\n left join TABLE_PROJECT as t3 on t3.id=t1.project\r\n where t1.deleted=\'0\' and t1.type in (\'sprint\',\'stage\') and t2.deleted=\'0\' and if($project=\'\',1,t3.id=$project) and if($status=\'\',1,t1.status=$status) and if($beginDate=\'\',1,t1.begin>=$beginDate) and if($endDate=\'\',1,t1.end<=$endDate)', '{\"varName\":[\"project\",\"status\",\"beginDate\",\"endDate\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u72b6\\u6001\",\"\\u6267\\u884c\\u8d77\\u59cb\\u65e5\\u671f\",\"\\u6267\\u884c\\u7ed3\\u675f\\u65e5\\u671f\"],\"requestType\":[\"select\",\"select\",\"date\",\"date\"],\"selectList\":[\"project\",\"project.status\",\"user\",\"user\"],\"default\":[\"\",\"\",\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"project\":{\"zh-cn\":\"\\u9879\\u76ee\\u540d\\u79f0\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"status\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u6267\\u884c\\u7edf\\u8ba1\\u4efb\\u52a1\\u7684\\u72b6\\u6001\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u57f7\\u884c\\u7d71\\u8a08\\u4efb\\u52d9\\u7684\\u72c0\\u614b\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-07-22 11:28:33'),
('task-type', '{\"zh-cn\":\"\\u4efb\\u52a1\\u7c7b\\u578b\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u4efb\\u52d9\\u985e\\u578b\\u7d71\\u8a08\\u8868\",\"en\":\"Task Type Report\",\"de\":\"Task Type Report\",\"fr\":\"Task Type Report\",\"vi\":\"Task Type Report\",\"ja\":\"Task Type Report\"}', ',project', 'select t1.id,t3.name as project,IF(t3.multiple="1",t1.name,"") as execution,t2.type,t2.id as taskID, t1.status as projectstatus from TABLE_EXECUTION as t1 \r\nleft join TABLE_TASK as t2 on t1.id=t2.execution\r\nleft join TABLE_PROJECT as t3 on t3.id=t1.project\r\nwhere t1.deleted=\'0\' and t1.type in (\'sprint\',\'stage\') and t2.deleted=\'0\' and if($project=\'\',1,t3.id=$project) and if($status=\'\',1,t1.status=$status) and if($beginDate=\'\',1,t1.begin>=$beginDate) and if($endDate=\'\',1,t1.end<=$endDate)', '{\"varName\":[\"project\",\"status\",\"beginDate\",\"endDate\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u72b6\\u6001\",\"\\u6267\\u884c\\u8d77\\u59cb\\u65e5\\u671f\",\"\\u6267\\u884c\\u7ed3\\u675f\\u65e5\\u671f\"],\"requestType\":[\"select\",\"select\",\"date\",\"date\"],\"selectList\":[\"project\",\"project.status\",\"user\",\"user\"],\"default\":[\"\",\"\",\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"project\":{\"zh-cn\":\"\\u9879\\u76ee\\u540d\\u79f0\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"type\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u9879\\u76ee\\u7edf\\u8ba1\\u4efb\\u52a1\\u7684\\u7c7b\\u578b\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u9805\\u76ee\\u7d71\\u8a08\\u4efb\\u52d9\\u7684\\u985e\\u578b\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-07-22 13:06:46'),
('task-assign', '{\"zh-cn\":\"\\u9879\\u76ee\\u4efb\\u52a1\\u6307\\u6d3e\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u9805\\u76ee\\u4efb\\u52d9\\u6307\\u6d3e\\u7d71\\u8a08\\u8868\",\"en\":\"Task Assign Report\",\"de\":\"Task Assign Report\",\"fr\":\"Task Assign Report\",\"vi\":\"Task Assign Report\",\"ja\":\"Task Assign Report\"}', ',project', 'select t1.id,t4.name as project,IF(t4.multiple="1",t1.name,"") as execution,if(t3.account is not null, t3.account,t2.assignedTo) as assignedTo,t2.id as taskID, t1.status as projectstatus from TABLE_EXECUTION as t1\r\n left join TABLE_TASK as t2 on t1.id=t2.execution\r\n left join TABLE_TEAM as t3 on t3.type=\'task\' && t3.root=t2.id \r\nleft join TABLE_PROJECT as t4 on t1.project=t4.id\r\nwhere t1.deleted=\'0\' and t1.type in (\'sprint\',\'stage\') and t2.deleted=\'0\' and if($project=\'\',1,t4.id=$project) and if($status=\'\',1,t1.status=$status) and if($beginDate=\'\',1,t1.begin>=$beginDate) and if($endDate=\'\',1,t1.end<=$endDate)', '{\"varName\":[\"project\",\"status\",\"beginDate\",\"endDate\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u72b6\\u6001\",\"\\u6267\\u884c\\u8d77\\u59cb\\u65e5\\u671f\",\"\\u6267\\u884c\\u7ed3\\u675f\\u65e5\\u671f\"],\"requestType\":[\"select\",\"select\",\"date\",\"date\"],\"selectList\":[\"project\",\"project.status\",\"user\",\"user\"],\"default\":[\"\",\"\",\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"assignedTo\":{\"zh-cn\":\"\\u6307\\u6d3e\\u7ed9\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"assignedTo\"],\"isUser\":{\"reportField\":[[\"1\"]]},\"reportType\":[\"count\"],\"sumAppend\":[\"\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u9879\\u76ee\\u7edf\\u8ba1\\u4efb\\u52a1\\u7684\\u6307\\u6d3e\\u7ed9\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u9805\\u76ee\\u7d71\\u8a08\\u4efb\\u52d9\\u7684\\u6307\\u6d3e\\u7d66\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-07-22 13:13:28'),
@@ -112,11 +115,18 @@ REPLACE INTO `zt_report` (`code`, `name`, `module`, `sql`, `vars`, `langs`, `par
('projectbug-resolve', '{\"zh-cn\":\"\\u9879\\u76eeBug\\u89e3\\u51b3\\u8005\\u5206\\u5e03\\u8868\",\"zh-tw\":\"\\u9805\\u76eeBug\\u89e3\\u6c7a\\u8005\\u5206\\u5e03\\u8868\",\"en\":\"Project Bug Resolve\",\"de\":\"Project Bug Resolve\",\"fr\":\"Project Bug Resolve\",\"vi\":\"Project Bug Resolve\",\"ja\":\"Project Bug Resolve\"}', ',project,test', 'select t1.id,t3.name as project,t3.id,IF(t3.multiple="1",t1.name,"") as execution,t1.id as bugID,t2.resolvedBy from TABLE_EXECUTION as t1 \r\nleft join TABLE_BUG as t2 on t1.id=t2.execution\r\nleft join TABLE_PROJECT as t3 on t3.id=t1.project\r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\' and t2.status!=\'active\' and t2.resolvedBy!=\'\' having bugID!=\'\' and if($project=\'\',1,t3.id=$project) and if($execution=\'\',1,t1.id=$execution)', '{\"varName\":[\"project\",\"execution\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u5217\\u8868\"],\"requestType\":[\"select\",\"select\"],\"selectList\":[\"project\",\"execution\"],\"default\":[\"\",\"\"]}', '{\"project\":{\"zh-cn\":\"\\u9879\\u76ee\\u540d\\u79f0\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"resolvedBy\"],\"isUser\":{\"reportField\":[[\"1\"]]},\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u9879\\u76ee\\u7edf\\u8ba1Bug\\u7684\\u89e3\\u51b3\\u8005\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u9805\\u76ee\\u7d71\\u8a08Bug\\u7684\\u89e3\\u6c7a\\u8005\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-07-23 16:13:16'),
('projectbug-assign', '{\"zh-cn\":\"\\u9879\\u76eeBug\\u6307\\u6d3e\\u7ed9\\u5206\\u5e03\\u8868\",\"zh-tw\":\"\\u9805\\u76eeBug\\u6307\\u6d3e\\u7d66\\u5206\\u5e03\\u8868\",\"en\":\"Project Bug Assign\",\"de\":\"Project Bug Assign\",\"fr\":\"Project Bug Assign\",\"vi\":\"Project Bug Assign\",\"ja\":\"Project Bug Assign\"}', ',project,test', 'select t1.id,t3.name as project,t3.id,IF(t3.multiple="1",t1.name,"") as execution,t1.id as bugID,t2.assignedTo from TABLE_EXECUTION as t1 \r\nleft join TABLE_BUG as t2 on t1.id=t2.execution \r\nleft join TABLE_PROJECT as t3 on t3.id=t1.project\r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\' having bugID!=\'\' and if($project=\'\',1,t3.id=$project) and if($execution=\'\',1,t1.id=$execution)', '{\"varName\":[\"project\",\"execution\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u5217\\u8868\"],\"requestType\":[\"select\",\"select\"],\"selectList\":[\"project\",\"execution\"],\"default\":[\"\",\"\"]}', '{\"project\":{\"zh-cn\":\"\\u9879\\u76ee\\u540d\\u79f0\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"assignedTo\"],\"isUser\":{\"reportField\":[[\"1\"]]},\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u9879\\u76ee\\u7edf\\u8ba1Bug\\u7684\\u6307\\u6d3e\\u7ed9\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u9805\\u76ee\\u7d71\\u8a08Bug\\u7684\\u6307\\u6d3e\\u7d66\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-07-23 16:29:10'),
('project-quality', '{\"zh-cn\":\"\\u9879\\u76ee\\u8d28\\u91cf\\u8868\",\"zh-tw\":\"\\u9805\\u76ee\\u8cea\\u91cf\\u8868\",\"en\":\"Project Quality Report\",\"de\":\"Project Quality Report\",\"fr\":\"Project Quality Report\",\"vi\":\"Project Quality Report\",\"ja\":\"Project Quality Report\"}', ',project', 'select t1.id, t5.name as project,t5.id,IF(t5.multiple="1",t1.name,"") as execution,t2.stories,(t2.stories-t2.undone) as doneStory,t3.number,(t3.number-t3.undone) as doneTask,t4.bugs,t4.resolutions, round(t4.bugs/(t2.stories-t2.undone),2) as bugthanstory,round(t4.bugs/(t3.number-t3.undone),2) as bugthantask,t4.seriousBugs from TABLE_EXECUTION as t1 \r\nleft join ztv_projectstories as t2 on t1.id=t2.execution\r\nleft join ztv_executionsummary as t3 on t1.id=t3.execution\r\nleft join ztv_projectbugs as t4 on t1.id=t4.execution\r\nleft join TABLE_PROJECT as t5 on t5.id=t1.project\r\nwhere t1.deleted=\'0\' and t1.type in (\'sprint\',\'stage\') and t1.grade=\'1\' and if($project=\'\',1,t5.id=$project) and if($execution=\'\',1,t1.id=$execution)', '{\"varName\":[\"project\",\"execution\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u5217\\u8868\"],\"requestType\":[\"select\",\"select\"],\"selectList\":[\"project\",\"execution\"],\"default\":[\"\",\"\"]}', '{\"stories\":{\"zh-cn\":\"\\u9700\\u6c42\\u603b\\u6570\"},\"doneStory\":{\"zh-cn\":\"\\u5b8c\\u6210\\u9700\\u6c42\\u6570\"},\"number\":{\"zh-cn\":\"\\u4efb\\u52a1\\u603b\\u6570\"},\"doneTask\":{\"zh-cn\":\"\\u5b8c\\u6210\\u4efb\\u52a1\\u6570\"},\"bugs\":{\"zh-cn\":\"Bug\\u6570\"},\"resolutions\":{\"zh-cn\":\"\\u89e3\\u51b3Bug\\u6570\"},\"bugthanstory\":{\"zh-cn\":\"Bug\\/\\u5b8c\\u6210\\u9700\\u6c42\"},\"bugthantask\":{\"zh-cn\":\"Bug\\/\\u5b8c\\u6210\\u4efb\\u52a1\"},\"seriousBugs\":{\"zh-cn\":\"\\u91cd\\u8981Bug\\u6570\"},\"seriousBugsPercent\":{\"zh-cn\":\"\\u4e25\\u91cdBug\\u6bd4\\u7387\"},\"project\":{\"zh-cn\":\"\\u9879\\u76ee\\u540d\\u79f0\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"stories\",\"doneStory\",\"number\",\"doneTask\",\"bugs\",\"resolutions\",\"bugthanstory\",\"bugthantask\",\"seriousBugs\"],\"reportType\":[\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\"],\"sumAppend\":[\"stories\",\"doneStory\",\"number\",\"doneTask\",\"bugs\",\"resolutions\",\"bugthanstory\",\"bugthantask\",\"seriousBugs\"]}', 2, '{\"zh-cn\":\"\\u5217\\u51fa\\u9879\\u76ee\\u7684\\u9700\\u6c42\\u603b\\u6570\\uff0c\\u5b8c\\u6210\\u9700\\u6c42\\u6570\\uff0c\\u4efb\\u52a1\\u603b\\u6570\\uff0c\\u5b8c\\u6210\\u7684\\u4efb\\u52a1\\u6570\\uff0cBug\\u6570\\uff0c\\u89e3\\u51b3\\u7684Bug\\u6570\\uff0cBug\\/\\u9700\\u6c42\\uff0cBug\\/\\u4efb\\u52a1\\uff0c\\u91cd\\u8981Bug\\u6570\\u91cf(\\u4e25\\u91cd\\u7a0b\\u5ea6\\u4e0d\\u5927\\u4e8e3\\uff09\\u3002\",\"zh-tw\":\"\\u5217\\u51fa\\u9805\\u76ee\\u7684\\u9700\\u6c42\\u7e3d\\u6578\\uff0c\\u5b8c\\u6210\\u9700\\u6c42\\u6578\\uff0c\\u4efb\\u52d9\\u7e3d\\u6578\\uff0c\\u5b8c\\u6210\\u7684\\u4efb\\u52d9\\u6578\\uff0cBug\\u6578\\uff0c\\u89e3\\u6c7a\\u7684Bug\\u6578\\uff0cBug\\/\\u9700\\u6c42\\uff0cBug\\/\\u4efb\\u52d9\\uff0c\\u91cd\\u8981Bug\\u6578\\u91cf(\\u56b4\\u91cd\\u7a0b\\u5ea6\\u4e0d\\u5927\\u65bc3\\uff09\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-07-23 17:03:10'),
('productbug-type', '{\"zh-cn\":\"\\u4ea7\\u54c1Bug\\u7c7b\\u578b\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u7522\\u54c1Bug\\u985e\\u578b\\u7d71\\u8a08\\u8868\",\"en\":\"Bug Type of Product\"}', ',product,test', 'select t1.id,t1.name,t2.id as bugID,t2.type from TABLE_PRODUCT as t1 \r\nleft join TABLE_BUG as t2 on t1.id=t2.product \r\nleft join TABLE_PROGRAM as t3 on t1.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t1.line desc, t1.`order` asc', '', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"type\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u7edf\\u8ba1Bug\\u7684\\u7c7b\\u578b\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u7d71\\u8a08Bug\\u7684\\u985e\\u578b\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"Type distribution of Bugs.\"}', 'admin', '2015-07-24 13:48:22'),
('product-quality', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u8d28\\u91cf\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u8cea\\u91cf\\u8868\",\"en\":\"Product Quality\"}', ',product', 'select t1.id,t1.name,t2.stories,(t2.stories-t2.undone) as doneStory,t3.bugs,t3.resolutions,round(t3.bugs/(t2.stories-t2.undone),2) as bugthanstory,t3.seriousBugs from TABLE_PRODUCT as t1 \r\nleft join ztv_productstories as t2 on t1.id=t2.product \r\nleft join ztv_productbugs as t3 on t1.id=t3.product \r\nleft join TABLE_PROGRAM as t4 on t1.program=t4.id \r\nwhere t1.deleted=\'0\'\r\norder by t4.`order` asc, t1.line desc, t1.`order` asc', '', '{\"stories\":{\"zh-cn\":\"\\u9700\\u6c42\\u603b\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u603b\\u6570\",\"en\":\"Stories\"},\"doneStory\":{\"zh-cn\":\"\\u5b8c\\u6210\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u9700\\u6c42\\u6570\",\"en\":\"Finished Stories\"},\"bugs\":{\"zh-cn\":\"Bug\\u6570\",\"zh-tw\":\"Bug\\u6570\",\"en\":\"Bugs\"},\"resolutions\":{\"zh-cn\":\"\\u89e3\\u51b3Bug\\u6570\",\"zh-tw\":\"\\u89e3\\u51b3Bug\\u6570\",\"en\":\"Solved Bugs\"},\"bugthanstory\":{\"zh-cn\":\"Bug\\/\\u5b8c\\u6210\\u9700\\u6c42\",\"zh-tw\":\"Bug\\/\\u5b8c\\u6210\\u9700\\u6c42\",\"en\":\"Bug\\/Finished Story\"},\"seriousBugs\":{\"zh-cn\":\"\\u91cd\\u8981Bug\\u6570\",\"zh-tw\":\"\\u91cd\\u8981Bug\\u6570\",\"en\":\"Serious Bugs\"},\"seriousBugsPercent\":{\"zh-cn\":\"\\u4e25\\u91cdbug\\u6bd4\\u7387\",\"zh-tw\":\"\\u4e25\\u91cdbug\\u6bd4\\u7387\",\"en\":\"Serious Bugs %\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"stories\",\"doneStory\",\"bugs\",\"resolutions\",\"bugthanstory\",\"seriousBugs\"],\"reportType\":[\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\"],\"sumAppend\":[\"stories\",\"doneStory\",\"bugs\",\"resolutions\",\"bugthanstory\",\"seriousBugs\"],\"percent\":{\"5\":\"1\"},\"contrast\":{\"5\":\"bugs\"},\"showAlone\":{\"5\":\"1\"}}', 2, '{\"zh-cn\":\"\\u5217\\u51fa\\u4ea7\\u54c1\\u7684\\u9700\\u6c42\\u6570\\uff0c\\u5b8c\\u6210\\u7684\\u9700\\u6c42\\u603b\\u6570\\uff0cBug\\u6570\\uff0c\\u89e3\\u51b3\\u7684Bug\\u603b\\u6570\\uff0cBug\\/\\u9700\\u6c42\\uff0c\\u91cd\\u8981Bug\\u6570\\u91cf(\\u4e25\\u91cd\\u7a0b\\u5ea6\\u4e0d\\u5927\\u4e8e3)\\u3002\",\"zh-tw\":\"\\u5217\\u51fa\\u7522\\u54c1\\u7684\\u9700\\u6c42\\u6578\\uff0c\\u5b8c\\u6210\\u7684\\u9700\\u6c42\\u7e3d\\u6578\\uff0cBug\\u6578\\uff0c\\u89e3\\u6c7a\\u7684Bug\\u7e3d\\u6578\\uff0cBug\\/\\u9700\\u6c42\\uff0c\\u91cd\\u8981Bug\\u6578\\u91cf(\\u56b4\\u91cd\\u7a0b\\u5ea6\\u4e0d\\u5927\\u65bc3)\\u3002\",\"en\":\"Serious Bug (severity is less than 3).\"}', 'admin', '2015-07-23 17:17:40'),
('user-login', '{\"zh-cn\":\"\\u5458\\u5de5\\u767b\\u5f55\\u6b21\\u6570\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u54e1\\u5de5\\u767b\\u9304\\u6b21\\u6578\\u7d71\\u8a08\\u8868\",\"en\":\"Login Times\"}', ',staff', 'select actor,LEFT(`date`,10) as `day` from TABLE_ACTION where `action`=\'login\' and if($startDate=\'\',1,`date`>=$startDate) and if($endDate=\'\',1,`date`<=$endDate) order by `date` asc, actor asc', '{\"varName\":[\"startDate\",\"endDate\"],\"showName\":[\"\\u8d77\\u59cb\\u65f6\\u95f4\",\"\\u7ed3\\u675f\\u65f6\\u95f4\"],\"requestType\":[\"date\",\"date\"],\"selectList\":[\"user\",\"user\"],\"default\":[\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"actor\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"day\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u5b9e\\u73b0\\u5458\\u5de5\\u767b\\u5f55\\u6b21\\u6570\\u7edf\\u8ba1\\u62a5\\u8868\\uff0c\\u6309\\u7167\\u5929\\u7edf\\u8ba1\\u6bcf\\u5929\\u6bcf\\u4e2a\\u4eba\\u7684\\u767b\\u5f55\\u6b21\\u6570\\uff0c\\u4ee5\\u53ca\\u603b\\u6570\\u3002\",\"zh-tw\":\"\\u5be6\\u73fe\\u54e1\\u5de5\\u767b\\u9304\\u6b21\\u6578\\u7d71\\u8a08\\u5831\\u8868\\uff0c\\u6309\\u7167\\u5929\\u7d71\\u8a08\\u6bcf\\u5929\\u6bcf\\u500b\\u4eba\\u7684\\u767b\\u9304\\u6b21\\u6578\\uff0c\\u4ee5\\u53ca\\u7e3d\\u6578\\u3002\",\"en\":\"The summary of user login times.\"}', 'admin', '2015-07-24 14:28:11'),
('effort', '{\"zh-cn\":\"\\u65e5\\u5fd7\\u6c47\\u603b\\u8868\",\"zh-tw\":\"\\u65e5\\u8a8c\\u532f\\u7e3d\\u8868\",\"en\":\"Effort Summary\"}', ',staff', 'select t1.account,t1.consumed,t1.`date`,if($dept=\'0\',0,t2.dept) as dept from TABLE_EFFORT as t1 left join TABLE_USER as t2 on t1.account=t2.account where t1.`deleted`=\'0\' and if($startDate=\'\',1,t1.`date`>=$startDate) and if($endDate=\'\',1,t1.`date`<=$endDate) having dept=$dept order by `date` asc', '{\"varName\":[\"dept\",\"startDate\",\"endDate\"],\"showName\":[\"\\u90e8\\u95e8\",\"\\u8d77\\u59cb\\u65f6\\u95f4\",\"\\u7ed3\\u675f\\u65f6\\u95f4\"],\"requestType\":[\"select\",\"date\",\"date\"],\"selectList\":[\"dept\",\"user\",\"user\"],\"default\":[\"\",\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"date\":{\"zh-cn\":\"\\u65e5\\u671f\",\"zh-tw\":\"\\u65e5\\u671f\",\"en\":\"Date\"},\"consumed\":{\"zh-cn\":\"\\u6d88\\u8017\\u5de5\\u65f6\",\"zh-tw\":\"\\u6d88\\u8017\\u5de5\\u65f6\",\"en\":\"Cost\"}}', '{\"group1\":\"account\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"date\"],\"reportType\":[\"sum\"],\"sumAppend\":[\"consumed\"]}', 2, '{\"zh-cn\":\"\\u67e5\\u770b\\u67d0\\u4e2a\\u65f6\\u95f4\\u6bb5\\u5185\\u7684\\u65e5\\u5fd7\\u60c5\\u51b5\\uff0c\\u53ef\\u4ee5\\u6309\\u7167\\u90e8\\u95e8\\u9009\\u62e9\\u3002\",\"zh-tw\":\"\\u67e5\\u770b\\u67d0\\u500b\\u6642\\u9593\\u6bb5\\u5167\\u7684\\u65e5\\u8a8c\\u60c5\\u6cc1\\uff0c\\u53ef\\u4ee5\\u6309\\u7167\\u90e8\\u9580\\u9078\\u64c7\\u3002\",\"en\":\"Effort summary of users.\"}', 'admin', '2015-07-27 13:53:32'),
('company-dynamic', '{\"zh-cn\":\"\\u516c\\u53f8\\u52a8\\u6001\\u6c47\\u603b\\u8868\",\"zh-tw\":\"\\u516c\\u53f8\\u52d5\\u614b\\u532f\\u7e3d\\u8868\",\"en\":\"Company Dynamics\"}', ',staff', 'select t1.day,t2.userlogin,t3.consumed,t4.storyopen,t5.storyclose,t6.taskopen,t7.taskfinish,t8.bugopen,t9.bugresolve,t1.actions from ztv_dayactions as t1 left join ztv_dayuserlogin as t2 on t1.day=t2.day left join ztv_dayeffort as t3 on t1.day=t3.date left join ztv_daystoryopen as t4 on t1.day=t4.day left join ztv_daystoryclose as t5 on t1.day=t5.day left join ztv_daytaskopen as t6 on t1.day=t6.day left join ztv_daytaskfinish as t7 on t1.day=t7.day left join ztv_daybugopen as t8 on t1.day=t8.day left join ztv_daybugresolve as t9 on t1.day=t9.day where if($startDate=\'\',1,t1.day>=$startDate) and if($endDate=\'\',1,t1.day<=$endDate)', '{\"varName\":[\"startDate\",\"endDate\"],\"showName\":[\"\\u8d77\\u59cb\\u65f6\\u95f4\",\"\\u7ed3\\u675f\\u65f6\\u95f4\"],\"requestType\":[\"date\",\"date\"],\"selectList\":[\"user\",\"user\"],\"default\":[\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"day\":{\"zh-cn\":\"\\u65e5\\u671f\",\"zh-tw\":\"\\u65e5\\u671f\",\"en\":\"Date\"},\"userlogin\":{\"zh-cn\":\"\\u767b\\u5f55\\u6b21\\u6570\",\"zh-tw\":\"\\u767b\\u9304\\u6b21\\u6578\",\"en\":\"Login\"},\"consumed\":{\"zh-cn\":\"\\u65e5\\u5fd7\\u5de5\\u65f6\",\"zh-tw\":\"\\u65e5\\u8a8c\\u5de5\\u6642\",\"en\":\"Cost(h)\"},\"storyopen\":{\"zh-cn\":\"\\u65b0\\u589e\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u65b0\\u589e\\u9700\\u6c42\\u6578\",\"en\":\"Open Story\"},\"storyclose\":{\"zh-cn\":\"\\u5173\\u95ed\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u95dc\\u9589\\u9700\\u6c42\\u6578\",\"en\":\"Closed Story\"},\"taskopen\":{\"zh-cn\":\"\\u65b0\\u589e\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u65b0\\u589e\\u4efb\\u52d9\\u6578\",\"en\":\"Open Task\"},\"taskfinish\":{\"zh-cn\":\"\\u5b8c\\u6210\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u4efb\\u52d9\\u6578\",\"en\":\"Finished Task\"},\"bugopen\":{\"zh-cn\":\"\\u65b0\\u589eBug\\u6570\",\"zh-tw\":\"\\u65b0\\u589eBug\\u6578\",\"en\":\"Open Bug\"},\"bugresolve\":{\"zh-cn\":\"\\u89e3\\u51b3Bug\\u6570\",\"zh-tw\":\"\\u89e3\\u51b3Bug\\u6578\",\"en\":\"Resolved bug\"},\"actions\":{\"zh-cn\":\"\\u52a8\\u6001\\u6570\",\"zh-tw\":\"\\u52d5\\u614b\\u6578\",\"en\":\"Dynamics\"}}', '{\"group1\":\"day\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"userlogin\",\"consumed\",\"storyopen\",\"storyclose\",\"taskopen\",\"taskfinish\",\"bugopen\",\"bugresolve\",\"actions\"],\"reportType\":[\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\"],\"sumAppend\":[\"userlogin\",\"consumed\",\"storyopen\",\"storyclose\",\"taskopen\",\"taskfinish\",\"bugopen\",\"bugresolve\",\"actions\"]}', 2, '{\"zh-cn\":\"\\u53ef\\u4ee5\\u6307\\u5b9a\\u4e00\\u4e2a\\u65f6\\u671f\\uff0c\\u5217\\u51fa\\u76f8\\u5e94\\u7684\\u6570\\u636e\\uff1a1. \\u6bcf\\u5929\\u7684\\u767b\\u5f55\\u6b21\\u6570\\u30022. \\u6bcf\\u5929\\u7684\\u65e5\\u5fd7\\u5de5\\u65f6\\u91cf\\u30023. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u9700\\u6c42\\u6570\\u30024. \\u6bcf\\u5929\\u5173\\u95ed\\u7684\\u9700\\u6c42\\u6570\\u30025. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u4efb\\u52a1\\u6570\\u30026. \\u6bcf\\u5929\\u5b8c\\u6210\\u7684\\u4efb\\u52a1\\u6570\\u30027. \\u6bcf\\u5929\\u65b0\\u589e\\u7684Bug\\u6570\\u30028. \\u6bcf\\u5929\\u89e3\\u51b3\\u7684Bug\\u6570\\u30029. \\u6bcf\\u5929\\u7684\\u52a8\\u6001\\u6570\\u3002\",\"zh-tw\":\"\\u53ef\\u4ee5\\u6307\\u5b9a\\u4e00\\u500b\\u6642\\u671f\\uff0c\\u5217\\u51fa\\u76f8\\u61c9\\u7684\\u6578\\u64da\\uff1a1. \\u6bcf\\u5929\\u7684\\u767b\\u9304\\u6b21\\u6578\\u30022. \\u6bcf\\u5929\\u7684\\u65e5\\u8a8c\\u5de5\\u6642\\u91cf\\u30023. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u9700\\u6c42\\u6578\\u30024. \\u6bcf\\u5929\\u95dc\\u9589\\u7684\\u9700\\u6c42\\u6578\\u30025. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u4efb\\u52d9\\u6578\\u30026. \\u6bcf\\u5929\\u5b8c\\u6210\\u7684\\u4efb\\u52d9\\u6578\\u30027. \\u6bcf\\u5929\\u65b0\\u589e\\u7684Bug\\u6578\\u30028. \\u6bcf\\u5929\\u89e3\\u6c7a\\u7684Bug\\u6578\\u30029. \\u6bcf\\u5929\\u7684\\u52d5\\u614b\\u6578\\u3002\",\"en\":\"The summary of company dynamics\"}', 'admin', '2015-07-27 15:09:42'),
('bug-resolve', '{\"zh-cn\":\"Bug\\u89e3\\u51b3\\u8868\",\"zh-tw\":\"Bug\\u89e3\\u6c7a\\u8868\",\"en\":\"Solved Bugs\"}', ',test', 'select *,if($product=\'\',0,product) as customproduct from TABLE_BUG where deleted=\'0\' and resolution!=\'\' and if($startDate=\'\',1,resolvedDate>=$startDate) and if($endDate=\'\',1,resolvedDate<=$endDate) having customproduct=$product', '{\"varName\":[\"product\",\"startDate\",\"endDate\"],\"showName\":[\"\\u4ea7\\u54c1\",\"\\u89e3\\u51b3\\u65e5\\u671f\\u5f00\\u59cb\",\"\\u89e3\\u51b3\\u65e5\\u671f\\u7ed3\\u675f\"],\"requestType\":[\"select\",\"date\",\"date\"],\"selectList\":[\"product\",\"user\",\"user\"],\"default\":[\"\",\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"resolvedBy\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"resolution\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"],\"percent\":[\"1\"],\"contrast\":[\"crystalTotal\"],\"showAlone\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u5217\\u51fa\\u89e3\\u51b3\\u7684Bug\\u603b\\u6570\\uff0c\\u89e3\\u51b3\\u65b9\\u6848\\u7684\\u5206\\u5e03\\uff0c\\u5360\\u7684\\u6bd4\\u4f8b\\uff08\\u8be5\\u7528\\u6237\\u89e3\\u51b3\\u7684Bug\\u7684\\u6570\\u91cf\\u5360\\u6240\\u6709\\u7684\\u89e3\\u51b3\\u7684Bug\\u7684\\u6570\\u91cf)\\u3002\",\"zh-tw\":\"\\u5217\\u51fa\\u89e3\\u6c7a\\u7684Bug\\u7e3d\\u6578\\uff0c\\u89e3\\u6c7a\\u65b9\\u6848\\u7684\\u5206\\u5e03\\uff0c\\u5360\\u7684\\u6bd4\\u4f8b\\uff08\\u8a72\\u7528\\u6236\\u89e3\\u6c7a\\u7684Bug\\u7684\\u6578\\u91cf\\u5360\\u6240\\u6709\\u7684\\u89e3\\u6c7a\\u7684Bug\\u7684\\u6578\\u91cf)\\u3002\",\"en\":\"percentage:self resolved \\/ all resolved\"}', 'admin', '2015-07-24 13:44:25'),
('productbug-type', '{\"zh-cn\":\"\\u4ea7\\u54c1Bug\\u7c7b\\u578b\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u7522\\u54c1Bug\\u985e\\u578b\\u7d71\\u8a08\\u8868\",\"en\":\"Bug Type of Product\",\"de\":\"Bug Type of Product\",\"fr\":\"Bug Type of Product\"}', ',product,test', 'select t1.id,t1.name,t2.id as bugID,t2.type from TABLE_PRODUCT as t1 \r\nleft join TABLE_BUG as t2 on t1.id=t2.product \r\nleft join TABLE_PROGRAM as t3 on t1.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t1.line desc, t1.`order` asc', '', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"type\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u7edf\\u8ba1Bug\\u7684\\u7c7b\\u578b\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u7d71\\u8a08Bug\\u7684\\u985e\\u578b\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"Type distribution of Bugs.\",\"de\":\"Type distribution of Bugs.\",\"fr\":\"Type distribution of Bugs.\"}', 'admin', '2015-07-24 13:48:22'),
('product-quality', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u8d28\\u91cf\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u8cea\\u91cf\\u8868\",\"en\":\"Product Quality\",\"de\":\"Product Quality\",\"fr\":\"Product Quality\"}', ',product', 'select t1.id,t1.name,t2.stories,(t2.stories-t2.undone) as doneStory,t3.bugs,t3.resolutions,round(t3.bugs/(t2.stories-t2.undone),2) as bugthanstory,t3.seriousBugs from TABLE_PRODUCT as t1 \r\nleft join ztv_productstories as t2 on t1.id=t2.product \r\nleft join ztv_productbugs as t3 on t1.id=t3.product \r\nleft join TABLE_PROGRAM as t4 on t1.program=t4.id \r\nwhere t1.deleted=\'0\'\r\norder by t4.`order` asc, t1.line desc, t1.`order` asc', '', '{\"stories\":{\"zh-cn\":\"\\u9700\\u6c42\\u603b\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u603b\\u6570\",\"en\":\"Stories\"},\"doneStory\":{\"zh-cn\":\"\\u5b8c\\u6210\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u9700\\u6c42\\u6570\",\"en\":\"Finished Stories\"},\"bugs\":{\"zh-cn\":\"Bug\\u6570\",\"zh-tw\":\"Bug\\u6570\",\"en\":\"Bugs\"},\"resolutions\":{\"zh-cn\":\"\\u89e3\\u51b3Bug\\u6570\",\"zh-tw\":\"\\u89e3\\u51b3Bug\\u6570\",\"en\":\"Solved Bugs\"},\"bugthanstory\":{\"zh-cn\":\"Bug\\/\\u5b8c\\u6210\\u9700\\u6c42\",\"zh-tw\":\"Bug\\/\\u5b8c\\u6210\\u9700\\u6c42\",\"en\":\"Bug\\/Finished Story\"},\"seriousBugs\":{\"zh-cn\":\"\\u91cd\\u8981Bug\\u6570\",\"zh-tw\":\"\\u91cd\\u8981Bug\\u6570\",\"en\":\"Serious Bugs\"},\"seriousBugsPercent\":{\"zh-cn\":\"\\u4e25\\u91cdbug\\u6bd4\\u7387\",\"zh-tw\":\"\\u4e25\\u91cdbug\\u6bd4\\u7387\",\"en\":\"Serious Bugs %\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"stories\",\"doneStory\",\"bugs\",\"resolutions\",\"bugthanstory\",\"seriousBugs\"],\"reportType\":[\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\"],\"sumAppend\":[\"stories\",\"doneStory\",\"bugs\",\"resolutions\",\"bugthanstory\",\"seriousBugs\"],\"percent\":{\"5\":\"1\"},\"contrast\":{\"5\":\"bugs\"},\"showAlone\":{\"5\":\"1\"}}', 2, '{\"zh-cn\":\"\\u5217\\u51fa\\u4ea7\\u54c1\\u7684\\u9700\\u6c42\\u6570\\uff0c\\u5b8c\\u6210\\u7684\\u9700\\u6c42\\u603b\\u6570\\uff0cBug\\u6570\\uff0c\\u89e3\\u51b3\\u7684Bug\\u603b\\u6570\\uff0cBug\\/\\u9700\\u6c42\\uff0c\\u91cd\\u8981Bug\\u6570\\u91cf(\\u4e25\\u91cd\\u7a0b\\u5ea6\\u4e0d\\u5927\\u4e8e3)\\u3002\",\"zh-tw\":\"\\u5217\\u51fa\\u7522\\u54c1\\u7684\\u9700\\u6c42\\u6578\\uff0c\\u5b8c\\u6210\\u7684\\u9700\\u6c42\\u7e3d\\u6578\\uff0cBug\\u6578\\uff0c\\u89e3\\u6c7a\\u7684Bug\\u7e3d\\u6578\\uff0cBug\\/\\u9700\\u6c42\\uff0c\\u91cd\\u8981Bug\\u6578\\u91cf(\\u56b4\\u91cd\\u7a0b\\u5ea6\\u4e0d\\u5927\\u65bc3)\\u3002\",\"en\":\"Serious Bug (severity is less than 3).\",\"de\":\"Serious Bug (severity is less than 3).\",\"fr\":\"Serious Bug (severity is less than 3).\"}', 'admin', '2015-07-23 17:17:40'),
('user-login', '{\"zh-cn\":\"\\u5458\\u5de5\\u767b\\u5f55\\u6b21\\u6570\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u54e1\\u5de5\\u767b\\u9304\\u6b21\\u6578\\u7d71\\u8a08\\u8868\",\"en\":\"Login Times\",\"de\":\"Login Times\",\"fr\":\"Login Times\"}', ',staff', 'select actor,LEFT(`date`,10) as `day` from TABLE_ACTION where `action`=\'login\' and if($startDate=\'\',1,`date`>=$startDate) and if($endDate=\'\',1,`date`<=$endDate) order by `date` asc, actor asc', '{\"varName\":[\"startDate\",\"endDate\"],\"showName\":[\"\\u8d77\\u59cb\\u65f6\\u95f4\",\"\\u7ed3\\u675f\\u65f6\\u95f4\"],\"requestType\":[\"date\",\"date\"],\"selectList\":[\"user\",\"user\"],\"default\":[\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"actor\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"day\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u5b9e\\u73b0\\u5458\\u5de5\\u767b\\u5f55\\u6b21\\u6570\\u7edf\\u8ba1\\u62a5\\u8868\\uff0c\\u6309\\u7167\\u5929\\u7edf\\u8ba1\\u6bcf\\u5929\\u6bcf\\u4e2a\\u4eba\\u7684\\u767b\\u5f55\\u6b21\\u6570\\uff0c\\u4ee5\\u53ca\\u603b\\u6570\\u3002\",\"zh-tw\":\"\\u5be6\\u73fe\\u54e1\\u5de5\\u767b\\u9304\\u6b21\\u6578\\u7d71\\u8a08\\u5831\\u8868\\uff0c\\u6309\\u7167\\u5929\\u7d71\\u8a08\\u6bcf\\u5929\\u6bcf\\u500b\\u4eba\\u7684\\u767b\\u9304\\u6b21\\u6578\\uff0c\\u4ee5\\u53ca\\u7e3d\\u6578\\u3002\",\"en\":\"The summary of user login times.\",\"de\":\"The summary of user login times.\",\"fr\":\"The summary of user login times.\"}', 'admin', '2015-07-24 14:28:11'),
('effort', '{\"zh-cn\":\"\\u65e5\\u5fd7\\u6c47\\u603b\\u8868\",\"zh-tw\":\"\\u65e5\\u8a8c\\u532f\\u7e3d\\u8868\",\"en\":\"Effort Summary\",\"de\":\"Effort Summary\",\"fr\":\"Effort Summary\"}', ',staff', 'select t1.account,t1.consumed,t1.`date`,if($dept=\'0\',0,t2.dept) as dept from TABLE_EFFORT as t1 left join TABLE_USER as t2 on t1.account=t2.account where t1.`deleted`=\'0\' and if($startDate=\'\',1,t1.`date`>=$startDate) and if($endDate=\'\',1,t1.`date`<=$endDate) having dept=$dept order by `date` asc', '{\"varName\":[\"dept\",\"startDate\",\"endDate\"],\"showName\":[\"\\u90e8\\u95e8\",\"\\u8d77\\u59cb\\u65f6\\u95f4\",\"\\u7ed3\\u675f\\u65f6\\u95f4\"],\"requestType\":[\"select\",\"date\",\"date\"],\"selectList\":[\"dept\",\"user\",\"user\"],\"default\":[\"\",\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"date\":{\"zh-cn\":\"\\u65e5\\u671f\",\"zh-tw\":\"\\u65e5\\u671f\",\"en\":\"Date\"},\"consumed\":{\"zh-cn\":\"\\u6d88\\u8017\\u5de5\\u65f6\",\"zh-tw\":\"\\u6d88\\u8017\\u5de5\\u65f6\",\"en\":\"Cost\"}}', '{\"group1\":\"account\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"date\"],\"reportType\":[\"sum\"],\"sumAppend\":[\"consumed\"]}', 2, '{\"zh-cn\":\"\\u67e5\\u770b\\u67d0\\u4e2a\\u65f6\\u95f4\\u6bb5\\u5185\\u7684\\u65e5\\u5fd7\\u60c5\\u51b5\\uff0c\\u53ef\\u4ee5\\u6309\\u7167\\u90e8\\u95e8\\u9009\\u62e9\\u3002\",\"zh-tw\":\"\\u67e5\\u770b\\u67d0\\u500b\\u6642\\u9593\\u6bb5\\u5167\\u7684\\u65e5\\u8a8c\\u60c5\\u6cc1\\uff0c\\u53ef\\u4ee5\\u6309\\u7167\\u90e8\\u9580\\u9078\\u64c7\\u3002\",\"en\":\"Effort summary of users.\",\"de\":\"Effort summary of users\",\"fr\":\"Effort summary of users\"}', 'admin', '2015-07-27 13:53:32'),
('company-dynamic', '{\"zh-cn\":\"\\u516c\\u53f8\\u52a8\\u6001\\u6c47\\u603b\\u8868\",\"zh-tw\":\"\\u516c\\u53f8\\u52d5\\u614b\\u532f\\u7e3d\\u8868\",\"en\":\"Company Dynamics\",\"de\":\"Company Dynamics\",\"fr\":\"Company Dynamics\"}', ',staff', 'select t1.day,t2.userlogin,t3.consumed,t4.storyopen,t5.storyclose,t6.taskopen,t7.taskfinish,t8.bugopen,t9.bugresolve,t1.actions from ztv_dayactions as t1 left join ztv_dayuserlogin as t2 on t1.day=t2.day left join ztv_dayeffort as t3 on t1.day=t3.date left join ztv_daystoryopen as t4 on t1.day=t4.day left join ztv_daystoryclose as t5 on t1.day=t5.day left join ztv_daytaskopen as t6 on t1.day=t6.day left join ztv_daytaskfinish as t7 on t1.day=t7.day left join ztv_daybugopen as t8 on t1.day=t8.day left join ztv_daybugresolve as t9 on t1.day=t9.day where if($startDate=\'\',1,t1.day>=$startDate) and if($endDate=\'\',1,t1.day<=$endDate)', '{\"varName\":[\"startDate\",\"endDate\"],\"showName\":[\"\\u8d77\\u59cb\\u65f6\\u95f4\",\"\\u7ed3\\u675f\\u65f6\\u95f4\"],\"requestType\":[\"date\",\"date\"],\"selectList\":[\"user\",\"user\"],\"default\":[\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"day\":{\"zh-cn\":\"\\u65e5\\u671f\",\"zh-tw\":\"\\u65e5\\u671f\",\"en\":\"Date\"},\"userlogin\":{\"zh-cn\":\"\\u767b\\u5f55\\u6b21\\u6570\",\"zh-tw\":\"\\u767b\\u9304\\u6b21\\u6578\",\"en\":\"Login\"},\"consumed\":{\"zh-cn\":\"\\u65e5\\u5fd7\\u5de5\\u65f6\",\"zh-tw\":\"\\u65e5\\u8a8c\\u5de5\\u6642\",\"en\":\"Cost(h)\"},\"storyopen\":{\"zh-cn\":\"\\u65b0\\u589e\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u65b0\\u589e\\u9700\\u6c42\\u6578\",\"en\":\"Open Story\"},\"storyclose\":{\"zh-cn\":\"\\u5173\\u95ed\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u95dc\\u9589\\u9700\\u6c42\\u6578\",\"en\":\"Closed Story\"},\"taskopen\":{\"zh-cn\":\"\\u65b0\\u589e\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u65b0\\u589e\\u4efb\\u52d9\\u6578\",\"en\":\"Open Task\"},\"taskfinish\":{\"zh-cn\":\"\\u5b8c\\u6210\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u4efb\\u52d9\\u6578\",\"en\":\"Finished Task\"},\"bugopen\":{\"zh-cn\":\"\\u65b0\\u589eBug\\u6570\",\"zh-tw\":\"\\u65b0\\u589eBug\\u6578\",\"en\":\"Open Bug\"},\"bugresolve\":{\"zh-cn\":\"\\u89e3\\u51b3Bug\\u6570\",\"zh-tw\":\"\\u89e3\\u51b3Bug\\u6578\",\"en\":\"Resolved bug\"},\"actions\":{\"zh-cn\":\"\\u52a8\\u6001\\u6570\",\"zh-tw\":\"\\u52d5\\u614b\\u6578\",\"en\":\"Dynamics\"}}', '{\"group1\":\"day\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"userlogin\",\"consumed\",\"storyopen\",\"storyclose\",\"taskopen\",\"taskfinish\",\"bugopen\",\"bugresolve\",\"actions\"],\"reportType\":[\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\"],\"sumAppend\":[\"userlogin\",\"consumed\",\"storyopen\",\"storyclose\",\"taskopen\",\"taskfinish\",\"bugopen\",\"bugresolve\",\"actions\"]}', 2, '{\"zh-cn\":\"\\u53ef\\u4ee5\\u6307\\u5b9a\\u4e00\\u4e2a\\u65f6\\u671f\\uff0c\\u5217\\u51fa\\u76f8\\u5e94\\u7684\\u6570\\u636e\\uff1a1. \\u6bcf\\u5929\\u7684\\u767b\\u5f55\\u6b21\\u6570\\u30022. \\u6bcf\\u5929\\u7684\\u65e5\\u5fd7\\u5de5\\u65f6\\u91cf\\u30023. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u9700\\u6c42\\u6570\\u30024. \\u6bcf\\u5929\\u5173\\u95ed\\u7684\\u9700\\u6c42\\u6570\\u30025. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u4efb\\u52a1\\u6570\\u30026. \\u6bcf\\u5929\\u5b8c\\u6210\\u7684\\u4efb\\u52a1\\u6570\\u30027. \\u6bcf\\u5929\\u65b0\\u589e\\u7684Bug\\u6570\\u30028. \\u6bcf\\u5929\\u89e3\\u51b3\\u7684Bug\\u6570\\u30029. \\u6bcf\\u5929\\u7684\\u52a8\\u6001\\u6570\\u3002\",\"zh-tw\":\"\\u53ef\\u4ee5\\u6307\\u5b9a\\u4e00\\u500b\\u6642\\u671f\\uff0c\\u5217\\u51fa\\u76f8\\u61c9\\u7684\\u6578\\u64da\\uff1a1. \\u6bcf\\u5929\\u7684\\u767b\\u9304\\u6b21\\u6578\\u30022. \\u6bcf\\u5929\\u7684\\u65e5\\u8a8c\\u5de5\\u6642\\u91cf\\u30023. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u9700\\u6c42\\u6578\\u30024. \\u6bcf\\u5929\\u95dc\\u9589\\u7684\\u9700\\u6c42\\u6578\\u30025. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u4efb\\u52d9\\u6578\\u30026. \\u6bcf\\u5929\\u5b8c\\u6210\\u7684\\u4efb\\u52d9\\u6578\\u30027. \\u6bcf\\u5929\\u65b0\\u589e\\u7684Bug\\u6578\\u30028. \\u6bcf\\u5929\\u89e3\\u6c7a\\u7684Bug\\u6578\\u30029. \\u6bcf\\u5929\\u7684\\u52d5\\u614b\\u6578\\u3002\",\"en\":\"The summary of company dynamics\",\"de\":\"The summary of company dynamics\",\"fr\":\"The summary of company dynamics\"}', 'admin', '2015-07-27 15:09:42'),
('bug-resolve', '{\"zh-cn\":\"Bug\\u89e3\\u51b3\\u8868\",\"zh-tw\":\"Bug\\u89e3\\u6c7a\\u8868\",\"en\":\"Solved Bugs\",\"de\":\"Solved Bugs\",\"fr\":\"Solved Bugs\"}', ',test', 'select *,if($product=\'\',0,product) as customproduct from TABLE_BUG where deleted=\'0\' and resolution!=\'\' and if($startDate=\'\',1,resolvedDate>=$startDate) and if($endDate=\'\',1,resolvedDate<=$endDate) having customproduct=$product', '{\"varName\":[\"product\",\"startDate\",\"endDate\"],\"showName\":[\"\\u4ea7\\u54c1\",\"\\u89e3\\u51b3\\u65e5\\u671f\\u5f00\\u59cb\",\"\\u89e3\\u51b3\\u65e5\\u671f\\u7ed3\\u675f\"],\"requestType\":[\"select\",\"date\",\"date\"],\"selectList\":[\"product\",\"user\",\"user\"],\"default\":[\"\",\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"resolvedBy\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"resolution\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"],\"percent\":[\"1\"],\"contrast\":[\"crystalTotal\"],\"showAlone\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u5217\\u51fa\\u89e3\\u51b3\\u7684Bug\\u603b\\u6570\\uff0c\\u89e3\\u51b3\\u65b9\\u6848\\u7684\\u5206\\u5e03\\uff0c\\u5360\\u7684\\u6bd4\\u4f8b\\uff08\\u8be5\\u7528\\u6237\\u89e3\\u51b3\\u7684Bug\\u7684\\u6570\\u91cf\\u5360\\u6240\\u6709\\u7684\\u89e3\\u51b3\\u7684Bug\\u7684\\u6570\\u91cf)\\u3002\",\"zh-tw\":\"\\u5217\\u51fa\\u89e3\\u6c7a\\u7684Bug\\u7e3d\\u6578\\uff0c\\u89e3\\u6c7a\\u65b9\\u6848\\u7684\\u5206\\u5e03\\uff0c\\u5360\\u7684\\u6bd4\\u4f8b\\uff08\\u8a72\\u7528\\u6236\\u89e3\\u6c7a\\u7684Bug\\u7684\\u6578\\u91cf\\u5360\\u6240\\u6709\\u7684\\u89e3\\u6c7a\\u7684Bug\\u7684\\u6578\\u91cf)\\u3002\",\"en\":\"percentage:self resolved \\/ all resolved\",\"de\":\"percentage:self resolved \\/ all resolved\",\"fr\":\"percentage:self resolved \\/ all resolved\"}', 'admin', '2015-07-24 13:44:25'),
('project-progress', '{\"zh-cn\":\"\\u9879\\u76ee\\u8fdb\\u5c55\\u8868\",\"zh-tw\":\"\\u9805\\u76ee\\u9032\\u5c55\\u8868\",\"en\":\"Project Progress Report\",\"de\":\"Project Progress Report\",\"fr\":\"Project Progress Report\",\"vi\":\"Project Progress Report\",\"ja\":\"Project Progress Report\"}', ',project', 'select t1.id,t4.name as project,t4.id,IF(t4.multiple="1",t1.name,"") as execution,t1.status,t2.number as tasks,round(t2.consumed,2) as consumed,round(t2.`left`,2) as `left`,t3.stories,t2.undone as undoneTask,t3.undone as undoneStory,t2.totalReal from TABLE_EXECUTION as t1 \r\nleft join ztv_executionsummary as t2 on t1.id=t2.execution\r\nleft join ztv_projectstories as t3 on t1.id=t3.execution\r\nleft join TABLE_PROJECT as t4 on t4.id=t1.project\r\nwhere t1.deleted=\'0\' and t1.type in (\'sprint\',\'stage\') and if($project=\'\',1,t4.id=$project) and if($execution=\'\',1,t1.id=$execution) and if($status=\'\',1,t1.status=$status)', '{\"varName\":[\"project\",\"execution\",\"status\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u5217\\u8868\",\"\\u6267\\u884c\\u72b6\\u6001\"],\"requestType\":[\"select\",\"select\",\"select\"],\"selectList\":[\"project\",\"execution\",\"project.status\"],\"default\":[\"\",\"\",\"\"]}', '{\"stories\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"tasks\":{\"zh-cn\":\"\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u4efb\\u52a1\\u6570\",\"en\":\"Tasks\"},\"undoneStory\":{\"zh-cn\":\"\\u5269\\u4f59\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u5269\\u4f59\\u9700\\u6c42\\u6570\",\"en\":\"Undone Story\"},\"undoneTask\":{\"zh-cn\":\"\\u5269\\u4f59\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u5269\\u4f59\\u4efb\\u52a1\\u6570\",\"en\":\"Undone Task\"},\"consumed\":{\"zh-cn\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"zh-tw\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"en\":\"Cost(h)\"},\"left\":{\"zh-cn\":\"\\u5269\\u4f59\\u5de5\\u65f6\",\"zh-tw\":\"\\u5269\\u4f59\\u5de5\\u65f6\",\"en\":\"Left(h)\"},\"consumedPercent\":{\"zh-cn\":\"\\u8fdb\\u5ea6\",\"zh-tw\":\"\\u8fdb\\u5ea6\",\"en\":\"Process\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"stories\",\"undoneStory\",\"tasks\",\"undoneTask\",\"left\",\"consumed\"],\"reportType\":[\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\"],\"sumAppend\":[\"stories\",\"undoneStory\",\"tasks\",\"undoneTask\",\"left\",\"consumed\"],\"percent\":{\"5\":\"1\"},\"contrast\":{\"5\":\"totalReal\"},\"showAlone\":{\"5\":\"1\"}}', 2, '{\"zh-cn\":\"\\u9879\\u76ee\\u7684\\u9700\\u6c42\\u6570\\uff0c\\u4efb\\u52a1\\u6570\\uff0c\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\\uff0c\\u5269\\u4f59\\u5de5\\u65f6\\uff0c\\u5269\\u4f59\\u9700\\u6c42\\u6570\\uff0c\\u5269\\u4f59\\u4efb\\u52a1\\u6570\\uff0c\\u8fdb\\u5ea6\\u3002\",\"zh-tw\":\"\\u9805\\u76ee\\u7684\\u9700\\u6c42\\u6578\\uff0c\\u4efb\\u52d9\\u6578\\uff0c\\u5df2\\u6d88\\u8017\\u5de5\\u6642\\uff0c\\u5269\\u9918\\u5de5\\u6642\\uff0c\\u5269\\u9918\\u9700\\u6c42\\u6578\\uff0c\\u5269\\u9918\\u4efb\\u52d9\\u6578\\uff0c\\u9032\\u5ea6\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-07-23 14:03:06'),
('projectbug-type', '{\"zh-cn\":\"\\u9879\\u76eeBug\\u7c7b\\u578b\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u9805\\u76eeBug\\u985e\\u578b\\u7d71\\u8a08\\u8868\",\"en\":\"Project Bug Type\",\"de\":\"Project Bug Type\",\"fr\":\"Project Bug Type\",\"vi\":\"Project Bug Type\",\"ja\":\"Project Bug Type\"}', ',project,test', 'select t1.id,t3.name as project,t3.id,IF(t3.multiple="1",t1.name,"") as execution,t2.id as bugID,t2.type from TABLE_EXECUTION as t1 \r\nleft join TABLE_BUG as t2 on t1.id=t2.execution\r\nleft join TABLE_PROJECT as t3 on t3.id=t1.project\r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\' and if($project=\'\',1,t3.id=$project) and if($execution=\'\',1,t1.id=$execution)', '{\"varName\":[\"project\",\"execution\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u5217\\u8868\"],\"requestType\":[\"select\",\"select\"],\"selectList\":[\"project\",\"execution\"],\"default\":[\"\",\"\"]}', '{\"stories\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"tasks\":{\"zh-cn\":\"\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u4efb\\u52a1\\u6570\",\"en\":\"Tasks\"},\"undoneStory\":{\"zh-cn\":\"\\u5269\\u4f59\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u5269\\u4f59\\u9700\\u6c42\\u6570\",\"en\":\"Undone Story\"},\"undoneTask\":{\"zh-cn\":\"\\u5269\\u4f59\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u5269\\u4f59\\u4efb\\u52a1\\u6570\",\"en\":\"Undone Task\"},\"consumed\":{\"zh-cn\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"zh-tw\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"en\":\"Cost(h)\"},\"left\":{\"zh-cn\":\"\\u5269\\u4f59\\u5de5\\u65f6\",\"zh-tw\":\"\\u5269\\u4f59\\u5de5\\u65f6\",\"en\":\"Left(h)\"},\"consumedPercent\":{\"zh-cn\":\"\\u8fdb\\u5ea6\",\"zh-tw\":\"\\u8fdb\\u5ea6\",\"en\":\"Process\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"type\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u9879\\u76ee\\u7edf\\u8ba1Bug\\u7684\\u7c7b\\u578b\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u9805\\u76ee\\u7d71\\u8a08Bug\\u7684\\u985e\\u578b\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-08-04 13:54:22');
ALTER TABLE `zt_project` ADD `division` enum('0','1') COLLATE 'utf8_general_ci' NOT NULL DEFAULT '1' AFTER `vision`;
ALTER TABLE `zt_build` ADD `builds` varchar(255) NOT NULL AFTER `execution`;
UPDATE `zt_block` SET block = 'scrumrisk' WHERE module = 'project' AND type = 'scrum' AND block = 'waterfallrisk';
UPDATE `zt_block` SET block = 'scrumissue' WHERE module = 'project' AND type = 'scrum' AND block = 'waterfallissue';
+19 -16
View File
@@ -323,6 +323,7 @@ CREATE TABLE IF NOT EXISTS `zt_build` (
`product` mediumint(8) unsigned NOT NULL default '0',
`branch` mediumint(8) unsigned NOT NULL default '0',
`execution` mediumint(8) unsigned NOT NULL default '0',
`builds` varchar(255) NOT NULL,
`name` char(150) NOT NULL,
`scmPath` char(255) NOT NULL,
`filePath` char(255) NOT NULL,
@@ -1150,7 +1151,6 @@ CREATE TABLE IF NOT EXISTS `zt_project` (
`project` mediumint(8) NOT NULL DEFAULT 0,
`model` char(30) NOT NULL,
`type` char(30) NOT NULL DEFAULT 'sprint',
`hasProduct` tinyint(1) unsigned NOT NULL DEFAULT 1,
`lifetime` char(30) NOT NULL DEFAULT '',
`budget` varchar(30) NOT NULL DEFAULT '0',
`budgetUnit` char(30) NOT NULL DEFAULT 'CNY',
@@ -1164,6 +1164,7 @@ CREATE TABLE IF NOT EXISTS `zt_project` (
`grade` tinyint(3) unsigned NOT NULL,
`name` varchar(90) NOT NULL,
`code` varchar(45) NOT NULL,
`hasProduct` tinyint(1) unsigned NOT NULL DEFAULT 1,
`begin` date NOT NULL,
`end` date NOT NULL,
`realBegan` date NOT NULL,
@@ -1196,6 +1197,7 @@ CREATE TABLE IF NOT EXISTS `zt_project` (
`whitelist` text NOT NULL,
`order` mediumint(8) unsigned NOT NULL,
`vision` varchar(10) NOT NULL DEFAULT 'rnd',
`division` enum('0','1') NOT NULL DEFAULT '1',
`displayCards` smallint(6) NOT NULL default '0',
`fluidBoard` enum('0','1') NOT NULL DEFAULT '0',
`multiple` enum('0','1') NOT NULL DEFAULT '1',
@@ -1280,10 +1282,11 @@ CREATE TABLE IF NOT EXISTS `zt_relation` (
-- DROP TABLE IF EXISTS `zt_release`;
CREATE TABLE IF NOT EXISTS `zt_release` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`project` mediumint(8) unsigned NOT NULL,
`project` varchar(255) NOT NULL,
`product` mediumint(8) unsigned NOT NULL default '0',
`branch` mediumint(8) unsigned NOT NULL default '0',
`build` mediumint(8) unsigned NOT NULL,
`branch` varchar(255) NOT NULL default '0',
`shadow` mediumint(8) unsigned NOT NULL default '0',
`build` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL default '',
`marker` enum('0','1') NOT NULL default '0',
`date` date NOT NULL,
@@ -6309,7 +6312,7 @@ INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'common', '', 'CRProduct', '1');
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'common', '', 'CRExecution', '1');
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'custom', '', 'URSR', '2');
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'common', 'global', 'mode', 'new');
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'common', 'global', 'mode', 'ALM');
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'project', '', 'unitList', 'CNY,USD');
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'project', '', 'defaultCurrency', 'CNY');
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'story', '', 'reviewRules', 'allpass');
@@ -6338,6 +6341,7 @@ CREATE TABLE IF NOT EXISTS `zt_im_chat` (
`mergedChats` text NOT NULL DEFAULT '',
`adminInvite` enum('0','1') NOT NULL DEFAULT '0',
`avatar` text NOT NULL DEFAULT '',
`archiveDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
KEY `gid` (`gid`),
KEY `name` (`name`),
@@ -7020,11 +7024,10 @@ CREATE OR REPLACE VIEW `ztv_dayactions` AS select count(*) AS `actions`,left(`zt
CREATE OR REPLACE VIEW `ztv_normalproduct` AS SELECT * FROM `zt_product` WHERE `shadow` = 0;
REPLACE INTO `zt_report` (`code`, `name`, `module`, `sql`, `vars`, `langs`, `params`, `step`, `desc`, `addedBy`, `addedDate`) VALUES
('product-invest', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u6295\\u5165\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u6295\\u5165\\u8868\",\"en\":\"Product Investment\"}', ',product', 'select t1.id,t1.name,1 as projects, round(t3.consumed,2) as consumed from TABLE_PRODUCT as t1\r\n left join TABLE_PROJECTPRODUCT as t2 on t1.id=t2.product\r\n left join ztv_projectsummary as t3 on t2.project=t3.project\r\n left join TABLE_PROJECT as t4 on t2.project=t4.id\r\n left join TABLE_PROGRAM as t5 on t1.program=t5.id\r\n where t1.deleted=\'0\' and t4.deleted=\'0\' and t4.type=\'project\'\r\norder by t5.`order` asc, t1.line desc, t1.`order` asc', '', '{\"projects\":{\"zh-cn\":\"\\u9879\\u76ee\\u6570\",\"zh-tw\":\"\\u9879\\u76ee\\u6570\",\"en\":\"Projects\"},\"consumed\":{\"zh-cn\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"zh-tw\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"en\":\"Cost(h)\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"projects\",\"consumed\"],\"reportType\":[\"sum\",\"sum\"],\"sumAppend\":[\"projects\",\"consumed\"]}', 2, '{\"zh-cn\":\"\\u5217\\u51fa\\u6bcf\\u4e2a\\u4ea7\\u54c1\\u7684\\u9879\\u76ee\\u603b\\u6570\\uff0c\\u5df2\\u7ecf\\u6d88\\u8017\\u7684\\u5de5\\u65f6\\u3002\",\"zh-tw\":\"\\u5217\\u51fa\\u6bcf\\u500b\\u7522\\u54c1\\u7684\\u9805\\u76ee\\u7e3d\\u6578\\uff0c\\u5df2\\u7d93\\u6d88\\u8017\\u7684\\u5de5\\u6642\\u3002\",\"en\":\"Number of projects and consumed hours.\"}', 'admin', '2015-07-20 14:21:30'),
('product-progress', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u5b8c\\u6210\\u5ea6\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u5b8c\\u6210\\u5ea6\\u7d71\\u8a08\\u8868\",\"en\":\"Product Progress\"}', ',product', 'select t1.*,t2.name, (case when t1.status = \'closed\' or t1.stage = \'released\' then 1 else 0 end) as done, 1 as count from TABLE_STORY as t1 \r\nleft join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"count\",\"done\"],\"reportType\":[\"sum\",\"sum\"],\"sumAppend\":[\"count\",\"done\"],\"percent\":{\"1\":\"1\"},\"contrast\":{\"1\":\"count\"},\"showAlone\":{\"1\":\"1\"}}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u603b\\u6570\\uff0c\\u5b8c\\u6210\\u7684\\u603b\\u6570(\\u72b6\\u6001\\u662f\\u5173\\u95ed\\uff0c\\u6216\\u8005\\u7814\\u53d1\\u9636\\u6bb5\\u662f\\u53d1\\u5e03)\\uff0c\\u5b8c\\u6210\\u7684\\u767e\\u5206\\u6bd4\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u7e3d\\u6578\\uff0c\\u5b8c\\u6210\\u7684\\u7e3d\\u6578(\\u72c0\\u614b\\u662f\\u95dc\\u9589\\uff0c\\u6216\\u8005\\u7814\\u767c\\u968e\\u6bb5\\u662f\\u767c\\u5e03)\\uff0c\\u5b8c\\u6210\\u7684\\u767e\\u5206\\u6bd4\\u3002\",\"en\":\"Number of total stories,done stories(state is closed, or stage is released), percent of completion.\"}', 'admin', '2015-07-21 15:07:48'),
('story-status', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u9700\\u6c42\\u72b6\\u6001\\u5206\\u5e03\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u9700\\u6c42\\u72c0\\u614b\\u5206\\u5e03\\u8868\",\"en\":\"Story Status\"}', ',product', 'select t1.*,t2.name from TABLE_STORY as t1\r\n left join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"status\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u603b\\u6570\\uff0c\\u72b6\\u6001\\u7684\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u7e3d\\u6578\\uff0c\\u72c0\\u614b\\u7684\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"Total number and status distribution of stories.\"}', 'admin', '2015-07-21 15:35:38'),
('story-stage', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u9700\\u6c42\\u9636\\u6bb5\\u5206\\u5e03\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u9700\\u6c42\\u968e\\u6bb5\\u5206\\u5e03\\u8868\",\"en\":\"Story Stage\"}', ',product', 'select t1.*,t2.name from TABLE_STORY as t1\r\n left join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"stage\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u603b\\u6570\\uff0c\\u7814\\u53d1\\u9636\\u6bb5\\u7684\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u7e3d\\u6578\\uff0c\\u7814\\u767c\\u968e\\u6bb5\\u7684\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"Total number and stage distribution of stories \"}', 'admin', '2015-07-21 15:38:34'),
('product-release', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u53d1\\u5e03\\u6570\\u91cf\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u767c\\u5e03\\u6578\\u91cf\\u7d71\\u8a08\\u8868\",\"en\":\"Product Release\"}', ',product', 'select t2.name, 1 as releases from TABLE_RELEASE as t1 \r\nleft join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"releases\"],\"reportType\":[\"sum\"],\"sumAppend\":[\"releases\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u53d1\\u5e03\\u7684\\u6570\\u91cf\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u767c\\u5e03\\u7684\\u6578\\u91cf\\u3002\",\"en\":\"Product Release.\"}', 'admin', '2015-07-21 16:00:52'),
('product-progress', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u5b8c\\u6210\\u5ea6\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u5b8c\\u6210\\u5ea6\\u7d71\\u8a08\\u8868\",\"en\":\"Product Progress\",\"de\":\"Product Progress\",\"fr\":\"Product Progress\"}', ',product', 'select t1.*,t2.name, (case when t1.status = \'closed\' or t1.stage = \'released\' then 1 else 0 end) as done, 1 as count from TABLE_STORY as t1 \r\nleft join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"count\",\"done\"],\"reportType\":[\"sum\",\"sum\"],\"sumAppend\":[\"count\",\"done\"],\"percent\":{\"1\":\"1\"},\"contrast\":{\"1\":\"count\"},\"showAlone\":{\"1\":\"1\"}}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u603b\\u6570\\uff0c\\u5b8c\\u6210\\u7684\\u603b\\u6570(\\u72b6\\u6001\\u662f\\u5173\\u95ed\\uff0c\\u6216\\u8005\\u7814\\u53d1\\u9636\\u6bb5\\u662f\\u53d1\\u5e03)\\uff0c\\u5b8c\\u6210\\u7684\\u767e\\u5206\\u6bd4\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u7e3d\\u6578\\uff0c\\u5b8c\\u6210\\u7684\\u7e3d\\u6578(\\u72c0\\u614b\\u662f\\u95dc\\u9589\\uff0c\\u6216\\u8005\\u7814\\u767c\\u968e\\u6bb5\\u662f\\u767c\\u5e03)\\uff0c\\u5b8c\\u6210\\u7684\\u767e\\u5206\\u6bd4\\u3002\",\"en\":\"Number of total stories,done stories(state is closed, or stage is released), percent of completion.\",\"de\":\"Number of total stories,done stories(state is closed, or stage is released), percent of completion.\",\"fr\":\"Number of total stories,done stories(state is closed, or stage is released), percent of completion.\"}', 'admin', '2015-07-21 15:07:48'),
('story-status', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u9700\\u6c42\\u72b6\\u6001\\u5206\\u5e03\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u9700\\u6c42\\u72c0\\u614b\\u5206\\u5e03\\u8868\",\"en\":\"Story Status\",\"de\":\"Story Status\",\"fr\":\"Story Status\"}', ',product', 'select t1.*,t2.name from TABLE_STORY as t1\r\n left join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"status\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u603b\\u6570\\uff0c\\u72b6\\u6001\\u7684\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u7e3d\\u6578\\uff0c\\u72c0\\u614b\\u7684\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"Total number and status distribution of stories.\",\"de\":\"Total number and status distribution of stories.\",\"fr\":\"Total number and status distribution of stories.\"}', 'admin', '2015-07-21 15:35:38'),
('story-stage', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u9700\\u6c42\\u9636\\u6bb5\\u5206\\u5e03\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u9700\\u6c42\\u968e\\u6bb5\\u5206\\u5e03\\u8868\",\"en\":\"Story Stage\",\"de\":\"Story Stage\",\"fr\":\"Story Stage\"}', ',product', 'select t1.*,t2.name from TABLE_STORY as t1\r\n left join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"stage\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u603b\\u6570\\uff0c\\u7814\\u53d1\\u9636\\u6bb5\\u7684\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u7e3d\\u6578\\uff0c\\u7814\\u767c\\u968e\\u6bb5\\u7684\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"Total number and stage distribution of stories \",\"de\":\"Total number and stage distribution of stories \",\"fr\":\"Total number and stage distribution of stories \"}', 'admin', '2015-07-21 15:38:34'),
('product-release', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u53d1\\u5e03\\u6570\\u91cf\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u767c\\u5e03\\u6578\\u91cf\\u7d71\\u8a08\\u8868\",\"en\":\"Product Release\",\"de\":\"Product Release\",\"fr\":\"Product Release\"}', ',product', 'select t2.name, 1 as releases from TABLE_RELEASE as t1 \r\nleft join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"releases\"],\"reportType\":[\"sum\"],\"sumAppend\":[\"releases\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u53d1\\u5e03\\u7684\\u6570\\u91cf\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u767c\\u5e03\\u7684\\u6578\\u91cf\\u3002\",\"en\":\"Product Release.\",\"de\":\"Product Release.\",\"fr\":\"Product Release.\"}', 'admin', '2015-07-21 16:00:52'),
('task-status', '{\"zh-cn\":\"\\u4efb\\u52a1\\u72b6\\u6001\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u4efb\\u52d9\\u72c0\\u614b\\u7d71\\u8a08\\u8868\",\"en\":\"Task Status Report\",\"de\":\"Task Status Report\",\"fr\":\"Task Status Report\",\"vi\":\"Task Status Report\",\"ja\":\"Task Status Report\"}', ',project', 'select t1.id,t3.name as project,t1.name,t2.status,IF(t3.multiple="1",t1.name,"") as execution,t2.id as taskID, t1.status as projectstatus, (case when t2.deadline < CURDATE() and t2.deadline != \'0000-00-00\' and t2.status != \'closed\' and t2.status != \'done\' and t2.status != \'cancel\' then 1 else 0 end) as timeout from TABLE_EXECUTION as t1\r\n left join TABLE_TASK as t2 on t1.id=t2.execution\r\n left join TABLE_PROJECT as t3 on t3.id=t1.project\r\n where t1.deleted=\'0\' and t1.type in (\'sprint\',\'stage\') and t2.deleted=\'0\' and if($project=\'\',1,t3.id=$project) and if($status=\'\',1,t1.status=$status) and if($beginDate=\'\',1,t1.begin>=$beginDate) and if($endDate=\'\',1,t1.end<=$endDate)', '{\"varName\":[\"project\",\"status\",\"beginDate\",\"endDate\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u72b6\\u6001\",\"\\u6267\\u884c\\u8d77\\u59cb\\u65e5\\u671f\",\"\\u6267\\u884c\\u7ed3\\u675f\\u65e5\\u671f\"],\"requestType\":[\"select\",\"select\",\"date\",\"date\"],\"selectList\":[\"project\",\"project.status\",\"user\",\"user\"],\"default\":[\"\",\"\",\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"project\":{\"zh-cn\":\"\\u9879\\u76ee\\u540d\\u79f0\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"status\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u6267\\u884c\\u7edf\\u8ba1\\u4efb\\u52a1\\u7684\\u72b6\\u6001\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u57f7\\u884c\\u7d71\\u8a08\\u4efb\\u52d9\\u7684\\u72c0\\u614b\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-07-22 11:28:33'),
('task-type', '{\"zh-cn\":\"\\u4efb\\u52a1\\u7c7b\\u578b\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u4efb\\u52d9\\u985e\\u578b\\u7d71\\u8a08\\u8868\",\"en\":\"Task Type Report\",\"de\":\"Task Type Report\",\"fr\":\"Task Type Report\",\"vi\":\"Task Type Report\",\"ja\":\"Task Type Report\"}', ',project', 'select t1.id,t3.name as project,IF(t3.multiple="1",t1.name,"") as execution,t2.type,t2.id as taskID, t1.status as projectstatus from TABLE_EXECUTION as t1 \r\nleft join TABLE_TASK as t2 on t1.id=t2.execution\r\nleft join TABLE_PROJECT as t3 on t3.id=t1.project\r\nwhere t1.deleted=\'0\' and t1.type in (\'sprint\',\'stage\') and t2.deleted=\'0\' and if($project=\'\',1,t3.id=$project) and if($status=\'\',1,t1.status=$status) and if($beginDate=\'\',1,t1.begin>=$beginDate) and if($endDate=\'\',1,t1.end<=$endDate)', '{\"varName\":[\"project\",\"status\",\"beginDate\",\"endDate\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u72b6\\u6001\",\"\\u6267\\u884c\\u8d77\\u59cb\\u65e5\\u671f\",\"\\u6267\\u884c\\u7ed3\\u675f\\u65e5\\u671f\"],\"requestType\":[\"select\",\"select\",\"date\",\"date\"],\"selectList\":[\"project\",\"project.status\",\"user\",\"user\"],\"default\":[\"\",\"\",\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"project\":{\"zh-cn\":\"\\u9879\\u76ee\\u540d\\u79f0\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"type\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u9879\\u76ee\\u7edf\\u8ba1\\u4efb\\u52a1\\u7684\\u7c7b\\u578b\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u9805\\u76ee\\u7d71\\u8a08\\u4efb\\u52d9\\u7684\\u985e\\u578b\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-07-22 13:06:46'),
('task-assign', '{\"zh-cn\":\"\\u9879\\u76ee\\u4efb\\u52a1\\u6307\\u6d3e\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u9805\\u76ee\\u4efb\\u52d9\\u6307\\u6d3e\\u7d71\\u8a08\\u8868\",\"en\":\"Task Assign Report\",\"de\":\"Task Assign Report\",\"fr\":\"Task Assign Report\",\"vi\":\"Task Assign Report\",\"ja\":\"Task Assign Report\"}', ',project', 'select t1.id,t4.name as project,IF(t4.multiple="1",t1.name,"") as execution,if(t3.account is not null, t3.account,t2.assignedTo) as assignedTo,t2.id as taskID, t1.status as projectstatus from TABLE_EXECUTION as t1\r\n left join TABLE_TASK as t2 on t1.id=t2.execution\r\n left join TABLE_TEAM as t3 on t3.type=\'task\' && t3.root=t2.id \r\nleft join TABLE_PROJECT as t4 on t1.project=t4.id\r\nwhere t1.deleted=\'0\' and t1.type in (\'sprint\',\'stage\') and t2.deleted=\'0\' and if($project=\'\',1,t4.id=$project) and if($status=\'\',1,t1.status=$status) and if($beginDate=\'\',1,t1.begin>=$beginDate) and if($endDate=\'\',1,t1.end<=$endDate)', '{\"varName\":[\"project\",\"status\",\"beginDate\",\"endDate\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u72b6\\u6001\",\"\\u6267\\u884c\\u8d77\\u59cb\\u65e5\\u671f\",\"\\u6267\\u884c\\u7ed3\\u675f\\u65e5\\u671f\"],\"requestType\":[\"select\",\"select\",\"date\",\"date\"],\"selectList\":[\"project\",\"project.status\",\"user\",\"user\"],\"default\":[\"\",\"\",\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"assignedTo\":{\"zh-cn\":\"\\u6307\\u6d3e\\u7ed9\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"assignedTo\"],\"isUser\":{\"reportField\":[[\"1\"]]},\"reportType\":[\"count\"],\"sumAppend\":[\"\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u9879\\u76ee\\u7edf\\u8ba1\\u4efb\\u52a1\\u7684\\u6307\\u6d3e\\u7ed9\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u9805\\u76ee\\u7d71\\u8a08\\u4efb\\u52d9\\u7684\\u6307\\u6d3e\\u7d66\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-07-22 13:13:28'),
@@ -7038,12 +7041,12 @@ REPLACE INTO `zt_report` (`code`, `name`, `module`, `sql`, `vars`, `langs`, `par
('projectbug-resolve', '{\"zh-cn\":\"\\u9879\\u76eeBug\\u89e3\\u51b3\\u8005\\u5206\\u5e03\\u8868\",\"zh-tw\":\"\\u9805\\u76eeBug\\u89e3\\u6c7a\\u8005\\u5206\\u5e03\\u8868\",\"en\":\"Project Bug Resolve\",\"de\":\"Project Bug Resolve\",\"fr\":\"Project Bug Resolve\",\"vi\":\"Project Bug Resolve\",\"ja\":\"Project Bug Resolve\"}', ',project,test', 'select t1.id,t3.name as project,t3.id,IF(t3.multiple="1",t1.name,"") as execution,t1.id as bugID,t2.resolvedBy from TABLE_EXECUTION as t1 \r\nleft join TABLE_BUG as t2 on t1.id=t2.execution\r\nleft join TABLE_PROJECT as t3 on t3.id=t1.project\r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\' and t2.status!=\'active\' and t2.resolvedBy!=\'\' having bugID!=\'\' and if($project=\'\',1,t3.id=$project) and if($execution=\'\',1,t1.id=$execution)', '{\"varName\":[\"project\",\"execution\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u5217\\u8868\"],\"requestType\":[\"select\",\"select\"],\"selectList\":[\"project\",\"execution\"],\"default\":[\"\",\"\"]}', '{\"project\":{\"zh-cn\":\"\\u9879\\u76ee\\u540d\\u79f0\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"resolvedBy\"],\"isUser\":{\"reportField\":[[\"1\"]]},\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u9879\\u76ee\\u7edf\\u8ba1Bug\\u7684\\u89e3\\u51b3\\u8005\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u9805\\u76ee\\u7d71\\u8a08Bug\\u7684\\u89e3\\u6c7a\\u8005\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-07-23 16:13:16'),
('projectbug-assign', '{\"zh-cn\":\"\\u9879\\u76eeBug\\u6307\\u6d3e\\u7ed9\\u5206\\u5e03\\u8868\",\"zh-tw\":\"\\u9805\\u76eeBug\\u6307\\u6d3e\\u7d66\\u5206\\u5e03\\u8868\",\"en\":\"Project Bug Assign\",\"de\":\"Project Bug Assign\",\"fr\":\"Project Bug Assign\",\"vi\":\"Project Bug Assign\",\"ja\":\"Project Bug Assign\"}', ',project,test', 'select t1.id,t3.name as project,t3.id,IF(t3.multiple="1",t1.name,"") as execution,t1.id as bugID,t2.assignedTo from TABLE_EXECUTION as t1 \r\nleft join TABLE_BUG as t2 on t1.id=t2.execution \r\nleft join TABLE_PROJECT as t3 on t3.id=t1.project\r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\' having bugID!=\'\' and if($project=\'\',1,t3.id=$project) and if($execution=\'\',1,t1.id=$execution)', '{\"varName\":[\"project\",\"execution\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u5217\\u8868\"],\"requestType\":[\"select\",\"select\"],\"selectList\":[\"project\",\"execution\"],\"default\":[\"\",\"\"]}', '{\"project\":{\"zh-cn\":\"\\u9879\\u76ee\\u540d\\u79f0\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"assignedTo\"],\"isUser\":{\"reportField\":[[\"1\"]]},\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u9879\\u76ee\\u7edf\\u8ba1Bug\\u7684\\u6307\\u6d3e\\u7ed9\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u9805\\u76ee\\u7d71\\u8a08Bug\\u7684\\u6307\\u6d3e\\u7d66\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-07-23 16:29:10'),
('project-quality', '{\"zh-cn\":\"\\u9879\\u76ee\\u8d28\\u91cf\\u8868\",\"zh-tw\":\"\\u9805\\u76ee\\u8cea\\u91cf\\u8868\",\"en\":\"Project Quality Report\",\"de\":\"Project Quality Report\",\"fr\":\"Project Quality Report\",\"vi\":\"Project Quality Report\",\"ja\":\"Project Quality Report\"}', ',project', 'select t1.id, t5.name as project,t5.id,IF(t5.multiple="1",t1.name,"") as execution,t2.stories,(t2.stories-t2.undone) as doneStory,t3.number,(t3.number-t3.undone) as doneTask,t4.bugs,t4.resolutions, round(t4.bugs/(t2.stories-t2.undone),2) as bugthanstory,round(t4.bugs/(t3.number-t3.undone),2) as bugthantask,t4.seriousBugs from TABLE_EXECUTION as t1 \r\nleft join ztv_projectstories as t2 on t1.id=t2.execution\r\nleft join ztv_executionsummary as t3 on t1.id=t3.execution\r\nleft join ztv_projectbugs as t4 on t1.id=t4.execution\r\nleft join TABLE_PROJECT as t5 on t5.id=t1.project\r\nwhere t1.deleted=\'0\' and t1.type in (\'sprint\',\'stage\') and t1.grade=\'1\' and if($project=\'\',1,t5.id=$project) and if($execution=\'\',1,t1.id=$execution)', '{\"varName\":[\"project\",\"execution\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u5217\\u8868\"],\"requestType\":[\"select\",\"select\"],\"selectList\":[\"project\",\"execution\"],\"default\":[\"\",\"\"]}', '{\"stories\":{\"zh-cn\":\"\\u9700\\u6c42\\u603b\\u6570\"},\"doneStory\":{\"zh-cn\":\"\\u5b8c\\u6210\\u9700\\u6c42\\u6570\"},\"number\":{\"zh-cn\":\"\\u4efb\\u52a1\\u603b\\u6570\"},\"doneTask\":{\"zh-cn\":\"\\u5b8c\\u6210\\u4efb\\u52a1\\u6570\"},\"bugs\":{\"zh-cn\":\"Bug\\u6570\"},\"resolutions\":{\"zh-cn\":\"\\u89e3\\u51b3Bug\\u6570\"},\"bugthanstory\":{\"zh-cn\":\"Bug\\/\\u5b8c\\u6210\\u9700\\u6c42\"},\"bugthantask\":{\"zh-cn\":\"Bug\\/\\u5b8c\\u6210\\u4efb\\u52a1\"},\"seriousBugs\":{\"zh-cn\":\"\\u91cd\\u8981Bug\\u6570\"},\"seriousBugsPercent\":{\"zh-cn\":\"\\u4e25\\u91cdBug\\u6bd4\\u7387\"},\"project\":{\"zh-cn\":\"\\u9879\\u76ee\\u540d\\u79f0\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"stories\",\"doneStory\",\"number\",\"doneTask\",\"bugs\",\"resolutions\",\"bugthanstory\",\"bugthantask\",\"seriousBugs\"],\"reportType\":[\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\"],\"sumAppend\":[\"stories\",\"doneStory\",\"number\",\"doneTask\",\"bugs\",\"resolutions\",\"bugthanstory\",\"bugthantask\",\"seriousBugs\"]}', 2, '{\"zh-cn\":\"\\u5217\\u51fa\\u9879\\u76ee\\u7684\\u9700\\u6c42\\u603b\\u6570\\uff0c\\u5b8c\\u6210\\u9700\\u6c42\\u6570\\uff0c\\u4efb\\u52a1\\u603b\\u6570\\uff0c\\u5b8c\\u6210\\u7684\\u4efb\\u52a1\\u6570\\uff0cBug\\u6570\\uff0c\\u89e3\\u51b3\\u7684Bug\\u6570\\uff0cBug\\/\\u9700\\u6c42\\uff0cBug\\/\\u4efb\\u52a1\\uff0c\\u91cd\\u8981Bug\\u6570\\u91cf(\\u4e25\\u91cd\\u7a0b\\u5ea6\\u4e0d\\u5927\\u4e8e3\\uff09\\u3002\",\"zh-tw\":\"\\u5217\\u51fa\\u9805\\u76ee\\u7684\\u9700\\u6c42\\u7e3d\\u6578\\uff0c\\u5b8c\\u6210\\u9700\\u6c42\\u6578\\uff0c\\u4efb\\u52d9\\u7e3d\\u6578\\uff0c\\u5b8c\\u6210\\u7684\\u4efb\\u52d9\\u6578\\uff0cBug\\u6578\\uff0c\\u89e3\\u6c7a\\u7684Bug\\u6578\\uff0cBug\\/\\u9700\\u6c42\\uff0cBug\\/\\u4efb\\u52d9\\uff0c\\u91cd\\u8981Bug\\u6578\\u91cf(\\u56b4\\u91cd\\u7a0b\\u5ea6\\u4e0d\\u5927\\u65bc3\\uff09\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-07-23 17:03:10'),
('productbug-type', '{\"zh-cn\":\"\\u4ea7\\u54c1Bug\\u7c7b\\u578b\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u7522\\u54c1Bug\\u985e\\u578b\\u7d71\\u8a08\\u8868\",\"en\":\"Bug Type of Product\"}', ',product,test', 'select t1.id,t1.name,t2.id as bugID,t2.type from TABLE_PRODUCT as t1 \r\nleft join TABLE_BUG as t2 on t1.id=t2.product \r\nleft join TABLE_PROGRAM as t3 on t1.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t1.line desc, t1.`order` asc', '', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"type\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u7edf\\u8ba1Bug\\u7684\\u7c7b\\u578b\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u7d71\\u8a08Bug\\u7684\\u985e\\u578b\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"Type distribution of Bugs.\"}', 'admin', '2015-07-24 13:48:22'),
('product-quality', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u8d28\\u91cf\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u8cea\\u91cf\\u8868\",\"en\":\"Product Quality\"}', ',product', 'select t1.id,t1.name,t2.stories,(t2.stories-t2.undone) as doneStory,t3.bugs,t3.resolutions,round(t3.bugs/(t2.stories-t2.undone),2) as bugthanstory,t3.seriousBugs from TABLE_PRODUCT as t1 \r\nleft join ztv_productstories as t2 on t1.id=t2.product \r\nleft join ztv_productbugs as t3 on t1.id=t3.product \r\nleft join TABLE_PROGRAM as t4 on t1.program=t4.id \r\nwhere t1.deleted=\'0\'\r\norder by t4.`order` asc, t1.line desc, t1.`order` asc', '', '{\"stories\":{\"zh-cn\":\"\\u9700\\u6c42\\u603b\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u603b\\u6570\",\"en\":\"Stories\"},\"doneStory\":{\"zh-cn\":\"\\u5b8c\\u6210\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u9700\\u6c42\\u6570\",\"en\":\"Finished Stories\"},\"bugs\":{\"zh-cn\":\"Bug\\u6570\",\"zh-tw\":\"Bug\\u6570\",\"en\":\"Bugs\"},\"resolutions\":{\"zh-cn\":\"\\u89e3\\u51b3Bug\\u6570\",\"zh-tw\":\"\\u89e3\\u51b3Bug\\u6570\",\"en\":\"Solved Bugs\"},\"bugthanstory\":{\"zh-cn\":\"Bug\\/\\u5b8c\\u6210\\u9700\\u6c42\",\"zh-tw\":\"Bug\\/\\u5b8c\\u6210\\u9700\\u6c42\",\"en\":\"Bug\\/Finished Story\"},\"seriousBugs\":{\"zh-cn\":\"\\u91cd\\u8981Bug\\u6570\",\"zh-tw\":\"\\u91cd\\u8981Bug\\u6570\",\"en\":\"Serious Bugs\"},\"seriousBugsPercent\":{\"zh-cn\":\"\\u4e25\\u91cdbug\\u6bd4\\u7387\",\"zh-tw\":\"\\u4e25\\u91cdbug\\u6bd4\\u7387\",\"en\":\"Serious Bugs %\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"stories\",\"doneStory\",\"bugs\",\"resolutions\",\"bugthanstory\",\"seriousBugs\"],\"reportType\":[\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\"],\"sumAppend\":[\"stories\",\"doneStory\",\"bugs\",\"resolutions\",\"bugthanstory\",\"seriousBugs\"],\"percent\":{\"5\":\"1\"},\"contrast\":{\"5\":\"bugs\"},\"showAlone\":{\"5\":\"1\"}}', 2, '{\"zh-cn\":\"\\u5217\\u51fa\\u4ea7\\u54c1\\u7684\\u9700\\u6c42\\u6570\\uff0c\\u5b8c\\u6210\\u7684\\u9700\\u6c42\\u603b\\u6570\\uff0cBug\\u6570\\uff0c\\u89e3\\u51b3\\u7684Bug\\u603b\\u6570\\uff0cBug\\/\\u9700\\u6c42\\uff0c\\u91cd\\u8981Bug\\u6570\\u91cf(\\u4e25\\u91cd\\u7a0b\\u5ea6\\u4e0d\\u5927\\u4e8e3)\\u3002\",\"zh-tw\":\"\\u5217\\u51fa\\u7522\\u54c1\\u7684\\u9700\\u6c42\\u6578\\uff0c\\u5b8c\\u6210\\u7684\\u9700\\u6c42\\u7e3d\\u6578\\uff0cBug\\u6578\\uff0c\\u89e3\\u6c7a\\u7684Bug\\u7e3d\\u6578\\uff0cBug\\/\\u9700\\u6c42\\uff0c\\u91cd\\u8981Bug\\u6578\\u91cf(\\u56b4\\u91cd\\u7a0b\\u5ea6\\u4e0d\\u5927\\u65bc3)\\u3002\",\"en\":\"Serious Bug (severity is less than 3).\"}', 'admin', '2015-07-23 17:17:40'),
('user-login', '{\"zh-cn\":\"\\u5458\\u5de5\\u767b\\u5f55\\u6b21\\u6570\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u54e1\\u5de5\\u767b\\u9304\\u6b21\\u6578\\u7d71\\u8a08\\u8868\",\"en\":\"Login Times\"}', ',staff', 'select actor,LEFT(`date`,10) as `day` from TABLE_ACTION where `action`=\'login\' and if($startDate=\'\',1,`date`>=$startDate) and if($endDate=\'\',1,`date`<=$endDate) order by `date` asc, actor asc', '{\"varName\":[\"startDate\",\"endDate\"],\"showName\":[\"\\u8d77\\u59cb\\u65f6\\u95f4\",\"\\u7ed3\\u675f\\u65f6\\u95f4\"],\"requestType\":[\"date\",\"date\"],\"selectList\":[\"user\",\"user\"],\"default\":[\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"actor\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"day\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u5b9e\\u73b0\\u5458\\u5de5\\u767b\\u5f55\\u6b21\\u6570\\u7edf\\u8ba1\\u62a5\\u8868\\uff0c\\u6309\\u7167\\u5929\\u7edf\\u8ba1\\u6bcf\\u5929\\u6bcf\\u4e2a\\u4eba\\u7684\\u767b\\u5f55\\u6b21\\u6570\\uff0c\\u4ee5\\u53ca\\u603b\\u6570\\u3002\",\"zh-tw\":\"\\u5be6\\u73fe\\u54e1\\u5de5\\u767b\\u9304\\u6b21\\u6578\\u7d71\\u8a08\\u5831\\u8868\\uff0c\\u6309\\u7167\\u5929\\u7d71\\u8a08\\u6bcf\\u5929\\u6bcf\\u500b\\u4eba\\u7684\\u767b\\u9304\\u6b21\\u6578\\uff0c\\u4ee5\\u53ca\\u7e3d\\u6578\\u3002\",\"en\":\"The summary of user login times.\"}', 'admin', '2015-07-24 14:28:11'),
('effort', '{\"zh-cn\":\"\\u65e5\\u5fd7\\u6c47\\u603b\\u8868\",\"zh-tw\":\"\\u65e5\\u8a8c\\u532f\\u7e3d\\u8868\",\"en\":\"Effort Summary\"}', ',staff', 'select t1.account,t1.consumed,t1.`date`,if($dept=\'0\',0,t2.dept) as dept from TABLE_EFFORT as t1 left join TABLE_USER as t2 on t1.account=t2.account where t1.`deleted`=\'0\' and if($startDate=\'\',1,t1.`date`>=$startDate) and if($endDate=\'\',1,t1.`date`<=$endDate) having dept=$dept order by `date` asc', '{\"varName\":[\"dept\",\"startDate\",\"endDate\"],\"showName\":[\"\\u90e8\\u95e8\",\"\\u8d77\\u59cb\\u65f6\\u95f4\",\"\\u7ed3\\u675f\\u65f6\\u95f4\"],\"requestType\":[\"select\",\"date\",\"date\"],\"selectList\":[\"dept\",\"user\",\"user\"],\"default\":[\"\",\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"date\":{\"zh-cn\":\"\\u65e5\\u671f\",\"zh-tw\":\"\\u65e5\\u671f\",\"en\":\"Date\"},\"consumed\":{\"zh-cn\":\"\\u6d88\\u8017\\u5de5\\u65f6\",\"zh-tw\":\"\\u6d88\\u8017\\u5de5\\u65f6\",\"en\":\"Cost\"}}', '{\"group1\":\"account\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"date\"],\"reportType\":[\"sum\"],\"sumAppend\":[\"consumed\"]}', 2, '{\"zh-cn\":\"\\u67e5\\u770b\\u67d0\\u4e2a\\u65f6\\u95f4\\u6bb5\\u5185\\u7684\\u65e5\\u5fd7\\u60c5\\u51b5\\uff0c\\u53ef\\u4ee5\\u6309\\u7167\\u90e8\\u95e8\\u9009\\u62e9\\u3002\",\"zh-tw\":\"\\u67e5\\u770b\\u67d0\\u500b\\u6642\\u9593\\u6bb5\\u5167\\u7684\\u65e5\\u8a8c\\u60c5\\u6cc1\\uff0c\\u53ef\\u4ee5\\u6309\\u7167\\u90e8\\u9580\\u9078\\u64c7\\u3002\",\"en\":\"Effort summary of users.\"}', 'admin', '2015-07-27 13:53:32'),
('company-dynamic', '{\"zh-cn\":\"\\u516c\\u53f8\\u52a8\\u6001\\u6c47\\u603b\\u8868\",\"zh-tw\":\"\\u516c\\u53f8\\u52d5\\u614b\\u532f\\u7e3d\\u8868\",\"en\":\"Company Dynamics\"}', ',staff', 'select t1.day,t2.userlogin,t3.consumed,t4.storyopen,t5.storyclose,t6.taskopen,t7.taskfinish,t8.bugopen,t9.bugresolve,t1.actions from ztv_dayactions as t1 left join ztv_dayuserlogin as t2 on t1.day=t2.day left join ztv_dayeffort as t3 on t1.day=t3.date left join ztv_daystoryopen as t4 on t1.day=t4.day left join ztv_daystoryclose as t5 on t1.day=t5.day left join ztv_daytaskopen as t6 on t1.day=t6.day left join ztv_daytaskfinish as t7 on t1.day=t7.day left join ztv_daybugopen as t8 on t1.day=t8.day left join ztv_daybugresolve as t9 on t1.day=t9.day where if($startDate=\'\',1,t1.day>=$startDate) and if($endDate=\'\',1,t1.day<=$endDate)', '{\"varName\":[\"startDate\",\"endDate\"],\"showName\":[\"\\u8d77\\u59cb\\u65f6\\u95f4\",\"\\u7ed3\\u675f\\u65f6\\u95f4\"],\"requestType\":[\"date\",\"date\"],\"selectList\":[\"user\",\"user\"],\"default\":[\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"day\":{\"zh-cn\":\"\\u65e5\\u671f\",\"zh-tw\":\"\\u65e5\\u671f\",\"en\":\"Date\"},\"userlogin\":{\"zh-cn\":\"\\u767b\\u5f55\\u6b21\\u6570\",\"zh-tw\":\"\\u767b\\u9304\\u6b21\\u6578\",\"en\":\"Login\"},\"consumed\":{\"zh-cn\":\"\\u65e5\\u5fd7\\u5de5\\u65f6\",\"zh-tw\":\"\\u65e5\\u8a8c\\u5de5\\u6642\",\"en\":\"Cost(h)\"},\"storyopen\":{\"zh-cn\":\"\\u65b0\\u589e\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u65b0\\u589e\\u9700\\u6c42\\u6578\",\"en\":\"Open Story\"},\"storyclose\":{\"zh-cn\":\"\\u5173\\u95ed\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u95dc\\u9589\\u9700\\u6c42\\u6578\",\"en\":\"Closed Story\"},\"taskopen\":{\"zh-cn\":\"\\u65b0\\u589e\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u65b0\\u589e\\u4efb\\u52d9\\u6578\",\"en\":\"Open Task\"},\"taskfinish\":{\"zh-cn\":\"\\u5b8c\\u6210\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u4efb\\u52d9\\u6578\",\"en\":\"Finished Task\"},\"bugopen\":{\"zh-cn\":\"\\u65b0\\u589eBug\\u6570\",\"zh-tw\":\"\\u65b0\\u589eBug\\u6578\",\"en\":\"Open Bug\"},\"bugresolve\":{\"zh-cn\":\"\\u89e3\\u51b3Bug\\u6570\",\"zh-tw\":\"\\u89e3\\u51b3Bug\\u6578\",\"en\":\"Resolved bug\"},\"actions\":{\"zh-cn\":\"\\u52a8\\u6001\\u6570\",\"zh-tw\":\"\\u52d5\\u614b\\u6578\",\"en\":\"Dynamics\"}}', '{\"group1\":\"day\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"userlogin\",\"consumed\",\"storyopen\",\"storyclose\",\"taskopen\",\"taskfinish\",\"bugopen\",\"bugresolve\",\"actions\"],\"reportType\":[\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\"],\"sumAppend\":[\"userlogin\",\"consumed\",\"storyopen\",\"storyclose\",\"taskopen\",\"taskfinish\",\"bugopen\",\"bugresolve\",\"actions\"]}', 2, '{\"zh-cn\":\"\\u53ef\\u4ee5\\u6307\\u5b9a\\u4e00\\u4e2a\\u65f6\\u671f\\uff0c\\u5217\\u51fa\\u76f8\\u5e94\\u7684\\u6570\\u636e\\uff1a1. \\u6bcf\\u5929\\u7684\\u767b\\u5f55\\u6b21\\u6570\\u30022. \\u6bcf\\u5929\\u7684\\u65e5\\u5fd7\\u5de5\\u65f6\\u91cf\\u30023. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u9700\\u6c42\\u6570\\u30024. \\u6bcf\\u5929\\u5173\\u95ed\\u7684\\u9700\\u6c42\\u6570\\u30025. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u4efb\\u52a1\\u6570\\u30026. \\u6bcf\\u5929\\u5b8c\\u6210\\u7684\\u4efb\\u52a1\\u6570\\u30027. \\u6bcf\\u5929\\u65b0\\u589e\\u7684Bug\\u6570\\u30028. \\u6bcf\\u5929\\u89e3\\u51b3\\u7684Bug\\u6570\\u30029. \\u6bcf\\u5929\\u7684\\u52a8\\u6001\\u6570\\u3002\",\"zh-tw\":\"\\u53ef\\u4ee5\\u6307\\u5b9a\\u4e00\\u500b\\u6642\\u671f\\uff0c\\u5217\\u51fa\\u76f8\\u61c9\\u7684\\u6578\\u64da\\uff1a1. \\u6bcf\\u5929\\u7684\\u767b\\u9304\\u6b21\\u6578\\u30022. \\u6bcf\\u5929\\u7684\\u65e5\\u8a8c\\u5de5\\u6642\\u91cf\\u30023. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u9700\\u6c42\\u6578\\u30024. \\u6bcf\\u5929\\u95dc\\u9589\\u7684\\u9700\\u6c42\\u6578\\u30025. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u4efb\\u52d9\\u6578\\u30026. \\u6bcf\\u5929\\u5b8c\\u6210\\u7684\\u4efb\\u52d9\\u6578\\u30027. \\u6bcf\\u5929\\u65b0\\u589e\\u7684Bug\\u6578\\u30028. \\u6bcf\\u5929\\u89e3\\u6c7a\\u7684Bug\\u6578\\u30029. \\u6bcf\\u5929\\u7684\\u52d5\\u614b\\u6578\\u3002\",\"en\":\"The summary of company dynamics\"}', 'admin', '2015-07-27 15:09:42'),
('bug-resolve', '{\"zh-cn\":\"Bug\\u89e3\\u51b3\\u8868\",\"zh-tw\":\"Bug\\u89e3\\u6c7a\\u8868\",\"en\":\"Solved Bugs\"}', ',test', 'select *,if($product=\'\',0,product) as customproduct from TABLE_BUG where deleted=\'0\' and resolution!=\'\' and if($startDate=\'\',1,resolvedDate>=$startDate) and if($endDate=\'\',1,resolvedDate<=$endDate) having customproduct=$product', '{\"varName\":[\"product\",\"startDate\",\"endDate\"],\"showName\":[\"\\u4ea7\\u54c1\",\"\\u89e3\\u51b3\\u65e5\\u671f\\u5f00\\u59cb\",\"\\u89e3\\u51b3\\u65e5\\u671f\\u7ed3\\u675f\"],\"requestType\":[\"select\",\"date\",\"date\"],\"selectList\":[\"product\",\"user\",\"user\"],\"default\":[\"\",\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"resolvedBy\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"resolution\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"],\"percent\":[\"1\"],\"contrast\":[\"crystalTotal\"],\"showAlone\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u5217\\u51fa\\u89e3\\u51b3\\u7684Bug\\u603b\\u6570\\uff0c\\u89e3\\u51b3\\u65b9\\u6848\\u7684\\u5206\\u5e03\\uff0c\\u5360\\u7684\\u6bd4\\u4f8b\\uff08\\u8be5\\u7528\\u6237\\u89e3\\u51b3\\u7684Bug\\u7684\\u6570\\u91cf\\u5360\\u6240\\u6709\\u7684\\u89e3\\u51b3\\u7684Bug\\u7684\\u6570\\u91cf)\\u3002\",\"zh-tw\":\"\\u5217\\u51fa\\u89e3\\u6c7a\\u7684Bug\\u7e3d\\u6578\\uff0c\\u89e3\\u6c7a\\u65b9\\u6848\\u7684\\u5206\\u5e03\\uff0c\\u5360\\u7684\\u6bd4\\u4f8b\\uff08\\u8a72\\u7528\\u6236\\u89e3\\u6c7a\\u7684Bug\\u7684\\u6578\\u91cf\\u5360\\u6240\\u6709\\u7684\\u89e3\\u6c7a\\u7684Bug\\u7684\\u6578\\u91cf)\\u3002\",\"en\":\"percentage:self resolved \\/ all resolved\"}', 'admin', '2015-07-24 13:44:25'),
('productbug-type', '{\"zh-cn\":\"\\u4ea7\\u54c1Bug\\u7c7b\\u578b\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u7522\\u54c1Bug\\u985e\\u578b\\u7d71\\u8a08\\u8868\",\"en\":\"Bug Type of Product\",\"de\":\"Bug Type of Product\",\"fr\":\"Bug Type of Product\"}', ',product,test', 'select t1.id,t1.name,t2.id as bugID,t2.type from TABLE_PRODUCT as t1 \r\nleft join TABLE_BUG as t2 on t1.id=t2.product \r\nleft join TABLE_PROGRAM as t3 on t1.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t1.line desc, t1.`order` asc', '', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"type\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u7edf\\u8ba1Bug\\u7684\\u7c7b\\u578b\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u7d71\\u8a08Bug\\u7684\\u985e\\u578b\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"Type distribution of Bugs.\",\"de\":\"Type distribution of Bugs.\",\"fr\":\"Type distribution of Bugs.\"}', 'admin', '2015-07-24 13:48:22'),
('product-quality', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u8d28\\u91cf\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u8cea\\u91cf\\u8868\",\"en\":\"Product Quality\",\"de\":\"Product Quality\",\"fr\":\"Product Quality\"}', ',product', 'select t1.id,t1.name,t2.stories,(t2.stories-t2.undone) as doneStory,t3.bugs,t3.resolutions,round(t3.bugs/(t2.stories-t2.undone),2) as bugthanstory,t3.seriousBugs from TABLE_PRODUCT as t1 \r\nleft join ztv_productstories as t2 on t1.id=t2.product \r\nleft join ztv_productbugs as t3 on t1.id=t3.product \r\nleft join TABLE_PROGRAM as t4 on t1.program=t4.id \r\nwhere t1.deleted=\'0\'\r\norder by t4.`order` asc, t1.line desc, t1.`order` asc', '', '{\"stories\":{\"zh-cn\":\"\\u9700\\u6c42\\u603b\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u603b\\u6570\",\"en\":\"Stories\"},\"doneStory\":{\"zh-cn\":\"\\u5b8c\\u6210\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u9700\\u6c42\\u6570\",\"en\":\"Finished Stories\"},\"bugs\":{\"zh-cn\":\"Bug\\u6570\",\"zh-tw\":\"Bug\\u6570\",\"en\":\"Bugs\"},\"resolutions\":{\"zh-cn\":\"\\u89e3\\u51b3Bug\\u6570\",\"zh-tw\":\"\\u89e3\\u51b3Bug\\u6570\",\"en\":\"Solved Bugs\"},\"bugthanstory\":{\"zh-cn\":\"Bug\\/\\u5b8c\\u6210\\u9700\\u6c42\",\"zh-tw\":\"Bug\\/\\u5b8c\\u6210\\u9700\\u6c42\",\"en\":\"Bug\\/Finished Story\"},\"seriousBugs\":{\"zh-cn\":\"\\u91cd\\u8981Bug\\u6570\",\"zh-tw\":\"\\u91cd\\u8981Bug\\u6570\",\"en\":\"Serious Bugs\"},\"seriousBugsPercent\":{\"zh-cn\":\"\\u4e25\\u91cdbug\\u6bd4\\u7387\",\"zh-tw\":\"\\u4e25\\u91cdbug\\u6bd4\\u7387\",\"en\":\"Serious Bugs %\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"stories\",\"doneStory\",\"bugs\",\"resolutions\",\"bugthanstory\",\"seriousBugs\"],\"reportType\":[\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\"],\"sumAppend\":[\"stories\",\"doneStory\",\"bugs\",\"resolutions\",\"bugthanstory\",\"seriousBugs\"],\"percent\":{\"5\":\"1\"},\"contrast\":{\"5\":\"bugs\"},\"showAlone\":{\"5\":\"1\"}}', 2, '{\"zh-cn\":\"\\u5217\\u51fa\\u4ea7\\u54c1\\u7684\\u9700\\u6c42\\u6570\\uff0c\\u5b8c\\u6210\\u7684\\u9700\\u6c42\\u603b\\u6570\\uff0cBug\\u6570\\uff0c\\u89e3\\u51b3\\u7684Bug\\u603b\\u6570\\uff0cBug\\/\\u9700\\u6c42\\uff0c\\u91cd\\u8981Bug\\u6570\\u91cf(\\u4e25\\u91cd\\u7a0b\\u5ea6\\u4e0d\\u5927\\u4e8e3)\\u3002\",\"zh-tw\":\"\\u5217\\u51fa\\u7522\\u54c1\\u7684\\u9700\\u6c42\\u6578\\uff0c\\u5b8c\\u6210\\u7684\\u9700\\u6c42\\u7e3d\\u6578\\uff0cBug\\u6578\\uff0c\\u89e3\\u6c7a\\u7684Bug\\u7e3d\\u6578\\uff0cBug\\/\\u9700\\u6c42\\uff0c\\u91cd\\u8981Bug\\u6578\\u91cf(\\u56b4\\u91cd\\u7a0b\\u5ea6\\u4e0d\\u5927\\u65bc3)\\u3002\",\"en\":\"Serious Bug (severity is less than 3).\",\"de\":\"Serious Bug (severity is less than 3).\",\"fr\":\"Serious Bug (severity is less than 3).\"}', 'admin', '2015-07-23 17:17:40'),
('user-login', '{\"zh-cn\":\"\\u5458\\u5de5\\u767b\\u5f55\\u6b21\\u6570\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u54e1\\u5de5\\u767b\\u9304\\u6b21\\u6578\\u7d71\\u8a08\\u8868\",\"en\":\"Login Times\",\"de\":\"Login Times\",\"fr\":\"Login Times\"}', ',staff', 'select actor,LEFT(`date`,10) as `day` from TABLE_ACTION where `action`=\'login\' and if($startDate=\'\',1,`date`>=$startDate) and if($endDate=\'\',1,`date`<=$endDate) order by `date` asc, actor asc', '{\"varName\":[\"startDate\",\"endDate\"],\"showName\":[\"\\u8d77\\u59cb\\u65f6\\u95f4\",\"\\u7ed3\\u675f\\u65f6\\u95f4\"],\"requestType\":[\"date\",\"date\"],\"selectList\":[\"user\",\"user\"],\"default\":[\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"actor\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"day\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u5b9e\\u73b0\\u5458\\u5de5\\u767b\\u5f55\\u6b21\\u6570\\u7edf\\u8ba1\\u62a5\\u8868\\uff0c\\u6309\\u7167\\u5929\\u7edf\\u8ba1\\u6bcf\\u5929\\u6bcf\\u4e2a\\u4eba\\u7684\\u767b\\u5f55\\u6b21\\u6570\\uff0c\\u4ee5\\u53ca\\u603b\\u6570\\u3002\",\"zh-tw\":\"\\u5be6\\u73fe\\u54e1\\u5de5\\u767b\\u9304\\u6b21\\u6578\\u7d71\\u8a08\\u5831\\u8868\\uff0c\\u6309\\u7167\\u5929\\u7d71\\u8a08\\u6bcf\\u5929\\u6bcf\\u500b\\u4eba\\u7684\\u767b\\u9304\\u6b21\\u6578\\uff0c\\u4ee5\\u53ca\\u7e3d\\u6578\\u3002\",\"en\":\"The summary of user login times.\",\"de\":\"The summary of user login times.\",\"fr\":\"The summary of user login times.\"}', 'admin', '2015-07-24 14:28:11'),
('effort', '{\"zh-cn\":\"\\u65e5\\u5fd7\\u6c47\\u603b\\u8868\",\"zh-tw\":\"\\u65e5\\u8a8c\\u532f\\u7e3d\\u8868\",\"en\":\"Effort Summary\",\"de\":\"Effort Summary\",\"fr\":\"Effort Summary\"}', ',staff', 'select t1.account,t1.consumed,t1.`date`,if($dept=\'0\',0,t2.dept) as dept from TABLE_EFFORT as t1 left join TABLE_USER as t2 on t1.account=t2.account where t1.`deleted`=\'0\' and if($startDate=\'\',1,t1.`date`>=$startDate) and if($endDate=\'\',1,t1.`date`<=$endDate) having dept=$dept order by `date` asc', '{\"varName\":[\"dept\",\"startDate\",\"endDate\"],\"showName\":[\"\\u90e8\\u95e8\",\"\\u8d77\\u59cb\\u65f6\\u95f4\",\"\\u7ed3\\u675f\\u65f6\\u95f4\"],\"requestType\":[\"select\",\"date\",\"date\"],\"selectList\":[\"dept\",\"user\",\"user\"],\"default\":[\"\",\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"date\":{\"zh-cn\":\"\\u65e5\\u671f\",\"zh-tw\":\"\\u65e5\\u671f\",\"en\":\"Date\"},\"consumed\":{\"zh-cn\":\"\\u6d88\\u8017\\u5de5\\u65f6\",\"zh-tw\":\"\\u6d88\\u8017\\u5de5\\u65f6\",\"en\":\"Cost\"}}', '{\"group1\":\"account\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"date\"],\"reportType\":[\"sum\"],\"sumAppend\":[\"consumed\"]}', 2, '{\"zh-cn\":\"\\u67e5\\u770b\\u67d0\\u4e2a\\u65f6\\u95f4\\u6bb5\\u5185\\u7684\\u65e5\\u5fd7\\u60c5\\u51b5\\uff0c\\u53ef\\u4ee5\\u6309\\u7167\\u90e8\\u95e8\\u9009\\u62e9\\u3002\",\"zh-tw\":\"\\u67e5\\u770b\\u67d0\\u500b\\u6642\\u9593\\u6bb5\\u5167\\u7684\\u65e5\\u8a8c\\u60c5\\u6cc1\\uff0c\\u53ef\\u4ee5\\u6309\\u7167\\u90e8\\u9580\\u9078\\u64c7\\u3002\",\"en\":\"Effort summary of users.\",\"de\":\"Effort summary of users\",\"fr\":\"Effort summary of users\"}', 'admin', '2015-07-27 13:53:32'),
('company-dynamic', '{\"zh-cn\":\"\\u516c\\u53f8\\u52a8\\u6001\\u6c47\\u603b\\u8868\",\"zh-tw\":\"\\u516c\\u53f8\\u52d5\\u614b\\u532f\\u7e3d\\u8868\",\"en\":\"Company Dynamics\",\"de\":\"Company Dynamics\",\"fr\":\"Company Dynamics\"}', ',staff', 'select t1.day,t2.userlogin,t3.consumed,t4.storyopen,t5.storyclose,t6.taskopen,t7.taskfinish,t8.bugopen,t9.bugresolve,t1.actions from ztv_dayactions as t1 left join ztv_dayuserlogin as t2 on t1.day=t2.day left join ztv_dayeffort as t3 on t1.day=t3.date left join ztv_daystoryopen as t4 on t1.day=t4.day left join ztv_daystoryclose as t5 on t1.day=t5.day left join ztv_daytaskopen as t6 on t1.day=t6.day left join ztv_daytaskfinish as t7 on t1.day=t7.day left join ztv_daybugopen as t8 on t1.day=t8.day left join ztv_daybugresolve as t9 on t1.day=t9.day where if($startDate=\'\',1,t1.day>=$startDate) and if($endDate=\'\',1,t1.day<=$endDate)', '{\"varName\":[\"startDate\",\"endDate\"],\"showName\":[\"\\u8d77\\u59cb\\u65f6\\u95f4\",\"\\u7ed3\\u675f\\u65f6\\u95f4\"],\"requestType\":[\"date\",\"date\"],\"selectList\":[\"user\",\"user\"],\"default\":[\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"day\":{\"zh-cn\":\"\\u65e5\\u671f\",\"zh-tw\":\"\\u65e5\\u671f\",\"en\":\"Date\"},\"userlogin\":{\"zh-cn\":\"\\u767b\\u5f55\\u6b21\\u6570\",\"zh-tw\":\"\\u767b\\u9304\\u6b21\\u6578\",\"en\":\"Login\"},\"consumed\":{\"zh-cn\":\"\\u65e5\\u5fd7\\u5de5\\u65f6\",\"zh-tw\":\"\\u65e5\\u8a8c\\u5de5\\u6642\",\"en\":\"Cost(h)\"},\"storyopen\":{\"zh-cn\":\"\\u65b0\\u589e\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u65b0\\u589e\\u9700\\u6c42\\u6578\",\"en\":\"Open Story\"},\"storyclose\":{\"zh-cn\":\"\\u5173\\u95ed\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u95dc\\u9589\\u9700\\u6c42\\u6578\",\"en\":\"Closed Story\"},\"taskopen\":{\"zh-cn\":\"\\u65b0\\u589e\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u65b0\\u589e\\u4efb\\u52d9\\u6578\",\"en\":\"Open Task\"},\"taskfinish\":{\"zh-cn\":\"\\u5b8c\\u6210\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u4efb\\u52d9\\u6578\",\"en\":\"Finished Task\"},\"bugopen\":{\"zh-cn\":\"\\u65b0\\u589eBug\\u6570\",\"zh-tw\":\"\\u65b0\\u589eBug\\u6578\",\"en\":\"Open Bug\"},\"bugresolve\":{\"zh-cn\":\"\\u89e3\\u51b3Bug\\u6570\",\"zh-tw\":\"\\u89e3\\u51b3Bug\\u6578\",\"en\":\"Resolved bug\"},\"actions\":{\"zh-cn\":\"\\u52a8\\u6001\\u6570\",\"zh-tw\":\"\\u52d5\\u614b\\u6578\",\"en\":\"Dynamics\"}}', '{\"group1\":\"day\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"userlogin\",\"consumed\",\"storyopen\",\"storyclose\",\"taskopen\",\"taskfinish\",\"bugopen\",\"bugresolve\",\"actions\"],\"reportType\":[\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\"],\"sumAppend\":[\"userlogin\",\"consumed\",\"storyopen\",\"storyclose\",\"taskopen\",\"taskfinish\",\"bugopen\",\"bugresolve\",\"actions\"]}', 2, '{\"zh-cn\":\"\\u53ef\\u4ee5\\u6307\\u5b9a\\u4e00\\u4e2a\\u65f6\\u671f\\uff0c\\u5217\\u51fa\\u76f8\\u5e94\\u7684\\u6570\\u636e\\uff1a1. \\u6bcf\\u5929\\u7684\\u767b\\u5f55\\u6b21\\u6570\\u30022. \\u6bcf\\u5929\\u7684\\u65e5\\u5fd7\\u5de5\\u65f6\\u91cf\\u30023. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u9700\\u6c42\\u6570\\u30024. \\u6bcf\\u5929\\u5173\\u95ed\\u7684\\u9700\\u6c42\\u6570\\u30025. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u4efb\\u52a1\\u6570\\u30026. \\u6bcf\\u5929\\u5b8c\\u6210\\u7684\\u4efb\\u52a1\\u6570\\u30027. \\u6bcf\\u5929\\u65b0\\u589e\\u7684Bug\\u6570\\u30028. \\u6bcf\\u5929\\u89e3\\u51b3\\u7684Bug\\u6570\\u30029. \\u6bcf\\u5929\\u7684\\u52a8\\u6001\\u6570\\u3002\",\"zh-tw\":\"\\u53ef\\u4ee5\\u6307\\u5b9a\\u4e00\\u500b\\u6642\\u671f\\uff0c\\u5217\\u51fa\\u76f8\\u61c9\\u7684\\u6578\\u64da\\uff1a1. \\u6bcf\\u5929\\u7684\\u767b\\u9304\\u6b21\\u6578\\u30022. \\u6bcf\\u5929\\u7684\\u65e5\\u8a8c\\u5de5\\u6642\\u91cf\\u30023. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u9700\\u6c42\\u6578\\u30024. \\u6bcf\\u5929\\u95dc\\u9589\\u7684\\u9700\\u6c42\\u6578\\u30025. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u4efb\\u52d9\\u6578\\u30026. \\u6bcf\\u5929\\u5b8c\\u6210\\u7684\\u4efb\\u52d9\\u6578\\u30027. \\u6bcf\\u5929\\u65b0\\u589e\\u7684Bug\\u6578\\u30028. \\u6bcf\\u5929\\u89e3\\u6c7a\\u7684Bug\\u6578\\u30029. \\u6bcf\\u5929\\u7684\\u52d5\\u614b\\u6578\\u3002\",\"en\":\"The summary of company dynamics\",\"de\":\"The summary of company dynamics\",\"fr\":\"The summary of company dynamics\"}', 'admin', '2015-07-27 15:09:42'),
('bug-resolve', '{\"zh-cn\":\"Bug\\u89e3\\u51b3\\u8868\",\"zh-tw\":\"Bug\\u89e3\\u6c7a\\u8868\",\"en\":\"Solved Bugs\",\"de\":\"Solved Bugs\",\"fr\":\"Solved Bugs\"}', ',test', 'select *,if($product=\'\',0,product) as customproduct from TABLE_BUG where deleted=\'0\' and resolution!=\'\' and if($startDate=\'\',1,resolvedDate>=$startDate) and if($endDate=\'\',1,resolvedDate<=$endDate) having customproduct=$product', '{\"varName\":[\"product\",\"startDate\",\"endDate\"],\"showName\":[\"\\u4ea7\\u54c1\",\"\\u89e3\\u51b3\\u65e5\\u671f\\u5f00\\u59cb\",\"\\u89e3\\u51b3\\u65e5\\u671f\\u7ed3\\u675f\"],\"requestType\":[\"select\",\"date\",\"date\"],\"selectList\":[\"product\",\"user\",\"user\"],\"default\":[\"\",\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"resolvedBy\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"resolution\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"],\"percent\":[\"1\"],\"contrast\":[\"crystalTotal\"],\"showAlone\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u5217\\u51fa\\u89e3\\u51b3\\u7684Bug\\u603b\\u6570\\uff0c\\u89e3\\u51b3\\u65b9\\u6848\\u7684\\u5206\\u5e03\\uff0c\\u5360\\u7684\\u6bd4\\u4f8b\\uff08\\u8be5\\u7528\\u6237\\u89e3\\u51b3\\u7684Bug\\u7684\\u6570\\u91cf\\u5360\\u6240\\u6709\\u7684\\u89e3\\u51b3\\u7684Bug\\u7684\\u6570\\u91cf)\\u3002\",\"zh-tw\":\"\\u5217\\u51fa\\u89e3\\u6c7a\\u7684Bug\\u7e3d\\u6578\\uff0c\\u89e3\\u6c7a\\u65b9\\u6848\\u7684\\u5206\\u5e03\\uff0c\\u5360\\u7684\\u6bd4\\u4f8b\\uff08\\u8a72\\u7528\\u6236\\u89e3\\u6c7a\\u7684Bug\\u7684\\u6578\\u91cf\\u5360\\u6240\\u6709\\u7684\\u89e3\\u6c7a\\u7684Bug\\u7684\\u6578\\u91cf)\\u3002\",\"en\":\"percentage:self resolved \\/ all resolved\",\"de\":\"percentage:self resolved \\/ all resolved\",\"fr\":\"percentage:self resolved \\/ all resolved\"}', 'admin', '2015-07-24 13:44:25'),
('project-progress', '{\"zh-cn\":\"\\u9879\\u76ee\\u8fdb\\u5c55\\u8868\",\"zh-tw\":\"\\u9805\\u76ee\\u9032\\u5c55\\u8868\",\"en\":\"Project Progress Report\",\"de\":\"Project Progress Report\",\"fr\":\"Project Progress Report\",\"vi\":\"Project Progress Report\",\"ja\":\"Project Progress Report\"}', ',project', 'select t1.id,t4.name as project,t4.id,IF(t4.multiple="1",t1.name,"") as execution,t1.status,t2.number as tasks,round(t2.consumed,2) as consumed,round(t2.`left`,2) as `left`,t3.stories,t2.undone as undoneTask,t3.undone as undoneStory,t2.totalReal from TABLE_EXECUTION as t1 \r\nleft join ztv_executionsummary as t2 on t1.id=t2.execution\r\nleft join ztv_projectstories as t3 on t1.id=t3.execution\r\nleft join TABLE_PROJECT as t4 on t4.id=t1.project\r\nwhere t1.deleted=\'0\' and t1.type in (\'sprint\',\'stage\') and if($project=\'\',1,t4.id=$project) and if($execution=\'\',1,t1.id=$execution) and if($status=\'\',1,t1.status=$status)', '{\"varName\":[\"project\",\"execution\",\"status\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u5217\\u8868\",\"\\u6267\\u884c\\u72b6\\u6001\"],\"requestType\":[\"select\",\"select\",\"select\"],\"selectList\":[\"project\",\"execution\",\"project.status\"],\"default\":[\"\",\"\",\"\"]}', '{\"stories\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"tasks\":{\"zh-cn\":\"\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u4efb\\u52a1\\u6570\",\"en\":\"Tasks\"},\"undoneStory\":{\"zh-cn\":\"\\u5269\\u4f59\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u5269\\u4f59\\u9700\\u6c42\\u6570\",\"en\":\"Undone Story\"},\"undoneTask\":{\"zh-cn\":\"\\u5269\\u4f59\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u5269\\u4f59\\u4efb\\u52a1\\u6570\",\"en\":\"Undone Task\"},\"consumed\":{\"zh-cn\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"zh-tw\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"en\":\"Cost(h)\"},\"left\":{\"zh-cn\":\"\\u5269\\u4f59\\u5de5\\u65f6\",\"zh-tw\":\"\\u5269\\u4f59\\u5de5\\u65f6\",\"en\":\"Left(h)\"},\"consumedPercent\":{\"zh-cn\":\"\\u8fdb\\u5ea6\",\"zh-tw\":\"\\u8fdb\\u5ea6\",\"en\":\"Process\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"stories\",\"undoneStory\",\"tasks\",\"undoneTask\",\"left\",\"consumed\"],\"reportType\":[\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\"],\"sumAppend\":[\"stories\",\"undoneStory\",\"tasks\",\"undoneTask\",\"left\",\"consumed\"],\"percent\":{\"5\":\"1\"},\"contrast\":{\"5\":\"totalReal\"},\"showAlone\":{\"5\":\"1\"}}', 2, '{\"zh-cn\":\"\\u9879\\u76ee\\u7684\\u9700\\u6c42\\u6570\\uff0c\\u4efb\\u52a1\\u6570\\uff0c\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\\uff0c\\u5269\\u4f59\\u5de5\\u65f6\\uff0c\\u5269\\u4f59\\u9700\\u6c42\\u6570\\uff0c\\u5269\\u4f59\\u4efb\\u52a1\\u6570\\uff0c\\u8fdb\\u5ea6\\u3002\",\"zh-tw\":\"\\u9805\\u76ee\\u7684\\u9700\\u6c42\\u6578\\uff0c\\u4efb\\u52d9\\u6578\\uff0c\\u5df2\\u6d88\\u8017\\u5de5\\u6642\\uff0c\\u5269\\u9918\\u5de5\\u6642\\uff0c\\u5269\\u9918\\u9700\\u6c42\\u6578\\uff0c\\u5269\\u9918\\u4efb\\u52d9\\u6578\\uff0c\\u9032\\u5ea6\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-07-23 14:03:06'),
('projectbug-type', '{\"zh-cn\":\"\\u9879\\u76eeBug\\u7c7b\\u578b\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u9805\\u76eeBug\\u985e\\u578b\\u7d71\\u8a08\\u8868\",\"en\":\"Project Bug Type\",\"de\":\"Project Bug Type\",\"fr\":\"Project Bug Type\",\"vi\":\"Project Bug Type\",\"ja\":\"Project Bug Type\"}', ',project,test', 'select t1.id,t3.name as project,t3.id,IF(t3.multiple="1",t1.name,"") as execution,t2.id as bugID,t2.type from TABLE_EXECUTION as t1 \r\nleft join TABLE_BUG as t2 on t1.id=t2.execution\r\nleft join TABLE_PROJECT as t3 on t3.id=t1.project\r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\' and if($project=\'\',1,t3.id=$project) and if($execution=\'\',1,t1.id=$execution)', '{\"varName\":[\"project\",\"execution\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u5217\\u8868\"],\"requestType\":[\"select\",\"select\"],\"selectList\":[\"project\",\"execution\"],\"default\":[\"\",\"\"]}', '{\"stories\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"tasks\":{\"zh-cn\":\"\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u4efb\\u52a1\\u6570\",\"en\":\"Tasks\"},\"undoneStory\":{\"zh-cn\":\"\\u5269\\u4f59\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u5269\\u4f59\\u9700\\u6c42\\u6570\",\"en\":\"Undone Story\"},\"undoneTask\":{\"zh-cn\":\"\\u5269\\u4f59\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u5269\\u4f59\\u4efb\\u52a1\\u6570\",\"en\":\"Undone Task\"},\"consumed\":{\"zh-cn\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"zh-tw\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"en\":\"Cost(h)\"},\"left\":{\"zh-cn\":\"\\u5269\\u4f59\\u5de5\\u65f6\",\"zh-tw\":\"\\u5269\\u4f59\\u5de5\\u65f6\",\"en\":\"Left(h)\"},\"consumedPercent\":{\"zh-cn\":\"\\u8fdb\\u5ea6\",\"zh-tw\":\"\\u8fdb\\u5ea6\",\"en\":\"Process\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"type\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u9879\\u76ee\\u7edf\\u8ba1Bug\\u7684\\u7c7b\\u578b\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u9805\\u76ee\\u7d71\\u8a08Bug\\u7684\\u985e\\u578b\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-08-04 13:54:22');
+395 -2
View File
@@ -1,6 +1,399 @@
2022-11-16 18.0.beta1
完成的需求
开源版:
39874 瀑布项目设置中产品页面提示文案修改
39873 瀑布项目创建页面按产品创建阶段文案修改
39849 发布可以关联多个版本后,调整产品发布中关联软件需求的规则
39848 发布可以关联多个版本后,调整产品发布中关联解决的Bug的规则
39847 发布可以关联多个版本后,调整项目发布中关联软件需求的规则
39846 发布可以关联多个版本后,调整项目发布中关联解决的Bug的规则
39659 后台功能设置中项目均关闭了问题、风险、机会功能后资产库中创建库按钮置灰
39623 项目发布详情页中,版本可以显示已关联的一个或多个版本信息
39622 项目发布列表中,版本列可以显示已关联的一个或多个版本信息
39621 项目编辑发布页面版本可以关联多个
39620 项目创建发布页面版本可以关联多个
39619 产品发布详情页中,版本可以显示已关联的一个或多个版本信息
39618 产品发布列表中,版本列可以显示已关联的一个或多个版本信息
39617 产品编辑发布页面版本可以关联多个
39616 产品创建发布页面版本可以关联多个
39615 项目中创建版本时,相关版本中选择了一个或多个版本后给出关联版本的规则提示
39614 项目版本的详情页中增加相关版本信息
39613 编辑在项目中创建的版本时,可以修改相关版本信息
39612 项目下创建版本时增加关联迭代版本功能
39527 调整测试单列表中报告列表操作名称
39460 从全生命周期管理模式切到轻量管理模式时,使用弹窗来提醒用户选择默认项目集
39450 系统层面和界面层面启用或关闭功能后,视野中可同步更新
39420 安装和升级界面中更新备注中的信息
39419 系统升级界面中增加研发综合界面和运营管理界面的信息
39418 新用户安装界面中增加研发综合界面和运营管理界面的信息
39417 从轻量管理模式切换到全生命周期管理模式时进行二次确认
39415 从全生命周期管理模式切换到轻量管理模式时进行二次确认
39381 调整模式切换界面的引导方式
39379 将自定义中的模式设置功能调整到后台系统三级导航的第一个菜单
39361 父需求自动关闭后调整历史记录的记录方式
39302 币种设置中“台元”调整为”台币“
39168 迅捷界面名称调整为运营管理界面
39167 调整禅道使用模式名称
39093 不启用迭代的项目关联或取消关联计划时,计划关联信息自动同步到隐藏的迭代
39092 不启用迭代的项目关联或取消关联产品时,产品关联信息自动同步到隐藏的迭代
39091 编辑不启用迭代的项目时,项目起止日期自动同步到隐藏迭代的起止日期
39090 创建不启用迭代的项目时,项目起止日期自动同步到隐藏迭代的起止日期
38949 产品看板中增加显示非当前项目集的项目信息的开关功能
38948 项目集看板中增加显示非当前项目集的项目信息的开关功能
38934 单迭代项目型项目的研发需求增加报表功能
38931 单迭代项目型项目的权限去掉计划和会议相关的权限
38928 单迭代项目型项目的版本关联需求和bug时搜索条件去掉所属计划
38927 单迭代项目型项目增加发布功能
38925 单迭代项目型项目的研发需求相关页面去掉计划信息
38924 单迭代项目型项目研发需求看板中去掉关联研发需求的按钮
38922 单迭代项目型项目中研发需求列表增加细分按钮
38921 单迭代项目型项目增加用户需求功能
38920 将地盘待处理中的评审功能与地盘审批功能进行合并
38918 无迭代项目的任务列表中,导出数据的字段中所属执行调整为所属项目
38917 无迭代项目的任务列表中,导出模板的字段中所属执行调整为所属项目
38916 无迭代的项目中隐藏转入任务操作
38915 无迭代项目的任务报表中,隐藏掉按迭代任务数统计报表
38882 迅捷模式中产品去掉需求跟踪矩阵功能
38840 不启用迭代的项目中,日志功能使用隐藏迭代的日志权限
38839 不启用迭代的项目中,软件需求功能使用隐藏迭代的软件需求权限
38838 不启用迭代的项目中,任务日历功能使用隐藏迭代的任务日历权限
38837 不启用迭代的项目中,工时明细表功能使用隐藏迭代的工时明细表权限
38836 不启用迭代的项目中,树状图功能使用隐藏迭代的树状图权限
38835 不启用迭代的项目中,分组视图功能使用隐藏迭代的分组视图权限
38834 不启用迭代的项目中,甘特图功能使用隐藏迭代的甘特图权限
38833 不启用迭代的项目中,燃尽图功能使用隐藏迭代的燃尽图权限
38832 不启用迭代的项目中,看板功能使用隐藏迭代的看板权限
38831 不启用迭代的项目中,任务功能使用隐藏迭代的任务权限
38824 不启用迭代的项目,隐藏的迭代可以与项目的状态进行联动
38701 办公相关审批可以记录由谁发起的评审流程
38700 反馈可以记录由谁发起的评审流程
38699 用例可以记录由谁发起的评审流程
38698 需求可以记录由谁发起的评审流程
38691 执行关联产品列表中可以展示项目关联的所有产品
38689 项目关联产品列表中增加关联其他项目集产品的功能
38578 地盘待处理的区块中增加评审列表
38576 地盘贡献的评审列表中增加反馈的评审类型
38575 地盘贡献的评审列表中增加办公相关的评审类型
38574 地盘贡献的评审列表中增加用例的评审类型
38573 地盘贡献的评审列表中增加需求的评审类型
38572 调整贡献中评审列表的字段
38571 地盘贡献的三级导航中打印评审菜单
38570 地盘待处理的评审列表中增加筛选标签
38569 地盘待处理的评审列表中增加反馈的评审类型
38568 地盘待处理的评审列表中增加办公相关的评审类型
38567 地盘待处理的评审列表中增加用例的评审类型
38566 地盘待处理的评审列表中增加需求的评审类型
38565 调整待处理中评审列表的字段
38564 地盘待处理的三级导航中打印评审菜单
38515 迅捷模式下如果未开启瀑布项目,则隐藏后台审批中项目审批功能
38511 从综合模式切换到迅捷模式时,地盘待处理区块中根据历史数据来判断是否隐藏问题、风险、会议功能
38510 从综合模式切换到迅捷模式时,地盘贡献的三级导航中根据历史数据来判断是否隐藏问题、风险、QA功能
38509 从综合模式切换到迅捷模式时,地盘待处理的三级导航中根据历史数据来判断是否隐藏问题、风险、QA、会议功能
38508 从经典模式升级到18版本迅捷模式时,地盘待处理区块中隐藏问题、风险、会议功能
38507 从经典模式升级到18版本迅捷模式时,地盘贡献的三级导航中隐藏问题、风险、QA功能
38506 从经典模式升级到18版本迅捷模式时,地盘待处理的三级导航中隐藏问题、风险、QA、会议功能
38505 从12版本升级到18版本迅捷模式时,地盘待处理区块中隐藏问题、风险、会议功能
38504 从12版本升级到18版本迅捷模式时,地盘贡献的三级导航中隐藏问题、风险、QA功能
38503 从12版本升级到18版本迅捷模式时,地盘待处理的三级导航中隐藏问题、风险、QA、会议功能
38496 从综合模式切到迅捷模式后关闭敏捷项目的度量功能
38495 12版本升级到禅道18版本迅捷模式后关闭敏捷项目的度量功能
38494 新用户安装禅道18版本迅捷模式后关闭敏捷项目的度量功能
38464 项目内部权限中隐藏执行、会议和执行列表权限
38420 执行创建时,瀑布项目要根据项目的阶段类型关联产品
38419 瀑布项目阶段关联产品不可修改
38352 从综合模式切到迅捷模式时,敏捷项目根据是否存在会议数据来判断是否开启会议功能
38351 从综合模式切到迅捷模式时,敏捷项目根据是否存在QA数据来判断是否开启QA功能
38350 从综合模式切到迅捷模式时,敏捷项目根据是否存在过程数据来判断是否开启过程功能
38349 从综合模式切到迅捷模式时,敏捷项目根据是否存在机会数据来判断是否开启机会功能
38347 从综合模式切到迅捷模式时,敏捷项目根据是否存在风险数据来判断是否开启风险功能
38345 从综合模式切到迅捷模式时,敏捷项目根据是否存在问题数据来判断是否开启问题功能
38324 项目管理员权限分组中项目型项目的权限特殊处理
38281 实现从15版本经典模式直接升级到18本版迅捷模式
38234 综合模式下如果没有项目集数据,切换迅捷模式时可以不用选择默认项目集
38231 执行创建阶段类型为需求、设计、总结评审的瀑布项目阶段时,隐藏关联计划
38230 复制项目的阶段信息确认页面文案修改
38229 单套阶段的项目的费用估算的阶段隐藏产品
38228 单套阶段的项目的里程牌报告隐藏2.5级产品菜单
38223 瀑布项目的设计增加所有产品选项
38222 瀑布项目阶段菜单样式优化
38221 单阶段的瀑布项目的阶段隐藏产品
38220 瀑布项目创建增加阶段类型选项
38156 组织统计报表中,任务指派给统计表中执行名称列显示项目名称
38155 组织统计报表中,任务完成统计表中执行名称列显示项目名称
38154 组织统计报表中,员工负载表中执行名称列不显示隐藏的执行
38153 测试统计报表中,项目Bug类型统计表中执行名称列不显示隐藏的执行
38152 测试统计报表中,项目Bug指派给分布表中执行名称列不显示隐藏的执行
38151 测试统计报表中,项目Bug解决者分布表中执行名称列不显示隐藏的执行
38150 测试统计报表中,项目Bug创建者分布表中执行名称列不显示隐藏的执行
38149 测试统计报表中,项目Bug状态分布表中执行名称列不显示隐藏的执行
38148 测试统计报表中,项目Bug解决者分布表中执行名称列不显示隐藏的执行
38147 项目统计报表中,相关执行下拉菜单中不显示隐藏的执行
38146 项目统计报表中,项目Bug类型统计表中执行名称列不显示隐藏的执行
38145 项目统计报表中,项目进展表中执行名称列不显示隐藏的执行
38144 项目统计报表中,项目质量表中执行名称列不显示隐藏的执行
38143 项目统计报表中,项目Bug指派给分布表中执行名称列不显示隐藏的执行
38142 项目统计报表中,项目Bug解决者分布表中执行名称列不显示隐藏的执行
38141 项目统计报表中,项目Bug创建者分布表中执行名称列不显示隐藏的执行
38140 项目统计报表中,项目Bug状态分布表中执行名称列不显示隐藏的执行
38139 项目统计报表中,项目Bug解决分布表中执行名称列不显示隐藏的执行
38138 项目统计报表中,项目需求阶段分布表中执行名称列不显示隐藏的执行
38137 项目统计报表中,项目需求状态分布表中执行名称列不显示隐藏的执行
38136 项目统计报表中,项目投入统计报表中执行名称列不显示隐藏的执行
38135 项目统计报表中,任务完成者报表中执行名称列不显示隐藏的执行
38134 项目统计报表中,任务指派统计报表中执行名称列不显示隐藏的执行
38133 项目统计报表中,任务类型统计报表中执行名称列不显示隐藏的执行
38132 项目统计报表中,任务状态统计报表中执行名称列不显示隐藏的执行
38131 项目统计报表中,交付吞吐率报表中不显示隐藏的执行
38130 项目统计报表中,执行速率报表中不显示隐藏的执行
38129 项目统计报表中,执行偏差报表中不显示隐藏的执行
38128 组织的动态列表中,执行的下拉菜单中不显示隐藏的执行
38127 组织的动态中,不显示隐藏执行的相关动态
38126 项目的动态中,不显示隐藏执行的相关动态
38125 地盘贡献的任务列表中,所属执行列不显示隐藏的执行
38124 地盘执行列表中,不显示隐藏的执行
38123 地盘待处理的质量保证计划列表中,所属执行列显示项目名称
38122 地盘待处理的测试单列表中,所属执行列显示项目名称
38121 地盘待处理的任务列表中,所属执行列不显示隐藏的执行
38120 地盘会议列表中,执行列不显示隐藏的执行
38119 地盘日志列表中,执行列显示项目名称
38118 地盘动态列表中,不显示隐藏执行的相关动态
38117 地盘仪表盘的最新动态中,不显示隐藏执行的相关动态
38116 地盘仪表盘的近期项目区块中,不启用迭代的项目不显示近期执行信息
38115 地盘仪表盘的执行总览区块中,不显示隐藏的执行
38114 地盘仪表盘的项目统计区块中,不启用迭代的项目不显示近期执行信息
38113 地盘仪表盘的产品列表区块中,当前执行列显示项目名称
38112 会议详情页面,不显示所属执行字段
38111 编辑会议页面,不显示所属执行字段
38110 创建会议页面,不显示所属执行字段
38109 风险详情页面,不显示所属执行字段
38108 编辑风险页面,不显示所属执行字段
38107 创建风险页面,不显示所属执行字段
38106 问题详情页面,不显示所属执行字段
38105 编辑问题页面,不显示所属执行字段
38104 创建问题页面,不显示所属执行字段
38103 版本列表中,不显示所属执行列
38102 版本详情页面,不显示所属执行字段
38101 编辑版本页面,不显示所属执行字段
38100 创建版本页面,不显示所属执行字段
38099 测试单概况页面,不显示所属执行字段
38098 编辑测试单页面,不显示所属执行字段
38097 提交测试单页面,不显示所属执行字段
38096 测试报告列表中,所属执行列不显示隐藏的执行
38095 测试的Bug列表中,所属执行列不显示隐藏的执行
38094 Bug详情页面,不显示所属执行字段
38093 编辑Bug页面,不显示所属执行字段
38092 批量提Bug页面,不显示所属执行字段
38091 提Bug页面,不显示所属执行字段
38090 任务详情页面,不显示所属执行字段
38089 批量编辑任务页面,不显示所属执行信息
38088 编辑任务页面,不显示所属执行字段
38087 创建任务页面,不显示所属执行字段
38086 执行的1.5级导航的下拉菜单中隐藏不启用执行项目的这个隐藏的执行
37875 不启用迭代功能的项目中,在日志中执行相关操作时导航高亮在当前项目菜单
37874 不启用迭代功能的项目中,在需求列表中执行相关操作时导航高亮在当前项目菜单
37873 不启用迭代功能的项目中,在任务日历中执行相关操作时导航高亮在当前项目菜单
37872 不启用迭代功能的项目中,在工时明细表中执行相关操作时导航高亮在当前项目菜单
37871 不启用迭代功能的项目中,在树状图中执行相关操作时导航高亮在当前项目菜单
37870 项目取消与产品的关联后,同步取消该项目下执行与产品的关联关系
37838 不启用迭代功能的项目中,执行分组视图的相关操作时导航高亮在当前项目菜单
37830 不启用迭代功能的项目中,执行燃尽图的相关操作时导航高亮在当前项目菜单
37829 不启用迭代功能的项目中,执行看板的相关操作时导航高亮在当前项目菜单
37827 不启用迭代功能的项目中,执行任务的相关操作时导航高亮在当前项目菜单
37804 看板项目中,实现不启用迭代功能项目中的设置功能
37803 看板项目中,实现不启用迭代功能项目中的版本功能
37802 看板项目中,实现不启用迭代功能项目中的看板功能
37801 实现看板项目不启用迭代功能的二级导航菜单
37800 敏捷项目中,实现不启用迭代功能项目中的设置功能
37799 敏捷项目中,实现不启用迭代功能项目中的版本功能
37798 敏捷项目中,实现不启用迭代功能项目中的文档功能
37797 敏捷项目中,实现不启用迭代功能项目中的代码功能
37796 敏捷项目中,实现不启用迭代功能项目中的测试功能
37795 敏捷项目中,实现不启用迭代功能项目中的日志功能
37794 敏捷项目中,实现不启用迭代功能项目中的软件需求功能
37793 敏捷项目中,实现不启用迭代功能项目中的任务日历功能
37792 敏捷项目中,实现不启用迭代功能项目中的工时明细功能
37791 敏捷项目中,实现不启用迭代功能项目中的分组视图功能
37790 敏捷项目中,实现不启用迭代功能项目中的甘特图功能
37789 敏捷项目中,实现不启用迭代功能项目中的燃尽图功能
37788 敏捷项目中,实现不启用迭代功能项目中的看板功能
37787 敏捷项目中,实现不启用迭代功能项目中的任务功能
37786 实现敏捷项目不启用迭代功能的二级导航菜单
37779 12版本升级到禅道18版本迅捷模式后关闭敏捷项目的会议功能
37778 12版本升级到禅道18版本迅捷模式后关闭敏捷项目的QA功能
37777 12版本升级到禅道18版本迅捷模式后关闭敏捷项目的过程功能
37776 12版本升级到禅道18版本迅捷模式后关闭敏捷项目的机会功能
37775 12版本升级到禅道18版本迅捷模式后关闭敏捷项目的风险功能
37774 12版本升级到禅道18版本迅捷模式后关闭敏捷项目的问题功能
37773 经典模式升级到禅道18版本迅捷模式后关闭敏捷项目的会议功能
37772 经典模式升级到禅道18版本迅捷模式后关闭敏捷项目的QA功能
37771 经典模式升级到禅道18版本迅捷模式后关闭敏捷项目的过程功能
37770 经典模式升级到禅道18版本迅捷模式后关闭敏捷项目的机会功能
37769 经典模式升级到禅道18版本迅捷模式后关闭敏捷项目的风险功能
37768 经典模式升级到禅道18版本迅捷模式后关闭敏捷项目的问题功能
37767 新用户安装禅道18版本迅捷模式后关闭敏捷项目的会议功能
37766 新用户安装禅道18版本迅捷模式后关闭敏捷项目的QA功能
37765 新用户安装禅道18版本迅捷模式后关闭敏捷项目的过程功能
37764 新用户安装禅道18版本迅捷模式后关闭敏捷项目的机会功能
37763 新用户安装禅道18版本迅捷模式后关闭敏捷项目的风险功能
37762 新用户安装禅道18版本迅捷模式后关闭敏捷项目的问题功能
37758 经典模式版本升级到18版本迅捷模式后,根据是否存在用户需求数据来判断是否开启用户需求功能
37757 经典模式版本升级到18版本迅捷模式后关闭资产库功能
37756 经典模式版本升级到18版本迅捷模式后关闭瀑布项目功能
37755 12版升级到18版本迅捷模式后,根据是否存在用户需求数据来判断是否开启用户需求功能
37754 12版升级到18版本迅捷模式后关闭资产库功能
37753 新用户安装禅道18版本迅捷模式后关闭用户需求功能
37752 从综合模式切到迅捷模式时,根据是否存在用户需求数据来判断是否开启用户需求功能
37751 从综合模式切到迅捷模式时,根据是否存在资产库数据来判断是否开启资产库功能
37750 新用户安装禅道18版本迅捷模式后关闭资产库功能
37746 在后台系统功能列表中实现对系统功能的自定义
37745 在后台系统设置中增加系统功能设置菜单
37743 从全新项目集模式的版本升级到18版本,无需选择模式直接升级到综合模式
37736 创建敏捷项目时可以设置是否启用迭代功能
37735 编辑敏捷项目时,是否启用迭代字段不可调整
37734 编辑看板项目时,是否启用迭代字段不可调整
37733 编辑产品页面所属项目集为空时,不显示产品线字段
37732 执行产品列表可以取消已关联的产品
37731 编辑执行时可以取消已关联的产品
37730 项目的产品列表中可以取消已关联的产品
37729 后台自定义的流程中,去掉组合方式之间的减号
37675 项目型项目复制模块可以复制产品和项目型项目的模块
37674 项目概况中展示产品型项目和项目型项目的标签
37673 项目型项目研发需求隐藏移除按钮
37660 创建产品页面所属项目集为空时,不显示产品线字段
37658 产品调整所属项目集时,可以任意选择一个项目集
37657 项目调整所属项目集时,可以任意选择一个项目集
37656 编辑项目时可以取消已关联的产品
37654 编辑项目的时候,可以跨项目集关联产品
37653 创建项目的时候,可以跨项目集关联产品
37613 12版升级到18版本迅捷模式后关闭瀑布项目功能
37612 新用户安装禅道18版本迅捷模式后关闭瀑布项目功能
37603 从综合模式切到迅捷模式时,根据是否存在瀑布项目数据来判断是否开启瀑布项目功能
37596 从综合模式切到迅捷模式时,访问权限是项目集内公开的项目统一调整为私有
37572 项目型项目项目复制
37553 项目型项目的权限通过项目维护
37552 项目型项目的视野权限在产品中进行过滤,通过项目维护
37551 项目型项目恢复时同步恢复影子产品
37549 测试模块测试单功能展示产品和项目型项目的信息
37546 测试模块用例功能统计产品和项目型项目的信息
37544 测试模块bug功能统计产品和项目型项目的信息
37542 实现从12版本升级到18版本综合模式的手工归并数据功能
37541 项目型项目在测试区块仪表盘的所属产品展示为项目型项目名
37540 地盘动态不展示影子产品的动态
37539 项目型项目在地盘贡献的产品名称下展示为项目型项目名
37538 项目型项目在地盘待处理的产品名称下展示为项目型项目名
37537 项目型项目在地盘日志的所属产品展示为项目型项目名
37534 项目型项目在地盘区块的产品名称下展示为项目型项目名
37533 反馈不支持项目型项目
37532 组织中项目型项目的所属产品展示为项目名
37531 统计产品和测试菜单下的列表,项目型项目进行特殊处理
37530 资产库导入需求不展示无产品的产品名称
37529 通用看板导入发布与导入计划的产品中增加项目型项目的层级,展示项目型项目名
37528 从12版本升级到18版本的综合模式时,增加自动或手工归并数据的功能
37527 从12版本升级到18版本的迅捷模式时,增加自动或手工归并数据的功能
37525 从综合模式切换为迅捷模式时可以选择一个项目集作为默认项目集
37517 创建看板项目时可以设置是否启用迭代功能
37504 迅捷模式下默认创建一个隐藏的项目集,关联所有产品和项目数据
37462 项目型项目仪表盘隐藏所属产品字段
37461 项目型项目执行的任务导入bug隐藏搜索的所属产品字段
37460 项目型项目执行的日志导出数据隐藏所属产品
37458 项目型项目中测试单功能隐藏产品信息
37457 项目型项目中用例功能隐藏产品信息
37456 项目型项目中bug功能隐藏产品信息
37455 项目型项目中研发需求和用户需求列表导出和导入功能隐藏产品信息
37454 项目型项目中研发需求和用户需求列表增加维护模块按钮
37453 项目型项目中研发需求和用户需求列表隐藏所属产品信息
37452 项目型项目执行的看板新建隐藏产品与计划
37451 看板项目的设置隐藏产品与计划字段
37450 项目型项目中研发需求隐藏所属产品信息
37449 项目型项目中增加用户需求模块
37448 项目型项目中二级菜单研发需求改为需求,包含研发需求和用户需求
37447 瀑布项目的报告隐藏产品
37445 瀑布项目的估算的阶段隐藏产品
37444 瀑布项目的评审隐藏产品
37443 瀑布项目的矩阵隐藏产品
37442 瀑布项目的阶段隐藏产品
37441 看板执行的看板编辑隐藏产品与计划
37438 敏捷、瀑布项目的设置隐藏产品与计划字段
37437 敏捷、瀑布、看板项目的版本隐藏产品字段
37424 项目模块中执行的相关页面隐藏“所属产品”字段
37422 项目列表页导出列表中增加“项目类型”,项目型项目的所属产品为“”
37421 项目列表搜索项增加“项目类型”
37420 创建项目选择“项目类型”,可以创建产品型项目或项目型项目
37346 项目列表页增加字段“项目类型”
37336 迅捷模式中隐藏产品线的相关功能
37333 项目型项目的需求列表中增加批量创建功能
37332 项目型项目的需求列表中取消关联研发需求功能
37331 敏捷项目型项目中增加计划功能
37328 项目型项目中发布隐藏产品信息
37308 实现从15版本经典模式升级到18本版迅捷模式
37292 实现从12版本升级到18版本迅捷模式的手工归并数据功能
37291 12版本升级到18版本时,提供综合模式和迅捷模式的介绍和选择
37290 新用户安装禅道时提供综合模式和迅捷模式的介绍和选择
37289 迅捷模式切换到综合模式后开启项目集功能
37284 从综合模式切换到迅捷模式后隐藏项目集相关功能和数据
37275 从迅捷模式切换到综合模式增加功能影响的提示信息
37272 从综合模式切换到迅捷模式时增加功能影响的提示信息
37270 迅捷模式和综合模式的切换不做次数限制
37268 调整后台自定义模式中的名称
38176 项目型项目下可以设置与代码库的关联关系
37635 在项目型项目下可以创建代码库
37465 在项目型项目下可以提交评审问题
37464 代码库可以关联项目
企业版:
39500 反馈1.5级导航样式优化
39123 工单增加导出数据功能
38160 反馈的权限改名为设置
37570 权限增加产品设置功能
36930 反馈权限列表产品展示同产品列表
禅道客户端:
36616 实现版本升级后原存档讨论组逻辑处理
36543 实现群主取消归档讨论组相关提醒及操作
36540 实现对已归档的讨论组限制移动分组
36542 限制对已归档讨论组相关操作
32237 实现归档后的讨论组交互显示
36541 实现对已归档讨论组消息的处理
36832 实现讨论组归档提醒的功能
36831 实现讨论组归档入口
37463 实现群管理应用对已归档讨论组的相关操作
37670 实现讨论组会话中@成员时的快捷键操作
37669 实现优化讨论组会话中@多个成员的功能
37668 实现优化讨论组会话中@单个成员的功能
37667 实现讨论组会话中@所有人功能
37663 实现讨论组中会话中@成员能够以列表形式展现
37631 禅道客户端“反馈”的相关通知增加到喧喧小助手
38190 禅道相关通知增加到小喧喧交互设计
37661 提升禅道相关通知推送到喧喧小助手的速度
37634 喧喧不在前台时使用其快捷键截屏不自动调出界面
37642 修改会议初检设置项文案
修复的Bug
29763 执行关联产品页面未关联的产品应该显示项目集
29702 批量编辑产品,自定义表单项显示产品线
29650 新建项目时,关联产品下拉列表显示了非所选项目集下的产品
29628 Bug默认指派人没指派给产品测试负责人
29549 项目型项目和无产品迭代文档下搜索条件“所属产品”未隐藏掉
29535 执行中转入任务后F12有报错信息
29508 地盘--待处理中Bug列表错乱
29499 项目概况页面所属项目集代码报错
29452 项目型项目下批量编辑和批量指派给下拉数据与单个指派下拉数据范围不一致
27994 禅道系统使用时切换页面会突然登录超时退出
28255 无产品权限人员编辑代码库显示项目不正确
27516 可合并讨论组的列表中列出了已经被合并的群
27458 新加入群聊后未读消息会显示新加入群所有消息的条数
26453 引用小喧喧的推送不显示小喧喧的头像和名称
28077 快捷键截图后打开xxc偶发xxc窗口一直置于桌面最上方
27983 用户名大小写不对,提示有问题
27629 预览txt文件乱码
28095 LDAP密码有特殊字符无法登录
30119 设计Bug解决表页面代码报错
30057 输入方式的选中样式与文字不在同一水平线
29661 透视表字段显示为英文
29617 保存透视表时必填项未增加必填标识
29367 点击分组维护主机、虚拟机二级导航高亮展示
28580 统计-测试报表中有两个报表没有翻译德语和法语语言项
2022-11-02 17.8
完成的需求
开源版
开源版:
39354 项目集列表中恢复项目名称前的模型标识
39165 玉烟紫主题下,地盘仪表盘待处理区块中标题颜色调整
39164 bug严重程度的样式调整
@@ -4404,7 +4797,7 @@
1734 权限--按模块分配权限,提示文案里,control 能否改为 Ctrl。shift 改为 Shift。
1733 用户列表页,点击用户真实姓名,跳转的页面,测试--负责的版本。表头字段没显示完整,没加title。样式也要调整一下,排序按钮太靠边框。
1731 动态--搜索,对象类型里的 build 能否改为中文。
1729 权限--视图维护,产品和项目不显示填写框。(无产品项目)
1729 权限--视图维护,产品和项目不显示填写框。(项目型项目)
1727 部门折叠展开按钮的显示位置要调整。
1724 统计,测试,Bug创建表,选择产品和项目时,刷新选择框,显示的样式不对。
1722 项目起止时间选择框,宽度不一致。前面窄后面的宽。
@@ -1,6 +1,7 @@
<?php
$lang->action->label->execution = "Kanban|execution|task|executionID=%s";
$lang->action->label->task = 'Task|task|view|taskID=%s';
$lang->action->label->module = 'Katalog|tree|browse|productid=%s&type=story&currentModuleID=0&branch=all';
/* Object type. */
$lang->action->objectTypes['execution'] = 'Project' . $lang->executionCommon;
@@ -1,6 +1,7 @@
<?php
$lang->action->label->execution = "Kanban|execution|task|executionID=%s";
$lang->action->label->task = 'Task|task|view|taskID=%s';
$lang->action->label->module = 'Catalog|tree|browse|productid=%s&type=story&currentModuleID=0&branch=all';
/* Object type. */
$lang->action->objectTypes['execution'] = 'Project' . $lang->executionCommon;
@@ -1,6 +1,7 @@
<?php
$lang->action->label->execution = "Kanban|execution|task|executionID=%s";
$lang->action->label->task = 'Task|task|view|taskID=%s';
$lang->action->label->module = 'Table des matières|tree|browse|productid=%s&type=story&currentModuleID=0&branch=all';
/* Object type. */
$lang->action->objectTypes['execution'] = 'Project' . $lang->executionCommon;
@@ -1,6 +1,7 @@
<?php
$lang->action->label->execution = "看板|execution|task|executionID=%s";
$lang->action->label->task = '任务|task|view|taskID=%s';
$lang->action->label->module = '目录|tree|browse|productid=%s&type=story&currentModuleID=0&branch=all';
/* Object type. */
$lang->action->objectTypes['execution'] = '项目' . $lang->executionCommon;
@@ -4,7 +4,8 @@ class myExecution extends execution
{
public function create($projectID = '', $executionID = 0, $copyExecutionID = '', $planID = 0, $confirm = 'no', $productID = 0, $extra = '')
{
$this->config->execution->create->requiredFields = 'name,code,begin,end';
$this->config->execution->create->requiredFields = 'name,code,begin,end';
$this->loadModel('project')->setMenu($projectID);
parent::create($projectID, $executionID, $copyExecutionID, $planID, $confirm, $productID, $extra);
}
}
}
@@ -106,6 +106,7 @@
<?php echo html::hidden("RD", '');?>
<?php echo html::hidden("type", 'kanban');?>
<?php echo html::hidden("vision", 'lite');?>
<?php echo html::hidden('project', $projectID);?>
</td>
</tr>
</table>
@@ -1,7 +1,7 @@
<script>
<?php if(trim($config->visions, ',') == 'lite'): ?>
$('#headerActions').css("right", '110px');
$('#headerActions').css("right", '140px');
<?php else: ?>
$('#headerActions').css("right", '205px');
$('#headerActions').css("right", '235px');
<?php endif; ?>
</script>
@@ -90,6 +90,7 @@ class product extends control
$product = $this->product->getById($productID);
/* Get stories. */
if(in_array($browseType, array('reviewing', 'draft', 'changing'))) $browseType .= 'story';
$stories = $this->product->getStories($productID, $branchID, $browseType, $queryID, $moduleID, $storyType, $sort, $pager);
/* Display status of branch. */
+16 -12
View File
@@ -20,22 +20,26 @@ body {margin-bottom: 25px;}
.assignedTo{border-radius: 4px !important;}
#productStoryForm table tbody tr td.c-actions .dividing-line {width: 1px; height: 16px; display: inline-block; vertical-align: middle; background: #F4F5F7; margin: 0 4px 0 0;}
</style>
<?php js::set('browseType', $browseType);?>
<?php js::set('productID', $productID);?>
<?php js::set('projectID', $projectID);?>
<?php js::set('branch', $branch);?>
<?php js::set('rawModule', $this->app->rawModule);?>
<?php js::set('productType', $this->app->tab == 'product' ? $product->type : '');?>
<?php
$unfoldStories = isset($config->product->browse->unfoldStories) ? json_decode($config->product->browse->unfoldStories, true) : array();
$unfoldStories = zget($unfoldStories, $productID, array());
$lang->story->createCommon = $storyType == 'story' ? $lang->story->createStory : $lang->story->createRequirement;
$unfoldStories = isset($config->product->browse->unfoldStories) ? json_decode($config->product->browse->unfoldStories, true) : array();
$unfoldStories = zget($unfoldStories, $productID, array());
$isProjectStory = $this->app->rawModule == 'projectstory';
$projectHasProduct = $isProjectStory && !empty($project->hasProduct);
$projectIDParam = $isProjectStory ? "projectID=$projectID&" : '';
js::set('unfoldStories', $unfoldStories);
js::set('unfoldAll', $lang->execution->treeLevel['all']);
js::set('foldAll', $lang->execution->treeLevel['root']);
js::set('storyType', $storyType);
$lang->story->createCommon = $storyType == 'story' ? $lang->story->createStory : $lang->story->createRequirement;
$isProjectStory = $this->app->rawModule == 'projectstory';
$projectIDParam = $isProjectStory ? "projectID=$projectID&" : '';
js::set('browseType', $browseType);
js::set('productID', $productID);
js::set('projectID', $projectID);
js::set('branch', $branch);
js::set('rawModule', $this->app->rawModule);
js::set('productType', $this->app->tab == 'product' ? $product->type : '');
js::set('projectHasProduct', $projectHasProduct);
js::set('URAndSR', $this->config->URAndSR);
js::set('vision', $this->config->vision);
?>
<style>
.btn-group .icon-close:before {font-size: 5px; vertical-align: 25%;}
@@ -200,7 +204,7 @@ $projectIDParam = $isProjectStory ? "projectID=$projectID&" : '';
<p>
<span class="text-muted"><?php echo $storyType == 'story' ? $lang->story->noStory : $lang->story->noRequirement;?></span>
<?php if(common::canModify('product', $product) and common::hasPriv('story', 'create')):?>
<?php echo html::a($this->createLink('story', 'create', "productID={$productID}&branch={$branch}&moduleID={$moduleID}&storyID=0&projectID=$projectID&bugID=0&planID=0&todoID=0&extra=&type=$storyType"), "<i class='icon icon-plus'></i> " . $lang->story->createCommon, '', "class='btn btn-info' data-app='$from'");?>
<?php echo html::a($this->createLink('story', 'create', "productID={$productID}&branch={$branch}&moduleID={$moduleID}&storyID=0&projectID=$projectID&bugID=0&planID=0&todoID=0&extra=&type=$storyType"), "<i class='icon icon-plus'></i> " . $lang->story->create, '', "class='btn btn-info' data-app='$from'");?>
<?php endif;?>
</p>
</div>
+3 -1
View File
@@ -1,2 +1,4 @@
<?php
$config->project->list->exportFields = 'id,code,name,status,budget,PM,desc';
$config->project->list->exportFields = 'id,code,name,status,PM,desc';
$config->project->datatable->defaultField = array('id', 'name', 'status', 'PM', 'begin', 'end', 'progress', 'actions');
unset($config->project->datatable->fieldList['budget']);
+44
View File
@@ -50,6 +50,50 @@ class helper extends baseHelper
return isset($viewType) ? $viewType : $config->default->view;
}
/**
* Verify that the system has opened on the feature.
*
* @param string $feature scrum_risk | risk | scrum
* @static
* @access public
* @return bool
*/
public static function hasFeature($feature)
{
global $config;
if(strpos($feature, '_') !== false)
{
$code = explode('_', $feature);
$code = $code[0] . ucfirst($code[1]);
return strpos(",$config->disabledFeatures,", ",{$code},") === false;
}
else
{
if($feature == 'product' or $feature == 'scrum' or $feature == 'waterfall') return strpos(",$config->disabledFeatures,", ",{$feature},") === false;
$hasFeature = false;
foreach($config->featureGroup as $group => $modules)
{
if($feature == $group)
{
foreach($modules as $module)
{
if(helper::hasFeature("{$group}_{$module}")) $hasFeature = true;
}
}
else
{
foreach($modules as $module)
{
if($feature == $module and helper::hasFeature("{$group}_{$module}")) $hasFeature = true;
}
}
}
return $hasFeature && strpos(",$config->disabledFeatures,", ",{$feature},") === false;
}
}
/**
* Encode json for $.parseJSON
*
+45 -39
View File
@@ -251,6 +251,15 @@ class baseControl
* Set super vars.
*/
$this->setSuperVars();
/**
* 读取当前模块的zen类。
* Load the zen file auto.
*/
$zenClass = $this->moduleName . 'Zen';
$selfClass = get_class($this);
$parentClasses = class_parents($this);
if($selfClass != $zenClass && !isset($parentClasses[$zenClass])) $this->loadZen($this->moduleName, $appName);
}
//-------------------- Model相关方法(Model related methods) --------------------//
@@ -282,34 +291,25 @@ class baseControl
}
/**
* 加载指定模块的model文件。
* Load the model file of one module.
* 加载一个模块的model对象。加载完成后,使用$this->$moduleName来访问这个model对象。
* 比如:loadModel('user')引入user模块的model实例对象,可以通过$this->user来访问它。
*
* Load the model object of one module. After loaded, can use $this->$moduleName to visit the model object.
*
* @param string $moduleName 模块名,如果为空,使用当前模块。The module name, if empty, use current module's name.
* @param string $appName The app name, if empty, use current app's name.
* @access public
* @return object|bool 如果没有model文件,返回false,否则返回model对象。If no model file, return false, else return the model object.
* @param string $appName 应用名,如果为空,使用当前应用。The app name, if empty, use current app's name.
* @access public
* @return object|bool 如果没有model文件,返回false,否则返回model对象。If no model file, return false, else return the model object.
*/
public function loadModel($moduleName = '', $appName = '')
{
if(empty($moduleName)) $moduleName = $this->moduleName;
if(empty($appName)) $appName = $this->appName;
global $loadedModels;
if(isset($loadedModels[$appName][$moduleName]))
{
$this->$moduleName = $loadedModels[$appName][$moduleName];
$this->dao = $this->$moduleName->dao;
return $this->$moduleName;
}
$modelFile = $this->app->setModelFile($moduleName, $appName);
$model = $this->app->loadTarget($moduleName, $appName);
/**
* 如果没有model文件,尝试加载config配置信息。
* If no model file, try load config.
* 如果加载model失败,尝试加载config, lang配置信息。
* If model is not loaded, try load config and lang.
*/
if(!helper::import($modelFile))
if(!$model)
{
$this->app->loadModuleConfig($moduleName, $appName);
$this->app->loadLang($moduleName, $appName);
@@ -317,25 +317,32 @@ class baseControl
return false;
}
/**
* 如果没有扩展文件,model类名是$moduleName + 'model',如果有扩展,还需要增加ext前缀。
* If no extension file, model class name is $moduleName + 'model', else with 'ext' as the prefix.
*/
$modelClass = class_exists('ext' . $appName . $moduleName . 'model') ? 'ext' . $appName . $moduleName . 'model' : $appName . $moduleName . 'model';
if(!class_exists($modelClass))
{
$modelClass = class_exists('ext' . $moduleName . 'model') ? 'ext' . $moduleName . 'model' : $moduleName . 'model';
if(!class_exists($modelClass)) $this->app->triggerError(" The model $modelClass not found", __FILE__, __LINE__, $exit = true);
}
$this->{$moduleName} = $model;
$this->dao = $model->dao;
return $model;
}
/**
* 初始化model对象,在control对象中可以通过$this->$moduleName来引用。同时将dao对象赋为control对象的成员变量,方便引用。
* Init the model object thus you can try $this->$moduleName to access it. Also assign the $dao object as a member of control object.
*/
$loadedModels[$appName][$moduleName] = new $modelClass($appName);
$this->$moduleName = $loadedModels[$appName][$moduleName];
$this->dao = $this->$moduleName->dao;
return $this->$moduleName;
/**
* 加载一个模块的zen对象。加载完成后,使用$this->{$moduleName}Zen来访问这个zen对象。
* 比如:loadZen('user')引入user模块的zen实例对象,可以通过$this->userZen来访问它。
*
* Load the zen object of one module. After loaded, can use $this->{$moduleName}Zen to visit the zen object.
*
* @param string $moduleName 模块名,如果为空,使用当前模块。The module name, if empty, use current module's name.
* @param string $appName 应用名,如果为空,使用当前应用。The app name, if empty, use current app's name.
* @access public
* @return object|bool 如果没有zen文件,返回false,否则返回zen对象。If no zen file, return false, else return the zen object.
*/
public function loadZen($moduleName = '', $appName = '')
{
$zen = $this->app->loadTarget($moduleName, $appName, 'zen');
if(!$zen) return false;
$zen->view = $this->view;
$zenObjectName = $moduleName . 'Zen';
$this->{$zenObjectName} = $zen;
return $zen;
}
/**
@@ -770,7 +777,6 @@ class baseControl
$currentModuleName = $this->moduleName;
$currentMethodName = $this->methodName;
$currentAppName = $this->appName;
$currentParams = $this->app->getParams();
/**
+13
View File
@@ -740,6 +740,19 @@ class baseHelper
session_write_close();
session_id($sessionID);
if(ini_get('session.save_handler') == 'user' and isset($_GET['tid']))
{
$ztSessionHandler = new ztSessionHandler($_GET['tid']);
session_set_save_handler(
array($ztSessionHandler, "open"),
array($ztSessionHandler, "close"),
array($ztSessionHandler, "read"),
array($ztSessionHandler, "write"),
array($ztSessionHandler, "destroy"),
array($ztSessionHandler, "gc")
);
register_shutdown_function('session_write_close');
}
session_start();
}
+52 -35
View File
@@ -150,6 +150,15 @@ class baseModel
$this->loadDAO();
$this->setSuperVars();
/**
* 读取当前模块的tao类。
* Load the tao file auto.
*/
$taoClass = $moduleName . 'Tao';
$selfClass = get_class($this);
$parentClasses = class_parents($this);
if($selfClass != $taoClass && !isset($parentClasses[$taoClass])) $this->loadTao($moduleName, $this->appName);
}
/**
@@ -170,11 +179,11 @@ class baseModel
*/
public function getModuleName()
{
$parentClass = get_parent_class($this);
$selfClass = get_class($this);
$className = $parentClass == 'model' ? $selfClass : $parentClass;
if($className == 'extensionModel') return 'extension';
return strtolower(str_ireplace(array('ext', 'Model'), '', $className));
$className = get_class($this);
$parentClasses = class_parents($this);
if(count($parentClasses) > 2) $className = current(array_slice($parentClasses, -3, 1));
if(strtolower(substr($className, -5)) == 'model') $className = strtolower(substr($className, 0, strlen($className) - 5));
return $className;
}
/**
@@ -194,41 +203,44 @@ class baseModel
}
/**
* 加载一个模块的model。加载完成后,使用$this->$moduleName来访问这个model对象。
* 加载一个模块的model对象。加载完成后,使用$this->$moduleName来访问这个model对象。
* 比如:loadModel('user')引入user模块的model实例对象,可以通过$this->user来访问它。
*
* Load the model of one module. After loaded, can use $this->$moduleName to visit the model object.
* Load the model object of one module. After loaded, can use $this->$moduleName to visit the model object.
*
* @param string $moduleName
* @access public
* @return object|bool the model object or false if model file not exists.
* @param string $moduleName 模块名,如果为空,使用当前模块。The module name, if empty, use current module's name.
* @param string $appName 应用名,如果为空,使用当前应用。The app name, if empty, use current app's name.
* @access public
* @return object|bool 如果没有model文件,返回false,否则返回model对象。If no model file, return false, else return the model object.
*/
public function loadModel($moduleName, $appName = '')
{
if(empty($moduleName)) return false;
if(empty($appName)) $appName = $this->appName;
$moduleName = strtolower($moduleName);
$model = $this->app->loadTarget($moduleName, $appName);
if(!$model) return false;
global $loadedModels;
if(isset($loadedModels[$appName][$moduleName]))
{
$this->$moduleName = $loadedModels[$appName][$moduleName];
return $this->$moduleName;
}
$this->{$moduleName} = $model;
return $model;
}
$modelFile = $this->app->setModelFile($moduleName, $appName);
/**
* 加载一个模块的tao对象。加载完成后,使用$this->{$moduleName}Tao来访问这个tao对象。
* 比如:loadTao('user')引入user模块的tao实例对象,可以通过$this->userTao来访问它。
*
* Load the tao object of one module. After loaded, can use $this->{$moduleName}Tao to visit the tao object.
*
* @param string $moduleName 模块名,如果为空,使用当前模块。The module name, if empty, use current module's name.
* @param string $appName 应用名,如果为空,使用当前应用。The app name, if empty, use current app's name.
* @access public
* @return object|bool 如果没有tao文件,返回false,否则返回tao对象。If no tao file, return false, else return the tao object.
*/
public function loadTao($moduleName, $appName = '')
{
$tao = $this->app->loadTarget($moduleName, $appName, 'tao');
if(!$tao) return false;
if(!helper::import($modelFile)) return false;
$modelClass = class_exists('ext' . $appName . $moduleName. 'model') ? 'ext' . $appName . $moduleName . 'model' : $appName . $moduleName . 'model';
if(!class_exists($modelClass))
{
$modelClass = class_exists('ext' . $moduleName. 'model') ? 'ext' . $moduleName . 'model' : $moduleName . 'model';
if(!class_exists($modelClass)) $this->app->triggerError(" The model $modelClass not found", __FILE__, __LINE__, $exit = true);
}
$loadedModels[$appName][$moduleName] = new $modelClass($appName);
$this->$moduleName = $loadedModels[$appName][$moduleName];
return $this->$moduleName;
$taoObjectName = $moduleName . 'Tao';
$this->{$taoObjectName} = $tao;
return $tao;
}
/**
@@ -252,17 +264,22 @@ class baseModel
public function loadExtension($extensionName, $moduleName = '')
{
if(empty($extensionName)) return false;
if(empty($moduleName)) $moduleName = $this->getModuleName();
$moduleName = $moduleName ? $moduleName : $this->getModuleName();
$moduleName = strtolower($moduleName);
$extensionName = strtolower($extensionName);
$type = 'model';
$className = strtolower(get_class($this));
if($className == $moduleName . 'tao' || $className == 'ext' . $moduleName . 'tao') $type = 'tao';
/* 设置扩展类的名字。Set the extension class name. */
$extensionClass = $extensionName . ucfirst($moduleName);
if($type != 'model') $extensionClass .= ucfirst($type);
if(isset($this->$extensionClass)) return $this->$extensionClass;
/* 设置扩展的名字和相应的文件。Set extenson name and extension file. */
$moduleExtPath = $this->app->getModuleExtPath($this->appName, $moduleName, 'model');
$moduleExtPath = $this->app->getModuleExtPath($this->appName, $moduleName, $type);
if(!empty($moduleExtPath['site'])) $extensionFile = $moduleExtPath['site'] . 'class/' . $extensionName . '.class.php';
if(!isset($extensionFile) or !file_exists($extensionFile)) $extensionFile = $moduleExtPath['custom'] . 'class/' . $extensionName . '.class.php';
if(!isset($extensionFile) or !file_exists($extensionFile)) $extensionFile = $moduleExtPath['saas'] . 'class/' . $extensionName . '.class.php';
@@ -271,13 +288,13 @@ class baseModel
if(!isset($extensionFile) or !file_exists($extensionFile)) $extensionFile = $moduleExtPath['common'] . 'class/' . $extensionName . '.class.php';
/* 载入父类。Try to import parent model file auto and then import the extension file. */
if(!class_exists($moduleName . 'Model')) helper::import($this->app->getModulePath($this->appName, $moduleName) . 'model.php');
if(!class_exists($moduleName . ucfirst($type))) helper::import($this->app->getModulePath($this->appName, $moduleName) . $type . '.php');
if(!helper::import($extensionFile)) return false;
if(!class_exists($extensionClass)) return false;
/* 实例化扩展类。Create an instance of the extension class and return it. */
$extensionObject = new $extensionClass;
$extensionClass = str_replace('Model', '', $extensionClass);
if($type == 'model') $extensionClass = str_replace(ucfirst($type), '', $extensionClass);
$this->$extensionClass = $extensionObject;
return $extensionObject;
}
+163 -88
View File
@@ -1004,7 +1004,6 @@ class baseRouter
array($ztSessionHandler, "destroy"),
array($ztSessionHandler, "gc")
);
register_shutdown_function('session_write_close');
}
}
@@ -1624,7 +1623,7 @@ class baseRouter
*
* @param string $appName the app name
* @param string $moduleName the module name
* @param string $ext the extension type, can be control|model|view|lang|config
* @param string $ext the extension type, can be control|model|view|lang|config|zen|tao
* @access public
* @return string the extension path.
*/
@@ -1776,19 +1775,33 @@ class baseRouter
* 设置一个模块的model文件,如果存在model扩展,一起合并。
* Set the model file of one module. If there's an extension file, merge it with the main model file.
*
* @param string $moduleName the module name
* @param string $appName the app name
* @static
* @access public
* @return string the model file
* @param string $moduleName 模块名,如果为空,使用当前模块。The module name, if empty, use current module's name.
* @param string $appName 应用名,如果为空,使用当前应用。The app name, if empty, use current app's name.
* @access public
* @return string the model file
*/
public function setModelFile($moduleName, $appName = '')
{
return $this->setTargetFile($moduleName, $appName);
}
/**
* 设置一个模块的target文件,如果存在target扩展,一起合并。
* Set the target file of one module. If there's an extension file, merge it with the main target file.
*
* @param string $moduleName 模块名,如果为空,使用当前模块。The module name, if empty, use current module's name.
* @param string $appName 应用名,如果为空,使用当前应用。The app name, if empty, use current app's name.
* @param string $class 对象的类型,可选值 target、zen、tao,默认为 target。The type of the object, optional values target, zen, tao, the default is target.
* @access public
* @return string the target file
*/
public function setTargetFile($moduleName, $appName = '', $class = 'model')
{
if($appName == '') $appName = $this->getAppName();
/* 设置主model文件。 Set the main model file. */
$mainModelFile = $this->getModulePath($appName, $moduleName) . 'model.php';
if($this->config->framework->extensionLevel == 0) return $mainModelFile;
/* 设置主target文件。 Set the main target file. */
$mainTargetFile = $this->getModulePath($appName, $moduleName) . "{$class}.php";
if($this->config->framework->extensionLevel == 0) return $mainTargetFile;
/* 计算扩展的文件和hook文件。Compute the extension files and hook files. */
$hookFiles = array();
@@ -1796,14 +1809,14 @@ class baseRouter
$apiFiles = array();
$siteExtended = false;
$modelExtPaths = $this->getModuleExtPath($appName, $moduleName, 'model');
foreach($modelExtPaths as $extType => $modelExtPath)
$targetExtPaths = $this->getModuleExtPath($appName, $moduleName, $class);
foreach($targetExtPaths as $extType => $targetExtPath)
{
if(empty($modelExtPath)) continue;
if(empty($targetExtPath)) continue;
$tmpHookFiles = helper::ls($modelExtPath . 'hook/', '.php');
$tmpExtFiles = helper::ls($modelExtPath, '.php');
$tmpAPIFiles = helper::ls($modelExtPath, '.api');
$tmpHookFiles = helper::ls($targetExtPath . 'hook/', '.php');
$tmpExtFiles = helper::ls($targetExtPath, '.php');
$tmpAPIFiles = helper::ls($targetExtPath, '.api');
$hookFiles = array_merge($hookFiles, $tmpHookFiles);
$extFiles = array_merge($extFiles, $tmpExtFiles);
$apiFiles = array_merge($apiFiles, $tmpAPIFiles);
@@ -1812,119 +1825,127 @@ class baseRouter
}
/* 如果没有扩展文件,返回主文件。 If no extension or hook files, return the main file directly. */
if(empty($extFiles) and empty($hookFiles) and empty($apiFiles)) return $mainModelFile;
if(empty($extFiles) and empty($hookFiles) and empty($apiFiles)) return $mainTargetFile;
/* 计算合并之后的modelFile路径。Compute the merged model file path. */
$extModelPrefix = $this->config->edition . DS . $this->config->vision . DS;
if($siteExtended and !empty($this->siteCode)) $extModelPrefix .= $this->siteCode[0] . DS . $this->siteCode;
/* 计算合并之后的targetFile路径。Compute the merged target file path. */
$extTargetPrefix = $this->config->edition . DS . $this->config->vision . DS;
if($siteExtended and !empty($this->siteCode)) $extTargetPrefix .= $this->siteCode[0] . DS . $this->siteCode;
$mergedModelDir = $this->getTmpRoot() . 'model' . DS . $extModelPrefix;
$mergedModelFile = $mergedModelDir . $moduleName . '.php';
if(!is_dir($mergedModelDir)) mkdir($mergedModelDir, 0755, true);
$mergedTargetDir = $this->getTmpRoot() . $class . DS . $extTargetPrefix;
$mergedTargetFile = $mergedTargetDir . $moduleName . '.php';
if(!is_dir($mergedTargetDir)) mkdir($mergedTargetDir, 0755, true);
/* 判断生成的缓存文件是否需要更新。 Judge whether the merged model file needed update or not. */
if(!$this->needModelFileUpdate($mergedModelFile, $extFiles, $hookFiles, $apiFiles, $modelExtPaths, $mainModelFile)) return $mergedModelFile;
/* 判断生成的缓存文件是否需要更新。 Judge whether the merged target file needed update or not. */
if(!$this->needTargetFileUpdate($mergedTargetFile, $extFiles, $hookFiles, $apiFiles, $targetExtPaths, $mainTargetFile)) return $mergedTargetFile;
/* 合并扩展和hook文件。Merge the extension and hook files. */
$modelLines = $this->mergeModelExtFiles($moduleName, $mainModelFile, $extFiles, $mergedModelDir);
$this->mergeModelHookFiles($moduleName, $mainModelFile, $modelLines, $hookFiles, $mergedModelDir, $mergedModelFile, $apiFiles);
$targetLines = $this->mergeTargetExtFiles($moduleName, $extFiles, $mergedTargetDir, $class);
$this->mergeTargetHookFiles($moduleName, $mainTargetFile, $targetLines, $hookFiles, $mergedTargetDir, $mergedTargetFile, $apiFiles, $class);
return $mergedModelFile;
return $mergedTargetFile;
}
/**
* 检查合并之后的model文件是否需要更新。Check whether the merged model file need update or not.
* 检查合并之后的target文件是否需要更新。Check whether the merged target file need update or not.
*
* @param string $mergedModelFile
* @param string $mergedTargetFile
* @param array $extFiles
* @param array $hookFiles
* @param array $apiFiles
* @param string $modelExtPaths
* @param string $mainModelFile
* @param string $targetExtPaths
* @param string $mainTargetFile
* @access public
* @return bool
*/
public function needModelFileUpdate($mergedModelFile, $extFiles, $hookFiles, $apiFiles, $modelExtPaths, $mainModelFile)
public function needTargetFileUpdate($mergedTargetFile, $extFiles, $hookFiles, $apiFiles, $targetExtPaths, $mainTargetFile)
{
$lastTime = file_exists($mergedModelFile) ? filemtime($mergedModelFile) : 0;
$lastTime = file_exists($mergedTargetFile) ? filemtime($mergedTargetFile) : 0;
foreach($extFiles as $extFile) if(filemtime($extFile) > $lastTime) return true;
foreach($hookFiles as $hookFile) if(filemtime($hookFile) > $lastTime) return true;
foreach($apiFiles as $apiFile) if(filemtime($apiFile) > $lastTime) return true;
$modelExtPath = $modelExtPaths['common'];
$modelHookPath = $modelExtPaths['common'] . 'hook/';
if(is_dir($modelExtPath ) and filemtime($modelExtPath) > $lastTime) return true;
if(is_dir($modelHookPath) and filemtime($modelHookPath) > $lastTime) return true;
$targetExtPath = $targetExtPaths['common'];
$targetHookPath = $targetExtPaths['common'] . 'hook/';
if(is_dir($targetExtPath ) and filemtime($targetExtPath) > $lastTime) return true;
if(is_dir($targetHookPath) and filemtime($targetHookPath) > $lastTime) return true;
if(!empty($modelExtPaths['site']))
if(!empty($targetExtPaths['site']))
{
$modelExtPath = $modelExtPaths['site'];
$modelHookPath = $modelExtPaths['site'] . 'hook/';
if(is_dir($modelExtPath ) and filemtime($modelExtPath) > $lastTime) return true;
if(is_dir($modelHookPath) and filemtime($modelHookPath) > $lastTime) return true;
$targetExtPath = $targetExtPaths['site'];
$targetHookPath = $targetExtPaths['site'] . 'hook/';
if(is_dir($targetExtPath ) and filemtime($targetExtPath) > $lastTime) return true;
if(is_dir($targetHookPath) and filemtime($targetHookPath) > $lastTime) return true;
}
if(filemtime($mainModelFile) > $lastTime) return true;
if(filemtime($mainTargetFile) > $lastTime) return true;
return false;
}
/**
* 将model的扩展文件合并在一起。Merge model ext files.
* 将target的扩展文件合并在一起。Merge target ext files.
*
* @param string $moduleName
* @param string $mainModelFile
* @param array $extFiles
* @param string $mergedModelDir
* @param string $mergedTargetDir
* @param string $class model | zen | tao
* @access public
* @return void
*/
public function mergeModelExtFiles($moduleName, $mainModelFile, $extFiles, $mergedModelDir)
public function mergeTargetExtFiles($moduleName, $extFiles, $mergedTargetDir, $class = 'model')
{
/* 设置类名。Set the class names. */
$modelClass = "{$moduleName}Model";
$tmpModelClass = "tmpExt$modelClass";
$targetClass = $moduleName . ucfirst($class);
$tmpTargetClass = "tmpExt$targetClass";
/* 开始拼装代码。Prepare the codes. */
$modelLines = "<?php\n";
$modelLines .= "global \$app;\n";
$modelLines .= "helper::import(\$app->getModulePath('', '$moduleName') . " . "'model.php');\n";
$modelLines .= "class $tmpModelClass extends $modelClass \n{\n";
$targetLines = "<?php\n";
$targetLines .= "global \$app;\n";
$targetLines .= "helper::import(\$app->getModulePath('', '$moduleName') . " . "'$class.php');\n";
$targetLines .= "class $tmpTargetClass extends $targetClass \n{\n";
/* 将扩展文件的代码合并到代码中。Cycle all the extension files and merge them into model lines. */
$extModels = array();
foreach($extFiles as $extFile) $extModels[basename($extFile)] = $extFile;
foreach($extModels as $extModel) $modelLines .= self::removePHPTAG($extModel);
/* 将扩展文件的代码合并到代码中。Cycle all the extension files and merge them into target lines. */
$extTargets = array();
foreach($extFiles as $extFile) $extTargets[basename($extFile)] = $extFile;
foreach($extTargets as $extTarget) $targetLines .= self::removePHPTAG($extTarget);
/* 做个标记,方便后面替换代码使用。Make a mark for replacing codes. */
$replaceMark = '//**//';
$modelLines .= "\n$replaceMark\n}";
$targetLines .= "\n$replaceMark\n}";
/* 生成一个临时的model扩展文件,并加载,用于后续的hook文件加载使用。Create a tmp merged model file and import it for merge hook codes using. */
$tmpModelFile = $mergedModelDir . "tmp$moduleName.php";
if(@file_put_contents($tmpModelFile, $modelLines))
/* 生成一个临时的target扩展文件,并加载,用于后续的hook文件加载使用。Create a tmp merged target file and import it for merge hook codes using. */
$tmpTargetFile = $mergedTargetDir . "tmp$moduleName.php";
if(@file_put_contents($tmpTargetFile, $targetLines))
{
if(!class_exists($tmpModelClass)) include $tmpModelFile;
return $modelLines;
if(!class_exists($tmpTargetClass)) include $tmpTargetFile;
return $targetLines;
}
$this->triggerError("ERROR: $tmpModelFile not writable.", __FILE__, __LINE__, true);
$this->triggerError("ERROR: $tmpTargetFile not writable.", __FILE__, __LINE__, true);
}
/**
* 合并model的hook脚本。Merge hook files for a model.
* 合并target的hook脚本。Merge hook files for a target.
*
* @param string $moduleName
* @param string $mainTargetFile
* @param string $targetLines
* @param array $hookFiles
* @param string $mergedTargetDir
* @param string $mergedTargetFile
* @param array $apiFiles
* @param string $class model | zen | tao
* @access public
* @return void
*/
public function mergeModelHookFiles($moduleName, $mainModelFile, $modelLines, $hookFiles, $mergedModelDir, $mergedModelFile, $apiFiles)
public function mergeTargetHookFiles($moduleName, $mainTargetFile, $targetLines, $hookFiles, $mergedTargetDir, $mergedTargetFile, $apiFiles, $class = 'model')
{
/* 定义相关变量。Init vars. */
$modelClass = $moduleName . 'Model';
$extModelClass = 'ext' . $modelClass;
$tmpModelClass = 'tmpExt' . $modelClass;
$tmpModelFile = $mergedModelDir . "tmp$moduleName.php";
$targetClass = $moduleName . ucfirst($class);
$extTargetClass = 'ext' . $targetClass;
$tmpTargetClass = 'tmpExt' . $targetClass;
$tmpTargetFile = $mergedTargetDir . "tmp$moduleName.php";
$replaceMark = '//**//';
/* 读取hook文件。Get hook codes need to merge. */
@@ -1948,31 +1969,31 @@ class baseRouter
/* 合并Hook文件。Cycle the hook methods and merge hook codes. */
$hookedMethods = array_keys($hookCodes);
$mainModelCodes = file($mainModelFile);
$mergedModelCodes = file($tmpModelFile);
$mainTargetCodes = file($mainTargetFile);
$mergedTargetCodes = file($tmpTargetFile);
foreach($hookedMethods as $method)
{
/* 通过反射获得hook脚本对应的方法所在的文件和起止行数。Reflection the hooked method to get it's defined position. */
if(!method_exists($tmpModelClass, $method)) continue;
$methodRelfection = new reflectionMethod($tmpModelClass, $method);
if(!method_exists($tmpTargetClass, $method)) continue;
$methodRelfection = new reflectionMethod($tmpTargetClass, $method);
$definedFile = $methodRelfection->getFileName();
$startLine = $methodRelfection->getStartLine();
$endLine = $methodRelfection->getEndLine();
/* 将Hook脚本和老的代码合并在一起,并替换原来的定义。Merge hook codes with old codes and replace back. */
$oldCodes = $definedFile == $tmpModelFile ? $mergedModelCodes : $mainModelCodes;
$oldCodes = $definedFile == $tmpTargetFile ? $mergedTargetCodes : $mainTargetCodes;
$oldCodes = join("", array_slice($oldCodes, $startLine - 1, $endLine - $startLine + 1));
$openBrace = strpos($oldCodes, '{');
$newCodes = substr($oldCodes, 0, $openBrace + 1) . "\n" . join("\n", $hookCodes[$method]) . substr($oldCodes, $openBrace + 1);
if($definedFile == $tmpModelFile) $modelLines = str_replace($oldCodes, $newCodes, $modelLines);
if($definedFile != $tmpModelFile) $modelLines = str_replace($replaceMark, $newCodes . "\n$replaceMark", $modelLines);
if($definedFile == $tmpTargetFile) $targetLines = str_replace($oldCodes, $newCodes, $targetLines);
if($definedFile != $tmpTargetFile) $targetLines = str_replace($replaceMark, $newCodes . "\n$replaceMark", $targetLines);
}
/* 保存最终的Model文件。Save the last merged model file. */
$modelLines = str_replace($tmpModelClass, $extModelClass, $modelLines);
file_put_contents($mergedModelFile, $modelLines);
unlink($tmpModelFile);
/* 保存最终的Target文件。Save the last merged target file. */
$targetLines = str_replace($tmpTargetClass, $extTargetClass, $targetLines);
file_put_contents($mergedTargetFile, $targetLines);
unlink($tmpTargetFile);
}
/**
@@ -2182,6 +2203,57 @@ class baseRouter
return isset($module) ? $module : false;
}
/**
* 加载指定模块下的某种对象。
* Load the target object of one module.
*
* @param string $moduleName 模块名,如果为空,使用当前模块。The module name, if empty, use current module's name.
* @param string $appName 应用名,如果为空,使用当前应用。The app name, if empty, use current app's name.
* @param string $class 对象的类型,可选值 model、zen、tao,默认为 model。The type of the object, optional values model, zen, tao, the default is model.
* @access public
* @return object|bool 如果没有model文件,返回false,否则返回model对象。If no model file, return false, else return the model object.
*/
public function loadTarget($moduleName = '', $appName = '', $class = 'model')
{
if(empty($moduleName)) $moduleName = $this->moduleName;
if(empty($appName)) $appName = $this->appName;
global $loadedTargets;
if(isset($loadedTargets[$class][$appName][$moduleName])) return $loadedTargets[$class][$appName][$moduleName];
$targetFile = $this->setTargetFile($moduleName, $appName, $class);
/**
* 如果没有target文件,返回false。
* If no target file, return false.
*/
if(!helper::import($targetFile)) return false;
/**
* 如果没有扩展文件,target类名是$moduleName + $class,如果有扩展,还需要增加ext前缀。
* If no extension file, target class name is $moduleName + $class, else with 'ext' as the prefix.
*/
$targetClass = class_exists('ext' . $appName . $moduleName. $class) ? 'ext' . $appName . $moduleName . $class : $appName . $moduleName . $class;
if(!class_exists($targetClass))
{
$targetClass = class_exists('ext' . $moduleName. $class) ? 'ext' . $moduleName . $class : $moduleName . $class;
if(!class_exists($targetClass)) $this->triggerError(" The $class $targetClass not found", __FILE__, __LINE__, $exit = true);
}
/**
* 因为zen继承自control,tao继承自model,构造函数里会调用loadTarget方法,赋默认值值防止递归调用。
*/
if($class == 'zen' || $class == 'tao') $loadedTargets[$class][$appName][$moduleName] = false;
/**
* 初始化target 对象并返回。
* Init the target object and return it.
*/
$target = new $targetClass($appName);
$loadedTargets[$class][$appName][$moduleName] = $target;
return $target;
}
/**
* 设置请求的参数(PATH_INFO 方式)。
* Set the params by PATH_INFO.
@@ -3169,6 +3241,7 @@ class ztSessionHandler
{
$this->tagID = $tagID;
ini_set('session.save_handler', 'files');
register_shutdown_function('session_write_close');
}
/**
@@ -3263,15 +3336,16 @@ class ztSessionHandler
public function write($id, $sessData)
{
$sessFile = $this->getSessionFile($id);
touch($sessFile);
touch($this->rawFile);
if(md5_file($sessFile) == md5($sessData)) return true;
if(file_put_contents($sessFile, $sessData))
if(file_put_contents($sessFile, $sessData, LOCK_EX))
{
if(!file_exists($this->rawFile)) touch($this->rawFile);
if(strpos($sessData, 'user|') !== false)
{
$rawSessContent = (string) file_get_contents($this->rawFile);
if(strpos($rawSessContent, 'user|') === false) file_put_contents($this->rawFile, $sessData);
$rawSessContent = (string) file_get_contents($this->rawFile, false, null, 0, 1024 * 2);
if(strpos($rawSessContent, 'user|') === false) file_put_contents($this->rawFile, $sessData, LOCK_EX);
}
return true;
@@ -3290,9 +3364,10 @@ class ztSessionHandler
public function destroy($id)
{
$sessFile = $this->getSessionFile($id);
unlink($sessFile);
unlink($this->rawFile);
if(file_exists($sessFile)) unlink($sessFile);
if(file_exists($this->rawFile)) unlink($this->rawFile);
touch($sessFile);
touch($this->rawFile);
return true;
}
+176 -42
View File
@@ -42,48 +42,71 @@ class control extends baseControl
/* Code for task #9224. Set requiredFields for workflow. */
if($this->dbh and (defined('IN_USE') or (defined('RUN_MODE') and RUN_MODE == 'api')))
{
if(isset($this->config->{$this->moduleName}) and strpos($this->methodName, 'export') !== false)
{
if(isset($this->config->{$this->moduleName}->exportFields) or isset($this->config->{$this->moduleName}->list->exportFields))
{
$exportFields = $this->dao->select('*')->from(TABLE_WORKFLOWFIELD)->where('module')->eq($this->moduleName)->andWhere('canExport')->eq('1')->andWhere('buildin')->eq('0')->fetchAll('field');
if(isset($this->config->{$this->moduleName}->exportFields))
{
foreach($exportFields as $field) $this->config->{$this->moduleName}->exportFields .= ",{$field->field}";
}
if(isset($this->config->{$this->moduleName}->list->exportFields))
{
foreach($exportFields as $field) $this->config->{$this->moduleName}->list->exportFields .= ",{$field->field}";
}
foreach($exportFields as $flowField => $exportField)
{
if(!isset($this->lang->{$this->moduleName}->$flowField)) $this->lang->{$this->moduleName}->$flowField = $exportField->name;
}
}
}
/* Append editor field to this module config from workflow. */
$textareaFields = $this->dao->select('*')->from(TABLE_WORKFLOWFIELD)->where('module')->eq($this->moduleName)->andWhere('control')->eq('richtext')->andWhere('buildin')->eq('0')->fetchAll('field');
if($textareaFields)
{
$editorIdList = array();
foreach($textareaFields as $textareaField) $editorIdList[] = $textareaField->field;
if(!isset($this->config->{$this->moduleName})) $this->config->{$this->moduleName} = new stdclass();
if(!isset($this->config->{$this->moduleName}->editor)) $this->config->{$this->moduleName}->editor = new stdclass();
if(!isset($this->config->{$this->moduleName}->editor->{$this->methodName})) $this->config->{$this->moduleName}->editor->{$this->methodName} = array('id' => '', 'tools' => 'simpleTools');
$this->config->{$this->moduleName}->editor->{$this->methodName}['id'] .= ',' . join(',', $editorIdList);
trim($this->config->{$this->moduleName}->editor->{$this->methodName}['id'], ',');
}
$this->extendExportFields();
$this->extendEditorFields();
/* If workflow is created by a normal user, set priv. */
if(isset($this->app->user) and !$this->app->user->admin) $this->setDefaultPrivByWorkflow();
}
}
/**
* Append export fields to the config of this module from workflow.
*
* @access public
* @return void
*/
public function extendExportFields()
{
if(isset($this->config->{$this->moduleName}) and strpos($this->methodName, 'export') !== false)
{
if(isset($this->config->{$this->moduleName}->exportFields) or isset($this->config->{$this->moduleName}->list->exportFields))
{
$exportFields = $this->dao->select('*')->from(TABLE_WORKFLOWFIELD)->where('module')->eq($this->moduleName)->andWhere('canExport')->eq('1')->andWhere('buildin')->eq('0')->fetchAll('field');
if(isset($this->config->{$this->moduleName}->exportFields))
{
foreach($exportFields as $field) $this->config->{$this->moduleName}->exportFields .= ",{$field->field}";
}
if(isset($this->config->{$this->moduleName}->list->exportFields))
{
foreach($exportFields as $field) $this->config->{$this->moduleName}->list->exportFields .= ",{$field->field}";
}
foreach($exportFields as $flowField => $exportField)
{
if(!isset($this->lang->{$this->moduleName}->$flowField)) $this->lang->{$this->moduleName}->$flowField = $exportField->name;
}
}
}
}
/**
* Append editor fields to the config of this module from workflow.
*
* @access public
* @return void
*/
public function extendEditorFields()
{
$moduleName = $this->moduleName;
$methodName = $this->methodName;
$textareaFields = $this->dao->select('*')->from(TABLE_WORKFLOWFIELD)->where('module')->eq($this->moduleName)->andWhere('control')->eq('richtext')->andWhere('buildin')->eq('0')->fetchAll('field');
if($textareaFields)
{
$editorIdList = array();
foreach($textareaFields as $textareaField) $editorIdList[] = $textareaField->field;
if(!isset($this->config->{$moduleName})) $this->config->{$moduleName} = new stdclass();
if(!isset($this->config->{$moduleName}->editor)) $this->config->{$moduleName}->editor = new stdclass();
if(!isset($this->config->{$moduleName}->editor->{$methodName})) $this->config->{$moduleName}->editor->{$methodName} = array('id' => '', 'tools' => 'simpleTools');
$this->config->{$moduleName}->editor->{$methodName}['id'] .= ',' . join(',', $editorIdList);
trim($this->config->{$moduleName}->editor->{$methodName}['id'], ',');
}
}
/**
* Det default priv by workflow.
*
@@ -146,21 +169,94 @@ class control extends baseControl
}
/**
* 企业版部分功能是从然之合并过来的。然之代码中调用loadModel方法时传递了一个非空的appName,在禅道中会导致错误。
* 企业版部分功能是从然之合并过来的。ZDOO代码中调用loadModel方法时传递了一个非空的appName,在禅道中会导致错误。
* 调用父类的loadModel方法来避免这个错误。
* Some codes merged from ranzhi called the function loadModel with a non-empty appName which causes an error in zentao.
* Some codes merged from ZDOO called the function loadModel with a non-empty appName which causes an error in zentao.
* Call the parent function with empty appName to avoid this error.
*
* @param string $moduleName 模块名,如果为空,使用当前模块。The module name, if empty, use current module's name.
* @param string $appName The app name, if empty, use current app's name.
* @access public
* @return object|bool 如果没有model文件,返回false,否则返回model对象。If no model file, return false, else return the model object.
* @param string $moduleName 模块名,如果为空,使用当前模块。The module name, if empty, use current module's name.
* @param string $appName 应用名,如果为空,使用当前应用。The app name, if empty, use current app's name.
* @access public
* @return object|bool 如果没有model文件,返回false,否则返回model对象。If no model file, return false, else return the model object.
*/
public function loadModel($moduleName = '', $appName = '')
{
return parent::loadModel($moduleName);
}
/**
* 企业版部分功能是从然之合并过来的。ZDOO代码中调用loadZen方法时传递了一个非空的appName,在禅道中会导致错误。
* 调用父类的loadZen方法来避免这个错误。
* Some codes merged from ZDOO called the function loadZen with a non-empty appName which causes an error in zentao.
* Call the parent function with empty appName to avoid this error.
*
* @param string $moduleName 模块名,如果为空,使用当前模块。The module name, if empty, use current module's name.
* @param string $appName 应用名,如果为空,使用当前应用。The app name, if empty, use current app's name.
* @access public
* @return object|bool 如果没有model文件,返回false,否则返回model对象。If no model file, return false, else return the model object.
*/
public function loadZen($moduleName = '', $appName = '')
{
return parent::loadZen($moduleName);
}
/**
* 加载model的class扩展,主要是为了开发加密代码使用。
* 可以将主要的逻辑存放到$moduleName/ext/model/class/$extensionName.class.php中。
* 然后在ext/model/$extension.php的扩展里面使用$this->loadExtension()来调用相应的方法。
* ext/model/class/*.class.php代码可以加密。而ext/model/*.php可以不用加密。
* 因为框架对model的扩展是采取合并文件的方式,ext/model/*.php文件不能加密。
*
* Load extension class of a model thus user can encrypt the code.
* You can put the main extension logic codes in $moduleName/ext/model/class/$extensionName.class.php.
* And call them by the ext/model/$extension.php like this: $this->loadExtension('myextension')->method().
* You can encrypt the code in ext/model/class/*.class.php.
* Because the framework will merge the extension files in ext/model/*.php to the module/model.php.
*
* @param string $extensionName
* @param string $moduleName
* @access public
* @return void
*/
public function loadExtension($extensionName, $moduleName = '')
{
if(empty($extensionName)) return false;
if(empty($moduleName)) $moduleName = $this->moduleName;
$moduleName = strtolower($moduleName);
$extensionName = strtolower($extensionName);
$type = 'model';
$className = strtolower(get_class($this));
if($className == $moduleName . 'zen' || $className == 'ext' . $moduleName . 'zen') $type = 'zen';
/* 设置扩展类的名字。Set the extension class name. */
$extensionClass = $extensionName . ucfirst($moduleName);
if($type != 'model') $extensionClass .= ucfirst($type);
if(isset($this->$extensionClass)) return $this->$extensionClass;
/* 设置扩展的名字和相应的文件。Set extenson name and extension file. */
$moduleExtPath = $this->app->getModuleExtPath($this->appName, $moduleName, $type);
if(!empty($moduleExtPath['site'])) $extensionFile = $moduleExtPath['site'] . 'class/' . $extensionName . '.class.php';
if(!isset($extensionFile) or !file_exists($extensionFile)) $extensionFile = $moduleExtPath['custom'] . 'class/' . $extensionName . '.class.php';
if(!isset($extensionFile) or !file_exists($extensionFile)) $extensionFile = $moduleExtPath['saas'] . 'class/' . $extensionName . '.class.php';
if(!isset($extensionFile) or !file_exists($extensionFile)) $extensionFile = $moduleExtPath['vision'] . 'class/' . $extensionName . '.class.php';
if(!isset($extensionFile) or !file_exists($extensionFile)) $extensionFile = $moduleExtPath['xuan'] . 'class/' . $extensionName . '.class.php';
if(!isset($extensionFile) or !file_exists($extensionFile)) $extensionFile = $moduleExtPath['common'] . 'class/' . $extensionName . '.class.php';
/* 载入父类。Try to import parent model file auto and then import the extension file. */
if(!class_exists($moduleName . ucfirst($type))) helper::import($this->app->getModulePath($this->appName, $moduleName) . $type . '.php');
if(!helper::import($extensionFile)) return false;
if(!class_exists($extensionClass)) return false;
/* 实例化扩展类。Create an instance of the extension class and return it. */
$extensionObject = new $extensionClass;
if($type == 'model') $extensionClass = str_replace(ucfirst($type), '', $extensionClass);
$this->$extensionClass = $extensionObject;
$this->$extensionClass->view = $this->view;
return $extensionObject;
}
/**
* 设置视图文件:主视图文件,扩展视图文件, 站点扩展视图文件,以及钩子脚本。
* Set view files: the main file, extension view file, site extension view file and hook files.
@@ -553,4 +649,42 @@ class control extends baseControl
if($message) $this->send(array('result' => 'fail', 'message' => $message));
}
/**
* Call the functions declared in the tao files.
*
* @param string $method
* @param array $arguments
* @access public
* @return mixed
*/
public function __call($method, $arguments)
{
$moduleName = $this->app->getModuleName();
$zenClass = $moduleName . 'Zen';
if(is_callable(array($this->{$zenClass}, $method))) return call_user_func_array(array($this->{$zenClass}, $method), $arguments);
$this->app->triggerError("the module {$moduleName} has no {$method} method", __FILE__, __LINE__, $exit = true);
}
/**
* Call the static functions declared in the tao files.
*
* @param string $method
* @param array $arguments
* @access public
* @return mixed
*/
public static function __callStatic($method, $arguments)
{
global $app;
$moduleName = $app->getModuleName();
$zenClass = 'ext' . $moduleName . 'Zen';
if(is_callable("{$zenClass}::{$method}")) return call_user_func_array("{$zenClass}::{$method}", $arguments);
$zenClass = $moduleName . 'Zen';
if(is_callable("{$zenClass}::{$method}")) return call_user_func_array("{$zenClass}::{$method}", $arguments);
$app->triggerError("the module {$moduleName} has no {$method} method", __FILE__, __LINE__, $exit = true);
}
}
+15 -13
View File
@@ -96,27 +96,29 @@ class helper extends baseHelper
}
else
{
if($feature == 'product' or $feature == 'scrum' or $feature == 'waterfall') return strpos(",$config->disabledFeatures,", ",{$feature},") === false;
if($feature == 'scrum' or $feature == 'waterfall') return strpos(",$config->disabledFeatures,", ",{$feature},") === false;
$hasFeature = false;
$hasFeature = false;
$canConfigFeature = false;
foreach($config->featureGroup as $group => $modules)
{
if($feature == $group)
foreach($modules as $module)
{
foreach($modules as $module)
if($feature == $group or $feature == $module)
{
if(helper::hasFeature("{$group}_{$module}")) $hasFeature = true;
}
}
else
{
foreach($modules as $module)
{
if($feature == $module and helper::hasFeature("{$group}_{$module}")) $hasFeature = true;
$canConfigFeature = true;
if($group == 'scrum' or $group == 'waterfall')
{
if(helper::hasFeature("{$group}") and helper::hasFeature("{$group}_{$module}")) $hasFeature = true;
}
else
{
if(helper::hasFeature("{$group}_{$module}")) $hasFeature = true;
}
}
}
}
return $hasFeature && strpos(",$config->disabledFeatures,", ",{$feature},") === false;
return !$canConfigFeature or ($hasFeature && strpos(",$config->disabledFeatures,", ",{$feature},") === false);
}
}
+77 -5
View File
@@ -21,20 +21,37 @@ include dirname(__FILE__) . '/base/model.class.php';
class model extends baseModel
{
/**
* 企业版部分功能是从然之合并过来的。然之代码中调用loadModel方法时传递了一个非空的appName,在禅道中会导致错误。
* 企业版部分功能是从然之合并过来的。ZDOO代码中调用loadModel方法时传递了一个非空的appName,在禅道中会导致错误。
* 调用父类的loadModel方法来避免这个错误。
* Some codes merged from ranzhi called the function loadModel with a non-empty appName which causes an error in zentao.
* Some codes merged from ZDOO called the function loadModel with a non-empty appName which causes an error in zentao.
* Call the parent function with empty appName to avoid this error.
*
* @param string $moduleName
* @access public
* @return object|bool the model object or false if model file not exists.
* @param string $moduleName 模块名,如果为空,使用当前模块。The module name, if empty, use current module's name.
* @param string $appName 应用名,如果为空,使用当前应用。The app name, if empty, use current app's name.
* @access public
* @return object|bool the model object or false if model file not exists.
*/
public function loadModel($moduleName, $appName = '')
{
return parent::loadModel($moduleName);
}
/**
* 企业版部分功能是从然之合并过来的。ZDOO代码中调用loadTao方法时传递了一个非空的appName,在禅道中会导致错误。
* 调用父类的loadTao方法来避免这个错误。
* Some codes merged from ZDOO called the function loadTao with a non-empty appName which causes an error in zentao.
* Call the parent function with empty appName to avoid this error.
*
* @param string $moduleName 模块名,如果为空,使用当前模块。The module name, if empty, use current module's name.
* @param string $appName 应用名,如果为空,使用当前应用。The app name, if empty, use current app's name.
* @access public
* @return object|bool the model object or false if model file not exists.
*/
public function loadTao($moduleName, $appName = '')
{
return parent::loadTao($moduleName);
}
/**
* 删除记录
* Delete one record.
@@ -320,4 +337,59 @@ class model extends baseModel
$flow = $this->loadModel('workflow')->getByModule($moduleName);
if($flow && $action) return $this->loadModel('workflowhook')->execute($flow, $action, $objectID);
}
/**
* Call the functions declared in the tao files.
*
* @param string $method
* @param array $arguments
* @access public
* @return mixed
*/
public function __call($method, $arguments)
{
$moduleName = $this->getModuleName();
$taoClass = $moduleName . 'Tao';
if(is_callable(array($this->{$taoClass}, $method))) return call_user_func_array(array($this->{$taoClass}, $method), $arguments);
$this->app->triggerError("the module {$moduleName} has no {$method} method", __FILE__, __LINE__, $exit = true);
}
/**
* Call the static functions declared in the tao files.
*
* @param string $method
* @param array $arguments
* @access public
* @return mixed
*/
public static function __callStatic($method, $arguments)
{
global $app;
$moduleName = strtolower(get_called_class());
preg_match_all('/^(ext)?(\w+)model/', $moduleName, $matches);
if(isset($matches[2][0]))
{
$moduleName = $matches[2][0];
}
else
{
preg_match_all('/^(ext)?(\w+)tao/', $moduleName, $matches);
if(isset($matches[2][0])) $moduleName = $matches[2][0];
}
$modelClass = 'ext' . $moduleName . 'Model';
if(method_exists($modelClass, $method)) return call_user_func_array("{$modelClass}::{$method}", $arguments);
$taoClass = 'ext' . $moduleName . 'Tao';
if(method_exists($taoClass, $method)) return call_user_func_array("{$taoClass}::{$method}", $arguments);
$taoClass = $moduleName . 'Tao';
if(method_exists($taoClass, $method)) return call_user_func_array("{$taoClass}::{$method}", $arguments);
$app->triggerError("the module {$moduleName} has no {$method} method", __FILE__, __LINE__, $exit = true);
}
}
+2 -2
View File
@@ -181,7 +181,7 @@ class router extends baseRouter
$hourKey = $planKey = $URSR = $URAndSR = 0;
$mode = 'new';
$mode = 'ALM';
$score = '0';
$projectKey = ITERATION_KEY;
$disabledFeatures = '';
@@ -200,7 +200,7 @@ class router extends baseRouter
}
/* Lite Version is compatible with classic modes */
if($config->vision == 'lite') $mode = 'new';
if($config->vision == 'lite') $mode = 'ALM';
/* Record system mode. */
$config->systemMode = $mode;
+2 -2
View File
@@ -521,8 +521,8 @@ class baseHTML
/* If the link of the referer is not the link of the current page or the link of the index, the cookie and gobackLink will be updated. */
if(!preg_match("/(m=|\/)(index|search|$currentModule)(&f=|-)(index|buildquery|$currentMethod)(&|-|\.)?/", strtolower($refererLink)))
{
$gobackList[$tab] = $referer . "#app=$tab";
$gobackLink = $referer . "#app=$tab";
$gobackList[$tab] = $referer;
$gobackLink = $referer;
setcookie('goback', json_encode($gobackList), $config->cookieLife, $config->webRoot, '', $config->cookieSecure, false);
}
+3 -1
View File
@@ -28,7 +28,9 @@ class GitRepo
if($branch)
{
$branches = $this->branch();
if(isset($branches[$branch])) $branch = "origin/$branch";
$cmd = escapeCmd("$this->client branch -r");
execCmd($cmd . ' 2>&1', 'string', $result);
if(isset($branches[$branch]) and !empty($result)) $branch = "origin/$branch";
}
$this->branch = $branch;
$this->repo = $repo;
+7 -5
View File
@@ -18,10 +18,11 @@ class zfile
* @param string $to
* @param bool $logLevel
* @param string $logFile
* @param array $excludeFiles
* @access public
* @return array copied files, count, size or message.
*/
public function copyDir($from, $to, $logLevel = false, $logFile = '')
public function copyDir($from, $to, $logLevel = false, $logFile = '', $excludeFiles = array())
{
static $copiedFiles = array();
static $errorFiles = array();
@@ -46,7 +47,7 @@ class zfile
$entries = scandir($from);
foreach($entries as $entry)
{
if($entry == '.' or $entry == '..' or $entry == '.svn' or $entry == '.git') continue;
if($entry == '.' or $entry == '..' or $entry == '.svn' or $entry == '.git' or in_array($entry, $excludeFiles)) continue;
$fullEntry = $from . $entry;
if(is_file($fullEntry))
@@ -101,10 +102,11 @@ class zfile
* Get count.
*
* @param string $dir
* @param array $excludeFiles
* @access public
* @return int
*/
public function getCount($dir)
public function getCount($dir, $excludeFiles = array())
{
if(!file_exists($dir)) return 0;
if(is_file($dir)) return 1;
@@ -113,7 +115,7 @@ class zfile
$entries = scandir($dir);
foreach($entries as $entry)
{
if($entry == '.' or $entry == '..' or $entry == '.svn' or $entry == '.git') continue;
if($entry == '.' or $entry == '..' or $entry == '.svn' or $entry == '.git' or in_array($entry, $excludeFiles)) continue;
$fullEntry = $dir . '/' . $entry;
$count += $this->getCount($fullEntry);
@@ -223,7 +225,7 @@ class zfile
*
* @param string $patern
* @access public
* @return avoid
* @return void
*/
public function batchRemoveFile($patern)
{
+3 -2
View File
@@ -207,6 +207,7 @@ $lang->action->desc->estimated = '$date, by <strong>$actor</strong> e
$lang->action->desc->run = '$date, by <strong>$actor</strong> executed.' . "\n";
$lang->action->desc->syncprogram = '$date, started by <strong>$actor</strong>(starting the project sets the program status as Ongoing).' . "\n";
$lang->action->desc->syncproject = '$date, starting the execution sets the project status as Ongoing.' . "\n";
$lang->action->desc->syncmultipleproject = '$date, starting the task sets the project status as Ongoing.' . "\n";
$lang->action->desc->syncexecution = '$date, starting the task sets the execution status as Ongoing.' . "\n";
$lang->action->desc->syncexecutionbychild = '$date, starting the sub stage sets the execution status as Ongoing.' . "\n";
$lang->action->desc->importfromgitlab = '$date, Issue associate created from gitlab by <strong>$actor</strong>.' . "\n";
@@ -641,8 +642,6 @@ $lang->action->dynamicAction->caselib['hidden'] = 'Hide Case Lib';
$lang->action->dynamicAction->zahost['created'] = 'Create Host';
$lang->action->dynamicAction->vmtemplate['created'] = 'Create Virtual Host Template';
$lang->action->dynamicAction->zanode['created'] = 'Create Zagent Node';
$lang->action->dynamicAction->zanode['suspend'] = 'Suspend Zagent Node';
$lang->action->dynamicAction->zanode['resume'] = 'Resume Zagent Node';
@@ -933,3 +932,5 @@ $lang->action->desc->deletemr = '$date, <strong>$actor</stro
$lang->action->desc->mergedmr = '$date, <strong>$actor</strong> merged <a href="$extra">code</a>.';
$lang->action->desc->approve = '$date, <strong>$actor</strong> approved.';
$lang->action->desc->reject = '$date, <strong>$actor</strong> rejected.';
$lang->action->desc->linkedrepo = '$date, <strong>$actor</strong> linked repo $extra';
$lang->action->desc->unlinkedrepo = '$date, <strong>$actor</strong> unlinked repo $extra';
+3 -2
View File
@@ -207,6 +207,7 @@ $lang->action->desc->estimated = '$date, by <strong>$actor</strong> e
$lang->action->desc->run = '$date, by <strong>$actor</strong> executed.' . "\n";
$lang->action->desc->syncprogram = '$date, started by <strong>$actor</strong>(starting the project sets the program status as Ongoing).' . "\n";
$lang->action->desc->syncproject = '$date, starting the execution sets the project status as Ongoing.' . "\n";
$lang->action->desc->syncmultipleproject = '$date, starting the task sets the project status as Ongoing.' . "\n";
$lang->action->desc->syncexecution = '$date, starting the task sets the execution status as Ongoing.' . "\n";
$lang->action->desc->syncexecutionbychild = '$date, starting the sub stage sets the execution status as Ongoing.' . "\n";
$lang->action->desc->importfromgitlab = '$date, Issue associate created from gitlab by <strong>$actor</strong>.' . "\n";
@@ -642,8 +643,6 @@ $lang->action->dynamicAction->caselib['hidden'] = 'Hide Case Lib';
$lang->action->dynamicAction->zahost['created'] = 'Create Host';
$lang->action->dynamicAction->vmtemplate['created'] = 'Create Virtual Host Template';
$lang->action->dynamicAction->zanode['created'] = 'Create Zagent Node';
$lang->action->dynamicAction->zanode['suspend'] = 'Suspend Zagent Node';
$lang->action->dynamicAction->zanode['resume'] = 'Resume Zagent Node';
@@ -934,3 +933,5 @@ $lang->action->desc->deletemr = '$date, <strong>$actor</stro
$lang->action->desc->mergedmr = '$date, <strong>$actor</strong> merged <a href="$extra">code</a>.';
$lang->action->desc->approve = '$date, <strong>$actor</strong> approved.';
$lang->action->desc->reject = '$date, <strong>$actor</strong> rejected.';
$lang->action->desc->linkedrepo = '$date, <strong>$actor</strong> linked repo $extra';
$lang->action->desc->unlinkedrepo = '$date, <strong>$actor</strong> unlinked repo $extra';
+3 -2
View File
@@ -207,6 +207,7 @@ $lang->action->desc->estimated = '$date, by <strong>$actor</strong> e
$lang->action->desc->run = '$date, by <strong>$actor</strong> executed.' . "\n";
$lang->action->desc->syncprogram = '$date, started by <strong>$actor</strong>(starting the project sets the program status as Ongoing).' . "\n";
$lang->action->desc->syncproject = '$date, starting the execution sets the project status as Ongoing.' . "\n";
$lang->action->desc->syncmultipleproject = '$date, starting the task sets the project status as Ongoing.' . "\n";
$lang->action->desc->syncexecution = '$date, starting the task sets the execution status as Ongoing.' . "\n";
$lang->action->desc->syncexecutionbychild = '$date, starting the sub stage sets the execution status as Ongoing.' . "\n";
$lang->action->desc->importfromgitlab = '$date, Issue associate created from gitlab by <strong>$actor</strong>.' . "\n";
@@ -641,8 +642,6 @@ $lang->action->dynamicAction->caselib['hidden'] = 'Masqué CasTest Lib';
$lang->action->dynamicAction->zahost['created'] = 'Create Host';
$lang->action->dynamicAction->vmtemplate['created'] = 'Create Virtual Host Template';
$lang->action->dynamicAction->zanode['created'] = 'Create Zagent Node';
$lang->action->dynamicAction->zanode['suspend'] = 'Suspend Zagent Node';
$lang->action->dynamicAction->zanode['resume'] = 'Resume Zagent Node';
@@ -933,3 +932,5 @@ $lang->action->desc->deletemr = '$date, <strong>$actor</stro
$lang->action->desc->mergedmr = '$date, <strong>$actor</strong> merged <a href="$extra">code</a>.';
$lang->action->desc->approve = '$date, <strong>$actor</strong> approved.';
$lang->action->desc->reject = '$date, <strong>$actor</strong> rejected.';
$lang->action->desc->linkedrepo = '$date, <strong>$actor</strong> linked repo $extra';
$lang->action->desc->unlinkedrepo = '$date, <strong>$actor</strong> unlinked repo $extra';
-3
View File
@@ -89,7 +89,6 @@ $lang->action->objectTypes['testsuite'] = 'Suite';
$lang->action->objectTypes['testtask'] = 'Test bản dựng';
$lang->action->objectTypes['testreport'] = 'Báo cáo';
$lang->action->objectTypes['zahost'] = 'Host';
$lang->action->objectTypes['vmtemplate'] = 'Virtual Host Template';
$lang->action->objectTypes['zanode'] = 'ZA Node';
$lang->action->objectTypes['doc'] = 'Tài liệu';
$lang->action->objectTypes['doclib'] = 'Thư viện tài liệu';
@@ -496,8 +495,6 @@ $lang->action->dynamicAction->caselib['hidden'] = 'Ẩn Case Lib';
$lang->action->dynamicAction->zahost['created'] = 'Create Host';
$lang->action->dynamicAction->vmtemplate['created'] = 'Create Virtual Host Template';
$lang->action->dynamicAction->zanode['created'] = 'Create Zagent Node';
$lang->action->dynamicAction->zanode['suspend'] = 'Suspend Zagent Node';
$lang->action->dynamicAction->zanode['resume'] = 'Resume Zagent Node';
+4 -3
View File
@@ -207,6 +207,7 @@ $lang->action->desc->estimated = '$date, 由 <strong>$actor</strong>
$lang->action->desc->run = '$date, 由 <strong>$actor</strong> 执行。' . "\n";
$lang->action->desc->syncprogram = '$date, 由 <strong>$actor</strong> 启动(因项目开始而启动项目集)。' . "\n";
$lang->action->desc->syncproject = '$date, 系统判断由于' . $lang->executionCommon .'开始,将项目状态置为进行中。' . "\n";
$lang->action->desc->syncmultipleproject = '$date, 系统判断由于任务开始,将项目状态置为进行中。' . "\n";
$lang->action->desc->syncexecution = '$date, 系统判断由于任务开始,将' . $lang->executionCommon . '状态置为进行中。' . "\n";
$lang->action->desc->syncexecutionbychild = '$date, 系统判断由于子阶段开始,将' . $lang->executionCommon . '状态置为进行中。' . "\n";
$lang->action->desc->importfromgitlab = '$date, 由 <strong>$actor</strong> 从Gitlab的Issue关联创建。' . "\n";
@@ -230,7 +231,7 @@ $lang->action->desc->suspend = '$date, 由 <strong>$actor</strong>
$lang->action->desc->resume = '$date, 由 <strong>$actor</strong> 恢复。' . "\n";
$lang->action->desc->reboot = '$date, 由 <strong>$actor</strong> 重启。' . "\n";
$lang->action->desc->destroy = '$date, 由 <strong>$actor</strong> 销毁。' . "\n";
$lang->action->desc->switchtolight = '$date, 由 <strong>'. $lang->admin->system .'</strong> 从全生命周期管理模式切换为轻量管理模式。' . "\n";
$lang->action->desc->switchtolight = '$date, 由于 <strong>'. $lang->admin->system .'</strong> 从全生命周期管理模式切换为轻量管理模式,项目访问控制由项目集内公开调整为私有。' . "\n";
$lang->action->desc->unlinkproduct = '$date, 系统判断由于迭代所属项目与$extra取消关联,同步将迭代与$extra取消关联。' . "\n";
$lang->action->desc->getvnc = '$date, <strong>$actor</strong>对执行节点 <strong>$extra</strong> 进行了远程操控。' . "\n";
@@ -642,8 +643,6 @@ $lang->action->dynamicAction->caselib['hidden'] = '隐藏用例库';
$lang->action->dynamicAction->zahost['created'] = '创建宿主机';
$lang->action->dynamicAction->vmtemplate['created'] = '创建虚拟机模板';
$lang->action->dynamicAction->zanode['created'] = '创建执行节点';
$lang->action->dynamicAction->zanode['suspend'] = '暂停执行节点';
$lang->action->dynamicAction->zanode['resume'] = '恢复执行节点';
@@ -934,3 +933,5 @@ $lang->action->desc->deletemr = '$date, 由 <strong>$actor</
$lang->action->desc->mergedmr = '$date, 由 <strong>$actor</strong> 合并了 <a href="$extra">代码</a>。';
$lang->action->desc->approve = '$date, 由 <strong>$actor</strong> 审核通过。';
$lang->action->desc->reject = '$date, 由 <strong>$actor</strong> 拒绝。';
$lang->action->desc->linkedrepo = '$date, 由 <strong>$actor</strong> 关联代码库 $extra';
$lang->action->desc->unlinkedrepo = '$date, 由 <strong>$actor</strong> 取消了项目与代码库 $extra 的关联';
+9 -7
View File
@@ -325,29 +325,30 @@ class actionModel extends model
*/
public function getList($objectType, $objectID)
{
$modules = $objectType == 'module' ? $this->dao->select('id')->from(TABLE_MODULE)->where('root')->eq($objectID)->fetchPairs('id') : array();
$objectID = is_array($objectID) ? $objectID : (int)$objectID;
$modules = $objectType == 'module' ? $this->dao->select('id')->from(TABLE_MODULE)->where('root')->in($objectID)->fetchPairs('id') : array();
$commiters = $this->loadModel('user')->getCommiters();
$actions = $this->dao->select('*')->from(TABLE_ACTION)
->beginIF($objectType == 'project')
->where("objectType IN('project', 'testtask', 'build')")
->andWhere('project')->eq((int)$objectID)
->andWhere('project')->in($objectID)
->fi()
->beginIF($objectType == 'story')
->where('objectType')->in('story,requirement')
->andWhere('objectID')->eq((int)$objectID)
->andWhere('objectID')->in($objectID)
->fi()
->beginIF($objectType == 'case')
->where('objectType')->in('case,testcase')
->andWhere('objectID')->eq((int)$objectID)
->andWhere('objectID')->in($objectID)
->fi()
->beginIF($objectType == 'module')
->where('objectType')->eq($objectType)
->andWhere('((action')->ne('deleted')->andWhere('objectID')->eq((int)$objectID)->markRight(1)
->andWhere('((action')->ne('deleted')->andWhere('objectID')->in($objectID)->markRight(1)
->orWhere('(action')->eq('deleted')->andWhere('objectID')->in($modules)->markRight(1)->markRight(1)
->fi()
->beginIF(strpos('project,case,story,module', $objectType) === false)
->where('objectType')->eq($objectType)
->andWhere('objectID')->eq((int)$objectID)
->andWhere('objectID')->in($objectID)
->fi()
->orderBy('date, id')
->fetchAll('id');
@@ -386,7 +387,7 @@ class actionModel extends model
$name = $execution->name;
$method = $execution->type == 'kanban' ? 'kanban' : 'view';
$action->extra = (!common::hasPriv('execution', $method) or ($method == 'kanban' and isonlybody())) ? $name : html::a(helper::createLink('execution', $method, "executionID=$action->execution"), $name);
$action->extra = (!common::hasPriv('execution', $method) or ($method == 'kanban' and isonlybody())) ? $name : html::a(helper::createLink('execution', $method, "executionID=$action->execution"), $name, '', "data-app='execution'");
}
}
elseif($actionName == 'linked2project')
@@ -1660,6 +1661,7 @@ class actionModel extends model
/* Set app for no multiple project. */
if(!empty($action->objectLink) and !empty($project) and empty($project->multiple)) $action->objectLink .= '#app=project';
if($this->config->vision == 'lite' and $action->objectType == 'module') $action->objectLink .= '#app=project';
return $action;
}
-10
View File
@@ -1,14 +1,4 @@
<?php
$config->url = new stdclass();
$config->url->community = 'https://www.zentao.net';
$config->url->ask = 'https://www.zentao.net/ask-browse.html';
$config->url->document = 'https://www.zentao.net/help-book-zentaopmshelp.html';
$config->url->feedback = 'https://www.zentao.net/forum-board-1074.html';
$config->url->faq = 'https://www.zentao.net/ask-faq.html';
$config->url->extension = 'https://www.zentao.net/extension-browse.html';
$config->url->donation = 'https://www.zentao.net/help-donation.html';
$config->url->service = 'https://www.cnezsoft.com/article-browse-1078.html';
$config->admin->apiRoot = 'https://www.zentao.net';
$config->admin->log = new stdclass();
+9 -1
View File
@@ -11,5 +11,13 @@ $(function()
{
$("input[name='" + name + "'][type=hidden]").val('0').attr('disabled', false);
}
})
});
$('input[name=allChecker]').change(function()
{
$(this).closest('tr').find("input[name^='module']").prop('checked', $(this).prop('checked')).change();
});
$('#allChecker').change(function()
{
$('input[name=allChecker]').prop('checked', $(this).prop('checked')).change();
});
})
+1 -1
View File
@@ -88,7 +88,7 @@ $lang->admin->setModule->auditplan = 'QA';
$lang->admin->setModule->meeting = 'Meeting';
$lang->admin->setModule->roadmap = 'Roadmap';
$lang->admin->setModule->track = 'Track';
$lang->admin->setModule->URStory = 'URStroy';
$lang->admin->setModule->UR = 'URStroy';
$lang->admin->setModule->researchplan = 'Researchplan';
$lang->admin->setModule->gapanalysis = 'Gapanalysis';
$lang->admin->setModule->storylib = 'Story Lib';
+1 -1
View File
@@ -88,7 +88,7 @@ $lang->admin->setModule->auditplan = 'QA';
$lang->admin->setModule->meeting = 'Meeting';
$lang->admin->setModule->roadmap = 'Roadmap';
$lang->admin->setModule->track = 'Track';
$lang->admin->setModule->URStory = 'URStroy';
$lang->admin->setModule->UR = 'URStroy';
$lang->admin->setModule->researchplan = 'Researchplan';
$lang->admin->setModule->gapanalysis = 'Gapanalysis';
$lang->admin->setModule->storylib = 'Story Lib';
+1 -1
View File
@@ -88,7 +88,7 @@ $lang->admin->setModule->auditplan = 'QA';
$lang->admin->setModule->meeting = 'Meeting';
$lang->admin->setModule->roadmap = 'Roadmap';
$lang->admin->setModule->track = 'Track';
$lang->admin->setModule->URStory = 'URStroy';
$lang->admin->setModule->UR = 'URStroy';
$lang->admin->setModule->researchplan = 'Researchplan';
$lang->admin->setModule->gapanalysis = 'Gapanalysis';
$lang->admin->setModule->storylib = 'Story Lib';
+1 -1
View File
@@ -88,7 +88,7 @@ $lang->admin->setModule->auditplan = 'QA';
$lang->admin->setModule->meeting = '会议';
$lang->admin->setModule->roadmap = '路线图';
$lang->admin->setModule->track = '矩阵';
$lang->admin->setModule->URStory = '用户需求';
$lang->admin->setModule->UR = '用户需求';
$lang->admin->setModule->researchplan = '调研';
$lang->admin->setModule->gapanalysis = '培训';
$lang->admin->setModule->storylib = '需求库';
+18 -22
View File
@@ -20,12 +20,8 @@
<table class='table table-condensed table-bordered active-disabled table-fixed'>
<thead class='text-center'>
<tr>
<th rowspan='2' class='w-120px'><?php echo $lang->admin->setModule->module;?></th>
<th colspan='2'><?php echo $lang->admin->setModule->optional;?></th>
</tr>
<tr>
<th><?php echo $lang->admin->setModule->opened;?></th>
<th><?php echo $lang->admin->setModule->closed;?></th>
<th class='w-150px'><?php echo $lang->admin->setModule->module;?></th>
<th><?php echo $lang->admin->setModule->optional;?></th>
</tr>
</thead>
<tbody>
@@ -41,26 +37,20 @@
<?php if($hasData):?>
<tr>
<td class='text-right'><?php echo $lang->admin->setModule->{$group};?></td>
<td class='text-middle text-right thWidth'>
<div class="checkbox-primary checkbox-inline checkbox-right check-all">
<input type='checkbox' id='allChecker<?php echo $group;?>' name='allChecker'>
<label class='text-right' for='allChecker<?php echo $group;?>'><?php echo $lang->admin->setModule->{$group};?></label>
</div>
</td>
<td>
<?php foreach($features as $feature):?>
<?php $code = $group. ucfirst($feature);?>
<?php if(strpos(",$disabledFeatures,", ",$code,") !== false) continue;?>
<?php if(strpos(",$closedFeatures,", ",$code,") !== false) continue;?>
<?php $value = strpos(",$closedFeatures,", ",$code,") === false ? '1' : '0';?>
<div class='group-item'>
<?php echo html::checkbox("module[{$code}]", array('1' => $lang->admin->setModule->{$feature}), '1', "data-code='{$code}'", 'inline');?>
<?php echo html::hidden("module[{$code}][]", '1', 'disabled');?>
</div>
<?php endForeach;?>
</td>
<td>
<?php foreach($features as $feature):?>
<?php $code = $group . ucfirst($feature);?>
<?php if(strpos(",$disabledFeatures,", ",$code,") !== false) continue;?>
<?php if(strpos(",$closedFeatures,", ",$code,") === false) continue;?>
<div class='group-item'>
<?php echo html::checkbox("module[{$code}]", array('1' => $lang->admin->setModule->{$feature}), '0', "data-code='{$code}'", 'inline');?>
<?php echo html::hidden("module[{$code}][]", '0');?>
<?php echo html::checkbox("module[{$code}]", array('1' => $lang->admin->setModule->{$feature}), $value, "data-code='{$code}'", 'inline');?>
<?php echo html::hidden("module[{$code}][]", $value, $value ? 'disabled' : '');?>
</div>
<?php endForeach;?>
</td>
@@ -68,7 +58,13 @@
<?php endif;?>
<?php endForeach;?>
<tr>
<td colspan='3' class='text-center'><?php echo html::submitButton();?></td>
<td class='text-middle text-right thWidth'>
<div class="checkbox-primary checkbox-inline checkbox-right check-all">
<input type='checkbox' id='allChecker'>
<label class='text-right' for='allChecker'><?php echo $lang->selectAll;?></label>
</div>
</td>
<td><?php echo html::submitButton();?></td>
</tr>
</tbody>
</table>
+4 -3
View File
@@ -337,11 +337,12 @@ class backup extends control
{
$this->app->loadLang('extension');
$search = dirname($this->app->getBasePath()) . DS;
$search = $this->app->getBasePath();
$pos = strpos($statusFile, $search);
if($pos !== false) $statusFile = substr_replace($statusFile, '', $pos, strlen($search));
$okFile = $statusFile;
if($pos !== false) $okFile = substr_replace($statusFile, '', $pos, strlen($search));
$this->view->error = sprintf($this->lang->extension->noticeOkFile, $statusFile, $statusFile);
$this->view->error = sprintf($this->lang->extension->noticeOkFile, $okFile, $statusFile);
return print($this->display());
}
+3 -2
View File
@@ -34,6 +34,7 @@ class backupModel extends model
public function backFile($backupFile)
{
$zfile = $this->app->loadClass('zfile');
$return = new stdclass();
$return->result = true;
$return->error = '';
@@ -42,10 +43,10 @@ class backupModel extends model
$tmpLogFile = $this->getTmpLogFile($backupFile);
$dataDir = $this->app->getAppRoot() . 'www/data/';
$count = $zfile->getCount($dataDir);
$count = $zfile->getCount($dataDir, array('course'));
file_put_contents($tmpLogFile, json_encode(array('allCount' => $count)));
$result = $zfile->copyDir($dataDir, $backupFile, $logLevel = false, $tmpLogFile);
$result = $zfile->copyDir($dataDir, $backupFile, $logLevel = false, $tmpLogFile, array('course'));
$this->processSummary($backupFile, $result['count'], $result['size'], $result['errorFiles'], $count);
unlink($tmpLogFile);
+33
View File
@@ -253,6 +253,10 @@ class block extends control
$shortBlocks = $longBlocks = array();
foreach($blocks as $key => $block)
{
if($block->block == 'waterfallrisk' and !helper::hasFeature('waterfall_risk')) continue;
if($block->block == 'waterfallissue' and !helper::hasFeature('waterfall_issue')) continue;
if($block->block == 'scrumrisk' and !helper::hasFeature('scrum_risk')) continue;
if($block->block == 'scrumissue' and !helper::hasFeature('scrum_issue')) continue;
if(!empty($block->source) and $block->source != 'todo' and !empty($acls['views']) and !isset($acls['views'][$block->source]))
{
unset($blocks[$key]);
@@ -1430,6 +1434,35 @@ class block extends control
$this->view->releases = $releases;
}
/**
* Print scrum issue block.
*
* @access public
* @return void
*/
public function printScrumIssueBlock()
{
$uri = $this->app->tab == 'my' ? $this->createLink('my', 'index') : $this->server->http_referer;
$this->session->set('issueList', $uri, 'project');
if(preg_match('/[^a-zA-Z0-9_]/', $this->params->type)) return;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->issues = $this->loadModel('issue')->getBlockIssues($this->session->project, $this->params->type, $this->viewType == 'json' ? 0 : (int)$this->params->count, $this->params->orderBy);
}
/**
* Print scrum risk block.
*
* @access public
* @return void
*/
public function printScrumRiskBlock()
{
$uri = $this->app->tab == 'my' ? $this->createLink('my', 'index') : $this->server->http_referer;
$this->session->set('riskList', $uri, 'project');
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->risks = $this->loadModel('risk')->getBlockRisks($this->session->project, $this->params->type, $this->viewType == 'json' ? 0 : (int)$this->params->count, $this->params->orderBy);
}
/**
* Print sprint block.
*
-1
View File
@@ -567,7 +567,6 @@ $lang->block->flowchart['admin'] = array('Administrator', 'Abteilung erstellen
if($config->systemMode == 'ALM') $lang->block->flowchart['program'] = array('Program Owner', 'Create Program', 'Link Product', "Create Project", "Budgeting and planning", 'Add Stakeholder');
$lang->block->flowchart['product'] = array($lang->productCommon . ' Besitzer', $lang->productCommon . ' erstellen', 'Module pflegen', 'Pläne pflegen', 'Storys pflegen', 'Release erstellen');
$lang->block->flowchart['project'] = array('Project Manager', 'Add projects and ' . $lang->executionCommon . 's', 'Maintain Teams', 'Link Stories', 'Create Tasks', 'Track');
$lang->block->flowchart['project'] = array('Project Manager', 'Add projects and ' . $lang->executionCommon . 's', 'Maintain Teams', 'Link Stories', 'Create Tasks', 'Track');
$lang->block->flowchart['dev'] = array('Entwickler', 'Aufgabe/Bugs anfordern', 'Update Status', 'Aufgaben/Bugs abschließen');
$lang->block->flowchart['tester'] = array('QS Team', 'Fälle erstellen', 'Fälle ausführen', 'Bug Berichte', 'Bugs überprüfen', 'Bugs schließen');
-1
View File
@@ -567,7 +567,6 @@ $lang->block->flowchart['admin'] = array('Administrator', 'Add Departments', '
if($config->systemMode == 'ALM') $lang->block->flowchart['program'] = array('Program Owner', 'Create Program', 'Link Product', "Create Project", "Budgeting and planning", 'Add Stakeholder');
$lang->block->flowchart['product'] = array($lang->productCommon . ' Owner', 'Add ' . $lang->productCommon, 'Maintain Modules', 'Maintain Plans', 'Maintain Stories', 'Create Releases');
$lang->block->flowchart['project'] = array('Project Manager', 'Add projects and ' . $lang->executionCommon . 's', 'Maintain Teams', 'Link Stories', 'Create Tasks', 'Track');
$lang->block->flowchart['project'] = array('Project Manager', 'Add ' . $lang->executionCommon . 's', 'Maintain Teams', 'Link Stories', 'Create Tasks', 'Track');
$lang->block->flowchart['dev'] = array('Dev Team', 'Claim Tasks/Bugs', 'Design', 'Update Status', 'Finish Tasks/Bugs', 'Commit Code');
$lang->block->flowchart['tester'] = array('Test Team', 'Write Cases', 'Run Cases', 'Report Bugs', 'Verify Bugs', 'Close Bugs');
-1
View File
@@ -567,7 +567,6 @@ $lang->block->flowchart['admin'] = array('Administrateur', 'Ajoute Compartimen
if($config->systemMode == 'ALM') $lang->block->flowchart['program'] = array('Program Owner', 'Create Program', 'Link Product', "Create Project", "Budgeting and planning", 'Add Stakeholder');
$lang->block->flowchart['product'] = array($lang->productCommon . ' Owner', 'Ajoute ' . $lang->productCommon . '/Modules', 'Ajoute ' . $lang->executionCommon . 's', 'Ajoute Stories', 'Maintient Plans', 'Crée Releases');
$lang->block->flowchart['project'] = array('Project Manager', 'Add projects and ' . $lang->executionCommon . 's', 'Maintain Teams', 'Link Stories', 'Create Tasks', 'Track');
$lang->block->flowchart['project'] = array('Project Manager', 'Add projects and ' . $lang->executionCommon . 's', 'Maintain Teams', 'Link Stories', 'Create Tasks', 'Track');
$lang->block->flowchart['dev'] = array('Développeurs', 'Réclament Tâches/Bugs', 'Effectuent Tâches', 'Corrigent Bugs', 'MàJ Statuts', 'Terminent Tâches/Bugs');
$lang->block->flowchart['tester'] = array('Testeurs', 'Rédigent CasTests', 'Jouent CasTests', 'Détectent Bugs', 'Vérifient Corrections', 'Ferment Bugs');
+45
View File
@@ -750,6 +750,51 @@ class blockModel extends model
return json_encode($params);
}
/**
* Get scrum issue params.
*
* @param string $module
* @access public
* @return void
*/
public function getScrumIssueParams($module = '')
{
$this->app->loadLang('issue');
$params = $this->appendCountParams();
$params->type['name'] = $this->lang->block->type;
$params->type['options'] = $this->lang->issue->labelList;
$params->type['control'] = 'select';
$params->orderBy['name'] = $this->lang->block->orderBy;
$params->orderBy['options'] = $this->lang->block->orderByList->product;
$params->orderBy['control'] = 'select';
return json_encode($params);
}
/**
* Get scrum risk params.
*
* @param string $module▫
* @access public
* @return void
*/
public function getScrumRiskParams($module = '')
{
$this->app->loadLang('risk');
$params = $this->appendCountParams();
$params->type['name'] = $this->lang->block->type;
$params->type['options'] = $this->lang->risk->featureBar['browse'];
$params->type['control'] = 'select';
$params->orderBy['name'] = $this->lang->block->orderBy;
$params->orderBy['options'] = $this->lang->block->orderByList->product;
$params->orderBy['control'] = 'select';
return json_encode($params);
}
/**
* Get execution params.
*
+4
View File
@@ -33,6 +33,7 @@
<div class="tile-amount"><?php echo empty($data['createdCases']) ? 0 : html::a($this->createLink('my', 'contribute', 'mode=testcase&type=openedbyme'), (int)$data['createdCases']);?></div>
</div>
<?php if($this->config->edition == 'max'):?>
<?php if(helper::hasFeature('risk')):?>
<div class="col-xs-4 tile">
<div class="tile-title"><?php echo $lang->block->createdRisks;?></div>
<div class="tile-amount"><?php echo empty($data['createdRisks']) ? 0 : html::a($this->createLink('my', 'contribute', 'mode=risk'), (int)$data['createdRisks']);?></div>
@@ -41,6 +42,8 @@
<div class="tile-title"><?php echo $lang->block->resolvedRisks;?></div>
<div class="tile-amount"><?php echo $data['resolvedRisks'];?></div>
</div>
<?php endif;?>
<?php if(helper::hasFeature('issue')):?>
<div class="col-xs-4 tile">
<div class="tile-title"><?php echo $lang->block->createdIssues;?></div>
<div class="tile-amount"><?php echo empty($data['createdIssues']) ? 0 : html::a($this->createLink('my', 'contribute', 'mode=issue'), (int)$data['createdIssues']);?></div>
@@ -50,6 +53,7 @@
<div class="tile-amount"><?php echo $data['resolvedIssues'];?></div>
</div>
<?php endif;?>
<?php endif;?>
<div class="col-xs-4 tile">
<div class="tile-title"><?php echo $lang->block->createdDocs;?></div>
<div class="tile-amount"><?php echo empty($data['createdDocs']) ? 0 : html::a($this->createLink('my', 'contribute', 'mode=doc&type=openedbyme'), (int)$data['createdDocs']);?></div>
+1 -1
View File
@@ -46,5 +46,5 @@
.block-sm .row-3 .flow-item-1, .block-sm .row-3 .flow-item-3 {width: 25%}
.block-sm .flow-item > div:after {right: -6px;}
.flow-item-display {overflow: hidden; white-space:nowrap; text-overflow: ellipsis;}
.flow-item-display {overflow: hidden; white-space:nowrap; text-overflow: clip;}
</style>
@@ -0,0 +1,50 @@
<?php if(empty($issues)): ?>
<div class='empty-tip'><?php echo $lang->block->emptyTip;?></div>
<?php else:?>
<style>
.block-issues .c-id {width: 55px;}
.block-issues .c-status {width: 80px;}
.block-issues.block-sm .c-status {text-align: center;}
.c-assignedTo {width: 100px; padding:0px !important;text-align:center;}
.c-severity, .c-pri {text-align:center;}
</style>
<div class='panel-body has-table scrollbar-hover'>
<table class='table table-borderless table-hover table-fixed table-fixed-head tablesorter block-issues <?php if(!$longBlock) echo 'block-sm';?>'>
<thead>
<tr>
<th class='c-id'><?php echo $lang->idAB;?></th>
<th class='c-status'><?php echo $lang->issue->type;?></th>
<th class='c-name'> <?php echo $lang->issue->title;?></th>
<?php if($longBlock):?>
<th class='c-status'><?php echo $lang->issue->severity;?></th>
<th class='c-number'><?php echo $lang->issue->pri;?></th>
<th class='c-user'><?php echo $lang->issue->owner;?></th>
<th class='c-assignedTo'><?php echo $lang->issue->assignedTo;?></th>
<?php endif;?>
<th class='c-status'><?php echo $lang->issue->status;?></th>
</tr>
</thead>
<tbody>
<?php foreach($issues as $issue):?>
<?php
$viewLink = $this->createLink('issue', 'view', "issueID={$issue->id}");
?>
<tr>
<td class='c-id-xs'><?php echo sprintf('%03d', $issue->id);?></td>
<td class='c-type'><?php echo zget($lang->issue->typeList, $issue->type);?></td>
<td class='c-name' title='<?php echo $issue->title?>'><?php echo html::a($viewLink, $issue->title);?></td>
<?php if($longBlock):?>
<td class='c-severity'><?php echo zget($lang->issue->severityList, $issue->severity, $issue->severity)?></td>
<td class='c-pri'><?php echo zget($lang->issue->priList, $issue->pri, $issue->pri)?></td>
<td><?php echo zget($users, $issue->owner, $issue->owner)?></td>
<td class='c-assignedTo'><?php echo zget($users, $issue->assignedTo, $issue->assignedTo)?></td>
<?php endif;?>
<td class='c-status'>
<span class="status-issue status-<?php echo $issue->status?>"><?php echo zget($lang->issue->statusList, $issue->status);?></span>
</td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
<?php endif;?>
+58
View File
@@ -0,0 +1,58 @@
<?php if(empty($risks)): ?>
<div class='empty-tip'><?php echo $lang->block->emptyTip;?></div>
<?php else:?>
<style>
.block-risks .c-id {width: 40px;}
.block-risks .c-pri {width: 85px; text-align: center;}
.block-risks .c-strategy, .block-risks .c-status {width: 80px;}
.block-risks .c-user, .block-risks .c-rate, .block-risks .c-category {width: 110px;}
.c-rate, .c-category {text-align:center;}
.c-assignedTo {width: 100px; padding:0px !important;text-align:center;}
.pri-low {color: #000000;}
.pri-middle {color: #FF9900;}
.pri-high {color: #E53333;}
</style>
<div class='panel-body has-table scrollbar-hover'>
<table class='table table-borderless table-hover table-fixed table-fixed-head tablesorter block-risks <?php if(!$longBlock) echo 'block-sm';?>'>
<thead>
<tr>
<th class='c-id'><?php echo $lang->idAB;?></th>
<th class='c-name'><?php echo $lang->risk->name;?></th>
<?php if($longBlock):?>
<th class='c-strategy'> <?php echo $lang->risk->strategy;?></th>
<?php endif;?>
<th class='c-status'><?php echo $lang->risk->status;?></th>
<?php if($longBlock):?>
<th class='c-rate'><?php echo $lang->risk->rate;?></th>
<th class='c-pri'><?php echo $lang->risk->pri;?></th>
<th class='c-assignedTo text-center'><?php echo $lang->risk->assignedTo;?></th>
<th class='c-category'><?php echo $lang->risk->category;?></th>
<?php endif;?>
</tr>
</thead>
<tbody>
<?php foreach($risks as $risk):?>
<?php
$viewLink = $this->createLink('risk', 'view', "riskID={$risk->id}");
?>
<tr>
<td class='c-id-xs'><?php echo sprintf('%03d', $risk->id);?></td>
<td class='c-name' title='<?php echo $risk->name?>'><?php echo html::a($viewLink, $risk->name);?></td>
<?php if($longBlock):?>
<td class='c-strategy'><?php echo zget($lang->risk->strategyList, $risk->strategy, $risk->strategy)?></td>
<?php endif;?>
<td class='c-status'>
<span class="status-risk status-<?php echo $risk->status?>"><?php echo zget($lang->risk->statusList, $risk->status);?></span>
</td>
<?php if($longBlock):?>
<td class='c-rate'><?php echo $risk->rate?></td>
<td class='c-pri'><?php echo "<span class='pri-{$risk->pri}'>" . zget($lang->risk->priList, $risk->pri) . "</span>";?></td>
<td class='c-assignedTo'><?php echo zget($users, $risk->assignedTo, $risk->assignedTo)?></td>
<td class='c-category'><?php echo zget($lang->risk->categoryList, $risk->category, $risk->category)?></td>
<?php endif;?>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
<?php endif;?>
@@ -124,7 +124,7 @@
{
plan.progress = !plan.tasks.length ? 0 : plan.progress / plan.tasks.length;
var $plan = $('<div class="gantt-plan"></div>');
$plan.append('<div class="strong" title="' + plan.text + '">' + plan.text + '</div>');
$plan.append('<div class="strong" title="' + plan.name + '">' + plan.text + '</div>');
$plans.append($plan);
var $bar = $('<div class="gantt-bar"></div>');
+1 -1
View File
@@ -211,7 +211,7 @@ class branch extends control
public function ajaxGetDropMenu($productID, $branch, $module, $method, $extra = '')
{
parse_str($extra, $output);
$isQaModule = (strpos(',project,execution,', ",{$this->app->tab},") !== false and strpos(',bug,testcase,', ",$method,") !== false and !empty($productID)) ? true : false;
$isQaModule = (strpos(',project,execution,', ",{$this->app->tab},") !== false and strpos(',bug,testcase,groupCase,zeroCase,', ",$method,") !== false and !empty($productID)) ? true : false;
$param = $isQaModule ? $extra : 0;
$param = isset($output['projectID']) ? $output['projectID'] : $param;
$branches = $this->branch->getPairs($productID, 'all', $param);
+15 -1
View File
@@ -126,7 +126,7 @@ class branchModel extends model
if($executionID)
{
if(isset($executionBranches['0'])) $branches = array('0' => $this->lang->branch->main) + $branches;
$branches = array('all' => $this->lang->branch->all, '0' => $this->lang->branch->main) + $branches;
return $branches;
}
@@ -782,4 +782,18 @@ class branchModel extends model
return $targetBranch;
}
/**
* Judge an action is clickable or not..
*
* @param object $branch
* @param string $action
* @static
* @access public
* @return bool
*/
public static function isClickable($branch, $action)
{
return true;
}
}
+29 -12
View File
@@ -227,7 +227,7 @@ class bug extends control
$this->view->product = $product;
$this->view->projectProducts = $this->product->getProducts($this->projectID);
$this->view->productName = $productName;
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, $branch);
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'withreleased');
$this->view->modules = $this->tree->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0, $branch);
$this->view->moduleTree = $moduleTree;
$this->view->moduleName = $moduleID ? $this->tree->getById($moduleID)->name : $this->lang->tree->all;
@@ -286,6 +286,9 @@ class bug extends control
}
}
$project = $this->loadModel('project')->getByShadowProduct($productID);
if(!$project->multiple) unset($this->lang->bug->report->charts['bugsPerExecution']);
$this->qa->setMenu($this->products, $productID, $branchID);
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->bug->common . $this->lang->colon . $this->lang->bug->reportChart;
$this->view->position[] = html::a($this->createLink('bug', 'browse', "productID=$productID"), $this->products[$productID]);
@@ -930,7 +933,7 @@ class bug extends control
$this->view->branchName = $product->type == 'normal' ? '' : zget($branches, $bug->branch, '');
$this->view->users = $this->user->getPairs('noletter');
$this->view->actions = $this->action->getList('bug', $bugID);
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, 'all', '');
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, 'all', 'withreleased');
$this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('bug', $bugID);
$this->view->product = $product;
$this->view->linkCommits = $this->loadModel('repo')->getCommitsByObject($bugID, 'bug');
@@ -1077,7 +1080,7 @@ class bug extends control
$this->view->position[] = $this->lang->bug->edit;
/* Assign. */
$allBuilds = $this->loadModel('build')->getBuildPairs($productID, 'all', 'noempty');
$allBuilds = $this->loadModel('build')->getBuildPairs($productID, 'all', 'noempty,withreleased');
if($executionID)
{
$openedBuilds = $this->build->getBuildPairs($productID, $bug->branch, 'noempty,noterminate,nodone,withbranch', $executionID, 'execution');
@@ -1241,8 +1244,12 @@ class bug extends control
$branchProduct = $product->type == 'normal' ? false : true;
/* Set plans. */
$plans = $this->loadModel('productplan')->getPairs($productID, $branch, '', true);
$plans = array('' => '', 'ditto' => $this->lang->bug->ditto) + $plans;
foreach($bugs as $bug)
{
$plans = $this->loadModel('productplan')->getPairs($productID, $bug->branch, '', true);
$plans = array('' => '', 'ditto' => $this->lang->bug->ditto) + $plans;
$bug->plans = $plans;
}
/* Set branches and modules. */
$branches = 0;
@@ -1927,7 +1934,7 @@ class bug extends control
$this->view->bug = $bug;
$this->view->users = $this->user->getPairs('noclosed', $bug->resolvedBy);
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, $bug->branch, 'noempty');
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, $bug->branch, 'noempty', 0, 'execution', $bug->openedBuild);
$this->view->actions = $this->action->getList('bug', $bugID);
$this->display();
@@ -2042,7 +2049,11 @@ class bug extends control
if(!$project->hasProduct)
{
unset($this->config->bug->search['fields']['product']);
if($project->model != 'scrum') unset($this->config->bug->search['fields']['plan']);
if(!$project->multiple)
{
unset($this->config->bug->search['fields']['execution']);
unset($this->config->bug->search['fields']['plan']);
}
}
}
@@ -2332,8 +2343,8 @@ class bug extends control
{
if($_POST)
{
$this->loadModel('port');
$this->session->set('bugPortParams', array('productID' => $productID, 'executionID' => $executionID, 'branch' => 'all'));
$this->loadModel('transfer');
$this->session->set('bugTransferParams', array('productID' => $productID, 'executionID' => $executionID, 'branch' => 'all'));
if(!$productID)
{
$this->config->bug->datatable->fieldList['module']['dataSource']['method'] = 'getAllModulePairs';
@@ -2343,7 +2354,7 @@ class bug extends control
$this->config->bug->datatable->fieldList['execution']['dataSource'] = array('module' => 'execution', 'method' => 'getPairs', 'params' => $executionID);
}
$this->port->export('bug');
$this->transfer->export('bug');
$this->fetch('file', 'export2' . $_POST['fileType'], $_POST);
}
$product = $this->loadModel('product')->getByID($productID);
@@ -2351,6 +2362,8 @@ class bug extends control
if($this->app->tab == 'project' or $this->app->tab == 'execution')
{
$execution = $this->loadModel('execution')->getByID($executionID);
if(empty($execution->multiple)) $this->config->bug->exportFields = str_replace('execution,', '', $this->config->bug->exportFields);
if($product->shadow) $this->config->bug->exportFields = str_replace('product,', '', $this->config->bug->exportFields);
}
@@ -2423,6 +2436,12 @@ class bug extends control
$products = array();
if(!empty($extra)) $products = $this->product->getProducts($extra, 'all', 'program desc, line desc, ');
if($this->config->systemMode == 'ALM')
{
$this->view->programs = $this->loadModel('program')->getPairs(true);
$this->view->lines = $this->product->getLinePairs();
}
$this->view->link = $this->product->getProductLink($module, $method, $extra);
$this->view->productID = $productID;
$this->view->module = $module;
@@ -2430,8 +2449,6 @@ class bug extends control
$this->view->extra = $extra;
$this->view->products = $products;
$this->view->projectID = $this->session->project;
$this->view->programs = $this->loadModel('program')->getPairs(true);
$this->view->lines = $this->product->getLinePairs();
$this->display();
}
+2
View File
@@ -16,6 +16,8 @@ $(function()
saveCustomFields('batchCreateFields', 10, $titleCol, 150);
return false;
});
$('#dropMenu').css('z-index', 9999);
})
/**
+17 -5
View File
@@ -293,14 +293,15 @@ function loadProductStories(productID)
*/
function loadProductProjects(productID)
{
required = $('#project_chosen').hasClass('required');
branch = $('#branch').val();
if(typeof(branch) == 'undefined') branch = 0;
link = createLink('product', 'ajaxGetProjects', 'productID=' + productID + '&branch=' + branch + '&projectID=' + oldProjectID);
$('#projectBox').load(link, function()
{
$(this).find('select').chosen();
var projectID = $('#project').find("option:selected").val();
if(required) $(this).find('#project_chosen').addClass('required');
loadProductExecutions(productID, projectID);
});
}
@@ -587,13 +588,13 @@ function loadProjectBuilds(projectID)
function loadExecutionBuilds(executionID, num)
{
if(typeof(num) == 'undefined') num = '';
var branch = $('#branch' + num).val();
if(typeof(branch) == 'undefined') var branch = 0;
var branch = $('#branch' + num).val();
var oldOpenedBuild = $('#openedBuild' + num).val() ? $('#openedBuild' + num).val() : 0;
var productID = $('#product' + num).val();
if(typeof(branch) == 'undefined') var branch = 0;
if(typeof(productID) == 'undefined') var productID = 0;
if(page == 'create')
{
link = createLink('build', 'ajaxGetExecutionBuilds', 'executionID=' + executionID + '&productID=' + productID + '&varName=openedBuild&build=' + oldOpenedBuild + "&branch=" + branch + "&index=0&needCreate=true");
@@ -882,9 +883,20 @@ function setBranchRelated(branchID, productID, num)
{
planID = $('#plans' + num).val();
planLink = createLink('product', 'ajaxGetPlans', 'productID=' + productID + '&branch=' + branchID + '&planID=' + planID + '&fieldID=' + num + '&needCreate=false&expired=&param=skipParent');
$.ajaxSettings.async = false;
$('#plans' + num).parent('td').load(planLink, function()
{
$('#plans' + num).chosen();
var firstBugID = $('.table-form tbody').first('tr').find('input[id^=bugIDList]').val();
if(num == firstBugID)
{
$('#plans' + firstBugID).find('option').each(function()
{
if($(this).val() == 'ditto') $(this).remove();
$('#plans' + firstBugID).trigger('chosen:updated');
});
}
});
$.ajaxSettings.async = true;
}
}
+10 -2
View File
@@ -23,7 +23,15 @@ function loadProductExecutions(productID, projectID)
$('#executionBox').load(link, function()
{
$(this).find('select').chosen();
$select = $(this).find('select');
$tr = $(this).closest('tr');
$tr.removeClass('hidden');
if($select.data('multiple') == 0)
{
$tr.addClass('hidden');
$select.find('option:last').prop('selected', true);
}
$select.chosen();
});
}
@@ -37,7 +45,7 @@ $('#toTaskButton').on('click', function()
{
$('#cancelButton').click();
link = createLink('task', 'create', 'executionID=' + executionID + '&storyID=0&moduleID=0&taskID=0&todoID=0&extra=projectID=' + projectID + '&bugID=' + bugID);
window.parent.$.apps.open(link, 'execution');
window.parent.$.apps.open(link, $('#execution').data('multiple') == 0 ? 'project' : 'execution');
}
else if(projectID == 0)
{
+110 -56
View File
@@ -728,6 +728,7 @@ class bugModel extends model
->setIF($this->post->assignedTo == '' and $oldBug->status == 'closed', 'assignedTo', 'closed')
->setIF($this->post->resolution == '' and $this->post->resolvedDate =='', 'status', 'active')
->setIF($this->post->resolution != '', 'confirmed', 1)
->setIF($this->post->resolution != '' and $this->post->resolution != 'duplicate', 'duplicateBug', 0)
->setIF($this->post->story != false and $this->post->story != $oldBug->story, 'storyVersion', $this->loadModel('story')->getVersion($this->post->story))
->setIF(!$this->post->linkBug, 'linkBug', '')
->setIF($this->post->case === '', 'case', 0)
@@ -839,8 +840,9 @@ class bugModel extends model
{
$oldBug = $oldBugs[$bugID];
$os = array_filter($data->os[$bugID]);
$browsers = array_filter($data->browsers[$bugID]);
$os = array_filter($data->os[$bugID]);
$browsers = array_filter($data->browsers[$bugID]);
$duplicateBug = $data->duplicateBugs[$bugID] ? $data->duplicateBugs[$bugID] : $oldBug->duplicateBug;
$bug = new stdclass();
$bug->id = $bugID;
@@ -861,7 +863,7 @@ class bugModel extends model
$bug->os = implode(',', $os);
$bug->browser = implode(',', $browsers);
$bug->resolution = $data->resolutions[$bugID];
$bug->duplicateBug = $data->duplicateBugs[$bugID] ? $data->duplicateBugs[$bugID] : $oldBug->duplicateBug;
$bug->duplicateBug = ($bug->resolution != '' and $bug->resolution != 'duplicate') ? 0 : $duplicateBug;
if($bug->assignedTo != $oldBug->assignedTo) $bug->assignedDate = $now;
if($bug->resolution != '') $bug->confirmed = 1;
@@ -1869,7 +1871,7 @@ class bugModel extends model
->where('t1.deleted')->eq(0)
->beginIF(empty($build))->andWhere('t1.project')->eq($projectID)->fi()
->beginIF(!empty($productID))->andWhere('t1.product')->eq($productID)->fi()
->beginIF(!empty($productID))->andWhere('t1.branch')->eq($branchID)->fi()
->beginIF(!empty($productID) and $branchID != 'all')->andWhere('t1.branch')->eq($branchID)->fi()
->beginIF($type == 'unresolved')->andWhere('t1.status')->eq('active')->fi()
->beginIF($type == 'noclosed')->andWhere('t1.status')->ne('closed')->fi()
->beginIF($type == 'assignedtome')->andWhere('t1.assignedTo')->eq($this->app->user->account)->fi()
@@ -1888,19 +1890,19 @@ class bugModel extends model
/**
* Get bugs of a execution.
*
* @param int $executionID
* @param int $productID
* @param int $branchID
* @param int $build
* @param string $type
* @param int $param
* @param string $orderBy
* @param string $excludeBugs
* @param object $pager
* @param int $executionID
* @param int $productID
* @param int $branchID
* @param string|array $builds
* @param string $type
* @param int $param
* @param string $orderBy
* @param string $excludeBugs
* @param object $pager
* @access public
* @return array
*/
public function getExecutionBugs($executionID, $productID = 0, $branchID = 'all', $build = 0, $type = '', $param = 0, $orderBy = 'id_desc', $excludeBugs = '', $pager = null)
public function getExecutionBugs($executionID, $productID = 0, $branchID = 'all', $builds = 0, $type = '', $param = 0, $orderBy = 'id_desc', $excludeBugs = '', $pager = null)
{
$type = strtolower($type);
if(strpos($orderBy, 'pri_') !== false) $orderBy = str_replace('pri_', 'priOrder_', $orderBy);
@@ -1935,15 +1937,28 @@ class bugModel extends model
}
else
{
$condition = '';
if($builds)
{
if(!is_array($builds)) $builds = explode(',', $builds);
$conditions = array();
foreach($builds as $build)
{
if($build) $conditions[] = "FIND_IN_SET('$build', t1.openedBuild)";
}
$condition = join(' OR ', $conditions);
$condition = "($condition)";
}
$bugs = $this->dao->select("t1.*, IF(t1.`pri` = 0, {$this->config->maxPriValue}, t1.`pri`) as priOrder, IF(t1.`severity` = 0, {$this->config->maxPriValue}, t1.`severity`) as severityOrder")->from(TABLE_BUG)->alias('t1')
->leftJoin(TABLE_MODULE)->alias('t2')->on('t1.module=t2.id')
->where('t1.deleted')->eq(0)
->beginIF(!empty($productID) and $branchID !== 'all')->andWhere('t1.branch')->eq($branchID)->fi()
->beginIF(empty($build))->andWhere('t1.execution')->eq($executionID)->fi()
->beginIF(empty($builds))->andWhere('t1.execution')->eq($executionID)->fi()
->beginIF(!empty($productID))->andWhere('t1.product')->eq($productID)->fi()
->beginIF($type == 'unresolved')->andWhere('t1.status')->eq('active')->fi()
->beginIF($type == 'noclosed')->andWhere('t1.status')->ne('closed')->fi()
->beginIF($build)->andWhere("CONCAT(',', t1.openedBuild, ',') like '%,$build,%'")->fi()
->beginIF($condition)->andWhere("$condition")->fi()
->beginIF(!empty($param))->andWhere('t2.path')->like("%,$param,%")->andWhere('t2.deleted')->eq(0)->fi()
->beginIF($excludeBugs)->andWhere('t1.id')->notIN($excludeBugs)->fi()
->orderBy($orderBy)
@@ -1959,35 +1974,43 @@ class bugModel extends model
/**
* Get product left bugs.
*
* @param int $build
* @param int $productID
* @param int $branch
* @param string $linkedBugs
* @param object $pager
* @param int|string $buildIdList
* @param int $productID
* @param int $branch
* @param string $linkedBugs
* @param object $pager
* @access public
* @return array
*/
public function getProductLeftBugs($build, $productID, $branch = '', $linkedBugs = '', $pager = null)
public function getProductLeftBugs($buildIdList, $productID, $branch = '', $linkedBugs = '', $pager = null)
{
$build = $this->dao->select('*')->from(TABLE_BUILD)->where('id')->eq($build)->fetch();
if(empty($build->execution)) return array();
$executionIdList = $this->getLinkedExecutionByIdList($buildIdList);
if(empty($executionIdList)) return array();
$executions = $this->dao->select('*')->from(TABLE_EXECUTION)->where('id')->in($executionIdList)->fetchAll();
$minBegin = '';
$maxEnd = '';
foreach($executions as $execution)
{
if(empty($minBegin) or $minBegin > $execution->begin) $minBegin = $execution->begin;
if(empty($maxEnd) or $maxEnd < $execution->end) $maxEnd = $execution->end;
}
$execution = $this->dao->select('*')->from(TABLE_EXECUTION)->where('id')->eq($build->execution)->fetch();
$beforeBuilds = $this->dao->select('t1.id')->from(TABLE_BUILD)->alias('t1')
->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.execution=t2.id')
->where('t1.product')->eq($productID)
->andWhere('t2.status')->ne('done')
->andWhere('t2.deleted')->eq(0)
->andWhere('t1.deleted')->eq(0)
->andWhere('t1.date')->lt($execution->begin)
->andWhere('t1.date')->lt($minBegin)
->fetchPairs('id', 'id');
$bugs = $this->dao->select('*')->from(TABLE_BUG)->where('deleted')->eq(0)
->andWhere('product')->eq($productID)
->andWhere('toStory')->eq(0)
->andWhere('openedDate')->ge($execution->begin)
->andWhere('openedDate')->le($execution->end)
->andWhere("(status = 'active' OR resolvedDate > '{$execution->end}')")
->andWhere('openedDate')->ge($minBegin)
->andWhere('openedDate')->le($maxEnd)
->andWhere("(status = 'active' OR resolvedDate > '{$maxEnd}')")
->andWhere('openedBuild')->notin($beforeBuilds)
->beginIF($linkedBugs)->andWhere('id')->notIN($linkedBugs)->fi()
->beginIF($branch !== '')->andWhere('branch')->in("0,$branch")->fi()
@@ -2060,31 +2083,74 @@ class bugModel extends model
/**
* Get bugs according to buildID and productID.
*
* @param int $buildID
* @param int $productID
* @param int|string $buildIdList
* @param int $productID
* @param string $branch
* @param string $linkedBugs
* @param object $pager
* @access public
* @return object
* @return array
*/
public function getReleaseBugs($buildID, $productID, $branch = 0, $linkedBugs = '', $pager = null)
public function getReleaseBugs($buildIdList, $productID, $branch = 0, $linkedBugs = '', $pager = null)
{
$execution = $this->dao->select('t1.id,t1.begin')->from(TABLE_EXECUTION)->alias('t1')
->leftJoin(TABLE_BUILD)->alias('t2')->on('t1.id = t2.execution')
->where('t2.id')->eq($buildID)
->fetch();
$executionIdList = $this->getLinkedExecutionByIdList($buildIdList);
if(empty($executionIdList)) return array();
$executions = $this->dao->select('id,type,begin')->from(TABLE_EXECUTION)->where('id')->in($executionIdList)->fetchAll('id');
$condition = 'execution NOT ' . helper::dbIN($executionIdList);
$minBegin = '';
foreach($executions as $execution)
{
if(empty($minBegin) or $minBegin > $execution->begin) $minBegin = $execution->begin;
$condition .= " OR (`execution` = '{$execution->id}' AND openedDate < '{$execution->begin}')";
}
$bugs = $this->dao->select('*')->from(TABLE_BUG)
->where('resolvedDate')->ge($execution->begin)
->where('resolvedDate')->ge($minBegin)
->andWhere('resolution')->ne('postponed')
->andWhere('product')->eq($productID)
->beginIF($linkedBugs)->andWhere('id')->notIN($linkedBugs)->fi()
->beginIF($branch)->andWhere('branch')->in("0,$branch")->fi()
->andWhere("(execution != '$execution->id' OR (execution = '$execution->id' and openedDate < '$execution->begin'))")
->andWhere("($condition)")
->andWhere('deleted')->eq(0)
->orderBy('openedDate ASC')
->page($pager)
->fetchAll();
->fetchAll('id');
return $bugs;
}
/**
* Get linked execution by build id list.
*
* @param string $buildIdList
* @access public
* @return array
*/
public function getLinkedExecutionByIdList($buildIdList)
{
$builds = $this->dao->select('id,execution,builds')->from(TABLE_BUILD)->where('id')->in($buildIdList)->fetchAll('id');
$executionIdList = array();
$linkedBuildIdList = array();
foreach($builds as $build)
{
if($build->builds) $linkedBuildIdList = array_merge($linkedBuildIdList, explode(',', $build->builds));
if(empty($build->execution)) continue;
$executionIdList[$build->execution] = $build->execution;
}
if($linkedBuildIdList)
{
$linkedBuilds = $this->dao->select('*')->from(TABLE_BUILD)->where('id')->in(array_unique($linkedBuildIdList))->fetchAll('id');
foreach($linkedBuilds as $build)
{
if(empty($build->execution)) continue;
$executionIdList[$build->execution] = $build->execution;
}
}
return $executionIdList;
}
/**
* Get bugs of a story.
*
@@ -2181,8 +2247,8 @@ class bugModel extends model
if(!empty($stepResults))
{
$bugStep = '';
$bugResult = '';
$bugStep = '';
$bugResult = isset($stepResults[0]) ? $stepResults[0]['real'] : '';
$bugExpect = '';
foreach($steps as $stepId)
{
@@ -3426,19 +3492,7 @@ class bugModel extends model
echo helper::isZeroDate($bug->openedDate) ? '' : substr($bug->openedDate, 5, 11);
break;
case 'openedBuild':
$builds = array_flip($builds);
foreach(explode(',', $bug->openedBuild) as $build)
{
$buildID = zget($builds, $build, '');
if($buildID == 'trunk')
{
echo $build . ' ';
}
elseif($buildID and common::hasPriv('build', 'view'))
{
echo html::a(helper::createLink('build', 'view', "buildID=$buildID"), $build, '', "title='$bug->openedBuild'") . ' ';
}
}
echo $bug->openedBuild;
break;
case 'assignedTo':
$this->printAssignedHtml($bug, $users);
@@ -3648,7 +3702,7 @@ class bugModel extends model
public function getRelatedObjects($object, $pairs = '')
{
/* Get bugs. */
$bugs = $this->loadModel('port')->getQueryDatas('bug');
$bugs = $this->loadModel('transfer')->getQueryDatas('bug');
/* Get related objects id lists. */
$relatedObjectIdList = array();
+3 -3
View File
@@ -17,13 +17,13 @@ foreach($products as $product)
}
$productsPinYin = common::convert2Pinyin($productNames);
$linkHtml = $this->product->setParamsForLink($module, $link, $projectID, 0);
$productsHtml = count($products) > 1 ? html::a($linkHtml, $this->lang->bug->allProduct, '', "class='text-primary' title='{$this->lang->bug->allProduct}' data-key='" . zget($productsPinYin, $this->lang->bug->allProduct, '') . "' data-app='{$this->app->tab}'") : '';
$productsHtml = (count($products) > 1 and strpos(',zeroCase,browseUnits,groupCase,', ",$method,") === false) ? html::a($linkHtml, $this->lang->bug->allProduct, '', "class='text-primary' title='{$this->lang->bug->allProduct}' data-key='" . zget($productsPinYin, $this->lang->bug->allProduct, '') . "' data-app='{$this->app->tab}'") : '';
foreach($products as $product)
{
$selected = $product->id == $productID ? 'selected' : '';
$productName = $product->program ? zget($programs, $product->program, '') . '/' : '';
$productName .= $product->line ? zget($lines, $product->line, '') . '/' . $product->name : $product->name;
$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}'");
+1 -1
View File
@@ -103,7 +103,7 @@
</td>
<?php endif;?>
<td><?php echo html::select("modules[$bugID]", isset($modules[$bug->product][$bug->branch]) ? $modules[$bug->product][$bug->branch] : array(0 => '/'), $bug->module, "class='form-control picker-select' data-drop-width='auto'");?></td>
<td class='<?php echo zget($visibleFields, 'productplan', ' hidden')?>' style='overflow:visible'><?php echo html::select("plans[$bugID]", $plans, $bug->plan, "class='form-control picker-select' data-drop-width='auto'");?></td>
<td class='<?php echo zget($visibleFields, 'productplan', ' hidden')?>' style='overflow:visible'><?php echo html::select("plans[$bugID]", $bug->plans, $bug->plan, "class='form-control picker-select' data-drop-width='auto'");?></td>
<?php
$assignedToList = array();
if($app->tab == 'project' or $app->tab == 'execution')
+1 -1
View File
@@ -123,7 +123,7 @@ if($this->app->tab == 'project') js::set('objectID', $bug->project);
</div>
</td>
</tr>
<tr class='<?php if($product->shadow and zget($project, 'model') != 'scrum') echo 'hide'?>'>
<tr class='<?php if(!($product->shadow and zget($project, 'model') == 'scrum' and $project->multiple)) echo 'hide'?>'>
<th><?php echo $lang->bug->productplan;?></th>
<td>
<span id="planIdBox"><?php echo html::select('plan', $plans, $bug->plan, "class='form-control chosen'");?></span>
+3 -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 zget($project, 'model') != 'scrum') echo 'hide'?>'>
<tr valign='middle' class='<?php if(!($product->shadow and zget($project, 'model') == 'scrum' and $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>
@@ -422,6 +422,7 @@
<td><?php echo html::a($this->createLink('task', 'view', "taskID=$bug->toTask", '', true), "#$bug->toTask $bug->toTaskTitle", '', "class='iframe' data-width='80%'");?></td>
</tr>
<?php endif;?>
<?php if(helper::hasFeature('devops')):?>
<tr>
<th><?php echo $lang->bug->linkMR;?></th>
<td>
@@ -448,6 +449,7 @@
?>
</td>
</tr>
<?php endif;?>
</tbody>
</table>
</div>
+2 -2
View File
@@ -2,8 +2,8 @@
$config->build = new stdclass();
$config->build->create = new stdclass();
$config->build->edit = new stdclass();
$config->build->create->requiredFields = 'product,execution,name,builder,date';
$config->build->edit->requiredFields = 'product,execution,name,builder,date';
$config->build->create->requiredFields = 'product,name,builder,date';
$config->build->edit->requiredFields = 'product,name,builder,date';
$config->build->editor = new stdclass();
$config->build->editor->create = array('id' => 'desc', 'tools' => 'simpleTools');
+116 -82
View File
@@ -49,13 +49,12 @@ class build extends control
if(!empty($_POST))
{
$executionID = empty($executionID) ? $this->post->execution : $executionID;
if(empty($executionID)) dao::$errors['execution'] = $this->lang->build->emptyExecution;
if(empty($executionID) && $this->app->tab == 'execution') dao::$errors['execution'] = $this->lang->build->emptyExecution;
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
if(defined('TUTORIAL')) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true)); // Fix bug #21095.
$buildID = $this->build->create($executionID);
$buildID = $this->build->create();
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
$this->loadModel('action')->create('build', $buildID, 'opened');
@@ -67,40 +66,40 @@ class build extends control
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('build', 'view', "buildID=$buildID") . "#app={$this->app->tab}"));
}
$this->loadModel('product');
$this->loadModel('project');
/* Set menu. */
$executions = array();
if($this->app->tab == 'project')
{
$this->loadModel('project')->setMenu($projectID);
$executions = $this->execution->getPairs($projectID, 'all', 'stagefilter');
$executionID = empty($executionID) ? key($executions) : $executionID;
$this->project->setMenu($projectID);
$executions = $this->execution->getPairs($projectID, 'all', 'stagefilter');
$executionID = empty($executionID) ? key($executions) : $executionID;
$productGroups = $executionID ? $this->product->getProducts($executionID) : array();
$branchGroups = $executionID ? $this->project->getBranchesByProject($executionID) : array();
$this->session->set('project', $projectID);
}
elseif($this->app->tab == 'execution')
{
$execution = $this->execution->getByID($executionID);
$executions = $this->execution->getPairs($execution->project);
$projectID = $execution->project;
$execution = $this->execution->getByID($executionID);
$executions = $this->execution->getPairs($execution->project);
$projectID = $execution->project;
$productGroups = $this->product->getProducts($executionID);
$branchGroups = $this->project->getBranchesByProject($executionID);
$this->execution->setMenu($executionID);
$this->session->set('project', $execution->project);
}
elseif($this->app->tab == 'qa')
{
$execution = $this->execution->getByID($executionID);
$projectID = $execution ? $execution->project : 0;
$executions = $this->execution->getPairs($projectID);
$execution = $this->execution->getByID($executionID);
$projectID = $execution ? $execution->project : 0;
$executions = $this->execution->getPairs($projectID);
$productGroups = $this->product->getProducts($executionID);
$branchGroups = $this->project->getBranchesByProject($executionID);
}
$this->commonActions($projectID);
$executionList = empty($executions) ? array() : $this->execution->getByIdList(array_keys($executions));
foreach($executionList as $execution)
{
if($execution->lifetime == 'ops') unset($executions[$execution->id]);
}
$productGroups = $this->loadModel('product')->getProducts($executionID);
$productID = $productID ? $productID : key($productGroups);
$branchGroups = $this->loadModel('project')->getBranchesByProject($executionID);
$branchPairs = $this->loadModel('branch')->getPairs($productID, 'active');
$branches = array();
$products = array();
@@ -125,7 +124,7 @@ class build extends control
$this->view->products = $products;
$this->view->projectID = $projectID;
$this->view->executions = $executions;
$this->view->lastBuild = $this->build->getLast($executionID);
$this->view->lastBuild = $this->build->getLast($executionID, $projectID);
$this->view->productGroups = $productGroups;
$this->view->users = $this->user->getPairs('nodeleted|noclosed');
$this->display();
@@ -157,7 +156,7 @@ class build extends control
$message = $this->executeHooks($buildID);
if($message) $this->lang->saveSuccess = $message;
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('view', "buildID=$buildID")));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('build', 'view', "buildID=$buildID") . "#app={$this->app->tab}"));
}
$this->loadModel('execution');
@@ -165,30 +164,26 @@ class build extends control
$build = $this->build->getById((int)$buildID);
/* Set menu. */
if($this->app->tab == 'project')
{
$this->loadModel('project')->setMenu($build->project);
}
elseif($this->app->tab == 'execution')
{
$this->execution->setMenu($build->execution);
}
if($this->app->tab == 'project') $this->loadModel('project')->setMenu($build->project);
if($this->app->tab == 'execution') $this->execution->setMenu($build->execution);
/* Get stories and bugs. */
$orderBy = 'status_asc, stage_asc, id_desc';
/* Assign. */
$execution = $this->execution->getByID($build->execution);
if(empty($execution))
$builds = array();
if($build->execution)
{
$execution = new stdclass();
$execution->name = '';
$productGroups = $this->product->getProducts($build->execution);
$branches = $this->loadModel('branch')->getList($build->product, $build->execution, 'all');
}
else
{
$productGroups = $this->product->getProducts($build->project);
$branches = $this->loadModel('branch')->getList($build->product, $build->project, 'all');
$builds = $this->build->getBuildPairs($build->product, $build->branch, 'noempty,notrunk,singled,separate', $build->project, 'project', $build->builds, false);
}
$executions = $this->product->getExecutionPairsByProduct($build->product, $build->branch, 'id_desc', $this->session->project, 'stagefilter');
if(!isset($executions[$build->execution])) $executions[$build->execution] = $execution->name;
$productGroups = $this->product->getProducts($build->execution);
/* Get stories and bugs. */
$orderBy = 'status_asc, stage_asc, id_desc';
if(!isset($productGroups[$build->product]))
{
@@ -198,7 +193,6 @@ class build extends control
}
/* Display status of branch. */
$branches = $this->loadModel('branch')->getList($build->product, $build->execution, 'all');
$branchTagOption = array();
foreach($branches as $branchInfo)
{
@@ -210,19 +204,18 @@ class build extends control
$this->commonActions($build->project);
$this->view->title = $execution->name . $this->lang->colon . $this->lang->build->edit;
$this->view->position[] = html::a($this->createLink('execution', 'task', "executionID=$build->execution"), $execution->name);
$this->view->title = $build->name . $this->lang->colon . $this->lang->build->edit;
$this->view->position[] = $this->lang->build->edit;
$this->view->product = isset($productGroups[$build->product]) ? $productGroups[$build->product] : '';
$this->view->branchTagOption = $branchTagOption;
$this->view->executions = $executions;
$this->view->orderBy = $orderBy;
$this->view->productGroups = $productGroups;
$this->view->products = $products;
$this->view->users = $this->loadModel('user')->getPairs('noletter', $build->builder);
$this->view->build = $build;
$this->view->testtaskID = $this->dao->select('id')->from(TABLE_TESTTASK)->where('build')->eq($build->id)->andWhere('deleted')->eq(0)->fetch('id');
$this->view->executions = $executions;
$this->view->productGroups = $productGroups;
$this->view->products = $products;
$this->view->users = $this->loadModel('user')->getPairs('noletter', $build->builder);
$this->view->build = $build;
$this->view->builds = $builds;
$this->view->testtaskID = $this->dao->select('id')->from(TABLE_TESTTASK)->where('build')->eq($build->id)->andWhere('deleted')->eq(0)->fetch('id');
$this->display();
}
@@ -267,7 +260,7 @@ class build extends control
$bugPager = new pager($type == 'bug' ? $recTotal : 0, $recPerPage, $type == 'bug' ? $pageID : 1);
$bugs = $this->dao->select('*')->from(TABLE_BUG)
->where('id')->in($build->bugs)
->where('id')->in($build->allBugs)
->andWhere('deleted')->eq(0)
->beginIF($type == 'bug')->orderBy($sort)->fi()
->page($bugPager)
@@ -276,7 +269,7 @@ class build extends control
/* Get stories and stages. */
$storyPager = new pager($type == 'story' ? $recTotal : 0, $recPerPage, $type == 'story' ? $pageID : 1);
$stories = $this->dao->select("*, IF(`pri` = 0, {$this->config->maxPriValue}, `pri`) as priOrder")->from(TABLE_STORY)
->where('id')->in($build->stories)
->where('id')->in($build->allStories)
->andWhere('deleted')->eq(0)
->beginIF($type == 'story')->orderBy($sort)->fi()
->page($storyPager)
@@ -285,15 +278,18 @@ class build extends control
$stages = $this->dao->select('*')->from(TABLE_STORYSTAGE)->where('story')->in(array_keys($stories))->andWhere('branch')->eq($build->branch)->fetchPairs('story', 'stage');
foreach($stages as $storyID => $stage) $stories[$storyID]->stage = $stage;
/* Set menu. */
if($this->app->tab == 'project')
{
$this->loadModel('project')->setMenu($build->project);
$objectType = 'project';
$objectID = $build->project;
}
elseif($this->app->tab == 'execution')
{
$this->loadModel('execution')->setMenu($build->execution);
$objectType = 'execution';
$objectID = $build->execution;
}
$executions = $this->loadModel('execution')->getPairs($this->session->project, 'all', 'empty');
@@ -305,18 +301,18 @@ class build extends control
$this->view->storyPager = $storyPager;
$generatedBugPager = new pager($type == 'generatedBug' ? $recTotal : 0, $recPerPage, $type == 'generatedBug' ? $pageID : 1);
$this->view->generatedBugs = $this->bug->getExecutionBugs($build->execution, $build->product, 'all', $build->id, $type, $param, $type == 'generatedBug' ? $sort : 'status_desc,id_desc', '', $generatedBugPager);
$this->view->generatedBugs = $this->bug->getExecutionBugs($build->execution, $build->product, 'all', "$build->id,{$build->builds}", $type, $param, $type == 'generatedBug' ? $sort : 'status_desc,id_desc', '', $generatedBugPager);
$this->view->generatedBugPager = $generatedBugPager;
$this->executeHooks($buildID);
$buildIdList = $build->execution ? array() : array($buildID => $buildID);
/* Assign. */
$this->view->canBeChanged = common::canBeChanged('build', $build); // Determines whether an object is editable.
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->build = $build;
$this->view->buildPairs = $this->build->getBuildPairs(0, 'all', 'noempty,notrunk', $build->execution, 'execution', $buildIdList);
$this->view->buildPairs = $this->build->getBuildPairs(0, 'all', 'noempty,notrunk', $objectID, $objectType);
$this->view->builds = $this->build->getByList(array_keys($this->view->buildPairs));
$this->view->executions = $executions;
$this->view->actions = $this->loadModel('action')->getList('build', $buildID);
$this->view->link = $link;
$this->view->param = $param;
@@ -397,21 +393,21 @@ class build extends control
$isJsonView = $this->app->getViewType() == 'json';
if($varName == 'openedBuild' )
{
$params = ($type == 'all') ? 'noempty,withbranch' : 'noempty, noterminate, nodone, withbranch';
$builds = $this->build->getBuildPairs($productID, $branch, $params);
$params = ($type == 'all') ? 'noempty,withbranch' : 'noempty,noterminate,nodone,withbranch';
$builds = $this->build->getBuildPairs($productID, $branch, $params, 0, 'project', $build);
if($isJsonView) return print(json_encode($builds));
return print(html::select($varName . '[]', $builds, $build, 'size=4 class=form-control multiple'));
}
if($varName == 'openedBuilds' )
{
$builds = $this->build->getBuildPairs($productID, $branch, 'noempty');
$builds = $this->build->getBuildPairs($productID, $branch, 'noempty', 0, 'project', $build);
if($isJsonView) return print(json_encode($builds));
return print(html::select($varName . "[$index][]", $builds, $build, 'size=4 class=form-control multiple'));
}
if($varName == 'resolvedBuild')
{
$params = ($type == 'all') ? 'withbranch' : 'noterminate, nodone, withbranch';
$builds = $this->build->getBuildPairs($productID, $branch, $params);
$params = ($type == 'all') ? 'withbranch' : 'noterminate,nodone,withbranch';
$builds = $this->build->getBuildPairs($productID, $branch, $params, 0, 'project', $build);
if($isJsonView) return print(json_encode($builds));
return print(html::select($varName, $builds, $build, "class='form-control'"));
}
@@ -427,17 +423,18 @@ class build extends control
* @param int $index the index of batch create bug.
* @param bool $needCreate if need to append the link of create build
* @param string $type get all builds or some builds belong to normal releases and executions are not done.
* @param string $extra
* @access public
* @return string
*/
public function ajaxGetProjectBuilds($projectID, $productID, $varName, $build = '', $branch = 'all', $index = 0, $needCreate = false, $type = 'normal')
public function ajaxGetProjectBuilds($projectID, $productID, $varName, $build = '', $branch = 'all', $index = 0, $needCreate = false, $type = 'normal', $extra = '')
{
$isJsonView = $this->app->getViewType() == 'json';
if($varName == 'openedBuild')
{
if(empty($projectID)) return $this->ajaxGetProductBuilds($productID, $varName, $build, $branch, $index, $type);
$params = ($type == 'all') ? 'noempty, withbranch' : 'noempty, noterminate, nodone, withbranch';
$params = ($type == 'all') ? 'noempty,withbranch' : 'noempty,noterminate,nodone,withbranch';
$builds = $this->build->getBuildPairs($productID, $branch, $params, $projectID, 'project', $build);
if($isJsonView) return print(json_encode($builds));
return print(html::select($varName . '[]', $builds , '', 'size=4 class=form-control multiple'));
@@ -446,11 +443,17 @@ class build extends control
{
if(empty($projectID)) return $this->ajaxGetProductBuilds($productID, $varName, $build, $branch, $index, $type);
$params = ($type == 'all') ? 'withbranch' : 'noterminate, nodone, withbranch';
$params = ($type == 'all') ? 'withbranch' : 'noterminate,nodone,withbranch';
$builds = $this->build->getBuildPairs($productID, $branch, $params, $projectID, 'project', $build);
if($isJsonView) return print(json_encode($builds));
return print(html::select($varName, $builds, $build, "class='form-control'"));
}
if(empty($projectID)) return $this->ajaxGetProductBuilds($productID, $varName, $build, $branch, $index, $type);
$builds = $this->build->getBuildPairs($productID, $branch, $type, $projectID, 'project', $build, false);
if(strpos($extra, 'multiple') !== false) $varName .= '[]';
if($isJsonView) return print(json_encode($builds));
return print(html::select($varName, $builds, $build, "class='form-control chosen' $extra"));
}
/**
@@ -475,7 +478,7 @@ class build extends control
{
if(empty($executionID)) return $this->ajaxGetProductBuilds($productID, $varName, $build, $branch, $index, $type);
$params = ($type == 'all') ? 'noempty' : 'noempty, noterminate, nodone';
$params = ($type == 'all') ? 'noempty' : 'noempty,noterminate,nodone';
$builds = $this->build->getBuildPairs($productID, $branch, $params, $executionID, 'execution', $build);
if($isJsonView) return print(json_encode($builds));
@@ -486,7 +489,7 @@ class build extends control
{
if(empty($executionID)) return $this->ajaxGetProductBuilds($productID, $varName, $build, $branch, $index, $type);
$builds = $this->build->getBuildPairs($productID, $branch, 'noempty', $executionID, 'execution');
$builds = $this->build->getBuildPairs($productID, $branch, 'noempty', $executionID, 'execution', $build);
if($isJsonView) return print(json_encode($builds));
return print(html::select($varName . "[$index][]", $builds , $build, 'size=4 class=form-control multiple'));
}
@@ -494,7 +497,7 @@ class build extends control
{
if(empty($executionID)) return $this->ajaxGetProductBuilds($productID, $varName, $build, $branch, $index, $type);
$params = ($type == 'all') ? '' : 'noterminate, nodone';
$params = ($type == 'all') ? '' : 'noterminate,nodone';
$builds = $this->build->getBuildPairs($productID, $branch, $params, $executionID, 'execution', $build);
if($isJsonView) return print(json_encode($builds));
return print(html::select($varName, $builds, $build, "class='form-control'"));
@@ -528,6 +531,27 @@ class build extends control
}
}
/**
* Ajax get last build.
*
* @param int $projectID
* @param int $executionID
* @access public
* @return string
*/
public function ajaxGetLastBuild($projectID, $executionID)
{
$lastBuild = $this->build->getLast($executionID, $projectID);
if($lastBuild)
{
echo "<div class='help-block'> &nbsp; " . $this->lang->build->last . ": <a class='code label label-badge label-light' id='lastBuildBtn'>" . $lastBuild->name . "</a></div>";
}
else
{
echo '';
}
}
/**
* Link stories.
*
@@ -553,14 +577,11 @@ class build extends control
$build = $this->build->getById($buildID);
$product = $this->loadModel('product')->getById($build->product);
$this->loadModel('execution')->setMenu($build->execution);
if($build->execution) $this->loadModel('execution')->setMenu($build->execution);
$this->loadModel('story');
$this->loadModel('tree');
$this->loadModel('product');
$execution = $this->execution->getByID($build->execution);
if(empty($execution->hasProduct) and empty($execution->multiple)) unset($this->config->product->search['fields']['plan']);
/* Load pager. */
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
@@ -579,7 +600,14 @@ class build extends control
if($build->project)
{
$project = $this->loadModel('project')->getByID($build->project);
if(!$project->hasProduct and $project->model != 'scrum') unset($this->config->product->search['fields']['plan']);
if(!$project->hasProduct and $project->model != 'scrum')
{
unset($this->config->product->search['fields']['plan']);
}
else if(!$project->hasProduct and !$project->multiple)
{
unset($this->config->product->search['fields']['plan']);
}
}
if($product->type == 'normal')
@@ -598,13 +626,14 @@ class build extends control
}
$this->loadModel('search')->setSearchParams($this->config->product->search);
$executionID = $build->execution ? $build->execution : $build->project;
if($browseType == 'bySearch')
{
$allStories = $this->story->getBySearch($build->product, $build->branch, $queryID, 'id', $build->execution, 'story', $build->stories, $pager);
$allStories = $this->story->getBySearch($build->product, $build->branch, $queryID, 'id', $executionID, 'story', $build->allStories, $pager);
}
else
{
$allStories = $this->story->getExecutionStories($build->execution, $build->product, 0, 't1.`order`_desc', 'byBranch', $build->branch, 'story', $build->stories, $pager);
$allStories = $this->story->getExecutionStories($executionID, $build->product, 0, 't1.`order`_desc', 'byBranch', $build->branch, 'story', $build->allStories, $pager);
}
$this->view->allStories = $allStories;
@@ -669,7 +698,7 @@ class build extends control
/* Set menu. */
$build = $this->build->getByID($buildID);
$product = $this->loadModel('product')->getByID($build->product);
$this->loadModel('execution')->setMenu($build->execution);
if($build->execution) $this->loadModel('execution')->setMenu($build->execution);
/* Load pager. */
$this->app->loadClass('pager', $static = true);
@@ -688,9 +717,6 @@ class build extends control
$this->config->bug->search['params']['openedBuild']['values'] = $this->build->getBuildPairs($build->product, $branch = 'all', $params = '');
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values'];
$execution = $this->execution->getByID($build->execution);
if(!$execution->hasProduct and !$execution->multiple) unset($this->config->bug->search['fields']['plan']);
unset($this->config->bug->search['fields']['product']);
unset($this->config->bug->search['params']['product']);
unset($this->config->bug->search['fields']['project']);
@@ -699,7 +725,14 @@ class build extends control
if($build->project)
{
$project = $this->loadModel('project')->getByID($build->project);
if(!$project->hasProduct and $project->model != 'scrum') unset($this->config->bug->search['fields']['plan']);
if(!$project->hasProduct and $project->model != 'scrum')
{
unset($this->config->bug->search['fields']['plan']);
}
else if(!$project->hasProduct and !$project->multiple)
{
unset($this->config->bug->search['fields']['plan']);
}
}
if($product->type == 'normal')
@@ -717,13 +750,14 @@ class build extends control
}
$this->loadModel('search')->setSearchParams($this->config->bug->search);
$executionID = $build->execution ? $build->execution : $build->project;
if($browseType == 'bySearch')
{
$allBugs = $this->bug->getBySearch($build->product, $build->branch, $queryID, 'id_desc', $build->bugs, $pager, $build->project);
$allBugs = $this->bug->getBySearch($build->product, $build->branch, $queryID, 'id_desc', $build->allBugs, $pager, $build->project);
}
else
{
$allBugs = $this->bug->getExecutionBugs($build->execution, 0, 'all', $buildID, 'noclosed', 0, 'status_desc,id_desc', $build->bugs, $pager);
$allBugs = $this->bug->getExecutionBugs($executionID, 0, 'all', $buildID, 'noclosed', 0, 'status_desc,id_desc', $build->allBugs, $pager);
}
$this->view->allBugs = $allBugs;
+4 -2
View File
@@ -15,8 +15,8 @@ function loadBranches(productID)
oldBranch = productGroups[productID]['branches'];
}
executionID = currentTab == 'execution' ? executionID : $('#execution').val();
$.get(createLink('branch', 'ajaxGetBranches', 'productID=' + productID + '&oldBranch=0&param=active&projectID=' + executionID), function(data)
projectID = currentTab == 'execution' ? executionID : projectID;
$.get(createLink('branch', 'ajaxGetBranches', 'productID=' + productID + '&oldBranch=0&param=active&projectID=' + projectID), function(data)
{
if(data)
{
@@ -25,3 +25,5 @@ function loadBranches(productID)
}
});
}
function loadBranch() {return false;}
+52 -1
View File
@@ -1,11 +1,42 @@
$().ready(function()
{
$('#lastBuildBtn').click(function()
$(document).on('click', '#lastBuildBtn', function()
{
$('#name').val($(this).text()).focus();
});
$(document).on('change', '#product, #branch', function()
{
var projectID = $('#project').val();
var productID = $('#product').val();
var branch = $('#branch').length > 0 ? $('#branch').val() : '';
$.get(createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&varName=builds&build=&branch=' + branch + '&index=&needCreate=&type=noempty,notrunk,separate,singled&extra=multiple'), function(data)
{
if(data) $('#buildBox').html(data);
$('#builds').attr('data-placeholder', multipleSelect).chosen();
});
});
$('input[name=isIntegrated]').change(function()
{
var projectID = $('#project').val();
var executionID = $('#execution').val();
if($(this).val() == 'no')
{
$('#execution').closest('tr').show();
$('#buildBox').closest('tr').hide();
loadProducts(executionID);
}
else
{
$('#execution').closest('tr').hide();
$('#buildBox').closest('tr').show();
loadProducts(projectID);
}
});
$('#product').change();
});
/**
* Load products.
*
@@ -20,6 +51,7 @@ function loadProducts(executionID)
$('#branch').remove();
$('#branch_chosen').remove();
$('#noProduct').remove();
executionID = executionID ? executionID : 0;
$.get(createLink('product', 'ajaxGetProducts', 'executionID=' + executionID), function(data)
{
if(data)
@@ -38,4 +70,23 @@ function loadProducts(executionID)
loadBranches($("#product").val());
}
});
loadLastBuild();
}
/**
* Load last build
*
* @access public
* @return void
*/
function loadLastBuild()
{
var isIntegrated = $('input[name=isIntegrated]:checked').val();
var projectID = $('#project').val();
var executionID = $('#execution').val();
if(isIntegrated == 'yes') executionID = 0;
$.get(createLink('build', 'ajaxGetLastBuild', 'projectID=' + projectID + '&executionID=' + executionID), function(data)
{
$('#lastBuildBox').html(data);
});
}
+22 -7
View File
@@ -1,6 +1,26 @@
var oldExecutionID = $('#execution').val();
$().ready(function()
{
var oldExecutionID = $('#execution').val();
$(document).on('change', '#product, #branch', function()
{
if(executionID)
{
loadExecutions(oldExecutionID);
}
else
{
var productID = $('#product').val();
var branch = $('#branch').val();
$.get(createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&varName=builds&build=&branch=' + branch + '&index=&needCreate=&type=noempty,notrunk,separate,singled&extra=multiple'), function(data)
{
if(data) $('#buildBox').html(data);
$('#builds').attr('data-placeholder', multipleSelect).chosen();
});
}
});
});
function loadExecutions()
function loadExecutions(oldExecutionID)
{
var productID = $('#product').val();
var branchID = $('#branch').length > 0 ? $('#branch').val() : 0;
@@ -9,8 +29,3 @@ function loadExecutions()
$('#executionsBox #execution').chosen().removeAttr('onchange');
});
}
$(document).on('change', '#product,#branch', function()
{
loadExecutions();
})
+1 -1
View File
@@ -2,7 +2,7 @@ function showLink(buildID, type, param)
{
var method = type == 'story' ? 'linkStory' : 'linkBug';
if(typeof(param) == 'undefined') param = '&browseType=' + type + '&param=0';
loadURL(createLink('build', method, 'buildID=' + buildID + param), type);
loadURL(createLink(currentModule, method, 'buildID=' + buildID + param), type);
$('.actions').find("a[href*='" + type + "']").addClass('hidden');
}
+11 -3
View File
@@ -33,6 +33,9 @@ $lang->build->project = 'Project';
$lang->build->branch = 'Platform/Branch';
$lang->build->branchName = '%s';
$lang->build->execution = $lang->executionCommon;
$lang->build->integrated = 'Integrated';
$lang->build->singled = 'Singled';
$lang->build->builds = 'Included Builds';
$lang->build->name = 'Name';
$lang->build->date = 'Datum';
$lang->build->builder = 'Builder';
@@ -55,18 +58,23 @@ $lang->build->emptyExecution = $lang->executionCommon . 'should be not empty.';
$lang->build->notice = new stdclass();
$lang->build->notice->changeProduct = "The {$lang->SRCommon}, bug, or the version of the submitted test order has been linked, and its {$lang->productCommon} cannot be modified";
$lang->build->notice->changeExecution = "The version of the submitted test order cannot be modified {$lang->executionCommon}";
$lang->build->notice->changeBuilds = "The version of the submitted test order cannot be modified builds";
$lang->build->notice->autoRelation = "The completed requirements, resolved bugs, and generated bugs under the relevant version will be automatically associated with the project version";
$lang->build->finishStories = " %s {$lang->SRCommon} sind abgeschlossen.";
$lang->build->resolvedBugs = ' %s Bugs sind gelöst.';
$lang->build->createdBugs = ' %s Bugs wurden erstellt.';
$lang->build->placeholder = new stdclass();
$lang->build->placeholder->scmPath = ' Source code repository, z.B. Subversion/Git Pfad';
$lang->build->placeholder->filePath = ' Pfad zum Download für diese Build.';
$lang->build->placeholder->scmPath = ' Source code repository, z.B. Subversion/Git Pfad';
$lang->build->placeholder->filePath = ' Pfad zum Download für diese Build.';
$lang->build->placeholder->multipleSelect = "Support select multiple builds";
$lang->build->action = new stdclass();
$lang->build->action->buildopened = '$date, erstellt von <strong>$actor</strong>, Build <strong>$extra</strong>.' . "\n";
$lang->backhome = 'zurück';
$lang->build->featureBar['browse']['all'] = 'Build List';
$lang->build->isIntegrated = array();
$lang->build->isIntegrated['no'] = 'No';
$lang->build->isIntegrated['yes'] = 'Yes';
+11 -3
View File
@@ -33,6 +33,9 @@ $lang->build->project = 'Project';
$lang->build->branch = 'Platform/Branch';
$lang->build->branchName = '%s';
$lang->build->execution = $lang->executionCommon;
$lang->build->integrated = 'Integrated';
$lang->build->singled = 'Singled';
$lang->build->builds = 'Included Builds';
$lang->build->name = 'Name';
$lang->build->date = 'Date';
$lang->build->builder = 'Builder';
@@ -55,18 +58,23 @@ $lang->build->emptyExecution = $lang->executionCommon . 'should be not empty.';
$lang->build->notice = new stdclass();
$lang->build->notice->changeProduct = "The {$lang->SRCommon}, bug, or the version of the submitted test order has been linked, and its {$lang->productCommon} cannot be modified";
$lang->build->notice->changeExecution = "The version of the submitted test order cannot be modified {$lang->executionCommon}";
$lang->build->notice->changeBuilds = "The version of the submitted test order cannot be modified builds";
$lang->build->notice->autoRelation = "The completed requirements, resolved bugs, and generated bugs under the relevant version will be automatically associated with the project version";
$lang->build->finishStories = " Finished {$lang->SRCommon} %s";
$lang->build->resolvedBugs = ' Resolved Bug %s';
$lang->build->createdBugs = ' Reported Bug %s';
$lang->build->placeholder = new stdclass();
$lang->build->placeholder->scmPath = ' Source code repository, e.g. Subversion/Git Library path';
$lang->build->placeholder->filePath = ' Download path for this Build.';
$lang->build->placeholder->scmPath = ' Source code repository, e.g. Subversion/Git Library path';
$lang->build->placeholder->filePath = ' Download path for this Build.';
$lang->build->placeholder->multipleSelect = "Support select multiple builds";
$lang->build->action = new stdclass();
$lang->build->action->buildopened = '$date, created by <strong>$actor</strong>, Build <strong>$extra</strong>.' . "\n";
$lang->backhome = 'back';
$lang->build->featureBar['browse']['all'] = 'Build List';
$lang->build->isIntegrated = array();
$lang->build->isIntegrated['no'] = 'No';
$lang->build->isIntegrated['yes'] = 'Yes';
+11 -3
View File
@@ -33,6 +33,9 @@ $lang->build->project = 'Project';
$lang->build->branch = 'Plateforme/Branche';
$lang->build->branchName = '%s';
$lang->build->execution = $lang->executionCommon;
$lang->build->integrated = 'Integrated';
$lang->build->singled = 'Singled';
$lang->build->builds = 'Included Builds';
$lang->build->name = 'Nom';
$lang->build->date = 'Date';
$lang->build->builder = 'Builder';
@@ -55,18 +58,23 @@ $lang->build->emptyExecution = $lang->executionCommon . 'should be not empty.';
$lang->build->notice = new stdclass();
$lang->build->notice->changeProduct = "The {$lang->SRCommon}, bug, or the version of the submitted test order has been linked, and its {$lang->productCommon} cannot be modified";
$lang->build->notice->changeExecution = "The version of the submitted test order cannot be modified {$lang->executionCommon}";
$lang->build->notice->changeBuilds = "The version of the submitted test order cannot be modified builds";
$lang->build->notice->autoRelation = "The completed requirements, resolved bugs, and generated bugs under the relevant version will be automatically associated with the project version";
$lang->build->finishStories = " {$lang->SRCommon} Terminées %s";
$lang->build->resolvedBugs = ' Bugs Résolus %s';
$lang->build->createdBugs = ' Bugs Signalés %s';
$lang->build->placeholder = new stdclass();
$lang->build->placeholder->scmPath = ' Répertoire des codes sources, ex: chemin de la bibliothèque Subversion / GitSource';
$lang->build->placeholder->filePath = ' Chemin de téléchargement pour ce Build.';
$lang->build->placeholder->scmPath = ' Répertoire des codes sources, ex: chemin de la bibliothèque Subversion / GitSource';
$lang->build->placeholder->filePath = ' Chemin de téléchargement pour ce Build.';
$lang->build->placeholder->multipleSelect = "Support select multiple builds";
$lang->build->action = new stdclass();
$lang->build->action->buildopened = '$date, Build <strong>$extra</strong> créé par <strong>$actor</strong>.' . "\n";
$lang->backhome = 'Retour';
$lang->build->featureBar['browse']['all'] = 'Build List';
$lang->build->isIntegrated = array();
$lang->build->isIntegrated['no'] = 'No';
$lang->build->isIntegrated['yes'] = 'Yes';
+3
View File
@@ -31,6 +31,7 @@ $lang->build->id = 'ID';
$lang->build->product = $lang->productCommon;
$lang->build->branch = 'Platform/Branch';
$lang->build->execution = $lang->executionCommon;
$lang->build->builds = 'Builds';
$lang->build->name = 'Tên';
$lang->build->date = 'Ngày';
$lang->build->builder = 'Builder';
@@ -51,6 +52,8 @@ $lang->build->noBuild = 'Không có bản dựng nào';
$lang->build->notice = new stdclass();
$lang->build->notice->changeProduct = "The {$lang->SRCommon}, bug, or the version of the submitted test order has been linked, and its {$lang->productCommon} cannot be modified";
$lang->build->notice->changeExecution = "The version of the submitted test order cannot be modified {$lang->executionCommon}";
$lang->build->notice->changeBuilds = "The version of the submitted test order cannot be modified builds";
$lang->build->notice->autoRelation = "The completed requirements, resolved bugs, and generated bugs under the relevant version will be automatically associated with the project version";
$lang->build->finishStories = " {$lang->SRCommon} đã kết thúc %s";
$lang->build->resolvedBugs = ' Bug đã giải quyết %s';
+12 -2
View File
@@ -33,6 +33,9 @@ $lang->build->project = '所属项目';
$lang->build->branch = '平台/分支';
$lang->build->branchName = '所属%s';
$lang->build->execution = '所属' . $lang->executionCommon;
$lang->build->integrated = '集成版本';
$lang->build->singled = '单一版本';
$lang->build->builds = '包含版本';
$lang->build->name = '名称编号';
$lang->build->date = '打包日期';
$lang->build->builder = '构建者';
@@ -55,16 +58,23 @@ $lang->build->emptyExecution = $lang->executionCommon . '不能为空。';
$lang->build->notice = new stdclass();
$lang->build->notice->changeProduct = "已经关联{$lang->SRCommon}、Bug或提交测试单的版本,不能修改其所属{$lang->productCommon}";
$lang->build->notice->changeExecution = "提交测试单的版本,不能修改其所属{$lang->executionCommon}";
$lang->build->notice->changeBuilds = "提交测试单的版本,不能修改关联版本";
$lang->build->notice->autoRelation = "相关版本下完成的需求、解决的Bug、产生的Bug将会自动关联到项目版本中";
$lang->build->finishStories = " 本次共完成 %s 个{$lang->SRCommon}";
$lang->build->resolvedBugs = ' 本次共解决 %s 个Bug';
$lang->build->createdBugs = ' 本次共产生 %s 个Bug';
$lang->build->placeholder = new stdclass();
$lang->build->placeholder->scmPath = ' 软件源代码库,如Subversion、Git库地址';
$lang->build->placeholder->filePath = ' 该版本软件包下载存储地址';
$lang->build->placeholder->scmPath = ' 软件源代码库,如Subversion、Git库地址';
$lang->build->placeholder->filePath = ' 该版本软件包下载存储地址';
$lang->build->placeholder->multipleSelect = "版本支持多选";
$lang->build->action = new stdclass();
$lang->build->action->buildopened = '$date, 由 <strong>$actor</strong> 创建版本 <strong>$extra</strong>。' . "\n";
$lang->backhome = '返回';
$lang->build->isIntegrated = array();
$lang->build->isIntegrated['no'] = '否';
$lang->build->isIntegrated['yes'] = '是';
+122 -42
View File
@@ -31,6 +31,7 @@ class buildModel extends model
->fetch();
if(!$build) return false;
$build = $this->joinChildBuilds($build);
$build = $this->loadModel('file')->replaceImgURL($build, 'desc');
$build->files = $this->file->getByObject('build', $buildID);
if($setImgSize) $build->desc = $this->file->setImgSize($build->desc);
@@ -201,7 +202,7 @@ class buildModel extends model
*
* @param int|array $products
* @param string|int $branch
* @param string $params noempty|notrunk|noterminate|withbranch, can be a set of them
* @param string $params noempty|notrunk|noterminate|withbranch|hasproject|noDeleted|singled|withreleased, can be a set of them
* @param string|int $objectID
* @param string $objectType
* @param int|array $buildIdList
@@ -220,76 +221,108 @@ class buildModel extends model
$selectedBuilds = $this->dao->select('id, name')->from(TABLE_BUILD)
->where('id')->in($buildIdList)
->beginIF($products)->andWhere('product')->in($products)->fi()
->beginIF($objectType === 'execution')->andWhere('execution')->eq($objectID)->fi()
->beginIF($objectType === 'project')->andWhere('project')->eq($objectID)->fi()
->beginIF($objectType === 'execution' and $objectID)->andWhere('execution')->eq($objectID)->fi()
->beginIF($objectType === 'project' and $objectID)->andWhere('project')->eq($objectID)->fi()
->fetchPairs();
}
$allBuilds = $this->dao->select('t1.id, t1.name, t1.deleted, t2.status as objectStatus, t3.id as releaseID, t3.status as releaseStatus, t4.name as branchName, t5.type as productType')->from(TABLE_BUILD)->alias('t1')
$branchs = strpos($params, 'separate') === false ? "0,$branch" : $branch;
$allBuilds = $this->dao->select('t1.id, t1.name, t1.date, t1.deleted, t2.status as objectStatus, t3.id as releaseID, t3.status as releaseStatus, t4.name as branchName, t5.type as productType')->from(TABLE_BUILD)->alias('t1')
->beginIF($objectType === 'execution')->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.execution = t2.id')->fi()
->beginIF($objectType === 'project')->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')->fi()
->leftJoin(TABLE_RELEASE)->alias('t3')->on('t1.id = t3.build')
->leftJoin(TABLE_RELEASE)->alias('t3')->on("FIND_IN_SET(t1.id,t3.build)")
->leftJoin(TABLE_BRANCH)->alias('t4')->on('t1.branch = t4.id')
->leftJoin(TABLE_PRODUCT)->alias('t5')->on('t1.product = t5.id')
->where(1)->eq(1)
->where('1=1')
->beginIF(strpos($params, 'hasDeleted') === false)->andWhere('t1.deleted')->eq(0)->fi()
->beginIF(strpos($params, 'hasproject') !== false)->andWhere('t1.project')->ne(0)->fi()
->beginIF(strpos($params, 'singled') !== false)->andWhere('t1.execution')->ne(0)->fi()
->beginIF($products)->andWhere('t1.product')->in($products)->fi()
->beginIF($objectType === 'execution' and $objectID)->andWhere('t1.execution')->eq($objectID)->fi()
->beginIF($objectType === 'project' and $objectID)->andWhere('t1.project')->eq($objectID)->fi()
->beginIF($objectType === 'execution' and !$objectID)->andWhere('t1.id')->in($buildIdList)->fi()
->beginIF($branch !== 'all')->andWhere('t1.branch')->in("0,$branch")->fi()
->beginIF($branch !== 'all')->andWhere('t1.branch')->in("$branchs")->fi()
->orderBy('t1.date desc, t1.id desc')->fetchAll('id');
/* Set builds and filter done executions and terminate releases. */
$builds = array();
$builds = array();
$buildIdList = array();
$this->app->loadLang('branch');
foreach($allBuilds as $key => $build)
foreach($allBuilds as $id => $build)
{
if(empty($build->releaseID) and (strpos($params, 'nodone') !== false) and ($build->objectStatus === 'done')) continue;
if((strpos($params, 'noterminate') !== false) and ($build->releaseStatus === 'terminate')) continue;
if($build->deleted == 1) $build->name .= ' (' . $this->lang->build->deleted . ')';
$branchName = $build->branchName ? $build->branchName : $this->lang->branch->main;
$builds[$key] = $build->name;
if(strpos($params, 'withbranch') !== false and $build->productType != 'normal') $builds[$key] = $branchName . '/' . $builds[$key];
$buildName = $build->name;
if(strpos($params, 'withbranch') !== false and $build->productType != 'normal') $buildName = $branchName . '/' . $buildName;
$buildIdList[$id] = $id;
$builds[$build->date][$id] = $buildName;
}
if(!$builds) return $sysBuilds + $selectedBuilds;
if(empty($builds)) return $sysBuilds + $selectedBuilds;
/* if the build has been released and replace is true, replace build name with release name. */
if($replace)
{
$releases = $this->dao->select('build, name')->from(TABLE_RELEASE)
->where('build')->in(array_keys($builds))
->andWhere('product')->in($products)
->beginIF($branch !== 'all')->andWhere('branch')->in("0,$branch")->fi()
->andWhere('deleted')->eq(0)
->fetchPairs();
foreach($releases as $buildID => $releaseName)
$releases = $this->dao->select('t1.id,t1.shadow,t1.product,t1.branch,t1.build,t1.name,t1.date,t3.name as branchName,t4.type as productType')->from(TABLE_RELEASE)->alias('t1')
->leftJoin(TABLE_BUILD)->alias('t2')->on('FIND_IN_SET(t2.id, t1.build)')
->leftJoin(TABLE_BRANCH)->alias('t3')->on('FIND_IN_SET(t3.id, t1.branch)')
->leftJoin(TABLE_PRODUCT)->alias('t4')->on('t1.product=t4.id')
->where('t2.id')->in($buildIdList)
->andWhere('t1.product')->in($products)
->andWhere('t1.deleted')->eq(0)
->andWhere('t1.shadow')->ne(0)
->fetchAll('id');
foreach($releases as $release)
{
$branchName = $allBuilds[$buildID]->branchName ? $allBuilds[$buildID]->branchName : $this->lang->branch->main;
if($allBuilds[$buildID]->productType != 'normal')
if($branch !== 'all')
{
$builds[$buildID] = (strpos($params, 'withbranch') !== false ? $branchName . '/' : '') . $releaseName;
$inBranch = false;
foreach(explode(',', trim($release->branch, ',')) as $branchID)
{
if($branchID === '') continue;
if(strpos(",{$branchs},", ",{$branchID},") !== false) $inBranch = true;
}
if(!$inBranch) continue;
}
$releaseName = $release->name;
$branchName = $release->branchName ? $release->branchName : $this->lang->branch->main;
if($release->productType != 'normal') $releaseName = (strpos($params, 'withbranch') !== false ? $branchName . '/' : '') . $releaseName;
$builds[$release->date][$release->shadow] = $releaseName;
foreach(explode(',', trim($release->build, ',')) as $buildID)
{
if(!isset($allBuilds[$buildID])) continue;
$build = $allBuilds[$buildID];
if(strpos($params, 'withreleased') === false) unset($builds[$build->date][$buildID]);
}
}
}
return $sysBuilds + $builds + $selectedBuilds;
krsort($builds);
$buildPairs = array();
foreach($builds as $date => $childBuilds) $buildPairs += $childBuilds;
return $sysBuilds + $buildPairs + $selectedBuilds;
}
/**
* Get last build.
*
* @param int $executionID
* @param int $projectID
* @access public
* @return bool | object
*/
public function getLast($executionID)
public function getLast($executionID = 0, $projectID = 0)
{
return $this->dao->select('id, name')->from(TABLE_BUILD)
->where('execution')->eq((int)$executionID)
->andWhere('deleted')->eq(0)
->where('deleted')->eq(0)
->andWhere('execution')->eq((int)$executionID)
->beginIF($projectID)->andWhere('project')->eq((int)$projectID)->fi()
->orderBy('date DESC,id DESC')
->limit(1)
->fetch();
@@ -298,30 +331,31 @@ class buildModel extends model
/**
* Create a build
*
* @param int $executionID
* @access public
* @return void
*/
public function create($executionID)
public function create()
{
$build = new stdclass();
$build->stories = '';
$build->bugs = '';
$execution = $this->loadModel('execution')->getByID($executionID);
$build = fixer::input('post')
->setDefault('project', $execution->project)
->setDefault('project', 0)
->setDefault('execution', 0)
->setDefault('product', 0)
->setDefault('branch', 0)
->setDefault('builds', '')
->cleanInt('product,branch')
->add('execution', (int)$executionID)
->add('createdBy', $this->app->user->account)
->add('createdDate', helper::now())
->stripTags($this->config->build->editor->create['id'], $this->config->allowedTags)
->remove('resolvedBy,allchecker,files,labels,uid')
->join('builds', ',')
->remove('resolvedBy,allchecker,files,labels,isIntegrated,uid')
->get();
if($this->post->isIntegrated == 'yes') $build->execution = 0;
$build = $this->loadModel('file')->processImgURL($build, $this->config->build->editor->create['id'], $this->post->uid);
$this->dao->insert(TABLE_BUILD)->data($build)
->autoCheck()
@@ -355,7 +389,9 @@ class buildModel extends model
->add('id', $buildID)
->setIF(!isset($_POST['branch']), 'branch', $oldBuild->branch)
->setDefault('product', $oldBuild->product)
->setDefault('builds', '')
->cleanInt('product,branch,execution')
->join('builds', ',')
->remove('allchecker,resolvedBy,files,labels,uid')
->get();
@@ -545,6 +581,49 @@ class buildModel extends model
foreach($this->post->unlinkBugs as $unlinkBugID) $this->action->create('bug', $unlinkBugID, 'unlinkedfrombuild', '', $buildID);
}
/**
* Bugs and stories associated with child builds.
*
* @param object $build
* @access public
* @return object
*/
public function joinChildBuilds($build)
{
$build->allBugs = $build->bugs;
$build->allStories = $build->stories;
$childBuilds = $this->dao->select('bugs, stories')->from(TABLE_BUILD)->where('id')->in($build->builds)->fetchAll();
foreach($childBuilds as $childBuild)
{
if($childBuild->bugs) $build->allBugs .= ",{$childBuild->bugs}";
if($childBuild->stories) $build->allStories .= ",{$childBuild->stories}";
}
$build->allBugs = explode(',', $build->allBugs);
$build->allBugs = join(',', array_unique(array_filter($build->allBugs)));
$build->allStories = explode(',', $build->allStories);
$build->allStories = join(',', array_unique(array_filter($build->allStories)));
return $build;
}
/**
* Adjust the action is clickable.
*
* @param string $bug
* @param string $action
* @param string $module
* @access public
* @return void
*/
public static function isClickable($object, $action, $module = 'bug')
{
$action = strtolower($action);
return true;
}
/**
* Build action menu.
*
@@ -565,21 +644,22 @@ class buildModel extends model
global $app;
$tab = $app->tab;
$module = $build->execution ? 'build' : 'projectbuild';
if($type == 'browse')
{
$executionID = $tab == 'execution' ? $extraParams['executionID'] : $build->execution;
$execution = $this->loadModel('execution')->getByID($executionID);
$testtaskApp = (!empty($execution->type) and $execution->type == 'kanban') ? 'data-app="qa"' : "data-app='{$tab}'";
if(common::hasPriv('build', 'linkstory') and common::canBeChanged('build', $build)) $menu .= $this->buildMenu('build', 'view', "{$params}&type=story&link=true", $build, $type, 'link', '', '', '', "data-app={$tab}", $this->lang->build->linkStory);
if(common::hasPriv($module, 'linkstory') and common::canBeChanged('build', $build)) $menu .= $this->buildMenu($module, 'view', "{$params}&type=story&link=true", $build, $type, 'link', '', '', '', "data-app={$tab}", $this->lang->build->linkStory);
$menu .= $this->buildMenu('testtask', 'create', "product=$build->product&execution={$executionID}&build=$build->id&projectID=$build->project", $build, $type, 'bullhorn', '', '', '', $testtaskApp);
if($tab == 'execution' and !empty($execution->type) and $execution->type != 'kanban') $menu .= $this->buildMenu('execution', 'bug', "execution={$extraParams['executionID']}&productID={$extraParams['productID']}&branchID=all&orderBy=status&build=$build->id", $build, $type, '', '', '', '', $this->lang->execution->viewBug);
if($tab == 'project' or empty($execution->type) or $execution->type == 'kanban') $menu .= $this->buildMenu('build', 'view', "{$params}&type=generatedBug", $build, $type, 'bug', '', '', '', "data-app='$tab'", $this->lang->project->bug);
if($tab == 'project' or empty($execution->type) or $execution->type == 'kanban') $menu .= $this->buildMenu($module, 'view', "{$params}&type=generatedBug", $build, $type, 'bug', '', '', '', "data-app='$tab'", $this->lang->project->bug);
$menu .= $this->buildMenu('build', 'edit', $params, $build, $type);
$menu .= $this->buildMenu('build', 'delete', $params, $build, $type, 'trash', 'hiddenwin');
$menu .= $this->buildMenu($module, 'edit', $params, $build, $type);
$menu .= $this->buildMenu($module, 'delete', $params, $build, $type, 'trash', 'hiddenwin');
}
else
{
@@ -588,10 +668,10 @@ class buildModel extends model
$menu .= $this->buildFlowMenu('build', $build, 'view', 'direct');
$editClickable = $this->buildMenu('build', 'edit', $params, $build, $type, '', '', '', '', '', '', false);
$deleteClickable = $this->buildMenu('build', 'delete', $params, $build, $type, '', '', '', '', '', '', false);
if(common::hasPriv('build', 'edit') and $editClickable) $menu .= html::a(helper::createLink('build', 'edit', $params), "<i class='icon-common-edit icon-edit'></i> " . $this->lang->edit, '', "class='btn btn-link' title='{$this->lang->build->edit}' data-app='{$app->tab}'");
if(common::hasPriv('build', 'delete') and $deleteClickable) $menu .= html::a(helper::createLink('build', 'delete', $params), "<i class='icon-common-delete icon-trash'></i> " . $this->lang->delete, '', "class='btn btn-link' title='{$this->lang->build->delete}' target='hiddenwin' data-app='{$app->tab}'");
$editClickable = $this->buildMenu($module, 'edit', $params, $build, $type, '', '', '', '', '', '', false);
$deleteClickable = $this->buildMenu($module, 'delete', $params, $build, $type, '', '', '', '', '', '', false);
if(common::hasPriv($module, 'edit') and $editClickable) $menu .= html::a(helper::createLink($module, 'edit', $params), "<i class='icon-common-edit icon-edit'></i> " . $this->lang->edit, '', "class='btn btn-link' title='{$this->lang->build->edit}' data-app='{$app->tab}'");
if(common::hasPriv($module, 'delete') and $deleteClickable) $menu .= html::a(helper::createLink($module, 'delete', $params), "<i class='icon-common-delete icon-trash'></i> " . $this->lang->delete, '', "class='btn btn-link' title='{$this->lang->build->delete}' target='hiddenwin' data-app='{$app->tab}'");
}
return $menu;
+17 -7
View File
@@ -19,15 +19,17 @@
</div>
<form class='load-indicator main-form form-ajax' id='dataform' method='post' enctype='multipart/form-data'>
<table class='table table-form'>
<?php if($app->tab == 'project'):?>
<tr class="<?php echo empty($multipleProject) ? 'hidden' : '';?>">
<tr class="<?php echo ($app->tab == 'project' and !empty($multipleProject)) ? '' : 'hidden';?>">
<th class='w-120px'><?php echo $lang->build->integrated;?></th>
<td><?php echo html::radio('isIntegrated', $lang->build->isIntegrated, 'no');?></td>
</tr>
<tr class="<?php echo !empty($multipleProject) ? '' : 'hidden';?>">
<th><?php echo $lang->executionCommon;?></th>
<td><?php echo html::select('execution', $executions, $executionID, "onchange='loadProducts(this.value);' class='form-control chosen' required");?></td>
</tr>
<?php endif;?>
<tr class="<?php echo $hidden;?>">
<th><?php echo $lang->build->product;?></th>
<?php if(!empty($products)):?>
<th class='w-120px'><?php echo $lang->build->product;?></th>
<?php if(!empty($products) || !$executionID):?>
<td>
<div class='input-group' id='productBox'>
<?php echo html::select('product', $products, empty($product) ? '' : $product->id, "onchange='loadBranches(this.value);' class='form-control chosen' required");?>
@@ -48,10 +50,15 @@
<?php endif;?>
<td></td>
</tr>
<tr class='hide'>
<th class='w-120px'><?php echo $lang->build->builds;?></th>
<td id='buildBox'><?php echo html::select('builds[]', array(), '', "class='form-control chosen' multiple data-placeholder='{$lang->build->placeholder->multipleSelect}'");?></td>
<td><?php echo $lang->build->notice->autoRelation;?></td>
</tr>
<tr>
<th><?php echo $lang->build->name;?></th>
<th class='w-120px'><?php echo $lang->build->name;?></th>
<td><?php echo html::input('name', '', "class='form-control' required");?></td>
<td class='text-muted'>
<td class='text-muted' id='lastBuildBox'>
<?php if($lastBuild):?>
<div class='help-block'> &nbsp; <?php echo $lang->build->last . ': <a class="code label label-badge label-light" id="lastBuildBtn">' . $lastBuild->name . '</a>';?></div>
<?php endif;?>
@@ -85,6 +92,7 @@
<tr>
<td colspan="3" class="text-center form-actions">
<?php echo html::submitButton();?>
<?php echo html::hidden('project', $projectID);?>
<?php echo html::backButton();?>
</td>
</tr>
@@ -93,6 +101,8 @@
</div>
</div>
<?php js::set('productGroups', $productGroups);?>
<?php js::set('projectID', $projectID);?>
<?php js::set('executionID', $executionID);?>
<?php js::set('currentTab', $this->app->tab);?>
<?php js::set('multipleSelect', $lang->build->placeholder->multipleSelect);?>
<?php include '../../common/view/footer.html.php';?>
+20 -8
View File
@@ -23,8 +23,8 @@
</div>
<form class='load-indicator main-form form-ajax' method='post' id='dataform' enctype='multipart/form-data'>
<table class='table table-form'>
<tr class="<?php echo $hidden;?>">
<th><?php echo $lang->build->product;?></th>
<tr class="<?php echo $hidden;?>">
<th class='w-120px'><?php echo $lang->build->product;?></th>
<td>
<?php
$disabled = '';
@@ -42,16 +42,26 @@
</td>
<td><?php if($disabled) echo $lang->build->notice->changeProduct;?></td>
</tr>
<?php if(!empty($multipleProject)):?>
<?php $disabled = $testtaskID ? 'disabled' : '';?>
<?php if(!$build->execution):?>
<tr>
<?php $disabled = $testtaskID ? 'disabled' : '';?>
<th><?php echo $lang->build->execution;?></th>
<td id='executionsBox'><?php echo html::select('execution', $executions, $build->execution, "class='form-control chosen' required $disabled");?></td>
<td><?php if($disabled) echo $lang->build->notice->changeExecution;?></td>
<th class='w-120px'><?php echo $lang->build->builds;?></th>
<td id='buildBox'><?php echo html::select('builds[]', $builds, $build->builds, "class='form-control chosen' multiple $disabled data-placeholder='{$lang->build->placeholder->multipleSelect}'");?></td>
<td>
<?php if($disabled):?>
<?php echo $lang->build->notice->changeBuilds;?>
<?php else:?>
<?php echo $lang->build->notice->autoRelation;?>
<?php endif;?>
</td>
</tr>
<?php elseif(!empty($multipleProject)):?>
<th class='w-120px'><?php echo $lang->build->execution;?></th>
<td id='executionsBox'><?php echo html::select('execution', $executions, $build->execution, "class='form-control chosen' required $disabled");?></td>
<td><?php if($disabled) echo $lang->build->notice->changeExecution;?></td>
<?php endif;?>
<tr>
<th><?php echo $lang->build->name;?></th>
<th class='w-120px'><?php echo $lang->build->name;?></th>
<td><?php echo html::input('name', $build->name, "class='form-control' required");?></td>
</tr>
<tr>
@@ -91,6 +101,8 @@
</div>
<?php js::set('productGroups', $productGroups)?>
<?php js::set('projectID', $build->project)?>
<?php js::set('builds', $build->builds)?>
<?php js::set('executionID', $build->execution)?>
<?php js::set('currentTab', $this->app->tab);?>
<?php js::set('multipleSelect', $lang->build->placeholder->multipleSelect);?>
<?php include '../../common/view/footer.html.php';?>
+1 -1
View File
@@ -62,7 +62,7 @@
<?php echo html::submitButton($lang->build->linkBug, '', 'btn btn-secondary');?>
</div>
<div class="btn-toolbar">
<?php echo html::a(inlink('view', "buildID={$build->id}&type=bug"), $lang->goback, '', "class='btn'");?>
<?php echo html::a(inlink('view', "buildID={$build->id}&type=bug") . "#app={$app->tab}", $lang->goback, '', "class='btn'");?>
</div>
<div class='table-statistic'></div>
<?php $pager->show('right', 'pagerjs');?>
+1 -1
View File
@@ -72,7 +72,7 @@
<?php echo html::submitButton($lang->build->linkStory, '', 'btn btn-secondary');?>
</div>
<div class="btn-toolbar">
<?php echo html::a(inlink('view', "buildID={$build->id}&type=story"), $lang->goback, '', "class='btn'");?>
<?php echo html::a(inlink('view', "buildID={$build->id}&type=story") . "#app={$app->tab}", $lang->goback, '', "class='btn'");?>
</div>
<div class='table-statistic'></div>
<?php $pager->show('right', 'pagerjs');?>
+41 -19
View File
@@ -35,8 +35,9 @@ tbody tr td:first-child input {display: none;}
echo "<ul class='dropdown-menu'>";
foreach($buildPairs as $id => $name)
{
$buildInfo = zget($builds, $id);
echo '<li' . ($id == $build->id ? " class='active'" : '') . '>';
echo html::a($this->createLink('build', 'view', "buildID=$id"), $name);
echo html::a($this->createLink($buildInfo->execution ? 'build' : 'projectbuild', 'view', "buildID=$id") . "#app={$app->tab}", $name);
echo '</li>';
}
echo '</ul>';
@@ -53,6 +54,7 @@ tbody tr td:first-child input {display: none;}
</div>
<?php endif;?>
</div>
<?php $module = $build->execution ? 'build' : 'projectbuild';?>
<div id='mainContent' class='main-content'>
<div class='tabs' id='tabsNav'>
<?php $countStories = count($stories); $countBugs = count($bugs); $countGeneratedBugs = count($generatedBugs);?>
@@ -64,13 +66,13 @@ tbody tr td:first-child input {display: none;}
</ul>
<div class='tab-content'>
<div class='tab-pane <?php if($type == 'story') echo 'active'?>' id='stories'>
<?php if($canBeChanged and common::hasPriv('build', 'linkStory') and !isonlybody()):?>
<?php if($canBeChanged and common::hasPriv($module, 'linkStory') and !isonlybody()):?>
<div class='actions'><?php echo html::a("javascript:showLink($build->id, \"story\")", '<i class="icon-link"></i> ' . $lang->build->linkStory, '', "class='btn btn-primary'");?></div>
<div class='linkBox cell hidden'></div>
<?php endif;?>
<form class='main-table table-story' data-ride='table' method='post' target='hiddenwin' action='<?php echo inlink('batchUnlinkStory', "buildID={$build->id}")?>' id='linkedStoriesForm'>
<form class='main-table table-story' data-ride='table' method='post' target='hiddenwin' action='<?php echo $this->createLink($module, 'batchUnlinkStory', "buildID={$build->id}")?>' id='linkedStoriesForm'>
<table class='table has-sort-head' id='storyList'>
<?php $canBatchUnlink = ($canBeChanged and common::hasPriv('build', 'batchUnlinkStory'));?>
<?php $canBatchUnlink = ($canBeChanged and common::hasPriv($module, 'batchUnlinkStory'));?>
<?php $vars = "buildID={$build->id}&type=story&link=$link&param=$param&orderBy=%s";?>
<thead>
<tr class='text-center'>
@@ -93,10 +95,11 @@ tbody tr td:first-child input {display: none;}
</thead>
<tbody class='text-center'>
<?php foreach($stories as $storyID => $story):?>
<?php $unlinkClass = strpos(",$build->stories,", ",$story->id,") !== false ? '' : "disabled";?>
<tr>
<td class='c-id text-left'>
<?php if($canBatchUnlink):?>
<?php echo html::checkbox('unlinkStories', array($story->id => sprintf('%03d', $story->id)));?>
<?php echo html::checkbox('unlinkStories', array($story->id => sprintf('%03d', $story->id)), '', $unlinkClass);?>
<?php else:?>
<?php printf('%03d', $story->id);?>
<?php endif;?>
@@ -133,10 +136,10 @@ tbody tr td:first-child input {display: none;}
<td><?php echo $lang->story->stageList[$story->stage];?></td>
<td class='c-actions'>
<?php
if($canBeChanged and common::hasPriv('build', 'unlinkStory'))
if($canBeChanged and common::hasPriv($module, 'unlinkStory'))
{
$unlinkURL = inlink('unlinkStory', "buildID=$build->id&story=$story->id");
echo html::a($unlinkURL, '<i class="icon-unlink"></i>', 'hiddenwin', "class='btn' title='{$lang->build->unlinkStory}'");
$unlinkURL = $this->createLink($module, 'unlinkStory', "buildID=$build->id&story=$story->id");
echo html::a($unlinkURL, '<i class="icon-unlink"></i>', 'hiddenwin', "class='btn' title='{$lang->build->unlinkStory}' $unlinkClass");
}
?>
</td>
@@ -163,13 +166,13 @@ tbody tr td:first-child input {display: none;}
</form>
</div>
<div class='tab-pane <?php if($type == 'bug') echo 'active'?>' id='bugs'>
<?php if($canBeChanged and common::hasPriv('build', 'linkBug') and !isonlybody()):?>
<?php if($canBeChanged and common::hasPriv($module, 'linkBug') and !isonlybody()):?>
<div class='actions'><?php echo html::a("javascript:showLink($build->id, \"bug\")", '<i class="icon-bug"></i> ' . $lang->build->linkBug, '', "class='btn btn-primary'");?></div>
<div class='linkBox cell hidden'></div>
<?php endif;?>
<form class='main-table table-bug' data-ride='table' method='post' target='hiddenwin' action="<?php echo inLink('batchUnlinkBug', "build=$build->id");?>" id='linkedBugsForm'>
<form class='main-table table-bug' data-ride='table' method='post' target='hiddenwin' action="<?php echo $this->createLink($module, 'batchUnlinkBug', "build=$build->id");?>" id='linkedBugsForm'>
<table class='table has-sort-head' id='bugList'>
<?php $canBatchUnlink = $canBeChanged and common::hasPriv('build', 'batchUnlinkBug');?>
<?php $canBatchUnlink = $canBeChanged and common::hasPriv($module, 'batchUnlinkBug');?>
<?php $vars = "buildID={$build->id}&type=bug&link=$link&param=$param&orderBy=%s";?>
<thead>
<tr class='text-center'>
@@ -192,11 +195,12 @@ tbody tr td:first-child input {display: none;}
</thead>
<tbody class='text-center'>
<?php foreach($bugs as $bug):?>
<?php $bugLink = $this->createLink('bug', 'view', "bugID=$bug->id", '', true);?>
<?php $bugLink = $this->createLink('bug', 'view', "bugID=$bug->id", '', true);?>
<?php $unlinkClass = strpos(",$build->bugs,", ",$bug->id,") !== false ? '' : "disabled";?>
<tr>
<td class='c-id text-left'>
<?php if($canBatchUnlink):?>
<?php echo html::checkbox('unlinkBugs', array($bug->id => sprintf('%03d', $bug->id)));?>
<?php echo html::checkbox('unlinkBugs', array($bug->id => sprintf('%03d', $bug->id)), '', $unlinkClass);?>
<?php else:?>
<?php printf('%03d', $bug->id);?>
<?php endif;?>
@@ -214,10 +218,10 @@ tbody tr td:first-child input {display: none;}
<td><?php echo helper::isZeroDate($bug->resolvedDate) ? '' : substr($bug->resolvedDate, 5, 11);?></td>
<td class='c-actions'>
<?php
if($canBeChanged and common::hasPriv('build', 'unlinkBug'))
if($canBeChanged and common::hasPriv($module, 'unlinkBug'))
{
$unlinkURL = inlink('unlinkBug', "buildID=$build->id&bug=$bug->id");
echo html::a("###", '<i class="icon-unlink"></i>', '', "onclick='ajaxDelete(\"$unlinkURL\", \"bugList\", confirmUnlinkBug)' class='btn' title='{$lang->build->unlinkBug}'");
$unlinkURL = $this->createLink($module, 'unlinkBug', "buildID=$build->id&bug=$bug->id");
echo html::a("###", '<i class="icon-unlink"></i>', '', (!$unlinkClass ? "onclick='ajaxDelete(\"$unlinkURL\", \"bugList\", confirmUnlinkBug)'" : '') . "class='btn' title='{$lang->build->unlinkBug}' $unlinkClass");
}
?>
</td>
@@ -317,19 +321,36 @@ tbody tr td:first-child input {display: none;}
<div class='detail-content'>
<table class='table table-data table-condensed table-borderless table-fixed'>
<tr class="<?php echo $hidden;?>">
<th><?php echo $lang->build->product;?></th>
<th class='w-100px'><?php echo $lang->build->product;?></th>
<td><?php echo $build->productName;?></td>
</tr>
<?php if($build->productType != 'normal'):?>
<tr>
<th><?php echo $lang->product->branch;?></th>
<th class='w-100px'><?php echo $lang->product->branch;?></th>
<td><?php echo $branchName;?></td>
</tr>
<?php endif;?>
<tr>
<th><?php echo $lang->build->name;?></th>
<th class='w-100px'><?php echo $lang->build->name;?></th>
<td><?php echo $build->name;?></td>
</tr>
<?php if($build->execution):?>
<tr>
<th><?php echo empty($multipleProject) ? $lang->build->project : $lang->build->execution;?></th>
<td><?php echo zget($executions, $build->execution);?></td>
</tr>
<?php else:?>
<tr>
<th><?php echo $lang->build->builds;?></th>
<td>
<?php $builds = '';?>
<?php foreach(explode(',', $build->builds) as $buildID):?>
<?php if($buildID) $builds .= html::a($this->createLink('build', 'view', "buildID=$buildID") . "#app={$app->tab}", zget($buildPairs, $buildID)) . $lang->comma;?>
<?php endforeach;?>
<?php echo rtrim($builds, $lang->comma);?>
</td>
</tr>
<?php endif;?>
<tr>
<th><?php echo $lang->build->builder;?></th>
<td><?php echo zget($users, $build->builder);?></td>
@@ -369,6 +390,7 @@ tbody tr td:first-child input {display: none;}
</div>
<?php js::set('param', helper::safe64Decode($param))?>
<?php js::set('link', $link)?>
<?php js::set('currentModule', $module)?>
<?php js::set('buildID', $build->id)?>
<?php js::set('type', $type)?>
<?php include '../../common/view/footer.html.php';?>
+1 -1
View File
@@ -475,7 +475,7 @@ if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i');
if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31');
if(!defined('BRANCH_MAIN')) define('BRANCH_MAIN', '0');
if(!defined('DEFAULT_CARDCOUNT')) define('DEFAULT_CARDCOUNT', '2');
if(!defined('MAX_CARDCOUNT')) define('MAX_CARDCOUNT', '32767');
if(!defined('MAX_CARDCOUNT')) define('MAX_CARDCOUNT', '100');
/* Datepicker. */
$lang->datepicker = new stdclass();
+1 -1
View File
@@ -475,7 +475,7 @@ if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i');
if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31');
if(!defined('BRANCH_MAIN')) define('BRANCH_MAIN', '0');
if(!defined('DEFAULT_CARDCOUNT')) define('DEFAULT_CARDCOUNT', '2');
if(!defined('MAX_CARDCOUNT')) define('MAX_CARDCOUNT', '32767');
if(!defined('MAX_CARDCOUNT')) define('MAX_CARDCOUNT', '100');
/* Datepicker. */
$lang->datepicker = new stdclass();
+1 -1
View File
@@ -475,7 +475,7 @@ if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i');
if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31');
if(!defined('BRANCH_MAIN')) define('BRANCH_MAIN', '0');
if(!defined('DEFAULT_CARDCOUNT')) define('DEFAULT_CARDCOUNT', '2');
if(!defined('MAX_CARDCOUNT')) define('MAX_CARDCOUNT', '32767');
if(!defined('MAX_CARDCOUNT')) define('MAX_CARDCOUNT', '100');
/* Datepicker. */
$lang->datepicker = new stdclass();
+10 -7
View File
@@ -212,10 +212,10 @@ $lang->scrum->menu->projectplan = array('link' => "{$lang->productplan->shortCom
$lang->scrum->menu->doc = array('link' => "{$lang->doc->common}|doc|tableContents|type=project&objectID=%s", 'subModule' => 'doc');
$lang->scrum->menu->qa = array('link' => "{$lang->qa->common}|project|bug|projectID=%s", 'subModule' => 'testcase,testtask,bug,testreport', 'alias' => 'bug,testtask,testcase,testreport', 'exclude' => 'execution-create,execution-batchedit');
$lang->scrum->menu->devops = array('link' => "{$lang->repo->common}|repo|browse|repoID=0&branchID=&objectID=%s", 'subModule' => 'repo');
$lang->scrum->menu->build = array('link' => "{$lang->build->common}|project|build|project=%s");
$lang->scrum->menu->build = array('link' => "{$lang->build->common}|project|build|project=%s", 'subModule' => 'projectbuild');
$lang->scrum->menu->release = array('link' => "{$lang->release->common}|projectrelease|browse|project=%s", 'subModule' => 'projectrelease');
$lang->scrum->menu->dynamic = array('link' => "$lang->dynamic|project|dynamic|project=%s");
$lang->scrum->menu->settings = array('link' => "$lang->settings|project|view|project=%s", 'subModule' => 'tree,stakeholder', 'alias' => 'edit,manageproducts,group,managemembers,manageview,managepriv,whitelist,addwhitelist,team,managerepo');
$lang->scrum->menu->settings = array('link' => "$lang->settings|project|view|project=%s", 'subModule' => 'tree,stakeholder', 'alias' => 'edit,manageproducts,group,managemembers,manageview,managepriv,whitelist,addwhitelist,team', 'exclude' => 'tree-browsetask');
$lang->scrum->menu->storyGroup['dropMenu'] = new stdclass();
$lang->scrum->menu->storyGroup['dropMenu']->story = array('link' => "{$lang->SRCommon}|projectstory|story|projectID=%s&productID=%s", 'subModule' => 'projectstory,tree');
@@ -254,19 +254,19 @@ $lang->scrum->menu->settings['subMenu']->whitelist = array('link' => "{$lang->
$lang->scrum->menu->settings['subMenu']->stakeholder = array('link' => "{$lang->stakeholder->common}|stakeholder|browse|project=%s", 'subModule' => 'stakeholder');
$lang->scrum->menu->settings['subMenu']->group = array('link' => "{$lang->priv}|project|group|project=%s", 'alias' => 'group,manageview,managepriv');
$lang->scrum->menu->settings['subMenu']->module = array('link' => "{$lang->module}|tree|browse|product=%s&view=story");
$lang->scrum->menu->settings['subMenu']->managerepo = array('link' => "{$lang->repo->codeRepo}|project|managerepo|project=%s");
//$lang->scrum->menu->settings['subMenu']->managerepo = array('link' => "{$lang->repo->codeRepo}|project|managerepo|project=%s");
/* Waterfall menu. */
$lang->waterfall->menu = new stdclass();
$lang->waterfall->menu->index = array('link' => "$lang->dashboard|project|index|project=%s");
$lang->waterfall->menu->execution = array('link' => "{$lang->stage->common}|project|execution|status=all&projectID=%s", 'subModule' => 'programplan,task');
$lang->waterfall->menu->storyGroup = array('link' => "{$lang->common->story}|projectstory|story|projectID=%s",'class' => 'dropdown dropdown-hover', 'exclude' => 'tree-browse,projectstory-track');
$lang->waterfall->menu->story = array('link' => "$lang->SRCommon|projectstory|story|projectID=%s", 'subModule' => 'projectstory,tree', 'alias' => 'story,track', 'exclude' => 'projectstory-track');
$lang->waterfall->menu->story = array('link' => "$lang->SRCommon|projectstory|story|projectID=%s", 'subModule' => 'projectstory,tree', 'alias' => 'story', 'exclude' => 'projectstory-track');
$lang->waterfall->menu->design = array('link' => "{$lang->design->common}|design|browse|project=%s");
$lang->waterfall->menu->qa = array('link' => "{$lang->qa->common}|project|bug|projectID=%s", 'subModule' => 'testcase,testtask,bug,testreport', 'alias' => 'bug,testtask,testcase,testreport');
$lang->waterfall->menu->doc = array('link' => "{$lang->doc->common}|doc|tableContents|type=project&objectID=%s");
$lang->waterfall->menu->devops = array('link' => "{$lang->repo->common}|repo|browse|repoID=0&branchID=&objectID=%s", 'subModule' => 'repo');
$lang->waterfall->menu->build = array('link' => "{$lang->build->common}|project|build|project=%s");
$lang->waterfall->menu->build = array('link' => "{$lang->build->common}|project|build|project=%s", 'subModule' => 'projectbuild');
$lang->waterfall->menu->release = array('link' => "{$lang->release->common}|projectrelease|browse|project=%s", 'subModule' => 'projectrelease');
$lang->waterfall->menu->dynamic = array('link' => "$lang->dynamic|project|dynamic|project=%s");
@@ -312,7 +312,7 @@ $lang->waterfall->menu->design['subMenu']->bysearch = array('link' => '<a href="
$lang->kanbanProject = new stdclass();
$lang->kanbanProject->menu = new stdclass();
$lang->kanbanProject->menu->index = array('link' => "{$lang->kanban->common}|project|index|project=%s");
$lang->kanbanProject->menu->build = array('link' => "{$lang->build->common}|project|build|project=%s");
$lang->kanbanProject->menu->build = array('link' => "{$lang->build->common}|project|build|project=%s", 'subModule' => 'projectbuild');
$lang->kanbanProject->menu->settings = array('link' => "$lang->settings|project|view|project=%s", 'subModule' => 'tree,stakeholder', 'alias' => 'edit,manageproducts,group,managemembers,manageview,managepriv,whitelist,addwhitelist,team');
$lang->kanbanProject->dividerMenu = '';
@@ -343,7 +343,7 @@ $lang->execution->menu->view = array('link' => "$lang->view|execution|grouptas
if($config->edition != 'open') $lang->execution->menu->view = array('link' => "$lang->view|execution|gantt|executionID=%s", 'alias' => 'grouptask,tree,taskeffort,gantt,calendar,relation,maintainrelation');
$lang->execution->menu->storyGroup = array('link' => "{$lang->common->story}|execution|story|executionID=%s",'class' => 'dropdown dropdown-hover', 'subModule' => 'story', 'alias' => 'batchcreate,storykanban');
$lang->execution->menu->story = array('link' => "$lang->SRCommon|execution|story|executionID=%s", 'subModule' => 'story', 'alias' => 'storykanban');
$lang->execution->menu->story = array('link' => "$lang->SRCommon|execution|story|executionID=%s", 'subModule' => 'story', 'alias' => 'storykanban,linkstory');
$lang->execution->menu->qa = array('link' => "{$lang->qa->common}|execution|bug|executionID=%s", 'subModule' => 'bug,testcase,testtask,testreport', 'alias' => 'qa,bug,testcase,testtask,testreport');
$lang->execution->menu->devops = array('link' => "{$lang->repo->common}|repo|browse|repoID=0&branchID=&objectID=%s", 'subModule' => 'repo');
$lang->execution->menu->doc = array('link' => "{$lang->doc->common}|doc|tableContents|type=execution&objectID=%s", 'subModule' => 'doc');
@@ -794,6 +794,9 @@ if(!helper::hasFeature('devops'))
unset($lang->mainNav->devops, $lang->mainNav->menuOrder[35]);
unset($lang->scrum->menu->devops, $lang->scrum->menuOrder[25]);
unset($lang->waterfall->menu->devops, $lang->waterfall->menuOrder[35]);
unset($lang->execution->menu->devops, $lang->execution->menuOrder[45]);
unset($lang->project->noMultiple->scrum->menu->devops, $lang->project->noMultiple->scrum->menuOrder[35]);
unset($lang->scrum->menu->settings['subMenu']->managerepo);
}
if(!helper::hasFeature('kanban'))
+1 -1
View File
@@ -475,7 +475,7 @@ if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i');
if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31');
if(!defined('BRANCH_MAIN')) define('BRANCH_MAIN', '0');
if(!defined('DEFAULT_CARDCOUNT')) define('DEFAULT_CARDCOUNT', '2');
if(!defined('MAX_CARDCOUNT')) define('MAX_CARDCOUNT', '32767');
if(!defined('MAX_CARDCOUNT')) define('MAX_CARDCOUNT', '100');
/* datepicker 时间*/
$lang->datepicker = new stdclass();
+4 -3
View File
@@ -125,7 +125,8 @@ class commonModel extends model
->where('id')->eq($projectID)
->exec();
$this->loadModel('action')->create('project', $projectID, 'syncproject');
$actionType = $project->multiple ? 'syncproject' : 'syncmultipleproject';
$this->loadModel('action')->create('project', $projectID, $actionType);
}
return $project;
}
@@ -1679,7 +1680,7 @@ EOD;
{
if($app->getModuleName() != $module) $app->control->loadModel($module);
$modelClass = class_exists("ext{$module}Model") ? "ext{$module}Model" : $module . "Model";
if(class_exists($modelClass) and is_callable(array($modelClass, 'isClickable')))
if(class_exists($modelClass) and method_exists($modelClass, 'isClickable'))
{
//$clickable = call_user_func_array(array($modelClass, 'isClickable'), array('object' => $object, 'method' => $method));
// fix bug on php 8.0 link: https://www.php.net/manual/zh/function.call-user-func-array.php#125953
@@ -2420,9 +2421,9 @@ EOD;
'message' => array('ajaxgetmessage'),
);
if(!empty($this->app->user->modifyPassword) and (!isset($beforeValidMethods[$module]) or !in_array($method, $beforeValidMethods[$module]))) return print(js::locate(helper::createLink('my', 'changepassword')));
if($this->isOpenMethod($module, $method)) return true;
if(!$this->loadModel('user')->isLogon() and $this->server->php_auth_user) $this->user->identifyByPhpAuth();
if(!$this->loadModel('user')->isLogon() and $this->cookie->za) $this->user->identifyByCookie();
if($this->isOpenMethod($module, $method)) return true;
if(isset($this->app->user))
{
+4 -2
View File
@@ -115,10 +115,12 @@ function renderSpanItem(item, $item)
*/
function renderProductItem(item, $item)
{
var $title = $item.find('.title');
var $title = $item.find('.title');
var isShadow = (typeof(item.shadow) != 'undefined' && item.shadow == '1') ? true : false;
if(!$title.length)
{
if(window.userPrivs.product)
if(window.userPrivs.product && !isShadow)
{
$title = $('<a class="title" />')
.attr('href', $.createLink('product', 'browse', 'productID=' + item._id));
+1
View File
@@ -76,6 +76,7 @@
<?php endif;?>
<?php $tab = '';?>
<?php if($action->objectType == 'meeting') $tab = $action->project ? "data-app='project'" : "data-app='my'";?>
<?php if($action->objectType == 'module' and $config->vision == 'lite') $tab = "data-app='project'";?>
<span class="label-name">
<?php
if(empty($action->objectName) and $action->objectID)
+2 -6
View File
@@ -186,7 +186,7 @@ class cron extends control
/* Skip cron that status is running and run time is less than max. */
if($cronInfo->status == 'running' and (time() - strtotime($cronInfo->lastTime)) < $this->config->cron->maxRunTime) continue;
/* Skip cron that last time is more than this cron time. */
if ('cli' === PHP_SAPI)
if('cli' === PHP_SAPI)
{
if($cronInfo->lastTime >= $cron['time']->format(DT_DATETIME1)) continue;
}
@@ -197,10 +197,7 @@ class cron extends control
if($now > $cron['time'])
{
if (!$this->cron->changeStatusRunning($id, $cronInfo->lastTime))
{
continue;
}
if(!$this->cron->changeStatusRunning($id, $cronInfo->lastTime)) continue;
$parsedCrons[$id]['time'] = $cron['cron']->getNextRunDate();
/* Execution command. */
@@ -259,5 +256,4 @@ class cron extends control
/* Revert cron status to stop. */
$this->cron->markCronStatus('stop', $configID);
}
}
+5 -10
View File
@@ -98,21 +98,16 @@ class cronModel extends model
* Change cron status to running
*
* @param int $cronID
* @param string $lastTime
* @access public
* @return bool|int
* @return bool
*/
public function changeStatusRunning($cronID, $lastTime)
public function changeStatusRunning($cronID)
{
$data = new stdclass();
$data->status = 'running';
$data->status = 'running';
$data->lastTime = date(DT_DATETIME1);
$rows = $this->dao->update(TABLE_CRON)->data($data)
->where('id')->eq($cronID)
->andWhere('status')->ne('running')
->andWhere('lastTime')->eq($lastTime)
->exec();
return dao::isError() ? false : $rows;
$this->dao->update(TABLE_CRON)->data($data)->where('id')->eq($cronID)->exec();
return !dao::isError();
}
/**

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