diff --git a/module/bug/model.php b/module/bug/model.php
index 43b034b5cc..54b1989b50 100644
--- a/module/bug/model.php
+++ b/module/bug/model.php
@@ -115,6 +115,17 @@ class bugModel extends model
return $bug;
}
+ /**
+ * Get active Bugs.
+ *
+ * @access public
+ * @return void
+ */
+ public function getActiveBugs($pager)
+ {
+ return $this->dao->select('*')->from(TABLE_BUG)->where('status')->eq('active')->andWhere('toTask')->eq(0)->page($pager)->fetchAll();
+ }
+
/**
* Update a bug.
*
diff --git a/module/common/lang/en.php b/module/common/lang/en.php
index 1218773b11..f888e9ea3c 100644
--- a/module/common/lang/en.php
+++ b/module/common/lang/en.php
@@ -170,7 +170,7 @@ $lang->bug->menu->testtask = array('link' => 'Test Task|testtask|browse|productI
$lang->testcase->menu->product = '%s';
$lang->testcase->menu->bug = array('link' => 'Bug|bug|browse|productID=%s');
-$lang->testcase->menu->testcase = array('link' => 'Test Case|testcase|browse|productID=%s', 'alias' => 'view,create,edit', 'subModule' => 'tree');
+$lang->testcase->menu->testcase = array('link' => 'Test Case|testcase|browse|productID=%s', 'alias' => 'view,create,batchcreate,edit', 'subModule' => 'tree');
$lang->testcase->menu->testtask = array('link' => 'Test Task|testtask|browse|productID=%s');
$lang->testtask->menu->product = '%s';
diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php
index fadd0630d9..3683f19938 100644
--- a/module/common/lang/zh-cn.php
+++ b/module/common/lang/zh-cn.php
@@ -170,7 +170,7 @@ $lang->bug->menu->testtask = array('link' => '测试任务|testtask|browse|produ
$lang->testcase->menu->product = '%s';
$lang->testcase->menu->bug = array('link' => '缺陷管理|bug|browse|productID=%s');
-$lang->testcase->menu->testcase = array('link' => '用例管理|testcase|browse|productID=%s', 'alias' => 'view,create,edit', 'subModule' => 'tree');
+$lang->testcase->menu->testcase = array('link' => '用例管理|testcase|browse|productID=%s', 'alias' => 'view,create,batchcreate,edit', 'subModule' => 'tree');
$lang->testcase->menu->testtask = array('link' => '测试任务|testtask|browse|productID=%s');
$lang->testtask->menu->product = '%s';
diff --git a/module/project/css/task.css b/module/project/css/task.css
new file mode 100644
index 0000000000..5e4c0eeac8
--- /dev/null
+++ b/module/project/css/task.css
@@ -0,0 +1,2 @@
+.bug {color:gray; font-size:9px}
+.task {color:green; font-size:9px}
diff --git a/module/project/view/task.html.php b/module/project/view/task.html.php
index d30766fb23..ddee741161 100644
--- a/module/project/view/task.html.php
+++ b/module/project/view/task.html.php
@@ -62,7 +62,13 @@ var browseType = '';
| id", sprintf('%03d', $task->id))) printf('%03d', $task->id);?> |
task->priList[$task->pri];?> |
- id", $task->name)) echo $task->name;?> |
+
+ fromBug != 0) echo "[BUG] ";
+ else echo "[TASK] ";
+ if(!common::printLink('task', 'view', "task=$task->id", $task->name)) echo $task->name;
+ ?>
+ |
status;?> >
storyStatus == 'active' and $task->latestStoryVersion > $task->storyVersion);
diff --git a/module/project/view/taskheader.html.php b/module/project/view/taskheader.html.php
index 76160192cc..35c11663f2 100644
--- a/module/project/view/taskheader.html.php
+++ b/module/project/view/taskheader.html.php
@@ -21,6 +21,7 @@
export, '', 'class="export"');
common::printLink('project', 'importTask', "project=$project->id", $lang->project->importTask);
+ common::printLink('task', 'importFromBug', "projectID=$project->id", $lang->task->importFromBug);
common::printLink('task', 'report', "project=$project->id&browseType=$browseType", $lang->task->report->common);
common::printLink('task', 'batchCreate', "projectID=$project->id", $lang->task->batchCreate);
common::printLink('task', 'create', "project=$project->id", $lang->task->create);
diff --git a/module/task/control.php b/module/task/control.php
index 65a6d38355..b2df739903 100644
--- a/module/task/control.php
+++ b/module/task/control.php
@@ -664,4 +664,204 @@ class task extends control
$this->display();
}
+
+ /**
+ * Import from Bug.
+ *
+ * @param int $projectID
+ * @param string $orderBy
+ * @param int $recTotal
+ * @param int $recPerPage
+ * @param int $pageID
+ * @access public
+ * @return void
+ */
+ public function importFromBug($projectID = 0, $pager = '', $recTotal = 0, $recPerPage = 30, $pageID = 1)
+ {
+ if(!empty($_POST))
+ {
+ $mails = $this->task->importFromBug($projectID);
+ if(dao::isError()) die(js::error(dao::getError()));
+
+ foreach($mails as $mail)
+ {
+ $this->sendmail($mail->taskID, $mail->actionID);
+ }
+
+ /* Locate the browser. */
+ die(js::locate($this->createLink('project', 'task', "projectID=$projectID"), 'parent'));
+ }
+ $this->loadModel('bug');
+
+ $projects = $this->project->getPairs();
+ $users = $this->project->getTeamMemberPairs($projectID, 'nodeleted');
+
+ /* Load pager and get tasks. */
+ $this->app->loadClass('pager', $static = true);
+ $pager = new pager($recTotal, $recPerPage, $pageID);
+
+ $this->project->setMenu($projects, $projectID);
+ $header['title'] = $projects[$projectID] . $this->lang->colon . $this->lang->task->importFromBug;
+ $position[] = html::a($this->createLink('project', 'task', "projectID=$projectID"), $projects[$projectID]);
+ $position[] = $this->lang->task->importFromBug;
+
+ $bugs = $this->bug->getActiveBugs($pager);
+ $this->view->header = $header;
+ $this->view->pager = $pager;
+ $this->view->bugs = $bugs;
+ $this->view->users = $users;
+ $this->view->projectID = $projectID;
+ $this->display();
+ }
+
+
+ /* task#536.
+ public function importFromBug($projectID = 0, $browseType = 'noclosed', $param = 0, $orderBy = '', $recTotal = 0, $recPerPage = 20, $pageID = 1)
+ {
+ $this->products = $this->loadModel('product')->getPairs();
+ if(empty($this->products))
+ {
+ //echo js::alert($this->lang->product->errorNoProduct);
+ //die(js::locate($this->createLink('product', 'create')));
+ }
+ $this->view->products = $this->products;
+ $projects = $this->project->getPairs('all');
+
+ /* Set browseType and queryID. /
+ $browseType = strtolower($browseType);
+ $queryID = ($browseType == 'bysearch') ? (int)$param : 0;
+
+ /* Set menu and save session. /
+ $this->project->setMenu($this->project->getPairs(), $projectID);
+ $this->session->set('bugList', $this->app->getURI(true));
+
+ /* Process the order by field. /
+ if(!$orderBy) $orderBy = $this->cookie->qaBugOrder ? $this->cookie->qaBugOrder : 'id_desc';
+ setcookie('qaBugOrder', $orderBy, $this->config->cookieLife, $this->config->webRoot);
+
+ /* Load pager. /
+ $this->app->loadClass('pager', $static = true);
+ $pager = pager::init($recTotal, $recPerPage, $pageID);
+
+ $bugs = array();
+ if($browseType == 'all')
+ {
+ $bugs = $this->dao->select('*')->from(TABLE_BUG)->where('product')->eq($productID)
+ ->andWhere('deleted')->eq(0)
+ ->orderBy($orderBy)->page($pager)->fetchAll();
+ }
+ elseif($browseType == 'assigntome')
+ {
+ $bugs = $this->dao->findByAssignedTo($this->app->user->account)->from(TABLE_BUG)->andWhere('product')->eq($productID)
+ ->andWhere('deleted')->eq(0)
+ ->orderBy($orderBy)->page($pager)->fetchAll();
+ }
+ elseif($browseType == 'openedbyme')
+ {
+ $bugs = $this->dao->findByOpenedBy($this->app->user->account)->from(TABLE_BUG)->andWhere('product')->eq($productID)
+ ->andWhere('deleted')->eq(0)
+ ->orderBy($orderBy)->page($pager)->fetchAll();
+ }
+ elseif($browseType == 'resolvedbyme')
+ {
+ $bugs = $this->dao->findByResolvedBy($this->app->user->account)->from(TABLE_BUG)->andWhere('product')->eq($productID)
+ ->andWhere('deleted')->eq(0)
+ ->orderBy($orderBy)->page($pager)->fetchAll();
+ }
+ elseif($browseType == 'assigntonull')
+ {
+ $bugs = $this->dao->findByAssignedTo('')->from(TABLE_BUG)->andWhere('product')->eq($productID)
+ ->andWhere('deleted')->eq(0)
+ ->orderBy($orderBy)->page($pager)->fetchAll();
+ }
+ elseif($browseType == 'unresolved')
+ {
+ $bugs = $this->dao->findByStatus('active')->from(TABLE_BUG)->andWhere('product')->eq($productID)
+ ->andWhere('deleted')->eq(0)
+ ->orderBy($orderBy)->page($pager)->fetchAll();
+ }
+ elseif($browseType == 'longlifebugs')
+ {
+ $bugs = $this->dao->findByLastEditedDate("<", date(DT_DATE1, strtotime('-7 days')))->from(TABLE_BUG)->andWhere('product')->eq($productID)
+ ->andWhere('openedDate')->lt(date(DT_DATE1,strtotime('-7 days')))
+ ->andWhere('deleted')->eq(0)
+ ->andWhere('status')->ne('closed')->orderBy($orderBy)->page($pager)->fetchAll();
+ }
+ elseif($browseType == 'postponedbugs')
+ {
+ $bugs = $this->dao->findByResolution('postponed')->from(TABLE_BUG)->andWhere('product')->eq($productID)
+ ->orderBy($orderBy)->page($pager)->fetchAll();
+ }
+ elseif($browseType == 'needconfirm')
+ {
+ $bugs = $this->dao->select('t1.*, t2.title AS storyTitle')->from(TABLE_BUG)->alias('t1')->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id')
+ ->where("t2.status = 'active'")
+ ->andWhere('t1.deleted')->eq(0)
+ ->andWhere('t2.version > t1.storyVersion')
+ ->orderBy($orderBy)
+ ->fetchAll();
+ }
+ elseif($browseType == 'bysearch')
+ {
+ if($queryID)
+ {
+ $query = $this->loadModel('search')->getQuery($queryID);
+ if($query)
+ {
+ $this->session->set('bugQuery', $query->sql);
+ $this->session->set('bugForm', $query->form);
+ }
+ else
+ {
+ $this->session->set('bugQuery', ' 1 = 1');
+ }
+ }
+ else
+ {
+ if($this->session->bugQuery == false) $this->session->set('bugQuery', ' 1 = 1');
+ }
+ $bugQuery = str_replace("`product` = 'all'", '1', $this->session->bugQuery); // Search all product.
+ $bugs = $this->dao->select('*')->from(TABLE_BUG)->where($bugQuery)
+ ->andWhere('deleted')->eq(0)
+ ->orderBy($orderBy)->page($pager)->fetchAll();
+ }
+
+ / Process the sql, get the conditon partion, save it to session. Thus the report page can use the same condition. /
+ if($browseType != 'needconfirm')
+ {
+ $sql = explode('WHERE', $this->dao->get());
+ $sql = explode('ORDER', $sql[1]);
+ $this->session->set('bugReportCondition', $sql[0]);
+ }
+
+ / Build the search form. /
+ $this->config->bug->search['actionURL'] = $this->createLink('bug', 'browse', "productID=$productID&browseType=bySearch&queryID=myQueryID");
+ $this->config->bug->search['queryID'] = $queryID;
+ $this->config->bug->search['params']['product']['values'] = array($productID => $this->products[$productID], 'all' => $this->lang->bug->allProduct);
+ $this->config->bug->search['params']['module']['values'] = $this->tree->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0);
+ $this->config->bug->search['params']['project']['values'] = $this->product->getProjectPairs($productID);
+ $this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getProductBuildPairs($productID);
+ $this->config->bug->search['params']['resolvedBuild']['values'] = $this->build->getProductBuildPairs($productID);
+ $this->view->searchForm = $this->fetch('search', 'buildForm', $this->config->bug->search);
+
+ $users = $this->loadModel('user')->getPairs('noletter');
+
+ $header['title'] = $projects[$projectID] . $this->lang->colon . $this->lang->task->common;
+ $position[] = html::a($this->createLink('project', 'task', "projectID=$projectID"), $projects[$projectID]);
+ $position[] = $this->lang->task->common;
+
+ $this->view->header = $header;
+ $this->view->position = $position;
+ $this->view->projectID = $projectID;
+ $this->view->projectName = $projects[$projectID];
+ $this->view->browseType = $browseType;
+ $this->view->bugs = $bugs;
+ $this->view->users = $users;
+ $this->view->pager = $pager;
+ $this->view->param = $param;
+ $this->view->orderBy = $orderBy;
+
+ $this->display();
+ }
+ */
}
diff --git a/module/task/css/importfrombug.css b/module/task/css/importfrombug.css
new file mode 100644
index 0000000000..414a6ca6d6
--- /dev/null
+++ b/module/task/css/importfrombug.css
@@ -0,0 +1,6 @@
+.active1 {background:#E70014;}
+.active2 {background:#EA5407;}
+.active3 {background:#F39801;}
+.active4 {background:#FFF100;}
+.active1 a, .active2 a, .active3 a{color:white; text-decoration:none}
+.active4 a {color:blue; text-decoration:none}
diff --git a/module/task/lang/en.php b/module/task/lang/en.php
index 245eaeeeab..27bbfa2f57 100644
--- a/module/task/lang/en.php
+++ b/module/task/lang/en.php
@@ -9,22 +9,25 @@
* @version $Id$
* @link http://www.zentao.net
*/
-$lang->task->index = "Index";
-$lang->task->create = "Create";
-$lang->task->batchCreate = "Batch create";
-$lang->task->import = "Import undone";
-$lang->task->edit = "Update";
-$lang->task->delete = "Delete";
-$lang->task->view = "Info";
-$lang->task->logEfforts = "Efforts";
-$lang->task->start = "Start";
-$lang->task->finish = "Finish";
-$lang->task->close = "Close";
-$lang->task->batchClose = "Batch close";
-$lang->task->cancel = "Cancel";
-$lang->task->activate = "Activate";
-$lang->task->export = "Export";
-$lang->task->reportChart = "Report chart";
+$lang->task->index = "Index";
+$lang->task->create = "Create";
+$lang->task->batchCreate = "Batch create";
+$lang->task->import = "Import undone";
+$lang->task->edit = "Update";
+$lang->task->delete = "Delete";
+$lang->task->view = "Info";
+$lang->task->logEfforts = "Efforts";
+$lang->task->start = "Start";
+$lang->task->finish = "Finish";
+$lang->task->close = "Close";
+$lang->task->batchClose = "Batch close";
+$lang->task->cancel = "Cancel";
+$lang->task->activate = "Activate";
+$lang->task->export = "Export";
+$lang->task->reportChart = "Report chart";
+$lang->task->fromBug = 'From Bug';
+$lang->task->importBug = 'Import';
+$lang->task->importFromBug = 'Import tasks from Bug';
$lang->task->confirmStoryChange = "Confirm story change";
$lang->task->common = 'Task';
@@ -68,8 +71,21 @@ $lang->task->lastEditedBy = 'Last Edited By';
$lang->task->lastEditedDate = 'Last Edited Date';
$lang->task->lastEdited = 'Last Edited';
+$lang->task->bug->assignToMe = 'MyBugs';
+$lang->task->bug->openedByMe = 'MyOpen';
+$lang->task->bug->resolvedByMe = 'MyResolve';
+$lang->task->bug->closedByMe = 'MyClose';
+$lang->task->bug->assignToNull = 'Unassigned';
+$lang->task->bug->unResolved = 'Unresolved';
+$lang->task->bug->longLifeBugs = 'Longlife';
+$lang->task->bug->postponedBugs = 'Postponed';
+$lang->task->bug->moduleBugs = 'ByModule';
+$lang->task->bug->byQuery = 'Search';
+$lang->task->bug->needConfirm = 'StoryChanged';
+
$lang->task->same = 'The same as above';
$lang->task->notes = '(Notes: the name, type, pri and estimate must be written, otherwise it is no use)';
+$lang->task->descFromBug = 'ResolveBug:';
$lang->task->statusList[''] = '';
$lang->task->statusList['wait'] = 'Waiting';
diff --git a/module/task/lang/zh-cn.php b/module/task/lang/zh-cn.php
index 427879f8d9..250e740f39 100644
--- a/module/task/lang/zh-cn.php
+++ b/module/task/lang/zh-cn.php
@@ -9,22 +9,25 @@
* @version $Id$
* @link http://www.zentao.net
*/
-$lang->task->index = "任务一览";
-$lang->task->create = "新增任务";
-$lang->task->batchCreate = "批量添加任务";
-$lang->task->import = "导入之前未完任务";
-$lang->task->edit = "更新任务";
-$lang->task->delete = "删除任务";
-$lang->task->view = "查看任务";
-$lang->task->logEfforts = "记录工时";
-$lang->task->start = "开始任务";
-$lang->task->finish = "完成任务";
-$lang->task->close = "关闭任务";
-$lang->task->batchClose = "批量关闭";
-$lang->task->cancel = "取消任务";
-$lang->task->activate = "激活任务";
-$lang->task->export = "导出数据";
-$lang->task->reportChart = "报表统计";
+$lang->task->index = "任务一览";
+$lang->task->create = "新增任务";
+$lang->task->batchCreate = "批量添加任务";
+$lang->task->import = "导入之前未完任务";
+$lang->task->edit = "更新任务";
+$lang->task->delete = "删除任务";
+$lang->task->view = "查看任务";
+$lang->task->logEfforts = "记录工时";
+$lang->task->start = "开始任务";
+$lang->task->finish = "完成任务";
+$lang->task->close = "关闭任务";
+$lang->task->batchClose = "批量关闭";
+$lang->task->cancel = "取消任务";
+$lang->task->activate = "激活任务";
+$lang->task->export = "导出数据";
+$lang->task->reportChart = "报表统计";
+$lang->task->fromBug = '来源Bug';
+$lang->task->importBug = '导入';
+$lang->task->importFromBug = '导入Bug';
$lang->task->confirmStoryChange = "确认需求变动";
$lang->task->common = '任务';
@@ -68,8 +71,21 @@ $lang->task->lastEditedBy = '最后修改';
$lang->task->lastEditedDate = '最后修改日期';
$lang->task->lastEdited = '最后编辑';
+$lang->task->bug->assignToMe = '指派给我';
+$lang->task->bug->openedByMe = '由我创建';
+$lang->task->bug->resolvedByMe = '由我解决';
+$lang->task->bug->closedByMe = '由我关闭';
+$lang->task->bug->assignToNull = '未指派';
+$lang->task->bug->unResolved = '未解决';
+$lang->task->bug->longLifeBugs = '久未处理';
+$lang->task->bug->postponedBugs = '被延期';
+$lang->task->bug->allBugs = '所有Bug';
+$lang->task->bug->byQuery = '搜索';
+$lang->task->bug->needConfirm = '需求变动';
+
$lang->task->same = '同上';
$lang->task->notes = '(注:“任务类型”、“任务名称”、“优先级”和“预计工时”必需填写,否则此行无效)';
+$lang->task->descFromBug = '解决Bug:';
$lang->task->statusList[''] = '';
$lang->task->statusList['wait'] = '未开始';
diff --git a/module/task/model.php b/module/task/model.php
index 6d95f04a24..aeedadb496 100644
--- a/module/task/model.php
+++ b/module/task/model.php
@@ -141,6 +141,63 @@ class taskModel extends model
return $mails;
}
+ /**
+ * Import task from Bug.
+ *
+ * @param int $projectID
+ * @access public
+ * @return void
+ */
+ public function importFromBug($projectID)
+ {
+ $this->loadModel('bug');
+ $this->loadModel('task');
+ $now = helper::now();
+ $BugToTasks = fixer::input('post')->get();
+ foreach($BugToTasks->import as $key => $value)
+ {
+ $bug = $this->bug->getById($key);
+ $task->project = $projectID;
+ $task->story = $bug->story;
+ $task->storyVersion = $bug->story;
+ $task->fromBug = $key;
+ $task->name = $bug->title;
+ $task->type = 'devel';
+ $task->pri = $BugToTasks->pri[$key];
+ $task->consumed = 0;
+ $task->status = 'wait';
+ $task->statusCustom = 1;
+ $task->desc = $this->lang->task->descFromBug . sprintf('%03d', $key);
+ $task->openedDate = $now;
+ $task->openedBy = $this->app->user->account;
+ if(!empty($BugToTasks->estimate[$key]))
+ {
+ $task->estimate = $BugToTasks->estimate[$key];
+ $task->left = $task->estimate;
+ }
+ if(!empty($BugToTasks->assignedTo[$key]))
+ {
+ $task->assignedTo = $BugToTasks->assignedTo[$key];
+ $task->assignedDate = $now;
+ }
+ $this->dao->insert(TABLE_TASK)->data($task)->checkIF($task->estimate != '', 'estimate', 'float')->exec();
+
+ if(dao::isError())
+ {
+ echo js::error(dao::getError());
+ die(js::reload('parent'));
+ }
+
+ $taskID = $this->dao->lastInsertID();
+ if($task->story != false) $this->story->setStage($tasks->story[$i]);
+ $actionID = $this->loadModel('action')->create('task', $taskID, 'Opened', '');
+ $this->dao->update(TABLE_BUG)->set('toTask')->eq($taskID)->where('id')->eq($key)->exec();
+ $mails[$key]->taskID = $taskID;
+ $mails[$key]->actionID = $actionID;
+ }
+ return $mails;
+ }
+
/**
* Update a task.
*
diff --git a/module/task/view/importfrombug.html.php b/module/task/view/importfrombug.html.php
new file mode 100755
index 0000000000..8e1ff26378
--- /dev/null
+++ b/module/task/view/importfrombug.html.php
@@ -0,0 +1,65 @@
+
+ * @package task
+ * @version $Id$
+ * @link http://www.zentao.net
+ */
+?>
+
+
+
+
diff --git a/module/task/view/view.html.php b/module/task/view/view.html.php
index 515927707b..1d75170659 100644
--- a/module/task/view/view.html.php
+++ b/module/task/view/view.html.php
@@ -12,7 +12,11 @@
?>
+fromBug == 0):?>
'>TASK #id . $lang->colon . $task->name;?>
+
+ '>TASK #id . $lang->colon . $task->name . '('. $lang->task->fromBug . $lang->colon . $task->fromBug . ')';?>
+
session->taskList != false ? $app->session->taskList : $this->createLink('project', 'browse', "projectID=$task->project");
|