Merge pull request #110 from hootel/sprint

Sprint 1
This commit is contained in:
Darío Lodeiros
2019-07-28 23:43:31 +02:00
committed by GitHub
21 changed files with 225 additions and 112 deletions

View File

@@ -52,6 +52,7 @@ class BusHotelCalendar(models.TransientModel):
'price_room_services_set': vals['price_room_services_set'],
'amount_total': vals['pending_amount'] + vals['invoices_paid'],
'real_dates': vals['real_dates'],
'channel_type': vals['channel_type'],
},
'tooltip': {
'folio_name': vals['folio_name'],

View File

@@ -94,7 +94,9 @@ class HotelReservation(models.Model):
'state': reserv['state'],
'price_room_services_set': reserv['price_room_services_set'],
'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({
reserv['id']: {
'folio_name': reserv['folio_name'],

View File

@@ -376,6 +376,7 @@ var PMSCalendarController = AbstractController.extend({
_assign_multi_calendar_events: function() {
var self = this;
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);
});

View File

@@ -84,7 +84,9 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
save_changes: function() {
var oparams = this.get_values_to_save();
this.trigger_up('onSaveChanges', oparams);
if (oparams) {
this.trigger_up('onSaveChanges', oparams);
}
},
resetSaveState: function() {
@@ -138,6 +140,9 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
// Sticky Header Days
$('.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) {
@@ -149,23 +154,19 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
var self = this;
this._hcalendar.addEventListener('hcOnChangeDate', function(ev){
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 $dateTimePickerEnd = self.$el.find('#mpms-search #date_end');
$dateTimePickerBegin.data("ignore_onchange", true);
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
$dateTimePickerEnd.data("DateTimePicker").date(date_end);
self.reload_hcalendar_management();
});
this._hcalendar.addEventListener('hcmOnInputChanged', function(ev){
var btn_save = self.$el.find('#btn_save_changes');
if (self._hcalendar.hasChangesToSave()) {
btn_save.addClass('need-save');
document.getElementById("btn_save_changes").disabled = false;
} else {
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,
//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 $dateTimePickerEnd = this.$el.find('#mpms-search #date_end');
$dateTimePickerBegin.datetimepicker(DTPickerOptions);
$dateTimePickerEnd.datetimepicker($.extend({}, DTPickerOptions, { 'useCurrent': false }));
$dateTimePickerBegin.on("dp.change", function (e) {
$dateTimePickerEnd.data("DateTimePicker").minDate(e.date.clone().add(3,'d'));
$dateTimePickerEnd.data("DateTimePicker").maxDate(e.date.clone().add(2,'M'));
$dateTimePickerBegin.data("DateTimePicker").hide(); // TODO: Odoo uses old datetimepicker version
self.on_change_filter_date(e, true);
});
$dateTimePickerEnd.on("dp.change", function (e) {
$dateTimePickerEnd.data("DateTimePicker").hide(); // TODO: Odoo uses old datetimepicker version
self.on_change_filter_date(e, false);
var $dateEndDays = this.$el.find('#mpms-search #date_end_days');
$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');
// var date_end = date_begin.clone().add(this._view_options['days'], 'd').endOf('day');
// $dateTimePickerBegin.data("ignore_onchange", true);
// $dateTimePickerBegin.data("DateTimePicker").date(date_begin);
// $dateTimePickerEnd.data("DateTimePicker").date(date_end);
// this._last_dates = this.generate_params()['dates'];
$dateEndDays.on("change", function (e) {
self.on_change_filter_date();
});
// View Events
this.$el.find("#mpms-search #cal-pag-prev-plus").on('click', function(ev){
// FIXME: Ugly repeated code. Change place.
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_end = $dateTimePickerEnd.data("DateTimePicker").date().subtract(14, 'd');
$dateTimePickerBegin.data("ignore_onchange", true);
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
$dateTimePickerEnd.data("DateTimePicker").date(date_end);
self.on_change_filter_date(ev, true);
ev.preventDefault();
});
this.$el.find("#mpms-search #cal-pag-prev").on('click', function(ev){
// FIXME: Ugly repeated code. Change place.
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_end = $dateTimePickerEnd.data("DateTimePicker").date().subtract(7, 'd');
$dateTimePickerBegin.data("ignore_onchange", true);
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
$dateTimePickerEnd.data("DateTimePicker").date(date_end);
self.on_change_filter_date(ev, true);
ev.preventDefault();
});
this.$el.find("#mpms-search #cal-pag-next-plus").on('click', function(ev){
// FIXME: Ugly repeated code. Change place.
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_end = $dateTimePickerEnd.data("DateTimePicker").date().add(14, 'd');
$dateTimePickerBegin.data("ignore_onchange", true);
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
$dateTimePickerEnd.data("DateTimePicker").date(date_end);
self.on_change_filter_date(ev, true);
ev.preventDefault();
});
this.$el.find("#mpms-search #cal-pag-next").on('click', function(ev){
// FIXME: Ugly repeated code. Change place.
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_end = $dateTimePickerEnd.data("DateTimePicker").date().add(7, 'd');
$dateTimePickerBegin.data("ignore_onchange", true);
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
$dateTimePickerEnd.data("DateTimePicker").date(date_end);
self.on_change_filter_date(ev, true);
ev.preventDefault();
});
this.$el.find("#mpms-search #cal-pag-selector").on('click', function(ev){
// FIXME: Ugly repeated code. Change place.
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_end = date_begin.clone().add(self._view_options['days'], 'd').endOf('day');
$dateTimePickerBegin.data("ignore_onchange", true);
$dateTimePickerBegin.data("DateTimePicker").date(date_begin);
$dateTimePickerEnd.data("DateTimePicker").date(date_end);
self.on_change_filter_date(ev, true);
ev.preventDefault();
});
// 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();
});
@@ -358,15 +347,15 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
} else {
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');
},
@@ -374,25 +363,23 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
var self = this;
isStartDate = isStartDate || false;
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)
if ($dateTimePickerBegin.data("ignore_onchange") || $dateTimePickerEnd.data("ignore_onchange")) {
if ($dateTimePickerBegin.data("ignore_onchange") || $dateEndDays.data("ignore_onchange")) {
$dateTimePickerBegin.data("ignore_onchange", false);
$dateTimePickerEnd.data("ignore_onchange", false)
$dateEndDays.data("ignore_onchange", false);
return true;
}
var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().set({'hour': 0, 'minute': 0, 'second': 0}).clone();
if (this._hcalendar && date_begin) {
if (isStartDate) {
var ndate_end = date_begin.clone().add(this._view_options['days'], 'd');
$dateTimePickerEnd.data("ignore_onchange", true);
$dateTimePickerEnd.data("DateTimePicker").date(ndate_end.local());
var days = $dateEndDays.val();
if (days === 'month') {
days = date_begin.daysInMonth();
}
var date_end = $dateTimePickerEnd.data("DateTimePicker").date().set({'hour': 23, 'minute': 59, 'second': 59}).clone();
var date_end = date_begin.set({'hour': 23, 'minute': 59, 'second': 59}).clone().add(days, 'd');
this._check_unsaved_changes(function(){
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 $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_end = $dateTimePickerEnd.data("DateTimePicker").date().set({'hour': 23, 'minute': 59, 'second': 59}).clone().utc().format(HotelConstants.ODOO_DATE_MOMENT_FORMAT);
var date_begin = $dateTimePickerBegin.data("DateTimePicker").date().set({'hour': 0, 'minute': 0, 'second': 0}).clone();
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 {
'dates': [date_begin, date_end],
'prices': prices,
@@ -428,6 +419,7 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
var btn_save = this.$el.find("#btn_save_changes");
if (!btn_save.hasClass('need-save')) {
btn_save.removeClass('need-save');
document.getElementById("btn_save_changes").disabled = true;
fnCallback();
return;
}
@@ -440,6 +432,7 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
classes: 'btn-primary',
close: true,
click: function() {
document.getElementById("btn_save_changes").disabled = true;
self.save_changes();
fnCallback();
}
@@ -449,6 +442,7 @@ var HotelCalendarManagementView = AbstractRenderer.extend({
close: true,
click: function() {
btn_save.removeClass('need-save');
document.getElementById("btn_save_changes").disabled = true;
fnCallback();
}
}

View File

@@ -1240,6 +1240,8 @@ HotelCalendar.prototype = {
});
}
});
// Initialize Save Button state to disable
this.btnSaveChanges.disabled = true;
cell.appendChild(this.btnSaveChanges);
}
//cell.setAttribute('class', 'col-xs-1 col-lg-1');
@@ -2451,8 +2453,10 @@ HotelCalendar.prototype = {
if (this.edivc.querySelector('.hcal-input-changed') !== null)
{
this.btnSaveChanges.classList.add('need-save');
this.btnSaveChanges.disabled = false;
} else {
this.btnSaveChanges.classList.remove('need-save');
this.btnSaveChanges.disabled = true;
}
},

View File

@@ -22,22 +22,27 @@
<tbody>
<tr>
<td>
<span class="filter-title">FROM</span><br/>
<span class="filter-title">FROM</span>
<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>
<span class="filter-title">TO</span><br/>
<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>
<span class="filter-title">RANGE</span>
<div class="input-group date">
<input id="date_end_days" required="required" class="form-control" />
</div>
<!-- <span class="filter-title">TO</span><br/>-->
<!-- <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>

View File

@@ -76,7 +76,7 @@ var PMSHotelCalendarController = PMSCalendarController.include({
}
else if (notif[1]['type'] === 'reservation') {
var reserv = notif[1]['reservation'];
if (reserv['external_id']) {
if (reserv['channel_type'] == 'web') {
if (notif[1]['action'] === 'create') {
this._play_sound(this.SOUNDS.BOOK_NEW);
} else if (notif[1]['action'] !== 'unlink' && reserv['state'] === 'cancelled') {

View File

@@ -267,11 +267,11 @@ class ChannelBackend(models.Model):
_logger.warning(msg)
email_values.update({'body_html': email_values['body_html'] + msg + '<br/>'})
if len(email_values['body_html']) > 0:
template = self.env.ref('hotel_channel_connector.mail_template_hotel_availability_watchdog')
email_values.update({'email_to': self._context['email_to']})
template.send_mail(self.id, email_values=email_values)
if 'email_to' in self._context:
template = self.env.ref('hotel_channel_connector.mail_template_hotel_availability_watchdog')
email_values.update({'email_to': self._context['email_to']})
template.send_mail(self.id, email_values=email_values)
# push availability on demand
self.with_context({'show_notify': False}).push_availability()

View File

@@ -2,7 +2,6 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, models, fields, _
from odoo.exceptions import UserError
from odoo.exceptions import ValidationError
from odoo.addons import decimal_precision as dp
from odoo.addons.queue_job.job import job
@@ -26,7 +25,6 @@ class ChannelHotelRoomType(models.Model):
def _default_availability(self):
return max(min(self.default_quota, self.default_max_avail), 0)
odoo_id = fields.Many2one(comodel_name='hotel.room.type',
string='Room Type',
required=True,
@@ -139,6 +137,14 @@ class HotelRoomType(models.Model):
for record in self:
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
def get_restrictions(self, date, restriction_plan_id):
self.ensure_one()
@@ -172,10 +178,14 @@ class HotelRoomType(models.Model):
@api.multi
def disconnect_channel_bind_ids(self):
channel_bind_ids = self.mapped('channel_bind_ids')
msg = _("This function is not yet implemented.")
msg += _(" The room type [%s] should be delete from the channel manager.") % channel_bind_ids.get_external_id
raise UserError(msg)
# TODO: multichannel rooms is not implemented
self.channel_bind_ids.with_context({'connector_no_export': True}).unlink()
@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):

View File

@@ -53,6 +53,7 @@ class ChannelHotelRoomTypeRestriction(models.Model):
importer = work.component(usage='hotel.room.type.restriction.importer')
return importer.import_restriction_plans()
class HotelRoomTypeRestriction(models.Model):
_inherit = 'hotel.room.type.restriction'
@@ -99,10 +100,15 @@ class HotelRoomTypeRestriction(models.Model):
@api.multi
def disconnect_channel_bind_ids(self):
channel_bind_ids = self.mapped('channel_bind_ids')
msg = _("This function is not yet implemented.")
msg += _(" The restriction plan [%s] should be delete from the channel manager.") % channel_bind_ids.get_external_id
raise UserError(msg)
# TODO: multichannel rooms is not implemented
self.channel_bind_ids.with_context({'connector_no_export': True}).unlink()
@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):
_name = 'binding.hotel.room.type.restriction.listener'
@@ -115,6 +121,7 @@ class BindingHotelRoomTypeListener(Component):
for binding in record.channel_bind_ids:
binding.update_plan_name()
class ChannelBindingHotelRoomTypeRestrictionListener(Component):
_name = 'channel.binding.hotel.room.type.restriction.listener'
_inherit = 'base.connector.listener'

View File

@@ -61,7 +61,7 @@ class HotelRoom(models.Model):
channel_availability = self.env['channel.hotel.room.type.availability'].search([
('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)
], order='date asc') or False
if channel_availability:
@@ -119,6 +119,11 @@ class HotelRoom(models.Model):
checkout=dto,
backend_id=new_channel_room_type.backend_id.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:
res = super().write(vals)
return res

View File

@@ -82,7 +82,6 @@ class ProductPricelist(models.Model):
inverse_name='odoo_id',
string='Hotel Channel Connector Bindings')
pricelist_type = fields.Selection(selection_add=[
('virtual', 'Virtual Plan'),
])
@@ -104,7 +103,6 @@ class ProductPricelist(models.Model):
for item in record.item_ids):
record.is_virtual_plan = False
@api.multi
@api.depends('name')
def name_get(self):
@@ -144,10 +142,14 @@ class ProductPricelist(models.Model):
@api.multi
def disconnect_channel_bind_ids(self):
channel_bind_ids = self.mapped('channel_bind_ids')
msg = _("This function is not yet implemented.")
msg += _(" The pricelist [%s] should be delete from the channel manager.") % channel_bind_ids.get_external_id
raise UserError(msg)
# TODO: multichannel rooms is not implemented
self.channel_bind_ids.with_context({'connector_no_export': True}).unlink()
@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):

View File

@@ -5,20 +5,41 @@
<field name="model">hotel.room.type.restriction</field>
<field name="inherit_id" ref="hotel.room_type_restriction_view_form" />
<field name="arch" type="xml">
<xpath expr="//form/sheet" 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 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">
<field name="channel_bind_ids" invisible="1" />
<button name="open_channel_bind_ids" type="object"
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"
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','=', [])]}"
/>
<button name="disconnect_channel_bind_ids" type="object"
class="oe_stat_button" icon="fa-toggle-on" string="Disconnect from Channel"
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>
</field>

View File

@@ -5,20 +5,43 @@
<field name="model">hotel.room.type</field>
<field name="inherit_id" ref="hotel.hotel_room_type_view_form" />
<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">
<field name="channel_bind_ids" invisible="1" />
<button name="open_channel_bind_ids" type="object"
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"
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','=', [])]}"
/>
<button name="disconnect_channel_bind_ids" type="object"
class="oe_stat_button" icon="fa-toggle-on" string="Disconnect from Channel"
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>

View File

@@ -5,20 +5,41 @@
<field name="model">product.pricelist</field>
<field name="inherit_id" ref="product.product_pricelist_view" />
<field name="arch" type="xml">
<xpath expr="//form/sheet" 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 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">
<field name="channel_bind_ids" invisible="1" />
<button name="open_channel_bind_ids" type="object"
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"
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','=', [])]}"
/>
<button name="disconnect_channel_bind_ids" type="object"
class="oe_stat_button" icon="fa-toggle-on" string="Disconnect from Channel"
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>
</field>

View File

@@ -3,7 +3,8 @@
from odoo.addons.component.core import Component
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):
@@ -18,3 +19,4 @@ class HotelRoomTypeDeleter(Component):
section='room',
internal_message=str(err),
channel_message=err.data['message'])
raise ValidationError(_(err.data['message']) + ". " + _(str(err)))

View File

@@ -3,7 +3,8 @@
from odoo.addons.component.core import Component
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):
@@ -44,6 +45,7 @@ class HotelRoomTypeExporter(Component):
section='room',
internal_message=str(err),
channel_message=err.data['message'])
raise ValidationError(_(err.data['message']))
@api.model
def create_room(self, binding):
@@ -78,6 +80,7 @@ class HotelRoomTypeExporter(Component):
section='room',
internal_message=str(err),
channel_message=err.data['message'])
raise ValidationError(_(err.data['message']))
else:
binding.with_context({
'connector_no_export': True,

View File

@@ -3,7 +3,8 @@
from odoo.addons.component.core import Component
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):
@@ -18,3 +19,4 @@ class HotelRoomTypeRestrictionDeleter(Component):
section='restriction',
internal_message=str(err),
channel_message=err.data['message'])
raise ValidationError(_(err.data['message']) + ". " + _(str(err)))

View File

@@ -3,7 +3,8 @@
from odoo.addons.component.core import Component
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):
@@ -23,6 +24,7 @@ class HotelRoomTypeRestrictionExporter(Component):
section='restriction',
internal_message=str(err),
channel_message=err.data['message'])
raise ValidationError(_(err.data['message']))
@api.model
def create_rplan(self, binding):
@@ -33,5 +35,6 @@ class HotelRoomTypeRestrictionExporter(Component):
section='restriction',
internal_message=str(err),
channel_message=err.data['message'])
raise ValidationError(_(err.data['message']))
else:
self.binder.bind(external_id, binding)

View File

@@ -3,7 +3,8 @@
from odoo.addons.component.core import Component
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):
@@ -18,3 +19,4 @@ class ProductPricelistDeleter(Component):
section='pricelist',
internal_message=str(err),
channel_message=err.data['message'])
raise ValidationError(_(err.data['message']) + ". " + _(str(err)))

View File

@@ -3,7 +3,8 @@
from odoo.addons.component.core import Component
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):
@@ -23,6 +24,7 @@ class ProductPricelistExporter(Component):
section='pricelist',
internal_message=str(err),
channel_message=err.data['message'])
raise ValidationError(_(err.data['message']))
@api.model
def create_plan(self, binding):
@@ -33,6 +35,7 @@ class ProductPricelistExporter(Component):
section='pricelist',
internal_message=str(err),
channel_message=err.data['message'])
raise ValidationError(_(err.data['message']))
else:
binding.external_id = external_id
self.binder.bind(external_id, binding)
@@ -67,6 +70,7 @@ class ProductPricelistExporter(Component):
section='pricelist',
internal_message=str(err),
channel_message=err.data['message'])
raise ValidationError(_(err.data['message']))
else:
binding.external_id = external_id
self.binder.bind(external_id, binding)
@@ -102,3 +106,4 @@ class ProductPricelistExporter(Component):
section='pricelist',
internal_message=str(err),
channel_message=err.data['message'])
raise ValidationError(_(err.data['message']))