diff --git a/api/v1/entries/product.php b/api/v1/entries/product.php index 69e8704fda..524abf92d1 100644 --- a/api/v1/entries/product.php +++ b/api/v1/entries/product.php @@ -14,6 +14,7 @@ class productEntry extends Entry $control->view($productID); $data = $this->getData(); + if(!$data or (isset($data->status) and $data->message == '404 Not found')) return $this->send404(); if(isset($data->status) and $data->status == 'success') return $this->send(200, $this->format($data->data->product, 'createdDate:time')); if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message); diff --git a/api/v1/entries/project.php b/api/v1/entries/project.php index 1ce4d04db8..c8af26898a 100644 --- a/api/v1/entries/project.php +++ b/api/v1/entries/project.php @@ -14,6 +14,7 @@ class projectEntry extends entry $control->view($projectID); $data = $this->getData(); + if(!$data or (isset($data->status) and $data->message == '404 Not found')) return $this->send404(); if(isset($data->status) and $data->status == 'success') return $this->send(200, $this->format($data->data->project, 'openedDate:time,lastEditedDate:time,closedDate:time,canceledDate:time')); if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message); diff --git a/framework/api/entry.class.php b/framework/api/entry.class.php index 67cd73657b..801beacd6c 100644 --- a/framework/api/entry.class.php +++ b/framework/api/entry.class.php @@ -9,7 +9,7 @@ class entry extends baseEntry { parent::__construct(); - if(!isset($this->app->user)) $this->sendError(401, 'Unauthorized'); + if(!isset($this->app->user) or $this->app->user->account == 'guest') $this->sendError(401, 'Unauthorized'); $this->dao = $this->loadModel('common')->dao; } diff --git a/module/execution/control.php b/module/execution/control.php index c4707e1337..21d42a8537 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -2292,7 +2292,7 @@ class execution extends control $this->view->title = $title; $this->view->position = $position; - $this->view->execution = $execution; + $this->view->execution = $execution; $this->view->users = $users; $this->view->deptUsers = $deptUsers; $this->view->roles = $roles; diff --git a/module/personnel/model.php b/module/personnel/model.php index 35008cf8ec..cdb25bba17 100644 --- a/module/personnel/model.php +++ b/module/personnel/model.php @@ -491,8 +491,7 @@ class personnelModel extends model } elseif($objectType == 'project') { - $parentID = $this->dao->select('parent')->from(TABLE_PROJECT)->where('id')->eq($objectID)->fetch('parent'); - $objects = $this->loadModel('project')->getPairsByProgram($parentID); + $objects = $this->loadModel('project')->getPairsByProgram(); } elseif($objectType == 'product') { diff --git a/module/product/control.php b/module/product/control.php index 443ba574e3..0bbc0d90a3 100644 --- a/module/product/control.php +++ b/module/product/control.php @@ -687,7 +687,12 @@ class product extends control { $productID = (int)$productID; $product = $this->product->getStatByID($productID); - if(!$product) die(js::error($this->lang->notFound) . js::locate('back')); + + if(!$product) + { + if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'fail', 'message' => '404 Not found')); + die(js::error($this->lang->notFound) . js::locate('back')); + } $product->desc = $this->loadModel('file')->setImgSize($product->desc); $this->product->setMenu($productID); diff --git a/module/project/control.php b/module/project/control.php index cd3776e994..8255a7ddb1 100644 --- a/module/project/control.php +++ b/module/project/control.php @@ -560,9 +560,13 @@ class project extends control */ public function view($projectID = 0) { - $projectID = $this->project->saveState((int)$projectID, $this->project->getPairsByProgram()); - $project = $this->project->getById($projectID); - if(empty($project) || strpos('scrum,waterfall', $project->model) === false) die(js::error($this->lang->notFound) . js::locate('back')); + if(!defined('RUN_MODE') || RUN_MODE != 'api') $projectID = $this->project->saveState((int)$projectID, $this->project->getPairsByProgram()); + $project = $this->project->getById($projectID); + if(empty($project) || strpos('scrum,waterfall', $project->model) === false) + { + if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'fail', 'message' => '404 Not found')); + die(js::error($this->lang->notFound) . js::locate('back')); + } $this->project->setMenu($projectID); @@ -1171,10 +1175,11 @@ class project extends control * * @param int $projectID * @param int $dept + * @param int $copyProjectID * @access public * @return void */ - public function manageMembers($projectID, $dept = '') + public function manageMembers($projectID, $dept = '', $copyProjectID = 0) { /* Load model. */ $this->loadModel('user'); @@ -1187,7 +1192,7 @@ class project extends control $this->project->manageMembers($projectID); $this->loadModel('action')->create('team', $projectID, 'ManagedTeam'); - $link = $this->createLink('project', 'manageMembers', "projectID=$projectID"); + $link = $this->createLink('project', 'team', "projectID=$projectID"); return $this->send(array('message' => $this->lang->saveSuccess, 'result' => 'success', 'locate' => $link)); } @@ -1196,6 +1201,9 @@ class project extends control $roles = $this->user->getUserRoles(array_keys($users)); $deptUsers = $dept === '' ? array() : $this->dept->getDeptUserPairs($dept); + $currentMembers = $this->project->getTeamMembers($projectID); + $members2Import = $this->project->getMembers2Import($copyProjectID, array_keys($currentMembers)); + $this->view->title = $this->lang->project->manageMembers . $this->lang->colon . $project->name; $this->view->position[] = $this->lang->project->manageMembers; @@ -1205,7 +1213,10 @@ class project extends control $this->view->roles = $roles; $this->view->dept = $dept; $this->view->depts = array('' => '') + $this->dept->getOptionMenu(); - $this->view->currentMembers = $this->project->getTeamMembers($projectID); + $this->view->currentMembers = $currentMembers; + $this->view->members2Import = $members2Import; + $this->view->teams2Import = array('' => '') + $this->loadModel('personnel')->getCopyObjects($projectID, 'project'); + $this->view->copyProjectID = $copyProjectID; $this->display(); } diff --git a/module/project/js/managemembers.js b/module/project/js/managemembers.js index 9fd244022d..67d66cd033 100644 --- a/module/project/js/managemembers.js +++ b/module/project/js/managemembers.js @@ -34,3 +34,17 @@ function setDeptUsers(obj) link = createLink('project', 'manageMembers', 'projectID=' + projectID + '&dept=' + dept); // Create manageMembers link. location.href=link; } + +/** + * Chose team to copy. + * + * @param object $obj + * @access public + * @return void + */ +function choseTeam2Copy(obj) +{ + team = $(obj).val(); + link = createLink('project', 'manageMembers', 'projectID=' + projectID + '&dept=&team2Import=' + team); + location.href=link; +} diff --git a/module/project/model.php b/module/project/model.php index 5c5d22edc0..7e3f2374c6 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -1594,6 +1594,26 @@ class projectModel extends model return array('' => '') + $members; } + /** + * Get members of a project who can be imported. + * + * @param int $projectID + * @param array $currentMembers + * @access public + * @return array + */ + public function getMembers2Import($projectID, $currentMembers) + { + if($projectID == 0) return array(); + + return $this->dao->select('account, role, hours') + ->from(TABLE_TEAM) + ->where('root')->eq($projectID) + ->andWhere('type')->in('project') + ->andWhere('account')->notIN($currentMembers) + ->fetchAll('account'); + } + /** * Get project stats. * diff --git a/module/project/view/managemembers.html.php b/module/project/view/managemembers.html.php index 30c8ee11d6..c704ea7270 100644 --- a/module/project/view/managemembers.html.php +++ b/module/project/view/managemembers.html.php @@ -9,6 +9,10 @@
execution->selectDept?> execution->selectDeptTitle}'");?> + + execution->copyTeam?> + execution->copyTeamTitle}'");?> +
@@ -47,6 +51,23 @@ + + + account, "class='form-control chosen' onchange='setRole(this.value, $i)'");?> + + + + + + team->limitedList, 'no');?> + + + + + + + + $userName):?> diff --git a/module/story/model.php b/module/story/model.php index 9e1f1593ec..21da041035 100644 --- a/module/story/model.php +++ b/module/story/model.php @@ -1280,7 +1280,6 @@ class storyModel extends model ->setDefault('lastEditedDate', $now) ->setDefault('status', $oldStory->status) ->setIF($this->post->result == 'revert', 'version', $this->post->preVersion) - ->setIF($this->post->result == 'revert', 'status', 'active') ->removeIF($this->post->result != 'reject', 'closedReason, duplicateStory, childStories') ->removeIF($this->post->result == 'reject' and $this->post->closedReason != 'duplicate', 'duplicateStory') ->removeIF($this->post->result == 'reject' and $this->post->closedReason != 'subdivided', 'childStories') @@ -1299,7 +1298,7 @@ class storyModel extends model $reviewedBy = explode(',', trim($story->reviewedBy, ',')); if(!array_diff(array_keys($reviewerList), $reviewedBy)) { - $status = $this->setStatusByReviewRules($reviewerList); + $status = $this->post->result == 'revert' ? 'active' : $this->setStatusByReviewRules($reviewerList); $story->status = $status ? $status : $oldStory->status; if($story->status == 'closed') { @@ -4497,9 +4496,12 @@ class storyModel extends model $comment = isset($_POST['comment']) ? $this->post->comment : ''; $actionID = !empty($result) ? $this->loadModel('action')->create('story', $story->id, 'Reviewed', $comment, ucfirst($result) . $reasonParam) : ''; - if($story->status == 'closed') $this->action->create('story', $story->id, 'ReviewClosed'); - if($story->status == 'active') $this->action->create('story', $story->id, 'PassReviewed'); - if(!array_diff(array_keys($reviewers), $reviewedBy) and ($story->status == 'draft' || $story->status == 'changed')) $this->action->create('story', $story->id, 'ClarifyReviewed'); + if(ucfirst($result) != 'Revert') + { + if($story->status == 'closed') $this->action->create('story', $story->id, 'ReviewClosed'); + if($story->status == 'active') $this->action->create('story', $story->id, 'PassReviewed'); + if(!array_diff(array_keys($reviewers), $reviewedBy) and ($story->status == 'draft' || $story->status == 'changed')) $this->action->create('story', $story->id, 'ClarifyReviewed'); + } return $actionID; } diff --git a/module/story/view/edit.html.php b/module/story/view/edit.html.php index 76fcbc4893..06b7112486 100644 --- a/module/story/view/edit.html.php +++ b/module/story/view/edit.html.php @@ -211,7 +211,7 @@ story->reviewers;?> - '') + $users, $reviewers, 'class="form-control chosen" multiple')?> + status == 'closed'):?>