mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
Merge branch '11.0' of https://github.com/hootel/hootel into 11.0
This commit is contained in:
@@ -52,6 +52,7 @@ class BusHotelCalendar(models.TransientModel):
|
|||||||
'price_room_services_set': vals['price_room_services_set'],
|
'price_room_services_set': vals['price_room_services_set'],
|
||||||
'amount_total': vals['pending_amount'] + vals['invoices_paid'],
|
'amount_total': vals['pending_amount'] + vals['invoices_paid'],
|
||||||
'real_dates': vals['real_dates'],
|
'real_dates': vals['real_dates'],
|
||||||
|
'channel_type': vals['channel_type'],
|
||||||
},
|
},
|
||||||
'tooltip': {
|
'tooltip': {
|
||||||
'folio_name': vals['folio_name'],
|
'folio_name': vals['folio_name'],
|
||||||
|
|||||||
@@ -94,7 +94,9 @@ class HotelReservation(models.Model):
|
|||||||
'state': reserv['state'],
|
'state': reserv['state'],
|
||||||
'price_room_services_set': reserv['price_room_services_set'],
|
'price_room_services_set': reserv['price_room_services_set'],
|
||||||
'amount_total': reserv['amount_total'],
|
'amount_total': reserv['amount_total'],
|
||||||
'real_dates': [reserv['real_checkin'], reserv['real_checkout']]})
|
'real_dates': [reserv['real_checkin'], reserv['real_checkout']],
|
||||||
|
'channel_type': reserv['channel_type'],
|
||||||
|
})
|
||||||
json_reservation_tooltips.update({
|
json_reservation_tooltips.update({
|
||||||
reserv['id']: {
|
reserv['id']: {
|
||||||
'folio_name': reserv['folio_name'],
|
'folio_name': reserv['folio_name'],
|
||||||
|
|||||||
@@ -376,6 +376,7 @@ var PMSCalendarController = AbstractController.extend({
|
|||||||
_assign_multi_calendar_events: function() {
|
_assign_multi_calendar_events: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
this._multi_calendar.on_calendar('hcalOnSavePricelist', function(ev){
|
this._multi_calendar.on_calendar('hcalOnSavePricelist', function(ev){
|
||||||
|
document.getElementById("btn_save_changes").disabled = true;
|
||||||
self.savePricelist(ev.detail.calendar_obj, ev.detail.pricelist_id, ev.detail.pricelist);
|
self.savePricelist(ev.detail.calendar_obj, ev.detail.pricelist_id, ev.detail.pricelist);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,9 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
|
|||||||
|
|
||||||
save_changes: function() {
|
save_changes: function() {
|
||||||
var oparams = this.get_values_to_save();
|
var oparams = this.get_values_to_save();
|
||||||
this.trigger_up('onSaveChanges', oparams);
|
if (oparams) {
|
||||||
|
this.trigger_up('onSaveChanges', oparams);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
resetSaveState: function() {
|
resetSaveState: function() {
|
||||||
@@ -138,6 +140,9 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
|
|||||||
|
|
||||||
// Sticky Header Days
|
// Sticky Header Days
|
||||||
$('.o_content').scroll(this._on_scroll.bind(this));
|
$('.o_content').scroll(this._on_scroll.bind(this));
|
||||||
|
|
||||||
|
// Initialize Save Button state to disable
|
||||||
|
document.getElementById("btn_save_changes").disabled = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
setCalendarData: function (prices, restrictions, availability, count_reservations) {
|
setCalendarData: function (prices, restrictions, availability, count_reservations) {
|
||||||
@@ -149,23 +154,19 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
|
|||||||
var self = this;
|
var self = this;
|
||||||
this._hcalendar.addEventListener('hcOnChangeDate', function(ev){
|
this._hcalendar.addEventListener('hcOnChangeDate', function(ev){
|
||||||
var date_begin = moment(ev.detail.newDate);
|
var date_begin = moment(ev.detail.newDate);
|
||||||
var days = self._hcalendar.getOptions('days')-1;
|
|
||||||
var date_end = date_begin.clone().add(days, 'd');
|
|
||||||
|
|
||||||
var $dateTimePickerBegin = self.$el.find('#mpms-search #date_begin');
|
var $dateTimePickerBegin = self.$el.find('#mpms-search #date_begin');
|
||||||
var $dateTimePickerEnd = self.$el.find('#mpms-search #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("DateTimePicker").date(date_end);
|
|
||||||
|
|
||||||
self.reload_hcalendar_management();
|
self.reload_hcalendar_management();
|
||||||
});
|
});
|
||||||
this._hcalendar.addEventListener('hcmOnInputChanged', function(ev){
|
this._hcalendar.addEventListener('hcmOnInputChanged', function(ev){
|
||||||
var btn_save = self.$el.find('#btn_save_changes');
|
var btn_save = self.$el.find('#btn_save_changes');
|
||||||
if (self._hcalendar.hasChangesToSave()) {
|
if (self._hcalendar.hasChangesToSave()) {
|
||||||
btn_save.addClass('need-save');
|
btn_save.addClass('need-save');
|
||||||
|
document.getElementById("btn_save_changes").disabled = false;
|
||||||
} else {
|
} else {
|
||||||
btn_save.removeClass('need-save');
|
btn_save.removeClass('need-save');
|
||||||
|
document.getElementById("btn_save_changes").disabled = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -250,94 +251,82 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
|
|||||||
format : HotelConstants.L10N_DATE_MOMENT_FORMAT,
|
format : HotelConstants.L10N_DATE_MOMENT_FORMAT,
|
||||||
//disabledHours: [0, 1, 2, 3, 4, 5, 6, 7, 8, 18, 19, 20, 21, 22, 23]
|
//disabledHours: [0, 1, 2, 3, 4, 5, 6, 7, 8, 18, 19, 20, 21, 22, 23]
|
||||||
};
|
};
|
||||||
|
|
||||||
var $dateTimePickerBegin = this.$el.find('#mpms-search #date_begin');
|
var $dateTimePickerBegin = this.$el.find('#mpms-search #date_begin');
|
||||||
var $dateTimePickerEnd = this.$el.find('#mpms-search #date_end');
|
|
||||||
$dateTimePickerBegin.datetimepicker(DTPickerOptions);
|
$dateTimePickerBegin.datetimepicker(DTPickerOptions);
|
||||||
$dateTimePickerEnd.datetimepicker($.extend({}, DTPickerOptions, { 'useCurrent': false }));
|
|
||||||
$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").maxDate(e.date.clone().add(2,'M'));
|
|
||||||
$dateTimePickerBegin.data("DateTimePicker").hide(); // TODO: Odoo uses old datetimepicker version
|
$dateTimePickerBegin.data("DateTimePicker").hide(); // TODO: Odoo uses old datetimepicker version
|
||||||
self.on_change_filter_date(e, true);
|
self.on_change_filter_date(e, true);
|
||||||
});
|
});
|
||||||
$dateTimePickerEnd.on("dp.change", function (e) {
|
|
||||||
$dateTimePickerEnd.data("DateTimePicker").hide(); // TODO: Odoo uses old datetimepicker version
|
var $dateEndDays = this.$el.find('#mpms-search #date_end_days');
|
||||||
self.on_change_filter_date(e, false);
|
$dateEndDays.select2({
|
||||||
|
data: [
|
||||||
|
{id:7, text: '1w'},
|
||||||
|
{id:12, text: '2w'},
|
||||||
|
{id:21, text: '3w'},
|
||||||
|
{id:'month', text: '1m'},
|
||||||
|
{id:60, text: '2m'},
|
||||||
|
{id:90, text: '3m'},
|
||||||
|
],
|
||||||
|
allowClear: true,
|
||||||
|
minimumResultsForSearch: -1
|
||||||
});
|
});
|
||||||
|
|
||||||
// var date_begin = moment().startOf('day');
|
$dateEndDays.on("change", function (e) {
|
||||||
// var date_end = date_begin.clone().add(this._view_options['days'], 'd').endOf('day');
|
self.on_change_filter_date();
|
||||||
// $dateTimePickerBegin.data("ignore_onchange", true);
|
});
|
||||||
// $dateTimePickerBegin.data("DateTimePicker").date(date_begin);
|
|
||||||
// $dateTimePickerEnd.data("DateTimePicker").date(date_end);
|
|
||||||
// this._last_dates = this.generate_params()['dates'];
|
|
||||||
|
|
||||||
// View Events
|
// View Events
|
||||||
this.$el.find("#mpms-search #cal-pag-prev-plus").on('click', function(ev){
|
this.$el.find("#mpms-search #cal-pag-prev-plus").on('click', function(ev){
|
||||||
// FIXME: Ugly repeated code. Change place.
|
// FIXME: Ugly repeated code. Change place.
|
||||||
var $dateTimePickerBegin = self.$el.find('#mpms-search #date_begin');
|
var $dateTimePickerBegin = self.$el.find('#mpms-search #date_begin');
|
||||||
var $dateTimePickerEnd = self.$el.find('#mpms-search #date_end');
|
|
||||||
//var days = moment($dateTimePickerBegin.data("DateTimePicker").date()).clone().local().daysInMonth();
|
|
||||||
var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().subtract(14, 'd');
|
var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().subtract(14, 'd');
|
||||||
var date_end = $dateTimePickerEnd.data("DateTimePicker").date().subtract(14, 'd');
|
|
||||||
$dateTimePickerBegin.data("ignore_onchange", true);
|
$dateTimePickerBegin.data("ignore_onchange", true);
|
||||||
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
|
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
|
||||||
$dateTimePickerEnd.data("DateTimePicker").date(date_end);
|
self.on_change_filter_date(ev, true);
|
||||||
|
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
});
|
});
|
||||||
this.$el.find("#mpms-search #cal-pag-prev").on('click', function(ev){
|
this.$el.find("#mpms-search #cal-pag-prev").on('click', function(ev){
|
||||||
// FIXME: Ugly repeated code. Change place.
|
// FIXME: Ugly repeated code. Change place.
|
||||||
var $dateTimePickerBegin = self.$el.find('#mpms-search #date_begin');
|
var $dateTimePickerBegin = self.$el.find('#mpms-search #date_begin');
|
||||||
var $dateTimePickerEnd = self.$el.find('#mpms-search #date_end');
|
|
||||||
var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().subtract(7, 'd');
|
var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().subtract(7, 'd');
|
||||||
var date_end = $dateTimePickerEnd.data("DateTimePicker").date().subtract(7, 'd');
|
|
||||||
$dateTimePickerBegin.data("ignore_onchange", true);
|
$dateTimePickerBegin.data("ignore_onchange", true);
|
||||||
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
|
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
|
||||||
$dateTimePickerEnd.data("DateTimePicker").date(date_end);
|
self.on_change_filter_date(ev, true);
|
||||||
|
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
});
|
});
|
||||||
this.$el.find("#mpms-search #cal-pag-next-plus").on('click', function(ev){
|
this.$el.find("#mpms-search #cal-pag-next-plus").on('click', function(ev){
|
||||||
// FIXME: Ugly repeated code. Change place.
|
// FIXME: Ugly repeated code. Change place.
|
||||||
var $dateTimePickerBegin = self.$el.find('#mpms-search #date_begin');
|
var $dateTimePickerBegin = self.$el.find('#mpms-search #date_begin');
|
||||||
var $dateTimePickerEnd = self.$el.find('#mpms-search #date_end');
|
|
||||||
//var days = moment($dateTimePickerBegin.data("DateTimePicker").date()).clone().local().daysInMonth();
|
|
||||||
var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().add(14, 'd');
|
var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().add(14, 'd');
|
||||||
var date_end = $dateTimePickerEnd.data("DateTimePicker").date().add(14, 'd');
|
|
||||||
$dateTimePickerBegin.data("ignore_onchange", true);
|
$dateTimePickerBegin.data("ignore_onchange", true);
|
||||||
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
|
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
|
||||||
$dateTimePickerEnd.data("DateTimePicker").date(date_end);
|
self.on_change_filter_date(ev, true);
|
||||||
|
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
});
|
});
|
||||||
this.$el.find("#mpms-search #cal-pag-next").on('click', function(ev){
|
this.$el.find("#mpms-search #cal-pag-next").on('click', function(ev){
|
||||||
// FIXME: Ugly repeated code. Change place.
|
// FIXME: Ugly repeated code. Change place.
|
||||||
var $dateTimePickerBegin = self.$el.find('#mpms-search #date_begin');
|
var $dateTimePickerBegin = self.$el.find('#mpms-search #date_begin');
|
||||||
var $dateTimePickerEnd = self.$el.find('#mpms-search #date_end');
|
|
||||||
var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().add(7, 'd');
|
var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().add(7, 'd');
|
||||||
var date_end = $dateTimePickerEnd.data("DateTimePicker").date().add(7, 'd');
|
|
||||||
$dateTimePickerBegin.data("ignore_onchange", true);
|
$dateTimePickerBegin.data("ignore_onchange", true);
|
||||||
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
|
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
|
||||||
$dateTimePickerEnd.data("DateTimePicker").date(date_end);
|
self.on_change_filter_date(ev, true);
|
||||||
|
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
});
|
});
|
||||||
this.$el.find("#mpms-search #cal-pag-selector").on('click', function(ev){
|
this.$el.find("#mpms-search #cal-pag-selector").on('click', function(ev){
|
||||||
// FIXME: Ugly repeated code. Change place.
|
// FIXME: Ugly repeated code. Change place.
|
||||||
var $dateTimePickerBegin = self.$el.find('#mpms-search #date_begin');
|
var $dateTimePickerBegin = self.$el.find('#mpms-search #date_begin');
|
||||||
var $dateTimePickerEnd = self.$el.find('#mpms-search #date_end');
|
|
||||||
var date_begin = moment().startOf('day');
|
var date_begin = moment().startOf('day');
|
||||||
var date_end = date_begin.clone().add(self._view_options['days'], 'd').endOf('day');
|
|
||||||
$dateTimePickerBegin.data("ignore_onchange", true);
|
$dateTimePickerBegin.data("ignore_onchange", true);
|
||||||
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
|
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
|
||||||
$dateTimePickerEnd.data("DateTimePicker").date(date_end);
|
self.on_change_filter_date(ev, true);
|
||||||
|
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Save Button
|
// Save Button
|
||||||
this.$el.find("#btn_save_changes").on('click', function(ev){
|
this.$el.find("#btn_save_changes").on('click', function(ev) {
|
||||||
|
document.getElementById(this.id).disabled = true;
|
||||||
self.save_changes();
|
self.save_changes();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -358,15 +347,15 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
|
|||||||
} else {
|
} else {
|
||||||
this._view_options['days'] = (this._view_options['days'] !== 'month')?parseInt(this._view_options['days']):date_begin.daysInMonth();
|
this._view_options['days'] = (this._view_options['days'] !== 'month')?parseInt(this._view_options['days']):date_begin.daysInMonth();
|
||||||
}
|
}
|
||||||
var date_end = date_begin.clone().add(this._view_options['days'], 'd').endOf('day');
|
|
||||||
var $dateTimePickerBegin = this.$el.find('#mpms-search #date_begin');
|
|
||||||
var $dateTimePickerEnd = this.$el.find('#mpms-search #date_end');
|
|
||||||
//$dateTimePickerBegin.data("ignore_onchange", true);
|
|
||||||
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
|
|
||||||
//$dateTimePickerEnd.data("ignore_onchange", true);
|
|
||||||
$dateTimePickerEnd.data("DateTimePicker").date(date_end);
|
|
||||||
this._last_dates = this.generate_params()['dates'];
|
|
||||||
|
|
||||||
|
var $dateTimePickerBegin = this.$el.find('#mpms-search #date_begin');
|
||||||
|
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
|
||||||
|
|
||||||
|
var $dateEndDays = this.$el.find('#mpms-search #date_end_days');
|
||||||
|
$dateEndDays.val('month');
|
||||||
|
$dateEndDays.trigger('change');
|
||||||
|
|
||||||
|
this._last_dates = this.generate_params()['dates'];
|
||||||
this.trigger_up('onLoadCalendar');
|
this.trigger_up('onLoadCalendar');
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -374,25 +363,23 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
|
|||||||
var self = this;
|
var self = this;
|
||||||
isStartDate = isStartDate || false;
|
isStartDate = isStartDate || false;
|
||||||
var $dateTimePickerBegin = this.$el.find('#mpms-search #date_begin');
|
var $dateTimePickerBegin = this.$el.find('#mpms-search #date_begin');
|
||||||
var $dateTimePickerEnd = this.$el.find('#mpms-search #date_end');
|
var $dateEndDays = this.$el.find('#mpms-search #date_end_days');
|
||||||
|
|
||||||
// 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") || $dateEndDays.data("ignore_onchange")) {
|
||||||
$dateTimePickerBegin.data("ignore_onchange", false);
|
$dateTimePickerBegin.data("ignore_onchange", false);
|
||||||
$dateTimePickerEnd.data("ignore_onchange", false)
|
$dateEndDays.data("ignore_onchange", false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().set({'hour': 0, 'minute': 0, 'second': 0}).clone();
|
var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().set({'hour': 0, 'minute': 0, 'second': 0}).clone();
|
||||||
|
|
||||||
if (this._hcalendar && date_begin) {
|
if (this._hcalendar && date_begin) {
|
||||||
if (isStartDate) {
|
var days = $dateEndDays.val();
|
||||||
var ndate_end = date_begin.clone().add(this._view_options['days'], 'd');
|
if (days === 'month') {
|
||||||
$dateTimePickerEnd.data("ignore_onchange", true);
|
days = date_begin.daysInMonth();
|
||||||
$dateTimePickerEnd.data("DateTimePicker").date(ndate_end.local());
|
|
||||||
}
|
}
|
||||||
|
var date_end = date_begin.set({'hour': 23, 'minute': 59, 'second': 59}).clone().add(days, 'd');
|
||||||
var date_end = $dateTimePickerEnd.data("DateTimePicker").date().set({'hour': 23, 'minute': 59, 'second': 59}).clone();
|
|
||||||
|
|
||||||
this._check_unsaved_changes(function(){
|
this._check_unsaved_changes(function(){
|
||||||
self._hcalendar.setStartDate(date_begin, self._hcalendar.getDateDiffDays(date_begin, date_end));
|
self._hcalendar.setStartDate(date_begin, self._hcalendar.getDateDiffDays(date_begin, date_end));
|
||||||
@@ -411,11 +398,15 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
|
|||||||
var restrictions = this.$el.find('#mpms-search #restriction_list').val();
|
var restrictions = this.$el.find('#mpms-search #restriction_list').val();
|
||||||
|
|
||||||
var $dateTimePickerBegin = this.$el.find('#mpms-search #date_begin');
|
var $dateTimePickerBegin = this.$el.find('#mpms-search #date_begin');
|
||||||
var $dateTimePickerEnd = this.$el.find('#mpms-search #date_end');
|
var $dateEndDays = this.$el.find('#mpms-search #date_end_days');
|
||||||
|
|
||||||
var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().set({'hour': 0, 'minute': 0, 'second': 0}).clone().utc().format(HotelConstants.ODOO_DATE_MOMENT_FORMAT);
|
var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().set({'hour': 0, 'minute': 0, 'second': 0}).clone();
|
||||||
var date_end = $dateTimePickerEnd.data("DateTimePicker").date().set({'hour': 23, 'minute': 59, 'second': 59}).clone().utc().format(HotelConstants.ODOO_DATE_MOMENT_FORMAT);
|
|
||||||
|
|
||||||
|
var days = $dateEndDays.val();
|
||||||
|
if (days === 'month') {
|
||||||
|
days = date_begin.daysInMonth();
|
||||||
|
}
|
||||||
|
var date_end = date_begin.set({'hour': 23, 'minute': 59, 'second': 59}).clone().add(days, 'd');
|
||||||
return {
|
return {
|
||||||
'dates': [date_begin, date_end],
|
'dates': [date_begin, date_end],
|
||||||
'prices': prices,
|
'prices': prices,
|
||||||
@@ -428,6 +419,7 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
|
|||||||
var btn_save = this.$el.find("#btn_save_changes");
|
var btn_save = this.$el.find("#btn_save_changes");
|
||||||
if (!btn_save.hasClass('need-save')) {
|
if (!btn_save.hasClass('need-save')) {
|
||||||
btn_save.removeClass('need-save');
|
btn_save.removeClass('need-save');
|
||||||
|
document.getElementById("btn_save_changes").disabled = true;
|
||||||
fnCallback();
|
fnCallback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -440,6 +432,7 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
|
|||||||
classes: 'btn-primary',
|
classes: 'btn-primary',
|
||||||
close: true,
|
close: true,
|
||||||
click: function() {
|
click: function() {
|
||||||
|
document.getElementById("btn_save_changes").disabled = true;
|
||||||
self.save_changes();
|
self.save_changes();
|
||||||
fnCallback();
|
fnCallback();
|
||||||
}
|
}
|
||||||
@@ -449,6 +442,7 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
|
|||||||
close: true,
|
close: true,
|
||||||
click: function() {
|
click: function() {
|
||||||
btn_save.removeClass('need-save');
|
btn_save.removeClass('need-save');
|
||||||
|
document.getElementById("btn_save_changes").disabled = true;
|
||||||
fnCallback();
|
fnCallback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1240,6 +1240,8 @@ HotelCalendar.prototype = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// Initialize Save Button state to disable
|
||||||
|
this.btnSaveChanges.disabled = true;
|
||||||
cell.appendChild(this.btnSaveChanges);
|
cell.appendChild(this.btnSaveChanges);
|
||||||
}
|
}
|
||||||
//cell.setAttribute('class', 'col-xs-1 col-lg-1');
|
//cell.setAttribute('class', 'col-xs-1 col-lg-1');
|
||||||
@@ -2451,8 +2453,10 @@ HotelCalendar.prototype = {
|
|||||||
if (this.edivc.querySelector('.hcal-input-changed') !== null)
|
if (this.edivc.querySelector('.hcal-input-changed') !== null)
|
||||||
{
|
{
|
||||||
this.btnSaveChanges.classList.add('need-save');
|
this.btnSaveChanges.classList.add('need-save');
|
||||||
|
this.btnSaveChanges.disabled = false;
|
||||||
} else {
|
} else {
|
||||||
this.btnSaveChanges.classList.remove('need-save');
|
this.btnSaveChanges.classList.remove('need-save');
|
||||||
|
this.btnSaveChanges.disabled = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -22,22 +22,27 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<span class="filter-title">FROM</span><br/>
|
<span class="filter-title">FROM</span>
|
||||||
<div class="input-group date" id="date_begin">
|
<div class="input-group date" id="date_begin">
|
||||||
<input type="text" class="o_datepicker_input form-control" name="date_begin" required="required" />
|
<input type="text" class="o_datepicker_input form-control" name="date_begin" required="required" />
|
||||||
<span class="input-group-addon">
|
<span class="input-group-addon">
|
||||||
<span class="fa fa-calendar"></span>
|
<span class="fa fa-calendar"></span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="filter-title">TO</span><br/>
|
<span class="filter-title">RANGE</span>
|
||||||
<div class="input-group date" id="date_end">
|
<div class="input-group date">
|
||||||
<input type="text" class="o_datepicker_input form-control" name="date_end" required="required" />
|
<input id="date_end_days" required="required" class="form-control" />
|
||||||
<span class="input-group-addon">
|
</div>
|
||||||
<span class="fa fa-calendar"></span>
|
<!-- <span class="filter-title">TO</span><br/>-->
|
||||||
</span>
|
<!-- <div class="input-group date" id="date_end">-->
|
||||||
</div>
|
<!-- <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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ var PMSHotelCalendarController = PMSCalendarController.include({
|
|||||||
}
|
}
|
||||||
else if (notif[1]['type'] === 'reservation') {
|
else if (notif[1]['type'] === 'reservation') {
|
||||||
var reserv = notif[1]['reservation'];
|
var reserv = notif[1]['reservation'];
|
||||||
if (reserv['external_id']) {
|
if (reserv['channel_type'] == 'web') {
|
||||||
if (notif[1]['action'] === 'create') {
|
if (notif[1]['action'] === 'create') {
|
||||||
this._play_sound(this.SOUNDS.BOOK_NEW);
|
this._play_sound(this.SOUNDS.BOOK_NEW);
|
||||||
} else if (notif[1]['action'] !== 'unlink' && reserv['state'] === 'cancelled') {
|
} else if (notif[1]['action'] !== 'unlink' && reserv['state'] === 'cancelled') {
|
||||||
|
|||||||
@@ -267,11 +267,11 @@ class ChannelBackend(models.Model):
|
|||||||
_logger.warning(msg)
|
_logger.warning(msg)
|
||||||
|
|
||||||
email_values.update({'body_html': email_values['body_html'] + msg + '<br/>'})
|
email_values.update({'body_html': email_values['body_html'] + msg + '<br/>'})
|
||||||
|
|
||||||
if len(email_values['body_html']) > 0:
|
if len(email_values['body_html']) > 0:
|
||||||
template = self.env.ref('hotel_channel_connector.mail_template_hotel_availability_watchdog')
|
if 'email_to' in self._context:
|
||||||
email_values.update({'email_to': self._context['email_to']})
|
template = self.env.ref('hotel_channel_connector.mail_template_hotel_availability_watchdog')
|
||||||
template.send_mail(self.id, email_values=email_values)
|
email_values.update({'email_to': self._context['email_to']})
|
||||||
|
template.send_mail(self.id, email_values=email_values)
|
||||||
# push availability on demand
|
# push availability on demand
|
||||||
self.with_context({'show_notify': False}).push_availability()
|
self.with_context({'show_notify': False}).push_availability()
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from odoo import api, models, fields, _
|
from odoo import api, models, fields, _
|
||||||
from odoo.exceptions import UserError
|
|
||||||
from odoo.exceptions import ValidationError
|
from odoo.exceptions import ValidationError
|
||||||
from odoo.addons import decimal_precision as dp
|
from odoo.addons import decimal_precision as dp
|
||||||
from odoo.addons.queue_job.job import job
|
from odoo.addons.queue_job.job import job
|
||||||
@@ -26,7 +25,6 @@ class ChannelHotelRoomType(models.Model):
|
|||||||
def _default_availability(self):
|
def _default_availability(self):
|
||||||
return max(min(self.default_quota, self.default_max_avail), 0)
|
return max(min(self.default_quota, self.default_max_avail), 0)
|
||||||
|
|
||||||
|
|
||||||
odoo_id = fields.Many2one(comodel_name='hotel.room.type',
|
odoo_id = fields.Many2one(comodel_name='hotel.room.type',
|
||||||
string='Room Type',
|
string='Room Type',
|
||||||
required=True,
|
required=True,
|
||||||
@@ -139,6 +137,14 @@ class HotelRoomType(models.Model):
|
|||||||
for record in self:
|
for record in self:
|
||||||
record.capacity = record.get_capacity()
|
record.capacity = record.get_capacity()
|
||||||
|
|
||||||
|
@api.constrains('active')
|
||||||
|
def _check_active(self):
|
||||||
|
for record in self:
|
||||||
|
if not record.active and record.total_rooms_count > 0:
|
||||||
|
raise ValidationError(
|
||||||
|
_("You can not archive a room type with active rooms.") + " " +
|
||||||
|
_("Please, change the %s room(s) to other room type.") % str(record.total_rooms_count))
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def get_restrictions(self, date, restriction_plan_id):
|
def get_restrictions(self, date, restriction_plan_id):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
@@ -172,10 +178,14 @@ class HotelRoomType(models.Model):
|
|||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def disconnect_channel_bind_ids(self):
|
def disconnect_channel_bind_ids(self):
|
||||||
channel_bind_ids = self.mapped('channel_bind_ids')
|
# TODO: multichannel rooms is not implemented
|
||||||
msg = _("This function is not yet implemented.")
|
self.channel_bind_ids.with_context({'connector_no_export': True}).unlink()
|
||||||
msg += _(" The room type [%s] should be delete from the channel manager.") % channel_bind_ids.get_external_id
|
|
||||||
raise UserError(msg)
|
@api.multi
|
||||||
|
def write(self, vals):
|
||||||
|
if 'active' in vals and vals.get('active') is False:
|
||||||
|
self.channel_bind_ids.unlink()
|
||||||
|
return super().write(vals)
|
||||||
|
|
||||||
|
|
||||||
class BindingHotelRoomTypeListener(Component):
|
class BindingHotelRoomTypeListener(Component):
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ class ChannelHotelRoomTypeRestriction(models.Model):
|
|||||||
importer = work.component(usage='hotel.room.type.restriction.importer')
|
importer = work.component(usage='hotel.room.type.restriction.importer')
|
||||||
return importer.import_restriction_plans()
|
return importer.import_restriction_plans()
|
||||||
|
|
||||||
|
|
||||||
class HotelRoomTypeRestriction(models.Model):
|
class HotelRoomTypeRestriction(models.Model):
|
||||||
_inherit = 'hotel.room.type.restriction'
|
_inherit = 'hotel.room.type.restriction'
|
||||||
|
|
||||||
@@ -99,10 +100,15 @@ class HotelRoomTypeRestriction(models.Model):
|
|||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def disconnect_channel_bind_ids(self):
|
def disconnect_channel_bind_ids(self):
|
||||||
channel_bind_ids = self.mapped('channel_bind_ids')
|
# TODO: multichannel rooms is not implemented
|
||||||
msg = _("This function is not yet implemented.")
|
self.channel_bind_ids.with_context({'connector_no_export': True}).unlink()
|
||||||
msg += _(" The restriction plan [%s] should be delete from the channel manager.") % channel_bind_ids.get_external_id
|
|
||||||
raise UserError(msg)
|
@api.multi
|
||||||
|
def write(self, vals):
|
||||||
|
if 'active' in vals and vals.get('active') is False:
|
||||||
|
self.channel_bind_ids.unlink()
|
||||||
|
return super().write(vals)
|
||||||
|
|
||||||
|
|
||||||
class BindingHotelRoomTypeListener(Component):
|
class BindingHotelRoomTypeListener(Component):
|
||||||
_name = 'binding.hotel.room.type.restriction.listener'
|
_name = 'binding.hotel.room.type.restriction.listener'
|
||||||
@@ -115,6 +121,7 @@ class BindingHotelRoomTypeListener(Component):
|
|||||||
for binding in record.channel_bind_ids:
|
for binding in record.channel_bind_ids:
|
||||||
binding.update_plan_name()
|
binding.update_plan_name()
|
||||||
|
|
||||||
|
|
||||||
class ChannelBindingHotelRoomTypeRestrictionListener(Component):
|
class ChannelBindingHotelRoomTypeRestrictionListener(Component):
|
||||||
_name = 'channel.binding.hotel.room.type.restriction.listener'
|
_name = 'channel.binding.hotel.room.type.restriction.listener'
|
||||||
_inherit = 'base.connector.listener'
|
_inherit = 'base.connector.listener'
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class HotelRoom(models.Model):
|
|||||||
|
|
||||||
channel_availability = self.env['channel.hotel.room.type.availability'].search([
|
channel_availability = self.env['channel.hotel.room.type.availability'].search([
|
||||||
('room_type_id', '=', item['old_room_type_id']),
|
('room_type_id', '=', item['old_room_type_id']),
|
||||||
('channel_avail', '>=', old_room_type_total_rooms_count),
|
('channel_avail', '>', old_room_type_total_rooms_count),
|
||||||
('date', '>=', _today)
|
('date', '>=', _today)
|
||||||
], order='date asc') or False
|
], order='date asc') or False
|
||||||
if channel_availability:
|
if channel_availability:
|
||||||
@@ -119,6 +119,11 @@ class HotelRoom(models.Model):
|
|||||||
checkout=dto,
|
checkout=dto,
|
||||||
backend_id=new_channel_room_type.backend_id.id,
|
backend_id=new_channel_room_type.backend_id.id,
|
||||||
room_type_id=item['new_room_type_id'], )
|
room_type_id=item['new_room_type_id'], )
|
||||||
|
# TODO: channel_backend MUST be the same for both room types
|
||||||
|
channel_backend = self.env['channel.hotel.room.type'].search([
|
||||||
|
('odoo_id', '=', vals.get('room_type_id'))
|
||||||
|
]).backend_id
|
||||||
|
channel_backend.channel_availability_watchdog()
|
||||||
else:
|
else:
|
||||||
res = super().write(vals)
|
res = super().write(vals)
|
||||||
return res
|
return res
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ class ProductPricelist(models.Model):
|
|||||||
inverse_name='odoo_id',
|
inverse_name='odoo_id',
|
||||||
string='Hotel Channel Connector Bindings')
|
string='Hotel Channel Connector Bindings')
|
||||||
|
|
||||||
|
|
||||||
pricelist_type = fields.Selection(selection_add=[
|
pricelist_type = fields.Selection(selection_add=[
|
||||||
('virtual', 'Virtual Plan'),
|
('virtual', 'Virtual Plan'),
|
||||||
])
|
])
|
||||||
@@ -104,7 +103,6 @@ class ProductPricelist(models.Model):
|
|||||||
for item in record.item_ids):
|
for item in record.item_ids):
|
||||||
record.is_virtual_plan = False
|
record.is_virtual_plan = False
|
||||||
|
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
@api.depends('name')
|
@api.depends('name')
|
||||||
def name_get(self):
|
def name_get(self):
|
||||||
@@ -144,10 +142,14 @@ class ProductPricelist(models.Model):
|
|||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def disconnect_channel_bind_ids(self):
|
def disconnect_channel_bind_ids(self):
|
||||||
channel_bind_ids = self.mapped('channel_bind_ids')
|
# TODO: multichannel rooms is not implemented
|
||||||
msg = _("This function is not yet implemented.")
|
self.channel_bind_ids.with_context({'connector_no_export': True}).unlink()
|
||||||
msg += _(" The pricelist [%s] should be delete from the channel manager.") % channel_bind_ids.get_external_id
|
|
||||||
raise UserError(msg)
|
@api.multi
|
||||||
|
def write(self, vals):
|
||||||
|
if 'active' in vals and vals.get('active') is False:
|
||||||
|
self.channel_bind_ids.unlink()
|
||||||
|
return super().write(vals)
|
||||||
|
|
||||||
|
|
||||||
class BindingProductPricelistListener(Component):
|
class BindingProductPricelistListener(Component):
|
||||||
|
|||||||
@@ -5,20 +5,39 @@
|
|||||||
<field name="model">hotel.room.type.restriction</field>
|
<field name="model">hotel.room.type.restriction</field>
|
||||||
<field name="inherit_id" ref="hotel.room_type_restriction_view_form" />
|
<field name="inherit_id" ref="hotel.room_type_restriction_view_form" />
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//form/sheet" position="inside">
|
||||||
|
<field name="channel_bind_ids" invisible="1" />
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<xpath expr="//button[@name='toggle_active']" position="replace">
|
||||||
|
<!-- custom message for warning when archiving a channel restriction plan with binding -->
|
||||||
|
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive"
|
||||||
|
confirm="Archive a restriction plan will automatically delete the restriction plan in the Channel.
|
||||||
|
Do you want to proceed?"
|
||||||
|
attrs="{'invisible': [('channel_bind_ids', '=', [])]}">
|
||||||
|
<field name="active" widget="boolean_button" options='{"terminology": "archive"}'/>
|
||||||
|
</button>
|
||||||
|
<!-- default message for archiving a channel restriction plan without binding -->
|
||||||
|
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive"
|
||||||
|
attrs="{'invisible': [('channel_bind_ids','!=', [])]}">
|
||||||
|
<field name="active" widget="boolean_button" options='{"terminology": "archive"}'/>
|
||||||
|
</button>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
<xpath expr="//button[@name='toggle_active']" position="before">
|
<xpath expr="//button[@name='toggle_active']" position="before">
|
||||||
<field name="channel_bind_ids" invisible="1" />
|
|
||||||
<button name="open_channel_bind_ids" type="object"
|
<button name="open_channel_bind_ids" type="object"
|
||||||
class="oe_stat_button" icon="fa-toggle-off" string="Connect to Channel"
|
class="oe_stat_button" icon="fa-toggle-off" string="Connect to Channel"
|
||||||
attrs="{'invisible': [('channel_bind_ids','!=', [])]}"
|
attrs="{'invisible': ['|', ('channel_bind_ids','!=', []), ('active','=', False) ]}"
|
||||||
/>
|
/>
|
||||||
<button name="open_channel_bind_ids" type="object"
|
<button name="open_channel_bind_ids" type="object"
|
||||||
class="oe_stat_button" icon="fa-cloud-upload" string="Synchronize to Channel"
|
class="oe_stat_button" icon="fa fa-gears" string="Configure Channel"
|
||||||
attrs="{'invisible': [('channel_bind_ids','=', [])]}"
|
attrs="{'invisible': [('channel_bind_ids','=', [])]}"
|
||||||
/>
|
/>
|
||||||
<button name="disconnect_channel_bind_ids" type="object"
|
<button name="disconnect_channel_bind_ids" type="object"
|
||||||
class="oe_stat_button" icon="fa-toggle-on" string="Disconnect from Channel"
|
class="oe_stat_button" icon="fa-toggle-on" string="Disconnect from Channel"
|
||||||
attrs="{'invisible': [('channel_bind_ids','=', [])]}"
|
attrs="{'invisible': [('channel_bind_ids','=', [])]}"
|
||||||
confirm="Disconnecting will automatically delete the restriction plan in the Channel. Do you want to proceed?"
|
confirm="Disconnecting will unbind the restriction plan from the Channel but it will not be deleted.
|
||||||
|
Do you want to proceed?"
|
||||||
/>
|
/>
|
||||||
</xpath>
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
|
|||||||
@@ -5,20 +5,43 @@
|
|||||||
<field name="model">hotel.room.type</field>
|
<field name="model">hotel.room.type</field>
|
||||||
<field name="inherit_id" ref="hotel.hotel_room_type_view_form" />
|
<field name="inherit_id" ref="hotel.hotel_room_type_view_form" />
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//form/sheet/notebook" position="inside">
|
||||||
|
<page string="Channel Bindings" invisible="1">
|
||||||
|
<field name="channel_bind_ids" />
|
||||||
|
</page>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<xpath expr="//button[@name='toggle_active']" position="replace">
|
||||||
|
<!-- custom message for warning when archiving a channel room type with binding -->
|
||||||
|
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive"
|
||||||
|
confirm="Archive a room type will automatically delete the room type in the Channel.
|
||||||
|
Ensure yourself no reservations are binded to this room type from today and hereafter.
|
||||||
|
Do you want to proceed?"
|
||||||
|
attrs="{'invisible': [('channel_bind_ids', '=', [])]}">
|
||||||
|
<field name="active" widget="boolean_button" options='{"terminology": "archive"}'/>
|
||||||
|
</button>
|
||||||
|
<!-- default message for archiving a channel room type without binding -->
|
||||||
|
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive"
|
||||||
|
attrs="{'invisible': [('channel_bind_ids','!=', [])]}">
|
||||||
|
<field name="active" widget="boolean_button" options='{"terminology": "archive"}'/>
|
||||||
|
</button>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
<xpath expr="//button[@name='toggle_active']" position="before">
|
<xpath expr="//button[@name='toggle_active']" position="before">
|
||||||
<field name="channel_bind_ids" invisible="1" />
|
|
||||||
<button name="open_channel_bind_ids" type="object"
|
<button name="open_channel_bind_ids" type="object"
|
||||||
class="oe_stat_button" icon="fa-toggle-off" string="Connect to Channel"
|
class="oe_stat_button" icon="fa-toggle-off" string="Connect to Channel"
|
||||||
attrs="{'invisible': [('channel_bind_ids','!=', [])]}"
|
attrs="{'invisible': ['|', ('channel_bind_ids','!=', []), ('active','=', False) ]}"
|
||||||
/>
|
/>
|
||||||
<button name="open_channel_bind_ids" type="object"
|
<button name="open_channel_bind_ids" type="object"
|
||||||
class="oe_stat_button" icon="fa-cloud-upload" string="Synchronize to Channel"
|
class="oe_stat_button" icon="fa fa-gears" string="Configure Channel"
|
||||||
attrs="{'invisible': [('channel_bind_ids','=', [])]}"
|
attrs="{'invisible': [('channel_bind_ids','=', [])]}"
|
||||||
/>
|
/>
|
||||||
<button name="disconnect_channel_bind_ids" type="object"
|
<button name="disconnect_channel_bind_ids" type="object"
|
||||||
class="oe_stat_button" icon="fa-toggle-on" string="Disconnect from Channel"
|
class="oe_stat_button" icon="fa-toggle-on" string="Disconnect from Channel"
|
||||||
attrs="{'invisible': [('channel_bind_ids','=', [])]}"
|
attrs="{'invisible': [('channel_bind_ids','=', [])]}"
|
||||||
confirm="Disconnecting will automatically delete the room type in the Channel. Do you want to proceed?"
|
confirm="Disconnecting will unbind the room type from the Channel but it will not be deleted.
|
||||||
|
Ensure yourself no reservations are binded to this room type from today and hereafter.
|
||||||
|
Do you want to proceed?"
|
||||||
/>
|
/>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|
||||||
|
|||||||
@@ -5,20 +5,39 @@
|
|||||||
<field name="model">product.pricelist</field>
|
<field name="model">product.pricelist</field>
|
||||||
<field name="inherit_id" ref="product.product_pricelist_view" />
|
<field name="inherit_id" ref="product.product_pricelist_view" />
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//form/sheet" position="inside">
|
||||||
|
<field name="channel_bind_ids" invisible="1" />
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<xpath expr="//button[@name='toggle_active']" position="replace">
|
||||||
|
<!-- custom message for warning when archiving a channel pricelist plan with binding -->
|
||||||
|
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive"
|
||||||
|
confirm="Archive a pricelist plan will automatically delete the pricelist plan in the Channel.
|
||||||
|
Do you want to proceed?"
|
||||||
|
attrs="{'invisible': [('channel_bind_ids', '=', [])]}">
|
||||||
|
<field name="active" widget="boolean_button" options='{"terminology": "archive"}'/>
|
||||||
|
</button>
|
||||||
|
<!-- default message for archiving a channel pricelist plan without binding -->
|
||||||
|
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive"
|
||||||
|
attrs="{'invisible': [('channel_bind_ids','!=', [])]}">
|
||||||
|
<field name="active" widget="boolean_button" options='{"terminology": "archive"}'/>
|
||||||
|
</button>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
<xpath expr="//button[@name='toggle_active']" position="before">
|
<xpath expr="//button[@name='toggle_active']" position="before">
|
||||||
<field name="channel_bind_ids" invisible="1" />
|
|
||||||
<button name="open_channel_bind_ids" type="object"
|
<button name="open_channel_bind_ids" type="object"
|
||||||
class="oe_stat_button" icon="fa-toggle-off" string="Connect to Channel"
|
class="oe_stat_button" icon="fa-toggle-off" string="Connect to Channel"
|
||||||
attrs="{'invisible': [('channel_bind_ids','!=', [])]}"
|
attrs="{'invisible': ['|', ('channel_bind_ids','!=', []), ('active','=', False) ]}"
|
||||||
/>
|
/>
|
||||||
<button name="open_channel_bind_ids" type="object"
|
<button name="open_channel_bind_ids" type="object"
|
||||||
class="oe_stat_button" icon="fa-cloud-upload" string="Synchronize to Channel"
|
class="oe_stat_button" icon="fa fa-gears" string="Configure Channel"
|
||||||
attrs="{'invisible': [('channel_bind_ids','=', [])]}"
|
attrs="{'invisible': [('channel_bind_ids','=', [])]}"
|
||||||
/>
|
/>
|
||||||
<button name="disconnect_channel_bind_ids" type="object"
|
<button name="disconnect_channel_bind_ids" type="object"
|
||||||
class="oe_stat_button" icon="fa-toggle-on" string="Disconnect from Channel"
|
class="oe_stat_button" icon="fa-toggle-on" string="Disconnect from Channel"
|
||||||
attrs="{'invisible': [('channel_bind_ids','=', [])]}"
|
attrs="{'invisible': [('channel_bind_ids','=', [])]}"
|
||||||
confirm="Disconnecting will automatically delete the pricelist in the Channel. Do you want to proceed?"
|
confirm="Disconnecting will unbind the pricelist plan from the Channel but it will not be deleted.
|
||||||
|
Do you want to proceed?"
|
||||||
/>
|
/>
|
||||||
</xpath>
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
from odoo.addons.component.core import Component
|
from odoo.addons.component.core import Component
|
||||||
from odoo.addons.hotel_channel_connector.components.core import ChannelConnectorError
|
from odoo.addons.hotel_channel_connector.components.core import ChannelConnectorError
|
||||||
from odoo import api
|
from odoo import api, _
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
class HotelRoomTypeDeleter(Component):
|
class HotelRoomTypeDeleter(Component):
|
||||||
@@ -18,3 +19,4 @@ class HotelRoomTypeDeleter(Component):
|
|||||||
section='room',
|
section='room',
|
||||||
internal_message=str(err),
|
internal_message=str(err),
|
||||||
channel_message=err.data['message'])
|
channel_message=err.data['message'])
|
||||||
|
raise ValidationError(_(err.data['message']) + ". " + _(str(err)))
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
from odoo.addons.component.core import Component
|
from odoo.addons.component.core import Component
|
||||||
from odoo.addons.hotel_channel_connector.components.core import ChannelConnectorError
|
from odoo.addons.hotel_channel_connector.components.core import ChannelConnectorError
|
||||||
from odoo import api, fields
|
from odoo import api, fields, _
|
||||||
|
from odoo.exceptions import AccessError, UserError, ValidationError
|
||||||
|
|
||||||
|
|
||||||
class HotelRoomTypeExporter(Component):
|
class HotelRoomTypeExporter(Component):
|
||||||
@@ -44,6 +45,7 @@ class HotelRoomTypeExporter(Component):
|
|||||||
section='room',
|
section='room',
|
||||||
internal_message=str(err),
|
internal_message=str(err),
|
||||||
channel_message=err.data['message'])
|
channel_message=err.data['message'])
|
||||||
|
raise ValidationError(_(err.data['message']))
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def create_room(self, binding):
|
def create_room(self, binding):
|
||||||
@@ -78,6 +80,7 @@ class HotelRoomTypeExporter(Component):
|
|||||||
section='room',
|
section='room',
|
||||||
internal_message=str(err),
|
internal_message=str(err),
|
||||||
channel_message=err.data['message'])
|
channel_message=err.data['message'])
|
||||||
|
raise ValidationError(_(err.data['message']))
|
||||||
else:
|
else:
|
||||||
binding.with_context({
|
binding.with_context({
|
||||||
'connector_no_export': True,
|
'connector_no_export': True,
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
from odoo.addons.component.core import Component
|
from odoo.addons.component.core import Component
|
||||||
from odoo.addons.hotel_channel_connector.components.core import ChannelConnectorError
|
from odoo.addons.hotel_channel_connector.components.core import ChannelConnectorError
|
||||||
from odoo import api
|
from odoo import api, _
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
class HotelRoomTypeRestrictionDeleter(Component):
|
class HotelRoomTypeRestrictionDeleter(Component):
|
||||||
@@ -18,3 +19,4 @@ class HotelRoomTypeRestrictionDeleter(Component):
|
|||||||
section='restriction',
|
section='restriction',
|
||||||
internal_message=str(err),
|
internal_message=str(err),
|
||||||
channel_message=err.data['message'])
|
channel_message=err.data['message'])
|
||||||
|
raise ValidationError(_(err.data['message']) + ". " + _(str(err)))
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
from odoo.addons.component.core import Component
|
from odoo.addons.component.core import Component
|
||||||
from odoo.addons.hotel_channel_connector.components.core import ChannelConnectorError
|
from odoo.addons.hotel_channel_connector.components.core import ChannelConnectorError
|
||||||
from odoo import api, fields
|
from odoo import api, fields, _
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
class HotelRoomTypeRestrictionExporter(Component):
|
class HotelRoomTypeRestrictionExporter(Component):
|
||||||
@@ -23,6 +24,7 @@ class HotelRoomTypeRestrictionExporter(Component):
|
|||||||
section='restriction',
|
section='restriction',
|
||||||
internal_message=str(err),
|
internal_message=str(err),
|
||||||
channel_message=err.data['message'])
|
channel_message=err.data['message'])
|
||||||
|
raise ValidationError(_(err.data['message']))
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def create_rplan(self, binding):
|
def create_rplan(self, binding):
|
||||||
@@ -33,5 +35,6 @@ class HotelRoomTypeRestrictionExporter(Component):
|
|||||||
section='restriction',
|
section='restriction',
|
||||||
internal_message=str(err),
|
internal_message=str(err),
|
||||||
channel_message=err.data['message'])
|
channel_message=err.data['message'])
|
||||||
|
raise ValidationError(_(err.data['message']))
|
||||||
else:
|
else:
|
||||||
self.binder.bind(external_id, binding)
|
self.binder.bind(external_id, binding)
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
from odoo.addons.component.core import Component
|
from odoo.addons.component.core import Component
|
||||||
from odoo.addons.hotel_channel_connector.components.core import ChannelConnectorError
|
from odoo.addons.hotel_channel_connector.components.core import ChannelConnectorError
|
||||||
from odoo import api
|
from odoo import api, _
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
class ProductPricelistDeleter(Component):
|
class ProductPricelistDeleter(Component):
|
||||||
@@ -18,3 +19,4 @@ class ProductPricelistDeleter(Component):
|
|||||||
section='pricelist',
|
section='pricelist',
|
||||||
internal_message=str(err),
|
internal_message=str(err),
|
||||||
channel_message=err.data['message'])
|
channel_message=err.data['message'])
|
||||||
|
raise ValidationError(_(err.data['message']) + ". " + _(str(err)))
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
from odoo.addons.component.core import Component
|
from odoo.addons.component.core import Component
|
||||||
from odoo.addons.hotel_channel_connector.components.core import ChannelConnectorError
|
from odoo.addons.hotel_channel_connector.components.core import ChannelConnectorError
|
||||||
from odoo import api, _, fields
|
from odoo import api, fields, _
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
class ProductPricelistExporter(Component):
|
class ProductPricelistExporter(Component):
|
||||||
@@ -23,6 +24,7 @@ class ProductPricelistExporter(Component):
|
|||||||
section='pricelist',
|
section='pricelist',
|
||||||
internal_message=str(err),
|
internal_message=str(err),
|
||||||
channel_message=err.data['message'])
|
channel_message=err.data['message'])
|
||||||
|
raise ValidationError(_(err.data['message']))
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def create_plan(self, binding):
|
def create_plan(self, binding):
|
||||||
@@ -33,6 +35,7 @@ class ProductPricelistExporter(Component):
|
|||||||
section='pricelist',
|
section='pricelist',
|
||||||
internal_message=str(err),
|
internal_message=str(err),
|
||||||
channel_message=err.data['message'])
|
channel_message=err.data['message'])
|
||||||
|
raise ValidationError(_(err.data['message']))
|
||||||
else:
|
else:
|
||||||
binding.external_id = external_id
|
binding.external_id = external_id
|
||||||
self.binder.bind(external_id, binding)
|
self.binder.bind(external_id, binding)
|
||||||
@@ -67,6 +70,7 @@ class ProductPricelistExporter(Component):
|
|||||||
section='pricelist',
|
section='pricelist',
|
||||||
internal_message=str(err),
|
internal_message=str(err),
|
||||||
channel_message=err.data['message'])
|
channel_message=err.data['message'])
|
||||||
|
raise ValidationError(_(err.data['message']))
|
||||||
else:
|
else:
|
||||||
binding.external_id = external_id
|
binding.external_id = external_id
|
||||||
self.binder.bind(external_id, binding)
|
self.binder.bind(external_id, binding)
|
||||||
@@ -102,3 +106,4 @@ class ProductPricelistExporter(Component):
|
|||||||
section='pricelist',
|
section='pricelist',
|
||||||
internal_message=str(err),
|
internal_message=str(err),
|
||||||
channel_message=err.data['message'])
|
channel_message=err.data['message'])
|
||||||
|
raise ValidationError(_(err.data['message']))
|
||||||
|
|||||||
@@ -564,6 +564,7 @@ class Data_Bi(models.Model):
|
|||||||
precio_comision = inv_percent(
|
precio_comision = inv_percent(
|
||||||
precio_neto, expedia_rate[1]) - precio_neto
|
precio_neto, expedia_rate[1]) - precio_neto
|
||||||
precio_calculo = precio_neto + precio_comision
|
precio_calculo = precio_neto + precio_comision
|
||||||
|
precio_neto -= precio_comision
|
||||||
# iva "interno" de expedia.....
|
# iva "interno" de expedia.....
|
||||||
precio_iva2 = (precio_calculo*1.1) - precio_calculo
|
precio_iva2 = (precio_calculo*1.1) - precio_calculo
|
||||||
precio_calculo += precio_iva2
|
precio_calculo += precio_iva2
|
||||||
|
|||||||
@@ -20,12 +20,11 @@ class HotelFolio(models.Model):
|
|||||||
if not stay.get('ReservationCode'):
|
if not stay.get('ReservationCode'):
|
||||||
reservation_obj = self.env['hotel.reservation']
|
reservation_obj = self.env['hotel.reservation']
|
||||||
vals = {
|
vals = {
|
||||||
'checkin': datetime.strptime(
|
'checkin': stay["Arrival"],
|
||||||
stay["Arrival"], DEFAULT_ROOMMATIK_DATE_FORMAT).date(),
|
'checkout': stay["Departure"],
|
||||||
'checkout': datetime.strptime(
|
|
||||||
stay["Departure"], DEFAULT_ROOMMATIK_DATE_FORMAT).date(),
|
|
||||||
'adults': stay['Adults'],
|
'adults': stay['Adults'],
|
||||||
'room_type_id': stay['RoomType'],
|
'arrival_hour': stay['Arrival_hour'],
|
||||||
|
'room_type_id': stay['RoomType']['Id'],
|
||||||
'partner_id': stay["Customers"][0]["Id"]
|
'partner_id': stay["Customers"][0]["Id"]
|
||||||
}
|
}
|
||||||
reservation_rm = reservation_obj.create(vals)
|
reservation_rm = reservation_obj.create(vals)
|
||||||
@@ -42,11 +41,9 @@ class HotelFolio(models.Model):
|
|||||||
checkin_partner_val = {
|
checkin_partner_val = {
|
||||||
'folio_id': reservation_rm.folio_id.id,
|
'folio_id': reservation_rm.folio_id.id,
|
||||||
'reservation_id': reservation_rm.id,
|
'reservation_id': reservation_rm.id,
|
||||||
'enter_date': datetime.strptime(
|
'partner_id': room_partner["Id"],
|
||||||
stay["Arrival"], DEFAULT_ROOMMATIK_DATE_FORMAT).date(),
|
'enter_date': stay["Arrival"],
|
||||||
'exit_date': datetime.strptime(
|
'exit_date': stay["Departure"],
|
||||||
stay["Departure"], DEFAULT_ROOMMATIK_DATE_FORMAT).date(),
|
|
||||||
'partner_id': room_partner["Customer"]["Id"],
|
|
||||||
}
|
}
|
||||||
try:
|
try:
|
||||||
record = self.env['hotel.checkin.partner'].create(
|
record = self.env['hotel.checkin.partner'].create(
|
||||||
|
|||||||
Reference in New Issue
Block a user