From 158152c119c2b24de1f8ba4190409ff411f5ea8d Mon Sep 17 00:00:00 2001 From: liuchenglong Date: Sat, 6 May 2023 01:41:38 +0000 Subject: [PATCH] * Split program plan edit function. --- module/programplan/config/form.php | 14 +++ module/programplan/control.php | 51 +++------ module/programplan/model.php | 172 ++++++++++++++++------------- module/programplan/tao.php | 36 ++++++ module/programplan/zen.php | 70 ++++++++++++ module/todo/control.php | 1 + 6 files changed, 228 insertions(+), 116 deletions(-) create mode 100644 module/programplan/config/form.php create mode 100644 module/programplan/tao.php create mode 100644 module/programplan/zen.php diff --git a/module/programplan/config/form.php b/module/programplan/config/form.php new file mode 100644 index 0000000000..6637033855 --- /dev/null +++ b/module/programplan/config/form.php @@ -0,0 +1,14 @@ +programplan->edit = new stdClass(); +$config->programplan->edit->form = array(); +$config->programplan->edit->form['begin'] = array('required' => false, 'type' => 'string', 'default' => '0000-00-00'); +$config->programplan->edit->form['end'] = array('required' => false, 'type' => 'string', 'default' => '0000-00-00'); +$config->programplan->edit->form['realBegan'] = array('required' => false, 'type' => 'string', 'default' => '0000-00-00'); +$config->programplan->edit->form['realEnd'] = array('required' => false, 'type' => 'string', 'default' => '0000-00-00'); +$config->programplan->edit->form['output'] = array('required' => false, 'type' => 'array', 'default' => array()); + + + + diff --git a/module/programplan/control.php b/module/programplan/control.php index 83f280143f..8a670f5591 100644 --- a/module/programplan/control.php +++ b/module/programplan/control.php @@ -231,60 +231,37 @@ class programplan extends control } /** + * 编辑阶段内容。 * Edit a project plan. * - * @param int $planID - * @param int $projectID + * @param string $planID + * @param string $projectID * @access public * @return void */ - public function edit($planID = 0, $projectID = 0) + public function edit(string $planID = 0, string $projectID = 0) { - $this->loadModel('project'); - $this->app->loadLang('execution'); - $this->app->loadLang('stage'); - - $plan = $this->programplan->getByID($planID); - - global $lang; - $lang->executionCommon = $lang->execution->stage; - include $this->app->getModulePath('', 'execution') . 'lang/' . $this->app->getClientLang() . '.php'; + $planID = (int)$planID; + $projectID = (int)$projectID; + $plan = $this->programplan->getByID($planID); if($_POST) { - $changes = $this->programplan->update($planID, $projectID); + $formData = form::data($this->config->programplan->edit->form); + $postData = $this->programplanZen->beforeEdit($formData); + $postData->id = $planID; + + $changes = $this->programplan->update($planID, $projectID, $postData); if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); - if($changes) - { - $actionID = $this->loadModel('action')->create('execution', $planID, 'edited'); - $this->action->logHistory($actionID, $changes); - $newPlan = $this->programplan->getByID($planID); + if($changes) $this->programplanZen->afterEdit($plan, $changes); - if($plan->parent != $newPlan->parent) - { - $this->programplan->computeProgress($planID, 'edit'); - $this->programplan->computeProgress($plan->parent, 'edit', true); - } - } $locate = isonlybody() ? 'parent' : inlink('browse', "program=$plan->program&type=lists"); return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $locate)); } - $parentStage = $this->project->getByID($plan->parent, 'stage'); - - $this->view->title = $this->lang->programplan->edit; - $this->view->position[] = $this->lang->programplan->edit; - $this->view->isCreateTask = $this->programplan->isCreateTask($planID); - $this->view->plan = $plan; - $this->view->parentStageList = $this->programplan->getParentStageList($this->session->project, $planID, $plan->product); - $this->view->enableOptionalAttr = (empty($parentStage) or (!empty($parentStage) and $parentStage->attribute == 'mix')); - $this->view->isTopStage = $this->programplan->checkTopStage($planID); - $this->view->isLeafStage = $this->programplan->checkLeafStage($planID); - $this->view->PMUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst', $plan->PM); - - $this->display(); + $this->programplanZen->buildEditView($plan); } /** diff --git a/module/programplan/model.php b/module/programplan/model.php index 97899d5f98..3a921283a8 100755 --- a/module/programplan/model.php +++ b/module/programplan/model.php @@ -1067,86 +1067,25 @@ class programplanModel extends model } /** + * 更新阶段。 * Update a plan. * - * @param int $planID - * @param int $projectID + * @param int $planID + * @param int $projectID + * @param object $plan * @access public * @return bool|array */ - public function update($planID = 0, $projectID = 0) + public function update(int $planID = 0, int $projectID = 0, object $plan): bool|array { - /* Get oldPlan and the data from the post. */ $oldPlan = $this->getByID($planID); - $plan = fixer::input('post') - ->setDefault('begin', '0000-00-00') - ->setDefault('end', '0000-00-00') - ->setDefault('realBegan', '0000-00-00') - ->setDefault('realEnd', '0000-00-00') - ->join('output', ',') - ->get(); /* Judgment of required items. */ - if($plan->begin == '0000-00-00') dao::$errors['begin'][] = sprintf($this->lang->error->notempty, $this->lang->programplan->begin); - if($plan->end == '0000-00-00') dao::$errors['end'][] = sprintf($this->lang->error->notempty, $this->lang->programplan->end); - if(dao::isError()) return false; - - if($plan->parent) $parentStage = $this->getByID($plan->parent); - if(isset($parentStage) and $plan->begin < $parentStage->begin) - { - dao::$errors['begin'] = sprintf($this->lang->programplan->error->letterParent, $parentStage->begin); - return false; - } - if(isset($parentStage) and $plan->end > $parentStage->end) - { - dao::$errors['end'] = sprintf($this->lang->programplan->error->greaterParent, $parentStage->end); - return false; - } - - if($projectID) $this->loadModel('execution')->checkBeginAndEndDate($projectID, $plan->begin, $plan->end); - if(dao::isError()) return false; - - $setCode = (isset($this->config->setCode) and $this->config->setCode == 1) ? true : false; - if($setCode and empty($plan->code)) - { - dao::$errors['code'][] = sprintf($this->lang->error->notempty, $this->lang->execution->code); - return false; - } + if(!$this->checkRequiredItems($oldPlan, $plan, $projectID)) return false; + $setCode = (isset($this->config->setCode) and $this->config->setCode == 1) ? true : false; $planChanged = ($oldPlan->name != $plan->name || $oldPlan->milestone != $plan->milestone || $oldPlan->begin != $plan->begin || $oldPlan->end != $plan->end); - $setPercent = isset($this->config->setPercent) and $this->config->setPercent == 1 ? true : false; - if($plan->parent > 0) - { - $plan->attribute = $parentStage->attribute == 'mix' ? $plan->attribute : $parentStage->attribute; - $plan->acl = $parentStage->acl; - if($setPercent) - { - $parentPercent = $parentStage->percent; - $childrenTotalPercent = $this->getTotalPercent($parentStage, true); - $childrenTotalPercent = $plan->parent == $oldPlan->parent ? ($childrenTotalPercent - $oldPlan->percent + $plan->percent) : ($childrenTotalPercent + $plan->percent); - if($childrenTotalPercent > 100) return dao::$errors['percent'][] = $this->lang->programplan->error->percentOver; - } - - /* If child plan has milestone, update parent plan set milestone eq 0 . */ - if($plan->milestone and $parentStage->milestone) $this->dao->update(TABLE_PROJECT)->set('milestone')->eq(0)->where('id')->eq($oldPlan->parent)->exec(); - } - else - { - /* Synchronously update sub-phase permissions. */ - $childrenIDList = $this->dao->select('id')->from(TABLE_PROJECT)->where('parent')->eq($oldPlan->id)->fetchAll('id'); - if(!empty($childrenIDList)) $this->dao->update(TABLE_PROJECT)->set('acl')->eq($plan->acl)->where('id')->in(array_keys($childrenIDList))->exec(); - - /* The workload of the parent plan cannot exceed 100%. */ - $oldPlan->parent = $plan->parent; - if($setPercent) - { - $totalPercent = $this->getTotalPercent($oldPlan); - $totalPercent = $totalPercent + $plan->percent; - if($totalPercent > 100) return dao::$errors['percent'][] = $this->lang->programplan->error->percentOver; - } - } - /* Set planDuration and realDuration. */ if($this->config->edition == 'max') { @@ -1156,7 +1095,6 @@ class programplanModel extends model if($planChanged) $plan->version = $oldPlan->version + 1; if(empty($plan->parent)) $plan->parent = $projectID; - $parentStage = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($plan->parent)->andWhere('type')->eq('stage')->fetch(); /* Fix bug #22030. Reset field name for show dao error. */ @@ -1166,19 +1104,20 @@ class programplanModel extends model $relatedExecutionsID = $this->loadModel('execution')->getRelatedExecutions($planID); $relatedExecutionsID = !empty($relatedExecutionsID) ? implode(',', array_keys($relatedExecutionsID)) : '0'; - $this->dao->update(TABLE_PROJECT)->data($plan) - ->autoCheck() - ->batchCheck($this->config->programplan->edit->requiredFields, 'notempty') - ->checkIF($plan->end != '0000-00-00', 'end', 'ge', $plan->begin) - ->checkIF(!empty($plan->percent), 'percent', 'float') - ->checkIF(!empty($plan->name), 'name', 'unique', "id in ({$relatedExecutionsID}) and type in ('sprint','stage') and `project` = {$oldPlan->project} and `deleted` = '0'" . ($parentStage ? " and `parent` = {$oldPlan->parent}" : '')) - ->checkIF(!empty($plan->code) and $setCode, 'code', 'unique', "id != $planID and type in ('sprint','stage','kanban') and `deleted` = '0'") - ->where('id')->eq($planID) - ->exec(); + $conditions = array(); + $conditions['requiredFields'] = $this->config->programplan->edit->requiredFields; + $conditions['relatedExecutionsID'] = $relatedExecutionsID; + $conditions['oldProject'] = $oldPlan->project; + $conditions['oldParent'] = $oldPlan->parent; + $conditions['parentStage'] = $parentStage; + $conditions['setCode'] = $setCode; + + $result = $this->programplanTao->update($plan, $conditions); + if(!$result) return false; - if(dao::isError()) return false; $this->setTreePath($planID); $this->updateSubStageAttr($planID, $plan->attribute); + if($plan->acl != 'open') { $planIdList = $this->dao->select('id')->from(TABLE_EXECUTION)->where('path')->like("%,$planID,%")->andWhere('type')->ne('project')->fetchAll('id'); @@ -1691,4 +1630,79 @@ class programplanModel extends model return $siblingStages; } + + /** + * 校验提交数据是否必须。 + * Check required items. + * + * @param object $oldPlan + * @param object $plan + * @param int $projectID + * @access private + * @return bool + */ + private function checkRequiredItems(object $oldPlan, object $plan, int $projectID): bool + { + if($plan->begin == '0000-00-00') dao::$errors['begin'][] = sprintf($this->lang->error->notempty, $this->lang->programplan->begin); + if($plan->end == '0000-00-00') dao::$errors['end'][] = sprintf($this->lang->error->notempty, $this->lang->programplan->end); + if(dao::isError()) return false; + + if($plan->parent) $parentStage = $this->getByID($plan->parent); + if(isset($parentStage) and $plan->begin < $parentStage->begin) + { + dao::$errors['begin'] = sprintf($this->lang->programplan->error->letterParent, $parentStage->begin); + return false; + } + if(isset($parentStage) and $plan->end > $parentStage->end) + { + dao::$errors['end'] = sprintf($this->lang->programplan->error->greaterParent, $parentStage->end); + return false; + } + + if($projectID) $this->loadModel('execution')->checkBeginAndEndDate($projectID, $plan->begin, $plan->end); + if(dao::isError()) return false; + + + $setCode = (isset($this->config->setCode) and $this->config->setCode == 1) ? true : false; + if($setCode and empty($plan->code)) + { + dao::$errors['code'][] = sprintf($this->lang->error->notempty, $this->lang->execution->code); + return false; + } + + + $setPercent = isset($this->config->setPercent) and $this->config->setPercent == 1 ? true : false; + if($plan->parent > 0) + { + $plan->attribute = $parentStage->attribute == 'mix' ? $plan->attribute : $parentStage->attribute; + $plan->acl = $parentStage->acl; + if($setPercent) + { + $parentPercent = $parentStage->percent; + $childrenTotalPercent = $this->getTotalPercent($parentStage, true); + $childrenTotalPercent = $plan->parent == $oldPlan->parent ? ($childrenTotalPercent - $oldPlan->percent + $plan->percent) : ($childrenTotalPercent + $plan->percent); + if($childrenTotalPercent > 100) return dao::$errors['percent'][] = $this->lang->programplan->error->percentOver; + } + + /* If child plan has milestone, update parent plan set milestone eq 0 . */ + if($plan->milestone and $parentStage->milestone) $this->dao->update(TABLE_PROJECT)->set('milestone')->eq(0)->where('id')->eq($oldPlan->parent)->exec(); + } + else + { + /* Synchronously update sub-phase permissions. */ + $childrenIDList = $this->dao->select('id')->from(TABLE_PROJECT)->where('parent')->eq($oldPlan->id)->fetchAll('id'); + if(!empty($childrenIDList)) $this->dao->update(TABLE_PROJECT)->set('acl')->eq($plan->acl)->where('id')->in(array_keys($childrenIDList))->exec(); + + /* The workload of the parent plan cannot exceed 100%. */ + $oldPlan->parent = $plan->parent; + if($setPercent) + { + $totalPercent = $this->getTotalPercent($oldPlan); + $totalPercent = $totalPercent + $plan->percent; + if($totalPercent > 100) return dao::$errors['percent'][] = $this->lang->programplan->error->percentOver; + } + } + + return true; + } } diff --git a/module/programplan/tao.php b/module/programplan/tao.php new file mode 100644 index 0000000000..14d4442f99 --- /dev/null +++ b/module/programplan/tao.php @@ -0,0 +1,36 @@ +dao->update(TABLE_PROJECT)->data($plan) + ->autoCheck() + ->batchCheckIF($requiredFields, $requiredFields, 'notempty') + ->checkIF($plan->end != '0000-00-00', 'end', 'ge', $plan->begin) + ->checkIF(!empty($plan->percent), 'percent', 'float') + ->checkIF(!empty($plan->name) && $ids && $project && $parentStage && $parent, 'name', 'unique', "id in ({$ids}) and type in ('sprint','stage') and `project` = {$project} and `deleted` = '0'" . ($parentStage ? " and `parent` = {$parent}" : '')) + ->checkIF(!empty($plan->code) and $setCode, 'code', 'unique', "id != {$plan->id} and type in ('sprint','stage','kanban') and `deleted` = '0'") + ->where('id')->eq($plan->id) + ->exec(); + + return !dao::isError(); + } +} diff --git a/module/programplan/zen.php b/module/programplan/zen.php new file mode 100644 index 0000000000..235571eb16 --- /dev/null +++ b/module/programplan/zen.php @@ -0,0 +1,70 @@ +rowdata; + $plan = $formData->join($rowData->output, ',')->get(); + return $plan; + } + + /** + * 阶段编辑后数据处理。 + * Handle data after edit. + * + * @param object $plan + * @param array $changes + * @access protected + * @return viod + */ + protected function afterEdit(object $plan, array $changes) + { + $actionID = $this->loadModel('action')->create('execution', $plan->id, 'edited'); + $this->action->logHistory($actionID, $changes); + + $newPlan = $this->programplan->getByID($plan->id); + + if($plan->parent != $newPlan->parent) + { + $this->programplan->computeProgress($plan->id, 'edit'); + $this->programplan->computeProgress($plan->parent, 'edit', true); + } + } + + /** + * 生成编辑阶段数据。 + * Build edit view data. + * + * @param object $plan + * @access protected + * @return viod + */ + protected function buildEditView(object $plan) + { + $this->loadModel('project'); + $this->app->loadLang('execution'); + $this->app->loadLang('stage'); + + $parentStage = $this->project->getByID($plan->parent, 'stage'); + + $this->view->title = $this->lang->programplan->edit; + $this->view->position[] = $this->lang->programplan->edit; + $this->view->isCreateTask = $this->programplan->isCreateTask($plan->id); + $this->view->plan = $plan; + $this->view->parentStageList = $this->programplan->getParentStageList($this->session->project, $plan->id, $plan->product); + $this->view->enableOptionalAttr = (empty($parentStage) or (!empty($parentStage) and $parentStage->attribute == 'mix')); + $this->view->isTopStage = $this->programplan->checkTopStage($plan->id); + $this->view->isLeafStage = $this->programplan->checkLeafStage($plan->id); + $this->view->PMUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst', $plan->PM); + $this->display(); + } +} diff --git a/module/todo/control.php b/module/todo/control.php index a5ea4c66ab..255a8d0a83 100755 --- a/module/todo/control.php +++ b/module/todo/control.php @@ -35,6 +35,7 @@ class todo extends control */ public function create(string $date = 'today', string $from = 'todo') { + $this->app->loadClass('date'); if($date == 'today') $date = date::today(); if(!empty($_POST))