diff --git a/extension/lite/story/ext/view/batchcreate.html.php b/extension/lite/story/ext/view/batchcreate.html.php index 0dd9d87f52..17effdc417 100644 --- a/extension/lite/story/ext/view/batchcreate.html.php +++ b/extension/lite/story/ext/view/batchcreate.html.php @@ -36,7 +36,7 @@ } unset($visibleFields['module']); ?> -
+
diff --git a/module/custom/config.php b/module/custom/config.php index dca615e25c..6d1b7729cf 100644 --- a/module/custom/config.php +++ b/module/custom/config.php @@ -43,8 +43,8 @@ $config->custom->fieldList['project']['create'] = 'budget,PM,desc'; $config->custom->fieldList['project']['edit'] = 'budget,PM,desc'; $config->custom->fieldList['product']['create'] = 'PO,QD,RD,type,desc'; $config->custom->fieldList['product']['edit'] = 'PO,QD,RD,type,desc,status'; -$config->custom->fieldList['story']['create'] = 'module,plan,source,pri,estimate,keywords,spec'; -$config->custom->fieldList['story']['change'] = 'comment,spec'; +$config->custom->fieldList['story']['create'] = 'module,plan,source,pri,estimate,keywords,spec,verify'; +$config->custom->fieldList['story']['change'] = 'comment,spec,verify'; $config->custom->fieldList['story']['close'] = 'comment'; $config->custom->fieldList['story']['review'] = 'reviewedDate,comment'; $config->custom->fieldList['productplan'] = 'begin,end,desc'; diff --git a/module/kanban/js/view.js b/module/kanban/js/view.js index 25e8edf42f..b2ead23b73 100644 --- a/module/kanban/js/view.js +++ b/module/kanban/js/view.js @@ -472,7 +472,6 @@ function renderExecutionItem(item, $item) ].join('')).appendTo($item); var $titleBox = $header.children('.executionName'); - debugger if(!$titleBox.length) $titleBox = $( [ '
', diff --git a/module/story/control.php b/module/story/control.php index d380938315..6233cbde13 100755 --- a/module/story/control.php +++ b/module/story/control.php @@ -576,7 +576,7 @@ class story extends control if(!empty($_POST)) { $mails = $this->story->batchCreate($productID, $branch, $storyType); - if(dao::isError()) return print(js::error(dao::getError())); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); $stories = array(); foreach($mails as $mail) $stories[] = $mail->storyID; @@ -600,7 +600,7 @@ class story extends control if($storyID and !empty($mails)) { $this->story->subdivide($storyID, $stories); - if(dao::isError()) return print(js::error(dao::getError())); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); } if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'idList' => $stories)); @@ -619,7 +619,7 @@ class story extends control $rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : ''; $kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue); $kanbanData = json_encode($kanbanData); - return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)")); + return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.parent.updateKanban($kanbanData)")); } else { @@ -628,12 +628,12 @@ class story extends control $kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData); $kanbanData = $kanbanData[$kanbanType]; $kanbanData = json_encode($kanbanData); - return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"story\", $kanbanData)")); + return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.parent.updateKanban(\"story\", $kanbanData)")); } } else { - return print(js::reload('parent.parent')); + return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => 'reloadByAjaxForm()')); } } @@ -641,24 +641,26 @@ class story extends control { if($this->app->tab == 'product') { - return print(js::locate(inlink('view', "storyID=$storyID&version=0¶m=0&storyType=$storyType"), 'parent')); + $locateLink = $this->inlink('view', "storyID=$storyID&version=0¶m=0&storyType=$storyType"); + return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $locateLink)); } else { + /* Lite. */ $locateLink = $this->session->storyList ? $this->session->storyList : $this->createLink('projectstory', 'view', "storyID=$storyID"); - return print(js::locate($locateLink, 'parent')); + return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $locateLink)); } } elseif($executionID) { setcookie('storyModuleParam', 0, 0, $this->config->webRoot, '', $this->config->cookieSecure, false); - return print(js::locate($this->session->storyList, 'parent')); + return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->session->storyList)); } else { setcookie('storyModule', 0, 0, $this->config->webRoot, '', $this->config->cookieSecure, false); $locateLink = $this->session->storyList ? $this->session->storyList : $this->createLink('product', 'browse', "productID=$productID&branch=$branch&browseType=unclosed&queryID=0&storyType=$storyType"); - return print(js::locate($locateLink, 'parent')); + return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $locateLink)); } } @@ -1211,7 +1213,7 @@ class story extends control if(dao::isError()) { if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'fail', 'message' => dao::getError())); - return print(js::error(dao::getError())); + return $this->send(array('result' => 'fail', 'message' => dao::getError())); } if($this->post->comment != '' or !empty($changes)) @@ -1241,7 +1243,7 @@ class story extends control $rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : ''; $kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue); $kanbanData = json_encode($kanbanData); - return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)")); + return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.parent.updateKanban($kanbanData)")); } if($from == 'taskkanban') { @@ -1250,12 +1252,12 @@ class story extends control $kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData); $kanbanData = $kanbanData[$kanbanType]; $kanbanData = json_encode($kanbanData); - return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"story\", $kanbanData)")); + return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.parent.updateKanban(\"story\", $kanbanData)")); } } else { - return print(js::reload('parent.parent')); + return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => 'reloadByAjaxForm()')); } } diff --git a/module/story/css/batchcreate.css b/module/story/css/batchcreate.css index 0cae942aed..fad4522720 100644 --- a/module/story/css/batchcreate.css +++ b/module/story/css/batchcreate.css @@ -11,3 +11,5 @@ #batchCreateForm .c-keywords {width: 140px;} .body-modal .main-header > h2 {max-width: 80%;} #batchCreateForm .reviewBox{width: 200px !important;} + +.table tbody>tr>td {vertical-align: top;} diff --git a/module/story/js/common.js b/module/story/js/common.js index 3edd5daa0e..001e955db7 100644 --- a/module/story/js/common.js +++ b/module/story/js/common.js @@ -153,3 +153,14 @@ function popoverCancel(index) $('[data-id="' + index + '"]').addClass('hide'); } + +/** + * Reload parent window When operating in a pop-up window. + * + * @access public + * @return void + */ +function reloadByAjaxForm() +{ + parent.location.reload(); +} diff --git a/module/story/model.php b/module/story/model.php index 6bae7bbe42..aebce8b6bc 100644 --- a/module/story/model.php +++ b/module/story/model.php @@ -541,8 +541,7 @@ class storyModel extends model { if(empty($title) and $this->common->checkValidRow('story', $stories, $i)) { - dao::$errors['message'][] = sprintf($this->lang->error->notempty, $this->lang->story->title); - return false; + dao::$errors["title$i"][] = sprintf($this->lang->error->notempty, $this->lang->story->title); } $module = $stories->module[$i] == 'ditto' ? $module : $stories->module[$i]; @@ -571,8 +570,7 @@ class storyModel extends model $_POST['reviewer'][$i] = $reviewers; if(empty($stories->reviewer[$i]) and $forceReview) { - dao::$errors[] = $this->lang->story->errorEmptyReviewedBy; - return false; + dao::$errors["reviewer$i"][] = $this->lang->story->errorEmptyReviewedBy; } $story = new stdclass(); @@ -587,6 +585,7 @@ class storyModel extends model $story->pri = $stories->pri[$i]; $story->estimate = $stories->estimate[$i]; $story->spec = $stories->spec[$i]; + $story->verify = $stories->verify[$i]; $story->status = $saveDraft ? 'draft' : ((empty($stories->reviewer[$i]) and !$forceReview) ? 'active' : 'reviewing'); $story->stage = ($this->app->tab == 'project' or $this->app->tab == 'execution') ? 'projected' : 'wait'; $story->keywords = $stories->keywords[$i]; @@ -605,8 +604,7 @@ class storyModel extends model $story->{$extendField->field} = htmlSpecialString($story->{$extendField->field}); if(empty($story->{$extendField->field})) { - dao::$errors[] = sprintf($this->lang->error->notempty, $extendField->name); - return false; + dao::$errors["{$extendField->field}$i"][] = sprintf($this->lang->error->notempty, $extendField->name); } } @@ -620,8 +618,7 @@ class storyModel extends model if(!empty($story->$field)) continue; if($field == 'estimate' and strlen(trim($story->estimate)) != 0) continue; - dao::$errors['message'][] = sprintf($this->lang->error->notempty, $this->lang->story->$field); - return false; + dao::$errors["{$field}$i"][] = sprintf($this->lang->error->notempty, $this->lang->story->$field); } $data[$i] = $story; } @@ -629,96 +626,95 @@ class storyModel extends model $link2Plans = array(); foreach($data as $i => $story) { - $this->dao->insert(TABLE_STORY)->data($story, 'spec')->autoCheck()->checkFlow()->exec(); - if(dao::isError()) + $this->dao->insert(TABLE_STORY)->data($story, 'spec,verify')->autoCheck()->checkFlow()->exec(); + if(!dao::isError()) { - echo js::error(dao::getError()); - return print(js::reload('parent')); - } + $storyID = $this->dao->lastInsertID(); + $this->setStage($storyID); - $storyID = $this->dao->lastInsertID(); - $this->setStage($storyID); - - /* Update product plan stories order. */ - if($story->plan) - { - $this->updateStoryOrderOfPlan($storyID, $story->plan); - $link2Plans[$story->plan] = empty($link2Plans[$story->plan]) ? $storyID : "{$link2Plans[$story->plan]},$storyID"; - } - - $specData = new stdclass(); - $specData->story = $storyID; - $specData->version = 1; - $specData->title = $stories->title[$i]; - $specData->spec = ''; - $specData->verify = ''; - if(!empty($stories->spec[$i])) $specData->spec = nl2br($stories->spec[$i]); - if(!empty($stories->verify[$i]))$specData->verify = nl2br($stories->verify[$i]); - - if(!empty($stories->uploadImage[$i])) - { - $fileName = $stories->uploadImage[$i]; - $file = $this->session->storyImagesFile[$fileName]; - - $realPath = $file['realpath']; - unset($file['realpath']); - - if(!is_dir($this->file->savePath)) mkdir($this->file->savePath, 0777, true); - if($realPath and rename($realPath, $this->file->savePath . $this->file->getSaveName($file['pathname']))) + /* Update product plan stories order. */ + if($story->plan) { - $file['addedBy'] = $this->app->user->account; - $file['addedDate'] = $now; - $file['objectType'] = 'story'; - $file['objectID'] = $storyID; - if(in_array($file['extension'], $this->config->file->imageExtensions)) - { - $file['extra'] = 'editor'; - $this->dao->insert(TABLE_FILE)->data($file)->exec(); + $this->updateStoryOrderOfPlan($storyID, $story->plan); + $link2Plans[$story->plan] = empty($link2Plans[$story->plan]) ? $storyID : "{$link2Plans[$story->plan]},$storyID"; + } - $fileID = $this->dao->lastInsertID(); - $specData->spec .= ''; - } - else + $specData = new stdclass(); + $specData->story = $storyID; + $specData->version = 1; + $specData->title = $stories->title[$i]; + $specData->spec = ''; + $specData->verify = ''; + if(!empty($stories->spec[$i])) $specData->spec = nl2br($stories->spec[$i]); + if(!empty($stories->verify[$i]))$specData->verify = nl2br($stories->verify[$i]); + + if(!empty($stories->uploadImage[$i]) and $stories->uploadImage[$i] !== 'undefined') + { + $fileName = $stories->uploadImage[$i]; + $file = $this->session->storyImagesFile[$fileName]; + + $realPath = $file['realpath']; + unset($file['realpath']); + + if(!is_dir($this->file->savePath)) mkdir($this->file->savePath, 0777, true); + if($realPath and rename($realPath, $this->file->savePath . $this->file->getSaveName($file['pathname']))) { - $this->dao->insert(TABLE_FILE)->data($file)->exec(); + $file['addedBy'] = $this->app->user->account; + $file['addedDate'] = $now; + $file['objectType'] = 'story'; + $file['objectID'] = $storyID; + if(in_array($file['extension'], $this->config->file->imageExtensions)) + { + $file['extra'] = 'editor'; + $this->dao->insert(TABLE_FILE)->data($file)->exec(); + + $fileID = $this->dao->lastInsertID(); + $specData->spec .= ''; + } + else + { + $this->dao->insert(TABLE_FILE)->data($file)->exec(); + } } } + + $this->dao->insert(TABLE_STORYSPEC)->data($specData)->exec(); + + /* Save the story reviewer to storyreview table. */ + foreach($_POST['reviewer'][$i] as $reviewer) + { + if(empty($reviewer)) continue; + + $reviewData = new stdclass(); + $reviewData->story = $storyID; + $reviewData->version = 1; + $reviewData->reviewer = $reviewer; + $this->dao->insert(TABLE_STORYREVIEW)->data($reviewData)->exec(); + } + + $this->executeHooks($storyID); + + $actionID = $this->action->create('story', $storyID, 'Opened', ''); + if(!dao::isError()) $this->loadModel('score')->create('story', 'create',$storyID); + $mails[$i] = new stdclass(); + $mails[$i]->storyID = $storyID; + $mails[$i]->actionID = $actionID; } - $this->dao->insert(TABLE_STORYSPEC)->data($specData)->exec(); - - /* Save the story reviewer to storyreview table. */ - foreach($_POST['reviewer'][$i] as $reviewer) - { - if(empty($reviewer)) continue; - - $reviewData = new stdclass(); - $reviewData->story = $storyID; - $reviewData->version = 1; - $reviewData->reviewer = $reviewer; - $this->dao->insert(TABLE_STORYREVIEW)->data($reviewData)->exec(); - } - - $this->executeHooks($storyID); - - $actionID = $this->action->create('story', $storyID, 'Opened', ''); - if(!dao::isError()) $this->loadModel('score')->create('story', 'create',$storyID); - $mails[$i] = new stdclass(); - $mails[$i]->storyID = $storyID; - $mails[$i]->actionID = $actionID; } - /* Remove upload image file and session. */ - if(!empty($stories->uploadImage) and $this->session->storyImagesFile) - { - $classFile = $this->app->loadClass('zfile'); - $file = current($_SESSION['storyImagesFile']); - $realPath = dirname($file['realpath']); - if(is_dir($realPath)) $classFile->removeDir($realPath); - unset($_SESSION['storyImagesFile']); - } if(!dao::isError()) { + /* Remove upload image file and session. */ + if(!empty($stories->uploadImage) and $this->session->storyImagesFile) + { + $classFile = $this->app->loadClass('zfile'); + $file = current($_SESSION['storyImagesFile']); + $realPath = dirname($file['realpath']); + if(is_dir($realPath)) $classFile->removeDir($realPath); + unset($_SESSION['storyImagesFile']); + } + $this->loadModel('score')->create('ajax', 'batchCreate'); foreach($link2Plans as $planID => $stories) $this->action->create('productplan', $planID, 'linkstory', '', $stories); } diff --git a/module/story/view/batchcreate.html.php b/module/story/view/batchcreate.html.php index df03cbafa5..c1e848640c 100755 --- a/module/story/view/batchcreate.html.php +++ b/module/story/view/batchcreate.html.php @@ -46,7 +46,7 @@ } unset($visibleFields['module']); ?> - +
diff --git a/module/story/view/change.html.php b/module/story/view/change.html.php index df9ed6da77..64aaca6944 100644 --- a/module/story/view/change.html.php +++ b/module/story/view/change.html.php @@ -21,7 +21,7 @@ arrow . ' ' . $lang->story->change;?> - +
story->reviewedBy;?>