diff --git a/hotel_calendar/models/bus_hotel_calendar.py b/hotel_calendar/models/bus_hotel_calendar.py index 4c283843e..6dd0242fb 100644 --- a/hotel_calendar/models/bus_hotel_calendar.py +++ b/hotel_calendar/models/bus_hotel_calendar.py @@ -64,8 +64,8 @@ class BusHotelCalendar(models.TransientModel): vals['checkin'], num_split, vals['price'], - vals['reservation_type'], - vals['out_service_description'], + vals['reservation_type'] if 'reservation_type' in vals else 'normal', + vals['out_service_description'] if 'out_service_description' in vals else '', ] } diff --git a/hotel_calendar/models/inherited_hotel_reservation.py b/hotel_calendar/models/inherited_hotel_reservation.py index fdb217034..fe3e5e4f7 100644 --- a/hotel_calendar/models/inherited_hotel_reservation.py +++ b/hotel_calendar/models/inherited_hotel_reservation.py @@ -416,6 +416,7 @@ class HotelReservation(models.Model): @api.multi def write(self, vals): ret = super(HotelReservation, self).write(vals) + _logger.info("RESERV WRITE") if 'partner_id' in vals or 'checkin' in vals or \ 'checkout' in vals or 'product_id' in vals or \ 'adults' in vals or 'children' in vals or \ @@ -425,7 +426,9 @@ class HotelReservation(models.Model): 'reserve_color' in vals or \ 'reserve_color_text' in vals or 'product_id' in vals or \ 'parent_reservation' in vals or 'overbooking' in vals: + _logger.info("PASA RESERV WRITE") for record in self: + _logger.info("PASA RESERV WRITE 22") record.send_bus_notification( 'write', (record.state == 'cancelled') and 'warn' or 'notify', diff --git a/hotel_calendar/static/src/js/views/calendar/hotel_calendar_controller.js b/hotel_calendar/static/src/js/views/calendar/hotel_calendar_controller.js index d97494c93..aa41237ea 100644 --- a/hotel_calendar/static/src/js/views/calendar/hotel_calendar_controller.js +++ b/hotel_calendar/static/src/js/views/calendar/hotel_calendar_controller.js @@ -4,6 +4,8 @@ odoo.define('hotel_calendar.PMSCalendarController', function (require) { "use strict"; var AbstractController = require('web.AbstractController'), + ViewDialogs = require('web.view_dialogs'), + Dialog = require('web.Dialog'), Core = require('web.core'), Bus = require('bus.bus').bus, HotelConstants = require('hotel_calendar.Constants'), @@ -19,10 +21,9 @@ var PMSCalendarController = AbstractController.extend({ onLoadViewFilters: '_onLoadViewFilters', onUpdateButtonsCounter: '_onUpdateButtonsCounter', onReloadCalendar: '_onReloadCalendar', - onUpdateReservations: '_onUpdateReservations', onSwapReservations: '_onSwapReservations', - onSaveChanges: '_onSaveChanges', onViewAttached: '_onViewAttached', + onApplyFilters: '_onApplyFilters', }), init: function (parent, model, renderer, params) { @@ -43,6 +44,7 @@ var PMSCalendarController = AbstractController.extend({ this._multi_calendar.start(); this._assign_multi_calendar_events(); this._load_calendars(); + this._assign_view_events(); }, //-------------------------------------------------------------------------- @@ -57,6 +59,18 @@ var PMSCalendarController = AbstractController.extend({ }); }, + updateReservations: function (ids, values, oldReserv, newReserv) { + var self = this; + return this.model.update_records(ids, values).then(function(result){ + // Remove OB Room Row? + if (oldReserv.room.overbooking && !newReserv.room.overbooking) { + self._multi_calendar.remove_obroom_row(oldReserv); + } + }).fail(function(err, errev){ + self._multi_calendar.replace_reservation(newReserv, oldReserv); + }); + }, + //-------------------------------------------------------------------------- // Private //-------------------------------------------------------------------------- @@ -144,314 +158,31 @@ var PMSCalendarController = AbstractController.extend({ for (var calendar of results['calendars']) { self._multi_calendar.create_calendar(calendar['name']); } + self._multi_calendar.set_active_calendar(self._multi_calendar._calendars.length-1); }); }, - _assign_multi_calendar_events: function() { - var self = this; - this._multi_calendar.on('hcalOnSavePricelist', function(ev){ - self.savePricelist(ev.calendar, ev.detail.pricelist_id, ev.detail.pricelist); - }); - this._multi_calendar.on('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._multi_calendar.on('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._multi_calendar.on('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; + _reload_active_calendar: function() { + var filterDates = this.renderer.get_view_filter_dates(); + // Clip dates + var dfrom = filterDates[0].clone(), + dto = filterDates[1].clone(); + if (filterDates[0].isBetween(this.renderer._last_dates[0], this.renderer._last_dates[1], 'days') && filterDates[1].isAfter(this.renderer._last_dates[1], 'day')) { + dfrom = this.renderer._last_dates[1].clone().local().startOf('day').utc(); + } else if (this.renderer._last_dates[0].isBetween(filterDates[0], filterDates[1], 'days') && this.renderer._last_dates[1].isAfter(filterDates[0], 'day')) { + dto = this.renderer._last_dates[0].clone().local().endOf('day').utc(); + } else { + clearReservations = true; + } - // 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._multi_calendar.on('hcalOnCancelSwapReservations', function(ev){ - $("#btn_swap span.ntext").html(_t("START SWAP")); - $("#btn_swap").css({ - 'backgroundColor': '', - 'fontWeight': 'normal' - }); - }); - this._multi_calendar.on('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._multi_calendar.on('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._multi_calendar.on('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._multi_calendar.on('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)); - }, - - //-------------------------------------------------------------------------- - // Handlers - //-------------------------------------------------------------------------- - _onUpdateReservations: function (ev) { - var self = this; - return this.model.update_records(ev.data.ids, ev.data.values).then(function(result){ - // Remove OB Room Row? - if (ev.data.oldReservation.room.overbooking) { - self.renderer._hcalendar.removeOBRoomRow(ev.data.oldReservation); - } - }).fail(function(err, errev){ - self.renderer._hcalendar.replaceReservation(ev.data.newReservation, ev.data.oldReservation); - }); - }, - - _onSwapReservations: function (ev) { - var self = this; - return this.model.swap_reservations(ev.data.fromIds, ev.data.toIds).then(function(results){ - var allReservs = ev.data.detail.inReservs.concat(ev.data.detail.outReservs); - for (var nreserv of allReservs) { - self.renderer.$el.find(nreserv._html).stop(true); - } - }).fail(function(err, errev){ - for (var nreserv of ev.data.detail.inReservs) { - self.renderer.$el.find(nreserv._html).animate({'top': refFromReservDiv.style.top}, 'fast'); - } - for (var nreserv of ev.detail.outReservs) { - self.renderer.$el.find(nreserv._html).animate({'top': refToReservDiv.style.top}, 'fast'); - } - - self.renderer.$el._hcalendar.swapReservations(ev.data.detail.outReservs, ev.data.detail.inReservs); - }); - }, - - _onLoadCalendarSettings: function (ev) { - var self = this; - return this.model.get_hcalendar_settings().then(function(options){ - self._view_options = options; - var date_begin = moment().startOf('day'); - if (['xs', 'md'].indexOf(self._find_bootstrap_environment()) >= 0) { - self._view_options['days'] = 7; - } else { - self._view_options['days'] = (self._view_options['days'] !== 'month')?parseInt(self._view_options['days']):date_begin.daysInMonth(); - } - self.renderer.load_hcalendar_options(self._view_options); - }); - }, - - _onViewAttached: function (ev) { - this._multi_calendar.recalculate_reservation_positions(); - }, - - _onReloadCalendar: function (ev) { - this.model.get_calendar_data(ev.data.oparams).then(function(results){ - this.renderer._merge_days_tooltips(results['events']); - this.renderer._reserv_tooltips = _.extend(this.renderer._reserv_tooltips, results['tooltips']); + var oparams = [ + dfrom.format(HotelConstants.ODOO_DATETIME_MOMENT_FORMAT), + dto.format(HotelConstants.ODOO_DATETIME_MOMENT_FORMAT), + false + ]; + this.model.get_calendar_data(oparams).then(function(results){ + this._multi_calendar._merge_days_tooltips(results['events']); + this._multi_calendar._reserv_tooltips = _.extend(this._multi_calendar._reserv_tooltips, results['tooltips']); var reservs = []; for (var r of results['reservations']) { var nreserv = new HReservation({ @@ -477,16 +208,340 @@ var PMSCalendarController = AbstractController.extend({ reservs.push(nreserv); } - this.renderer._hcalendar.addPricelist(results['pricelist']); - this.renderer._hcalendar.addRestrictions(results['restrictions']); - if (ev.data.clearReservations) { - this.renderer._hcalendar.setReservations(reservs); + this._multi_calendar.merge_pricelist(results['pricelist']); + this._multi_calendar.merge_restrictions(results['restrictions']); + this._multi_calendar.merge_reservations(reservs); + + this._multi_calendar._assign_extra_info(this._multi_calendar.get_active_calendar()); + }.bind(this)).then(function(){ + this.renderer._last_dates = filterDates; + }); + }, + + _assign_view_events: function() { + var self = this; + var $dateTimePickerBegin = this.renderer.$el.find('#pms-search #date_begin'); + var $dateTimePickerEnd = this.renderer.$el.find('#pms-search #date_end'); + $dateTimePickerBegin.on("dp.change", function (e) { + $dateTimePickerEnd.data("DateTimePicker").minDate(e.date.clone().add(3,'d')); + $dateTimePickerEnd.data("DateTimePicker").maxDate(e.date.clone().add(2,'M')); + $dateTimePickerBegin.data("DateTimePicker").hide(); + self._on_change_filter_date(true); + }); + $dateTimePickerEnd.on("dp.change", function (e) { + $dateTimePickerEnd.data("DateTimePicker").hide(); + self._on_change_filter_date(false); + }); + + this.renderer.$el.find("#btn_swap").on('click', function(ev){ + var active_calendar = self._multi_calendar.get_active_calendar(); + var hcalSwapMode = active_calendar.getSwapMode(); + if (hcalSwapMode === HotelCalendar.MODE.NONE) { + active_calendar.setSwapMode(HotelCalendar.MODE.SWAP_FROM); + $("#btn_swap span.ntext").html(_t("CONTINUE")); + $("#btn_swap").css({ + 'backgroundColor': 'rgb(145, 255, 0)', + 'fontWeight': 'bold' + }); + } else if (active_calendar.getReservationAction().inReservations.length > 0 && hcalSwapMode === HotelCalendar.MODE.SWAP_FROM) { + active_calendar.setSwapMode(HotelCalendar.MODE.SWAP_TO); + $("#btn_swap span.ntext").html(_t("END")); + $("#btn_swap").css({ + 'backgroundColor': 'orange', + 'fontWeight': 'bold' + }); } else { - this.renderer._hcalendar.addReservations(reservs); + active_calendar.setSwapMode(HotelCalendar.MODE.NONE); + $("#btn_swap span.ntext").html(_t("START SWAP")); + $("#btn_swap").css({ + 'backgroundColor': '', + 'fontWeight': '' + }); + } + }); + }, + + _assign_multi_calendar_events: function() { + var self = this; + this._multi_calendar.on('hcalOnSavePricelist', function(ev){ + self.savePricelist(ev.detail.calendar_obj, ev.detail.pricelist_id, ev.detail.pricelist); + }); + this._multi_calendar.on('hcalOnMouseEnterReservation', function(ev){ + if (ev.detail.reservationObj) { + var tp = self._multi_calendar._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._multi_calendar.on('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._multi_calendar.on('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 (ev.detail.calendar_obj.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._multi_calendar.on('hcalOnCancelSwapReservations', function(ev){ + $("#btn_swap span.ntext").html(_t("START SWAP")); + $("#btn_swap").css({ + 'backgroundColor': '', + 'fontWeight': 'normal' + }); + }); + this._multi_calendar.on('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(ev.detail.calendar_obj._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.updateReservations([newReservation.id], write_values, + oldReservation, newReservation); + hasChanged = true; + } + }, + { + text: _t("No"), + close: true, + } + ], + $content: QWeb.render('HotelCalendar.ConfirmReservationChanges', qdict) + }).open(); + dialog.opened(function(e){ + if (!hasChanged) { + ev.detail.calendar_obj.replaceReservation(newReservation, oldReservation); + } + }); + }); + this._multi_calendar.on('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(ev.detail.calendar_obj.etable.querySelector(`#${ev.detail.cells[0].dataset.hcalParentCell}`).dataset.hcalDate); + var date_cell_end = HotelCalendar.toMoment(ev.detail.calendar_obj.etable.querySelector(`#${last_cell.dataset.hcalParentCell}`).dataset.hcalDate); + var parentRow = document.querySelector(`#${ev.detail.cells[0].dataset.hcalParentRow}`); + var room = ev.detail.calendar_obj.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._multi_calendar.on('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 = ev.detail.calendar_obj.getRoom(parentRow.dataset.hcalRoomObjId); + if (room.overbooking) { + return; + } + var numBeds = (room.shared || ev.detail.calendar_obj.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._multi_calendar.on('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_active_calendar(); + }.bind(this)); + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + _onSwapReservations: function (ev) { + var self = this; + return this.model.swap_reservations(ev.data.fromIds, ev.data.toIds).then(function(results){ + var allReservs = ev.data.detail.inReservs.concat(ev.data.detail.outReservs); + for (var nreserv of allReservs) { + self.renderer.$el.find(nreserv._html).stop(true); + } + }).fail(function(err, errev){ + for (var nreserv of ev.data.detail.inReservs) { + self.renderer.$el.find(nreserv._html).animate({'top': refFromReservDiv.style.top}, 'fast'); + } + for (var nreserv of ev.detail.outReservs) { + self.renderer.$el.find(nreserv._html).animate({'top': refToReservDiv.style.top}, 'fast'); } - this.renderer._assign_extra_info(); - }.bind(this)); + self._multi_calendar.swap_reservations(ev.data.detail.outReservs, ev.data.detail.inReservs); + }); + }, + + _onLoadCalendarSettings: function (ev) { + var self = this; + return this.model.get_hcalendar_settings().then(function(options){ + self._view_options = options; + var date_begin = moment().startOf('day'); + if (['xs', 'md'].indexOf(self._find_bootstrap_environment()) >= 0) { + self._view_options['days'] = 7; + } else { + self._view_options['days'] = (self._view_options['days'] !== 'month')?parseInt(self._view_options['days']):date_begin.daysInMonth(); + } + self.renderer.load_hcalendar_options(self._view_options); + }); + }, + + _onViewAttached: function (ev) { + this._multi_calendar.recalculate_reservation_positions(); }, _onUpdateButtonsCounter: function (ev) { @@ -516,16 +571,15 @@ var PMSCalendarController = AbstractController.extend({ }, _onBusNotification: function(notifications) { - if (!this.renderer._hcalendar) { - return; - } var need_reload_pricelists = false; var need_update_counters = false; var nreservs = [] + console.log("BUS!"); for (var notif of notifications) { if (notif[0][1] === 'hotel.reservation') { switch (notif[1]['type']) { case 'reservation': + console.log("BUS RESERVA"); var reserv = notif[1]['reservation']; // Only show notifications of other users // if (notif[1]['subtype'] !== 'noshow' && this._view_options['show_notifications'] && notif[1]['userid'] != this.dataset.context.uid) { @@ -546,53 +600,43 @@ var PMSCalendarController = AbstractController.extend({ // Create/Update/Delete reservation if (notif[1]['action'] === 'unlink' || reserv['state'] === 'cancelled') { - this.renderer._hcalendar.removeReservation(reserv['reserv_id'], true); - this.renderer._reserv_tooltips = _.pick(this.renderer._reserv_tooltips, function(value, key, obj){ return key != reserv['reserv_id']; }); + this._multi_calendar.remove_reservation(reserv['reserv_id']); + this._multi_calendar._reserv_tooltips = _.pick(this._multi_calendar._reserv_tooltips, function(value, key, obj){ return key != reserv['reserv_id']; }); nreservs = _.reject(nreservs, function(item){ return item.id == reserv['reserv_id']; }); } else { nreservs = _.reject(nreservs, {'id': reserv['reserv_id']}); // Only like last changes - var room = this.renderer._hcalendar.getRoom(reserv['room_id'], reserv['overbooking'], reserv['reserv_id']); - // need create a overbooking row? - if (!room && reserv['overbooking']) { - room = this.renderer._hcalendar.createOBRoom(this.renderer._hcalendar.getRoom(reserv['room_id']), reserv['reserv_id']); - this.renderer._hcalendar.createOBRoomRow(room); - } - if (!room) { - console.warn(`Can't found a room for the reservation '${reserv['reserv_id']}'!`); - continue; - } - if (room) { - var nreserv = new HReservation({ - 'id': reserv['reserv_id'], - 'room': room, - 'title': reserv['partner_name'], - 'adults': reserv['adults'], - 'childrens': reserv['children'], - 'startDate': HotelCalendar.toMomentUTC(reserv['checkin'], HotelConstants.ODOO_DATETIME_MOMENT_FORMAT), - 'endDate': HotelCalendar.toMomentUTC(reserv['checkout'], HotelConstants.ODOO_DATETIME_MOMENT_FORMAT), - 'color': reserv['reserve_color'], - 'colorText': reserv['reserve_color_text'], - 'splitted': reserv['splitted'], - 'readOnly': reserv['read_only'], - 'fixDays': reserv['fix_days'], - 'fixRooms': reserv['fix_rooms'], - 'unusedZone': false, - 'linkedId': false, - 'overbooking': reserv['overbooking'], - }); - nreserv.addUserData({'folio_id': reserv['folio_id']}); - nreserv.addUserData({'parent_reservation': reserv['parent_reservation']}); - this.renderer._reserv_tooltips[reserv['reserv_id']] = notif[1]['tooltip']; - nreservs.push(nreserv); - } + var nreserv = new HReservation({ + 'id': reserv['reserv_id'], + 'room_id': reserv['room_id'], + 'title': reserv['partner_name'], + 'adults': reserv['adults'], + 'childrens': reserv['children'], + 'startDate': HotelCalendar.toMomentUTC(reserv['checkin'], HotelConstants.ODOO_DATETIME_MOMENT_FORMAT), + 'endDate': HotelCalendar.toMomentUTC(reserv['checkout'], HotelConstants.ODOO_DATETIME_MOMENT_FORMAT), + 'color': reserv['reserve_color'], + 'colorText': reserv['reserve_color_text'], + 'splitted': reserv['splitted'], + 'readOnly': reserv['read_only'], + 'fixDays': reserv['fix_days'], + 'fixRooms': reserv['fix_rooms'], + 'unusedZone': false, + 'linkedId': false, + 'overbooking': reserv['overbooking'], + }); + nreserv.addUserData({ + 'folio_id': reserv['folio_id'], + 'parent_reservation': reserv['parent_reservation'], + }); + this._multi_calendar._reserv_tooltips[reserv['reserv_id']] = notif[1]['tooltip']; + nreservs.push(nreserv); } need_update_counters = true; break; case 'pricelist': - this.renderer._hcalendar.addPricelist(notif[1]['price']); + this._multi_calendar.merge_pricelist(notif[1]['price']); break; case 'restriction': - this.renderer._hcalendar.addRestrictions(notif[1]['restriction']); + this._multi_calendar.merge_restrictions(notif[1]['restriction']); break; default: // Do Nothing @@ -600,22 +644,44 @@ var PMSCalendarController = AbstractController.extend({ } } if (nreservs.length > 0) { - this.renderer._hcalendar.addReservations(nreservs); + this._multi_calendar.merge_reservations(nreservs); } if (need_update_counters) { this._onUpdateButtonsCounter(); } }, + _onApplyFilters: function() { + var category = _.map(this.renderer.$el.find('#pms-search #type_list').val(), function(item){ return +item; }); + var floor = _.map(this.renderer.$el.find('#pms-search #floor_list').val(), function(item){ return +item; }); + var amenities = _.map(this.renderer.$el.find('#pms-search #amenities_list').val(), function(item){ return +item; }); + var virtual = _.map(this.renderer.$el.find('#pms-search #virtual_list').val(), function(item){ return +item; }); + var domain = []; + if (category && category.length > 0) { + domain.push(['class_name', 'in', category]); + } + if (floor && floor.length > 0) { + domain.push(['floor_id', 'in', floor]); + } + if (amenities && amenities.length > 0) { + domain.push(['amenities', 'in', amenities]); + } + if (virtual && virtual.length > 0) { + domain.push(['room_type_id', 'some', virtual]); + } + + this._multi_calendar.get_active_calendar().setDomain(HotelCalendar.DOMAIN.ROOMS, domain); + }, + _assign_hcalendar_events: function() { var self = this; this._multi_calendar.on('hcalOnSavePricelist', function(ev){ var oparams = [ev.detail.pricelist_id, false, ev.detail.pricelist, {}, {}]; - self.savePricelist(ev.calendar, ev.detail.pricelist_id, ev.detail.pricelist); + self.savePricelist(ev.detail.calendar_obj, ev.detail.pricelist_id, ev.detail.pricelist); }); this._multi_calendar.on('hcalOnMouseEnterReservation', function(ev){ if (ev.detail.reservationObj) { - var tp = self._reserv_tooltips[ev.detail.reservationObj.id]; + var tp = self._multi_calendar._reserv_tooltips[ev.detail.reservationObj.id]; var qdict = self._generate_reservation_tooltip_dict(tp); $(ev.detail.reservationDiv).tooltip('destroy').tooltip({ animation: false, @@ -650,55 +716,55 @@ var PMSCalendarController = AbstractController.extend({ this._multi_calendar.on('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; + title: _t("Confirm Reservation Swap"), + buttons: [ + { + text: _t("Yes, swap it"), + classes: 'btn-primary', + close: true, + click: function () { + if (ev.detail.calendar_obj.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(); - } + // Animate Movement + for (var nreserv of ev.detail.inReservs) { + $(nreserv._html).animate({'top': refToReservDiv.style.top}); } - }, - { - text: _t("No"), - close: true + 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(); } - ], - $content: QWeb.render('HotelCalendar.ConfirmSwapOperation', qdict) + } + }, + { + text: _t("No"), + close: true + } + ], + $content: QWeb.render('HotelCalendar.ConfirmSwapOperation', qdict) }).open(); }); this._multi_calendar.on('hcalOnCancelSwapReservations', function(ev){ @@ -709,71 +775,65 @@ var PMSCalendarController = AbstractController.extend({ }); }); this._multi_calendar.on('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 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 linkedReservs = _.find(ev.detail.calendar_obj._reservations, function(item){ + return item.id !== newReservation.id && !item.unusedZone && item.getUserData('folio_id') === folio_id; + }); - var hasChanged = false; + 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, + 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); } - ], - $content: QWeb.render('HotelCalendar.ConfirmReservationChanges', qdict) - }).open(); - dialog.opened(function(e){ - if (!hasChanged) { - self._hcalendar.replaceReservation(newReservation, oldReservation); - } - }); + 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.updateReservations([newReservation.id], write_values, + oldReservation, newReservation); + hasChanged = true; + } + }, + { + text: _t("No"), + close: true, + } + ], + $content: QWeb.render('HotelCalendar.ConfirmReservationChanges', qdict) + }).open(); + dialog.opened(function(e){ + if (!hasChanged) { + self._multicalendar.replace_reservation(newReservation, oldReservation); + } + }); }); this._multi_calendar.on('hcalOnUpdateSelection', function(ev){ for (var td of ev.detail.old_cells) { @@ -781,67 +841,67 @@ var PMSCalendarController = AbstractController.extend({ } 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 date_cell_start = HotelCalendar.toMoment(ev.detail.calendar_obj.etable.querySelector(`#${ev.detail.cells[0].dataset.hcalParentCell}`).dataset.hcalDate); + var date_cell_end = HotelCalendar.toMoment(ev.detail.calendar_obj.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); + var room = ev.detail.calendar_obj.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'); - } + 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._multi_calendar.on('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; - } + 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 = ev.detail.calendar_obj.getRoom(parentRow.dataset.hcalRoomObjId); + if (room.overbooking) { + return; + } + var numBeds = (room.shared || ev.detail.calendar_obj.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; - } + // 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 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(); + 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._multi_calendar.on('hcalOnDateChanged', function(ev){ @@ -853,10 +913,54 @@ var PMSCalendarController = AbstractController.extend({ $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); + this._reload_active_calendar(); }.bind(this)); }, + _generate_reservation_tooltip_dict: function(tp) { + return { + 'name': tp[0], + 'phone': tp[1], + 'arrival_hour': HotelCalendar.toMomentUTC(tp[2], HotelConstants.ODOO_DATETIME_MOMENT_FORMAT).local().format('HH:mm'), + 'num_split': tp[3], + 'amount_total': Number(tp[4]).toLocaleString(), + 'reservation_type': tp[5], + 'out_service_description': tp[6] + }; + }, + + _on_change_filter_date: function(isStartDate) { + isStartDate = isStartDate || false; + var $dateTimePickerBegin = this.renderer.$el.find('#pms-search #date_begin'); + var $dateTimePickerEnd = this.renderer.$el.find('#pms-search #date_end'); + + // FIXME: Hackish onchange ignore (Used when change dates from code) + if ($dateTimePickerBegin.data("ignore_onchange") || $dateTimePickerEnd.data("ignore_onchange")) { + $dateTimePickerBegin.data("ignore_onchange", false); + $dateTimePickerEnd.data("ignore_onchange", false) + return true; + } + + var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().set({'hour': 0, 'minute': 0, 'second': 0}).clone().utc(); + + var active_calendar = this._multi_calendar.get_active_calendar(); + if (active_calendar && date_begin) { + if (isStartDate) { + var ndate_end = date_begin.clone().add(this._view_options['days'], 'd'); + $dateTimePickerEnd.data("ignore_onchange", true); + $dateTimePickerEnd.data("DateTimePicker").date(ndate_end.local()); + } + + if (!date_begin.isSame(this.renderer._last_dates[0].clone().utc(), 'd') || !date_end.isSame(this.renderer._last_dates[1].clone().utc(), 'd')) { + var date_end = $dateTimePickerEnd.data("DateTimePicker").date().set({'hour': 23, 'minute': 59, 'second': 59}).clone().utc(); + console.log(date_end); + active_calendar.setStartDate(date_begin, active_calendar.getDateDiffDays(date_begin, date_end), false, function(){ + this._reload_active_calendar(); + }.bind(this)); + } + } + }, + _find_bootstrap_environment: function() { var envs = ['xs', 'sm', 'md', 'lg']; diff --git a/hotel_calendar/static/src/js/views/calendar/hotel_calendar_renderer.js b/hotel_calendar/static/src/js/views/calendar/hotel_calendar_renderer.js index 5a681f246..081950d49 100644 --- a/hotel_calendar/static/src/js/views/calendar/hotel_calendar_renderer.js +++ b/hotel_calendar/static/src/js/views/calendar/hotel_calendar_renderer.js @@ -51,18 +51,6 @@ var HotelCalendarView = AbstractRenderer.extend({ }, /** CUSTOM METHODS **/ - _generate_reservation_tooltip_dict: function(tp) { - return { - 'name': tp[0], - 'phone': tp[1], - 'arrival_hour': HotelCalendar.toMomentUTC(tp[2], HotelConstants.ODOO_DATETIME_MOMENT_FORMAT).local().format('HH:mm'), - 'num_split': tp[3], - 'amount_total': Number(tp[4]).toLocaleString(), - 'reservation_type': tp[5], - 'out_service_description': tp[6] - }; - }, - get_view_filter_dates: function () { var $dateTimePickerBegin = this.$el.find('#pms-search #date_begin'); var $dateTimePickerEnd = this.$el.find('#pms-search #date_end'); @@ -143,16 +131,6 @@ var HotelCalendarView = AbstractRenderer.extend({ var $dateTimePickerEnd = this.$el.find('#pms-search #date_end'); $dateTimePickerBegin.datetimepicker(DTPickerOptions); $dateTimePickerEnd.datetimepicker($.extend({}, DTPickerOptions, { 'useCurrent': false })); - $dateTimePickerBegin.on("dp.change", function (e) { - $dateTimePickerEnd.data("DateTimePicker").minDate(e.date.clone().add(3,'d')); - $dateTimePickerEnd.data("DateTimePicker").maxDate(e.date.clone().add(2,'M')); - $dateTimePickerBegin.data("DateTimePicker").hide(); - self.on_change_filter_date(true); - }); - $dateTimePickerEnd.on("dp.change", function (e) { - $dateTimePickerEnd.data("DateTimePicker").hide(); - self.on_change_filter_date(false); - }); var date_begin = moment().startOf('day'); var days = date_begin.daysInMonth(); @@ -219,32 +197,6 @@ var HotelCalendarView = AbstractRenderer.extend({ self.do_action(this.dataset.action); }); - this.$el.find("#btn_swap").on('click', function(ev){ - var hcalSwapMode = self._hcalendar.getSwapMode(); - if (hcalSwapMode === HotelCalendar.MODE.NONE) { - self._hcalendar.setSwapMode(HotelCalendar.MODE.SWAP_FROM); - $("#btn_swap span.ntext").html(_t("CONTINUE")); - $("#btn_swap").css({ - 'backgroundColor': 'rgb(145, 255, 0)', - 'fontWeight': 'bold' - }); - } else if (self._hcalendar.getReservationAction().inReservations.length > 0 && hcalSwapMode === HotelCalendar.MODE.SWAP_FROM) { - self._hcalendar.setSwapMode(HotelCalendar.MODE.SWAP_TO); - $("#btn_swap span.ntext").html(_t("END")); - $("#btn_swap").css({ - 'backgroundColor': 'orange', - 'fontWeight': 'bold' - }); - } else { - self._hcalendar.setSwapMode(HotelCalendar.MODE.NONE); - $("#btn_swap span.ntext").html(_t("START SWAP")); - $("#btn_swap").css({ - 'backgroundColor': '', - 'fontWeight': '' - }); - } - }); - return $.when( this.trigger_up('onLoadCalendarSettings'), this.trigger_up('onUpdateButtonsCounter'), @@ -262,7 +214,7 @@ var HotelCalendarView = AbstractRenderer.extend({ theme: "classic" }); $list.on('change', function(ev){ - this._apply_filters(); + this.trigger_up('onApplyFilters'); }.bind(this)); // Get Floors @@ -273,7 +225,7 @@ var HotelCalendarView = AbstractRenderer.extend({ }); $list.select2(); $list.on('change', function(ev){ - this._apply_filters(); + this.trigger_up('onApplyFilters'); }.bind(this)); // Get Amenities @@ -284,7 +236,7 @@ var HotelCalendarView = AbstractRenderer.extend({ }); $list.select2(); $list.on('change', function(ev){ - this._apply_filters(); + this.trigger_up('onApplyFilters'); }.bind(this)); // Get Virtual Rooms @@ -295,7 +247,7 @@ var HotelCalendarView = AbstractRenderer.extend({ }); $list.select2(); $list.on('change', function(ev){ - this._apply_filters(); + this.trigger_up('onApplyFilters'); }.bind(this)); }, @@ -348,94 +300,6 @@ var HotelCalendarView = AbstractRenderer.extend({ $elm.val(''); }, - - on_change_filter_date: function(isStartDate) { - isStartDate = isStartDate || false; - var $dateTimePickerBegin = this.$el.find('#pms-search #date_begin'); - var $dateTimePickerEnd = this.$el.find('#pms-search #date_end'); - - // FIXME: Hackish onchange ignore (Used when change dates from code) - if ($dateTimePickerBegin.data("ignore_onchange") || $dateTimePickerEnd.data("ignore_onchange")) { - $dateTimePickerBegin.data("ignore_onchange", false); - $dateTimePickerEnd.data("ignore_onchange", false) - return true; - } - - var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().set({'hour': 0, 'minute': 0, 'second': 0}).clone().utc(); - - if (this._hcalendar && date_begin) { - if (isStartDate) { - var ndate_end = date_begin.clone().add(this._view_options['days'], 'd'); - $dateTimePickerEnd.data("ignore_onchange", true); - $dateTimePickerEnd.data("DateTimePicker").date(ndate_end.local()); - } - - if (!date_begin.isSame(this._last_dates[0].clone().utc(), 'd') || !date_end.isSame(this._last_dates[1].clone().utc(), 'd')) { - var date_end = $dateTimePickerEnd.data("DateTimePicker").date().set({'hour': 23, 'minute': 59, 'second': 59}).clone().utc(); - this._hcalendar.setStartDate(date_begin, this._hcalendar.getDateDiffDays(date_begin, date_end), false, function(){ - this.reload_hcalendar_reservations(false); - }.bind(this)); - } - } - }, - - reload_hcalendar_reservations: function(clearReservations) { - var filterDates = this.get_view_filter_dates(); - // Clip dates - var dfrom = filterDates[0].clone(), - dto = filterDates[1].clone(); - if (filterDates[0].isBetween(this._last_dates[0], this._last_dates[1], 'days') && filterDates[1].isAfter(this._last_dates[1], 'day')) { - dfrom = this._last_dates[1].clone().local().startOf('day').utc(); - } else if (this._last_dates[0].isBetween(filterDates[0], filterDates[1], 'days') && this._last_dates[1].isAfter(filterDates[0], 'day')) { - dto = this._last_dates[0].clone().local().endOf('day').utc(); - } else { - clearReservations = true; - } - - return $.when(this.trigger_up('onReloadCalendar', { - oparams: [ - dfrom.format(HotelConstants.ODOO_DATETIME_MOMENT_FORMAT), - dto.format(HotelConstants.ODOO_DATETIME_MOMENT_FORMAT), - false, - ], - clearReservations: clearReservations, - })).then(function(){ - this._last_dates = filterDates; - }); - }, - - _apply_filters: function() { - var category = _.map(this.$el.find('#pms-search #type_list').val(), function(item){ return +item; }); - var floor = _.map(this.$el.find('#pms-search #floor_list').val(), function(item){ return +item; }); - var amenities = _.map(this.$el.find('#pms-search #amenities_list').val(), function(item){ return +item; }); - var virtual = _.map(this.$el.find('#pms-search #virtual_list').val(), function(item){ return +item; }); - var domain = []; - if (category && category.length > 0) { - domain.push(['class_name', 'in', category]); - } - if (floor && floor.length > 0) { - domain.push(['floor_id', 'in', floor]); - } - if (amenities && amenities.length > 0) { - domain.push(['amenities', 'in', amenities]); - } - if (virtual && virtual.length > 0) { - domain.push(['room_type_id', 'some', virtual]); - } - - this._hcalendar.setDomain(HotelCalendar.DOMAIN.ROOMS, domain); - }, - - _merge_days_tooltips: function(new_tooltips) { - for (var nt of new_tooltips) { - var fnt = _.find(this._days_tooltips, function(item) { return item[0] === nt[0]}); - if (fnt) { - fnt = nt; - } else { - this._days_tooltips.push(nt); - } - } - }, }); return HotelCalendarView; diff --git a/hotel_calendar/static/src/js/widgets/MultiCalendar.js b/hotel_calendar/static/src/js/widgets/MultiCalendar.js index ae32bcb2e..b355f900d 100644 --- a/hotel_calendar/static/src/js/widgets/MultiCalendar.js +++ b/hotel_calendar/static/src/js/widgets/MultiCalendar.js @@ -6,6 +6,9 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) { var core = require('web.core'); var session = require('web.session'); var Widget = require('web.Widget'); + var HotelConstants = require('hotel_calendar.Constants'); + + var QWeb = core.qweb; var MultiCalendar = Widget.extend({ _calendars: [], @@ -15,6 +18,7 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) { _dataset: {}, _base: null, + init: function(parent) { this._super.apply(this, arguments); }, @@ -38,7 +42,7 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) { }, get_active_calendar: function() { - return this._calendars[this._active_index]; + return this._calendars[this._active_index-1]; }, get_active_tab: function() { @@ -46,14 +50,23 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) { }, 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); + var active_calendar = this.get_active_calendar(); + if (active_calendar) { + setTimeout(function(calendar){ + for (var reserv of 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); + }.bind(this, active_calendar), 200); + } + }, + + remove_reservation: function(reserv_id) { + for (var calendar of this._calendars) { + calendar.removeReservation(reserv['reserv_id']); + } }, update_all_reservations: function() { @@ -64,11 +77,28 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) { update_reservations: function(calendar) { calendar.setReservations(this._dataset['reservations']); - this._assign_extra_info(calendar); + }, + + replace_reservation: function(newReserv, oldReserv) { + for (var calendar of this._calendars) { + calendar.replaceReservation(newReserv, oldReserv); + } + }, + + remove_obroom_row: function(reserv) { + for (var calendar of this._calendars) { + calendar.removeOBRoomRow(reserv); + } + }, + + swap_reservations: function(outReservs, inReservs) { + for (var calendar of this._calendars) { + calendar.swapReservations(outReservs, inReservs); + } }, set_active_calendar: function(index) { - this._tabs[index][0].tab('show'); + this._tabs[index+1][0].tab('show'); }, set_datasets: function(pricelist, restrictions, reservations) { @@ -87,6 +117,79 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) { this._base = element; }, + merge_pricelist: function(pricelist) { + var keys = _.keys(pricelist); + for (var k of keys) { + var pr = pricelist[k]; + for (var pr_k in pr) { + var pr_item = pricelist[k][pr_k]; + var pr_fk = _.findKey(this._dataset['pricelist'][k], {'room': pr_item.room}); + if (pr_fk) { + this._dataset['pricelist'][k][pr_fk].room = pr_item.room; + this._dataset['pricelist'][k][pr_fk].days = _.extend(this._dataset['pricelist'][k][pr_fk].days, pr_item.days); + if (pr_item.title) { + this._dataset['pricelist'][k][pr_fk].title = pr_item.title; + } + } else { + if (!(k in this._dataset['pricelist'])) { + this._dataset['pricelist'][k] = []; + } + this._dataset['pricelist'][k].push({ + 'room': pr_item.room, + 'days': pr_item.days, + 'title': pr_item.title + }); + } + } + } + + for (var calendar of this._calendars) { + calendar.setPricelist(this._dataset['pricelist']); + } + }, + + merge_restrictions: function(restrictions) { + var room_type_ids = Object.keys(restrictions); + for (var vid of room_type_ids) { + if (vid in this._dataset['restrictions']) { + this._dataset['restrictions'][vid] = _.extend(this._dataset['restrictions'][vid], restrictions[vid]); + } + else { + this._dataset['restrictions'][vid] = restrictions[vid]; + } + } + + for (var calendar of this._calendars) { + calendar.setRestrictions(this._dataset['restrictions']); + } + }, + + merge_reservations: function(reservations) { + for (var r of reservations) { + var rindex = _.findKey(this._dataset['reservations'], {'id': r.id}); + if (rindex) { + this._dataset['reservations'][rindex] = r; + } else { + this._dataset['reservations'].push(r); + } + } + + for (var calendar of this._calendars) { + calendar.addReservations(_.clone(this._dataset['reservations'])); + } + }, + + merge_days_tooltips: function(new_tooltips) { + for (var nt of new_tooltips) { + var fnt = _.find(this._days_tooltips, function(item) { return item[0] === nt[0]}); + if (fnt) { + fnt = nt; + } else { + this._days_tooltips.push(nt); + } + } + }, + create_calendar: function(name) { var [$tab, $panel] = this._create_tab(name, `calendar-pane-${name}`); var calendar = new HotelCalendar( @@ -96,6 +199,8 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) { this._dataset['restrictions'], this._base); this._assign_calendar_events(calendar); + this._assign_extra_info(calendar); + calendar.setReservations(_.clone(this._dataset['reservations'])); this._calendars.push(calendar); return this._calendars.length-1; }, @@ -106,6 +211,7 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) { _create_tab: function(name, id) { + var self = this; var sanitized_id = this._sanitizeId(id); // '+' Tab var $tab = $('', { @@ -114,6 +220,10 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) { text: name, role: 'tab', }).data('tabindex', this._tabs.length).appendTo($('
').prependTo(this.$tabs)); + $tab.on('shown.bs.tab', function(ev){ + self._active_index = $(ev.target).data('tabindex'); + self.recalculate_reservation_positions(); + }); $tab[0].dataset.toggle = 'tab'; var $panel = $('', { id: sanitized_id, diff --git a/hotel_calendar/static/src/lib/hcalendar/js/hcalendar.js b/hotel_calendar/static/src/lib/hcalendar/js/hcalendar.js index df82dcad6..464cc5f3e 100644 --- a/hotel_calendar/static/src/lib/hcalendar/js/hcalendar.js +++ b/hotel_calendar/static/src/lib/hcalendar/js/hcalendar.js @@ -197,9 +197,7 @@ HotelCalendar.prototype = { }, addReservations: function(/*List*/reservations, /*Bool*/forced) { - if (!reservations) { - return; - } + reservations = reservations || []; if (reservations.length > 0 && !(reservations[0] instanceof HReservation)) { console.warn("[HotelCalendar][addReservations] Invalid Reservation definition!"); @@ -207,9 +205,11 @@ HotelCalendar.prototype = { // Merge var uzr = []; for (var r of reservations) { + r = _.clone(r); // HOT-FIX: Multi-Calendar Support var rindex = !forced?_.findKey(this._reservations, {'id': r.id}):false; if (rindex) { r._html = this._reservations[rindex]._html; + r.room = this._reservations[rindex].room; if (this._reservations[rindex].overbooking && !r.overbooking) { if (this.getReservationsByRoom(this._reservations[rindex].room).length === 1) { this.removeOBRoomRow(this._reservations[rindex]); @@ -225,6 +225,7 @@ HotelCalendar.prototype = { this.createOBRoomRow(room); } if (room) { + r.room = room; this._reservations.push(r); } else { console.warn(`Can't found a room for the reservation '${r[0]}'!`); @@ -264,7 +265,7 @@ HotelCalendar.prototype = { } this._updateReservation(r); } - }.bind(this), reservations); + }.bind(this), this._reservations); _.defer(function(){ this._updateReservationOccupation(); }.bind(this)); } @@ -700,19 +701,6 @@ HotelCalendar.prototype = { this._updateRestrictions(); }, - addRestrictions: function(/*Object*/restrictions) { - var room_type_ids = Object.keys(restrictions); - for (var vid of room_type_ids) { - if (vid in this._restrictions) { - this._restrictions[vid] = _.extend(this._restrictions[vid], restrictions[vid]); - } - else { - this._restrictions[vid] = restrictions[vid]; - } - } - this._updateRestrictions(); - }, - _updateRestrictions: function() { // Clean var restDays = this.e.querySelectorAll('.hcal-restriction-room-day'); @@ -2093,34 +2081,6 @@ HotelCalendar.prototype = { this._updatePriceList(); }, - addPricelist: function(/*Dictionary*/pricelist) { - var keys = _.keys(pricelist); - for (var k of keys) { - var pr = pricelist[k]; - for (var pr_k in pr) { - var pr_item = pricelist[k][pr_k]; - var pr_fk = _.findKey(this._pricelist[k], {'room': pr_item.room}); - if (pr_fk) { - this._pricelist[k][pr_fk].room = pr_item.room; - this._pricelist[k][pr_fk].days = _.extend(this._pricelist[k][pr_fk].days, pr_item.days); - if (pr_item.title) { - this._pricelist[k][pr_fk].title = pr_item.title; - } - } else { - if (!(k in this._pricelist)) { - this._pricelist[k] = []; - } - this._pricelist[k].push({ - 'room': pr_item.room, - 'days': pr_item.days, - 'title': pr_item.title - }); - } - } - } - this._updatePriceList(); - }, - updateRoomTypePrice: function(pricelist_id, room_type_id, date, price) { var strDate = date.format(HotelCalendar.DATE_FORMAT_SHORT_); var cellId = this._sanitizeId(`CELL_PRICE_${pricelist_id}_${room_type_id}_${strDate}`); @@ -2248,8 +2208,7 @@ HotelCalendar.prototype = { _dispatchEvent: function(/*String*/eventName, /*Dictionary*/data) { this.e.dispatchEvent(new CustomEvent(eventName, { - 'detail': data, - 'calendar': this, + detail: _.extend({calendar_obj: this}, data), })); }, @@ -2753,7 +2712,7 @@ HRoom.prototype = { /** RESERVATION OBJECT **/ function HReservation(/*Dictionary*/rValues) { - if (typeof rValues.room === 'undefined') { + if (typeof rValues.room_id === 'undefined' && typeof rValues.room === 'undefined') { delete this; console.warn("[Hotel Calendar][HReservation] room can't be empty!"); return; @@ -2775,6 +2734,7 @@ function HReservation(/*Dictionary*/rValues) { this.linkedId = rValues.linkedId || -1; this.splitted = rValues.splitted || false; this.overbooking = rValues.overbooking || false; + this.room = rValues.room || null; this._drawModes = ['hard-start', 'hard-end']; this._html = false; @@ -2826,7 +2786,8 @@ HReservation.prototype = { 'unusedZone': this.unusedZone, 'linkedId': this.linkedId, 'splitted': this.splitted, - 'overbooking': this.overbooking + 'overbooking': this.overbooking, + 'room_id': this.room_id, }); nreserv._beds = _.clone(this._beds); nreserv._html = this._html;