zentaomax.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <?php
  2. /**
  3. * 关闭需求。
  4. * Close the story.
  5. *
  6. * @param int $storyID
  7. * @param object $postData
  8. * @access public
  9. * @return array|false
  10. */
  11. public function close($storyID, $postData)
  12. {
  13. $result = parent::close($storyID, $postData);
  14. if(dao::isError()) return $result;
  15. $this->syncClose($storyID);
  16. return $result;
  17. }
  18. /**
  19. * 批量关闭需求。
  20. * Batch close the stories.
  21. *
  22. * @param array $stories
  23. * @access public
  24. * @return bool
  25. */
  26. public function batchClose($stories)
  27. {
  28. $result = parent::batchClose($stories);
  29. if(dao::isError()) return $result;
  30. foreach($stories as $storyID => $story) $this->syncClose($storyID);
  31. return $result;
  32. }
  33. /**
  34. * Sync story status.
  35. *
  36. * @param int $storyID
  37. * @access public
  38. * @return void
  39. */
  40. public function syncClose($storyID)
  41. {
  42. $story = $this->getById($storyID);
  43. if($story->type == 'requirement') return false;
  44. /* Get all linked requirements.*/
  45. $relations = $this->getRelation($storyID, $story->type);
  46. if(empty($relations)) return false;
  47. /* Get requirement all related stories.*/
  48. foreach($relations as $id => $title)
  49. {
  50. $stories = $this->getRelation($id, 'requirement');
  51. $storiesStatus = $this->dao->select('status')->from(TABLE_STORY)
  52. ->where('id')->in(array_keys($stories))
  53. ->fetchPairs();
  54. $allClosed = true;
  55. foreach($storiesStatus as $status)
  56. {
  57. if($status != 'closed') $allClosed = false;
  58. }
  59. if($allClosed)
  60. {
  61. $data = new stdclass();
  62. $data->assignedTo = 'closed';
  63. $data->status = 'closed';
  64. $data->lastEditedBy = $this->app->user->account;
  65. $data->lastEditedDate = helper::now();
  66. $data->assignedDate = helper::now();
  67. $data->closedDate = helper::now();
  68. $data->closedBy = $this->app->user->account;
  69. $this->dao->update(TABLE_STORY)->data($data)
  70. ->autoCheck()
  71. ->where('id')->eq($id)->exec();
  72. }
  73. }
  74. }
  75. /**
  76. * Import story to asset lib.
  77. *
  78. * @param int|array|string $storyIDList
  79. * @access public
  80. * @return bool
  81. */
  82. public function importToLib($storyIDList = 0)
  83. {
  84. $data = fixer::input('post')->get();
  85. if(empty($data->lib))
  86. {
  87. dao::$errors['message'] = sprintf($this->lang->error->notempty, $this->lang->story->lib);
  88. return false;
  89. }
  90. $stories = $this->getByList($storyIDList);
  91. $importedStories = $this->dao->select('fromStory,fromVersion')->from(TABLE_STORY)
  92. ->where('lib')->eq($data->lib)
  93. ->andWhere('fromStory')->in($storyIDList)
  94. ->fetchGroup('fromStory');
  95. if(is_numeric($storyIDList) and isset($importedStories[$storyIDList]))
  96. {
  97. dao::$errors['message'] = $this->lang->story->isExist;
  98. return false;
  99. }
  100. /* Remove duplicate story. */
  101. foreach($stories as $story)
  102. {
  103. if(isset($importedStories[$story->id]))
  104. {
  105. foreach($importedStories[$story->id] as $improtedStory)
  106. {
  107. if($improtedStory->fromVersion == $story->version) unset($stories[$story->id]);
  108. }
  109. }
  110. }
  111. $now = helper::now();
  112. $hasApprovePiv = common::hasPriv('assetlib', 'approveStory') or common::hasPriv('assetlib', 'batchApproveStory');
  113. $this->loadModel('action');
  114. /* Create story to asset lib. */
  115. $idMap = array();
  116. foreach($stories as $story)
  117. {
  118. $assetStory = new stdclass();
  119. $assetStory->title = $story->title;
  120. $assetStory->type = $story->type;
  121. $assetStory->keywords = $story->keywords;
  122. $assetStory->pri = $story->pri;
  123. $assetStory->grade = $story->grade;
  124. $assetStory->path = $story->path;
  125. $assetStory->root = $story->root;
  126. $assetStory->parent = $story->parent;
  127. $assetStory->isParent = $story->isParent;
  128. $assetStory->estimate = $story->estimate;
  129. $assetStory->status = $hasApprovePiv ? 'active' : 'draft';
  130. $assetStory->category = $story->category;
  131. $assetStory->lib = $data->lib;
  132. $assetStory->fromStory = $story->id;
  133. $assetStory->fromVersion = $story->version;
  134. $assetStory->openedBy = $this->app->user->account;
  135. $assetStory->openedDate = $now;
  136. if(!empty($data->assignedTo)) $assetStory->assignedTo = $data->assignedTo;
  137. if($hasApprovePiv)
  138. {
  139. $assetStory->assignedTo = $this->app->user->account;
  140. $assetStory->approvedDate = $now;
  141. }
  142. $this->dao->insert(TABLE_STORY)->data($assetStory)->exec();
  143. $assetStoryID = $this->dao->lastInsertID();
  144. $idMap[$story->id] = $assetStoryID;
  145. $storySpec = new stdclass();
  146. $storySpec->story = $assetStoryID;
  147. $storySpec->version = 1;
  148. $storySpec->title = $story->title;
  149. $storySpec->spec = $story->spec;
  150. $storySpec->verify = $story->verify;
  151. $this->dao->insert(TABLE_STORYSPEC)->data($storySpec)->exec();
  152. if(!dao::isError()) $this->action->create('story', $assetStoryID, 'import2StoryLib');
  153. }
  154. $newStories = $this->getByList($idMap);
  155. foreach($newStories as $newStory)
  156. {
  157. $data = new stdclass();
  158. $data->parent = isset($idMap[$newStory->parent]) ? $idMap[$newStory->parent] : $newStory->parent;
  159. $data->root = isset($idMap[$newStory->root]) ? $idMap[$newStory->root] : $newStory->root;
  160. $path = '';
  161. foreach(explode(',', $newStory->path) as $storyID)
  162. {
  163. if(!$storyID) continue;
  164. $path .= isset($idMap[$storyID]) ? $idMap[$storyID] . ',' : $storyID . ',';
  165. }
  166. $data->path = trim($path, ',');
  167. $this->dao->update(TABLE_STORY)->data($data)->where('id')->eq($newStory->id)->exec();
  168. }
  169. return true;
  170. }
  171. /**
  172. * 获取需求关联设计的键值对。
  173. * Get story design pairs.
  174. *
  175. * @param int $projectID
  176. * @param int $storyID
  177. * @access public
  178. * @return array
  179. */
  180. public function getDesignPairs($projectID = 0, $storyID = 0)
  181. {
  182. return $this->dao->select('id, name')->from(TABLE_DESIGN)
  183. ->where('deleted')->eq(0)
  184. ->beginIF($storyID)->andWhere('story')->eq($storyID)->fi()
  185. ->beginIF($projectID)->andwhere('project')->eq($projectID)->fi()
  186. ->fetchPairs();
  187. }