diff --git a/module/execution/js/common.ui.js b/module/execution/js/common.ui.js index 270f6eb93e..3c76a64a47 100644 --- a/module/execution/js/common.ui.js +++ b/module/execution/js/common.ui.js @@ -4,7 +4,7 @@ * @access public * @return void */ -function computeWorkDays(currentID) +window.computeWorkDays = function(currentID) { isBatchEdit = false; if(currentID) diff --git a/module/execution/model.php b/module/execution/model.php index c6babab128..4e4e83328b 100755 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -441,180 +441,9 @@ class executionModel extends model $this->loadModel('project'); $this->app->loadLang('programplan'); - $executions = array(); $allChanges = array(); $oldExecutions = $this->getByIdList($postData->id); - $nameList = array(); - $codeList = array(); - - $parents = array(); - foreach($oldExecutions as $oldExecution) $parents[$oldExecution->id] = $oldExecution->parent; - - /* Replace required language. */ - if($this->app->tab == 'project') - { - $projectModel = $this->dao->select('model')->from(TABLE_PROJECT)->where('id')->eq($this->session->project)->fetch('model'); - if(empty($this->session->project) || $projectModel == 'scrum') - { - $this->lang->project->name = $this->lang->execution->name; - $this->lang->project->code = $this->lang->execution->code; - } - else - { - $this->lang->project->name = str_replace($this->lang->project->common, $this->lang->project->stage, $this->lang->project->name); - $this->lang->project->code = str_replace($this->lang->project->common, $this->lang->project->stage, $this->lang->project->code); - } - } - else - { - $this->lang->project->name = $this->lang->execution->name; - $this->lang->project->code = $this->lang->execution->code; - } - - $this->lang->error->unique = $this->lang->error->repeat; - $extendFields = $this->getFlowExtendFields(); - foreach($postData->id as $executionID) - { - $executionName = $postData->name[$executionID]; - if(isset($postData->code)) $executionCode = $postData->code[$executionID]; - - $executionID = (int)$executionID; - $executions[$executionID] = new stdClass(); - $executions[$executionID]->id = $executionID; - $executions[$executionID]->name = $executionName; - $executions[$executionID]->PM = $postData->PM[$executionID]; - $executions[$executionID]->PO = $postData->PO[$executionID]; - $executions[$executionID]->QD = $postData->QD[$executionID]; - $executions[$executionID]->RD = $postData->RD[$executionID]; - $executions[$executionID]->begin = $postData->begin[$executionID]; - $executions[$executionID]->end = $postData->end[$executionID]; - $executions[$executionID]->team = $postData->team[$executionID]; - $executions[$executionID]->desc = htmlspecialchars_decode($postData->desc[$executionID]); - $executions[$executionID]->days = $postData->days[$executionID]; - $executions[$executionID]->lastEditedBy = $this->app->user->account; - $executions[$executionID]->lastEditedDate = helper::now(); - - if(isset($postData->code)) $executions[$executionID]->code = $executionCode; - if(isset($postData->project)) $executions[$executionID]->project = zget($postData->project, $executionID, 0); - if(isset($postData->attribute[$executionID])) $executions[$executionID]->attribute = zget($postData->attribute, $executionID, ''); - if(isset($postData->lifetime[$executionID])) $executions[$executionID]->lifetime = $postData->lifetime[$executionID]; - - $oldExecution = $oldExecutions[$executionID]; - $projectID = isset($executions[$executionID]->project) ? (int)$executions[$executionID]->project : (int)$oldExecution->project; - $project = dao::isError() ? '' : $this->project->getByID($projectID); - - /* Check unique code for edited executions. */ - if(isset($postData->code) && empty($executionCode) && strpos(",{$this->config->execution->edit->requiredFields},", ',code,') !== false) - { - dao::$errors["code[$executionID]"] = sprintf($this->lang->error->notempty, $this->lang->execution->execCode); - } - elseif(isset($postData->code) and $executionCode) - { - if(isset($codeList[$executionCode])) - { - dao::$errors["code[$executionID]"] = sprintf($this->lang->error->unique, $this->lang->execution->execCode, $executionCode); - } - $codeList[$executionCode] = $executionCode; - } - - /* Name check. */ - $parentID = $parents[$executionID]; - if(isset($nameList[$executionName]) && !empty($executionName)) - { - foreach($nameList[$executionName] as $repeatID) - { - if($parentID == $parents[$repeatID]) - { - $type = $oldExecution->type == 'stage' ? 'stage' : 'agileplus'; - $repeatTip = $parentID == $projectID ? $this->lang->programplan->error->sameName : sprintf($this->lang->execution->errorNameRepeat, strtolower(zget($this->lang->programplan->typeList, $type))); - dao::$errors["name[$executionID]"] = $repeatTip; - } - } - } - - $nameList[$executionName][] = $executionID; - - /* Attribute check. */ - if(isset($postData->attribute) && isset($project->model) && in_array($project->model, array('waterfall', 'waterfallplus'))) - { - $this->app->loadLang('stage'); - $attribute = isset($executions[$executionID]->attribute) ? $executions[$executionID]->attribute : $oldExecution->attribute; - - if(isset($attributeList[$parentID])) - { - $parentAttr = $attributeList[$parentID]; - } - else - { - $parentAttr = dao::isError() ? $attribute : $this->dao->select('attribute')->from(TABLE_PROJECT)->where('id')->eq($parentID)->fetch('attribute'); - } - - if($parentAttr && $parentAttr != $attribute && $parentAttr != 'mix') - { - $parentAttr = zget($this->lang->stage->typeList, $parentAttr); - dao::$errors["attribute[$executionID]"] = sprintf($this->lang->execution->errorAttrMatch, $parentAttr); - } - - $attributeList[$executionID] = $attribute; - } - - /* Judge workdays is legitimate. */ - $workdays = helper::diffDate($postData->end[$executionID], $postData->begin[$executionID]) + 1; - if(isset($postData->days[$executionID]) and $postData->days[$executionID] > $workdays) - { - $this->app->loadLang('project'); - dao::$errors["days[{$executionID}]"] = sprintf($this->lang->project->workdaysExceed, $workdays); - } - - /* Parent stage begin and end check. */ - if(isset($executions[$parentID])) - { - $begin = $executions[$executionID]->begin; - $end = $executions[$executionID]->end; - $parentBegin = $executions[$parentID]->begin; - $parentEnd = $executions[$parentID]->end; - - if($begin < $parentBegin) - { - dao::$errors["begin[$executionID]"] = sprintf($this->lang->execution->errorLesserParent, $parentBegin); - } - - if($end > $parentEnd) - { - dao::$errors["end[$executionID]"] = sprintf($this->lang->execution->errorGreaterParent, $parentEnd); - } - } - - foreach($extendFields as $extendField) - { - $executions[$executionID]->{$extendField->field} = $postData->{$extendField->field}[$executionID]; - if(is_array($executions[$executionID]->{$extendField->field})) $executions[$executionID]->{$extendField->field} = implode(',', $executions[$executionID]->{$extendField->field}); - - $executions[$executionID]->{$extendField->field} = htmlSpecialString($executions[$executionID]->{$extendField->field}); - } - - if(empty($executions[$executionID]->begin)) dao::$errors["begin[{$executionID}]"] = sprintf($this->lang->error->notempty, $this->lang->execution->begin); - if(empty($executions[$executionID]->end)) dao::$errors["end[{$executionID}]"] = sprintf($this->lang->error->notempty, $this->lang->execution->end); - - /* Project begin and end check. */ - if(!empty($executions[$executionID]->begin) and !empty($executions[$executionID]->end)) - { - if($executions[$executionID]->begin > $executions[$executionID]->end) - { - dao::$errors["end[{$executionID}]"] = sprintf($this->lang->execution->errorLesserPlan, $executions[$executionID]->end, $executions[$executionID]->begin); - } - - if($project and $executions[$executionID]->begin < $project->begin) - { - dao::$errors["begin[{$executionID}]"] = sprintf($this->lang->execution->errorLesserProject, $project->begin); - } - if($project and $executions[$executionID]->end > $project->end) - { - dao::$errors["end[{$executionID}]"] = sprintf($this->lang->execution->errorGreaterProject, $project->end); - } - } - } - + $executions = $this->buildBatchUpdateExecutions($postData, $oldExecutions); if(dao::isError()) return false; /* Update burn before close execution. */ @@ -628,7 +457,7 @@ class executionModel extends model foreach($executions as $executionID => $execution) { $oldExecution = $oldExecutions[$executionID]; - $team = $this->loadModel('user')->getTeamMemberPairs($executionID, 'execution'); + $team = $this->user->getTeamMemberPairs($executionID, 'execution'); $projectID = isset($execution->project) ? (int)$execution->project : (int)$oldExecution->project; if(isset($execution->project)) @@ -671,7 +500,7 @@ class executionModel extends model { $execution->parent = $execution->project; $execution->path = ",{$execution->project},{$executionID},"; - $this->changeProject($execution->project, $oldExecution->project, $executionID, isset($postData->syncStories[$executionID]) ? $postData->syncStories[$executionID] : 'no'); + $this->changeProject((int)$execution->project, $oldExecution->project, $executionID, isset($postData->syncStories[$executionID]) ? $postData->syncStories[$executionID] : 'no'); } if(!empty($execution->attribute) && $oldExecution->attribute != $execution->attribute && $execution->attribute != 'mix') diff --git a/module/execution/tao.php b/module/execution/tao.php index 082a3d9408..4a45d3f48a 100644 --- a/module/execution/tao.php +++ b/module/execution/tao.php @@ -77,6 +77,194 @@ class executionTao extends executionModel return $executionPairs; } + /** + * 构造批量更新执行的数据。 + * Build bathc update execution data. + * + * @param object $postData + * @param array $oldExecutions + * @access public + * @return array + */ + public function buildBatchUpdateExecutions(object $postData, array $oldExecutions): array + { + $this->loadModel('user'); + $this->loadModel('project'); + $this->app->loadLang('programplan'); + + $executions = array(); + $nameList = array(); + $codeList = array(); + $parents = array(); + foreach($oldExecutions as $oldExecution) $parents[$oldExecution->id] = $oldExecution->parent; + + /* Replace required language. */ + if($this->app->tab == 'project') + { + $projectModel = $this->dao->select('model')->from(TABLE_PROJECT)->where('id')->eq($this->session->project)->fetch('model'); + if(empty($this->session->project) || $projectModel == 'scrum') + { + $this->lang->project->name = $this->lang->execution->name; + $this->lang->project->code = $this->lang->execution->code; + } + else + { + $this->lang->project->name = str_replace($this->lang->project->common, $this->lang->project->stage, $this->lang->project->name); + $this->lang->project->code = str_replace($this->lang->project->common, $this->lang->project->stage, $this->lang->project->code); + } + } + else + { + $this->lang->project->name = $this->lang->execution->name; + $this->lang->project->code = $this->lang->execution->code; + } + + $this->lang->error->unique = $this->lang->error->repeat; + $extendFields = $this->getFlowExtendFields(); + foreach($postData->id as $executionID) + { + $executionName = $postData->name[$executionID]; + if(isset($postData->code)) $executionCode = $postData->code[$executionID]; + + $executionID = (int)$executionID; + $executions[$executionID] = new stdClass(); + $executions[$executionID]->id = $executionID; + $executions[$executionID]->name = $executionName; + $executions[$executionID]->PM = $postData->PM[$executionID]; + $executions[$executionID]->PO = $postData->PO[$executionID]; + $executions[$executionID]->QD = $postData->QD[$executionID]; + $executions[$executionID]->RD = $postData->RD[$executionID]; + $executions[$executionID]->begin = $postData->begin[$executionID]; + $executions[$executionID]->end = $postData->end[$executionID]; + $executions[$executionID]->team = $postData->team[$executionID]; + $executions[$executionID]->desc = htmlspecialchars_decode($postData->desc[$executionID]); + $executions[$executionID]->days = $postData->days[$executionID]; + $executions[$executionID]->lastEditedBy = $this->app->user->account; + $executions[$executionID]->lastEditedDate = helper::now(); + + if(isset($postData->code)) $executions[$executionID]->code = $executionCode; + if(isset($postData->project)) $executions[$executionID]->project = zget($postData->project, $executionID, 0); + if(isset($postData->attribute[$executionID])) $executions[$executionID]->attribute = zget($postData->attribute, $executionID, ''); + if(isset($postData->lifetime[$executionID])) $executions[$executionID]->lifetime = $postData->lifetime[$executionID]; + + $oldExecution = $oldExecutions[$executionID]; + $projectID = isset($executions[$executionID]->project) ? (int)$executions[$executionID]->project : (int)$oldExecution->project; + $project = dao::isError() ? '' : $this->project->getByID($projectID); + + /* Check unique code for edited executions. */ + if(isset($postData->code) && empty($executionCode) && strpos(",{$this->config->execution->edit->requiredFields},", ',code,') !== false) + { + dao::$errors["code[$executionID]"] = sprintf($this->lang->error->notempty, $this->lang->execution->execCode); + } + elseif(isset($postData->code) and $executionCode) + { + if(isset($codeList[$executionCode])) + { + dao::$errors["code[$executionID]"] = sprintf($this->lang->error->unique, $this->lang->execution->execCode, $executionCode); + } + $codeList[$executionCode] = $executionCode; + } + + /* Name check. */ + $parentID = $parents[$executionID]; + if(isset($nameList[$executionName]) && !empty($executionName)) + { + foreach($nameList[$executionName] as $repeatID) + { + if($parentID == $parents[$repeatID]) + { + $type = $oldExecution->type == 'stage' ? 'stage' : 'agileplus'; + $repeatTip = $parentID == $projectID ? $this->lang->programplan->error->sameName : sprintf($this->lang->execution->errorNameRepeat, strtolower(zget($this->lang->programplan->typeList, $type))); + dao::$errors["name[$executionID]"] = $repeatTip; + } + } + } + + $nameList[$executionName][] = $executionID; + + /* Attribute check. */ + if(isset($postData->attribute) && isset($project->model) && in_array($project->model, array('waterfall', 'waterfallplus'))) + { + $this->app->loadLang('stage'); + $attribute = isset($executions[$executionID]->attribute) ? $executions[$executionID]->attribute : $oldExecution->attribute; + + if(isset($attributeList[$parentID])) + { + $parentAttr = $attributeList[$parentID]; + } + else + { + $parentAttr = dao::isError() ? $attribute : $this->dao->select('attribute')->from(TABLE_PROJECT)->where('id')->eq($parentID)->fetch('attribute'); + } + + if($parentAttr && $parentAttr != $attribute && $parentAttr != 'mix') + { + $parentAttr = zget($this->lang->stage->typeList, $parentAttr); + dao::$errors["attribute[$executionID]"] = sprintf($this->lang->execution->errorAttrMatch, $parentAttr); + } + + $attributeList[$executionID] = $attribute; + } + + /* Judge workdays is legitimate. */ + $workdays = helper::diffDate($postData->end[$executionID], $postData->begin[$executionID]) + 1; + if(isset($postData->days[$executionID]) and $postData->days[$executionID] > $workdays) + { + $this->app->loadLang('project'); + dao::$errors["days[{$executionID}]"] = sprintf($this->lang->project->workdaysExceed, $workdays); + } + + /* Parent stage begin and end check. */ + if(isset($executions[$parentID])) + { + $begin = $executions[$executionID]->begin; + $end = $executions[$executionID]->end; + $parentBegin = $executions[$parentID]->begin; + $parentEnd = $executions[$parentID]->end; + + if($begin < $parentBegin) + { + dao::$errors["begin[$executionID]"] = sprintf($this->lang->execution->errorLesserParent, $parentBegin); + } + + if($end > $parentEnd) + { + dao::$errors["end[$executionID]"] = sprintf($this->lang->execution->errorGreaterParent, $parentEnd); + } + } + + foreach($extendFields as $extendField) + { + $executions[$executionID]->{$extendField->field} = $postData->{$extendField->field}[$executionID]; + if(is_array($executions[$executionID]->{$extendField->field})) $executions[$executionID]->{$extendField->field} = implode(',', $executions[$executionID]->{$extendField->field}); + + $executions[$executionID]->{$extendField->field} = htmlSpecialString($executions[$executionID]->{$extendField->field}); + } + + if(empty($executions[$executionID]->begin)) dao::$errors["begin[{$executionID}]"] = sprintf($this->lang->error->notempty, $this->lang->execution->begin); + if(empty($executions[$executionID]->end)) dao::$errors["end[{$executionID}]"] = sprintf($this->lang->error->notempty, $this->lang->execution->end); + + /* Project begin and end check. */ + if(!empty($executions[$executionID]->begin) and !empty($executions[$executionID]->end)) + { + if($executions[$executionID]->begin > $executions[$executionID]->end) + { + dao::$errors["end[{$executionID}]"] = sprintf($this->lang->execution->errorLesserPlan, $executions[$executionID]->end, $executions[$executionID]->begin); + } + + if($project and $executions[$executionID]->begin < $project->begin) + { + dao::$errors["begin[{$executionID}]"] = sprintf($this->lang->execution->errorLesserProject, $project->begin); + } + if($project and $executions[$executionID]->end > $project->end) + { + dao::$errors["end[{$executionID}]"] = sprintf($this->lang->execution->errorGreaterProject, $project->end); + } + } + } + return $executions; + } + /** * 获取燃尽图相关数据。 * Get burn related data. diff --git a/module/execution/ui/batchedit.html.php b/module/execution/ui/batchedit.html.php index 49c68f2fbd..daedc79217 100644 --- a/module/execution/ui/batchedit.html.php +++ b/module/execution/ui/batchedit.html.php @@ -18,6 +18,160 @@ jsVar('stageList', $lang->stage->typeList); jsVar('confirmSync', $lang->execution->confirmSync); jsVar('parents', $parents); +$items = array(); +$items[] = array +( + 'name' => 'id', + 'label' => $lang->idAB, + 'control' => 'hidden', + 'hidden' => true +); +$items[] = array +( + 'name' => 'id', + 'label' => $lang->idAB, + 'control' => 'index', + 'width' => '38px' +); +if(isset($project) && $project->model == 'scrum') $items[] = array +( + 'label' => $lang->execution->projectName, + 'control' => 'picker', + 'name' => "project", + 'items' => $allProjects, + 'required' => true, + 'width' => '136px' +); +$items[] = array +( + 'name' => 'name', + 'label' => $app->tab == 'execution' ? $lang->execution->execName : $lang->execution->name, + 'width' => '240px', + 'required' => true +); +if($showMethod) $items[] = array +( + 'name' => 'type', + 'label' => $lang->execution->method, + 'control' => array('control' => 'picker', 'required' => true), + 'items' => $lang->execution->typeList, + 'disabled' => true, + 'width' => '100px' +); +if($setCode) $items[] = array +( + 'name' => 'code', + 'label' => $app->tab == 'execution' ? $lang->execution->execCode : $lang->execution->code, + 'width' => '136px', + 'required' => strpos(",{$config->execution->edit->requiredFields},", ',code,') !== false +); +$items[] = array +( + 'name' => 'PM', + 'label' => $app->tab == 'execution' ? $lang->execution->execPM : $lang->execution->PM, + 'control' => 'picker', + 'ditto' => true, + 'defaultDitto' => 'off', + 'items' => $pmUsers, + 'hidden' => strpos("{$showFields}", 'PM') === false, + 'width' => '112px' +); +$items[] = array +( + 'name' => 'PO', + 'label' => $lang->execution->PO, + 'control' => 'picker', + 'ditto' => true, + 'defaultDitto' => 'off', + 'items' => $poUsers, + 'hidden' => strpos("{$showFields}", 'PO') === false, + 'width' => '180px' +); +$items[] = array +( + 'name' => 'QD', + 'label' => $lang->execution->QD, + 'control' => 'picker', + 'ditto' => true, + 'defaultDitto' => 'off', + 'items' => $qdUsers, + 'hidden' => strpos("{$showFields}", 'QD') === false, + 'width' => '180px' +); +$items[] = array +( + 'name' => 'RD', + 'label' => $lang->execution->RD, + 'control' => 'picker', + 'ditto' => true, + 'defaultDitto' => 'off', + 'items' => $rdUsers, + 'hidden' => strpos("{$showFields}", 'RD') === false, + 'width' => '180px' +); +$items[] = array +( + 'name' => 'lifetime', + 'label' => $app->tab == 'execution' ? $lang->execution->execType : $lang->execution->type, + 'control' => 'picker', + 'items' => $lang->execution->lifeTimeList, + 'width' => '120px', + 'tipIcon' => 'help', + 'hidden' => strpos("{$showFields}", 'lifetime') === false, + 'tip' => $lang->execution->typeTip, + 'tipProps' => array + ( + 'id' => 'tooltipHover', + 'data-toggle' => 'tooltip', + 'data-placement' => 'right', + 'data-type' => 'white', + 'data-class-name' => 'text-gray border border-gray-300' + ) +); +$items[] = array +( + 'name' => 'begin', + 'label' => $lang->execution->begin, + 'control' => 'date', + 'width' => '120px', + 'required' => true +); +$items[] = array +( + 'name' => 'end', + 'label' => $lang->execution->end, + 'control' => 'date', + 'width' => '120px', + 'required' => true +); +$items[] = array +( + 'name' => 'team', + 'label' => $lang->execution->teamName, + 'width' => '136px', + 'hidden' => strpos("{$showFields}", 'team') === false +); +$items[] = array +( + 'name' => 'desc', + 'label' => $app->tab == 'execution' ? $lang->execution->execDesc : $lang->execution->desc, + 'control' => 'textarea', + 'width' => '160px', + 'hidden' => strpos("{$showFields}", 'desc') === false +); +$items[] = array +( + 'name' => 'days', + 'label' => $lang->execution->days, + 'control' => array + ( + 'control' => 'inputControl', + 'suffix' => $lang->execution->day, + 'suffixWidth' => 20 + ), + 'width' => '80px', + 'hidden' => strpos("{$showFields}", 'days') === false +); formBatchPanel ( set::title($lang->execution->batchEditAction), @@ -30,166 +184,7 @@ formBatchPanel on::change('[data-name="begin"]', "computeWorkDays($(e.target).attr('name'))"), on::change('[data-name="end"]', "computeWorkDays($(e.target).attr('name'))"), on::change('[data-name="attribute"]', 'changeAttribute'), - formBatchItem - ( - set::name('id'), - set::label($lang->idAB), - set::control('hidden'), - set::hidden(true) - ), - formBatchItem - ( - set::name('id'), - set::label($lang->idAB), - set::control('index'), - set::width('38px') - ), - isset($project) && $project->model == 'scrum' ? formBatchItem - ( - set::label($lang->execution->projectName), - set::control('picker'), - set::name("project"), - set::items($allProjects), - set::required(true), - set::width('136px') - ) : null, - formBatchItem - ( - set::name('name'), - set::label($app->tab == 'execution' ? $lang->execution->execName : $lang->execution->name), - set::width('240px'), - set::required(true) - ), - $showMethod ? formBatchItem - ( - set::name('type'), - set::label($lang->execution->method), - set::control(array('control' => 'picker', 'required' => true)), - set::items($lang->execution->typeList), - set::disabled(true), - set::width('100px') - ) : null, - $setCode ? formBatchItem - ( - set::name('code'), - set::label($app->tab == 'execution' ? $lang->execution->execCode : $lang->execution->code), - set::width('136px'), - set::required(strpos(",{$config->execution->edit->requiredFields},", ',code,') !== false) - ) : null, - formBatchItem - ( - set::name('PM'), - set::label($app->tab == 'execution' ? $lang->execution->execPM : $lang->execution->PM), - set::control('picker'), - set::ditto(true), - set::defaultDitto('off'), - set::items($pmUsers), - set::hidden(strpos("{$showFields}", 'PM') === false), - set::width('112px') - ), - formBatchItem - ( - set::name('PO'), - set::label($lang->execution->PO), - set::control('picker'), - set::ditto(true), - set::defaultDitto('off'), - set::items($poUsers), - set::hidden(strpos("{$showFields}", 'PO') === false), - set::width('180px') - ), - formBatchItem - ( - set::name('QD'), - set::label($lang->execution->QD), - set::control('picker'), - set::ditto(true), - set::defaultDitto('off'), - set::items($qdUsers), - set::hidden(strpos("{$showFields}", 'QD') === false), - set::width('180px') - ), - formBatchItem - ( - set::name('RD'), - set::label($lang->execution->RD), - set::control('picker'), - set::ditto(true), - set::defaultDitto('off'), - set::items($rdUsers), - set::hidden(strpos("{$showFields}", 'RD') === false), - set::width('180px') - ), - formBatchItem - ( - set::name('lifetime'), - set::label($app->tab == 'execution' ? $lang->execution->execType : $lang->execution->type), - set::control('picker'), - set::items($lang->execution->lifeTimeList), - set::width('120px'), - set::tipIcon('help'), - set::hidden(strpos("{$showFields}", 'lifetime') === false), - set::tip($lang->execution->typeTip), - set - ( - 'tipProps', - array - ( - 'id' => 'tooltipHover', - 'data-toggle' => 'tooltip', - 'data-placement' => 'right', - 'data-type' => 'white', - 'data-class-name' => 'text-gray border border-gray-300' - ) - ) - ), - formBatchItem - ( - set::name('begin'), - set::label($lang->execution->begin), - set::control('date'), - set::width('120px'), - set::required(true) - ), - formBatchItem - ( - set::name('end'), - set::label($lang->execution->end), - set::control('date'), - set::width('120px'), - set::required(true) - ), - formBatchItem - ( - set::name('team'), - set::label($lang->execution->teamName), - set::width('136px'), - set::hidden(strpos("{$showFields}", 'team') === false) - ), - formBatchItem - ( - set::name('desc'), - set::label($app->tab == 'execution' ? $lang->execution->execDesc : $lang->execution->desc), - set::control('textarea'), - set::width('160px'), - set::hidden(strpos("{$showFields}", 'desc') === false) - ), - formBatchItem - ( - set::name('days'), - set::label($lang->execution->days), - set::control - ( - array - ( - 'type' => 'inputControl', - 'suffix' => $lang->execution->day, - 'suffixWidth' => 20 - ) - ), - set::width('80px'), - set::hidden(strpos("{$showFields}", 'days') === false) - ) + set::items($items) ); render(); diff --git a/module/execution/ui/putoff.html.php b/module/execution/ui/putoff.html.php index d00bd7e639..e982f72a9f 100644 --- a/module/execution/ui/putoff.html.php +++ b/module/execution/ui/putoff.html.php @@ -25,6 +25,7 @@ formPanel set::label($lang->execution->dateRange), inputGroup ( + setID('dateBox'), datePicker ( set::control('date'), diff --git a/module/programplan/ui/create.html.php b/module/programplan/ui/create.html.php index c00934f46f..c614b7bf1c 100644 --- a/module/programplan/ui/create.html.php +++ b/module/programplan/ui/create.html.php @@ -255,11 +255,14 @@ $fnGenerateDefaultData = function() use ($config, $plans, $planID, $stages, $exe $item->order = $plan->order; $item->parallel = $plan->parallel; $item->point = implode(',', $points); + $plan->disabled = !isset($plan->setMilestone); + $plan->setMilestone = isset($plan->setMilestone) ? $plan->setMilestone : false; + $plan->point = implode(',', $points); if(in_array($config->edition, array('max', 'ipd')) && $executionType == 'stage') { - $item->output = empty($plan->output) ? 0 : explode(',', $plan->output); + $plan->output = empty($plan->output) ? 0 : explode(',', $plan->output); } - $items[] = $item; + $items[] = $plan; } return $items; diff --git a/module/programplan/ui/edit.html.php b/module/programplan/ui/edit.html.php index 137e55e372..20796efd52 100644 --- a/module/programplan/ui/edit.html.php +++ b/module/programplan/ui/edit.html.php @@ -123,6 +123,7 @@ formPanel set::required(true), inputGroup ( + setID('dateBox'), datepicker(set::name('begin'), set::value($plan->begin)), $lang->project->to, datepicker(set::name('end'), set::value($plan->end)) diff --git a/module/programplan/zen.php b/module/programplan/zen.php index 19d7c9c22a..1eb482c195 100644 --- a/module/programplan/zen.php +++ b/module/programplan/zen.php @@ -67,8 +67,10 @@ class programplanZen extends programplan $plan->parent = $parentID ? $parentID : $projectID; $plan->order = (int)array_shift($orders); $plan->hasProduct = $project->hasProduct; - if(!empty($parentID) and !empty($parentStage) and $parentStage->attribute != 'mix') $plan->attribute = $parentStage->attribute;; - if(!empty($parentID) and !empty($parentStage)) $plan->acl = $parentStage->acl; + + if(empty($plan->days)) $plan->days = helper::diffDate($plan->end, $plan->begin) + 1; + if(!empty($parentID) && !empty($parentStage) && $parentStage->attribute != 'mix') $plan->attribute = $parentStage->attribute;; + if(!empty($parentID) && !empty($parentStage)) $plan->acl = $parentStage->acl; if(in_array($this->config->edition, array('max', 'ipd')) && !dao::isError()) { diff --git a/module/project/config/form.php b/module/project/config/form.php index cb47b1eeda..2b3af515d4 100755 --- a/module/project/config/form.php +++ b/module/project/config/form.php @@ -47,14 +47,14 @@ $config->project->form->activate['end'] = array('type' => 'date', 're $config->project->form->activate['readjustTime'] = array('type' => 'int', 'required' => false, 'default' => ''); $config->project->form->activate['readjustTask'] = array('type' => 'array', 'required' => false, 'default' => ''); -$config->project->form->batchedit['id'] = array('type' => 'int', 'required' => false, 'base' => true); -$config->project->form->batchedit['parent'] = array('type' => 'int', 'required' => false); -$config->project->form->batchedit['name'] = array('type' => 'string', 'required' => true, 'filter' => 'trim'); -$config->project->form->batchedit['PM'] = array('type' => 'string', 'required' => false); -$config->project->form->batchedit['begin'] = array('type' => 'date', 'required' => true); -$config->project->form->batchedit['end'] = array('type' => 'date', 'required' => true); -$config->project->form->batchedit['day'] = array('type' => 'int', 'required' => false); -$config->project->form->batchedit['acl'] = array('type' => 'string', 'required' => false); +$config->project->form->batchedit['id'] = array('type' => 'int', 'required' => false, 'base' => true); +$config->project->form->batchedit['parent'] = array('type' => 'int', 'required' => false); +$config->project->form->batchedit['name'] = array('type' => 'string', 'required' => true, 'filter' => 'trim'); +$config->project->form->batchedit['PM'] = array('type' => 'string', 'required' => false); +$config->project->form->batchedit['begin'] = array('type' => 'date', 'required' => true); +$config->project->form->batchedit['end'] = array('type' => 'date', 'required' => true); +$config->project->form->batchedit['days'] = array('type' => 'int', 'required' => false); +$config->project->form->batchedit['acl'] = array('type' => 'string', 'required' => false); if(isset($config->setCode) and $config->setCode == 1) $config->project->form->batchedit['code'] = array('type' => 'string', 'required' => false, 'filter' => 'trim'); $config->project->form->manageMembers['account'] = array('type' => 'string', 'required' => false, 'base' => true); diff --git a/module/project/js/batchedit.ui.js b/module/project/js/batchedit.ui.js index 0068facf17..6eaa28215b 100644 --- a/module/project/js/batchedit.ui.js +++ b/module/project/js/batchedit.ui.js @@ -7,7 +7,7 @@ let batchIgnoreTips = []; * @access public * @return void */ -function batchComputeWorkDays() +window.batchComputeWorkDays = function() { const $tr = $(this).closest('tr'); if($tr.find('div[data-longtime="1"]').length > 0) return false; diff --git a/module/project/js/common.ui.js b/module/project/js/common.ui.js index 434cabaa78..0a0f6fce60 100644 --- a/module/project/js/common.ui.js +++ b/module/project/js/common.ui.js @@ -76,7 +76,7 @@ function computeDaysDelta(date1, date2) * @access public * @return void */ -function computeWorkDays() +window.computeWorkDays = function() { const begin = $('input[name=begin]').val(); const end = $('input[name=end]').val(); diff --git a/module/project/tao.php b/module/project/tao.php index 6b2314b343..a1ee2e2bf4 100755 --- a/module/project/tao.php +++ b/module/project/tao.php @@ -576,12 +576,12 @@ class projectTao extends projectModel * 构造批量更新项目的数据。 * Build bathc update project data. * - * @param array $data - * @param array $oldProjects - * @access protected + * @param array $data + * @param array $oldProjects + * @access public * @return array */ - protected function buildBatchUpdateProjects(array $data, array $oldProjects): array + public function buildBatchUpdateProjects(array $data, array $oldProjects): array { if(empty($data)) return array(); @@ -600,6 +600,7 @@ class projectTao extends projectModel $projects[$projectID]->begin = $project->begin; $projects[$projectID]->end = $project->end == $this->lang->project->longTime ? LONG_TIME : $project->end; $projects[$projectID]->acl = $project->acl; + $projects[$projectID]->days = $project->days; $projects[$projectID]->lastEditedBy = $this->app->user->account; $projects[$projectID]->lastEditedDate = helper::now();