diff --git a/module/action/lang/de.php b/module/action/lang/de.php
index 3433bcbcf7..39249727fd 100644
--- a/module/action/lang/de.php
+++ b/module/action/lang/de.php
@@ -310,6 +310,7 @@ $lang->action->dynamicAction->story['opened'] = 'Create Story';
$lang->action->dynamicAction->story['edited'] = 'Edit Story';
$lang->action->dynamicAction->story['activated'] = 'Activate Story';
$lang->action->dynamicAction->story['reviewed'] = 'Review Story';
+$lang->action->dynamicAction->story['recalled'] = 'Revoke';
$lang->action->dynamicAction->story['closed'] = 'Close Story';
$lang->action->dynamicAction->story['assigned'] = 'Assign Story';
$lang->action->dynamicAction->story['changed'] = 'Change Story';
diff --git a/module/action/lang/en.php b/module/action/lang/en.php
index a39bcf993c..217aa624dc 100755
--- a/module/action/lang/en.php
+++ b/module/action/lang/en.php
@@ -316,6 +316,7 @@ $lang->action->dynamicAction->story['opened'] = 'Create Story';
$lang->action->dynamicAction->story['edited'] = 'Edit Story';
$lang->action->dynamicAction->story['activated'] = 'Activate Story';
$lang->action->dynamicAction->story['reviewed'] = 'Review Story';
+$lang->action->dynamicAction->story['recalled'] = 'Revoke';
$lang->action->dynamicAction->story['closed'] = 'Close Story';
$lang->action->dynamicAction->story['assigned'] = 'Assign Story';
$lang->action->dynamicAction->story['changed'] = 'Change Story';
diff --git a/module/action/lang/fr.php b/module/action/lang/fr.php
index 4477988521..e207f0cb31 100644
--- a/module/action/lang/fr.php
+++ b/module/action/lang/fr.php
@@ -310,6 +310,7 @@ $lang->action->dynamicAction->story['opened'] = 'Créer Story';
$lang->action->dynamicAction->story['edited'] = 'Editer Story';
$lang->action->dynamicAction->story['activated'] = 'Activer Story';
$lang->action->dynamicAction->story['reviewed'] = 'Consulter Story';
+$lang->action->dynamicAction->story['recalled'] = 'Revoke';
$lang->action->dynamicAction->story['closed'] = 'Fermer Story';
$lang->action->dynamicAction->story['assigned'] = 'Assigner Story';
$lang->action->dynamicAction->story['changed'] = 'Changer Story';
diff --git a/module/action/lang/vi.php b/module/action/lang/vi.php
index a3545c5e43..6013682393 100644
--- a/module/action/lang/vi.php
+++ b/module/action/lang/vi.php
@@ -310,6 +310,7 @@ $lang->action->dynamicAction->story['opened'] = 'Tạo câu chuy
$lang->action->dynamicAction->story['edited'] = 'Sửa câu chuyện';
$lang->action->dynamicAction->story['activated'] = 'Kích hoạt câu chuyện';
$lang->action->dynamicAction->story['reviewed'] = 'Duyệt câu chuyện';
+$lang->action->dynamicAction->story['recalled'] = 'Revoke';
$lang->action->dynamicAction->story['closed'] = 'Đóng câu chuyện';
$lang->action->dynamicAction->story['assigned'] = 'Bàn giao câu chuyện';
$lang->action->dynamicAction->story['changed'] = 'Thay đổi câu chuyện';
diff --git a/module/action/lang/zh-cn.php b/module/action/lang/zh-cn.php
index 334ccb1cad..b3a652334b 100755
--- a/module/action/lang/zh-cn.php
+++ b/module/action/lang/zh-cn.php
@@ -316,6 +316,7 @@ $lang->action->dynamicAction->story['opened'] = "创建{$lang->SR
$lang->action->dynamicAction->story['edited'] = "编辑{$lang->SRCommon}";
$lang->action->dynamicAction->story['activated'] = "激活{$lang->SRCommon}";
$lang->action->dynamicAction->story['reviewed'] = "评审{$lang->SRCommon}";
+$lang->action->dynamicAction->story['recalled'] = "撤销评审";
$lang->action->dynamicAction->story['closed'] = "关闭{$lang->SRCommon}";
$lang->action->dynamicAction->story['assigned'] = "指派{$lang->SRCommon}";
$lang->action->dynamicAction->story['changed'] = "变更{$lang->SRCommon}";
diff --git a/module/action/lang/zh-tw.php b/module/action/lang/zh-tw.php
index f8a0d6950d..26957c65cd 100755
--- a/module/action/lang/zh-tw.php
+++ b/module/action/lang/zh-tw.php
@@ -316,6 +316,7 @@ $lang->action->dynamicAction->story['opened'] = "創建{$lang->SR
$lang->action->dynamicAction->story['edited'] = "編輯{$lang->SRCommon}";
$lang->action->dynamicAction->story['activated'] = "激活{$lang->SRCommon}";
$lang->action->dynamicAction->story['reviewed'] = "評審{$lang->SRCommon}";
+$lang->action->dynamicAction->story['recalled'] = '撤銷評審';
$lang->action->dynamicAction->story['closed'] = "關閉{$lang->SRCommon}";
$lang->action->dynamicAction->story['assigned'] = "指派{$lang->SRCommon}";
$lang->action->dynamicAction->story['changed'] = "變更{$lang->SRCommon}";
diff --git a/module/group/lang/resource.php b/module/group/lang/resource.php
index ebabdcb63d..1d3935a7a3 100644
--- a/module/group/lang/resource.php
+++ b/module/group/lang/resource.php
@@ -424,26 +424,27 @@ $lang->branch->methodOrder[10] = 'delete';
/* Story. */
$lang->resource->story = new stdclass();
-$lang->resource->story->create = 'create';
-$lang->resource->story->batchCreate = 'batchCreate';
-$lang->resource->story->edit = 'editAction';
-$lang->resource->story->linkStory = 'linkStory';
-$lang->resource->story->batchEdit = 'batchEdit';
-$lang->resource->story->export = 'exportAction';
-$lang->resource->story->delete = 'deleteAction';
-$lang->resource->story->view = 'view';
-$lang->resource->story->change = 'changeAction';
-$lang->resource->story->review = 'reviewAction';
-$lang->resource->story->batchReview = 'batchReview';
-$lang->resource->story->assignTo = 'assignAction';
-$lang->resource->story->close = 'closeAction';
-$lang->resource->story->batchClose = 'batchClose';
-$lang->resource->story->activate = 'activateAction';
-$lang->resource->story->tasks = 'tasks';
-$lang->resource->story->bugs = 'bugs';
-$lang->resource->story->cases = 'cases';
-$lang->resource->story->zeroCase = 'zeroCase';
-$lang->resource->story->report = 'reportAction';
+$lang->resource->story->create = 'create';
+$lang->resource->story->batchCreate = 'batchCreate';
+$lang->resource->story->edit = 'editAction';
+$lang->resource->story->linkStory = 'linkStory';
+$lang->resource->story->batchEdit = 'batchEdit';
+$lang->resource->story->export = 'exportAction';
+$lang->resource->story->delete = 'deleteAction';
+$lang->resource->story->view = 'view';
+$lang->resource->story->change = 'changeAction';
+$lang->resource->story->review = 'reviewAction';
+$lang->resource->story->batchReview = 'batchReview';
+$lang->resource->story->recall = 'recall';
+$lang->resource->story->assignTo = 'assignAction';
+$lang->resource->story->close = 'closeAction';
+$lang->resource->story->batchClose = 'batchClose';
+$lang->resource->story->activate = 'activateAction';
+$lang->resource->story->tasks = 'tasks';
+$lang->resource->story->bugs = 'bugs';
+$lang->resource->story->cases = 'cases';
+$lang->resource->story->zeroCase = 'zeroCase';
+$lang->resource->story->report = 'reportAction';
$lang->resource->story->batchChangePlan = 'batchChangePlan';
$lang->resource->story->batchChangeBranch = 'batchChangeBranch';
$lang->resource->story->batchChangeStage = 'batchChangeStage';
@@ -462,24 +463,25 @@ $lang->story->methodOrder[30] = 'view';
$lang->story->methodOrder[35] = 'change';
$lang->story->methodOrder[40] = 'review';
$lang->story->methodOrder[45] = 'batchReview';
-$lang->story->methodOrder[50] = 'close';
-$lang->story->methodOrder[55] = 'batchClose';
-$lang->story->methodOrder[60] = 'batchChangePlan';
-$lang->story->methodOrder[65] = 'batchChangeStage';
-$lang->story->methodOrder[70] = 'assignTo';
-$lang->story->methodOrder[75] = 'batchAssignTo';
-$lang->story->methodOrder[80] = 'activate';
-$lang->story->methodOrder[85] = 'tasks';
-$lang->story->methodOrder[90] = 'bugs';
-$lang->story->methodOrder[95] = 'cases';
-$lang->story->methodOrder[100] = 'zeroCase';
-$lang->story->methodOrder[105] = 'report';
-$lang->story->methodOrder[110] = 'linkStory';
-$lang->story->methodOrder[115] = 'batchChangeBranch';
-$lang->story->methodOrder[120] = 'batchChangeModule';
-$lang->story->methodOrder[125] = 'batchToTask';
-$lang->story->methodOrder[130] = 'track';
-$lang->story->methodOrder[135] = 'processStoryChange';
+$lang->story->methodOrder[50] = 'recall';
+$lang->story->methodOrder[55] = 'close';
+$lang->story->methodOrder[60] = 'batchClose';
+$lang->story->methodOrder[65] = 'batchChangePlan';
+$lang->story->methodOrder[70] = 'batchChangeStage';
+$lang->story->methodOrder[75] = 'assignTo';
+$lang->story->methodOrder[80] = 'batchAssignTo';
+$lang->story->methodOrder[85] = 'activate';
+$lang->story->methodOrder[90] = 'tasks';
+$lang->story->methodOrder[95] = 'bugs';
+$lang->story->methodOrder[100] = 'cases';
+$lang->story->methodOrder[105] = 'zeroCase';
+$lang->story->methodOrder[110] = 'report';
+$lang->story->methodOrder[115] = 'linkStory';
+$lang->story->methodOrder[120] = 'batchChangeBranch';
+$lang->story->methodOrder[125] = 'batchChangeModule';
+$lang->story->methodOrder[130] = 'batchToTask';
+$lang->story->methodOrder[135] = 'track';
+$lang->story->methodOrder[140] = 'processStoryChange';
/* Product plan. */
$lang->resource->productplan = new stdclass();
diff --git a/module/story/config.php b/module/story/config.php
index 247094693c..7fb95e824d 100644
--- a/module/story/config.php
+++ b/module/story/config.php
@@ -199,5 +199,5 @@ $config->story->datatable->fieldList['caseCount']['name'] = $lang->story->ca
$config->story->datatable->fieldList['actions']['title'] = 'actions';
$config->story->datatable->fieldList['actions']['fixed'] = 'right';
-$config->story->datatable->fieldList['actions']['width'] = $app->rawModule == 'projectstory' ? '200' : '180';
+$config->story->datatable->fieldList['actions']['width'] = '200';
$config->story->datatable->fieldList['actions']['required'] = 'yes';
diff --git a/module/story/control.php b/module/story/control.php
index e15c2be946..8aa844aa49 100644
--- a/module/story/control.php
+++ b/module/story/control.php
@@ -1103,6 +1103,21 @@ class story extends control
die(js::reload('parent'));
}
+ /**
+ * Recall the story review.
+ *
+ * @param int $storyID
+ * @access public
+ * @return void
+ */
+ public function recall($storyID)
+ {
+ $this->story->recall($storyID);
+ $this->loadModel('action')->create('story', $storyID, 'Recalled');
+
+ die(js::reload('parent.parent'));
+ }
+
/**
* Close a story.
*
diff --git a/module/story/lang/de.php b/module/story/lang/de.php
index 7acc0c162a..33b654af4a 100644
--- a/module/story/lang/de.php
+++ b/module/story/lang/de.php
@@ -27,6 +27,7 @@ $lang->story->changed = 'Geändert';
$lang->story->assignTo = 'Assign';
$lang->story->assignAction = 'Assign Story';
$lang->story->review = 'Prüfen';
+$lang->story->recall = 'Revoke';
$lang->story->reviewAction = 'Review Story';
$lang->story->needReview = 'Need Review';
$lang->story->batchReview = 'Mehere prüfen';
@@ -286,6 +287,7 @@ $lang->story->action->reviewed = array('main' => '$date, geprüft v
$lang->story->action->passreviewed = array('main' => '$date, determined by the System. The result is Pass.');
$lang->story->action->clarifyreviewed = array('main' => '$date, determined by the System. The result is Review Failed. Please re-initiate the review after changing.');
$lang->story->action->rejectreviewed = array('main' => '$date, geprüft von $actor. Das Ergebnis ist $extra, Der Grund ist $reason.', 'extra' => 'reviewResultList', 'reason' => 'reasonList');
+$lang->story->action->recalled = array('main' => '$date, recalled by $actor.');
$lang->story->action->closed = array('main' => '$date, geschlossen von $actor. Der Grund ist $extra $appendLink.', 'extra' => 'reasonList');
$lang->story->action->reviewclosed = array('main' => '$date, closed by System. The reasion is Review Failed.');
$lang->story->action->linked2plan = array('main' => '$date, verknüpft von $actor mit Plan $extra');
diff --git a/module/story/lang/en.php b/module/story/lang/en.php
index d18f18bb0d..9876a7b8a8 100644
--- a/module/story/lang/en.php
+++ b/module/story/lang/en.php
@@ -20,53 +20,54 @@ $lang->story->createStory = 'Create ' . $lang->story->story;
$lang->story->createRequirement = 'Create ' . $lang->story->requirement;
$lang->story->affectedStories = "Affected {$lang->story->story}";
-$lang->story->batchCreate = "Batch Create";
-$lang->story->change = "Change";
-$lang->story->changed = 'Change';
-$lang->story->assignTo = 'Assign';
-$lang->story->review = 'Review';
-$lang->story->needReview = 'Need Review';
-$lang->story->batchReview = 'Batch Review';
-$lang->story->edit = "Edit Story";
-$lang->story->batchEdit = "Batch Edit";
-$lang->story->subdivide = 'Decompose';
-$lang->story->link = 'Link';
-$lang->story->unlink = 'Unlink';
-$lang->story->track = 'Track';
-$lang->story->trackAB = 'Track';
-$lang->story->processStoryChange= 'Process Story Change';
-$lang->story->splitRequirent = 'Decompose';
-$lang->story->close = 'Close';
-$lang->story->batchClose = 'Batch Close';
-$lang->story->activate = 'Activate';
-$lang->story->delete = "Delete";
-$lang->story->view = "Story Detail";
-$lang->story->setting = "Settings";
-$lang->story->tasks = "Linked Tasks";
-$lang->story->bugs = "Linked Bugs";
-$lang->story->cases = "Linked Cases";
-$lang->story->taskCount = 'Tasks';
-$lang->story->bugCount = 'Bugs';
-$lang->story->caseCount = 'Cases';
-$lang->story->taskCountAB = 'T';
-$lang->story->bugCountAB = 'B';
-$lang->story->caseCountAB = 'C';
-$lang->story->linkStory = 'Link Story';
-$lang->story->unlinkStory = 'UnLinked';
-$lang->story->export = "Export Data";
-$lang->story->zeroCase = "Stories without cases";
-$lang->story->zeroTask = "Only list stories without tasks";
-$lang->story->reportChart = "Report";
-$lang->story->copyTitle = "Copy Title";
-$lang->story->batchChangePlan = "Batch Change Plans";
-$lang->story->batchChangeBranch = "Batch Change Branches";
-$lang->story->batchChangeStage = "Batch Change Phases";
-$lang->story->batchAssignTo = "Batch Assign";
-$lang->story->batchChangeModule = "Batch Change Modules";
-$lang->story->viewAll = "See All";
-$lang->story->toTask = 'Convert to Task';
-$lang->story->batchToTask = 'Batch Convert to Task';
-$lang->story->convertRelations = 'Convert Relations';
+$lang->story->batchCreate = "Batch Create";
+$lang->story->change = "Change";
+$lang->story->changed = 'Change';
+$lang->story->assignTo = 'Assign';
+$lang->story->review = 'Review';
+$lang->story->recall = 'Revoke';
+$lang->story->needReview = 'Need Review';
+$lang->story->batchReview = 'Batch Review';
+$lang->story->edit = "Edit Story";
+$lang->story->batchEdit = "Batch Edit";
+$lang->story->subdivide = 'Decompose';
+$lang->story->link = 'Link';
+$lang->story->unlink = 'Unlink';
+$lang->story->track = 'Track';
+$lang->story->trackAB = 'Track';
+$lang->story->processStoryChange = 'Process Story Change';
+$lang->story->splitRequirent = 'Decompose';
+$lang->story->close = 'Close';
+$lang->story->batchClose = 'Batch Close';
+$lang->story->activate = 'Activate';
+$lang->story->delete = "Delete";
+$lang->story->view = "Story Detail";
+$lang->story->setting = "Settings";
+$lang->story->tasks = "Linked Tasks";
+$lang->story->bugs = "Linked Bugs";
+$lang->story->cases = "Linked Cases";
+$lang->story->taskCount = 'Tasks';
+$lang->story->bugCount = 'Bugs';
+$lang->story->caseCount = 'Cases';
+$lang->story->taskCountAB = 'T';
+$lang->story->bugCountAB = 'B';
+$lang->story->caseCountAB = 'C';
+$lang->story->linkStory = 'Link Story';
+$lang->story->unlinkStory = 'UnLinked';
+$lang->story->export = "Export Data";
+$lang->story->zeroCase = "Stories without cases";
+$lang->story->zeroTask = "Only list stories without tasks";
+$lang->story->reportChart = "Report";
+$lang->story->copyTitle = "Copy Title";
+$lang->story->batchChangePlan = "Batch Change Plans";
+$lang->story->batchChangeBranch = "Batch Change Branches";
+$lang->story->batchChangeStage = "Batch Change Phases";
+$lang->story->batchAssignTo = "Batch Assign";
+$lang->story->batchChangeModule = "Batch Change Modules";
+$lang->story->viewAll = "See All";
+$lang->story->toTask = 'Convert to Task';
+$lang->story->batchToTask = 'Batch Convert to Task';
+$lang->story->convertRelations = 'Convert Relations';
$lang->story->editAction = "Edit {$lang->SRCommon}";
$lang->story->changeAction = "Change {$lang->SRCommon}";
@@ -287,6 +288,7 @@ $lang->story->action->reviewed = array('main' => '$date, recorded b
$lang->story->action->passreviewed = array('main' => '$date, determined by the System. The result is Pass.');
$lang->story->action->clarifyreviewed = array('main' => '$date, determined by the System. The result is Review Failed. Please re-initiate the review after changing.');
$lang->story->action->rejectreviewed = array('main' => '$date, recorded by $actor. The result is $extra. The reasion is $reason.', 'extra' => 'reviewResultList', 'reason' => 'reasonList');
+$lang->story->action->recalled = array('main' => '$date, recalled by $actor.');
$lang->story->action->closed = array('main' => '$date, closed by $actor. The reasion is $extra $appendLink.', 'extra' => 'reasonList');
$lang->story->action->reviewclosed = array('main' => '$date, closed by System. The reasion is Review Failed.');
$lang->story->action->linked2plan = array('main' => '$date, linked by $actor to Plan $extra');
diff --git a/module/story/lang/fr.php b/module/story/lang/fr.php
index 3cad39afcc..74eafeec2a 100644
--- a/module/story/lang/fr.php
+++ b/module/story/lang/fr.php
@@ -27,6 +27,7 @@ $lang->story->changed = 'Changée';
$lang->story->assignTo = 'Affecter';
$lang->story->assignAction = 'Affecter Story';
$lang->story->review = 'Valider';
+$lang->story->recall = 'Revoke';
$lang->story->reviewAction = 'Valider Story';
$lang->story->needReview = 'Validation requise';
$lang->story->batchReview = 'Validation par lot';
@@ -286,6 +287,7 @@ $lang->story->action->reviewed = array('main' => '$date, validée p
$lang->story->action->passreviewed = array('main' => '$date, determined by the System. The result is Pass.');
$lang->story->action->clarifyreviewed = array('main' => '$date, determined by the System. The result is Review Failed. Please re-initiate the review after changing.');
$lang->story->action->rejectreviewed = array('main' => '$date, validée par $actor. Le résultat est $extra. La raison est $reason.', 'extra' => 'reviewResultList', 'reason' => 'reasonList');
+$lang->story->action->recalled = array('main' => '$date, recalled by $actor.');
$lang->story->action->closed = array('main' => '$date, Fermée par $actor. La raison est $extra $appendLink.', 'extra' => 'reasonList');
$lang->story->action->reviewclosed = array('main' => '$date, closed by System. The reasion is Review Failed.');
$lang->story->action->linked2plan = array('main' => '$date, planifiée par $actor au Plan $extra');
diff --git a/module/story/lang/vi.php b/module/story/lang/vi.php
index 204c3aaac8..6254d9455d 100644
--- a/module/story/lang/vi.php
+++ b/module/story/lang/vi.php
@@ -27,6 +27,7 @@ $lang->story->changed = "Đã đổi";
$lang->story->assignTo = 'Giao cho';
$lang->story->assignAction = 'Bàn giao câu chuyện';
$lang->story->review = 'Xét duyệt';
+$lang->story->recall = 'Revoke';
$lang->story->reviewAction = 'Duyệt câu chuyện';
$lang->story->needReview = 'Duyệt nhu cầu';
$lang->story->batchReview = 'Duyệt hàng loạt';
@@ -286,6 +287,7 @@ $lang->story->action->reviewed = array('main' => '$date, ghi nhận
$lang->story->action->passreviewed = array('main' => '$date, determined by the System. The result is Pass.');
$lang->story->action->clarifyreviewed = array('main' => '$date, determined by the System. The result is Review Failed. Please re-initiate the review after changing.');
$lang->story->action->rejectreviewed = array('main' => '$date, ghi nhận bởi $actor. Kết quả là $extra. Lý do là $reason', 'extra' => 'reviewResultList', 'reason' => 'reasonList');
+$lang->story->action->recalled = array('main' => '$date, recalled by $actor.');
$lang->story->action->closed = array('main' => '$date, được đóng bởi $actor. Lý do là $extra $appendLink.', 'extra' => 'reasonList');
$lang->story->action->reviewclosed = array('main' => '$date, closed by System. The reasion is Review Failed.');
$lang->story->action->linked2plan = array('main' => '$date, liên kết bởi $actor tới kế hoạch $extra');
diff --git a/module/story/lang/zh-cn.php b/module/story/lang/zh-cn.php
index e893d74bbe..6284468bf3 100644
--- a/module/story/lang/zh-cn.php
+++ b/module/story/lang/zh-cn.php
@@ -25,6 +25,7 @@ $lang->story->change = "变更";
$lang->story->changed = "{$lang->SRCommon}变更";
$lang->story->assignTo = '指派';
$lang->story->review = '评审';
+$lang->story->recall = '撤销评审';
$lang->story->needReview = '需要评审';
$lang->story->batchReview = '批量评审';
$lang->story->edit = "编辑";
@@ -287,6 +288,7 @@ $lang->story->action->reviewed = array('main' => '$date, 由 story->action->passreviewed = array('main' => '$date, 由 系统 判定,结果为 确认通过。');
$lang->story->action->clarifyreviewed = array('main' => '$date, 由 系统 判定,结果为 评审不通过,请变更后重新发起评审。');
$lang->story->action->rejectreviewed = array('main' => '$date, 由 $actor 记录评审结果,结果为 $extra,原因为 $reason。', 'extra' => 'reviewResultList', 'reason' => 'reasonList');
+$lang->story->action->recalled = array('main' => '$date, 由 $actor 撤销评审。');
$lang->story->action->closed = array('main' => '$date, 由 $actor 关闭,原因为 $extra $appendLink。', 'extra' => 'reasonList');
$lang->story->action->reviewclosed = array('main' => '$date, 由 系统 关闭,原因为 评审失败。');
$lang->story->action->linked2plan = array('main' => '$date, 由 $actor 关联到计划 $extra。');
diff --git a/module/story/lang/zh-tw.php b/module/story/lang/zh-tw.php
index 6daa4cb252..356ffb26f8 100644
--- a/module/story/lang/zh-tw.php
+++ b/module/story/lang/zh-tw.php
@@ -25,6 +25,7 @@ $lang->story->change = "變更";
$lang->story->changed = "{$lang->SRCommon}變更";
$lang->story->assignTo = '指派';
$lang->story->review = '評審';
+$lang->story->recall = '撤銷評審';
$lang->story->needReview = '需要評審';
$lang->story->batchReview = '批量評審';
$lang->story->edit = "編輯";
@@ -287,6 +288,7 @@ $lang->story->action->reviewed = array('main' => '$date, 由 story->action->passreviewed = array('main' => '$date, 由 系統 判定,結果為 確認通過。');
$lang->story->action->clarifyreviewed = array('main' => '$date, 由 系統 判定,結果為 評審不通過,請變更後重新發起評審。');
$lang->story->action->rejectreviewed = array('main' => '$date, 由 $actor 記錄評審結果,結果為 $extra,原因為 $reason。', 'extra' => 'reviewResultList', 'reason' => 'reasonList');
+$lang->story->action->recalled = array('main' => '$date, 由 $actor 撤銷評審。');
$lang->story->action->closed = array('main' => '$date, 由 $actor 關閉,原因為 $extra $appendLink。', 'extra' => 'reasonList');
$lang->story->action->reviewclosed = array('main' => '$date, 由 系統 關閉,原因為 評審失敗。');
$lang->story->action->linked2plan = array('main' => '$date, 由 $actor 關聯到計劃 $extra。');
diff --git a/module/story/model.php b/module/story/model.php
index 2afa046068..a1cf48e819 100644
--- a/module/story/model.php
+++ b/module/story/model.php
@@ -1398,6 +1398,20 @@ class storyModel extends model
return $actions;
}
+ /**
+ * Recall the story review.
+ *
+ * @param int $storyID
+ * @access public
+ * @return void
+ */
+ public function recall($storyID)
+ {
+ $story = $this->getById($storyID);
+ $this->dao->update(TABLE_STORY)->set('status')->eq('draft')->where('id')->eq($storyID)->exec();
+ $this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($storyID)->andWhere('version')->eq($story->version)->exec();
+ }
+
/**
* Subdivide story
*
@@ -3377,6 +3391,7 @@ class storyModel extends model
if($action == 'change') return (count($story->reviewer) == 0 || count($story->notReview) == 0) and $story->status != 'closed';
if($action == 'review') return in_array($app->user->account, $story->notReview) and ($story->status == 'draft' or $story->status == 'changed');
+ if($action == 'recall') return empty($story->reviewedBy) and strpos('draft,changed', $story->status) !== false and !empty($story->reviewer);
if($action == 'close') return $story->status != 'closed';
if($action == 'activate') return $story->status == 'closed';
if($action == 'assignto') return $story->status != 'closed';
@@ -3782,6 +3797,7 @@ class storyModel extends model
common::printIcon('story', 'change', $vars . "&from=$story->from", $story, 'list', 'alter', '', '', false, "data-group=$story->from");
common::printIcon('story', 'review', $vars . "&from=$story->from", $story, 'list', 'search', '', '', false, "data-group=$story->from");
+ if($this->app->openApp != 'project') common::printIcon('story', 'recall', $vars . "&from=$story->from", $story, 'list', 'back', 'hiddenwin', '', '', '', $this->lang->story->recall);
common::printIcon('story', 'close', $vars, $story, 'list', '', '', 'iframe', true);
common::printIcon('story', 'edit', $vars . "&from=$story->from", $story, 'list', '', '', '', false, "data-group=$story->from");
if($story->type != 'requirement') common::printIcon('story', 'createCase', "productID=$story->product&branch=$story->branch&module=0&from=¶m=0&$vars", $story, 'list', 'sitemap', '', '', false, "data-app='qa'");