diff --git a/module/project/config/form.php b/module/project/config/form.php index be240c001e..9566370748 100644 --- a/module/project/config/form.php +++ b/module/project/config/form.php @@ -17,6 +17,22 @@ $config->project->form->create['whitelist'] = array('type' => 'array', 'requir $config->project->form->create['auth'] = array('type' => 'array', 'required' => false, 'default' => ''); $config->project->form->create['model'] = array('type' => 'string', 'required' => false, 'default' => ''); +$config->project->form->eidt = array(); +$config->project->form->edit['parent'] = array('type' => 'int', 'required' => false, 'default' => ''); +$config->project->form->edit['name'] = array('type' => 'string', 'required' => true, 'filter' => 'trim'); +$config->project->form->edit['code'] = array('type' => 'string', 'required' => true, 'filter' => 'trim'); +$config->project->form->edit['multiple'] = array('type' => 'string', 'required' => false, 'default' => ''); +$config->project->form->edit['hasProduct'] = array('type' => 'string', 'required' => false, 'default' => ''); +$config->project->form->edit['PM'] = array('type' => 'string', 'required' => false, 'default' => ''); +$config->project->form->edit['budget'] = array('type' => 'string', 'required' => false, 'default' => ''); +$config->project->form->edit['budgetUnit'] = array('type' => 'string', 'required' => false, 'default' => 'CNY'); +$config->project->form->edit['begin'] = array('type' => 'date', 'required' => true); +$config->project->form->edit['end'] = array('type' => 'date', 'required' => true); +$config->project->form->edit['desc'] = array('type' => 'string', 'required' => false, 'default' => ''); +$config->project->form->edit['acl'] = array('type' => 'string', 'required' => false, 'default' => ''); +$config->project->form->edit['whitelist'] = array('type' => 'array', 'required' => false, 'default' => '', 'filter' => 'join'); +$config->project->form->edit['auth'] = array('type' => 'array', 'required' => false, 'default' => ''); +$config->project->form->edit['model'] = array('type' => 'string', 'required' => false, 'default' => ''); $config->project->form->start['realBegan'] = array('type' => 'date', 'required' => true, 'filter' => 'trim'); $config->project->form->close['realEnd'] = array('type' => 'date', 'required' => true, 'filter' => 'trim'); diff --git a/module/project/control.php b/module/project/control.php index 4b9c66db02..9831f20cf3 100755 --- a/module/project/control.php +++ b/module/project/control.php @@ -511,7 +511,7 @@ class project extends control * @access public * @return void */ - public function edit($projectID = 0, $from = '') + public function edit(string $projectID, string $from = ''): void { $this->loadModel('action'); $this->loadModel('custom'); @@ -520,10 +520,12 @@ class project extends control $this->loadModel('program'); $this->loadModel('execution'); - $projectID = (int)$projectID; - $project = $this->project->getByID($projectID); - $programID = $project->parent; + + $projectID = (int)$projectID; + $project = $this->project->getByID($projectID); + $programID = $project->parent; $this->project->setMenu($projectID); + if($project->model == 'kanban') { unset($this->lang->project->authList['reset']); @@ -531,59 +533,7 @@ class project extends control $this->lang->project->subAclList = $this->lang->project->kanbanSubAclList; } - if($_POST) - { - $oldPlanList = $this->dao->select('plan')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($projectID)->andWhere('plan')->ne(0)->fetchPairs('plan'); - $oldPlans = array(); - foreach($oldPlanList as $oldPlanIDList) - { - if(is_numeric($oldPlanIDList)) $oldPlans[$oldPlanIDList] = $oldPlanIDList; - if(!is_numeric($oldPlanIDList)) - { - $oldPlanIDList = explode(',', $oldPlanIDList); - foreach($oldPlanIDList as $oldPlanID) $oldPlans[$oldPlanID] = $oldPlanID; - } - } - - $changes = $this->project->update($projectID); - if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); - - if($changes) - { - $actionID = $this->action->create('project', $projectID, 'edited'); - $this->action->logHistory($actionID, $changes); - } - - /* Link the plan stories. */ - $newPlans = array(); - if(isset($_POST['plans'])) - { - foreach($_POST['plans'] as $plans) - { - foreach($plans as $planIDList) - { - foreach($planIDList as $planID) $newPlans[$planID] = $planID; - } - } - } - - $diffResult = array_diff($oldPlans, $newPlans); - if(!empty($newPlans) and !empty($diffResult)) - { - $this->loadModel('productplan')->linkProject($projectID, $newPlans); - } - - $message = $this->executeHooks($projectID); - if($message) $this->lang->saveSuccess = $message; - - if(isonlybody()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent')); - - $locateLink = ($this->session->projectList and $from != 'view') ? $this->session->projectList : inLink('view', "projectID=$projectID"); - return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $locateLink)); - } - $withProgram = $this->config->systemMode == 'ALM' ? true : false; - $linkedBranchList = array(); $productPlans = array(); $branches = $this->project->getBranchesByProject($projectID); @@ -595,6 +545,35 @@ class project extends control $projectStories = $this->project->getStoriesByProject($projectID); $projectBranches = $this->project->getBranchGroupByProject($projectID, array_keys($linkedProducts)); + if($_POST) + { + $postData = form::data($this->config->project->form->eidt); + $project = $this->projectZen->prepareEditExtras($postData); + + $project->id = $projectID; + $project->products = isset($project->products) ? array_filter($project->products) : $linkedProducts; + + $plans = $project->plans; + if(!empty($plans)) $this->project->updatePlanIdListByProject($projectID, $plans); + + $changes = $this->project->update($projectID, $project); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + + if($changes) + { + $actionID = $this->action->create('project', $projectID, 'edited'); + $this->action->logHistory($actionID, $changes); + } + + $message = $this->executeHooks($projectID); + if($message) $this->lang->saveSuccess = $message; + + if(isonlybody()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent')); + + $locateLink = ($this->session->projectList and $from != 'view') ? $this->session->projectList : inLink('view', "projectID=$projectID"); + return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $locateLink)); + } + /* If the story of the product which linked the project, you don't allow to remove the product. */ $unmodifiableProducts = array(); $unmodifiableBranches = array(); @@ -1842,9 +1821,9 @@ class project extends control * @param string $from browse|view * * @access public - * @return void + * @return int */ - public function delete(string $projectID, string $confirm = 'no', string $from = 'browse'): void + public function delete(string $projectID, string $confirm = 'no', string $from = 'browse'): int { $projectID = (int)$projectID; $project = $this->project->getByID($projectID); @@ -1870,7 +1849,6 @@ class project extends control $this->session->set('project', ''); if($from == 'view') return print(js::locate($this->createLink('project', 'browse'), 'parent')); return print(js::reload('parent')); - } } diff --git a/module/project/model.php b/module/project/model.php index 0fa70fe65e..7284828fda 100755 --- a/module/project/model.php +++ b/module/project/model.php @@ -1317,30 +1317,10 @@ class projectModel extends model * @access public * @return array */ - public function update($projectID = 0, $project) + public function update($projectID, $project) { $oldProject = $this->dao->findById($projectID)->from(TABLE_PROJECT)->fetch(); $linkedProducts = $this->dao->select('product')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($projectID)->fetchPairs(); - $_POST['products'] = isset($_POST['products']) ? array_filter($_POST['products']) : $linkedProducts; - - $project = fixer::input('post') - ->add('id', $projectID) - ->callFunc('name', 'trim') - ->setDefault('team', $this->post->name) - ->setDefault('lastEditedBy', $this->app->user->account) - ->setDefault('lastEditedDate', helper::now()) - ->setDefault('days', '0') - ->setIF($this->post->delta == 999, 'end', LONG_TIME) - ->setIF($this->post->delta == 999, 'days', 0) - ->setIF($this->post->begin == '0000-00-00', 'begin', '') - ->setIF($this->post->end == '0000-00-00', 'end', '') - ->setIF($this->post->future, 'budget', 0) - ->setIF($this->post->budget != 0, 'budget', round((float)$this->post->budget, 2)) - ->setIF(!isset($_POST['whitelist']), 'whitelist', '') - ->join('whitelist', ',') - ->stripTags($this->config->project->editor->edit['id'], $this->config->allowedTags) - ->remove('products,branch,plans,delta,future,contactListMenu,teamMembers') - ->get(); if(!isset($project->parent)) $project->parent = $oldProject->parent; @@ -1938,7 +1918,7 @@ class projectModel extends model $canBatchEdit = common::hasPriv('project', 'batchEdit'); $account = $this->app->user->account; $id = $col->id; - $projectLink = helper::createLink('project', 'index', "projectID=$project->id", '', '', $project->id); + $projectLink = helper::createLink('project', 'index', "projectID=$project->id", '', false, $project->id); if($col->show) { @@ -3056,4 +3036,48 @@ class projectModel extends model return $repoPairs; } + + /** + * Fetch planIdList by project + * + * @param int $projectID + * @param array $plans + * @access public + * @return void + */ + public function updatePlanIdListByProject(int $projectID, array $plans): void + { + /* Link the plan stories. */ + $newPlans = array(); + if(isset($plans)) + { + foreach($plans as $planList) + { + foreach($planList as $planIDList) + { + foreach($planIDList as $planID) $newPlans[$planID] = $planID; + } + } + } + if(empty($newPlans)) return; + + /* Get old PlanIdList by project*/ + $oldPlanList = $this->dao->select('plan')->from(TABLE_PROJECTPRODUCT) + ->where('project')->eq($projectID) + ->andWhere('plan')->ne(0)->fetchPairs('plan'); + + $oldPlans = array(); + foreach($oldPlanList as $oldPlanIDList) + { + if(is_numeric($oldPlanIDList)) $oldPlans[$oldPlanIDList] = $oldPlanIDList; + if(!is_numeric($oldPlanIDList)) + { + $oldPlanIDList = explode(',', $oldPlanIDList); + foreach($oldPlanIDList as $oldPlanID) $oldPlans[$oldPlanID] = $oldPlanID; + } + } + + $diffResult = array_diff($oldPlans, $newPlans); + if(!empty($diffResult)) $this->loadModel('productplan')->linkProject($projectID, $newPlans); + } } diff --git a/module/project/zen.php b/module/project/zen.php index ffb884e0ea..c51852139e 100644 --- a/module/project/zen.php +++ b/module/project/zen.php @@ -50,6 +50,37 @@ class projectZen extends project return $project; } + /** + * Append extras data to post data. + * + * @param object $postData + * @access protected + * @return int|object + */ + protected function prepareEditExtras(object $postData): object + { + $rawdata = $postData->rawdata; + $project = $postData ->setDefault('team', $this->post->name) + ->setDefault('lastEditedBy', $this->app->user->account) + ->setDefault('lastEditedDate', helper::now()) + ->setDefault('days', '0') + ->setIF($this->post->delta == 999, 'end', LONG_TIME) + ->setIF($this->post->delta == 999, 'days', 0) + ->setIF($this->post->begin == '0000-00-00', 'begin', '') + ->setIF($this->post->end == '0000-00-00', 'end', '') + ->setIF($this->post->future, 'budget', 0) + ->setIF($this->post->budget != 0, 'budget', round((float)$this->post->budget, 2)) + ->stripTags($this->config->project->editor->edit['id'], $this->config->allowedTags) + ->get(); + + if(!isset($this->config->setCode) or $this->config->setCode == 0) unset($project->code); + + /* Lean mode relation defaultProgram. */ + if($this->config->systemMode == 'light') $project->parent = $this->config->global->defaultProgram; + + return $project; + } + /** * Check product and branch not empty. * @@ -584,9 +615,9 @@ class projectZen extends project * @param string $from * * @access protected - * @return void + * @return int 1 */ - protected function removeAssociatedExecutions(int $projectID, string $from): void + protected function removeAssociatedExecutions(int $projectID, string $from): int { /* Delete the execution under the project. */ $executionIdList = $this->loadModel('execution')->getPairs($projectID);