diff --git a/module/kanban/model.php b/module/kanban/model.php index ee6580f9be..d13038a88d 100644 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -537,7 +537,7 @@ class kanbanModel extends model $branches = array(); $colorIndex = 0; $laneOrder = 1; - $cardActions = array('view', 'createExecution', 'linkStory', 'linkBug', 'edit', 'start', 'finish', 'close', 'activate'); + $cardActions = array('view', 'createExecution', 'linkStory', 'linkBug', 'edit', 'start', 'finish', 'close', 'activate', 'delete'); if($product->type == 'normal') { diff --git a/module/my/control.php b/module/my/control.php index 748fcb8c36..6f6d6827d3 100644 --- a/module/my/control.php +++ b/module/my/control.php @@ -1078,6 +1078,7 @@ class my extends control $this->session->set('opportunityLibList', $uri, 'assetlib'); $this->session->set('practiceLibList', $uri, 'assetlib'); $this->session->set('componentLibList', $uri, 'assetlib'); + $this->session->set('opportunityList', $uri, 'project'); /* Set the pager. */ $this->app->loadClass('pager', $static = true); diff --git a/module/productplan/css/browse.css b/module/productplan/css/browse.css index d9750bbb47..154e628e50 100644 --- a/module/productplan/css/browse.css +++ b/module/productplan/css/browse.css @@ -18,7 +18,7 @@ td.c-branch {overflow: hidden; text-align: left !important; text-overflow: ellip .c-title {width: 160px;} .c-branch {width: 100px;} .c-story {width: 80px;} -.c-execution {width: 120px;} +.c-execution {width: 50px !important;} .c-bug, .c-hour {width: 60px;} .plan-name {position: relative; display: flex; align-items: center;} diff --git a/module/productplan/js/browse.js b/module/productplan/js/browse.js index 19e22af2a3..35a4c80cac 100644 --- a/module/productplan/js/browse.js +++ b/module/productplan/js/browse.js @@ -125,7 +125,11 @@ function createCardMenu(options) var executionLink = systemMode == 'new' ? '#projects' : createLink('execution', 'create', "projectID=0&executionID=0©ExecutionID=0&plan=" + card.id + "&confirm=no&productID=" + productID); var today = new Date(); var end = $.zui.createDate(card.end); - if(end.toLocaleDateString() < today.toLocaleDateString() && (card.status == 'wait' || card.status == 'doing')) + if(end.toLocaleDateString() < today.toLocaleDateString()) + { + className = 'disabled'; + } + else if(card.status == 'done' || card.status == 'closed') { className = 'disabled'; } @@ -163,6 +167,7 @@ function createCardMenu(options) if(privs.includes('finish')) items.push({label: productplanLang.finish, icon: 'checked', url: createLink('productplan', 'finish', "planID=" + card.id), attrs: {'target': 'hiddenwin'}}); if(privs.includes('close')) items.push({label: productplanLang.close, icon: 'off', url: createLink('productplan', 'close', "planID=" + card.id), attrs: {'target': 'hiddenwin'}}); if(privs.includes('activate')) items.push({label: productplanLang.activate, icon: 'magic', url: createLink('productplan', 'activate', "planID=" + card.id), attrs: {'target': 'hiddenwin'}}); + if(privs.includes('delete')) items.push({label: productplanLang.delete, icon: 'trash', url: createLink('productplan', 'delete', "planID=" + card.id), attrs: {'target': 'hiddenwin'}}); var bounds = options.$trigger[0].getBoundingClientRect(); items.$options = {x: bounds.right, y: bounds.top}; @@ -302,7 +307,7 @@ function changeCardColType(card, fromColType, toColType, kanbanID) function renderKanbanItem(item, $item) { var privs = item.actions; - var printMoreBtn = (privs.includes('createExecution') || privs.includes('linkStory') || privs.includes('linkBug') || privs.includes('edit') || privs.includes('start') || privs.includes('finish') || privs.includes('close') || privs.includes('activate')); + var printMoreBtn = (privs.includes('createExecution') || privs.includes('linkStory') || privs.includes('linkBug') || privs.includes('edit') || privs.includes('start') || privs.includes('finish') || privs.includes('close') || privs.includes('activate') || privs.includes('delete')); /* Output header information. */ var $header = $item.children('.header'); @@ -324,7 +329,7 @@ function renderKanbanItem(item, $item) if(!$title.length) { if(privs.includes('view')) $title = $('').appendTo($titleBox).attr('href', createLink('productplan', 'view', 'cardID=' + item.id)); - if(!privs.includes('view')) $title = $('

').appendTo($titleBox); + if(!privs.includes('view')) $title = $('').appendTo($titleBox); } $title.text(item.title).attr('title', item.title); @@ -334,7 +339,7 @@ function renderKanbanItem(item, $item) var end = $.zui.createDate(item.end); if(end.toLocaleDateString() < today.toLocaleDateString() && (item.status == 'wait' || item.status == 'doing')) { - $expired = $('.titleBox').children('.expired'); + $expired = $titleBox.children('.expired'); if(!$expired.length) { $('' + productplanLang.expired + '').appendTo($titleBox); diff --git a/module/productplan/model.php b/module/productplan/model.php index 4561d53268..316b698401 100644 --- a/module/productplan/model.php +++ b/module/productplan/model.php @@ -537,11 +537,15 @@ class productplanModel extends model ->batchCheck($this->config->productplan->start->requiredFields, 'notempty') ->checkIF(!empty($_POST['begin']) && !empty($_POST['end']), 'end', 'ge', $plan->begin) ->where('id')->eq($planID) - ->beginIF(isset($parentPlan))->orWhere('id')->eq($oldPlan->parent)->fi() ->exec(); $this->file->updateObjectID($this->post->uid, $planID, 'productplan'); - if($parentPlan->status != 'doing') $parentChange = true; + + if(isset($parentPlan) and $parentPlan->status != 'doing') + { + $this->dao->update(TABLE_PRODUCTPLAN)->set('status')->eq($status)->where('id')->eq($oldPlan->parent)->exec(); + $parentChange = true; + } } elseif($status == 'doing' and isset($parentPlan) and $parentPlan->status != 'doing') { @@ -607,22 +611,22 @@ class productplanModel extends model if($method == 'start') { $action = 'started'; - if($parentChange) $parentAction = 'startedbychild'; + if(isset($parentChange) and $parentChange) $parentAction = 'startedbychild'; } elseif($method == 'finish') { $action = 'finished'; - if($parentChange) $parentAction = 'finishedbychild'; + if(isset($parentChange) and $parentChange) $parentAction = 'finishedbychild'; } elseif($method == 'close') { $action = 'closed'; - if($parentChange) $parentAction = 'closedbychild'; + if(isset($parentChange) and $parentChange) $parentAction = 'closedbychild'; } elseif($method == 'activate') { $action = 'activated'; - if($parentChange) $parentAction = 'activatedbychild'; + if(isset($parentChange) and $parentChange) $parentAction = 'activatedbychild'; } if(isset($action)) @@ -631,7 +635,7 @@ class productplanModel extends model $actionID = $this->loadModel('action')->create('productplan', $planID, $action); $this->action->loghistory($actionID, $changes); - if($parentChange) $actionID = $this->action->create('productplan', $oldPlan->parent, $parentAction, '', $parentAction); + if(isset($parentChange) and $parentChange) $actionID = $this->action->create('productplan', $oldPlan->parent, $parentAction, '', $parentAction); } } } @@ -726,17 +730,17 @@ class productplanModel extends model $maxEnd = $end; foreach($childPlans as $childPlan) { - if($childPlan->begin < $minBegin) $minBegin = $childPlan->begin; - if($childPlan->end > $maxEnd) $maxEnd = $childPlan->end; + if($childPlan->begin < $minBegin and $minBegin != '2030-01-01') $minBegin = $childPlan->begin; + if($childPlan->end > $maxEnd and $maxEnd != '2030-01-01') $maxEnd = $childPlan->end; } - if($minBegin < $begin) dao::$errors['begin'] = sprintf($this->lang->beginGreaterChild, $minBegin); - if($maxEnd > $end) dao::$errors['end'] = sprintf($this->lang->endLetterChild, $maxEnd); + if($minBegin < $begin and $begin != '2030-01-01') dao::$errors['begin'] = sprintf($this->lang->beginGreaterChild, $minBegin); + if($maxEnd > $end and $end != '2030-01-01') dao::$errors['end'] = sprintf($this->lang->endLetterChild, $maxEnd); } elseif($plan->parent > 0) { $parentPlan = $this->getByID($plan->parent); - if($begin < $parentPlan->begin) dao::$errors['begin'] = sprintf($this->lang->productplan->beginLetterParent, $parentPlan->begin); - if($end > $parentPlan->end) dao::$errors['end'] = sprintf($this->lang->productplan->endGreaterParent, $parentPlan->end); + if($begin < $parentPlan->begin and $parentPlan->begin != '2030-01-01') dao::$errors['begin'] = sprintf($this->lang->productplan->beginLetterParent, $parentPlan->begin); + if($end > $parentPlan->end and $parentPlan->end != '2030-01-01') dao::$errors['end'] = sprintf($this->lang->productplan->endGreaterParent, $parentPlan->end); } } @@ -966,7 +970,11 @@ class productplanModel extends model if($plan->status != 'done' or $plan->parent < 0) return false; break; case 'activate' : +<<<<<<< module/productplan/model.php if(($plan->status != 'closed' and $plan->status != 'done') or $plan->parent < 0) return false; +======= + if($plan->status == 'wait' or $plan == 'doing' or $plan->parent < 0) return false; +>>>>>>> module/productplan/model.php break; } diff --git a/module/productplan/view/browsebylist.html.php b/module/productplan/view/browsebylist.html.php index 6f3ce09231..5736b01423 100644 --- a/module/productplan/view/browsebylist.html.php +++ b/module/productplan/view/browsebylist.html.php @@ -78,6 +78,7 @@ loadModel('file');?> + ' title="title?>"> end < helper::now()) $suffix = "{$this->lang->productplan->expired}"; - if($plan->parent == '-1') $suffix .= ''; + if($plan->parent > 0 and !isset($plans[$plan->parent])) $prefix = "{$this->lang->productplan->childrenAB}"; + if($plan->end < $today and in_array($plan->status, array('wait', 'doing'))) $suffix = "{$this->lang->productplan->expired}"; + if($plan->parent == '-1' and isset($plan->children)) $suffix .= ''; if(!empty($suffix)) echo '
'; + if(!empty($prefix)) echo $prefix; echo html::a(inlink('view', "id=$plan->id"), $plan->title); if(!empty($suffix)) echo $suffix . '
'; ?> @@ -166,6 +170,7 @@ $branchStatus = isset($branchStatusList[$plan->branch]) ? $branchStatusList[$plan->branch] : ''; if($branchStatus == 'closed') $disabled = 'disabled'; } + if(in_array($plan->status, array('done', 'closed'))) $disabled = 'disabled'; if($config->systemMode == 'new') { @@ -181,8 +186,14 @@ common::printIcon('productplan', 'edit', "planID=$plan->id", $plan, 'list'); if(common::hasPriv('productplan', 'create', $plan)) { - if($plan->parent > '0') echo " "; - if($plan->parent <= '0') echo html::a($this->createLink('productplan', 'create', "product=$productID&branch=$branch&parent={$plan->id}"), "", '', "class='btn' title='{$this->lang->productplan->children}'"); + if($plan->parent > 0 or in_array($plan->status, array('done', 'closed'))) + { + echo " "; + } + else + { + echo html::a($this->createLink('productplan', 'create', "product=$productID&branch=$branch&parent={$plan->id}"), "", '', "class='btn' title='{$this->lang->productplan->children}'"); + } } if(common::hasPriv('productplan', 'delete', $plan)) diff --git a/module/productplan/view/view.html.php b/module/productplan/view/view.html.php index d891801f4b..e966ae107a 100644 --- a/module/productplan/view/view.html.php +++ b/module/productplan/view/view.html.php @@ -59,11 +59,12 @@ common::printLink('productplan', 'finish', "planID=$plan->id", "{$lang->productplan->finishAB}", '', "class='btn btn-link {$class}' target='hiddenwin' title='{$lang->productplan->finish}'", '', false, $plan); $class = $plan->status == 'done' ? '' : 'disabled'; common::printLink('productplan', 'close', "planID=$plan->id", "{$lang->productplan->closeAB}", '', "class='btn btn-link {$class}' target='hiddenwin' title='{$lang->productplan->close}'", '', false, $plan); - $class = $plan->status == 'closed' ? '' : 'disabled'; + $class = in_array($plan->status, array('closed', 'done')) ? '' : 'disabled'; common::printLink('productplan', 'activate', "planID=$plan->id", "{$lang->productplan->activateAB}", '', "class='btn btn-link {$class}' target='hiddenwin' title='{$lang->productplan->activate}'", '', false, $plan); } - if(common::hasPriv('productplan', 'create', $plan) and $plan->parent <= '0') echo html::a($this->createLink('productplan', 'create', "product={$plan->product}&branch={$plan->branch}&parent={$plan->id}"), " " . $this->lang->productplan->children , '', "class='btn btn-link' title='{$this->lang->productplan->children}'"); + $class = in_array($plan->status, array('done', 'closed')) ? 'disabled' : ''; + if(common::hasPriv('productplan', 'create', $plan) and $plan->parent <= 0) echo html::a($this->createLink('productplan', 'create', "product={$plan->product}&branch={$plan->branch}&parent={$plan->id}"), " " . $this->lang->productplan->children , '', "class='btn btn-link {$class}' title='{$this->lang->productplan->children}'"); if(common::hasPriv('productplan', 'edit', $plan)) echo html::a($this->createLink('productplan', 'edit', "planID=$plan->id"), " " . $this->lang->edit, '', "class='btn btn-link' title='{$this->lang->edit}'"); if(common::hasPriv('productplan', 'delete', $plan) and $plan->parent >= 0) echo html::a($this->createLink('productplan', 'delete', "planID=$plan->id"), " " . $this->lang->delete, '', "class='btn btn-link' title='{$this->lang->delete}' target='hiddenwin'"); } diff --git a/module/programplan/control.php b/module/programplan/control.php index 8faba1e7c3..9eb751e67d 100644 --- a/module/programplan/control.php +++ b/module/programplan/control.php @@ -145,6 +145,7 @@ class programplan extends control $this->view->plans = $this->programplan->getStage($planID ? $planID : $projectID, $this->productID, 'parent'); $this->view->planID = $planID; $this->view->type = 'lists'; + $this->view->PMUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst', $project->PM); $this->display(); } diff --git a/module/programplan/js/create.js b/module/programplan/js/create.js index 62a08dbd0e..cd4322931a 100644 --- a/module/programplan/js/create.js +++ b/module/programplan/js/create.js @@ -5,6 +5,8 @@ function addItem(obj) var newItem = $('#names' + i).closest('tr'); newItem.find('.form-date').datepicker(); $("#output" + i).chosen(); + $("#PM_i__chosen").remove(); + $("#PM" + i).chosen(); $("#output_i__chosen").remove(); i ++; } diff --git a/module/programplan/lang/en.php b/module/programplan/lang/en.php index 5a6a4ed3ab..0d93fbccb9 100644 --- a/module/programplan/lang/en.php +++ b/module/programplan/lang/en.php @@ -21,6 +21,7 @@ $lang->programplan->createSubPlan = 'Create Sub Stage'; $lang->programplan->parent = 'Parent Stage'; $lang->programplan->emptyParent = 'N/A'; $lang->programplan->name = 'Stage Name'; +$lang->programplan->PM = 'Stage Manager'; $lang->programplan->subStageName = 'Sub Stage Name'; $lang->programplan->percent = 'Workload Ratio'; $lang->programplan->percentAB = 'Ratio'; diff --git a/module/programplan/lang/zh-cn.php b/module/programplan/lang/zh-cn.php index ef8951ee19..69bebee6ad 100644 --- a/module/programplan/lang/zh-cn.php +++ b/module/programplan/lang/zh-cn.php @@ -21,6 +21,7 @@ $lang->programplan->createSubPlan = '创建二级阶段'; $lang->programplan->parent = '父阶段'; $lang->programplan->emptyParent = '无'; $lang->programplan->name = '阶段名称'; +$lang->programplan->PM = '阶段负责人'; $lang->programplan->subStageName = '子阶段名称'; $lang->programplan->percent = '工作量占比'; $lang->programplan->percentAB = '工作量占比'; diff --git a/module/programplan/model.php b/module/programplan/model.php index 321c3b8309..6cac0425b7 100644 --- a/module/programplan/model.php +++ b/module/programplan/model.php @@ -409,8 +409,6 @@ class programplanModel extends model $parentACL = $parentStage->acl; } - $attributes = array_values($attributes); - $milestone = array_values($milestone); $datas = array(); foreach($names as $key => $name) { @@ -431,6 +429,7 @@ class programplanModel extends model $plan->realEnd = empty($realEnd[$key]) ? '0000-00-00' : $realEnd[$key]; $plan->output = empty($output[$key]) ? '' : implode(',', $output[$key]); $plan->acl = empty($parentID) ? $acl[$key] : $parentACL; + $plan->PM = empty($PM[$key]) ? '' : $PM[$key]; $datas[] = $plan; } diff --git a/module/programplan/view/create.html.php b/module/programplan/view/create.html.php index 98dfed8df9..812f4b8d97 100644 --- a/module/programplan/view/create.html.php +++ b/module/programplan/view/create.html.php @@ -45,6 +45,7 @@ + programplan->PM;?> programplan->percent;?> @@ -69,20 +70,21 @@ - + +
- + %
stage->typeList, $stage->type, "class='form-control'");?> - project->aclList, 'open', "class='form-control' $class");?> + project->aclList, 'open', "class='form-control' $class");?> programplan->milestoneList, 0);?> - - - - + + + + config->qcVersion)):?> @@ -98,22 +100,23 @@ setMilestone ? '' : "disabled='disabled'"?> - id);?> + id);?> - + +
- + %
stage->typeList, $plan->attribute, "class='form-control'");?> - project->aclList, $plan->acl, "class='form-control' $class");?> + project->aclList, $plan->acl, "class='form-control' $class");?> programplan->milestoneList, $plan->milestone, $disabled);?> - - - - + + + + config->qcVersion)):?> output) ? 0 : explode(',', $plan->output);?> @@ -128,20 +131,21 @@ - + +
- + %
stage->typeList, '', "class='form-control'");?> - project->aclList, 'open', "class='form-control' $class");?> + project->aclList, 'open', "class='form-control' $class");?> programplan->milestoneList, 0);?> - - - - + + + + config->qcVersion)):?> @@ -167,21 +171,22 @@ - - + + + - + - - - - + + + + config->qcVersion)):?> diff --git a/module/project/view/view.html.php b/module/project/view/view.html.php index 82cc615f3c..0285d8c651 100644 --- a/module/project/view/view.html.php +++ b/module/project/view/view.html.php @@ -193,7 +193,7 @@ - +