1 /*---------------------------------------------------------
3 *---------------------------------------------------------*/
4 openerp.base_gantt = function (openerp) {
5 QWeb.add_template('/base_gantt/static/src/xml/base_gantt.xml');
6 openerp.base.views.add('gantt', 'openerp.base_gantt.GanttView');
7 openerp.base_gantt.GanttView = openerp.base.View.extend({
9 init: function(parent, element_id, dataset, view_id) {
10 this._super(parent, element_id);
11 this.view_manager = parent || new openerp.base.NullViewManager();
12 this.dataset = dataset;
13 this.model = dataset.model;
14 this.view_id = view_id;
15 this.fields_views = {};
17 this.widgets_counter = 0;
18 this.fields = this.dataset.fields ? this.dataset.fields: {};
19 this.ids = this.dataset.ids;
24 this.color_field = "";
26 this.color_values = [];
27 this.calendar_fields = {};
28 this.info_fields = [];
29 this.domain = this.dataset._domain ? this.dataset._domain: [];
30 this.context = this.dataset.context || {};
34 this.rpc("/base_gantt/ganttview/load",
35 {"model": this.model, "view_id": this.view_id}, this.on_loaded);
38 on_loaded: function(data) {
41 this.fields_view = data.fields_view;
43 this.name = this.fields_view.arch.attrs.string;
44 this.view_id = this.fields_view.view_id;
46 this.date_start = this.fields_view.arch.attrs.date_start;
47 this.date_delay = this.fields_view.arch.attrs.date_delay;
48 this.date_stop = this.fields_view.arch.attrs.date_stop;
50 this.color_field = this.fields_view.arch.attrs.color;
51 this.day_length = this.fields_view.arch.attrs.day_length || 8;
52 this.colors = this.fields_view.arch.attrs.colors;
53 var arch_children = this.fields_view.arch.children[0];
54 this.text = arch_children.children[0] ? arch_children.children[0].attrs.name : arch_children.attrs.name;
55 this.parent = this.fields_view.arch.children[0].attrs.link;
57 this.format = "yyyy-MM-dd";
63 this.$element.html(QWeb.render("GanttView", {"view": this, "fields_view": this.fields_view}));
67 create_gantt: function() {
69 ganttChartControl = new GanttChart(this.day_length);
70 ganttChartControl.setImagePath("/base_gantt/static/lib/dhtmlxGantt/codebase/imgs/");
71 ganttChartControl.setEditable(true);
72 ganttChartControl.showTreePanel(true);
73 ganttChartControl.showContextMenu(true);
74 ganttChartControl.showDescTask(true,'d,s-f');
75 ganttChartControl.showDescProject(true,'n,d');
79 get_events: function() {
82 this.dataset.read_slice({}, function(result) {
83 self.load_event(result);
88 load_event: function(events) {
94 COLOR_PALETTE = ['#ccccff', '#cc99ff', '#75507b', '#3465a4', '#73d216', '#c17d11', '#edd400',
95 '#fcaf3e', '#ef2929', '#ff00c9', '#ad7fa8', '#729fcf', '#8ae234', '#e9b96e', '#fce94f',
96 '#ff8e00', '#ff0000', '#b0008c', '#9000ff', '#0078ff', '#00ff00', '#e6ff00', '#ffff00',
97 '#905000', '#9b0000', '#840067', '#510090', '#0000c9', '#009b00', '#9abe00', '#ffc900']
99 if (result.length != 0){
101 for (var i in result){
103 if (res[this.date_start] != false){
105 var start_date = this.convert_str_date(res[this.date_start]);
106 res[this.date_start] = start_date;
107 show_event.push(res);
108 if (smalldate == ""){
109 smalldate = start_date;
112 if (start_date < smalldate){
113 smalldate = start_date;
118 if (smalldate == ""){
119 smalldate = Date.today();
121 project = new GanttProjectInfo("_1", "", smalldate);
122 ganttChartControl.addProject(project);
130 var child_event = {};
132 var final_events = [];
133 for (var i in show_event) {
135 var res = show_event[i];
138 var text = res[this.text];
139 var start_date = res[this.date_start];
141 var color = res[this.color_field][0] || res[this.color_field];
142 if (color_box[color] == undefined){
143 color_box[color] = COLOR_PALETTE[k];
147 if (this.date_stop != undefined){
148 if (res[this.date_stop] != false){
149 var stop_date = this.convert_str_date(res[this.date_stop]);
150 var duration= self.hours_between(start_date, stop_date);
157 var duration = res[this.date_delay];
159 if (duration == false)
162 if (self.grp.length){
163 for (var j in self.grp){
164 var grp_key = res[self.grp[j]['group_by']];
165 if (typeof(grp_key) == "object"){
166 grp_key = res[self.grp[j]['group_by']][1];
169 grp_key = res[self.grp[j]['group_by']];
172 if (grp_key == false){
173 grp_key = "Undefined";
177 if (parents[grp_key] == undefined){
178 var mod_id = i+ "_" +j;
179 parents[grp_key] = mod_id;
180 child_event[mod_id] = {};
181 all_events[mod_id] = {'parent': "", 'evt':[mod_id , grp_key, start_date, start_date, 100, "", "white"]};
184 mod_id = parents[grp_key];
188 if (child_event[mod_id][grp_key] == undefined){
189 var ch_mod_id = i+ "_" +j;
190 child_event[mod_id][grp_key] = ch_mod_id;
191 child_event[ch_mod_id] = {};
193 all_events[ch_mod_id] = {'parent': mod_id, 'evt':[ch_mod_id , grp_key, start_date, start_date, 100, "","white"]};
197 mod_id = child_event[mod_id][grp_key];
202 all_events[id] = {'parent': temp_id, 'evt':[id , text, start_date, duration, 100, "", color_box[color]]};
203 final_events.push(id);
207 var mod_id = "_" + i;
208 all_events[mod_id] = {'parent': "", 'evt': [mod_id, this.name, start_date, start_date, 100, "", "white"]};
210 all_events[id] = {'parent': mod_id, 'evt':[id , text, start_date, duration, 100, "", color_box[color]]};
211 final_events.push(id);
215 for (var i in final_events){
216 var evt_id = final_events[i];
217 var evt_date = all_events[evt_id]['evt'][2];
218 while (all_events[evt_id]['parent'] != "") {
219 var parent_id =all_events[evt_id]['parent'];
220 if (all_events[parent_id]['evt'][2] > evt_date){
221 all_events[parent_id]['evt'][2] = evt_date;
228 var evt_duration = "";
229 var evt_end_date = "";
231 for (var i in final_events){
232 evt_id = final_events[i];
233 evt_date = all_events[evt_id]['evt'][2];
234 evt_duration = all_events[evt_id]['evt'][3];
236 evt_str_date = this.convert_date_str(evt_date);
237 evt_end_date = this.end_date(evt_str_date, evt_duration);
239 while (all_events[evt_id]['parent'] != "") {
240 var parent_id =all_events[evt_id]['parent'];
241 if (all_events[parent_id]['evt'][3] < evt_end_date){
242 all_events[parent_id]['evt'][3] = evt_end_date;
248 for (var j in self.grp) {
249 self.render_events(all_events, j);
252 if (!self.grp.length) {
253 self.render_events(all_events, 0);
256 for (var i in final_events){
257 evt_id = final_events[i];
258 res = all_events[evt_id];
259 task=new GanttTaskInfo(res['evt'][0], res['evt'][1], res['evt'][2], res['evt'][3], res['evt'][4], "",res['evt'][6]);
260 prt = project.getTaskById(res['parent']);
261 prt.addChildTask(task);
266 var name_min_wdt = 150;
267 var gantt_hgt = jQuery(window).height() - oth_hgt;
268 var search_wdt = jQuery("#oe_app_search").width();
270 if (gantt_hgt > min_hgt){
271 jQuery('#GanttDiv').height(gantt_hgt).width(search_wdt);
273 jQuery('#GanttDiv').height(min_hgt).width(search_wdt);
276 ganttChartControl.create("GanttDiv");
277 ganttChartControl.attachEvent("onTaskStartDrag", function(task) {self.on_drag_start(task);});
278 ganttChartControl.attachEvent("onTaskEndResize", function(task) {self.on_resize_drag_end(task, "resize");});
279 ganttChartControl.attachEvent("onTaskEndDrag", function(task) {self.on_resize_drag_end(task, "drag");});
280 ganttChartControl.attachEvent("onTaskDblClick", function(task) {self.open_popup(task);});
282 var taskdiv = jQuery("div.taskPanel").parent();
283 taskdiv.addClass('ganttTaskPanel');
284 taskdiv.prev().addClass('ganttDayPanel');
285 var $gantt_panel = jQuery(".ganttTaskPanel , .ganttDayPanel");
287 var ganttrow = jQuery('.taskPanel').closest('tr');
288 var gtd = ganttrow.children(':first-child');
289 gtd.children().addClass('task-name');
291 jQuery(".toggle-sidebar").click(function(e) {
295 jQuery(window).bind('resize',function(){
296 window.clearTimeout(ganttChartControl._resize_timer);
297 ganttChartControl._resize_timer = window.setTimeout(function(){
302 jQuery("div #_1, div #_1 + div").hide();
305 set_width: function() {
307 $gantt_panel.width(1);
308 jQuery(".ganttTaskPanel").parent().width(1);
310 var search_wdt = jQuery("#oe_app_search").width();
311 var day_wdt = jQuery(".ganttDayPanel").children().children().width();
312 jQuery('#GanttDiv').css('width','100%');
314 if (search_wdt - day_wdt <= name_min_wdt){
315 jQuery(".ganttTaskPanel").parent().width(search_wdt - name_min_wdt);
316 jQuery(".ganttTaskPanel").width(search_wdt - name_min_wdt);
317 jQuery(".ganttDayPanel").width(search_wdt - name_min_wdt - 14);
318 jQuery('.task-name').width(name_min_wdt);
319 jQuery('.task-name').children().width(name_min_wdt);
321 jQuery(".ganttTaskPanel").parent().width(day_wdt);
322 jQuery(".ganttTaskPanel").width(day_wdt);
323 jQuery(".taskPanel").width(day_wdt - 16);
324 jQuery(".ganttDayPanel").width(day_wdt -16);
325 jQuery('.task-name').width(search_wdt - day_wdt);
326 jQuery('.task-name').children().width(search_wdt - day_wdt);
331 end_date: function(dat, duration) {
335 var dat = this.convert_str_date(dat);
337 var day = Math.floor(duration/self.day_length);
338 var hrs = duration % self.day_length;
346 hours_between: function(date1, date2, parent_task) {
348 var ONE_DAY = 1000 * 60 * 60 * 24;
349 var date1_ms = date1.getTime();
350 var date2_ms = date2.getTime();
351 var difference_ms = Math.abs(date1_ms - date2_ms);
353 var d = parent_task? Math.ceil(difference_ms / ONE_DAY) : Math.floor(difference_ms / ONE_DAY);
354 var h = (difference_ms % ONE_DAY)/(1000 * 60 * 60);
355 var num = (d * this.day_length) + h;
356 return parseFloat(num.toFixed(2));
360 render_events : function(all_events, j) {
363 for (var i in all_events){
364 var res = all_events[i];
365 if ((typeof(res['evt'][3])) == "object"){
366 res['evt'][3] = self.hours_between(res['evt'][2],res['evt'][3], true);
369 k = res['evt'][0].toString().indexOf('_');
372 if (res['evt'][0].substring(k) == "_"+j){
374 task = new GanttTaskInfo(res['evt'][0], res['evt'][1], res['evt'][2], res['evt'][3], res['evt'][4], "",res['evt'][6]);
375 project.addTask(task);
377 task = new GanttTaskInfo(res['evt'][0], res['evt'][1], res['evt'][2], res['evt'][3], res['evt'][4], "",res['evt'][6]);
378 prt = project.getTaskById(res['parent']);
379 prt.addChildTask(task);
386 open_popup : function(task) {
387 var event_id = task.getId();
388 if(event_id.toString().search("_") != -1)
390 if(event_id) event_id = parseInt(event_id, 10);
393 "res_model": this.dataset.model,
395 "views":[[false,"form"]],
396 "type":"ir.actions.act_window",
404 views_switcher : false,
407 var element_id = _.uniqueId("act_window_dialog");
408 var dialog = jQuery('<div>', {
416 $(this).dialog("destroy");
419 var view_manager = action_manager.viewmanager;
421 view_manager.views[view_manager.active_view].controller.do_save(function(r) {
422 $(_dialog).dialog("destroy");
428 var action_manager = new openerp.base.ActionManager(this, element_id);
429 action_manager.start();
430 action_manager.do_action(action);
433 if(!event_id) action_manager.viewmanager.dataset.index = null;
436 on_drag_start : function(task){
437 var st_date = task.getEST();
438 if(st_date.getHours()){
439 self.hh = st_date.getHours();
440 self.mm = st_date.getMinutes();
444 on_resize_drag_end : function(task, evt){
446 var event_id = task.getId();
449 if(event_id.toString().search("_") != -1)
452 full_date = task.getEST().set({hour: self.hh, minute : self.mm, second:0});
453 data[this.date_start] = this.convert_date_str(full_date);
455 if (this.date_stop != undefined){
456 tm = (task.getDuration() % this.day_length);
457 stp = task.getFinishDate().add(tm).hour();
458 data[this.date_stop] = this.convert_date_str(stp);
460 data[this.date_delay] = task.getDuration();
462 this.dataset.write(event_id, data, function(result) {});
466 do_show: function () {
467 this.$element.show();
470 do_hide: function () {
471 this.$element.hide();
474 convert_str_date: function (str){
475 if (str.length == 19){
476 this.format = "yyyy-MM-dd HH:mm:ss";
477 return openerp.base.parse_datetime(str);
478 } else if (str.length == 10){
479 this.format = "yyyy-MM-dd";
480 return openerp.base.parse_date(str);
481 } else if (str.length == 8){
482 this.format = "HH:mm:ss";
483 return openerp.base.parse_time(str);
485 throw "Unrecognized date/time format";
488 convert_date_str: function(full_date) {
489 if (this.format == "yyyy-MM-dd HH:mm:ss"){
490 return openerp.base.format_datetime(full_date);
491 } else if (this.format == "yyyy-MM-dd"){
492 return openerp.base.format_date(full_date);
493 } else if (this.format == "HH:mm:ss"){
494 return openerp.base.format_time(full_date);
496 throw "Unrecognized date/time format";
499 reload_gantt: function() {
501 this.dataset.read_slice({}, function(response) {
502 ganttChartControl.clearAll();
503 jQuery("#GanttDiv").children().remove();
504 self.load_event(response);
508 do_search: function (domains, contexts, groupbys) {
511 return this.rpc('/base/session/eval_domain_and_context', {
514 group_by_seq: groupbys
515 }, function (results) {
516 self.dataset.context = results.context;
517 self.dataset.domain = results.domain;
524 // here you may tweak globals object, if any, and play with on_* or do_* callbacks on them
527 // vim:et fdc=0 fdl=0: