From c7395c8b446f758fbc0b6a99904279ad5264d553 Mon Sep 17 00:00:00 2001 From: chenfei Date: Mon, 17 Feb 2020 14:02:00 +0800 Subject: [PATCH] * Merge zentaopms_cmmi to zentaopms_12.0.1 --- db/update12.0.1.sql | 1 + module/block/control.php | 4 +- module/block/model.php | 2 +- module/doc/model.php | 2 +- module/product/control.php | 12 ++-- module/product/model.php | 44 +++++++------ module/product/view/browse.html.php | 10 +-- module/report/model.php | 28 +++++++-- module/story/control.php | 12 ++-- module/story/model.php | 92 ++++++++++++++++++---------- module/story/view/batchedit.html.php | 2 +- module/story/view/create.html.php | 4 +- module/story/view/view.html.php | 4 +- module/tree/model.php | 6 +- module/user/model.php | 2 +- 15 files changed, 144 insertions(+), 81 deletions(-) create mode 100644 db/update12.0.1.sql diff --git a/db/update12.0.1.sql b/db/update12.0.1.sql new file mode 100644 index 0000000000..88ade96e14 --- /dev/null +++ b/db/update12.0.1.sql @@ -0,0 +1 @@ +UPDATE zt_story SET `type` = 'story' WHERE `type` = ''; diff --git a/module/block/control.php b/module/block/control.php index f7960cc286..de00536d33 100644 --- a/module/block/control.php +++ b/module/block/control.php @@ -743,9 +743,10 @@ class block extends control * Print product statistic block. * * @access public + * @param string $storyType requirement|story * @return void */ - public function printProductStatisticBlock() + public function printProductStatisticBlock($storyType = 'story') { if(!empty($this->params->type) and preg_match('/[^a-zA-Z0-9_]/', $this->params->type)) die(); @@ -765,6 +766,7 @@ class block extends control $stories = $this->dao->select('product, stage, COUNT(status) AS count')->from(TABLE_STORY) ->where('deleted')->eq(0) ->andWhere('product')->in($productIdList) + ->beginIF($storyType)->andWhere('type')->eq($storyType)->fi() ->groupBy('product, stage') ->fetchGroup('product', 'stage'); /* Padding the stories to sure all status have records. */ diff --git a/module/block/model.php b/module/block/model.php index 4ca702ab2e..f35d493da6 100644 --- a/module/block/model.php +++ b/module/block/model.php @@ -174,7 +174,7 @@ class blockModel extends model ->beginIF(!$this->app->user->admin)->andWhere('project')->in('0,' . $this->app->user->view->projects)->fi() //Fix bug #2373. ->andWhere('deleted')->eq(0) ->fetch('count'); - $data['stories'] = (int)$this->dao->select('count(*) AS count')->from(TABLE_STORY)->where('assignedTo')->eq($this->app->user->account)->andWhere('deleted')->eq(0)->fetch('count'); + $data['stories'] = (int)$this->dao->select('count(*) AS count')->from(TABLE_STORY)->where('assignedTo')->eq($this->app->user->account)->andWhere('deleted')->eq(0)->andWhere('type')->eq('story')->fetch('count'); $data['projects'] = (int)$this->dao->select('count(*) AS count')->from(TABLE_PROJECT) ->where('status')->notIN('done,closed') ->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->projects)->fi() diff --git a/module/doc/model.php b/module/doc/model.php index 612e27ccf1..ed6d482ef3 100644 --- a/module/doc/model.php +++ b/module/doc/model.php @@ -1314,7 +1314,7 @@ class docModel extends model $searchTitle = $this->get->title; if($type == 'product') { - $storyIdList = $this->dao->select('id')->from(TABLE_STORY)->where('product')->eq($objectID)->andWhere('deleted')->eq('0')->andWhere('product')->in($this->app->user->view->products)->get(); + $storyIdList = $this->dao->select('id')->from(TABLE_STORY)->where('product')->eq($objectID)->andWhere('deleted')->eq('0')->andWhere('product')->in($this->app->user->view->products)->andWhere('type')->eq('story')->get(); $bugIdList = $this->dao->select('id')->from(TABLE_BUG)->where('product')->eq($objectID)->andWhere('deleted')->eq('0')->andWhere('product')->in($this->app->user->view->products)->get(); $releaseIdList = $this->dao->select('id')->from(TABLE_RELEASE)->where('product')->eq($objectID)->andWhere('deleted')->eq('0')->andWhere('product')->in($this->app->user->view->products)->get(); $planIdList = $this->dao->select('id')->from(TABLE_PRODUCTPLAN)->where('product')->eq($objectID)->andWhere('deleted')->eq('0')->andWhere('product')->in($this->app->user->view->products)->get(); diff --git a/module/product/control.php b/module/product/control.php index cf6a27b083..22355c2e9c 100644 --- a/module/product/control.php +++ b/module/product/control.php @@ -93,6 +93,7 @@ class product extends control * @param int $productID * @param string $browseType * @param int $param + * @param string $storyType requirement|story * @param string $orderBy * @param int $recTotal * @param int $recPerPage @@ -100,7 +101,7 @@ class product extends control * @access public * @return void */ - public function browse($productID = 0, $branch = '', $browseType = 'unclosed', $param = 0, $orderBy = '', $recTotal = 0, $recPerPage = 20, $pageID = 1) + public function browse($productID = 0, $branch = '', $browseType = 'unclosed', $param = 0, $storyType = 'story', $orderBy = '', $recTotal = 0, $recPerPage = 20, $pageID = 1) { /* Lower browse type. */ $browseType = strtolower($browseType); @@ -145,7 +146,7 @@ class product extends control $pager = new pager($recTotal, $recPerPage, $pageID); /* Get stories. */ - $stories = $this->product->getStories($productID, $branch, $browseType, $queryID, $moduleID, $sort, $pager); + $stories = $this->product->getStories($productID, $branch, $browseType, $queryID, $moduleID, $storyType, $sort, $pager); /* Process the sql, get the conditon partion, save it to session. */ $this->loadModel('common')->saveQueryCondition($this->dao->get(), 'story', $browseType != 'bysearch'); @@ -158,13 +159,15 @@ class product extends control $storyCases = $this->loadModel('testcase')->getStoryCaseCounts($storyIdList); /* Build search form. */ - $actionURL = $this->createLink('product', 'browse', "productID=$productID&branch=$branch&browseType=bySearch&queryID=myQueryID"); + $actionURL = $this->createLink('product', 'browse', "productID=$productID&branch=$branch&browseType=bySearch&queryID=myQueryID&storyType=$storyType"); $this->config->product->search['onMenuBar'] = 'yes'; $this->product->buildSearchForm($productID, $this->products, $queryID, $actionURL); $showModule = !empty($this->config->datatable->productBrowse->showModule) ? $this->config->datatable->productBrowse->showModule : ''; $this->view->modulePairs = $showModule ? $this->tree->getModulePairs($productID, 'story', $showModule) : array(); + $createModuleLink = $storyType == 'story' ? 'createStoryLink' : 'createRequirementLink'; + /* Assign. */ $this->view->title = $this->products[$productID]. $this->lang->colon . $this->lang->product->browse; $this->view->position[] = $this->products[$productID]; @@ -176,7 +179,7 @@ class product extends control $this->view->stories = $stories; $this->view->plans = $this->loadModel('productplan')->getPairs($productID, $branch); $this->view->summary = $this->product->summary($stories); - $this->view->moduleTree = $this->tree->getTreeMenu($productID, $viewType = 'story', $startModuleID = 0, array('treeModel', 'createStoryLink'), '', $branch); + $this->view->moduleTree = $this->tree->getTreeMenu($productID, $viewType = 'story', $startModuleID = 0, array('treeModel', $createModuleLink), '', $branch); $this->view->parentModules = $this->tree->getParents($moduleID); $this->view->pager = $pager; $this->view->users = $this->user->getPairs('noletter|pofirst|nodeleted'); @@ -194,6 +197,7 @@ class product extends control $this->view->storyCases = $storyCases; $this->view->param = $param; $this->view->products = $this->products; + $this->view->storyType = $storyType; $this->display(); } diff --git a/module/product/model.php b/module/product/model.php index 35085b1af5..508566fd10 100644 --- a/module/product/model.php +++ b/module/product/model.php @@ -547,12 +547,13 @@ class productModel extends model * @param string $browseType * @param int $queryID * @param int $moduleID + * @param string $type requirement|story * @param string $sort * @param object $pager * @access public * @return array */ - public function getStories($productID, $branch, $browseType, $queryID, $moduleID, $sort, $pager) + public function getStories($productID, $branch, $browseType, $queryID, $moduleID, $type = 'story', $sort, $pager) { if(defined('TUTORIAL')) return $this->loadModel('tutorial')->getStories(); @@ -568,21 +569,21 @@ class productModel extends model { $unclosedStatus = $this->lang->story->statusList; unset($unclosedStatus['closed']); - $stories = $this->story->getProductStories($productID, $branch, $modules, array_keys($unclosedStatus), $sort, $pager); + $stories = $this->story->getProductStories($productID, $branch, $modules, array_keys($unclosedStatus), $type, $sort, $pager); } - if($browseType == 'unplan') $stories = $this->story->getByPlan($productID, $queryID, $modules, '', $sort, $pager); - if($browseType == 'allstory') $stories = $this->story->getProductStories($productID, $branch, $modules, 'all', $sort, $pager); - if($browseType == 'bymodule') $stories = $this->story->getProductStories($productID, $branch, $modules, 'all', $sort, $pager); - if($browseType == 'bysearch') $stories = $this->story->getBySearch($productID, $queryID, $sort, $pager, '', $branch); - if($browseType == 'assignedtome') $stories = $this->story->getByAssignedTo($productID, $branch, $modules, $this->app->user->account, $sort, $pager); - if($browseType == 'openedbyme') $stories = $this->story->getByOpenedBy($productID, $branch, $modules, $this->app->user->account, $sort, $pager); - if($browseType == 'reviewedbyme') $stories = $this->story->getByReviewedBy($productID, $branch, $modules, $this->app->user->account, $sort, $pager); - if($browseType == 'closedbyme') $stories = $this->story->getByClosedBy($productID, $branch, $modules, $this->app->user->account, $sort, $pager); - if($browseType == 'draftstory') $stories = $this->story->getByStatus($productID, $branch, $modules, 'draft', $sort, $pager); - if($browseType == 'activestory') $stories = $this->story->getByStatus($productID, $branch, $modules, 'active', $sort, $pager); - if($browseType == 'changedstory') $stories = $this->story->getByStatus($productID, $branch, $modules, 'changed', $sort, $pager); - if($browseType == 'willclose') $stories = $this->story->get2BeClosed($productID, $branch, $modules, $sort, $pager); - if($browseType == 'closedstory') $stories = $this->story->getByStatus($productID, $branch, $modules, 'closed', $sort, $pager); + if($browseType == 'unplan') $stories = $this->story->getByPlan($productID, $queryID, $modules, '', $type, $sort, $pager); + if($browseType == 'allstory') $stories = $this->story->getProductStories($productID, $branch, $modules, 'all', $type, $sort, $pager); + if($browseType == 'bymodule') $stories = $this->story->getProductStories($productID, $branch, $modules, 'all', $type, $sort, $pager); + if($browseType == 'bysearch') $stories = $this->story->getBySearch($productID, $queryID, $sort, $pager, '', $branch, $type); + if($browseType == 'assignedtome') $stories = $this->story->getByAssignedTo($productID, $branch, $modules, $this->app->user->account, $type, $sort, $pager); + if($browseType == 'openedbyme') $stories = $this->story->getByOpenedBy($productID, $branch, $modules, $this->app->user->account, $type, $sort, $pager); + if($browseType == 'reviewedbyme') $stories = $this->story->getByReviewedBy($productID, $branch, $modules, $this->app->user->account, $type, $sort, $pager); + if($browseType == 'closedbyme') $stories = $this->story->getByClosedBy($productID, $branch, $modules, $this->app->user->account, $type, $sort, $pager); + if($browseType == 'draftstory') $stories = $this->story->getByStatus($productID, $branch, $modules, 'draft', $type, $sort, $pager); + if($browseType == 'activestory') $stories = $this->story->getByStatus($productID, $branch, $modules, 'active', $type, $sort, $pager); + if($browseType == 'changedstory') $stories = $this->story->getByStatus($productID, $branch, $modules, 'changed', $type, $sort, $pager); + if($browseType == 'willclose') $stories = $this->story->get2BeClosed($productID, $branch, $modules, $type, $sort, $pager); + if($browseType == 'closedstory') $stories = $this->story->getByStatus($productID, $branch, $modules, 'closed', $type, $sort, $pager); return $stories; } @@ -828,14 +829,19 @@ class productModel extends model * Get product stat by id * * @param int $productID + * @param string $storyType * @access public * @return object|bool */ - public function getStatByID($productID) + public function getStatByID($productID, $storyType = 'story') { if(!$this->checkPriv($productID)) return false; $product = $this->getById($productID); - $stories = $this->dao->select('product, status, count(status) AS count')->from(TABLE_STORY)->where('deleted')->eq(0)->andWhere('product')->eq($productID)->groupBy('product, status')->fetchAll('status'); + $stories = $this->dao->select('product, status, count(status) AS count')->from(TABLE_STORY) + ->where('deleted')->eq(0) + ->andWhere('type')->eq($storyType) + ->andWhere('product')->eq($productID) + ->groupBy('product, status')->fetchAll('status'); /* Padding the stories to sure all status have records. */ foreach(array_keys($this->lang->story->statusList) as $status) { @@ -873,10 +879,11 @@ class productModel extends model * @param object $pager * @param string $status * @param int $line + * @param string $storyType requirement|story * @access public * @return array */ - public function getStats($orderBy = 'order_desc', $pager = null, $status = 'noclosed', $line = 0) + public function getStats($orderBy = 'order_desc', $pager = null, $status = 'noclosed', $line = 0, $storyType = 'story') { $this->loadModel('report'); $this->loadModel('story'); @@ -892,6 +899,7 @@ class productModel extends model $stories = $this->dao->select('product, status, count(status) AS count') ->from(TABLE_STORY) ->where('deleted')->eq(0) + ->andWhere('type')->eq($storyType) ->andWhere('product')->in(array_keys($products)) ->groupBy('product, status') ->fetchGroup('product', 'status'); diff --git a/module/product/view/browse.html.php b/module/product/view/browse.html.php index 3d099cb4ac..9874911c92 100644 --- a/module/product/view/browse.html.php +++ b/module/product/view/browse.html.php @@ -22,7 +22,7 @@ echo $moduleName; if($moduleID) { - $removeLink = $browseType == 'bymodule' ? inlink('browse', "productID=$productID&branch=$branch&browseType=$browseType¶m=0&orderBy=$orderBy&recTotal=0&recPerPage={$pager->recPerPage}") : 'javascript:removeCookieByKey("storyModule")'; + $removeLink = $browseType == 'bymodule' ? inlink('browse', "productID=$productID&branch=$branch&browseType=$browseType¶m=0&storyType=$storyType&orderBy=$orderBy&recTotal=0&recPerPage={$pager->recPerPage}") : 'javascript:removeCookieByKey("storyModule")'; echo html::a($removeLink, "", '', "class='text-muted'"); } ?> @@ -52,20 +52,20 @@ foreach($lang->product->moreSelects as $key => $value) { $active = $key == $storyBrowseType ? 'btn-active-text' : ''; - echo '
  • ' . html::a($this->inlink('browse', "productID=$productID&branch=$branch&browseType=$key"), "{$value}", '', "class='btn btn-link $active'") . '
  • '; + echo '
  • ' . html::a($this->inlink('browse', "productID=$productID&branch=$branch&browseType=$key¶m=0&storyType=$storyType"), "{$value}", '', "class='btn btn-link $active'") . '
  • '; } echo ''; } } elseif($menuItem->name == 'QUERY') { - $searchBrowseLink = inlink('browse', "productID=$productID&branch=$branch&browseType=$menuBrowseType¶m=%s"); + $searchBrowseLink = inlink('browse', "productID=$productID&branch=$branch&browseType=$menuBrowseType¶m=%s&storyType=$storyType"); $isBySearch = $this->session->storyBrowseType == 'bysearch'; include '../../common/view/querymenu.html.php'; } else { - echo html::a($this->inlink('browse', "productID=$productID&branch=$branch&browseType=$menuBrowseType"), "$menuItem->text" . ($menuItem->name == $this->session->storyBrowseType ? ' ' . $pager->recTotal . '' : ''), '', "id='{$menuItem->name}Tab' class='btn btn-link" . ($this->session->storyBrowseType == $menuItem->name ? ' btn-active-text' : '') . "'"); + echo html::a($this->inlink('browse', "productID=$productID&branch=$branch&browseType=$menuBrowseType¶m=0&storyType=$storyType"), "$menuItem->text" . ($menuItem->name == $this->session->storyBrowseType ? ' ' . $pager->recTotal . '' : ''), '', "id='{$menuItem->name}Tab' class='btn btn-link" . ($this->session->storyBrowseType == $menuItem->name ? ' btn-active-text' : '') . "'"); } } ?> @@ -170,7 +170,7 @@ moduleName . ucfirst($this->methodName); $useDatatable = (isset($config->datatable->$datatableId->mode) and $config->datatable->$datatableId->mode == 'datatable'); - $vars = "productID=$productID&branch=$branch&browseType=$browseType¶m=$param&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; + $vars = "productID=$productID&branch=$branch&browseType=$browseType¶m=$param&storyType=$storyType&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; if($useDatatable) include '../../common/view/datatable.html.php'; $setting = $this->datatable->getSetting('product'); diff --git a/module/report/model.php b/module/report/model.php index 815e275c42..72ea75c5c2 100644 --- a/module/report/model.php +++ b/module/report/model.php @@ -134,7 +134,7 @@ class reportModel extends model * @access public * @return array */ - public function getProducts($conditions) + public function getProducts($conditions, $storyType = 'story') { $products = $this->dao->select('id, code, name, PO')->from(TABLE_PRODUCT) ->where('deleted')->eq(0) @@ -162,7 +162,11 @@ class reportModel extends model $planStories = array(); $unplannedStories = array(); - $stmt = $this->dao->select('id,plan,product,status')->from(TABLE_STORY)->where('deleted')->eq(0)->query(); + $stmt = $this->dao->select('id,plan,product,status') + ->from(TABLE_STORY) + ->where('deleted')->eq(0) + ->beginIF($storyType)->andWhere('type')->eq($storyType)->fi() + ->query(); while($story = $stmt->fetch()) { if(empty($story->plan)) @@ -548,12 +552,19 @@ class reportModel extends model * @param array $products * @param string $account * @param int $year + * @param string $type requirement|story * @access public * @return array */ - public function getUserYearStory($products, $account, $year) + public function getUserYearStory($products, $account, $year, $type = 'story') { - $stories = $this->dao->select('*')->from(TABLE_STORY)->where('openedBy')->eq($account)->andWhere('product')->in(array_keys($products))->andWhere('LEFT(openedDate, 4)')->eq($year)->andWhere('deleted')->eq(0)->fetchAll(); + $stories = $this->dao->select('*')->from(TABLE_STORY) + ->where('openedBy')->eq($account) + ->andWhere('product')->in(array_keys($products)) + ->andWhere('LEFT(openedDate, 4)')->eq($year) + ->andWhere('deleted')->eq(0) + ->beginIF($type)->andWhere('type')->eq($type)->fi() + ->fetchAll(); $storyInfo = array(); $storyInfo['count'] = 0; @@ -766,15 +777,17 @@ class reportModel extends model * @param array $products * @param string $account * @param int $year + * @param string $type requirement|story * @access public * @return array */ - public function getStoriesByProducts($products, $account, $year) + public function getStoriesByProducts($products, $account, $year, $type = 'story') { return $this->dao->select('product, count(*) as stories')->from(TABLE_STORY) ->where('product')->in(array_keys($products)) ->andWhere('LEFT(openedDate, 4)')->eq($year) ->andWhere('openedBy')->eq($account) + ->andWhere('type')->eq($type) ->groupBy('product') ->fetchPairs('product', 'stories'); } @@ -921,20 +934,23 @@ class reportModel extends model * @param array $products * @param string $account * @param int $year + * @param string $type requirement|story * @access public * @return array */ - public function getStatByProducts($products, $account, $year) + public function getStatByProducts($products, $account, $year, $type = 'story') { $allStories = $this->dao->select('product, count(*) as count')->from(TABLE_STORY) ->where('product')->in(array_keys($products)) ->andWhere('LEFT(openedDate, 4)')->eq($year) + ->beginIF($type)->andWhere('type')->eq($type)->fi() ->groupBy('product') ->fetchPairs('product', 'count'); $mineStories = $this->dao->select('product, count(*) as count')->from(TABLE_STORY) ->where('product')->in(array_keys($products)) ->andWhere('openedBy')->eq($account) ->andWhere('LEFT(openedDate, 4)')->eq($year) + ->beginIF($type)->andWhere('type')->eq($type)->fi() ->groupBy('product') ->fetchPairs('product', 'count'); diff --git a/module/story/control.php b/module/story/control.php index f72a2988d0..3e363eeba8 100644 --- a/module/story/control.php +++ b/module/story/control.php @@ -39,10 +39,11 @@ class story extends control * @param int $planID * @param int $todoID * @param string $extra for example feedbackID=0 + * @param string $type requirement|story * @access public * @return void */ - public function create($productID = 0, $branch = 0, $moduleID = 0, $storyID = 0, $projectID = 0, $bugID = 0, $planID = 0, $todoID = 0, $extra = '') + public function create($productID = 0, $branch = 0, $moduleID = 0, $storyID = 0, $projectID = 0, $bugID = 0, $planID = 0, $todoID = 0, $extra = '', $type = 'story') { /* Whether there is a object to transfer story, for example feedback. */ $extra = str_replace(array(',', ' '), array('&', ''), $extra); @@ -129,7 +130,7 @@ class story extends control setcookie('storyModule', 0, 0, $this->config->webRoot, '', false, false); $productID = $this->post->product ? $this->post->product : $productID; $branchID = $this->post->branch ? $this->post->branch : $branch; - $response['locate'] = $this->createLink('product', 'browse', "productID=$productID&branch=$branchID&browseType=unclosed¶m=0&orderBy=id_desc"); + $response['locate'] = $this->createLink('product', 'browse', "productID=$productID&branch=$branchID&browseType=unclosed¶m=0&type=$type&orderBy=id_desc"); } else { @@ -273,6 +274,7 @@ class story extends control $this->view->keywords = $keywords; $this->view->mailto = $mailto; $this->view->needReview = ($this->app->user->account == $product->PO || $projectID > 0 || $this->config->story->needReview == 0) ? "checked='checked'" : ""; + $this->view->type = $type; $this->display(); } @@ -286,10 +288,11 @@ class story extends control * @param int $storyID * @param int $project * @param int $plan + * @param string $type requirement|story * @access public * @return void */ - public function batchCreate($productID = 0, $branch = 0, $moduleID = 0, $storyID = 0, $project = 0, $plan = 0) + public function batchCreate($productID = 0, $branch = 0, $moduleID = 0, $storyID = 0, $project = 0, $plan = 0, $type = 'story') { if(!empty($_POST)) { @@ -320,7 +323,7 @@ class story extends control else { setcookie('storyModule', 0, 0, $this->config->webRoot, '', false, false); - die(js::locate($this->createLink('product', 'browse', "productID=$productID&branch=$branch"), 'parent')); + die(js::locate($this->createLink('product', 'browse', "productID=$productID&branch=$branch&browseType=unclosed&queryID=0&type=$type"), 'parent')); } } @@ -394,6 +397,7 @@ class story extends control $this->view->estimate = $estimate; $this->view->storyTitle = $title; $this->view->spec = $spec; + $this->view->type = $type; $this->view->branch = $branch; $this->view->branches = $this->loadModel('branch')->getPairs($productID); $this->view->needReview = ($this->app->user->account == $product->PO || $this->config->story->needReview == 0) ? 0 : 1; diff --git a/module/story/model.php b/module/story/model.php index f73b9fc896..0d7c7b7134 100644 --- a/module/story/model.php +++ b/module/story/model.php @@ -69,16 +69,18 @@ class storyModel extends model * Get stories by idList. * * @param int|array|string $storyIdList + * @param string $type requirement|story * @access public * @return array */ - public function getByList($storyIdList = 0) + public function getByList($storyIdList = 0, $type = 'story') { return $this->dao->select('t1.*, t2.spec, t2.verify')->from(TABLE_STORY)->alias('t1') ->leftJoin(TABLE_STORYSPEC)->alias('t2')->on('t1.id=t2.story') ->where('t1.deleted')->eq(0) ->andWhere('t1.version=t2.version') ->beginIF($storyIdList)->andWhere('t1.id')->in($storyIdList)->fi() + ->beginIF(!$storyIdList)->andWhere('t1.type')->eq($type)->fi() ->fetchAll('id'); } @@ -259,8 +261,9 @@ class storyModel extends model * * @access public * @return int|bool the id of the created story or false when error. + * @return type requirement|story */ - public function batchCreate($productID = 0, $branch = 0) + public function batchCreate($productID = 0, $branch = 0, $type = 'story') { $this->loadModel('action'); $branch = (int)$branch; @@ -296,6 +299,7 @@ class storyModel extends model { if(empty($title)) continue; $story = new stdclass(); + $story->type = $type; $story->branch = isset($stories->branch[$i]) ? $stories->branch[$i] : 0; $story->module = $stories->module[$i]; $story->plan = $stories->plan[$i]; @@ -1384,13 +1388,14 @@ class storyModel extends model * @param int $branch * @param array|string $moduleIdList * @param string $status + * @param string $type requirement|story * @param string $orderBy * @param object $pager * * @access public * @return array */ - public function getProductStories($productID = 0, $branch = 0, $moduleIdList = 0, $status = 'all', $orderBy = 'id_desc', $pager = null) + public function getProductStories($productID = 0, $branch = 0, $moduleIdList = 0, $status = 'all', $type = 'story', $orderBy = 'id_desc', $pager = null) { if(defined('TUTORIAL')) return $this->loadModel('tutorial')->getStories(); @@ -1406,6 +1411,7 @@ class storyModel extends model ->beginIF(!empty($moduleIdList))->andWhere('module')->in($moduleIdList)->fi() ->beginIF($status and $status != 'all')->andWhere('status')->in($status)->fi() ->andWhere('deleted')->eq(0) + ->andWhere('type')->eq($type) ->orderBy($orderBy)->page($pager)->fetchAll(); return $this->mergePlanTitle($productID, $stories, $branch); } @@ -1418,10 +1424,12 @@ class storyModel extends model * @param string $status * @param string $order * @param int $limit + * @param string $type + * @param string $storyType requirement|story * @access public * @return array */ - public function getProductStoryPairs($productID = 0, $branch = 0, $moduleIdList = 0, $status = 'all', $order = 'id_desc', $limit = 0, $type = 'full') + public function getProductStoryPairs($productID = 0, $branch = 0, $moduleIdList = 0, $status = 'all', $order = 'id_desc', $limit = 0, $type = 'full', $storyType = 'story') { if($branch) $branch = "0,$branch";//Fix bug 1059. $stories = $this->dao->select('t1.id, t1.title, t1.module, t1.pri, t1.estimate, t2.name AS product') @@ -1432,6 +1440,7 @@ class storyModel extends model ->beginIF($branch)->andWhere('t1.branch')->in($branch)->fi() ->beginIF($status and $status != 'all')->andWhere('t1.status')->in($status)->fi() ->andWhere('t1.deleted')->eq(0) + ->andWhere('t1.type')->eq($storyType) ->orderBy($order) ->fetchAll(); if(!$stories) return array(); @@ -1443,14 +1452,15 @@ class storyModel extends model * * @param int $productID * @param string $account + * @param string $type requirement|story * @param string $orderBy * @param object $pager * @access public * @return array */ - public function getByAssignedTo($productID, $branch, $modules, $account, $orderBy, $pager) + public function getByAssignedTo($productID, $branch, $modules, $account, $type = 'story', $orderBy, $pager) { - return $this->getByField($productID, $branch, $modules, 'assignedTo', $account, $orderBy, $pager); + return $this->getByField($productID, $branch, $modules, 'assignedTo', $account, $type, $orderBy, $pager); } /** @@ -1458,14 +1468,15 @@ class storyModel extends model * * @param int $productID * @param string $account + * @param string $type requirement|story * @param string $orderBy * @param object $pager * @access public * @return array */ - public function getByOpenedBy($productID, $branch, $modules, $account, $orderBy, $pager) + public function getByOpenedBy($productID, $branch, $modules, $account, $type = 'story', $orderBy, $pager) { - return $this->getByField($productID, $branch, $modules, 'openedBy', $account, $orderBy, $pager); + return $this->getByField($productID, $branch, $modules, 'openedBy', $account, $type, $orderBy, $pager); } /** @@ -1473,14 +1484,15 @@ class storyModel extends model * * @param int $productID * @param string $account + * @param string $type requirement|story * @param string $orderBy * @param object $pager * @access public * @return array */ - public function getByReviewedBy($productID, $branch, $modules, $account, $orderBy, $pager) + public function getByReviewedBy($productID, $branch, $modules, $account, $type = 'story', $orderBy, $pager) { - return $this->getByField($productID, $branch, $modules, 'reviewedBy', $account, $orderBy, $pager, 'include'); + return $this->getByField($productID, $branch, $modules, 'reviewedBy', $account, $type, $orderBy, $pager, 'include'); } /** @@ -1488,45 +1500,48 @@ class storyModel extends model * * @param int $productID * @param string $account + * @param string $type requirement|story * @param string $orderBy * @param object $pager * @return array */ - public function getByClosedBy($productID, $branch, $modules, $account, $orderBy, $pager) + public function getByClosedBy($productID, $branch, $modules, $account, $type = 'story', $orderBy, $pager) { - return $this->getByField($productID, $branch, $modules, 'closedBy', $account, $orderBy, $pager); + return $this->getByField($productID, $branch, $modules, 'closedBy', $account, $type, $orderBy, $pager); } /** * Get stories by status. * * @param int $productID + * @param string $status + * @param string $type requirement|story * @param string $orderBy * @param object $pager - * @param string $status * @access public * @return array */ - public function getByStatus($productID, $branch, $modules, $status, $orderBy, $pager) + public function getByStatus($productID, $branch, $modules, $status, $type = 'story', $orderBy, $pager) { - return $this->getByField($productID, $branch, $modules, 'status', $status, $orderBy, $pager); + return $this->getByField($productID, $branch, $modules, 'status', $status, $type, $orderBy, $pager); } /** * Get stories by plan. * - * @param $productID - * @param $branch - * @param $modules - * @param $plan - * @param $orderBy - * @param $pager + * @param int $productID + * @param int $branch + * @param array $modules + * @param int $plan + * @param string $type requirement|story + * @param string $orderBy + * @param object $pager * * @return array */ - public function getByPlan($productID, $branch, $modules, $plan, $orderBy, $pager) + public function getByPlan($productID, $branch, $modules, $plan, $type = 'story', $orderBy, $pager) { - return $this->getByField($productID, $branch, $modules, 'plan', $plan, $orderBy, $pager); + return $this->getByField($productID, $branch, $modules, 'plan', $plan, $type, $orderBy, $pager); } /** @@ -1535,18 +1550,20 @@ class storyModel extends model * @param int $productID * @param string $fieldName * @param mixed $fieldValue + * @param string $type requirement|story * @param string $orderBy * @param object $pager * @param string $operator equal|include * @access public * @return array */ - public function getByField($productID, $branch, $modules, $fieldName, $fieldValue, $orderBy, $pager, $operator = 'equal') + public function getByField($productID, $branch, $modules, $fieldName, $fieldValue, $type = 'story', $orderBy, $pager, $operator = 'equal') { if(!$this->loadModel('common')->checkField(TABLE_STORY, $fieldName)) return array(); $stories = $this->dao->select('*')->from(TABLE_STORY) ->where('product')->in($productID) ->andWhere('deleted')->eq(0) + ->andWhere('type')->eq($type) ->beginIF($branch)->andWhere("branch")->eq($branch)->fi() ->beginIF($modules)->andWhere("module")->in($modules)->fi() ->beginIF($operator == 'equal')->andWhere($fieldName)->eq($fieldValue)->fi() @@ -1561,15 +1578,17 @@ class storyModel extends model * Get to be closed stories. * * @param int $productID + * @param string $type requirement|story * @param string $orderBy * @param string $pager * @access public * @return array */ - public function get2BeClosed($productID, $branch, $modules, $orderBy, $pager) + public function get2BeClosed($productID, $branch, $modules, $type = 'story', $orderBy, $pager) { $stories = $this->dao->select('*')->from(TABLE_STORY) ->where('product')->in($productID) + ->andWhere('type')->eq($type) ->beginIF($branch)->andWhere("branch")->eq($branch)->fi() ->beginIF($modules)->andWhere("module")->in($modules)->fi() ->andWhere('deleted')->eq(0) @@ -1590,10 +1609,12 @@ class storyModel extends model * @param string $orderBy * @param object $pager * @param string $projectID + * @param int $branch + * @param string $type requirement|story * @access public * @return array */ - public function getBySearch($productID, $queryID, $orderBy, $pager = null, $projectID = '', $branch = 0) + public function getBySearch($productID, $queryID, $orderBy, $pager = null, $projectID = '', $branch = 0, $type = 'story') { if($projectID != '') { @@ -1645,7 +1666,7 @@ class storyModel extends model } $storyQuery = preg_replace("/`plan` +LIKE +'%([0-9]+)%'/i", "CONCAT(',', `plan`, ',') LIKE '%,$1,%'", $storyQuery); - return $this->getBySQL($queryProductID, $storyQuery, $orderBy, $pager); + return $this->getBySQL($queryProductID, $storyQuery, $orderBy, $pager, $type); } /** @@ -1655,10 +1676,11 @@ class storyModel extends model * @param string $sql * @param string $orderBy * @param object $pager + * @param string $type requirement|story * @access public * @return array */ - public function getBySQL($productID, $sql, $orderBy, $pager = null) + public function getBySQL($productID, $sql, $orderBy, $pager = null, $type = 'story') { /* Get plans. */ $plans = $this->dao->select('id,title')->from(TABLE_PRODUCTPLAN) @@ -1672,6 +1694,7 @@ class storyModel extends model ->where($sql) ->beginIF($productID != 'all' and $productID != '')->andWhere('t1.`product`')->eq((int)$productID)->fi() ->andWhere('deleted')->eq(0) + ->andWhere('type')->eq($type) ->orderBy($orderBy) ->page($pager, 't1.id') ->fetchAll('id'); @@ -1695,6 +1718,9 @@ class storyModel extends model * * @param int $projectID * @param string $orderBy + * @param string $type + * @param int $param + * @param object $pager * @access public * @return array */ @@ -1857,14 +1883,16 @@ class storyModel extends model * @param string $type the query type * @param string $orderBy * @param object $pager + * @param string $storyType requirement|story * @access public * @return array */ - public function getUserStories($account, $type = 'assignedTo', $orderBy = 'id_desc', $pager = null) + public function getUserStories($account, $type = 'assignedTo', $orderBy = 'id_desc', $pager = null, $storyType = 'story') { $stories = $this->dao->select('t1.*, t2.name as productTitle')->from(TABLE_STORY)->alias('t1') ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id') ->where('t1.deleted')->eq(0) + ->andWhere('t1.type')->eq($storyType) ->beginIF($type != 'closedBy' and $this->app->moduleName == 'block')->andWhere('t1.status')->ne('closed')->fi() ->beginIF($type != 'all') ->beginIF($type == 'assignedTo')->andWhere('assignedTo')->eq($account)->fi() @@ -1888,14 +1916,16 @@ class storyModel extends model * * @param string $account * @param string $limit + * @param string $type requirement|story * @access public * @return array */ - public function getUserStoryPairs($account, $limit = 10) + public function getUserStoryPairs($account, $limit = 10, $type = 'story') { return $this->dao->select('id, title') ->from(TABLE_STORY) ->where('deleted')->eq(0) + ->andWhere('type')->eq($type) ->andWhere('assignedTo')->eq($account) ->orderBy('id_desc') ->limit($limit) @@ -1953,7 +1983,7 @@ class storyModel extends model */ public function getZeroCase($productID, $orderBy = 'id_desc') { - $allStories = $this->getProductStories($productID, 0, 0, 'all', $orderBy); + $allStories = $this->getProductStories($productID, 0, 0, 'all', 'story', $orderBy); $casedStories = $this->dao->select('DISTINCT story')->from(TABLE_CASE)->where('product')->eq($productID)->andWhere('story')->ne(0)->andWhere('deleted')->eq(0)->fetchAll('story'); foreach($allStories as $key => $story) diff --git a/module/story/view/batchedit.html.php b/module/story/view/batchedit.html.php index 2d66581c75..909e59b349 100644 --- a/module/story/view/batchedit.html.php +++ b/module/story/view/batchedit.html.php @@ -42,7 +42,7 @@ foreach(explode(',', $showFields) as $field) '>story->branch;?> story->module;?> - '>story->planAB;?> + col-plan'>story->planAB;?> story->title;?> '> story->estimateAB;?> '> priAB;?> diff --git a/module/story/view/create.html.php b/module/story/view/create.html.php index f11b1bb186..80c54e50cd 100644 --- a/module/story/view/create.html.php +++ b/module/story/view/create.html.php @@ -58,7 +58,7 @@ - story->planAB;?> + story->planAB;?>
    - + diff --git a/module/story/view/view.html.php b/module/story/view/view.html.php index c394023a4c..0e26604693 100644 --- a/module/story/view/view.html.php +++ b/module/story/view/view.html.php @@ -170,7 +170,7 @@ ?> - + story->plan;?> story->status;?> processStatus('story', $story);?> - + story->stage;?> id}"), $module->name, '_self', "id='module{$module->id}'"); + return html::a(helper::createLink('product', 'browse', "root={$module->root}&branch=&type=byModule¶m={$module->id}&storyType=requirement"), $module->name, '_self', "id='module{$module->id}'"); } /** diff --git a/module/user/model.php b/module/user/model.php index 7052977b78..2c19e719c0 100644 --- a/module/user/model.php +++ b/module/user/model.php @@ -1589,7 +1589,7 @@ class userModel extends model $personalData = array(); $personalData['createdTodo'] = $this->dao->select('count(*) as count')->from(TABLE_TODO)->where('account')->eq($account)->fetch('count'); - $personalData['createdStory'] = $this->dao->select('count(*) as count')->from(TABLE_STORY)->where('openedBy')->eq($account)->andWhere('deleted')->eq('0')->fetch('count'); + $personalData['createdStory'] = $this->dao->select('count(*) as count')->from(TABLE_STORY)->where('openedBy')->eq($account)->andWhere('type')->eq('story')->andWhere('deleted')->eq('0')->fetch('count'); $personalData['finishedTask'] = $this->dao->select('count(*) as count')->from(TABLE_TASK)->where('finishedBy')->eq($account)->andWhere('deleted')->eq('0')->fetch('count'); $personalData['resolvedBug'] = $this->dao->select('count(*) as count')->from(TABLE_BUG)->where('resolvedBy')->eq($account)->andWhere('deleted')->eq('0')->fetch('count'); $personalData['createdCase'] = $this->dao->select('count(*) as count')->from(TABLE_CASE)->where('openedBy')->eq($account)->andWhere('deleted')->eq('0')->fetch('count');