diff --git a/module/programplan/control.php b/module/programplan/control.php index f55a7890cf..fbcd25ace9 100644 --- a/module/programplan/control.php +++ b/module/programplan/control.php @@ -237,4 +237,29 @@ class programplan extends control $response['message'] = ''; return $this->send($response); } + + /** + * Save task drag action. + * + * @access public + * @return void + */ + public function ajaxSaveTaskDrag() + { + if(!empty($_POST)) + { + if($_POST['type'] == 'task') + { + $objectID = explode('-', $_POST['id'])[1]; + } + else + { + $objectID = $_POST['id']; + } + + $this->loadModel('task')->saveTaskDrag($objectID, $_POST['type']); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + return $this->send(array('result' => 'success')); + } + } } diff --git a/module/programplan/model.php b/module/programplan/model.php index afea4b24d3..b01efa8209 100755 --- a/module/programplan/model.php +++ b/module/programplan/model.php @@ -191,8 +191,8 @@ class programplanModel extends model $data->status = $this->processStatus('execution', $plan); $data->begin = $start; $data->deadline = $end; - $data->realBegan = helper::isZeroDate($plan->realBegan) ? '' : substr($plan->realBegan, 0, 10); - $data->realEnd = helper::isZeroDate($plan->realEnd) ? '' : substr($plan->realEnd, 0, 10); + $data->realBegan = helper::isZeroDate($plan->realBegan) ? '' : $plan->realBegan; + $data->realEnd = helper::isZeroDate($plan->realEnd) ? '' : $plan->realEnd; $data->parent = $plan->grade == 1 ? 0 :$plan->parent; $data->open = true; $data->start_date = $data->realBegan ? $data->realBegan : $data->begin; @@ -242,8 +242,8 @@ class programplanModel extends model $estStart = helper::isZeroDate($task->estStarted) ? '' : $task->estStarted; $estEnd = helper::isZeroDate($task->deadline) ? '' : $task->deadline; - $realBegan = helper::isZeroDate($task->realStarted) ? '' : substr($task->realStarted, 0, 10); - $realEnd = (in_array($task->status, array('done', 'closed')) and !helper::isZeroDate($task->finishedDate)) ? substr($task->finishedDate, 0, 10) : ''; + $realBegan = helper::isZeroDate($task->realStarted) ? '' : $task->realStarted; + $realEnd = (in_array($task->status, array('done', 'closed')) and !helper::isZeroDate($task->finishedDate)) ? $task->finishedDate : ''; $start = $realBegan ? $realBegan : $estStart; $end = $realEnd ? $realEnd : $estEnd; diff --git a/module/programplan/view/gantt.html.php b/module/programplan/view/gantt.html.php index 03992508db..d094e68cc8 100644 --- a/module/programplan/view/gantt.html.php +++ b/module/programplan/view/gantt.html.php @@ -60,7 +60,6 @@ form {display: block; margin-top: 0em; margin-block-end: 1em;} #mainContent.loading #ganttContainer {padding: 40px;} #mainContent.loading .scrollVer_cell, #mainContent.loading .scrollVer_cell {display: none;} -# .gantt-fullscreen #header, .gantt-fullscreen #mainMenu, .gantt-fullscreen #footer {display: none!important;} @@ -380,6 +379,54 @@ function exitHandler() location.reload(); } } +function validateResources(id) +{ + var task = gantt.getTask(id); + var from = new Date(task.start_date), + to = new Date(task.end_date); + var status = task.status; + var type = task.type; + var statusLang = "task->statusList['wait'];?>"; + flag = true; + + /* Check status. */ + if(status !== statusLang) + { + new $.zui.Messager(status + '的任务不可以拖动', { + type: 'danger', + icon: 'exclamation-sign' + }).show(); + gantt.refreshData(); + return false; + } + + /* Check data. */ + var postData = { + 'id' : task.id, + 'start_date': from.toLocaleDateString('en-CA'), + 'end_date' : to.toLocaleDateString('en-CA'), + 'type' : type + }; + var link = createLink('programplan', 'ajaxSaveTaskDrag'); + /* Sync Close. */ + $.ajaxSettings.async = false; + $.post(link, postData, function(response) + { + response = JSON.parse(response); + if(response.result == 'fail' && response.message) + { + new $.zui.Messager(response.message, { + type: 'danger', + icon: 'exclamation-sign' + }).show(); + flag = false; + } + }) + /* Sync Open. */ + $.ajaxSettings.async = true; + + return flag; +} $(function() { @@ -409,40 +456,45 @@ $(function() ?> gantt.serverList("userList", ); - gantt.config.readonly = true; - gantt.config.smart_rendering = true; - gantt.config.smart_scales = true; - gantt.config.static_background = true; - gantt.config.show_task_cells = false; - gantt.config.row_height = 25; - gantt.config.min_column_width = 40; - gantt.config.details_on_create = false; - gantt.config.scales = [{unit: "year", step: 1, format: "%Y"}, {unit: 'day', step: 1, format: '%m-%d'}]; - gantt.config.scale_height = 22 * gantt.config.scales.length; - gantt.config.duration_unit = "day"; + gantt.config.readonly = false; + gantt.config.order_branch = true; + gantt.config.details_on_dblclick = false; + gantt.config.drag_progress = true; + gantt.config.drag_links = false; + gantt.config.drag_resize = false; + gantt.config.smart_rendering = true; + gantt.config.smart_scales = true; + gantt.config.static_background = true; + gantt.config.show_task_cells = false; + gantt.config.row_height = 25; + gantt.config.min_column_width = 40; + gantt.config.details_on_create = false; + gantt.config.scales = [{unit: "year", step: 1, format: "%Y"}, {unit: 'day', step: 1, format: '%m-%d'}]; + gantt.config.scale_height = 22 * gantt.config.scales.length; + gantt.config.duration_unit = "day"; gantt.config.columns = [ - {name: 'text', width: '*', tree: true, resize: true, width:200}, - {name: 'status', align: 'center', resize: true, width: 80}, - {name: 'begin', align: 'center', resize: true, width: 80}, - {name: 'deadline', align: 'center', resize: true, width: 80}, - {name: 'duration', align: 'center', resize: true, width: 60}, - {name: 'percent', align: 'center', resize: true, width:70, template: function(plan) + {name: 'text', width: '*', tree: true, resize: true, width:200}, + {name: 'status', align: 'center', resize: true, width: 80}, + {name: 'start_date', align: 'center', resize: true, width: 80}, + {name: 'end_date', align: 'center', resize: true, width: 80}, + {name: 'duration', align: 'center', resize: true, width: 60}, + {name: 'percent', align: 'center', resize: true, width:70, template: function(plan) { if(plan.percent) return Math.round(plan.percent) + '%'; } }, {name: 'taskProgress', align: 'center', resize: true, width: 60}, - {name: 'realBegan', align: 'center', resize: true, width: 80}, - {name: 'realEnd', align: 'center', width: 80} + {name: 'realBegan', align: 'center', resize: true, width: 80}, + {name: 'realEnd', align: 'center', width: 80} ]; gantt.locale.labels.column_text = "programplan->name;?>"; gantt.locale.labels.column_status = "statusAB;?>"; gantt.locale.labels.column_percent = "programplan->percentAB;?>"; gantt.locale.labels.column_taskProgress = "programplan->taskProgress;?>"; - gantt.locale.labels.column_begin = "programplan->begin;?>"; - gantt.locale.labels.column_deadline = "programplan->end;?>"; + gantt.locale.labels.column_start_date = "programplan->begin;?>"; + gantt.locale.labels.column_end_date = "programplan->end;?>"; gantt.locale.labels.column_realBegan = "programplan->realBegan;?>"; gantt.locale.labels.column_realEnd = "programplan->realEnd;?>"; gantt.locale.labels.column_duration = "programplan->duration;?>"; @@ -596,5 +648,13 @@ $(function() { setTimeout(function(){$('.gantt_tooltip').remove()}, 100); }); + + gantt.attachEvent("onBeforeTaskChanged", function(id, mode, task) + { + return validateResources(id); + }); + // gantt.attachEvent("onAfterTaskDrag", function (id, mode) + // { + // }); }); diff --git a/module/task/lang/de.php b/module/task/lang/de.php index 1b76afe797..23a341c440 100644 --- a/module/task/lang/de.php +++ b/module/task/lang/de.php @@ -352,3 +352,5 @@ $lang->task->report->finishedTasksPerDay->graph->xAxisName = 'Datum'; $lang->taskestimate = new stdclass(); $lang->taskestimate->consumed = 'Schätzung'; + +$lang->task->overTime = 'The %s scheduled time has been exceeded, please modify the %s time first'; \ No newline at end of file diff --git a/module/task/lang/en.php b/module/task/lang/en.php index df6caac102..0247ef8317 100755 --- a/module/task/lang/en.php +++ b/module/task/lang/en.php @@ -352,3 +352,5 @@ $lang->task->report->finishedTasksPerDay->graph->xAxisName = 'Date'; $lang->taskestimate = new stdclass(); $lang->taskestimate->consumed = 'Estimates'; + +$lang->task->overTime = 'The %s scheduled time has been exceeded, please modify the %s time first'; \ No newline at end of file diff --git a/module/task/lang/fr.php b/module/task/lang/fr.php index 630fe3fc71..43636cf959 100644 --- a/module/task/lang/fr.php +++ b/module/task/lang/fr.php @@ -352,3 +352,5 @@ $lang->task->report->finishedTasksPerDay->graph->xAxisName = 'Date'; $lang->taskestimate = new stdclass(); $lang->taskestimate->consumed = 'Estimés'; + +$lang->task->overTime = 'The %s scheduled time has been exceeded, please modify the %s time first'; \ No newline at end of file diff --git a/module/task/lang/zh-cn.php b/module/task/lang/zh-cn.php index fb3a7b85ca..b1c6647c80 100755 --- a/module/task/lang/zh-cn.php +++ b/module/task/lang/zh-cn.php @@ -352,3 +352,5 @@ $lang->task->report->finishedTasksPerDay->graph->xAxisName = '日期'; $lang->taskestimate = new stdclass(); $lang->taskestimate->consumed = '工时'; + +$lang->task->overTime = '已超出%s计划时间,请先修改%s时间'; \ No newline at end of file diff --git a/module/task/model.php b/module/task/model.php index c601c8f05a..cdba5ab456 100644 --- a/module/task/model.php +++ b/module/task/model.php @@ -3894,4 +3894,87 @@ class taskModel extends model return $menu; } + + public function saveTaskDrag($objectID, $objectType) + { + $post = fixer::input('post')->get(); + if($objectType == 'task') + { + $objectData = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq($objectID)->fetch(); + $parent = $objectData->parent; + $project = $objectData->project; + $execution = $objectData->execution; + $stage = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($execution)->andWhere('project')->eq($project)->fetch(); + + if(empty($parent)) + { + $parentData = $stage; + + $start = $parentData->realBegan ? $parentData->realBegan : $parentData->begin; + $end = $parentData->realEnd ? $parentData->realEnd : $parentData->deadline; + } + else + { + $parentData = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq($parent)->fetch(); + + $estStart = helper::isZeroDate($parentData->estStarted) ? '' : $parentData->estStarted; + $estEnd = helper::isZeroDate($parentData->deadline) ? '' : $parentData->deadline; + $realBegan = helper::isZeroDate($parentData->realStarted) ? '' : $parentData->realStarted; + $realEnd = helper::isZeroDate($parentData->finishedDate) ? '' : $parentData->finishedDate; + $start = $realBegan ? $realBegan : $estStart; + $end = $realEnd ? $realEnd : $estEnd; + if(empty($start) and $stage) $start = $stage->begin; + if(empty($end) and $stage) $end = $stage->end; + if($start > $end) $end = $start; + } + + if(helper::diffDate($start, $post->start_date) > 0) + { + $arg = !empty($parent) ? $this->lang->task->parent : $this->lang->project->stage; + return dao::$errors = sprintf($this->lang->task->overTime, $arg, $arg); + } + + } + elseif($objectType == 'plan') + { + $objectData = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($objectID)->fetch(); + $parent = $objectData->parent; + $project = $objectData->project; + + if(empty($parent)) + { + $parentData = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($project)->fetch(); + } + else + { + $parentData = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($parent)->fetch(); + } + $start = helper::isZeroDate($parentData->begin) ? '' : $parentData->begin; + $end = helper::isZeroDate($parentData->end) ? '' : $parentData->end; + $realBegan = helper::isZeroDate($parentData->realBegan) ? '' : $parentData->realBegan; + $realEnd = helper::isZeroDate($parentData->realEnd) ? '' : $parentData->realEnd; + + $startDate = $realBegan ? $realBegan : $start; + $endDate = $realEnd ? $realEnd : $end; + + if(helper::diffDate($startDate, $post->start_date) > 0) + { + $arg = !empty($parent) ? $this->lang->programplan->parent : $this->lang->project->common; + return dao::$errors = sprintf($this->lang->task->overTime, $arg, $arg); + } + } + else + { + return false; + } + + $this->dao->update(TABLE_TASK) + ->set('estStarted')->eq($post->start_date) + ->set('deadline')->eq($post->end_date) + ->set('lastEditedBy')->eq($this->app->user->account) + ->where('id')->eq($objectID) + ->exec(); + + return true; + } }