mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[WIP] Multi-Calendar
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -10,7 +10,6 @@ var Core = require('web.core'),
|
|||||||
Session = require('web.session'),
|
Session = require('web.session'),
|
||||||
AbstractRenderer = require('web.AbstractRenderer'),
|
AbstractRenderer = require('web.AbstractRenderer'),
|
||||||
HotelConstants = require('hotel_calendar.Constants'),
|
HotelConstants = require('hotel_calendar.Constants'),
|
||||||
MultiCalendar = require('hotel_calendar.MultiCalendar'),
|
|
||||||
//Formats = require('web.formats'),
|
//Formats = require('web.formats'),
|
||||||
|
|
||||||
_t = Core._t,
|
_t = Core._t,
|
||||||
@@ -27,23 +26,17 @@ var HotelCalendarView = AbstractRenderer.extend({
|
|||||||
|
|
||||||
// Custom Options
|
// Custom Options
|
||||||
_view_options: {},
|
_view_options: {},
|
||||||
_hcalendar: null,
|
|
||||||
_reserv_tooltips: {},
|
_reserv_tooltips: {},
|
||||||
_days_tooltips: [],
|
_days_tooltips: [],
|
||||||
_last_dates: [false, false],
|
_last_dates: [false, false],
|
||||||
_multi_calendar: null,
|
|
||||||
|
|
||||||
|
|
||||||
/** VIEW METHODS **/
|
/** VIEW METHODS **/
|
||||||
init: function(parent, state, params) {
|
init: function(parent, state, params) {
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
|
|
||||||
this._multi_calendar = new MultiCalendar(this);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
start: function () {
|
start: function () {
|
||||||
this._multi_calendar.setElement(this.$el.find('#hcal_widget'));
|
|
||||||
this._multi_calendar.start();
|
|
||||||
this.init_calendar_view();
|
this.init_calendar_view();
|
||||||
return this._super();
|
return this._super();
|
||||||
},
|
},
|
||||||
@@ -53,7 +46,7 @@ var HotelCalendarView = AbstractRenderer.extend({
|
|||||||
|
|
||||||
if (!this._is_visible) {
|
if (!this._is_visible) {
|
||||||
// FIXME: Workaround for restore "lost" reservations (Drawn when the view is hidden)
|
// FIXME: Workaround for restore "lost" reservations (Drawn when the view is hidden)
|
||||||
this._multi_calendar.recalculate_reservation_positions();
|
this.trigger_up('onViewAttached');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -70,11 +63,6 @@ var HotelCalendarView = AbstractRenderer.extend({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
load_reservations: function(reservs) {
|
|
||||||
this._hcalendar.setReservations(reservs);
|
|
||||||
this._assign_extra_info();
|
|
||||||
},
|
|
||||||
|
|
||||||
get_view_filter_dates: function () {
|
get_view_filter_dates: function () {
|
||||||
var $dateTimePickerBegin = this.$el.find('#pms-search #date_begin');
|
var $dateTimePickerBegin = this.$el.find('#pms-search #date_begin');
|
||||||
var $dateTimePickerEnd = this.$el.find('#pms-search #date_end');
|
var $dateTimePickerEnd = this.$el.find('#pms-search #date_end');
|
||||||
@@ -98,327 +86,6 @@ var HotelCalendarView = AbstractRenderer.extend({
|
|||||||
this._last_dates = this.get_view_filter_dates();
|
this._last_dates = this.get_view_filter_dates();
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy_calendar: function() {
|
|
||||||
if (this._hcalendar) {
|
|
||||||
this._hcalendar.$base.empty();
|
|
||||||
delete this._hcalendar;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_assign_hcalendar_events: function() {
|
|
||||||
var self = this;
|
|
||||||
this._hcalendar.addEventListener('hcalOnSavePricelist', function(ev){
|
|
||||||
var pricelist = self._hcalendar.getPricelist();
|
|
||||||
var oparams = [self._hcalendar._pricelist_id, false, pricelist, {}, {}];
|
|
||||||
self.trigger_up('onSaveChanges', oparams);
|
|
||||||
});
|
|
||||||
this._hcalendar.addEventListener('hcalOnMouseEnterReservation', function(ev){
|
|
||||||
if (ev.detail.reservationObj) {
|
|
||||||
var tp = self._reserv_tooltips[ev.detail.reservationObj.id];
|
|
||||||
var qdict = self._generate_reservation_tooltip_dict(tp);
|
|
||||||
$(ev.detail.reservationDiv).tooltip('destroy').tooltip({
|
|
||||||
animation: false,
|
|
||||||
html: true,
|
|
||||||
placement: 'bottom',
|
|
||||||
title: QWeb.render('HotelCalendar.TooltipReservation', qdict)
|
|
||||||
}).tooltip('show');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this._hcalendar.addEventListener('hcalOnClickReservation', function(ev){
|
|
||||||
//var res_id = ev.detail.reservationObj.getUserData('folio_id');
|
|
||||||
$(ev.detail.reservationDiv).tooltip('hide');
|
|
||||||
self.do_action({
|
|
||||||
type: 'ir.actions.act_window',
|
|
||||||
res_model: 'hotel.reservation',
|
|
||||||
res_id: ev.detail.reservationObj.id,
|
|
||||||
views: [[false, 'form']]
|
|
||||||
});
|
|
||||||
// self._model.call('get_formview_id', [res_id, Session.user_context]).then(function(view_id){
|
|
||||||
// var pop = new ViewDialogs.FormViewDialog(self, {
|
|
||||||
// res_model: 'hotel.folio',
|
|
||||||
// res_id: res_id,
|
|
||||||
// title: _t("Open: ") + ev.detail.reservationObj.title,
|
|
||||||
// view_id: view_id
|
|
||||||
// //readonly: false
|
|
||||||
// }).open();
|
|
||||||
// pop.on('write_completed', self, function(){
|
|
||||||
// self.trigger('changed_value');
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
});
|
|
||||||
this._hcalendar.addEventListener('hcalOnSwapReservations', function(ev){
|
|
||||||
var qdict = {};
|
|
||||||
var dialog = new Dialog(self, {
|
|
||||||
title: _t("Confirm Reservation Swap"),
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
text: _t("Yes, swap it"),
|
|
||||||
classes: 'btn-primary',
|
|
||||||
close: true,
|
|
||||||
click: function () {
|
|
||||||
if (self._hcalendar.swapReservations(ev.detail.inReservs, ev.detail.outReservs)) {
|
|
||||||
var fromIds = _.pluck(ev.detail.inReservs, 'id');
|
|
||||||
var toIds = _.pluck(ev.detail.outReservs, 'id');
|
|
||||||
var refFromReservDiv = ev.detail.inReservs[0]._html;
|
|
||||||
var refToReservDiv = ev.detail.outReservs[0]._html;
|
|
||||||
|
|
||||||
// Animate Movement
|
|
||||||
for (var nreserv of ev.detail.inReservs) {
|
|
||||||
$(nreserv._html).animate({'top': refToReservDiv.style.top});
|
|
||||||
}
|
|
||||||
for (var nreserv of ev.detail.outReservs) {
|
|
||||||
$(nreserv._html).animate({'top': refFromReservDiv.style.top});
|
|
||||||
}
|
|
||||||
self.trigger_up('onSwapReservations', {
|
|
||||||
'fromIds': fromIds,
|
|
||||||
'toIds': toIds,
|
|
||||||
'detail': ev.detail,
|
|
||||||
'refFromReservDiv': refFromReservDiv,
|
|
||||||
'refToReservDiv': refToReservDiv
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
var qdict = {};
|
|
||||||
var dialog = new Dialog(self, {
|
|
||||||
title: _t("Invalid Reservation Swap"),
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
text: _t("Oops, Ok!"),
|
|
||||||
classes: 'btn-primary',
|
|
||||||
close: true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
$content: QWeb.render('HotelCalendar.InvalidSwapOperation', qdict)
|
|
||||||
}).open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: _t("No"),
|
|
||||||
close: true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
$content: QWeb.render('HotelCalendar.ConfirmSwapOperation', qdict)
|
|
||||||
}).open();
|
|
||||||
});
|
|
||||||
this._hcalendar.addEventListener('hcalOnCancelSwapReservations', function(ev){
|
|
||||||
$("#btn_swap span.ntext").html(_t("START SWAP"));
|
|
||||||
$("#btn_swap").css({
|
|
||||||
'backgroundColor': '',
|
|
||||||
'fontWeight': 'normal'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
this._hcalendar.addEventListener('hcalOnChangeReservation', function(ev){
|
|
||||||
var newReservation = ev.detail.newReserv;
|
|
||||||
var oldReservation = ev.detail.oldReserv;
|
|
||||||
var oldPrice = ev.detail.oldPrice;
|
|
||||||
var newPrice = ev.detail.newPrice;
|
|
||||||
var folio_id = newReservation.getUserData('folio_id');
|
|
||||||
|
|
||||||
var linkedReservs = _.find(self._hcalendar._reservations, function(item){
|
|
||||||
return item.id !== newReservation.id && !item.unusedZone && item.getUserData('folio_id') === folio_id;
|
|
||||||
});
|
|
||||||
|
|
||||||
var hasChanged = false;
|
|
||||||
|
|
||||||
var qdict = {
|
|
||||||
ncheckin: newReservation.startDate.clone().local().format(HotelConstants.L10N_DATETIME_MOMENT_FORMAT),
|
|
||||||
ncheckout: newReservation.endDate.clone().local().format(HotelConstants.L10N_DATETIME_MOMENT_FORMAT),
|
|
||||||
nroom: newReservation.room.number,
|
|
||||||
nprice: newPrice,
|
|
||||||
ocheckin: oldReservation.startDate.clone().local().format(HotelConstants.L10N_DATETIME_MOMENT_FORMAT),
|
|
||||||
ocheckout: oldReservation.endDate.clone().local().format(HotelConstants.L10N_DATETIME_MOMENT_FORMAT),
|
|
||||||
oroom: oldReservation.room.number,
|
|
||||||
oprice: oldPrice,
|
|
||||||
hasReservsLinked: (linkedReservs && linkedReservs.length !== 0)?true:false
|
|
||||||
};
|
|
||||||
var dialog = new Dialog(self, {
|
|
||||||
title: _t("Confirm Reservation Changes"),
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
text: _t("Yes, change it"),
|
|
||||||
classes: 'btn-primary',
|
|
||||||
close: true,
|
|
||||||
disabled: !newReservation.id,
|
|
||||||
click: function () {
|
|
||||||
var roomId = newReservation.room.id;
|
|
||||||
if (newReservation.room.overbooking) {
|
|
||||||
roomId = +newReservation.room.id.substr(newReservation.room.id.indexOf('@')+1);
|
|
||||||
}
|
|
||||||
var write_values = {
|
|
||||||
'checkin': newReservation.startDate.format(HotelConstants.ODOO_DATETIME_MOMENT_FORMAT),
|
|
||||||
'checkout': newReservation.endDate.format(HotelConstants.ODOO_DATETIME_MOMENT_FORMAT),
|
|
||||||
'room_id': roomId,
|
|
||||||
'overbooking': newReservation.room.overbooking
|
|
||||||
};
|
|
||||||
self.trigger_up('onUpdateReservations', {
|
|
||||||
'ids': [newReservation.id],
|
|
||||||
'values': write_values,
|
|
||||||
'oldReservation': oldReservation,
|
|
||||||
'newReservation': newReservation
|
|
||||||
});
|
|
||||||
// Workarround for dispatch room lines regeneration
|
|
||||||
// new Model('hotel.reservation').call('on_change_checkin_checkout_product_id', [[newReservation.id], false]);
|
|
||||||
hasChanged = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: _t("No"),
|
|
||||||
close: true,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
$content: QWeb.render('HotelCalendar.ConfirmReservationChanges', qdict)
|
|
||||||
}).open();
|
|
||||||
dialog.opened(function(e){
|
|
||||||
if (!hasChanged) {
|
|
||||||
self._hcalendar.replaceReservation(newReservation, oldReservation);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
this._hcalendar.addEventListener('hcalOnUpdateSelection', function(ev){
|
|
||||||
for (var td of ev.detail.old_cells) {
|
|
||||||
$(td).tooltip('destroy');
|
|
||||||
}
|
|
||||||
if (ev.detail.cells.length > 1) {
|
|
||||||
var last_cell = ev.detail.cells[ev.detail.cells.length-1];
|
|
||||||
var date_cell_start = HotelCalendar.toMoment(self._hcalendar.etable.querySelector(`#${ev.detail.cells[0].dataset.hcalParentCell}`).dataset.hcalDate);
|
|
||||||
var date_cell_end = HotelCalendar.toMoment(self._hcalendar.etable.querySelector(`#${last_cell.dataset.hcalParentCell}`).dataset.hcalDate);
|
|
||||||
var parentRow = document.querySelector(`#${ev.detail.cells[0].dataset.hcalParentRow}`);
|
|
||||||
var room = self._hcalendar.getRoom(parentRow.dataset.hcalRoomObjId);
|
|
||||||
if (room.overbooking) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var nights = date_cell_end.diff(date_cell_start, 'days');
|
|
||||||
var qdict = {
|
|
||||||
'total_price': Number(ev.detail.totalPrice).toLocaleString(),
|
|
||||||
'nights': nights
|
|
||||||
};
|
|
||||||
$(last_cell).tooltip({
|
|
||||||
animation: false,
|
|
||||||
html: true,
|
|
||||||
placement: 'top',
|
|
||||||
title: QWeb.render('HotelCalendar.TooltipSelection', qdict)
|
|
||||||
}).tooltip('show');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this._hcalendar.addEventListener('hcalOnChangeSelection', function(ev){
|
|
||||||
var parentRow = document.querySelector(`#${ev.detail.cellStart.dataset.hcalParentRow}`);
|
|
||||||
var parentCellStart = document.querySelector(`#${ev.detail.cellStart.dataset.hcalParentCell}`);
|
|
||||||
var parentCellEnd = document.querySelector(`#${ev.detail.cellEnd.dataset.hcalParentCell}`);
|
|
||||||
var startDate = HotelCalendar.toMoment(parentCellStart.dataset.hcalDate);
|
|
||||||
var endDate = HotelCalendar.toMoment(parentCellEnd.dataset.hcalDate);
|
|
||||||
var room = self._hcalendar.getRoom(parentRow.dataset.hcalRoomObjId);
|
|
||||||
if (room.overbooking) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var numBeds = (room.shared || self._hcalendar.getOptions('divideRoomsByCapacity'))?(ev.detail.cellEnd.dataset.hcalBedNum - ev.detail.cellStart.dataset.hcalBedNum)+1:room.capacity;
|
|
||||||
if (numBeds <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normalize Dates
|
|
||||||
if (startDate.isAfter(endDate)) {
|
|
||||||
var tt = endDate;
|
|
||||||
endDate = startDate;
|
|
||||||
startDate = tt;
|
|
||||||
}
|
|
||||||
|
|
||||||
var def_arrival_hour = self._view_options['default_arrival_hour'].split(':');
|
|
||||||
var def_departure_hour = self._view_options['default_departure_hour'].split(':');
|
|
||||||
startDate.set({'hour': def_arrival_hour[0], 'minute': def_arrival_hour[1], 'second': 0});
|
|
||||||
endDate.set({'hour': def_departure_hour[0], 'minute': def_departure_hour[1], 'second': 0});
|
|
||||||
|
|
||||||
var popCreate = new ViewDialogs.FormViewDialog(self, {
|
|
||||||
res_model: 'hotel.reservation',
|
|
||||||
context: {
|
|
||||||
'default_checkin': startDate.utc().format(HotelConstants.ODOO_DATETIME_MOMENT_FORMAT),
|
|
||||||
'default_checkout': endDate.utc().format(HotelConstants.ODOO_DATETIME_MOMENT_FORMAT),
|
|
||||||
'default_adults': numBeds,
|
|
||||||
'default_children': 0,
|
|
||||||
'default_room_id': room.id,
|
|
||||||
'default_room_type_id': room.getUserData('room_type_id'),
|
|
||||||
},
|
|
||||||
title: _t("Create: ") + _t("Reservation"),
|
|
||||||
initial_view: "form",
|
|
||||||
disable_multiple_selection: true,
|
|
||||||
}).open();
|
|
||||||
});
|
|
||||||
|
|
||||||
this._hcalendar.addEventListener('hcalOnDateChanged', function(ev){
|
|
||||||
var $dateTimePickerBegin = this.$el.find('#pms-search #date_begin');
|
|
||||||
var $dateTimePickerEnd = this.$el.find('#pms-search #date_end');
|
|
||||||
$dateTimePickerBegin.data("ignore_onchange", true);
|
|
||||||
$dateTimePickerEnd.data("DateTimePicker").minDate(false);
|
|
||||||
$dateTimePickerEnd.data("DateTimePicker").maxDate(false);
|
|
||||||
$dateTimePickerBegin.data("DateTimePicker").date(ev.detail.date_begin.local().add(1, 'd'));
|
|
||||||
$dateTimePickerEnd.data("ignore_onchange", true);
|
|
||||||
$dateTimePickerEnd.data("DateTimePicker").date(ev.detail.date_end.local());
|
|
||||||
this.reload_hcalendar_reservations(false);
|
|
||||||
}.bind(this));
|
|
||||||
},
|
|
||||||
|
|
||||||
_assign_extra_info: function() {
|
|
||||||
var self = this;
|
|
||||||
$(this._hcalendar.etable).find('.hcal-cell-room-type-group-item.btn-hcal-3d').on("mouseenter", function(){
|
|
||||||
var $this = $(this);
|
|
||||||
var room = self._hcalendar.getRoom($this.parent().data("hcalRoomObjId"));
|
|
||||||
if (room.overbooking) {
|
|
||||||
$this.tooltip({
|
|
||||||
animation: true,
|
|
||||||
html: true,
|
|
||||||
placement: 'right',
|
|
||||||
title: QWeb.render('HotelCalendar.TooltipRoomOverbooking', {'name': room.number})
|
|
||||||
}).tooltip('show');
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
var qdict = {
|
|
||||||
'room_type_name': room.getUserData('room_type_name'),
|
|
||||||
'name': room.number
|
|
||||||
};
|
|
||||||
$this.tooltip({
|
|
||||||
animation: true,
|
|
||||||
html: true,
|
|
||||||
placement: 'right',
|
|
||||||
title: QWeb.render('HotelCalendar.TooltipRoom', qdict)
|
|
||||||
}).tooltip('show');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(this._hcalendar.etableHeader).find('.hcal-cell-header-day').each(function(index, elm){
|
|
||||||
var $elm = $(elm);
|
|
||||||
var cdate = HotelCalendar.toMoment($elm.data('hcalDate'), HotelConstants.L10N_DATE_MOMENT_FORMAT);
|
|
||||||
var data = _.filter(self._days_tooltips, function(item) {
|
|
||||||
var ndate = HotelCalendar.toMoment(item[2], HotelConstants.ODOO_DATE_MOMENT_FORMAT);
|
|
||||||
return ndate.isSame(cdate, 'd');
|
|
||||||
});
|
|
||||||
if (data.length > 0) {
|
|
||||||
$elm.addClass('hcal-event-day');
|
|
||||||
$elm.prepend("<i class='fa fa-bell' style='margin-right: 0.1em'></i>");
|
|
||||||
$elm.on("mouseenter", function(data){
|
|
||||||
var $this = $(this);
|
|
||||||
if (data.length > 0) {
|
|
||||||
var qdict = {
|
|
||||||
'date': $this.data('hcalDate'),
|
|
||||||
'events': _.map(data, function(item){
|
|
||||||
return {
|
|
||||||
'name': item[1],
|
|
||||||
'date': item[2],
|
|
||||||
'location': item[3]
|
|
||||||
};
|
|
||||||
})
|
|
||||||
};
|
|
||||||
$this.attr('title', '');
|
|
||||||
$this.tooltip({
|
|
||||||
animation: true,
|
|
||||||
html: true,
|
|
||||||
placement: 'bottom',
|
|
||||||
title: QWeb.render('HotelCalendar.TooltipEvent', qdict)
|
|
||||||
}).tooltip('show');
|
|
||||||
}
|
|
||||||
}.bind(elm, data));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
update_buttons_counter: function(ncheckouts, ncheckins, noverbookings) {
|
update_buttons_counter: function(ncheckouts, ncheckins, noverbookings) {
|
||||||
var self = this;
|
var self = this;
|
||||||
// Checkouts Button
|
// Checkouts Button
|
||||||
@@ -581,7 +248,6 @@ var HotelCalendarView = AbstractRenderer.extend({
|
|||||||
return $.when(
|
return $.when(
|
||||||
this.trigger_up('onLoadCalendarSettings'),
|
this.trigger_up('onLoadCalendarSettings'),
|
||||||
this.trigger_up('onUpdateButtonsCounter'),
|
this.trigger_up('onUpdateButtonsCounter'),
|
||||||
this.trigger_up('onLoadCalendar'),
|
|
||||||
this.trigger_up('onLoadViewFilters'),
|
this.trigger_up('onLoadViewFilters'),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -9,8 +9,11 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) {
|
|||||||
|
|
||||||
var MultiCalendar = Widget.extend({
|
var MultiCalendar = Widget.extend({
|
||||||
_calendars: [],
|
_calendars: [],
|
||||||
_active_calendar: -1,
|
_active_index: -1,
|
||||||
_events: {},
|
_events: {},
|
||||||
|
_tabs: [],
|
||||||
|
_dataset: {},
|
||||||
|
_base: null,
|
||||||
|
|
||||||
init: function(parent) {
|
init: function(parent) {
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
@@ -22,23 +25,108 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) {
|
|||||||
this._create_tabs_panel();
|
this._create_tabs_panel();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get_calendar: function(index) {
|
||||||
|
return this._calendars[index];
|
||||||
|
},
|
||||||
|
|
||||||
|
get_tab: function(index) {
|
||||||
|
return this._tabs[index];
|
||||||
|
},
|
||||||
|
|
||||||
|
get_active_index: function() {
|
||||||
|
return this._active_index;
|
||||||
|
},
|
||||||
|
|
||||||
|
get_active_calendar: function() {
|
||||||
|
return this._calendars[this._active_index];
|
||||||
|
},
|
||||||
|
|
||||||
|
get_active_tab: function() {
|
||||||
|
return this._tabs[this._active_index];
|
||||||
|
},
|
||||||
|
|
||||||
|
recalculate_reservation_positions: function() {
|
||||||
|
setTimeout(function(){
|
||||||
|
for (var reserv of this.get_active_calendar()._reservations) {
|
||||||
|
var style = window.getComputedStyle(reserv._html, null);
|
||||||
|
if (parseInt(style.width, 10) < 15 || parseInt(style.height, 10) < 15 || parseInt(style.top, 10) === 0) {
|
||||||
|
this.get_active_calendar()._updateReservation(reserv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.bind(this), 200);
|
||||||
|
},
|
||||||
|
|
||||||
|
update_all_reservations: function() {
|
||||||
|
for (var calendar of this._calendars) {
|
||||||
|
this._update_reservations(calendar);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
update_reservations: function(calendar) {
|
||||||
|
calendar.setReservations(this._dataset['reservations']);
|
||||||
|
this._assign_extra_info(calendar);
|
||||||
|
},
|
||||||
|
|
||||||
|
set_active_calendar: function(index) {
|
||||||
|
this._tabs[index][0].tab('show');
|
||||||
|
},
|
||||||
|
|
||||||
|
set_datasets: function(pricelist, restrictions, reservations) {
|
||||||
|
this._dataset = {
|
||||||
|
pricelist: pricelist,
|
||||||
|
restrictions: restrictions,
|
||||||
|
reservations: reservations,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
set_options: function(options) {
|
||||||
|
this._options = options;
|
||||||
|
},
|
||||||
|
|
||||||
|
set_base_element: function(element) {
|
||||||
|
this._base = element;
|
||||||
|
},
|
||||||
|
|
||||||
|
create_calendar: function(name) {
|
||||||
|
var [$tab, $panel] = this._create_tab(name, `calendar-pane-${name}`);
|
||||||
|
var calendar = new HotelCalendar(
|
||||||
|
$panel[0],
|
||||||
|
this._options,
|
||||||
|
this._dataset['pricelist'],
|
||||||
|
this._dataset['restrictions'],
|
||||||
|
this._base);
|
||||||
|
this._assign_calendar_events(calendar);
|
||||||
|
this._calendars.push(calendar);
|
||||||
|
return this._calendars.length-1;
|
||||||
|
},
|
||||||
|
|
||||||
|
on: function(event_name, callback) {
|
||||||
|
this._events[event_name] = callback;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
_create_tab: function(name, id) {
|
_create_tab: function(name, id) {
|
||||||
|
var sanitized_id = this._sanitizeId(id);
|
||||||
// '+' Tab
|
// '+' Tab
|
||||||
var $tab = $('<a/>', {
|
var $tab = $('<a/>', {
|
||||||
id: name,
|
id: this._sanitizeId(name),
|
||||||
href: `#${id}`,
|
href: `#${sanitized_id}`,
|
||||||
text: name,
|
text: name,
|
||||||
}).appendTo($('<li/>').prependTo(this.$tabs));
|
role: 'tab',
|
||||||
|
}).data('tabindex', this._tabs.length).appendTo($('<li/>').prependTo(this.$tabs));
|
||||||
$tab[0].dataset.toggle = 'tab';
|
$tab[0].dataset.toggle = 'tab';
|
||||||
var $pane = $('<div/>', {
|
var $panel = $('<div/>', {
|
||||||
id: id,
|
id: sanitized_id,
|
||||||
class: 'tab-pane',
|
class: 'tab-pane',
|
||||||
|
role: 'tabpanel'
|
||||||
}).appendTo(this.$tabs_content);
|
}).appendTo(this.$tabs_content);
|
||||||
|
|
||||||
return $pane;
|
this._tabs.push([$tab, $panel]);
|
||||||
|
return this._tabs[this._tabs.length-1];
|
||||||
},
|
},
|
||||||
|
|
||||||
_create_tabs_panel: function() {
|
_create_tabs_panel: function() {
|
||||||
|
var self = this;
|
||||||
this.$el.empty();
|
this.$el.empty();
|
||||||
this.$tabs = $('<ul/>', {
|
this.$tabs = $('<ul/>', {
|
||||||
class: 'nav nav-tabs',
|
class: 'nav nav-tabs',
|
||||||
@@ -48,44 +136,89 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) {
|
|||||||
}).appendTo(this.$el);
|
}).appendTo(this.$el);
|
||||||
|
|
||||||
// '+' Tab
|
// '+' Tab
|
||||||
var $pane = this._create_tab('+', 'default');
|
var [$tab, $panel] = this._create_tab('+', 'default');
|
||||||
|
$tab.on('shown.bs.tab', function(ev){
|
||||||
|
ev.preventDefault();
|
||||||
|
var new_calendar_id = self.create_calendar(`Calendar #${self._calendars.length}`);
|
||||||
|
self.set_active_calendar(new_calendar_id);
|
||||||
|
});
|
||||||
$('<p/>', {
|
$('<p/>', {
|
||||||
class: 'warn-message',
|
class: 'warn-message',
|
||||||
text: "NO CALENDAR DEFINED!",
|
text: "NO CALENDAR DEFINED!",
|
||||||
}).appendTo($pane);
|
}).appendTo($panel);
|
||||||
},
|
|
||||||
|
|
||||||
get_active_calendar: function() {
|
|
||||||
return this._calendars[this._active_calendar];
|
|
||||||
},
|
|
||||||
|
|
||||||
recalculate_reservation_positions: function() {
|
|
||||||
setTimeout(function(){
|
|
||||||
for (var reserv of this.get_active_calendar._reservations) {
|
|
||||||
var style = window.getComputedStyle(reserv._html, null);
|
|
||||||
if (parseInt(style.width, 10) < 15 || parseInt(style.height, 10) < 15 || parseInt(style.top, 10) === 0) {
|
|
||||||
this.get_active_calendar()._updateReservation(reserv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.bind(this), 200);
|
|
||||||
},
|
|
||||||
|
|
||||||
create_calendar: function(name, options, pricelist, restrictions, base) {
|
|
||||||
var $pane = this._create_tab(name, `calendar-pane-${name}`);
|
|
||||||
var calendar = new HotelCalendar($pane[0], options, pricelist, restrictions, base);
|
|
||||||
this._assign_calendar_events(calendar);
|
|
||||||
this._calendars.push(calendar);
|
|
||||||
this._active_calendar = this._calendars.length - 1;
|
|
||||||
},
|
|
||||||
|
|
||||||
on: function(event_name, callback) {
|
|
||||||
for (var calendar of this._calendars) {
|
|
||||||
calendar.addEventListener(event_name, callback);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_assign_calendar_events: function(calendar) {
|
_assign_calendar_events: function(calendar) {
|
||||||
|
for (var event_name in this._events) {
|
||||||
|
calendar.addEventListener(event_name, this._events[event_name]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_assign_extra_info: function(calendar) {
|
||||||
|
var self = this;
|
||||||
|
$(calendar.etable).find('.hcal-cell-room-type-group-item.btn-hcal-3d').on("mouseenter", function(){
|
||||||
|
var $this = $(this);
|
||||||
|
var room = calendar.getRoom($this.parent().data("hcalRoomObjId"));
|
||||||
|
if (room.overbooking) {
|
||||||
|
$this.tooltip({
|
||||||
|
animation: true,
|
||||||
|
html: true,
|
||||||
|
placement: 'right',
|
||||||
|
title: QWeb.render('HotelCalendar.TooltipRoomOverbooking', {'name': room.number})
|
||||||
|
}).tooltip('show');
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
var qdict = {
|
||||||
|
'room_type_name': room.getUserData('room_type_name'),
|
||||||
|
'name': room.number
|
||||||
|
};
|
||||||
|
$this.tooltip({
|
||||||
|
animation: true,
|
||||||
|
html: true,
|
||||||
|
placement: 'right',
|
||||||
|
title: QWeb.render('HotelCalendar.TooltipRoom', qdict)
|
||||||
|
}).tooltip('show');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(calendar.etableHeader).find('.hcal-cell-header-day').each(function(index, elm){
|
||||||
|
var $elm = $(elm);
|
||||||
|
var cdate = HotelCalendar.toMoment($elm.data('hcalDate'), HotelConstants.L10N_DATE_MOMENT_FORMAT);
|
||||||
|
var data = _.filter(self._days_tooltips, function(item) {
|
||||||
|
var ndate = HotelCalendar.toMoment(item[2], HotelConstants.ODOO_DATE_MOMENT_FORMAT);
|
||||||
|
return ndate.isSame(cdate, 'd');
|
||||||
|
});
|
||||||
|
if (data.length > 0) {
|
||||||
|
$elm.addClass('hcal-event-day');
|
||||||
|
$elm.prepend("<i class='fa fa-bell' style='margin-right: 0.1em'></i>");
|
||||||
|
$elm.on("mouseenter", function(data){
|
||||||
|
var $this = $(this);
|
||||||
|
if (data.length > 0) {
|
||||||
|
var qdict = {
|
||||||
|
'date': $this.data('hcalDate'),
|
||||||
|
'events': _.map(data, function(item){
|
||||||
|
return {
|
||||||
|
'name': item[1],
|
||||||
|
'date': item[2],
|
||||||
|
'location': item[3]
|
||||||
|
};
|
||||||
|
})
|
||||||
|
};
|
||||||
|
$this.attr('title', '');
|
||||||
|
$this.tooltip({
|
||||||
|
animation: true,
|
||||||
|
html: true,
|
||||||
|
placement: 'bottom',
|
||||||
|
title: QWeb.render('HotelCalendar.TooltipEvent', qdict)
|
||||||
|
}).tooltip('show');
|
||||||
|
}
|
||||||
|
}.bind(elm, data));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_sanitizeId: function(/*String*/str) {
|
||||||
|
return str.replace(/[^a-zA-Z0-9\-_]/g, '_');
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -218,7 +218,17 @@ HotelCalendar.prototype = {
|
|||||||
this._reservations[rindex] = r;
|
this._reservations[rindex] = r;
|
||||||
this._cleanUnusedZones(r);
|
this._cleanUnusedZones(r);
|
||||||
} else {
|
} else {
|
||||||
this._reservations.push(r);
|
var room = this.getRoom(r.room_id, r.overbooking, r.id);
|
||||||
|
// need create a overbooking row?
|
||||||
|
if (!room && r.overbooking) {
|
||||||
|
room = this.createOBRoom(this.getRoom(r.room_id), r.id);
|
||||||
|
this.createOBRoomRow(room);
|
||||||
|
}
|
||||||
|
if (room) {
|
||||||
|
this._reservations.push(r);
|
||||||
|
} else {
|
||||||
|
console.warn(`Can't found a room for the reservation '${r[0]}'!`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1138,7 +1148,10 @@ HotelCalendar.prototype = {
|
|||||||
this.btnSaveChanges.innerHTML = "<i class='fa fa-save fa-2x'> </i>";
|
this.btnSaveChanges.innerHTML = "<i class='fa fa-save fa-2x'> </i>";
|
||||||
this.btnSaveChanges.addEventListener('click', function(ev){
|
this.btnSaveChanges.addEventListener('click', function(ev){
|
||||||
if (this.classList.contains('need-save')) {
|
if (this.classList.contains('need-save')) {
|
||||||
$this._dispatchEvent('hcalOnSavePricelist');
|
$this._dispatchEvent('hcalOnSavePricelist', {
|
||||||
|
pricelist: $this.getPricelist(),
|
||||||
|
pricelist_id: $this._pricelist_id,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
cell.appendChild(this.btnSaveChanges);
|
cell.appendChild(this.btnSaveChanges);
|
||||||
@@ -2234,7 +2247,10 @@ HotelCalendar.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_dispatchEvent: function(/*String*/eventName, /*Dictionary*/data) {
|
_dispatchEvent: function(/*String*/eventName, /*Dictionary*/data) {
|
||||||
this.e.dispatchEvent(new CustomEvent(eventName, { 'detail': data }));
|
this.e.dispatchEvent(new CustomEvent(eventName, {
|
||||||
|
'detail': data,
|
||||||
|
'calendar': this,
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
_sanitizeId: function(/*String*/str) {
|
_sanitizeId: function(/*String*/str) {
|
||||||
@@ -2744,7 +2760,7 @@ function HReservation(/*Dictionary*/rValues) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.id = rValues.id;
|
this.id = rValues.id;
|
||||||
this.room = rValues.room;
|
this.room_id = rValues.room_id;
|
||||||
this.adults = rValues.adults || 1;
|
this.adults = rValues.adults || 1;
|
||||||
this.childrens = rValues.childrens || 0;
|
this.childrens = rValues.childrens || 0;
|
||||||
this.title = rValues.title || '';
|
this.title = rValues.title || '';
|
||||||
|
|||||||
Reference in New Issue
Block a user