[WIP] Multi-Calendar

This commit is contained in:
QS5ELkMu
2018-12-10 17:03:17 +01:00
parent d1d436ed04
commit faf0146b82
5 changed files with 112 additions and 85 deletions

View File

@@ -2,7 +2,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from datetime import datetime
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
from odoo import models, api
from odoo import models, api, _
from odoo.addons.hotel_calendar.controllers.bus import HOTEL_BUS_CHANNEL_ID
@@ -65,7 +65,7 @@ class BusHotelCalendar(models.TransientModel):
num_split,
vals['price'],
vals['reservation_type'] if 'reservation_type' in vals else 'normal',
vals['out_service_description'] if 'out_service_description' in vals else '',
vals['out_service_description'] if 'out_service_description' in vals else _('No reason given'),
]
}

View File

@@ -114,7 +114,7 @@ class HotelReservation(models.Model):
reserv.checkin,
num_split,
reserv.folio_id.amount_total,
reserv.reservation_type,
reserv.reservation_type or 'normal',
reserv.out_service_description or _('No reason given'),
]
})
@@ -346,8 +346,8 @@ class HotelReservation(models.Model):
'title': ntitle,
'room_id': record.room_id.id,
'reserv_id': record.id,
'partner_name': record.closure_reason_id.name or _('Out of service') if record.reservation_type == 'out'
else record.partner_id.name,
'partner_name': (record.closure_reason_id.name or _('Out of service'))
if record.reservation_type == 'out' else record.partner_id.name,
'adults': record.adults,
'children': record.children,
'checkin': record.checkin,
@@ -366,8 +366,8 @@ class HotelReservation(models.Model):
'overbooking': record.overbooking,
'price': record.folio_id.amount_total,
'reservation_type': record.reservation_type,
'closure_reason_id': record.closure_reason_id or None,
'out_service_description': record.out_service_description or _('No reason given')
'closure_reason_id': record.closure_reason_id,
'out_service_description': record.out_service_description or _('No reason given'),
})
@api.model

View File

@@ -39,9 +39,13 @@ var PMSCalendarController = AbstractController.extend({
start: function() {
this._super.apply(this, arguments);
var self = this;
this._multi_calendar.setElement(this.renderer.$el.find('#hcal_widget'));
this._multi_calendar.start();
this._multi_calendar.on('tab_changed', function(ev, active_index){
self._refresh_filters(active_index);
});
this._assign_multi_calendar_events();
this._load_calendars();
this._assign_view_events();
@@ -64,6 +68,7 @@ var PMSCalendarController = AbstractController.extend({
return this.model.update_records(ids, values).then(function(result){
// Remove OB Room Row?
if (oldReserv.room.overbooking && !newReserv.room.overbooking) {
console.log("DISPARA BORRADO!");
self._multi_calendar.remove_obroom_row(oldReserv);
}
}).fail(function(err, errev){
@@ -172,8 +177,6 @@ var PMSCalendarController = AbstractController.extend({
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;
}
var oparams = [
@@ -264,10 +267,10 @@ var PMSCalendarController = AbstractController.extend({
_assign_multi_calendar_events: function() {
var self = this;
this._multi_calendar.on('hcalOnSavePricelist', function(ev){
this._multi_calendar.on_calendar('hcalOnSavePricelist', function(ev){
self.savePricelist(ev.detail.calendar_obj, ev.detail.pricelist_id, ev.detail.pricelist);
});
this._multi_calendar.on('hcalOnMouseEnterReservation', function(ev){
this._multi_calendar.on_calendar('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);
@@ -279,7 +282,7 @@ var PMSCalendarController = AbstractController.extend({
}).tooltip('show');
}
});
this._multi_calendar.on('hcalOnClickReservation', function(ev){
this._multi_calendar.on_calendar('hcalOnClickReservation', function(ev){
//var res_id = ev.detail.reservationObj.getUserData('folio_id');
$(ev.detail.reservationDiv).tooltip('hide');
self.do_action({
@@ -301,7 +304,7 @@ var PMSCalendarController = AbstractController.extend({
// });
// });
});
this._multi_calendar.on('hcalOnSwapReservations', function(ev){
this._multi_calendar.on_calendar('hcalOnSwapReservations', function(ev){
var qdict = {};
var dialog = new Dialog(self, {
title: _t("Confirm Reservation Swap"),
@@ -355,14 +358,14 @@ var PMSCalendarController = AbstractController.extend({
$content: QWeb.render('HotelCalendar.ConfirmSwapOperation', qdict)
}).open();
});
this._multi_calendar.on('hcalOnCancelSwapReservations', function(ev){
this._multi_calendar.on_calendar('hcalOnCancelSwapReservations', function(ev){
$("#btn_swap span.ntext").html(_t("START SWAP"));
$("#btn_swap").css({
'backgroundColor': '',
'fontWeight': 'normal'
});
});
this._multi_calendar.on('hcalOnChangeReservation', function(ev){
this._multi_calendar.on_calendar('hcalOnChangeReservation', function(ev){
var newReservation = ev.detail.newReserv;
var oldReservation = ev.detail.oldReserv;
var oldPrice = ev.detail.oldPrice;
@@ -417,13 +420,13 @@ var PMSCalendarController = AbstractController.extend({
],
$content: QWeb.render('HotelCalendar.ConfirmReservationChanges', qdict)
}).open();
dialog.opened(function(e){
dialog.on('closed', this, function(e){
if (!hasChanged) {
ev.detail.calendar_obj.replaceReservation(newReservation, oldReservation);
}
});
});
this._multi_calendar.on('hcalOnUpdateSelection', function(ev){
this._multi_calendar.on_calendar('hcalOnUpdateSelection', function(ev){
for (var td of ev.detail.old_cells) {
$(td).tooltip('destroy');
}
@@ -449,7 +452,7 @@ var PMSCalendarController = AbstractController.extend({
}).tooltip('show');
}
});
this._multi_calendar.on('hcalOnChangeSelection', function(ev){
this._multi_calendar.on_calendar('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}`);
@@ -492,9 +495,9 @@ var PMSCalendarController = AbstractController.extend({
}).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');
this._multi_calendar.on_calendar('hcalOnDateChanged', function(ev){
var $dateTimePickerBegin = this.renderer.$el.find('#pms-search #date_begin');
var $dateTimePickerEnd = this.renderer.$el.find('#pms-search #date_end');
$dateTimePickerBegin.data("ignore_onchange", true);
$dateTimePickerEnd.data("DateTimePicker").minDate(false);
$dateTimePickerEnd.data("DateTimePicker").maxDate(false);
@@ -674,11 +677,11 @@ var PMSCalendarController = AbstractController.extend({
_assign_hcalendar_events: function() {
var self = this;
this._multi_calendar.on('hcalOnSavePricelist', function(ev){
this._multi_calendar.on_calendar('hcalOnSavePricelist', function(ev){
var oparams = [ev.detail.pricelist_id, false, ev.detail.pricelist, {}, {}];
self.savePricelist(ev.detail.calendar_obj, ev.detail.pricelist_id, ev.detail.pricelist);
});
this._multi_calendar.on('hcalOnMouseEnterReservation', function(ev){
this._multi_calendar.on_calendar('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);
@@ -690,7 +693,7 @@ var PMSCalendarController = AbstractController.extend({
}).tooltip('show');
}
});
this._multi_calendar.on('hcalOnClickReservation', function(ev){
this._multi_calendar.on_calendar('hcalOnClickReservation', function(ev){
//var res_id = ev.detail.reservationObj.getUserData('folio_id');
$(ev.detail.reservationDiv).tooltip('hide');
self.do_action({
@@ -712,7 +715,7 @@ var PMSCalendarController = AbstractController.extend({
// });
// });
});
this._multi_calendar.on('hcalOnSwapReservations', function(ev){
this._multi_calendar.on_calendar('hcalOnSwapReservations', function(ev){
var qdict = {};
var dialog = new Dialog(self, {
title: _t("Confirm Reservation Swap"),
@@ -766,14 +769,14 @@ var PMSCalendarController = AbstractController.extend({
$content: QWeb.render('HotelCalendar.ConfirmSwapOperation', qdict)
}).open();
});
this._multi_calendar.on('hcalOnCancelSwapReservations', function(ev){
this._multi_calendar.on_calendar('hcalOnCancelSwapReservations', function(ev){
$("#btn_swap span.ntext").html(_t("START SWAP"));
$("#btn_swap").css({
'backgroundColor': '',
'fontWeight': 'normal'
});
});
this._multi_calendar.on('hcalOnChangeReservation', function(ev){
this._multi_calendar.on_calendar('hcalOnChangeReservation', function(ev){
var newReservation = ev.detail.newReserv;
var oldReservation = ev.detail.oldReserv;
var oldPrice = ev.detail.oldPrice;
@@ -798,43 +801,43 @@ var PMSCalendarController = AbstractController.extend({
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;
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);
}
},
{
text: _t("No"),
close: true,
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;
}
],
$content: QWeb.render('HotelCalendar.ConfirmReservationChanges', qdict)
},
{
text: _t("No"),
close: true,
}
],
$content: QWeb.render('HotelCalendar.ConfirmReservationChanges', qdict)
}).open();
dialog.opened(function(e){
dialog.on('closed', this, function(e){
if (!hasChanged) {
self._multicalendar.replace_reservation(newReservation, oldReservation);
}
});
});
this._multi_calendar.on('hcalOnUpdateSelection', function(ev){
this._multi_calendar.on_calendar('hcalOnUpdateSelection', function(ev){
for (var td of ev.detail.old_cells) {
$(td).tooltip('destroy');
}
@@ -860,7 +863,7 @@ var PMSCalendarController = AbstractController.extend({
}).tooltip('show');
}
});
this._multi_calendar.on('hcalOnChangeSelection', function(ev){
this._multi_calendar.on_calendar('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}`);
@@ -903,9 +906,9 @@ var PMSCalendarController = AbstractController.extend({
}).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');
this._multi_calendar.on_calendar('hcalOnDateChanged', function(ev){
var $dateTimePickerBegin = this.renderer.$el.find('#pms-search #date_begin');
var $dateTimePickerEnd = this.renderer.$el.find('#pms-search #date_end');
$dateTimePickerBegin.data("ignore_onchange", true);
$dateTimePickerEnd.data("DateTimePicker").minDate(false);
$dateTimePickerEnd.data("DateTimePicker").maxDate(false);
@@ -950,8 +953,8 @@ var PMSCalendarController = AbstractController.extend({
$dateTimePickerEnd.data("DateTimePicker").date(ndate_end.local());
}
var date_end = $dateTimePickerEnd.data("DateTimePicker").date().set({'hour': 23, 'minute': 59, 'second': 59}).clone().utc();
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();
active_calendar.setStartDate(date_begin, active_calendar.getDateDiffDays(date_begin, date_end), false, function(){
this._reload_active_calendar();
}.bind(this));
@@ -959,6 +962,21 @@ var PMSCalendarController = AbstractController.extend({
}
},
_refresh_filters: function(active_index) {
var active_calendar = this._multi_calendar.get_calendar(active_index);
var $dateTimePickerBegin = this.$el.find('#pms-search #date_begin');
var $dateTimePickerEnd = this.$el.find('#pms-search #date_end');
var start_date = active_calendar.getOptions('startDate');
var end_date = start_date.clone().add(active_calendar.getOptions('days'), 'd');
start_date = start_date.clone().add(1, 'd');
$dateTimePickerBegin.data("ignore_onchange", true);
$dateTimePickerBegin.data("DateTimePicker").date(start_date.local());
$dateTimePickerEnd.data("ignore_onchange", true);
$dateTimePickerEnd.data("DateTimePicker").date(end_date.local());
},
_find_bootstrap_environment: function() {
var envs = ['xs', 'sm', 'md', 'lg'];

View File

@@ -29,6 +29,10 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) {
this._create_tabs_panel();
},
on: function(event_name, callback) {
this.$el.on(event_name, callback.bind(this));
},
get_calendar: function(index) {
return this._calendars[index-1];
},
@@ -64,8 +68,9 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) {
},
remove_reservation: function(reserv_id) {
this._dataset['reservations'] = _.reject(this._dataset['reservations'], {id: reserv_id});
for (var calendar of this._calendars) {
calendar.removeReservation(reserv['reserv_id']);
calendar.removeReservation(reserv_id);
}
},
@@ -195,7 +200,7 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) {
return this._calendars.length-1;
},
on: function(event_name, callback) {
on_calendar: function(event_name, callback) {
this._events[event_name] = callback;
},
@@ -219,6 +224,8 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) {
self.get_calendar(prev_index).cancelSwap();
}
}
self.$el.trigger('tab_changed', [self._active_index]);
});
$tab[0].dataset.toggle = 'tab';
var $panel = $('<div/>', {

View File

@@ -59,6 +59,7 @@ function HotelCalendar(/*String*/querySelector, /*Dictionary*/options, /*List*/p
}, options);
this.options.startDate = this.options.startDate.clone();
this.options.startDate.subtract('1', 'd');
this.options.rooms = _.map(this.options.rooms, function(item){ return item.clone(); });
// Check correct values
if (this.options.rooms.length > 0 && !(this.options.rooms[0] instanceof HRoom)) {
@@ -216,10 +217,21 @@ HotelCalendar.prototype = {
var uzr = [];
for (var r of reservations) {
r = r.clone(); // HOT-FIX: Multi-Calendar Support
r.room = this.getRoom(r.room_id, r.overbooking, r.id);
// need create a overbooking row?
if (!r.room && r.overbooking) {
r.room = this.createOBRoom(this.getRoom(r.room_id), r.id);
this.createOBRoomRow(r.room);
}
if (!r.room) {
console.warn(`Can't found a room for the reservation '${r[0]}'!`);
continue;
}
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]);
@@ -228,18 +240,7 @@ HotelCalendar.prototype = {
this._reservations[rindex] = r;
this._cleanUnusedZones(r);
} else {
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) {
r.room = room;
this._reservations.push(r);
} else {
console.warn(`Can't found a room for the reservation '${r[0]}'!`);
}
this._reservations.push(r);
}
}
@@ -304,7 +305,7 @@ HotelCalendar.prototype = {
// Remove Unused Zones
this._cleanUnusedZones(reserv);
this._reservations = _.without(this._reservations, reserv);
this._reservations = _.reject(this._reservations, {id: reserv.id});
this._updateReservationsMap();
} else {
console.warn(`[HotelCalendar][removeReservation] Can't remove '${reservation.id}' reservation!`);
@@ -615,7 +616,6 @@ HotelCalendar.prototype = {
var isfb = ob_reserv.room.number.search('/#');
var cnumber = ob_reserv.room.number;
if (isf != -1 && isfb != -1) { cnumber = cnumber.substr(isf+3, isfb-(isf+3)); }
return this.e.querySelector(`#${this._sanitizeId(`ROW_${cnumber}_${ob_reserv.room.type}_OVER${ob_reserv.id}`)}`);
},
@@ -2334,7 +2334,7 @@ HotelCalendar.prototype = {
var date_cell = HotelCalendar.toMoment(this.etable.querySelector(`#${ev.target.dataset.hcalParentCell}`).dataset.hcalDate);
var reserv;
if (this.reservationAction.reservation) {
var reserv = this.getReservation(this.reservationAction.reservation.dataset.hcalReservationObjId);
reserv = this.getReservation(this.reservationAction.reservation.dataset.hcalReservationObjId);
if (!this.reservationAction.oldReservationObj) {
this.reservationAction.oldReservationObj = reserv.clone();
this.reservationAction.daysOffset = this.getDateDiffDays(reserv.startDate.clone().local(), date_cell);
@@ -2511,6 +2511,8 @@ HotelCalendar.prototype = {
newPrice += this.getRoomPrice(newReservation.room, ndate);
}
console.log("OLLL----");
console.log(oldReservation);
this._dispatchEvent(
'hcalOnChangeReservation',
{
@@ -2701,11 +2703,11 @@ HRoom.prototype = {
clone: function() {
var nroom = new HRoom(
this.id,
this.number, // Name
this.capacity, // Capacity
this.type, // Category
this.shared, // Shared Room
this.price // Price
this.number,
this.capacity,
this.type,
this.shared,
this.price
);
nroom.overbooking = this.overbooking;
nroom._html = this._html;
@@ -2777,7 +2779,7 @@ HReservation.prototype = {
clone: function() {
var nreserv = new HReservation({
'id': this.id,
'room': this.room,
'room': this.room?this.room.clone():null,
'adults': this.adults,
'childrens': this.childrens,
'title': this.title,