diff --git a/module/issue/config.php b/module/issue/config.php index 7ed6ebfba3..c80ed978c8 100644 --- a/module/issue/config.php +++ b/module/issue/config.php @@ -1,6 +1,12 @@ issue->create = new stdclass(); +$config->issue->edit = new stdclass(); + $config->issue->create->requiredFields = 'title,type,severity'; +$config->issue->edit->requiredFields = 'title,type,severity'; $config->issue->editor = new stdclass(); -$config->issue->editor->create = array('id' => 'desc', 'tools' => 'simpleTools'); +$config->issue->editor->create = array('id' => 'desc', 'tools' => 'simpleTools'); +$config->issue->editor->edit = array('id' => 'desc', 'tools' => 'simpleTools'); +$config->issue->editor->cancel = array('id' => 'desc', 'tools' => 'simpleTools'); +$config->issue->editor->resolve = array('id' => 'resolutionComment', 'tools' => 'simpleTools'); diff --git a/module/issue/control.php b/module/issue/control.php index b537006768..0fb41af1b1 100644 --- a/module/issue/control.php +++ b/module/issue/control.php @@ -24,9 +24,23 @@ class issue extends control */ public function browse($browseType = 'all', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) { + $browseType = strtolower($browseType); + /* Load pager */ + $this->app->loadClass('pager', true); + $pager = pager::init($recTotal, $recPerPage, $pageID); + $this->view->title = $this->lang->issue->common . $this->lang->colon . $this->lang->issue->browse; $this->view->position[] = $this->lang->issue->browse; + $this->view->pager = $pager; + $this->view->recTotal = $recTotal; + $this->view->recPerPage = $recPerPage; + $this->view->pageID = $pageID; + $this->view->orderBy = $orderBy; + $this->view->browseType = $browseType; + $this->view->issueList = $this->issue->getIssueList($browseType, $orderBy, $pager); + $this->view->users = $this->loadModel('user')->getPairs('noletter|pofirst|nodeleted'); + $this->display(); } @@ -40,8 +54,9 @@ class issue extends control { if($_POST) { - $result = $this->issue->create(); + $issueID = $this->issue->create(); if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + $this->loadModel('action')->create('issue', $issueID, 'Opened'); $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inLink('browse', 'browseType=all'))); } @@ -53,8 +68,7 @@ class issue extends control $this->display(); } - - + /** * batchCreate issues * @@ -63,20 +77,194 @@ class issue extends control */ public function batchCreate() { - if($_POST) - { - $results = $this->issue->batchCreate(); - if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); - $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inLink('browse', 'browseType=all'))); - } - + if($_POST) + { + $results = $this->issue->batchCreate(); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inLink('browse', 'browseType=all'))); + } + $this->view->title = $this->lang->issue->common . $this->lang->colon . $this->lang->issue->batchCreate; $this->view->position[] = $this->lang->issue->common; - $this->view->position[] = $this->lang->issue->batchCreate; + $this->view->position[] = $this->lang->issue->batchCreate; $this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted'); - $this->display(); + $this->display(); } + /** + * Delete a issue. + * + * @param int $issueID + * @param string $confirm yes|no + * @access public + * @return void + */ + public function delete($issueID = 0, $confirm = 'no') + { + if($confirm == 'no') + { + die(js::confirm($this->lang->issue->confirmDelete, inLink('delete', "issueID=$issueID&confirm=yes"))); + } + else + { + $this->issue->delete($issueID); + die(js::reload('parent')); + } + } + + /** + * Edit a issue. + * + * @param int $issueID + * @access public + * @return void + */ + public function edit($issueID) + { + if($_POST) + { + $changes = $this->issue->update($issueID); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + + $actionID = $this->loadModel('action')->create('issue', $issueID, 'Edited'); + $this->action->logHistory($actionID, $changes); + $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inLink('browse', 'browseType=all'))); + } + + $this->view->title = $this->lang->issue->common . $this->lang->colon . $this->lang->issue->edit; + $this->view->position[] = $this->lang->issue->common; + $this->view->position[] = $this->lang->issue->edit; + + $this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted'); + $this->view->issue = $this->issue->getByID($issueID); + + $this->display(); + } + + /** + * Assign a issue. + * + * @param int $issueID + * @access public + * @return void + */ + public function assignTo($issueID) + { + if($_POST) + { + $changes = $this->issue->assignTo($issueID); + + if(dao::isError()) die(js::error(dao::getError())); + $actionID = $this->loadModel('action')->create('issue', $issueID, 'Edited'); + + $this->action->logHistory($actionID, $changes); + die(js::closeModal('parent.parent', 'this')); + } + + $this->view->issue = $this->issue->getByID($issueID); + $this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted'); + + $this->display(); + } + + /** + * Close a issue. + * + * @param int $issueID + * @access public + * @return void + */ + public function close($issueID) + { + if($_POST) + { + $changes = $this->issue->close($issueID); + + if(dao::isError()) die(js::error(dao::getError())); + $actionID = $this->loadModel('action')->create('issue', $issueID, 'Edited'); + + $this->action->logHistory($actionID, $changes); + die(js::closeModal('parent.parent', 'this')); + } + + $this->view->issue = $this->issue->getByID($issueID); + + $this->display(); + } + + /** + * Cancel a issue. + * + * @param int $issueID + * @access public + * @return void + */ + public function cancel($issueID) + { + if($_POST) + { + $changes = $this->issue->cancel($issueID); + + if(dao::isError()) die(js::error(dao::getError())); + $actionID = $this->loadModel('action')->create('issue', $issueID, 'Edited'); + + $this->action->logHistory($actionID, $changes); + die(js::closeModal('parent.parent', 'this')); + } + + $this->view->issue = $this->issue->getByID($issueID); + + $this->display(); + } + + /** + * Activate a issue. + * + * @param int $issueID + * @access public + * @return void + */ + public function activate($issueID) + { + if($_POST) + { + $changes = $this->issue->activate($issueID); + + if(dao::isError()) die(js::error(dao::getError())); + $actionID = $this->loadModel('action')->create('issue', $issueID, 'Edited'); + + $this->action->logHistory($actionID, $changes); + die(js::closeModal('parent.parent', 'this')); + } + + $this->view->issue = $this->issue->getByID($issueID); + $this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted'); + + $this->display(); + } + + /** + * Resolve a issue. + * + * @param int $issue + * @access public + * @return void + */ + public function resolve($issue) + { + if($_POST) + { + $this->issue->resolve($issue); + $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse'))); + } + + $this->view->title = $this->lang->issue->resolved; + $this->view->issue = $this->issue->getByID($issue); + $this->view->users = $this->loadModel('user')->getPairs('noletter'); + + $this->display(); + } +>>>>>>> Stashed changes } diff --git a/module/issue/lang/zh-cn.php b/module/issue/lang/zh-cn.php index fda597551e..3f74e74db2 100644 --- a/module/issue/lang/zh-cn.php +++ b/module/issue/lang/zh-cn.php @@ -29,11 +29,16 @@ $lang->issue->assignedBy = '由谁指派'; $lang->issue->assignedDate = '指派时间'; $lang->issue->resolved = '解决'; -$lang->issue->create = '新建'; +$lang->issue->delete = '删除'; +$lang->issue->active = '激活'; +$lang->issue->assign = '指派'; +$lang->issue->create = '新建问题'; +$lang->issue->edit = '编辑问题'; $lang->issue->batchCreate = '批量新建'; +$lang->issue->labelList['all'] = '全部'; $lang->issue->labelList['open'] = '开放'; -$lang->issue->labelList['assignTo'] = '指派给我'; +$lang->issue->labelList['assignto'] = '指派给我'; $lang->issue->labelList['closed'] = '已关闭'; $lang->issue->labelList['suspended'] = '已挂起'; $lang->issue->labelList['cancelled'] = '已取消'; @@ -72,4 +77,14 @@ $lang->issue->statusList['unresolved'] = '正解决'; $lang->issue->statusList['resolved'] = '已解决'; $lang->issue->statusList['canceled'] = '取消'; $lang->issue->statusList['closed'] = '已关闭'; +$lang->issue->statusList['active'] = '激活'; +$lang->issue->statusList['suspended'] = '挂起'; +$lang->issue->resolveMethods = array(); +$lang->issue->resolveMethods['resolved'] = '已解决'; +$lang->issue->resolveMethods['totask'] = '转任务'; +$lang->issue->resolveMethods['tobug'] = '转BUG'; +$lang->issue->resolveMethods['tostory'] = '转需求'; +$lang->issue->resolveMethods['torisk'] = '转风险'; + +$lang->issue->confirmDelete = '您确认删除该问题?'; diff --git a/module/issue/model.php b/module/issue/model.php index 0f53e7d601..20e16698b5 100644 --- a/module/issue/model.php +++ b/module/issue/model.php @@ -13,12 +13,20 @@ add('createdBy', $this->app->user->account) ->add('createdDate', $now) + ->add('program', $this->session->program) + ->remove('labels,files') ->addIF($this->post->assignedTo, 'assignedBy', $this->app->user->account) ->addIF($this->post->assignedTo, 'assignedDate', $now) ->stripTags($this->config->issue->editor->create['id'], $this->config->allowedTags) @@ -43,9 +51,178 @@ class issueModel extends model } $this->dao->insert(TABLE_ISSUE)->data($data)->exec(); - return true; + $issueID = $this->dao->lastInsertID(); + $this->loadModel('file')->saveUpload('issue', $issueID); + + return $issueID; } - + + /** + * Get question list data. + * + * @param string $browseType + * @param string $orderBy + * @param object $pager + * @access public + * @return object + */ + public function getIssueList($browseType = 'all', $orderBy = 'id_desc', $pager = null) + { + $issueList = $this->dao->select('*')->from(TABLE_ISSUE) + ->where('program')->eq($this->session->program) + ->andWhere('deleted')->eq('0') + ->beginIF($browseType == 'open')->andWhere('status')->eq('active')->fi() + ->beginIF($browseType == 'assignto')->andWhere('assignedTo')->eq($this->app->user->account)->fi() + ->beginIF($browseType == 'closed')->andWhere('status')->eq('closed')->fi() + ->beginIF($browseType == 'suspended')->andWhere('status')->eq('suspended')->fi() + ->beginIF($browseType == 'cancelled')->andWhere('status')->eq('canceled')->fi() + ->orderBy($orderBy) + ->page($pager) + ->fetchAll(); + + return $issueList; + } + + /** + * Delete a question. + * + * @param int $issueID + * @param int $null + * @access public + * @return object + */ + public function delete($issueID = 0, $null = null) + { + $this->dao->update(TABLE_ISSUE)->set('deleted')->eq('1')->where('id')->eq($issueID)->exec(); + } + + /** + * Get a issue details. + * + * @param int $issueID + * @access public + * @return object + */ + public function getByID($issueID) + { + return $this->dao->select('*')->from(TABLE_ISSUE)->where('id')->eq($issueID)->andWhere('deleted')->eq('0')->fetch(); + } + + /** + * Update a question. + * + * @param int $issueID + * @access public + * @return bool + */ + public function update($issueID) + { + $now = helper::now(); + $data = fixer::input('post') + ->add('editedBy', $this->app->user->account) + ->add('editedDate', $now) + ->addIF($this->post->assignedTo, 'assignedBy', $this->app->user->account) + ->addIF($this->post->assignedTo, 'assignedDate', $now) + ->stripTags($this->config->issue->editor->edit['id'], $this->config->allowedTags) + ->get(); + + if(strpos($this->config->issue->edit->requiredFields, 'type') !== false and !$this->post->type) + { + dao::$errors[] = sprintf($this->lang->error->notempty, $this->lang->issue->type); + return false; + } + + if(strpos($this->config->issue->edit->requiredFields, 'title') !== false and !$this->post->title) + { + dao::$errors[] = sprintf($this->lang->error->notempty, $this->lang->issue->title); + return false; + } + + if(strpos($this->config->issue->edit->requiredFields, 'severity') !== false and !$this->post->severity) + { + dao::$errors[] = sprintf($this->lang->error->notempty, $this->lang->issue->severity); + return false; + } + $oldIssue = $this->getByID($issueID); + + $this->dao->update(TABLE_ISSUE)->data($data)->where('id')->eq($issueID)->exec(); + return common::createChanges($oldIssue, $data); + } + + /** + * Update assignor. + * + * @param int $issueID + * @access public + * @return bool + */ + public function assignTo($issueID) + { + $data = fixer::input('post') + ->add('assignedBy', $this->app->user->account) + ->add('assignedDate', helper::now()) + ->get(); + + $oldIssue = $this->getByID($issueID); + $this->dao->update(TABLE_ISSUE)->data($data)->where('id')->eq($issueID)->exec(); + + return common::createChanges($oldIssue, $data); + } + + /** + * Close issue. + * + * @param int $issueID + * @access public + * @return bool + */ + public function close($issueID) + { + $data = fixer::input('post') + ->add('closeBy', $this->app->user->account) + ->add('status', 'closed') + ->get(); + + $oldIssue = $this->getByID($issueID); + $this->dao->update(TABLE_ISSUE)->data($data)->where('id')->eq($issueID)->exec(); + + return common::createChanges($oldIssue, $data); + } + + /** + * Cancel issue. + * + * @param int $issueID + * @access public + * @return bool + */ + public function cancel($issueID) + { + $data = fixer::input('post')->get(); + $oldIssue = $this->getByID($issueID); + $this->dao->update(TABLE_ISSUE)->data($data)->where('id')->eq($issueID)->exec(); + + return common::createChanges($oldIssue, $data); + } + + /** + * Activate issue. + * + * @param int $issueID + * @access public + * @return bool + */ + public function activate($issueID) + { + $data = fixer::input('post') + ->add('status', 'active') + ->get(); + $oldIssue = $this->getByID($issueID); + $this->dao->update(TABLE_ISSUE)->data($data)->where('id')->eq($issueID)->exec(); + + return common::createChanges($oldIssue, $data); + } + /** * Batch create issue. * @@ -55,33 +232,32 @@ class issueModel extends model public function batchCreate() { $now = helper::now(); - $data = fixer::input('post')->get(); + $data = fixer::input('post')->get(); - $issues = array(); - foreach($data->dataList as $issue) - { - if(!trim($issue['title'])) continue; + $issues = array(); + foreach($data->dataList as $issue) + { + if(!trim($issue['title'])) continue; - $issue['createdBy'] = $this->app->user->account; - $issue['createdDate'] = $now; + $issue['createdBy'] = $this->app->user->account; + $issue['createdDate'] = $now; - if($issue['assignedTo']) - { - $issue['assignedBy'] = $this->app->user->account; - $issue['assignedDate'] = $now; - } + if($issue['assignedTo']) + { + $issue['assignedBy'] = $this->app->user->account; + $issue['assignedDate'] = $now; + } - foreach(explode(',',$this->config->issue->create->requiredFields) as $field) - { - $field = trim($field); - if($field and empty($issue["$field"])) die(js::alert(sprintf($this->lang->error->notempty, $this->lang->issue->$field))); - } + foreach(explode(',',$this->config->issue->create->requiredFields) as $field) + { + $field = trim($field); + if($field and empty($issue["$field"])) die(js::alert(sprintf($this->lang->error->notempty, $this->lang->issue->$field))); + } - $issues[] = $issue; - } + $issues[] = $issue; + } + foreach($issues as $issue) $this->dao->insert(TABLE_ISSUE)->data($issue)->exec(); - foreach($issues as $issue) $this->dao->insert(TABLE_ISSUE)->data($issue)->exec(); - - return true; + return true; } } diff --git a/module/issue/view/activate.html.php b/module/issue/view/activate.html.php new file mode 100644 index 0000000000..70c9d980d0 --- /dev/null +++ b/module/issue/view/activate.html.php @@ -0,0 +1,43 @@ + + * @package issue + * @version $Id: complete.html.php 935 2010-07-06 07:49:24Z jajacn@126.com $ + * @link http://www.zentao.net + */ +?> + +