odoo/addons/base_calendar/static/src/js/calendar.js

474 lines
18 KiB
JavaScript
Raw Normal View History

/*---------------------------------------------------------
* OpenERP base_calendar
*---------------------------------------------------------*/
openerp.base_calendar = function(openerp) {
QWeb.add_template('/base_calendar/static/src/xml/base_calendar.xml');
openerp.base.views.add('calendar', 'openerp.base_calendar.CalendarView');
openerp.base_calendar.CalendarView = openerp.base.View.extend({
// Dhtmlx scheduler ?
init: function(parent, element_id, dataset, view_id, options) {
this._super(parent, element_id);
this.set_default_options(options);
this.dataset = dataset;
this.model = dataset.model;
this.view_id = view_id;
this.domain = this.dataset.domain || [];
this.context = this.dataset.context || {};
this.has_been_loaded = $.Deferred();
this.creating_event_id = null;
if (this.options.action_views_ids.form) {
this.form_dialog = new openerp.base_calendar.CalendarFormDialog(this, {}, this.options.action_views_ids.form, dataset);
this.form_dialog.start();
}
},
start: function() {
this.rpc("/base_calendar/calendarview/load", {"model": this.model, "view_id": this.view_id, 'toolbar': true}, this.on_loaded);
},
stop: function() {
scheduler.clearAll();
},
on_loaded: function(data) {
this.calendar_fields = {};
this.ids = this.dataset.ids;
this.color_values = [];
this.info_fields = [];
this.fields_view = data.fields_view;
this.name = this.fields_view.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.colors = this.fields_view.arch.attrs.colors;
this.day_length = this.fields_view.arch.attrs.day_length || 8;
this.color_field = this.fields_view.arch.attrs.color;
this.fields = this.fields_view.fields;
//* Calendar Fields *
this.calendar_fields.date_start = {'name': this.date_start, 'kind': this.fields[this.date_start].type};
if (this.date_delay) {
if (this.fields[this.date_delay].type != 'float') {
throw new Error("Calendar view has a 'date_delay' type != float");
}
this.calendar_fields.date_delay = {'name': this.date_delay, 'kind': this.fields[this.date_delay].type};
}
if (this.date_stop) {
this.calendar_fields.date_stop = {'name': this.date_stop, 'kind': this.fields[this.date_stop].type};
}
if (!this.date_delay && !this.date_stop) {
throw new Error("Calendar view has none of the following attributes : 'date_stop', 'date_delay'");
}
for (var fld = 0; fld < this.fields_view.arch.children.length; fld++) {
this.info_fields.push(this.fields_view.arch.children[fld].attrs.name);
}
this.$element.html(QWeb.render("CalendarView", {"fields_view": this.fields_view}));
if (this.options.sidebar && this.options.sidebar_id) {
this.sidebar = new openerp.base.Sidebar(this, this.options.sidebar_id);
this.sidebar.start();
this.sidebar.navigator = new openerp.base_calendar.SidebarNavigator(this.sidebar, this.sidebar.add_section('navigator', "Navigator"), this);
this.sidebar.responsible = new openerp.base_calendar.SidebarResponsible(this.sidebar, this.sidebar.add_section('responsible', "Responsible"), this);
this.sidebar.add_toolbar(data.fields_view.toolbar);
this.set_common_sidebar_sections(this.sidebar);
this.sidebar.do_unfold();
this.sidebar.do_fold.add_last(this.refresh_scheduler);
this.sidebar.do_unfold.add_last(this.refresh_scheduler);
this.sidebar.do_toggle.add_last(this.refresh_scheduler);
}
this.init_scheduler();
this.has_been_loaded.resolve();
if (this.dataset.ids.length) {
this.dataset.read_ids(this.dataset.ids, _.keys(this.fields), this.on_events_loaded);
}
},
init_scheduler: function() {
var self = this;
scheduler.clearAll();
if (this.fields[this.date_start]['type'] == 'time') {
scheduler.config.xml_date = "%H:%M:%S";
} else {
scheduler.config.xml_date = "%Y-%m-%d %H:%i";
}
scheduler.config.api_date = "%Y-%m-%d %H:%i";
scheduler.config.multi_day = true; //Multi day events are not rendered in daily and weekly views
scheduler.config.start_on_monday = true;
scheduler.config.scroll_hour = 8;
scheduler.config.drag_resize = scheduler.config.drag_create = !!this.date_stop;
// Initialize Sceduler
this.mode = this.mode || 'month';
scheduler.init('openerp_scheduler', null, this.mode);
scheduler.detachAllEvents();
scheduler.attachEvent('onEventAdded', this.do_create_event);
scheduler.attachEvent('onEventDeleted', this.do_delete_event);
scheduler.attachEvent('onEventChanged', this.do_save_event);
scheduler.attachEvent('onDblClick', this.do_edit_event);
this.mini_calendar = scheduler.renderCalendar({
container: this.sidebar.navigator.element_id,
navigation: true,
date: scheduler._date,
handler: function(date, calendar) {
scheduler.setCurrentView(date, 'day');
}
});
},
refresh_scheduler: function() {
scheduler.setCurrentView(scheduler._date);
},
refresh_minical: function() {
scheduler.updateCalendar(this.mini_calendar);
},
reload_event: function(id) {
this.dataset.read_ids([id], _.keys(this.fields), this.on_events_loaded);
},
load_scheduler: function() {
var self = this;
this.dataset.read_slice({}, function(events) {
if (self.session.locale_code) {
// TODO: replace $LAB
$LAB.setOptions({AlwaysPreserveOrder: true}).script([
'/base_calendar/static/lib/dhtmlxScheduler/sources/locale_' + self.session.locale_code + '.js',
'/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_' + self.session.locale_code + '.js'
]).wait(function() {
self.on_events_loaded(events);
});
} else {
self.on_events_loaded(events);
}
});
},
on_events_loaded: function(events) {
var self = this;
//To parse Events we have to convert date Format
var res_events = [],
sidebar_items = [],
sidebar_ids = [];
for (var e = 0; e < events.length; e++) {
var evt = events[e];
if (!evt[this.date_start]) {
this.notification.warn("Start date is not defined for event :", evt['id']);
break;
}
if (this.fields[this.date_start]['type'] == 'date') {
evt[this.date_start] = openerp.base.parse_date(evt[this.date_start]).set({hour: 9}).toString('yyyy-MM-dd HH:mm:ss');
}
if (this.date_stop && evt[this.date_stop] && this.fields[this.date_stop]['type'] == 'date') {
evt[this.date_stop] = openerp.base.parse_date(evt[this.date_stop]).set({hour: 17}).toString('yyyy-MM-dd HH:mm:ss');
}
if (this.color_field) {
var user = evt[this.color_field];
if (user) {
if (_.indexOf(sidebar_ids, user[0]) === -1) {
sidebar_items.push({
id: user[0],
name: user[1],
// TODO: use color table
color: '#dddddd'
});
sidebar_ids.push(user[0]);
}
}
}
res_events.push(this.convert_event(evt));
}
scheduler.parse(res_events, 'json');
this.refresh_scheduler();
this.refresh_minical();
this.sidebar.responsible.on_events_loaded(sidebar_items);
},
convert_event: function(event) {
var starts = event[this.date_start],
ends = event[this.date_delay] || 1,
span = 0,
res_text = '',
res_description = [];
var parse_start_date = openerp.base.parse_datetime(starts);
if (event[this.date_stop]) {
var parse_end_date = openerp.base.parse_datetime(event[this.date_stop]);
}
if (this.info_fields) {
var fld = event[this.info_fields[0]];
if (typeof fld == 'object') {
res_text = fld[fld.length -1];
} else {
res_text = fld;
}
var sliced_info_fields = this.info_fields.slice(1);
for (sl_fld in sliced_info_fields) {
var slc_fld = event[sliced_info_fields[sl_fld]];
if (typeof slc_fld == 'object') {
res_description.push(slc_fld[slc_fld.length - 1]);
} else {
if(slc_fld) res_description.push(slc_fld);
}
}
}
if (starts && ends) {
var n = 0,
h = ends;
if (ends == this.day_length) {
span = 1;
} else if (ends > this.day_length) {
n = ends / this.day_length;
h = ends % this.day_length;
n = parseInt(Math.floor(n));
if (h > 0) {
span = n + 1;
} else {
span = n;
}
}
var start = parse_start_date.setTime((parse_start_date.getTime() + (h * 60 * 60) + (n * 24 * 60 * 60)));
ends = parse_start_date;
}
if (starts && this.date_stop) {
ends = parse_end_date;
if (event[this.date_stop] == undefined) {
var start = parse_start_date.setTime((parse_start_date.getTime() + (h * 60 * 60) + (n * 24 * 60 * 60)));
ends = parse_start_date;
}
var tds = parse_start_date.getTime(),
tde = parse_end_date.getTime();
if (tds >= tde) {
tde = tds + 60 * 60;
parse_end_date.setTime(tde);
ends = parse_end_date;
}
n = (tde - tds) / (60 * 60);
if (n >= this.day_length) {
span = Math.ceil(n / 24);
}
}
return {
'start_date': parse_start_date.toString('yyyy-MM-dd HH:mm:ss'),
'end_date': ends.toString('yyyy-MM-dd HH:mm:ss'),
'text': res_text,
'id': event['id'],
'title': res_description.join()
}
},
do_create_event: function(event_id, event_obj) {
var self = this,
data = this.get_event_data(event_obj);
this.dataset.create(data, function(r) {
var id = parseInt(r.result, 10);
self.dataset.ids.push(id);
scheduler.changeEventId(event_id, id);
self.refresh_minical();
}, function(r, event) {
self.creating_event_id = event_id;
self.form_dialog.form.on_record_loaded(data);
self.form_dialog.open();
event.preventDefault();
});
},
do_save_event: function(event_id, event_obj) {
var self = this,
data = this.get_event_data(event_obj);
this.dataset.write(parseInt(event_id, 10), data, function() {
self.refresh_minical();
});
},
do_delete_event: function(event_id, event_obj) {
var self = this;
// dhtmlx sends this event even when it does not exist in openerp.
// Eg: use cancel in dhtmlx new event dialog
if (_.indexOf(this.dataset.ids, parseInt(event_id, 10)) > -1) {
this.dataset.unlink(parseInt(event_id, 10), function() {
self.refresh_minical();
});
}
},
do_edit_event: function(event_id) {
event_id = parseInt(event_id, 10);
var index = _.indexOf(this.dataset.ids, event_id);
if (index > -1) {
this.dataset.index = index;
this.form_dialog.form.do_show();
this.form_dialog.open();
} else {
this.notification.warn("Edit event", "Could not find event #" + event_id);
}
},
get_event_data: function(event_obj) {
var data = {
name: event_obj.text
};
data[this.date_start] = openerp.base.format_datetime(event_obj.start_date);
if (this.date_stop) {
data[this.date_stop] = openerp.base.format_datetime(event_obj.end_date);
}
if (this.date_delay) {
var tds = (event_obj.start_date.getOrdinalNumber() / 1e3 >> 0) - (event_obj.start_date.getOrdinalNumber() < 0);
var tde = (event_obj.end_date.getOrdinalNumber() / 1e3 >> 0) - (event_obj.end_date.getOrdinalNumber() < 0);
var n = (tde - tds) / (60 * 60);
if (n > this.day_length) {
var d = Math.floor(n / 24),
h = n % 24;
n = d * this.day_length + h;
}
data[this.date_delay] = n;
}
return data;
},
do_search: function(domains, contexts, groupbys) {
var self = this;
$.when(this.has_been_loaded).then(function() {
self.rpc('/base/session/eval_domain_and_context', {
domains: domains,
contexts: contexts,
group_by_seq: groupbys
}, function (results) {
// TODO: handle non-empty results.group_by with read_group
self.dataset.context = self.context = results.context;
self.dataset.domain = self.domain = results.domain;
self.dataset.read_slice({
fields: _.keys(self.fields),
offset:0,
limit: self.limit
}, self.on_events_loaded);
});
});
},
do_show: function () {
var self = this;
$.when(this.has_been_loaded).then(function() {
self.$element.show();
if (self.sidebar) {
self.sidebar.$element.show();
}
});
},
do_hide: function () {
this.$element.hide();
if (this.sidebar) {
this.sidebar.$element.hide();
}
},
popup_event: function(event_id) {
var self = this;
if (event_id) event_id = parseInt(event_id, 10);
var action = {
res_model: this.dataset.model,
res_id: event_id,
views: [[false, 'form']],
type: 'ir.actions.act_window',
view_type: 'form',
view_mode: 'form',
flags : {
search_view: false,
sidebar : false,
views_switcher : false,
action_buttons : false,
pager: false
}
}
var element_id = _.uniqueId("act_window_dialog");
var dialog = $('<div>', {
'id': element_id
}).dialog({
modal: true,
width: 'auto',
height: 'auto',
buttons: {
Cancel: function() {
$(this).dialog("destroy");
},
Save: function() {
var view_manager = action_manager.viewmanager;
var _dialog = this;
view_manager.views[view_manager.active_view].controller.do_save(function(r) {
$(_dialog).dialog("destroy");
// self.start();
self.load_scheduler();
})
}
}
});
var action_manager = new openerp.base.ActionManager(this, element_id);
action_manager.start();
action_manager.do_action(action);
//Default_get
if (!event_id) {
this.dataset.index = null;
}
}
});
openerp.base_calendar.CalendarFormDialog = openerp.base.Dialog.extend({
init: function(view, options, view_id, dataset) {
this._super(view, options);
this.dataset = dataset;
this.view_id = view_id;
this.view = view;
},
start: function() {
this._super();
this.form = new openerp.base.FormView(this, this.element_id, this.dataset, this.view_id, {
sidebar: false,
pager: false
});
this.form.start();
this.form.on_created.add_last(this.on_form_dialog_saved);
this.form.on_saved.add_last(this.on_form_dialog_saved);
},
on_form_dialog_saved: function() {
var id = this.dataset.ids[this.dataset.index];
if (this.view.creating_event_id) {
scheduler.changeEventId(this.view.creating_event_id, id);
this.view.creating_event_id = null;
}
this.view.reload_event(id);
this.close();
},
on_close: function() {
if (this.view.creating_event_id) {
scheduler.deleteEvent(this.view.creating_event_id);
this.view.creating_event_id = null;
}
}
});
openerp.base_calendar.SidebarResponsible = openerp.base.Widget.extend({
init: function(parent, element_id, view) {
this._super(parent, element_id);
this.view = view;
},
on_events_loaded: function(users) {
this.$element.html(QWeb.render('CalendarView.sidebar.responsible', { users : users }));
// TODO: bind checkboxes reload sheduler
}
});
openerp.base_calendar.SidebarNavigator = openerp.base.Widget.extend({
init: function(parent, element_id, view) {
this._super(parent, element_id);
this.view = view;
},
on_events_loaded: function(events) {
}
});
};
// DEBUG_RPC:rpc.request:('execute', 'addons-dsh-l10n_us', 1, '*', ('ir.filters', 'get_filters', u'res.partner'))
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax: