[WIP] New Calendar Theme

This commit is contained in:
QS5ELkMu
2018-12-12 04:25:53 +01:00
parent 8784f982c8
commit 4091dc0522
12 changed files with 566 additions and 575 deletions

View File

@@ -133,6 +133,7 @@ class HotelReservation(models.Model):
'name': room.name, 'name': room.name,
'capacity': room.capacity, 'capacity': room.capacity,
'class_name': room.room_type_id.class_id.name, 'class_name': room.room_type_id.class_id.name,
'class_id': room.room_type_id.class_id.id,
'shared': room.shared_room, 'shared': room.shared_room,
'price': room.room_type_id 'price': room.room_type_id
and ['pricelist', room.room_type_id.id, pricelist_id, and ['pricelist', room.room_type_id.id, pricelist_id,
@@ -151,6 +152,10 @@ class HotelReservation(models.Model):
json_calendars.append({ json_calendars.append({
'id': calendar.id, 'id': calendar.id,
'name': calendar.name, 'name': calendar.name,
'segmentation_ids': calendar.segmentation_ids.ids,
'location_ids': calendar.location_ids.ids,
'amenity_ids': calendar.amenity_ids.ids,
'room_type_ids': calendar.room_type_ids.ids,
}) })
return json_calendars return json_calendars

View File

@@ -18,53 +18,89 @@
#pms-menu { #pms-menu {
padding: 0 0.2em !important; padding: 0 0.2em !important;
} }
#pms-menu .input-group span, #pms-menu input {
border-radius: 0;
}
#pms-menu button { #pms-menu button {
min-height: 45px; border-radius: 0;
margin: 0.2em 0; border: 1px solid lightgray;
font-size: x-small;
} }
#pms-search { button .led {
padding: 0.5em !important; position: absolute;
background-color: white;
box-shadow: 10px 1px 12px #333;
}
#pms-search fieldset {
display: inline-block; display: inline-block;
right: 5px;
top: -1px;
width: 8px;
height: 8px;
border: 1px solid lightgray;
border-top-width: 0;
border-top-right-radius: 0;
border-top-left-radius: 0;
transition: all 0.5s ease;
} }
#pms-search fieldset legend { button .led-disabled {
font-size: initial !important; background-color: dimgrey;
margin: initial !important;
} }
#pms-search .list { button .led-enabled {
overflow-y: auto; background-color: khaki;
box-shadow: 0 0 8px 0px khaki;
}
button .led-green {
background-color: chartreuse;
box-shadow: 0 0 8px 0px chartreuse;
}
button .led-blue {
background-color: cornflowerblue;
box-shadow: 0 0 8px 0px cornflowerblue;
}
input#bookings_search {
border-top-left-radius: 0;
border-top-right-radius: 0;
border: 1px solid lightgray;
}
#pms-menu .menu-date-box {
margin-top: 2px !important;
}
#pms-menu .menu-button-box, #pms-menu .menu-search-box, #pms-menu .menu-filter-box {
margin-top: 2em !important;
}
#pms-menu .menu-filter-box .filter-record {
margin-top: 1em;
}
#pms-menu .button-box {
text-align: left; text-align: left;
} min-height: 3.5em;
#pms-search label { padding: 3px;
font-size: 12px; transition: all 0.5s ease;
} }
#pms-search-table > tbody > tr > td { .button-highlight {
background-color: white; background-color: orange;
padding: 0.1em; color: white;
border: 1px solid #efefef;
border-width: 0 2px;
vertical-align: middle;
text-align: center;
} }
#pms-search-table > tbody > tr > td:first-child { .button-highlight i {
border-width: 0 2px 0 0; color: white;
}
#pms-search-table > tbody > tr > td:last-child {
border-width: 0 0 0 2px;
} }
#pms-search-cal-pag .btn { .multi-calendar-tab-plus {
background-color: transparent; background-color: darkgray;
padding: 0.1em; font-weight: bold;
color: white;
} }
.input-group { #pms-menu div[id^=btn_] {
padding: 0.1em; padding: 2px;
} }
.warn-message { .warn-message {
@@ -75,29 +111,33 @@
} }
/** SELECT 2 **/ /** SELECT 2 **/
#pms-search .select2-search-choice { #pms-menu .select2-container {
padding-top: 1px !important; border-radius: 0;
padding-bottom: 1px !important;
font-size: 10px !important;
} }
#pms-search .select2-search-choice-close {
top: 1px !important;
}
/** BOOTSTRAP **/ /** BOOTSTRAP **/
.badge-danger { .badge-danger {
background-color: #d34f2a !important; background-color: #d34f2a !important;
} }
/** FONT AWESOME **/
.cloud-text {
margin-top: .12em;
font-size: 26px;
font-family: sans-serif;
font-weight: bold;
}
/** ODOO **/ /** ODOO **/
.o_chat_window { .o_chat_window {
z-index: 8 !important; z-index: 8 !important;
} }
.o_button_icon {
display: inline-block;
width: 37px;
padding: 0px 3px;
text-align: center;
vertical-align: middle;
color: #7C7BAD;
font-size: 24px;
}
.o_button_text {
display: inline-block;
vertical-align: middle;
max-width: 70%;
line-height: 1.2;
text-align: left;
}

View File

@@ -44,7 +44,9 @@ var PMSCalendarController = AbstractController.extend({
this._multi_calendar.setElement(this.renderer.$el.find('#hcal_widget')); this._multi_calendar.setElement(this.renderer.$el.find('#hcal_widget'));
this._multi_calendar.start(); this._multi_calendar.start();
this._multi_calendar.on('tab_changed', function(ev, active_index){ this._multi_calendar.on('tab_changed', function(ev, active_index){
self._refresh_filters(active_index); if (active_index) {
self._refresh_filters(active_index);
}
}); });
this._assign_multi_calendar_events(); this._assign_multi_calendar_events();
this._load_calendars(); this._load_calendars();
@@ -110,7 +112,7 @@ var PMSCalendarController = AbstractController.extend({
'room_type_id': r['room_type_id'], 'room_type_id': r['room_type_id'],
'floor_id': r['floor_id'], 'floor_id': r['floor_id'],
'amenities': r['amenity_ids'], 'amenities': r['amenity_ids'],
'class_name': r['class_name'] 'class_id': r['class_id'],
}); });
rooms.push(nroom); rooms.push(nroom);
} }
@@ -159,13 +161,33 @@ var PMSCalendarController = AbstractController.extend({
self._multi_calendar.set_datasets(results['pricelist'], results['restrictions'], reservs); self._multi_calendar.set_datasets(results['pricelist'], results['restrictions'], reservs);
self._multi_calendar.set_base_element(self.renderer.$el[0]); self._multi_calendar.set_base_element(self.renderer.$el[0]);
for (var calendar of results['calendars']) { for (var calendar_record of results['calendars']) {
self._multi_calendar.create_calendar(calendar['name']); var calendar_index = self._multi_calendar.create_calendar(calendar_record);
var domain = self._generate_calendar_filters_domain(calendar_record);
var calendar = self._multi_calendar.get_calendar(calendar_index+1);
calendar.setDomain(HotelCalendar.DOMAIN.ROOMS, domain);
} }
self._multi_calendar.set_active_calendar(self._multi_calendar._calendars.length-1); self._multi_calendar.set_active_calendar(self._multi_calendar._calendars.length-1);
}); });
}, },
_generate_calendar_filters_domain: function(calendar) {
var domain = [];
if (calendar['segmentation_ids'] && calendar['segmentation_ids'].length > 0) {
domain.push(['class_id', 'in', calendar['segmentation_ids']]);
}
if (calendar['location_ids'] && calendar['location_ids'].length > 0) {
domain.push(['floor_id', 'in', calendar['location_ids']]);
}
if (calendar['amenity_ids'] && calendar['amenity_ids'].length > 0) {
domain.push(['amenities', 'in', calendar['amenity_ids']]);
}
if (calendar['room_type_ids'] && calendar['room_type_ids'].length > 0) {
domain.push(['room_type_id', 'some', calendar['room_type_ids']]);
}
return domain;
},
_reload_active_calendar: function() { _reload_active_calendar: function() {
var self = this; var self = this;
var filterDates = this.renderer.get_view_filter_dates(); var filterDates = this.renderer.get_view_filter_dates();
@@ -223,8 +245,8 @@ var PMSCalendarController = AbstractController.extend({
_assign_view_events: function() { _assign_view_events: function() {
var self = this; var self = this;
var $dateTimePickerBegin = this.renderer.$el.find('#pms-search #date_begin'); var $dateTimePickerBegin = this.renderer.$el.find('#pms-menu #date_begin');
var $dateTimePickerEnd = this.renderer.$el.find('#pms-search #date_end'); var $dateTimePickerEnd = this.renderer.$el.find('#pms-menu #date_end');
$dateTimePickerBegin.on("dp.change", function (e) { $dateTimePickerBegin.on("dp.change", function (e) {
$dateTimePickerEnd.data("DateTimePicker").minDate(e.date.clone().add(3,'d')); $dateTimePickerEnd.data("DateTimePicker").minDate(e.date.clone().add(3,'d'));
$dateTimePickerEnd.data("DateTimePicker").maxDate(e.date.clone().add(2,'M')); $dateTimePickerEnd.data("DateTimePicker").maxDate(e.date.clone().add(2,'M'));
@@ -236,32 +258,75 @@ var PMSCalendarController = AbstractController.extend({
self._on_change_filter_date(false); self._on_change_filter_date(false);
}); });
this.renderer.$el.find("#btn_swap").on('click', function(ev){ this.renderer.$el.find("#btn_swap button").on('click', function(ev){
var active_calendar = self._multi_calendar.get_active_calendar(); var active_calendar = self._multi_calendar.get_active_calendar();
var hcalSwapMode = active_calendar.getSwapMode(); var hcalSwapMode = active_calendar.getSwapMode();
var $led = $(this).find('.led');
if (hcalSwapMode === HotelCalendar.MODE.NONE) { if (hcalSwapMode === HotelCalendar.MODE.NONE) {
active_calendar.setSwapMode(HotelCalendar.MODE.SWAP_FROM); active_calendar.setSwapMode(HotelCalendar.MODE.SWAP_FROM);
$("#btn_swap span.ntext").html(_t("CONTINUE")); $("#btn_swap span.ntext").html(_t("Continue"));
$("#btn_swap").css({ $led.removeClass('led-disabled');
'backgroundColor': 'rgb(145, 255, 0)', $led.addClass('led-green');
'fontWeight': 'bold'
});
} else if (active_calendar.getReservationAction().inReservations.length > 0 && hcalSwapMode === HotelCalendar.MODE.SWAP_FROM) { } else if (active_calendar.getReservationAction().inReservations.length > 0 && hcalSwapMode === HotelCalendar.MODE.SWAP_FROM) {
active_calendar.setSwapMode(HotelCalendar.MODE.SWAP_TO); active_calendar.setSwapMode(HotelCalendar.MODE.SWAP_TO);
$("#btn_swap span.ntext").html(_t("END")); $("#btn_swap span.ntext").html(_t("End"));
$("#btn_swap").css({ $led.removeClass('led-green');
'backgroundColor': 'orange', $led.addClass('led-blue');
'fontWeight': 'bold'
});
} else { } else {
active_calendar.setSwapMode(HotelCalendar.MODE.NONE); active_calendar.setSwapMode(HotelCalendar.MODE.NONE);
$("#btn_swap span.ntext").html(_t("START SWAP")); $("#btn_swap span.ntext").html(_t("Start Swap"));
$("#btn_swap").css({ $led.removeClass('led-blue');
'backgroundColor': '', $led.addClass('led-disabled');
'fontWeight': ''
});
} }
}); });
this.renderer.$el.find('#pms-menu #btn_action_overbooking button').on('click', function(ev){
var active_calendar = self._multi_calendar.get_active_calendar();
active_calendar.toggleOverbookingsVisibility();
active_calendar.addReservations(self._multi_calendar._dataset['reservations']);
if (active_calendar.options.showOverbookings) {
$(this).find('.led').removeClass('led-disabled');
$(this).find('.led').addClass('led-enabled');
} else {
$(this).find('.led').addClass('led-disabled');
$(this).find('.led').removeClass('led-enabled');
}
});
this.renderer.$el.find('#pms-menu #btn_action_cancelled button').on('click', function(ev){
var active_calendar = self._multi_calendar.get_active_calendar();
active_calendar.toggleCancelledVisibility();
active_calendar.addReservations(self._multi_calendar._dataset['reservations']);
});
this.renderer.$el.find('#pms-menu #btn_save_calendar_record').on('click', function(ev){
var active_calendar_record = self._multi_calendar.get_calendar_record(self._multi_calendar.get_active_index());
active_calendar_record.name = "LOLO";
var name = self.renderer.$el.find('#pms-menu #calendar_name').val();
var category = _.map(self.renderer.$el.find('#pms-menu #type_list').val(), function(item){ return +item; });
var floor = _.map(self.renderer.$el.find('#pms-menu #floor_list').val(), function(item){ return +item; });
var amenities = _.map(self.renderer.$el.find('#pms-menu #amenities_list').val(), function(item){ return +item; });
var types = _.map(self.renderer.$el.find('#pms-menu #virtual_list').val(), function(item){ return +item; });
var oparams = {
'name': name,
'segmentation_ids': [[6, false, category]],
'location_ids': [[6, false, floor]],
'amenity_ids': [[6, false, amenities]],
'room_type_ids': [[6, false, types]],
}
self._multi_calendar.update_active_tab_name(name);
self.model.update_or_create_calendar_record(active_calendar_record['id'], oparams).then(function(){
active_calendar_record.name = name;
active_calendar_record.segmentation_ids = category;
active_calendar_record.location_ids = floor;
active_calendar_record.amenity_ids = amenities;
active_calendar_record.room_type_ids = types;
}).fail(function(){
self._multi_calendar.update_active_tab_name(active_calendar_record.name);
});
});
}, },
_assign_multi_calendar_events: function() { _assign_multi_calendar_events: function() {
@@ -358,11 +423,9 @@ var PMSCalendarController = AbstractController.extend({
}).open(); }).open();
}); });
this._multi_calendar.on_calendar('hcalOnCancelSwapReservations', function(ev){ this._multi_calendar.on_calendar('hcalOnCancelSwapReservations', function(ev){
$("#btn_swap span.ntext").html(_t("START SWAP")); $("#btn_swap span.ntext").html(_t("Start Swap"));
$("#btn_swap").css({ var $led = $("#btn_swap").find('.led');
'backgroundColor': '', $led.removeClass('led-blue').removeClass('led-green').addClass('led-disabled');
'fontWeight': 'normal'
});
}); });
this._multi_calendar.on_calendar('hcalOnChangeReservation', function(ev){ this._multi_calendar.on_calendar('hcalOnChangeReservation', function(ev){
var newReservation = ev.detail.newReserv; var newReservation = ev.detail.newReserv;
@@ -429,10 +492,10 @@ var PMSCalendarController = AbstractController.extend({
for (var td of ev.detail.old_cells) { for (var td of ev.detail.old_cells) {
$(td).tooltip('destroy'); $(td).tooltip('destroy');
} }
if (ev.detail.cells.length > 1) { if (ev.detail.cells.length) {
var last_cell = ev.detail.cells[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_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 date_cell_end = HotelCalendar.toMoment(ev.detail.calendar_obj.etable.querySelector(`#${last_cell.dataset.hcalParentCell}`).dataset.hcalDate).add(1, 'd');
var parentRow = document.querySelector(`#${ev.detail.cells[0].dataset.hcalParentRow}`); var parentRow = document.querySelector(`#${ev.detail.cells[0].dataset.hcalParentRow}`);
var room = ev.detail.calendar_obj.getRoom(parentRow.dataset.hcalRoomObjId); var room = ev.detail.calendar_obj.getRoom(parentRow.dataset.hcalRoomObjId);
if (room.overbooking) { if (room.overbooking) {
@@ -456,7 +519,7 @@ var PMSCalendarController = AbstractController.extend({
var parentCellStart = document.querySelector(`#${ev.detail.cellStart.dataset.hcalParentCell}`); var parentCellStart = document.querySelector(`#${ev.detail.cellStart.dataset.hcalParentCell}`);
var parentCellEnd = document.querySelector(`#${ev.detail.cellEnd.dataset.hcalParentCell}`); var parentCellEnd = document.querySelector(`#${ev.detail.cellEnd.dataset.hcalParentCell}`);
var startDate = HotelCalendar.toMoment(parentCellStart.dataset.hcalDate); var startDate = HotelCalendar.toMoment(parentCellStart.dataset.hcalDate);
var endDate = HotelCalendar.toMoment(parentCellEnd.dataset.hcalDate); var endDate = HotelCalendar.toMoment(parentCellEnd.dataset.hcalDate).add(1, 'd');
var room = ev.detail.calendar_obj.getRoom(parentRow.dataset.hcalRoomObjId); var room = ev.detail.calendar_obj.getRoom(parentRow.dataset.hcalRoomObjId);
if (room.overbooking) { if (room.overbooking) {
return; return;
@@ -495,8 +558,8 @@ var PMSCalendarController = AbstractController.extend({
}); });
this._multi_calendar.on_calendar('hcalOnDateChanged', function(ev){ this._multi_calendar.on_calendar('hcalOnDateChanged', function(ev){
var $dateTimePickerBegin = this.renderer.$el.find('#pms-search #date_begin'); var $dateTimePickerBegin = this.renderer.$el.find('#pms-menu #date_begin');
var $dateTimePickerEnd = this.renderer.$el.find('#pms-search #date_end'); var $dateTimePickerEnd = this.renderer.$el.find('#pms-menu #date_end');
$dateTimePickerBegin.data("ignore_onchange", true); $dateTimePickerBegin.data("ignore_onchange", true);
$dateTimePickerEnd.data("DateTimePicker").minDate(false); $dateTimePickerEnd.data("DateTimePicker").minDate(false);
$dateTimePickerEnd.data("DateTimePicker").maxDate(false); $dateTimePickerEnd.data("DateTimePicker").maxDate(false);
@@ -653,13 +716,13 @@ var PMSCalendarController = AbstractController.extend({
}, },
_onApplyFilters: function() { _onApplyFilters: function() {
var category = _.map(this.renderer.$el.find('#pms-search #type_list').val(), function(item){ return +item; }); var category = _.map(this.renderer.$el.find('#pms-menu #type_list').val(), function(item){ return +item; });
var floor = _.map(this.renderer.$el.find('#pms-search #floor_list').val(), function(item){ return +item; }); var floor = _.map(this.renderer.$el.find('#pms-menu #floor_list').val(), function(item){ return +item; });
var amenities = _.map(this.renderer.$el.find('#pms-search #amenities_list').val(), function(item){ return +item; }); var amenities = _.map(this.renderer.$el.find('#pms-menu #amenities_list').val(), function(item){ return +item; });
var virtual = _.map(this.renderer.$el.find('#pms-search #virtual_list').val(), function(item){ return +item; }); var virtual = _.map(this.renderer.$el.find('#pms-menu #virtual_list').val(), function(item){ return +item; });
var domain = []; var domain = [];
if (category && category.length > 0) { if (category && category.length > 0) {
domain.push(['class_name', 'in', category]); domain.push(['class_id', 'in', category]);
} }
if (floor && floor.length > 0) { if (floor && floor.length > 0) {
domain.push(['floor_id', 'in', floor]); domain.push(['floor_id', 'in', floor]);
@@ -670,254 +733,9 @@ var PMSCalendarController = AbstractController.extend({
if (virtual && virtual.length > 0) { if (virtual && virtual.length > 0) {
domain.push(['room_type_id', 'some', virtual]); domain.push(['room_type_id', 'some', virtual]);
} }
this._multi_calendar.get_active_calendar().setDomain(HotelCalendar.DOMAIN.ROOMS, domain); this._multi_calendar.get_active_calendar().setDomain(HotelCalendar.DOMAIN.ROOMS, domain);
}, },
_assign_hcalendar_events: function() {
var self = this;
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_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);
$(ev.detail.reservationDiv).tooltip('destroy').tooltip({
animation: false,
html: true,
placement: 'bottom',
title: QWeb.render('HotelCalendar.TooltipReservation', qdict)
}).tooltip('show');
}
});
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({
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_calendar('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_calendar('hcalOnCancelSwapReservations', function(ev){
$("#btn_swap span.ntext").html(_t("START SWAP"));
$("#btn_swap").css({
'backgroundColor': '',
'fontWeight': 'normal'
});
});
this._multi_calendar.on_calendar('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.on('closed', this, function(e){
if (!hasChanged) {
self._multicalendar.replace_reservation(newReservation, oldReservation);
}
});
});
this._multi_calendar.on_calendar('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_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}`);
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_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);
$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));
},
_generate_reservation_tooltip_dict: function(tp) { _generate_reservation_tooltip_dict: function(tp) {
return { return {
'name': tp[0], 'name': tp[0],
@@ -932,8 +750,8 @@ var PMSCalendarController = AbstractController.extend({
_on_change_filter_date: function(isStartDate) { _on_change_filter_date: function(isStartDate) {
isStartDate = isStartDate || false; isStartDate = isStartDate || false;
var $dateTimePickerBegin = this.renderer.$el.find('#pms-search #date_begin'); var $dateTimePickerBegin = this.renderer.$el.find('#pms-menu #date_begin');
var $dateTimePickerEnd = this.renderer.$el.find('#pms-search #date_end'); var $dateTimePickerEnd = this.renderer.$el.find('#pms-menu #date_end');
// FIXME: Hackish onchange ignore (Used when change dates from code) // FIXME: Hackish onchange ignore (Used when change dates from code)
if ($dateTimePickerBegin.data("ignore_onchange") || $dateTimePickerEnd.data("ignore_onchange")) { if ($dateTimePickerBegin.data("ignore_onchange") || $dateTimePickerEnd.data("ignore_onchange")) {
@@ -963,8 +781,10 @@ var PMSCalendarController = AbstractController.extend({
_refresh_filters: function(active_index) { _refresh_filters: function(active_index) {
var active_calendar = this._multi_calendar.get_calendar(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'); /* Dates */
var $dateTimePickerBegin = this.renderer.$el.find('#pms-menu #date_begin');
var $dateTimePickerEnd = this.renderer.$el.find('#pms-menu #date_end');
var start_date = active_calendar.getOptions('startDate'); var start_date = active_calendar.getOptions('startDate');
var end_date = start_date.clone().add(active_calendar.getOptions('days'), 'd'); var end_date = start_date.clone().add(active_calendar.getOptions('days'), 'd');
@@ -974,6 +794,34 @@ var PMSCalendarController = AbstractController.extend({
$dateTimePickerBegin.data("DateTimePicker").date(start_date.local()); $dateTimePickerBegin.data("DateTimePicker").date(start_date.local());
$dateTimePickerEnd.data("ignore_onchange", true); $dateTimePickerEnd.data("ignore_onchange", true);
$dateTimePickerEnd.data("DateTimePicker").date(end_date.local()); $dateTimePickerEnd.data("DateTimePicker").date(end_date.local());
/* Overbooking Led */
var $led = this.renderer.$el.find('#pms-menu #btn_action_overbooking button .led');
if (active_calendar.options.showOverbookings) {
$led.removeClass('led-disabled').addClass('led-enabled');
} else {
$led.removeClass('led-enabled').addClass('led-disabled');
}
/* Calendar Record */
var active_calendar_record = this._multi_calendar.get_calendar_record(active_index);
var $calendar_name = this.renderer.$el.find('#pms-menu .menu-filter-box #calendar_name');
$calendar_name.val(active_calendar_record['name']);
/* Calendar Filters */
var active_filters = this._multi_calendar.get_active_filters();
var $segmentation = this.renderer.$el.find('#pms-menu #type_list');
var $location = this.renderer.$el.find('#pms-menu #floor_list');
var $amenities = this.renderer.$el.find('#pms-menu #amenities_list');
var $types = this.renderer.$el.find('#pms-menu #virtual_list');
$segmentation.val(active_filters['class_id']);
$segmentation.trigger('change');
$location.val(active_filters['floor_id']);
$location.trigger('change');
$amenities.val(active_filters['amenities']);
$amenities.trigger('change');
$types.val(active_filters['room_type_id']);
$types.trigger('change');
}, },
_find_bootstrap_environment: function() { _find_bootstrap_environment: function() {

View File

@@ -106,6 +106,23 @@ return AbstractModel.extend({
}); });
}, },
update_or_create_calendar_record: function(ids, vals) {
if (!ids) {
return this._rpc({
model: 'hotel.calendar',
method: 'create',
args: [vals],
context: Session.user_context,
});
}
return this._rpc({
model: 'hotel.calendar',
method: 'write',
args: [ids, vals],
context: Session.user_context,
});
},
folio_search_count: function(domain) { folio_search_count: function(domain) {
return this._rpc({ return this._rpc({
model: 'hotel.folio', model: 'hotel.folio',

View File

@@ -52,8 +52,8 @@ var HotelCalendarView = AbstractRenderer.extend({
/** CUSTOM METHODS **/ /** CUSTOM METHODS **/
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-menu #date_begin');
var $dateTimePickerEnd = this.$el.find('#pms-search #date_end'); var $dateTimePickerEnd = this.$el.find('#pms-menu #date_end');
var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().set({'hour': 0, 'minute': 0, 'second': 0}).clone().utc(); var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().set({'hour': 0, 'minute': 0, 'second': 0}).clone().utc();
var date_end = $dateTimePickerEnd.data("DateTimePicker").date().set({'hour': 23, 'minute': 59, 'second': 59}).clone().utc(); var date_end = $dateTimePickerEnd.data("DateTimePicker").date().set({'hour': 23, 'minute': 59, 'second': 59}).clone().utc();
@@ -65,8 +65,8 @@ var HotelCalendarView = AbstractRenderer.extend({
this._view_options = options; this._view_options = options;
var date_begin = moment().startOf('day'); var date_begin = moment().startOf('day');
var date_end = date_begin.clone().add(this._view_options['days'], 'd').endOf('day'); var date_end = date_begin.clone().add(this._view_options['days'], 'd').endOf('day');
var $dateTimePickerBegin = this.$el.find('#pms-search #date_begin'); var $dateTimePickerBegin = this.$el.find('#pms-menu #date_begin');
var $dateTimePickerEnd = this.$el.find('#pms-search #date_end'); var $dateTimePickerEnd = this.$el.find('#pms-menu #date_end');
//$dateTimePickerBegin.data("ignore_onchange", true); //$dateTimePickerBegin.data("ignore_onchange", true);
$dateTimePickerBegin.data("DateTimePicker").date(date_begin); $dateTimePickerBegin.data("DateTimePicker").date(date_begin);
//$dateTimePickerEnd.data("ignore_onchange", true); //$dateTimePickerEnd.data("ignore_onchange", true);
@@ -77,36 +77,30 @@ var HotelCalendarView = AbstractRenderer.extend({
update_buttons_counter: function(ncheckouts, ncheckins, noverbookings) { update_buttons_counter: function(ncheckouts, ncheckins, noverbookings) {
var self = this; var self = this;
// Checkouts Button // Checkouts Button
var $ninfo = self.$el.find('#pms-menu #btn_action_checkout div.ninfo'); var $ninfo = self.$el.find('#pms-menu #btn_action_checkout span.ninfo');
var $badge_checkout = $ninfo.find('.badge'); $ninfo.text(ncheckouts);
if (ncheckouts > 0) { if (ncheckouts) {
$badge_checkout.text(ncheckouts); $ninfo.parent().parent().addClass('button-highlight');
$badge_checkout.parent().show();
$ninfo.show();
} else { } else {
$ninfo.hide(); $ninfo.parent().parent().removeClass('button-highlight');
} }
// Checkins Button // Checkins Button
$ninfo = self.$el.find('#pms-menu #btn_action_checkin div.ninfo'); $ninfo = self.$el.find('#pms-menu #btn_action_checkin span.ninfo');
var $badge_checkin = $ninfo.find('.badge'); $ninfo.text(ncheckins);
if (ncheckins > 0) { if (ncheckins) {
$badge_checkin.text(ncheckins); $ninfo.parent().parent().addClass('button-highlight');
$badge_checkin.parent().show();
$ninfo.show();
} else { } else {
$ninfo.hide(); $ninfo.parent().parent().removeClass('button-highlight');
} }
// OverBookings // OverBookings
$ninfo = self.$el.find('#pms-menu #btn_swap div.ninfo'); $ninfo = self.$el.find('#pms-menu #btn_action_overbooking span.ninfo');
var $badge_swap = $ninfo.find('.badge'); $ninfo.text(noverbookings);
if (noverbookings > 0) { if (noverbookings) {
$badge_swap.text(noverbookings); $ninfo.parent().parent().addClass('button-highlight');
$badge_swap.parent().show();
$ninfo.show();
} else { } else {
$ninfo.hide(); $ninfo.parent().parent().removeClass('button-highlight');
} }
}, },
@@ -127,8 +121,8 @@ var HotelCalendarView = AbstractRenderer.extend({
locale : moment.locale(), locale : moment.locale(),
format : HotelConstants.L10N_DATE_MOMENT_FORMAT, format : HotelConstants.L10N_DATE_MOMENT_FORMAT,
}; };
var $dateTimePickerBegin = this.$el.find('#pms-search #date_begin'); var $dateTimePickerBegin = this.$el.find('#pms-menu #date_begin');
var $dateTimePickerEnd = this.$el.find('#pms-search #date_end'); var $dateTimePickerEnd = this.$el.find('#pms-menu #date_end');
$dateTimePickerBegin.datetimepicker(DTPickerOptions); $dateTimePickerBegin.datetimepicker(DTPickerOptions);
$dateTimePickerEnd.datetimepicker($.extend({}, DTPickerOptions, { 'useCurrent': false })); $dateTimePickerEnd.datetimepicker($.extend({}, DTPickerOptions, { 'useCurrent': false }));
@@ -140,21 +134,6 @@ var HotelCalendarView = AbstractRenderer.extend({
$dateTimePickerEnd.data("DateTimePicker").date(date_end); $dateTimePickerEnd.data("DateTimePicker").date(date_end);
this._last_dates = this.get_view_filter_dates(); this._last_dates = this.get_view_filter_dates();
// Initial State
var $pms_search = this.$el.find('#pms-search');
$pms_search.css({
'top': `-100%`,
'opacity': 0.0,
});
// Show search (Alt+S)
$(document).keydown(function(ev){
if (ev.altKey){
if (ev.key == 'x' || ev.key == 'X'){
self.toggle_pms_search();
}
}
});
/* TOUCH EVENTS */ /* TOUCH EVENTS */
this.$el.on('touchstart', function(ev){ this.$el.on('touchstart', function(ev){
var orgEvent = ev.originalEvent; var orgEvent = ev.originalEvent;
@@ -185,13 +164,19 @@ var HotelCalendarView = AbstractRenderer.extend({
/* BUTTONS */ /* BUTTONS */
var $button = this.$el.find('#pms-menu #btn_action_bookings'); var $button = this.$el.find('#pms-menu #btn_action_bookings');
$button.on('click', function(ev){ self._open_bookings_tree(); }); $button.on('click', function(ev){ self._open_search_tree('book'); });
var $btnInput = this.$el.find('#pms-menu #bookings_search'); $button = this.$el.find('#pms-menu #btn_action_checkins');
$btnInput.on('keypress', function(ev){ $button.on('click', function(ev){ self._open_search_tree('checkin'); });
if (ev.keyCode === 13) { $button = this.$el.find('#pms-menu #btn_action_invoices');
self._open_bookings_tree(); $button.on('click', function(ev){ self._open_search_tree('invoice'); });
} $button = this.$el.find('#pms-menu #btn_action_folios');
}); $button.on('click', function(ev){ self._open_search_tree('folio'); });
// $button = this.$el.find('#pms-menu #bookings_search');
// $button.on('keypress', function(ev){
// if (ev.keyCode === 13) {
// self._open_bookings_tree();
// }
// });
this.$el.find("button[data-action]").on('click', function(ev){ this.$el.find("button[data-action]").on('click', function(ev){
self.do_action(this.dataset.action); self.do_action(this.dataset.action);
@@ -205,7 +190,7 @@ var HotelCalendarView = AbstractRenderer.extend({
}, },
loadViewFilters: function(resultsHotelRoomType, resultsHotelFloor, resultsHotelRoomAmenities, resultsHotelVirtualRooms) { loadViewFilters: function(resultsHotelRoomType, resultsHotelFloor, resultsHotelRoomAmenities, resultsHotelVirtualRooms) {
var $list = this.$el.find('#pms-search #type_list'); var $list = this.$el.find('#pms-menu #type_list');
$list.html(''); $list.html('');
resultsHotelRoomType.forEach(function(item, index){ resultsHotelRoomType.forEach(function(item, index){
$list.append(`<option value="${item.id}">${item.name}</option>`); $list.append(`<option value="${item.id}">${item.name}</option>`);
@@ -218,7 +203,7 @@ var HotelCalendarView = AbstractRenderer.extend({
}.bind(this)); }.bind(this));
// Get Floors // Get Floors
$list = this.$el.find('#pms-search #floor_list'); $list = this.$el.find('#pms-menu #floor_list');
$list.html(''); $list.html('');
resultsHotelFloor.forEach(function(item, index){ resultsHotelFloor.forEach(function(item, index){
$list.append(`<option value="${item.id}">${item.name}</option>`); $list.append(`<option value="${item.id}">${item.name}</option>`);
@@ -229,7 +214,7 @@ var HotelCalendarView = AbstractRenderer.extend({
}.bind(this)); }.bind(this));
// Get Amenities // Get Amenities
$list = this.$el.find('#pms-search #amenities_list'); $list = this.$el.find('#pms-menu #amenities_list');
$list.html(''); $list.html('');
resultsHotelRoomAmenities.forEach(function(item, index){ resultsHotelRoomAmenities.forEach(function(item, index){
$list.append(`<option value="${item.id}">${item.name}</option>`); $list.append(`<option value="${item.id}">${item.name}</option>`);
@@ -240,7 +225,7 @@ var HotelCalendarView = AbstractRenderer.extend({
}.bind(this)); }.bind(this));
// Get Virtual Rooms // Get Virtual Rooms
$list = this.$el.find('#pms-search #virtual_list'); $list = this.$el.find('#pms-menu #virtual_list');
$list.html(''); $list.html('');
resultsHotelVirtualRooms.forEach(function(item, index){ resultsHotelVirtualRooms.forEach(function(item, index){
$list.append(`<option value="${item.id}">${item.name}</option>`); $list.append(`<option value="${item.id}">${item.name}</option>`);
@@ -252,7 +237,7 @@ var HotelCalendarView = AbstractRenderer.extend({
}, },
toggle_pms_search: function() { toggle_pms_search: function() {
var $pms_search = this.$el.find('#pms-search'); var $pms_search = this.$el.find('#pms-menu');
if ($pms_search.position().top < 0) if ($pms_search.position().top < 0)
{ {
var $navbar = $('.navbar'); var $navbar = $('.navbar');
@@ -269,7 +254,7 @@ var HotelCalendarView = AbstractRenderer.extend({
} }
}, },
_generate_bookings_domain: function(tsearch) { _generate_search_domain: function(tsearch) {
var domain = []; var domain = [];
domain.push('|', '|', '|', '|', domain.push('|', '|', '|', '|',
['partner_id.name', 'ilike', tsearch], ['partner_id.name', 'ilike', tsearch],
@@ -280,22 +265,41 @@ var HotelCalendarView = AbstractRenderer.extend({
return domain; return domain;
}, },
_open_bookings_tree: function() { _open_search_tree: function(type) {
var $elm = this.$el.find('#pms-menu #bookings_search'); var $elm = this.$el.find('#pms-menu #bookings_search');
var searchQuery = $elm.val(); var searchQuery = $elm.val();
var domain = false; var domain = false;
if (searchQuery) { if (searchQuery) {
domain = this._generate_bookings_domain(searchQuery); domain = this._generate_search_domain(searchQuery);
} else {
domain = [];
}
var model = '';
var title = '';
if (type === 'book' || type === 'book') {
model = 'hotel.reservation';
title = _t('Reservations');
} else if (type === 'checkin') {
model = 'hotel.reservation';
title = _t('Checkins');
domain.splice(0, 0, ['checkin', '=', moment().format(HotelConstants.ODOO_DATETIME_MOMENT_FORMAT)]);
} else if (type === 'invoice') {
model = 'sale.order';
title = _t('Invoices');
} else if (type === 'folio') {
model = 'hotel.folio'
title = _t('Folios');
} }
this.do_action({ this.do_action({
type: 'ir.actions.act_window', type: 'ir.actions.act_window',
view_mode: 'form', view_mode: 'form',
view_type: 'tree,form', view_type: 'tree,form',
res_model: 'hotel.reservation', res_model: model,
views: [[false, 'list'], [false, 'form']], views: [[false, 'list'], [false, 'form']],
domain: domain, domain: domain,
name: searchQuery?'Reservations for ' + searchQuery:'All Reservations' name: searchQuery?`${title} for ${searchQuery}`:`All ${title}`
}); });
$elm.val(''); $elm.val('');

View File

@@ -12,6 +12,7 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) {
var MultiCalendar = Widget.extend({ var MultiCalendar = Widget.extend({
_calendars: [], _calendars: [],
_calendar_records: [],
_active_index: -1, _active_index: -1,
_events: {}, _events: {},
_tabs: [], _tabs: [],
@@ -37,6 +38,10 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) {
return this._calendars[index-1]; return this._calendars[index-1];
}, },
get_calendar_record: function(index) {
return this._calendar_records[index-1];
},
get_tab: function(index) { get_tab: function(index) {
return this._tabs[index]; return this._tabs[index];
}, },
@@ -53,6 +58,23 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) {
return this._tabs[this._active_index]; return this._tabs[this._active_index];
}, },
update_active_tab_name: function(name) {
var [$tab, $panel] = this.get_tab(this.get_active_index());
$tab.text(name);
},
get_active_filters: function() {
var calendar = this.get_active_calendar();
var domain = calendar.getDomain(HotelCalendar.DOMAIN.ROOMS);
var filters = {};
for (var rule of domain) {
filters[rule[0]] = rule[2];
}
return filters;
},
recalculate_reservation_positions: function() { recalculate_reservation_positions: function() {
var active_calendar = this.get_active_calendar(); var active_calendar = this.get_active_calendar();
if (active_calendar) { if (active_calendar) {
@@ -189,8 +211,8 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) {
} }
}, },
create_calendar: function(name) { create_calendar: function(calendar_record) {
var [$tab, $panel] = this._create_tab(name, `calendar-pane-${name}`); var [$tab, $panel] = this._create_tab(calendar_record['name'], `calendar-pane-${calendar_record['name']}`);
var calendar = new HotelCalendar( var calendar = new HotelCalendar(
$panel[0], $panel[0],
this._options, this._options,
@@ -201,6 +223,7 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) {
this._assign_extra_info(calendar); this._assign_extra_info(calendar);
calendar.setReservations(this._dataset['reservations']); calendar.setReservations(this._dataset['reservations']);
this._calendars.push(calendar); this._calendars.push(calendar);
this._calendar_records.push(calendar_record);
return this._calendars.length-1; return this._calendars.length-1;
}, },
@@ -256,7 +279,15 @@ odoo.define('hotel_calendar.MultiCalendar', function(require) {
var [$tab, $panel] = this._create_tab('+', 'default', {class: 'multi-calendar-tab-plus'}); var [$tab, $panel] = this._create_tab('+', 'default', {class: 'multi-calendar-tab-plus'});
$tab.on('shown.bs.tab', function(ev){ $tab.on('shown.bs.tab', function(ev){
ev.preventDefault(); ev.preventDefault();
var new_calendar_id = self.create_calendar(`Calendar #${self._calendars.length}`); var calendar_record = {
id: false,
name: `Calendar #${self._calendars.length}`,
segmentation_ids: [],
location_ids: [],
amenity_ids: [],
room_type_ids: []
};
var new_calendar_id = self.create_calendar(calendar_record);
self.set_active_calendar(new_calendar_id); self.set_active_calendar(new_calendar_id);
}); });
$('<p/>', { $('<p/>', {

View File

@@ -53,6 +53,7 @@
#hcal_widget { #hcal_widget {
max-height: 100%; max-height: 100%;
background-color: white;
} }
#cal-pag-prev-plus, #cal-pag-prev, #cal-pag-selector, #cal-pag-next, #cal-pag-next-plus { #cal-pag-prev-plus, #cal-pag-prev, #cal-pag-selector, #cal-pag-next, #cal-pag-next-plus {
@@ -105,17 +106,22 @@
color: #654a37; color: #654a37;
} }
.btn-hcal.hcal-cell-end-week { .btn-hcal.hcal-cell-end-week {
background-color: #0D5A8F; background-color: #CBE5F8;
} }
.btn-hcal-3d { .btn-hcal-3d {
color: white; border: 1px solid #eaeaea;
background-color: #7c7bad; border-top-width: 0;
border: 1px solid #cfcfdd; border-bottom-width: 0;
/*border-color: white black black white !important;*/ /*border-color: white black black white !important;*/
} }
.btn-hcal-flat { .btn-hcal-flat {
background-color: #cfcfdd; background-color: white;
border: 1px solid #cfcfdd; border: 1px solid #eaeaea;
}
.btn-hcal-left {
background-color: white;
border: 1px solid #eaeaea;
border-left-width: 0;
} }
.hcal-warn-ob-indicator { .hcal-warn-ob-indicator {
@@ -168,7 +174,7 @@
.hcal-table-day { .hcal-table-day {
height: 100%; height: 100%;
border-collapse: collapse !important; border-collapse: collapse !important;
border: 0 dotted #cfcfcf; border: 0 dotted #eaeaea;
border-width: 2px 0; border-width: 2px 0;
} }
/*.hcal-table-day tr:first-child td{ /*.hcal-table-day tr:first-child td{
@@ -189,17 +195,17 @@
font-size: 7px; font-size: 7px;
vertical-align: middle; vertical-align: middle;
font-weight: bold; font-weight: bold;
border: 1px solid #cecece !important; border: 1px solid #eaeaea !important;
} }
.hcal-table-day td:hover:not(.hcal-cell-highlight):not(.hcal-cell-invalid) { .hcal-table-day td:hover:not(.hcal-cell-highlight):not(.hcal-cell-invalid) {
background-color: #FCFEE1 !important; background-color: #FCFEE1 !important;
} }
.hcal-cell-current-day { .hcal-cell-current-day {
background-color: #E0F8B0; background-color: #FAFFD9;
} }
.hcal-cell-end-week { .hcal-cell-end-week {
background-color: #E2EAF9; background-color: #ECF3FF;
} }
.hcal-cell-day-selector { .hcal-cell-day-selector {
@@ -292,8 +298,8 @@
text-align: center; text-align: center;
/*background-color: #729fcf;*/ /*background-color: #729fcf;*/
/*transform: skewX(-25deg);*/ /*transform: skewX(-25deg);*/
border-radius: 5px; /*border-radius: 5px;*/
border: 1px solid #3465a4; border: 0 double #3465a4;
color: white; color: white;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
@@ -377,7 +383,7 @@
} }
tr.hcal-row-room-type-group-overbooking-item td { tr.hcal-row-room-type-group-overbooking-item td {
background-color: #c78585; background-color: #fcebeb;
} }
.hcal-cell-month-day { .hcal-cell-month-day {
@@ -477,23 +483,6 @@ td.hcal-cell-month-day-occupied {
text-align: center; text-align: center;
} }
button#btn_action_bookings {
margin-bottom: -1px !important;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
input#bookings_search {
border-top-left-radius: 0;
border-top-right-radius: 0;
margin-bottom: 0.2em;
}
.multi-calendar-tab-plus {
background-color: darkgray;
font-weight: bold;
color: white;
}
.noselect { .noselect {
-webkit-touch-callout: none; /* iOS Safari */ -webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */ -webkit-user-select: none; /* Safari */

View File

@@ -56,6 +56,8 @@ function HotelCalendar(/*String*/querySelector, /*Dictionary*/options, /*List*/p
showNumRooms: 0, showNumRooms: 0,
paginatorStepsMin: 1, paginatorStepsMin: 1,
paginatorStepsMax: 15, paginatorStepsMax: 15,
showOverbookings: false,
showCancelled: false,
}, options); }, options);
this.options.startDate = this.options.startDate.clone(); this.options.startDate = this.options.startDate.clone();
this.options.startDate.subtract('1', 'd'); this.options.startDate.subtract('1', 'd');
@@ -134,6 +136,14 @@ HotelCalendar.prototype = {
return this.options; return this.options;
}, },
toggleOverbookingsVisibility: function(/*Bool*/show) {
this.options.showOverbookings = !this.options.showOverbookings;
},
toggleCancelledVisibility: function(/*Bool*/show) {
this.options.showCancelled = !this.options.showCancelled;
},
setSwapMode: function(/*Int*/mode) { setSwapMode: function(/*Int*/mode) {
if (mode !== this._modeSwap) { if (mode !== this._modeSwap) {
this._modeSwap = mode; this._modeSwap = mode;
@@ -172,7 +182,7 @@ HotelCalendar.prototype = {
}, },
getDomain: function(/*Int*/section) { getDomain: function(/*Int*/section) {
return this._domains[section]; return this._domains[section] || [];
}, },
//==== RESERVATIONS //==== RESERVATIONS
@@ -216,8 +226,15 @@ HotelCalendar.prototype = {
// Merge // Merge
var uzr = []; var uzr = [];
for (var r of reservations) { for (var r of reservations) {
r = r.clone(); // HOT-FIX: Multi-Calendar Support if (!this.options.showOverbookings && r.overbooking) {
var rindex = !forced?_.findKey(this._reservations, {'id': r.id}):false;
if (rindex) {
this.removeReservation(this._reservations[rindex]);
}
continue;
}
r = r.clone(); // HOT-FIX: Multi-Calendar Support
r.room = this.getRoom(r.room_id, r.overbooking, r.id); r.room = this.getRoom(r.room_id, r.overbooking, r.id);
// need create a overbooking row? // need create a overbooking row?
if (!r.room && r.overbooking) { if (!r.room && r.overbooking) {
@@ -399,7 +416,7 @@ HotelCalendar.prototype = {
// Search End Cell // Search End Cell
if (reservation.endDate.clone().local().isSameOrBefore(this._endDate, 'd')) { if (reservation.endDate.clone().local().isSameOrBefore(this._endDate, 'd')) {
reservation._drawModes[1] = 'hard-end'; reservation._drawModes[1] = 'hard-end';
limits.right = this.getCell(reservation.endDate.clone().local(), limits.right = this.getCell(reservation.endDate.clone().subtract(1, 'd').local(),
reservation.room, reservation.room,
bedNum); bedNum);
} }
@@ -697,8 +714,10 @@ HotelCalendar.prototype = {
for (var i=start_index; i<this.options.rooms.length; i++) { for (var i=start_index; i<this.options.rooms.length; i++) {
var reservs = this.getReservationsByRoom(this.options.rooms[i], true); var reservs = this.getReservationsByRoom(this.options.rooms[i], true);
for (var reserv of reservs) { for (var reserv of reservs) {
var top = parseInt(reserv._html.style.top, 10); if (reserv && reserv._html) {
reserv._html.style.top = (cheight === 0)?'0':`${top + cheight}px`; var top = parseInt(reserv._html.style.top, 10);
reserv._html.style.top = (cheight === 0)?'0':`${top + cheight}px`;
}
} }
} }
@@ -1025,7 +1044,7 @@ HotelCalendar.prototype = {
cell.classList.add('btn-hcal'); cell.classList.add('btn-hcal');
cell.classList.add('btn-hcal-3d'); cell.classList.add('btn-hcal-3d');
cell.dataset.hcalDate = dd_local.format(HotelCalendar.DATE_FORMAT_SHORT_); cell.dataset.hcalDate = dd_local.format(HotelCalendar.DATE_FORMAT_SHORT_);
cell.innerHTML = `${dd_local.format('D')}<br/>${dd_local.format('ddd')}`; cell.innerHTML = `${dd_local.format('ddd')}<br/>${dd_local.format('D')}`;
cell.setAttribute('title', dd_local.format('dddd')) cell.setAttribute('title', dd_local.format('dddd'))
var day = +dd_local.format('D'); var day = +dd_local.format('D');
if (day == 1) { if (day == 1) {
@@ -1076,7 +1095,7 @@ HotelCalendar.prototype = {
cell.textContent = itemRoom.number; cell.textContent = itemRoom.number;
cell.classList.add('hcal-cell-room-type-group-item'); cell.classList.add('hcal-cell-room-type-group-item');
cell.classList.add('btn-hcal'); cell.classList.add('btn-hcal');
cell.classList.add('btn-hcal-3d'); cell.classList.add('btn-hcal-left');
cell.setAttribute('colspan', '2'); cell.setAttribute('colspan', '2');
cell = row.insertCell(); cell = row.insertCell();
cell.textContent = itemRoom.type; cell.textContent = itemRoom.type;
@@ -1164,7 +1183,7 @@ HotelCalendar.prototype = {
cell.classList.add('btn-hcal'); cell.classList.add('btn-hcal');
cell.classList.add('btn-hcal-3d'); cell.classList.add('btn-hcal-3d');
cell.dataset.hcalDate = dd_local.format(HotelCalendar.DATE_FORMAT_SHORT_); cell.dataset.hcalDate = dd_local.format(HotelCalendar.DATE_FORMAT_SHORT_);
cell.innerHTML = `${dd_local.format('D')}<br/>${dd_local.format('ddd')}`; cell.innerHTML = `${dd_local.format('ddd')}<br/>${dd_local.format('D')}`;
cell.setAttribute('title', dd_local.format("dddd")) cell.setAttribute('title', dd_local.format("dddd"))
var day = +dd_local.format("D"); var day = +dd_local.format("D");
if (day == 1) { if (day == 1) {
@@ -1194,7 +1213,7 @@ HotelCalendar.prototype = {
cell.textContent = rt; cell.textContent = rt;
cell.classList.add('hcal-cell-detail-room-free-type-group-item'); cell.classList.add('hcal-cell-detail-room-free-type-group-item');
cell.classList.add('btn-hcal'); cell.classList.add('btn-hcal');
cell.classList.add('btn-hcal-flat'); cell.classList.add('btn-hcal-left');
cell.setAttribute("colspan", "3"); cell.setAttribute("colspan", "3");
for (var i=0; i<=this.options.days; i++) { for (var i=0; i<=this.options.days; i++) {
var dd = this.options.startDate.clone().local().startOf('day').add(i,'d').utc(); var dd = this.options.startDate.clone().local().startOf('day').add(i,'d').utc();
@@ -1226,7 +1245,7 @@ HotelCalendar.prototype = {
cell.textContent = 'FREE TOTAL'; cell.textContent = 'FREE TOTAL';
cell.classList.add('hcal-cell-detail-room-free-total-group-item'); cell.classList.add('hcal-cell-detail-room-free-total-group-item');
cell.classList.add('btn-hcal'); cell.classList.add('btn-hcal');
cell.classList.add('btn-hcal-flat'); cell.classList.add('btn-hcal-left');
cell.setAttribute("colspan", "3"); cell.setAttribute("colspan", "3");
for (var i=0; i<=this.options.days; i++) { for (var i=0; i<=this.options.days; i++) {
var dd = this.options.startDate.clone().local().startOf('day').add(i,'d').utc(); var dd = this.options.startDate.clone().local().startOf('day').add(i,'d').utc();
@@ -1255,7 +1274,7 @@ HotelCalendar.prototype = {
cell.textContent = '% OCCUP.'; cell.textContent = '% OCCUP.';
cell.classList.add('hcal-cell-detail-room-perc-occup-group-item'); cell.classList.add('hcal-cell-detail-room-perc-occup-group-item');
cell.classList.add('btn-hcal'); cell.classList.add('btn-hcal');
cell.classList.add('btn-hcal-flat'); cell.classList.add('btn-hcal-left');
cell.setAttribute("colspan", "3"); cell.setAttribute("colspan", "3");
for (var i=0; i<=this.options.days; i++) { for (var i=0; i<=this.options.days; i++) {
var dd = this.options.startDate.clone().local().startOf('day').add(i,'d').utc(); var dd = this.options.startDate.clone().local().startOf('day').add(i,'d').utc();
@@ -1293,7 +1312,7 @@ HotelCalendar.prototype = {
cell = row.insertCell(); cell = row.insertCell();
var span = document.createElement('span'); var span = document.createElement('span');
cell.title = cell.textContent = listitem.title + ' ' + this.options.currencySymbol; cell.title = cell.textContent = listitem.title + ' ' + this.options.currencySymbol;
cell.classList.add('hcal-cell-detail-room-group-item', 'btn-hcal', 'btn-hcal-flat'); cell.classList.add('hcal-cell-detail-room-group-item', 'btn-hcal', 'btn-hcal-left');
cell.dataset.currencySymbol = this.options.currencySymbol; cell.dataset.currencySymbol = this.options.currencySymbol;
cell.setAttribute("colspan", "3"); cell.setAttribute("colspan", "3");
for (var i=0; i<=$this.options.days; i++) { for (var i=0; i<=$this.options.days; i++) {
@@ -1535,6 +1554,7 @@ HotelCalendar.prototype = {
var limitLeftDateMoment = HotelCalendar.toMoment(limitLeftDate); var limitLeftDateMoment = HotelCalendar.toMoment(limitLeftDate);
var limitRightDateMoment = HotelCalendar.toMoment(limitRightDate); var limitRightDateMoment = HotelCalendar.toMoment(limitRightDate);
var diff_date = this.getDateDiffDays(limitLeftDateMoment, limitRightDateMoment); var diff_date = this.getDateDiffDays(limitLeftDateMoment, limitRightDateMoment);
if (reserv._drawModes[1] === 'hard-end') { --diff_date; }
var date = limitLeftDateMoment.clone().startOf('day'); var date = limitLeftDateMoment.clone().startOf('day');
var selector = []; var selector = [];
for (var i=0; i<=diff_date; i++) { for (var i=0; i<=diff_date; i++) {
@@ -1604,7 +1624,7 @@ HotelCalendar.prototype = {
// FIXME: Normalize data calendar (gmt) vs extra info (utc) // FIXME: Normalize data calendar (gmt) vs extra info (utc)
var date_cell = HotelCalendar.toMoment(this.etable.querySelector(`#${c.dataset.hcalParentCell}`).dataset.hcalDate); var date_cell = HotelCalendar.toMoment(this.etable.querySelector(`#${c.dataset.hcalParentCell}`).dataset.hcalDate);
var room_price = this.getRoomPrice(parentRow.dataset.hcalRoomObjId, date_cell); var room_price = this.getRoomPrice(parentRow.dataset.hcalRoomObjId, date_cell);
if (c === cells[0] || !date_cell.isSame(limitRightDate, 'day')) { if (c === cells[0]) {
c.textContent = room_price + ' ' + this.options.currencySymbol; c.textContent = room_price + ' ' + this.options.currencySymbol;
if (!room.shared && c.dataset.hcalBedNum > limits.left.dataset.hcalBedNum) { if (!room.shared && c.dataset.hcalBedNum > limits.left.dataset.hcalBedNum) {
c.style.color = 'lightgray'; c.style.color = 'lightgray';
@@ -1683,39 +1703,28 @@ HotelCalendar.prototype = {
var divHeight = (boundsEnd.bottom-etableOffset.top)-(boundsInit.top-etableOffset.top); var divHeight = (boundsEnd.bottom-etableOffset.top)-(boundsInit.top-etableOffset.top);
reserv._html.style.height = `${divHeight}px`; reserv._html.style.height = `${divHeight}px`;
reserv._html.style.lineHeight = `${divHeight}px`; reserv._html.style.lineHeight = `${divHeight}px`;
var fontHeight = divHeight/1.3; var fontHeight = divHeight/1.2;
if (fontHeight > 16) { if (fontHeight > 16) {
fontHeight = 16; fontHeight = 16;
} }
reserv._html.style.fontSize = `${fontHeight}px`; reserv._html.style.fontSize = `${fontHeight}px`;
var clearBorderLeft = function(/*HTMLObject*/elm) { var clearBorderLeft = function(/*HTMLObject*/elm) {
elm.style.borderLeftWidth = '0'; elm.style.borderLeftWidth = '3px';
elm.style.borderTopLeftRadius = '0';
elm.style.borderBottomLeftRadius = '0';
}; };
var clearBorderRight = function(/*HTMLObject*/elm) { var clearBorderRight = function(/*HTMLObject*/elm) {
elm.style.borderRightWidth = '0'; elm.style.borderRightWidth = '3px';
elm.style.borderTopRightRadius = '0';
elm.style.borderBottomRightRadius = '0';
}; };
reserv._html.style.left = `${boundsInit.left-etableOffset.left}px`;
reserv._html.style.width = `${(boundsEnd.left-boundsInit.left)+boundsEnd.width}px`;
if (reserv._drawModes[0] === 'soft-start' && reserv._drawModes[1] === 'soft-end') { if (reserv._drawModes[0] === 'soft-start' && reserv._drawModes[1] === 'soft-end') {
clearBorderLeft(reserv._html); clearBorderLeft(reserv._html);
clearBorderRight(reserv._html); clearBorderRight(reserv._html);
reserv._html.style.left = `${boundsInit.left-etableOffset.left}px`;
reserv._html.style.width = `${(boundsEnd.left-boundsInit.left)+boundsEnd.width}px`;
} else if (reserv._drawModes[0] === 'soft-start') { } else if (reserv._drawModes[0] === 'soft-start') {
clearBorderLeft(reserv._html); clearBorderLeft(reserv._html);
reserv._html.style.left = `${boundsInit.left-etableOffset.left}px`;
reserv._html.style.width = `${(boundsEnd.left-boundsInit.left)+boundsEnd.width/2.0}px`;
} else if (reserv._drawModes[1] === 'soft-end') { } else if (reserv._drawModes[1] === 'soft-end') {
clearBorderRight(reserv._html); clearBorderRight(reserv._html);
reserv._html.style.left = `${boundsInit.left-etableOffset.left+boundsInit.width/2.0}px`;
reserv._html.style.width = `${(boundsEnd.left-boundsInit.left)+boundsEnd.width}px`;
} else {
reserv._html.style.left = `${(boundsInit.left-etableOffset.left)+boundsEnd.width/2.0}px`;
reserv._html.style.width = `${(boundsEnd.left-boundsInit.left)}px`;
} }
} }
}, },
@@ -2163,7 +2172,9 @@ HotelCalendar.prototype = {
//break; //break;
} else { return false; } } else { return false; }
} else if (compMode === 'some') { } else if (compMode === 'some') {
if ((obj[fieldName] && typeof obj[fieldName] === 'object' && _.some(f[2], function(item) { return obj[fieldName].indexOf(item) !== -1; })) || if ((fieldName in obj && obj[fieldName] in f[2]) ||
f[2].indexOf(userDataValue) != -1 ||
(obj[fieldName] && typeof obj[fieldName] === 'object' && _.some(f[2], function(item) { return obj[fieldName].indexOf(item) !== -1; })) ||
(userDataValue && typeof userDataValue === 'object' && userDataValue.length && _.some(f[2], function(item) { return userDataValue.indexOf(item) !== -1; }))) { (userDataValue && typeof userDataValue === 'object' && userDataValue.length && _.some(f[2], function(item) { return userDataValue.indexOf(item) !== -1; }))) {
founded = true; founded = true;
//break; //break;
@@ -2311,7 +2322,6 @@ HotelCalendar.prototype = {
_onCellMouseUp: function(ev) { _onCellMouseUp: function(ev) {
if (this._cellSelection.start && if (this._cellSelection.start &&
this._cellSelection.start != ev.target &&
this._cellSelection.start.dataset.hcalParentRow === ev.target.dataset.hcalParentRow) { this._cellSelection.start.dataset.hcalParentRow === ev.target.dataset.hcalParentRow) {
this._cellSelection.end = ev.target; this._cellSelection.end = ev.target;
@@ -2362,12 +2372,12 @@ HotelCalendar.prototype = {
return true; return true;
} }
if (!date_cell.isAfter(reserv.startDate, 'd')) { if (!date_cell.isAfter(reserv.startDate, 'd')) {
date_cell = reserv.startDate.clone().startOf('day').add(1, 'd'); date_cell = reserv.startDate.clone().startOf('day');
} }
if (!this.reservationAction.oldReservationObj) { if (!this.reservationAction.oldReservationObj) {
this.reservationAction.oldReservationObj = reserv.clone(); this.reservationAction.oldReservationObj = reserv.clone();
} }
reserv.endDate.set({'date': date_cell.date(), 'month': date_cell.month(), 'year': date_cell.year()}); reserv.endDate.set({'date': date_cell.date(), 'month': date_cell.month(), 'year': date_cell.year()}).add(1, 'd');
this.reservationAction.newReservationObj = reserv; this.reservationAction.newReservationObj = reserv;
needUpdate = true; needUpdate = true;
} else if (this.reservationAction.action == HotelCalendar.ACTION.MOVE_LEFT) { } else if (this.reservationAction.action == HotelCalendar.ACTION.MOVE_LEFT) {
@@ -2624,7 +2634,7 @@ HotelCalendar.prototype = {
if (reverse) { if (reverse) {
value = max-value; value = max-value;
} }
rgb = this._hslToRgb(((max-value)*offset)/max, 1.0, 0.5); rgb = this._hslToRgb(((max-value)*offset)/max, 1.0, 0.8);
if (!strmode) { if (!strmode) {
return rgb; return rgb;
} }

View File

@@ -3,88 +3,139 @@
<t t-name="hotel_calendar.HotelCalendarView"> <t t-name="hotel_calendar.HotelCalendarView">
<div class="col-xs-12 col-md-12 nopadding"> <div class="col-xs-12 col-md-12 nopadding">
<div class="col-lg-1 hidden-xs hidden-sm nopadding" id="pms-menu"> <div class="col-lg-2 hidden-xs hidden-sm" id="pms-menu">
<button class="btn btn-default col-xs-12 col-md-12" id="btn_action_checkout" data-action="hotel_calendar.hotel_reservation_action_checkout"> <div class="col-xs-12 col-md-12 nopadding menu-date-box">
<div class="ninfo"><span class="badge badge-danger">0</span></div> <div class="input-group date" id="date_begin">
CHECK-OUT <input type="text" class="o_datepicker_input form-control" name="date_begin" required="required"/>
</button> <span class="input-group-addon">
<button class="btn btn-default col-xs-12 col-md-12" id="btn_action_checkin" data-action="hotel_calendar.hotel_reservation_action_checkin"> <span class="fa fa-calendar"></span>
<div class="ninfo"><span class="badge badge-danger">0</span></div> </span>
CHECK-IN </div>
</button> <div class="input-group date" id="date_end">
<button class="btn btn-default col-xs-12 col-md-12" id="btn_action_bookings"> <input type="text" class="o_datepicker_input form-control" name="date_end" required="required"/>
<!--div class="ninfo"><span class="badge badge-danger">0</span></div--> <span class="input-group-addon">
BOOKS<br/> <span class="fa fa-calendar"></span>
</button> </span>
<input type="edit" id="bookings_search" placeholder="Search..." style="width:100%; border:1px solid lightgray;" /> </div>
<button class="btn btn-default col-xs-12 col-md-12" id="btn_action_control" data-action="hotel.open_wizard_reservations">
WIZARD
</button>
<button class="btn btn-default col-xs-12 col-md-12" id="btn_swap">
<div class="ninfo"><span class="badge badge-danger">0</span></div>
<span class="ntext">START SWAP</span>
</button>
<!--button class="btn btn-default col-xs-12 col-md-12" id="btn_action_refresh">
<i class="fa fa-4x fa-refresh"> </i>
</button-->
</div>
<div class="col-xs-12 col-sm-12 col-md-11 nopadding">
<div class="col-xs-11 col-md-11 nopadding" id="pms-search">
<table class="col-xs-12 col-md-12 nopadding" id="pms-search-table">
<tbody>
<tr>
<td class="col-xs-3 col-md-4">
<div class="col-xs-12 col-md-12 text-left">
<label for="type_list">SEGMENTATION:</label>
<select class="form-control" id="type_list" multiple="multiple"/>
</div>
<div class="col-xs-12 col-md-12 text-left">
<label for="floor_list">LOCATION:</label>
<select class="list form-control" id="floor_list" multiple="multiple"/>
</div>
</td>
<td class="col-xs-3 col-md-4">
<div class="col-xs-12 col-md-12 text-left">
<label for="amenities_list">AMENITIES:</label>
<select class="list form-control" id="amenities_list" multiple="multiple"/>
</div>
<div class="col-xs-12 col-md-12 text-left">
<label for="virtual_list">VIRTUAL:</label>
<select class="list form-control" id="virtual_list" multiple="multiple"/>
</div>
</td>
<td class="col-xs-6 col-md-4">
<div class="col-xs-12 col-md-12">
<table style="margin: 0 auto">
<tbody>
<tr>
<td>
<label for="date_begin">FROM</label>
<div class="input-group date" id="date_begin">
<input type="text" class="o_datepicker_input form-control" name="date_begin" required="required"/>
<span class="input-group-addon">
<span class="fa fa-calendar"></span>
</span>
</div>
</td>
<td>
<label for="date_end">TO</label>
<div class="input-group date" id="date_end">
<input type="text" class="o_datepicker_input form-control" name="date_end" required="required"/>
<span class="input-group-addon">
<span class="fa fa-calendar"></span>
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</div> </div>
<div class="col-xs-12 col-md-12 nopadding menu-button-box">
<div class="col-xs-6 col-md-6" id="btn_action_checkout">
<button class="btn btn-default col-xs-12 col-md-12 button-box" data-action="hotel_calendar.hotel_reservation_action_checkout">
<i class="fa fa-fw o_button_icon fa-sign-out"> </i>
<div class="o_button_text">
<span class="ninfo">0</span><br/>
Checkouts
</div>
</button>
</div>
<div class="col-xs-6 col-md-6" id="btn_action_checkin">
<button class="btn btn-default col-xs-12 col-md-12 button-box" data-action="hotel_calendar.hotel_reservation_action_checkin">
<i class="fa fa-fw o_button_icon fa-sign-in"> </i>
<div class="o_button_text">
<span class="ninfo">0</span><br/>
Checkins
</div>
</button>
</div>
<div class="col-xs-6 col-md-6" id="btn_swap">
<button class="btn btn-default col-xs-12 col-md-12 button-box">
<div class='led led-disabled'></div>
<i class="fa fa-fw o_button_icon fa-retweet"> </i>
<div class="o_button_text">
<span class="ntext">Start Swap</span>
</div>
</button>
</div>
<div class="col-xs-6 col-md-6" id="btn_action_control">
<button class="btn btn-default col-xs-12 col-md-12 button-box" data-action="hotel.open_wizard_reservations">
<i class="fa fa-fw o_button_icon fa-magic"> </i>
<div class="o_button_text">
Wizard
</div>
</button>
</div>
<div class="col-xs-6 col-md-6" id="btn_action_overbooking">
<button class="btn btn-default col-xs-12 col-md-12 button-box">
<div class='led led-disabled'></div>
<i class="fa fa-fw o_button_icon fa-clock-o"> </i>
<div class="o_button_text">
<span class="ninfo">0</span><br/>
Overbooking
</div>
</button>
</div>
<div class="col-xs-6 col-md-6" id="btn_action_cancelled">
<button class="btn btn-default col-xs-12 col-md-12 button-box">
<div class='led led-disabled'></div>
<i class="fa fa-fw o_button_icon fa-calendar-times-o"> </i>
<div class="o_button_text">
Cancelled
</div>
</button>
</div>
<div class="col-xs-6 col-md-6" id="btn_action_divide">
<button class="btn btn-default col-xs-12 col-md-12 button-box">
<div class='led led-disabled'></div>
<i class="fa fa-fw o_button_icon fa-scissors"> </i>
<div class="o_button_text">
Divide
</div>
</button>
</div>
<div class="col-xs-6 col-md-6" id="btn_action_unify">
<button class="btn btn-default col-xs-12 col-md-12 button-box">
<div class='led led-disabled'></div>
<i class="fa fa-fw o_button_icon fa-compress"> </i>
<div class="o_button_text">
Unify
</div>
</button>
</div>
</div>
<div class="col-xs-12 col-md-12 nopadding menu-search-box">
<div class="input-group">
<input type="edit" id="bookings_search" placeholder="Name, Mail, Vat, Book..." class="form-control extra-search" />
<span class="input-group-addon bg-primary">
<span class="fa fa-search"></span>
</span>
</div>
<button class="btn btn-primary col-xs-6 col-md-6" id="btn_action_bookings">
Books
</button>
<button class="btn btn-primary col-xs-6 col-md-6" id="btn_action_checkins">
Checkins
</button>
<button class="btn btn-primary col-xs-6 col-md-6" id="btn_action_invoices">
Invoices
</button>
<button class="btn btn-primary col-xs-6 col-md-6" id="btn_action_folios">
Folios
</button>
</div>
<div class="col-xs-12 col-md-12 nopadding menu-filter-box">
<h4>Filters</h4>
<select class="form-control" id="type_list" placeholder="Select Segmentation..." multiple="multiple"/>
<select class="list form-control" id="floor_list" placeholder="Select Location..." multiple="multiple"/>
<select class="list form-control" id="amenities_list" placeholder="Select Amenities..." multiple="multiple"/>
<select class="list form-control" id="virtual_list" placeholder="Select Type..." multiple="multiple"/>
<div class="filter-record col-xs-12 col-md-12" style="padding:4px">
<div class="col-xs-8 col-md-8 nopadding">
<input type="edit" id="calendar_name" class="form-control" />
</div>
<div class="col-xs-2 col-md-2 nopadding">
<button class="btn btn-primary col-xs-12 col-md-12" id="btn_save_calendar_record">
<i class="fa fa-fw fa-save"> </i>
</button>
</div>
<div class="col-xs-2 col-md-2 nopadding">
<button class="btn btn-primary col-xs-12 col-md-12" id="btn_reload_calendar_filters">
<i class="fa fa-fw fa-refresh"> </i>
</button>
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-10 nopadding">
<div id="hcal_widget" class="col-xs-12 col-md-12 nopadding"> <div id="hcal_widget" class="col-xs-12 col-md-12 nopadding">
<div id="hcal_load"> <div id="hcal_load">
<span> <span>

View File

@@ -4,7 +4,7 @@
* Aloxa Solucions S.L. <info@aloxa.eu> * Aloxa Solucions S.L. <info@aloxa.eu>
* Alexandre Díaz <alex@aloxa.eu> * Alexandre Díaz <alex@aloxa.eu>
*/ */
/** ANIMATIONS **/ /** ANIMATIONS **/
@keyframes channel-manager-changes { @keyframes channel-manager-changes {
0% { 0% {
@@ -34,17 +34,11 @@
color: black; color: black;
} }
} }
#pms-menu #btn_channel_manager_request.incoming i { #pms-menu #btn_channel_manager_request.incoming i {
animation-name: channel-manager-changes; animation-name: channel-manager-changes;
animation-duration: 2s; animation-duration: 2s;
animation-iteration-count: infinite; animation-iteration-count: infinite;
animation-direction: alternate; animation-direction: alternate;
} }
#pms-menu #btn_channel_manager_request.incoming span {
animation-name: channel-manager-changes-text;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
}

View File

@@ -10,26 +10,22 @@ odoo.define('hotel_calendar_channel_connector.PMSHotelCalendarRendererChannelCon
update_buttons_counter_channel_connector: function (nreservations, nissues) { update_buttons_counter_channel_connector: function (nreservations, nissues) {
// Cloud Reservations // Cloud Reservations
var $button = this.$el.find('#btn_channel_manager_request');
var $text = this.$el.find('#btn_channel_manager_request .cloud-text'); var $text = this.$el.find('#btn_channel_manager_request .cloud-text');
if (nreservations > 0) { if (nreservations > 0) {
$button.addClass('incoming'); $text.parent().parent().addClass('button-highlight');
$text.parent().addClass('incoming');
$text.text(nreservations); $text.text(nreservations);
$text.show();
} else { } else {
$button.removeClass('incoming'); $text.parent().removeClass('incoming');
$text.hide();
} }
// Issues // Issues
var $ninfo = this.$el.find('#pms-menu #btn_action_issues div.ninfo'); var $ninfo = this.$el.find('#pms-menu #btn_action_issues div.ninfo');
var $badge_issues = $ninfo.find('.badge'); $ninfo.text(nissues);
if (nissues > 0) { if (nissues) {
$badge_issues.text(nissues); $ninfo.parent().parent().addClass('button-highlight');
$badge_issues.parent().show();
$ninfo.show();
} else { } else {
$ninfo.hide(); $ninfo.parent().parent().removeClass('button-highlight');
} }
}, },

View File

@@ -2,19 +2,25 @@
<templates xml:space="preserve"> <templates xml:space="preserve">
<t t-extend="hotel_calendar.HotelCalendarView"> <t t-extend="hotel_calendar.HotelCalendarView">
<t t-jquery="button#btn_action_checkout" t-operation="before"> <t t-jquery="div#btn_action_checkin" t-operation="after">
<button class="btn col-xs-12 col-lg-12" id="btn_channel_manager_request"> <div class="col-xs-6 col-md-6" id="btn_action_issues">
<div class="fa-stack fa-2x"> <button class="btn btn-default col-xs-12 col-md-12 button-box" data-action="hotel_calendar_channel_connector.calendar_channel_connector_issues_action">
<i class="fa fa-cloud fa-stack-2x"> </i> <i class="fa fa-fw o_button_icon fa-exclamation-circle"> </i>
<span class="fa-stack-1x cloud-text">0</span> <div class="o_button_text">
</div> <span class="ninfo">0</span><br/>
</button> Issues
</t> </div>
<t t-jquery="input#bookings_search" t-operation="after"> </button>
<button class="btn btn-default col-xs-12 col-lg-12" id="btn_action_issues" data-action="hotel_calendar_channel_connector.calendar_channel_connector_issues_action"> </div>
<div class="ninfo"><span class="badge badge-danger">0</span></div> <div class="col-xs-6 col-md-6" id="btn_channel_manager_request">
ISSUES <button class="btn btn-default col-xs-12 col-md-12 button-box">
</button> <i class="fa fa-fw o_button_icon fa-cloud"></i>
<div class="o_button_text">
<span class="cloud-text">0</span><br/>
To Assign
</div>
</button>
</div>
</t> </t>
</t> </t>