From 109ddd9d0ca7760806aef959f55ce649f2036df0 Mon Sep 17 00:00:00 2001 From: "Vaibhav (OpenERP)" Date: Thu, 3 Nov 2011 16:21:41 +0530 Subject: [PATCH] [IMP] Gantt View.Still need to improve for group by. bzr revid: vda@tinyerp.com-20111103105141-dahiz09fvu0l45bu --- .../lib/dhtmlxGantt/sources/dhtmlxcommon.js | 31 +++ .../lib/dhtmlxGantt/sources/dhtmlxgantt.js | 19 +- addons/web_gantt/static/src/js/gantt.js | 202 ++++++++++++++---- addons/web_gantt/static/src/xml/web_gantt.xml | 2 +- 4 files changed, 197 insertions(+), 57 deletions(-) diff --git a/addons/web_gantt/static/lib/dhtmlxGantt/sources/dhtmlxcommon.js b/addons/web_gantt/static/lib/dhtmlxGantt/sources/dhtmlxcommon.js index bc7de14346d..7f68a0a702c 100644 --- a/addons/web_gantt/static/lib/dhtmlxGantt/sources/dhtmlxcommon.js +++ b/addons/web_gantt/static/lib/dhtmlxGantt/sources/dhtmlxcommon.js @@ -2,6 +2,37 @@ Copyright DHTMLX LTD. http://www.dhtmlx.com To use this component please contact sales@dhtmlx.com to obtain license */ + +dhtmlx=function(obj){ + for (var a in obj) dhtmlx[a]=obj[a]; + return dhtmlx; //simple singleton +}; +dhtmlx.extend_api=function(name,map,ext){ + var t = window[name]; + if (!t) return; //component not defined + window[name]=function(obj){ + if (obj && typeof obj == "object" && !obj.tagName){ + var that = t.apply(this,(map._init?map._init(obj):arguments)); + //global settings + for (var a in dhtmlx) + if (map[a]) this[map[a]](dhtmlx[a]); + //local settings + for (var a in obj){ + if (map[a]) this[map[a]](obj[a]); + else if (a.indexOf("on")==0){ + this.attachEvent(a,obj[a]); + } + } + } else + var that = t.apply(this,arguments); + if (map._patch) map._patch(this); + return that||this; + }; + window[name].prototype=t.prototype; + if (ext) + dhtmlXHeir(window[name].prototype,ext); +}; + dhtmlxAjax={ get:function(url,callback){ var t=new dtmlXMLLoaderObject(true); diff --git a/addons/web_gantt/static/lib/dhtmlxGantt/sources/dhtmlxgantt.js b/addons/web_gantt/static/lib/dhtmlxGantt/sources/dhtmlxgantt.js index 0d838fdd510..52b9b562e96 100644 --- a/addons/web_gantt/static/lib/dhtmlxGantt/sources/dhtmlxgantt.js +++ b/addons/web_gantt/static/lib/dhtmlxGantt/sources/dhtmlxgantt.js @@ -173,9 +173,8 @@ GanttProjectInfo.prototype.getTaskByIdInTree = function(parentTask, id) * @type: public * @topic: 0 */ -function GanttTaskInfo(id, name, est, duration, percentCompleted, predecessorTaskId, color) +function GanttTaskInfo(id, name, est, duration, percentCompleted, predecessorTaskId) { - this.color = color || "white"; this.Id = id; this.Name = name; this.EST = est; @@ -349,7 +348,7 @@ GanttProject.prototype.create = function() * @type: public * @topic: 0 */ -function GanttChart(day_length) +function GanttChart() { this.Error = new GanttError(); this.dhtmlXMLSenderObject = new dhtmlXMLSenderObject(this); @@ -357,7 +356,7 @@ function GanttChart(day_length) //settings this.heightTaskItem = 12; this.dayInPixels = 24; - this.hoursInDay = day_length; + this.hoursInDay = 8; this._showTreePanel = true; this._showTooltip = true; this.isShowDescTask = false; @@ -1162,7 +1161,7 @@ GanttProject.prototype.deleteChildTask = function(task) * @type: public * @topic: 1 */ -GanttProject.prototype.insertTask = function(id, name, EST, Duration, PercentCompleted, predecessorTaskId, color, parentTaskId) +GanttProject.prototype.insertTask = function(id, name, EST, Duration, PercentCompleted, predecessorTaskId, parentTaskId) { var task = null; var _task = null; @@ -1205,7 +1204,7 @@ GanttProject.prototype.insertTask = function(id, name, EST, Duration, PercentCom return false; } - task = new GanttTaskInfo(id, name, EST, Duration, PercentCompleted, predecessorTaskId, color); + task = new GanttTaskInfo(id, name, EST, Duration, PercentCompleted, predecessorTaskId); if (!this.Chart.checkPosParentTask(parentTask, task)) { this.Chart.Error.throwError("DATA_INSERT_ERROR", 19, [parentTaskId,id]); @@ -4870,13 +4869,11 @@ GanttTask.prototype.createTaskItem = function() cellTblTask.height = this.Chart.heightTaskItem + "px"; cellTblTask.width = this.TaskInfo.PercentCompleted + "%"; cellTblTask.style.lineHeight = "1px"; - cellTblTask.style.backgroundColor = self.TaskInfo.color; - var imgPr = document.createElement("img"); imgPr.style.width = (this.TaskInfo.PercentCompleted * this.TaskInfo.Duration * this.Chart.hourInPixelsWork) / 100 + "px"; imgPr.style.height = this.Chart.heightTaskItem + "px"; cellTblTask.appendChild(imgPr); - //imgPr.src = this.Chart.imgs + "progress_filled.png"; + imgPr.src = this.Chart.imgs + "progress_filled.png"; } if (this.TaskInfo.PercentCompleted != 100) @@ -4946,9 +4943,9 @@ GanttTask.prototype.createTaskItem = function() } var taskClick = function() { - self.Chart.callEvent("onTaskDblClick", [self]); + self.Chart.callEvent("onTaskClick", [self]); }; - this.addEvent(divMove, 'dblclick', taskClick, false); + this.addEvent(divMove, 'click', taskClick, false); if (this.Chart.isEditable) { diff --git a/addons/web_gantt/static/src/js/gantt.js b/addons/web_gantt/static/src/js/gantt.js index bdd57b7bf0a..3ba19a67c98 100644 --- a/addons/web_gantt/static/src/js/gantt.js +++ b/addons/web_gantt/static/src/js/gantt.js @@ -2,7 +2,9 @@ * OpenERP web_gantt *---------------------------------------------------------*/ openerp.web_gantt = function (openerp) { +var _t = openerp.web._t; var QWeb = openerp.web.qweb; + QWeb.add_template('/web_gantt/static/src/xml/web_gantt.xml'); openerp.web.views.add('gantt', 'openerp.web_gantt.GanttView'); openerp.web_gantt.GanttView = openerp.web.View.extend({ @@ -13,68 +15,167 @@ init: function(parent, dataset, view_id) { this.dataset = dataset; this.model = dataset.model; this.view_id = view_id; - this.fields_views = {}; - this.widgets = {}; - this.widgets_counter = 0; - this.fields = this.dataset.fields ? this.dataset.fields: {}; - this.ids = this.dataset.ids; - this.name = ""; - this.date_start = ""; - this.date_delay = ""; - this.date_stop = ""; - this.color_field = ""; - this.colors = []; - this.color_values = []; - this.calendar_fields = {}; - this.info_fields = []; - this.domain = this.dataset._domain ? this.dataset._domain: []; + this.domain = this.dataset.domain || []; + this.groupby = []; this.context = this.dataset.context || {}; + this.has_been_loaded = $.Deferred(); +// this.ganttChartControl = new GanttChart(); + this.COLOR_PALETTE = ['#ccccff', '#cc99ff', '#75507b', '#3465a4', '#73d216', '#c17d11', '#edd400', + '#fcaf3e', '#ef2929', '#ff00c9', '#ad7fa8', '#729fcf', '#8ae234', '#e9b96e', '#fce94f', + '#ff8e00', '#ff0000', '#b0008c', '#9000ff', '#0078ff', '#00ff00', '#e6ff00', '#ffff00', + '#905000', '#9b0000', '#840067', '#510090', '#0000c9', '#009b00', '#9abe00', '#ffc900']; }, start: function() { this._super(); - this.rpc("/web/view/load", {"model": this.model, "view_id": this.view_id, "view_type": "gantt"}, this.on_loaded); + return this.rpc("/web/view/load", {"model": this.model, "view_id": this.view_id, "view_type": "gantt"}, this.on_loaded); }, on_loaded: function(data) { - - var self = this; - this.fields_view = data; - - this.name = this.fields_view.arch.attrs.string; - this.view_id = this.fields_view.view_id; - - this.date_start = this.fields_view.arch.attrs.date_start; - this.date_delay = this.fields_view.arch.attrs.date_delay; - this.date_stop = this.fields_view.arch.attrs.date_stop; - - this.color_field = this.fields_view.arch.attrs.color; + this.fields_view = data, + this.name = this.fields_view.arch.attrs.string, + this.view_id = this.fields_view.view_id, + this.fields = this.fields_view.fields; + + this.date_start = this.fields_view.arch.attrs.date_start, + this.date_delay = this.fields_view.arch.attrs.date_delay, + this.date_stop = this.fields_view.arch.attrs.date_stop, this.day_length = this.fields_view.arch.attrs.day_length || 8; + + this.color_field = this.fields_view.arch.attrs.color, this.colors = this.fields_view.arch.attrs.colors; - var arch_children = this.fields_view.arch.children[0]; - this.text = arch_children.children[0] ? arch_children.children[0].attrs.name : arch_children.attrs.name; - this.parent = this.fields_view.arch.children[0].attrs.link; - - this.format = "yyyy-MM-dd"; - this.grp = []; - - self.create_gantt(); - self.get_events(); - - this.$element.html(QWeb.render("GanttView", {"view": this, "fields_view": this.fields_view})); - + + var level = this.fields_view.arch.children[0]; + this.parent = level.attrs.link, + this.text = level.children.length ? level.children[0].attrs.name : level.attrs.name; + + this.$element.html(QWeb.render("GanttView", {'height': $('.oe-application-container').height(), 'width': $('.oe-application-container').width()})); + this.has_been_loaded.resolve(); + }, + + on_project_loaded: function(projects) { + + if(!projects.length) return; + var self = this, + unstarted_project = _.detect(projects, function(res) { + return !res[self.date_start]; + }); + + if(unstarted_project) return self.do_warn(_t("Start date is not defined "), unstarted_project.id); + + $.when(this.project_starting_date(projects), this.project_duration(projects), this.calculate_difference()) + .done(function() { + var Project = new GanttProjectInfo(0, self.name, self.project_start_date), + Task = new GanttTaskInfo(0, self.name, self.project_start_date, self.total_duration, 100, ""); + $.when(self.add_tasks(projects, Task)) + .done(function() { + self.init_gantt_view(Project, Task); + }) + }); + }, + + project_duration: function(projects) { + + var self = this; + this.project_duration = []; + + _.each(projects, function(project, index) { + if (this.date_stop && project[this.date_stop]) { + //ToDO + console.log('TODO for date_stop'); + self.project_duration.push(0); + } else if(self.date_delay && project[self.date_delay]) { + self.project_duration.push(project[self.date_delay]); + } else { + self.project_duration.push(0); + } + }); + + this.max_project_duration = _.max(this.project_duration); + + return $.Deferred().resolve().promise(); + }, + + calculate_difference: function() { + + + var extend_end_date_day = Math.floor(this.max_project_duration / this.day_length), + extend_end_date_hours = this.max_project_duration % this.day_length; + + this.project_end_date = this.project_end_date.add({days: extend_end_date_day, hours: extend_end_date_hours}) + + var DAY = 1000 * 60 * 60 * 24, + difference = Math.abs(this.project_start_date.getTime() - this.project_end_date.getTime()), + day = Math.ceil(difference / DAY), + hour = (difference % DAY)/(1000 * 60 * 60), + DiffHour = (day * this.day_length) + hour; + + this.total_duration = parseFloat(DiffHour.toFixed(2)); + return $.Deferred().resolve().promise(); + }, + + add_tasks: function(tasks, parentTask) { + var self = this; + + _.each(tasks, function(task, index) { + parentTask.addChildTask(new GanttTaskInfo(task.id, task.name, self.format_date(task[self.date_start]), self.project_duration[index], 100, "")); + }); + + return $.Deferred().resolve().promise(); + }, + + project_starting_date : function(projects) { + var self = this; + var min_date = _.min(projects, function(prj) { + return new Date(prj[self.date_start]); + }); + + var max_date = _.max(projects, function(prj) { + return self.format_date(prj[self.date_start]) + }); + this.project_end_date = this.format_date(max_date[self.date_start]); + if (min_date) this.project_start_date = this.format_date(min_date[self.date_start]); + else + this.project_start_date = Date.today(); + + return $.Deferred().resolve().promise(); }, - create_gantt: function() { + init_gantt_view: function(Project, Task) { + Project.addTask(Task); + ganttChartControl = new GanttChart(); - ganttChartControl = new GanttChart(this.day_length); + // Setup paths and behavior ganttChartControl.setImagePath("/web_gantt/static/lib/dhtmlxGantt/codebase/imgs/"); ganttChartControl.setEditable(true); ganttChartControl.showTreePanel(true); ganttChartControl.showContextMenu(false); ganttChartControl.showDescTask(true,'d,s-f'); ganttChartControl.showDescProject(true,'n,d'); - + // Load data structure + ganttChartControl.addProject(Project); + ganttChartControl.create('GanttView'); + // Create Gantt control + + }, + + add_project_info: function(smalldate, project, index) { + + }, + + format_date : function(date) { + var datetime_regex = /^(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d)(?:\.\d+)?$/, + date_regex = /^\d\d\d\d-\d\d-\d\d$/, + time_regex = /^(\d\d:\d\d:\d\d)(?:\.\d+)?$/, + def = $.Deferred(); + if(date_regex.exec(date)) { + this.date_format = "yyyy-MM-dd"; + } else if(time_regex.exec(date)) { + this.date_format = "HH:mm:ss"; + } else { + this.date_format = "yyyy-MM-dd HH:mm:ss"; + } + return openerp.web.auto_str_to_date(date); }, get_events: function() { @@ -502,8 +603,19 @@ init: function(parent, dataset, view_id) { do_search: function (domains, contexts, groupbys) { var self = this; - this.grp = groupbys; - self.reload_gantt(); + this.group_by = groupbys; + $.when(this.has_been_loaded).then(function() { + self.dataset + .read_slice(_.keys(self.fields), { + domain: domains, + context: contexts, + group_by: groupbys + }) + .done(function(projects) { + self.on_project_loaded(projects); + }); + }) + } }); diff --git a/addons/web_gantt/static/src/xml/web_gantt.xml b/addons/web_gantt/static/src/xml/web_gantt.xml index d064d6e9ef2..48a1a1025dd 100644 --- a/addons/web_gantt/static/src/xml/web_gantt.xml +++ b/addons/web_gantt/static/src/xml/web_gantt.xml @@ -1,5 +1,5 @@