[WIP] Refresh Availability

This commit is contained in:
Dario Lodeiros
2019-02-28 17:27:23 +01:00
parent d39b22a257
commit 69b66b6d87
3 changed files with 86 additions and 61 deletions

View File

@@ -36,8 +36,8 @@ class HotelCalendarManagement(models.TransientModel):
'id': False,
'date': date,
'no_ota': False,
'quota': -1, # FIXED: `avail and avail.max_quota or -1` returns -1 if quota = 0
'max_avail': -1,
'quota': room_type.channel_bind_ids.default_quota,
'max_avail': room_type.channel_bind_ids.default_max_avail,
'channel_avail': room_type.channel_bind_ids.default_availability
}
if avail:

View File

@@ -35,6 +35,13 @@ class ChannelHotelReservation(models.Model):
channel_modified = fields.Boolean("Channel Modified", readonly=True,
default=False, old_name='wmodified')
# Inherit binding constrain becouse two reservations can have
# the same external_id
_sql_constraints = [
('channel_uniq', 'unique(odoo_id, external_id)',
'A binding already exists with the same Channel ID.'),
]
@api.depends('channel_reservation_id', 'ota_id')
def _is_from_ota(self):
for record in self:
@@ -42,9 +49,9 @@ class ChannelHotelReservation(models.Model):
@job(default_channel='root.channel')
@api.model
def refresh_availability(self, checkin, checkout, room_id):
def refresh_availability(self, checkin, checkout, backend_id, room_id):
self.env['channel.hotel.room.type.availability'].refresh_availability(
checkin, checkout, room_id)
checkin, checkout, backend_id, room_id)
@job(default_channel='root.channel')
@api.model
@@ -82,15 +89,24 @@ class ChannelHotelReservation(models.Model):
older_vals = []
new_vals = []
for record in self:
backend_id = self.env['channel.hotel.room.type'].search([
('odoo_id', '=', record.room_id.room_type_id.id)
]).backend_id.id
older_vals.append({
'checkin': record.checkin,
'checkout': record.checkout,
'room_id': record.room_id,
'backend_id': backend_id,
'room_id': record.room_id.id,
})
new_backend_id = self.env['channel.hotel.room.type'].search([
('odoo_id', '=', self.env['hotel.room'].
browse(vals.get('room_id', record.room_id.id)).
room_type_id.id)]).backend_id.id
new_vals.append({
'checkin': vals.get('checkin', record.checkin),
'checkout': vals.get('checkout', record.checkout),
'room_id': vals.get('room_id', record.room_id),
'backend_id': new_backend_id,
'room_id': vals.get('room_id', record.room_id.id),
})
res = super(ChannelHotelReservation, self).write(vals)
@@ -99,14 +115,16 @@ class ChannelHotelReservation(models.Model):
for k_i, v_i in enumerate(older_vals):
# FIX: 3rd parameters is backend_id, use room_id=v_i['room_id'] instead
channel_room_type_avail_obj.refresh_availability(
v_i['checkin'],
v_i['checkout'],
v_i['room_id'])
checkin=v_i['checkin'],
checkout=v_i['checkout'],
backend_id=v_i['backend_id'],
room_id=v_i['room_id'])
# FIX: 3rd parameters is backend_id, use room_id=new_vals[k_i]['room_id'] instead
channel_room_type_avail_obj.refresh_availability(
new_vals[k_i]['checkin'],
new_vals[k_i]['checkout'],
new_vals[k_i]['room_id'])
checkin=new_vals[k_i]['checkin'],
checkout=new_vals[k_i]['checkout'],
backend_id=new_vals[k_i]['backend_id'],
room_id=new_vals[k_i]['room_id'])
else:
res = super(ChannelHotelReservation, self).write(vals)
return res
@@ -117,9 +135,13 @@ class ChannelHotelReservation(models.Model):
for record in self:
if record.is_from_ota and self._context.get('ota_limits', True):
raise UserError(_("You can't delete OTA's reservations"))
backend_id = self.env['channel.hotel.room.type'].search([
('odoo_id', '=', record.room_id.room_type_id.id)
]).backend_id.id
vals.append({
'checkin': record.checkin,
'checkout': record.checkout,
'backend_id': backend_id,
'room_id': record.room_id.id,
})
res = super(ChannelHotelReservation, self).unlink()
@@ -130,9 +152,11 @@ class ChannelHotelReservation(models.Model):
channel_room_type_avail_obj.refresh_availability(
record['checkin'],
record['checkout'],
record['backend_id'],
record['room_id'])
return res
class HotelReservation(models.Model):
_inherit = 'hotel.reservation'
@@ -244,7 +268,6 @@ class ChannelBindingHotelReservationListener(Component):
_inherit = 'base.connector.listener'
_apply_on = ['channel.hotel.reservation']
@skip_if(lambda self, record, **kwargs: self.no_connector_export(record))
def on_record_create(self, record, fields=None):
record.refresh_availability()

View File

@@ -18,8 +18,10 @@ class HotelRoomTypeAvailability(models.Model):
@api.model
def _default_max_avail(self):
if self.room_type_id:
return self.room_type_id.total_rooms_count
room_type_id = self._context.get('room_type_id')
if room_type_id:
room_type_id = self.env['hotel.room_type'].browse(room_type_id)
return room_type_id.default_max_avail if room_type_id else -1
return -1
@api.model
@@ -64,9 +66,6 @@ class HotelRoomTypeAvailability(models.Model):
if record.quota > record.room_type_id.total_rooms_count:
raise ValidationError(_("The quota assigned to the channel manager can't be greater "
"than the total rooms count!"))
if (record.max_avail > record.quota) and (record.quota >= 0):
raise ValidationError(_("The maximum simultaneous availability can't be greater "
"than a given quota."))
if record.max_avail > record.room_type_id.total_rooms_count:
raise ValidationError(_("The maximum simultaneous availability can't be greater "
"than the total rooms count!"))
@@ -122,12 +121,13 @@ class ChannelHotelRoomTypeAvailability(models.Model):
room_type_id=False, from_channel=False):
date_start = fields.Date.from_string(checkin)
date_end = fields.Date.from_string(checkout)
if date_start == date_end:
date_end = date_start + timedelta(days=1)
# Not count end day of the reservation
date_diff = (date_end - date_start).days
channel_room_type_obj = self.env['channel.hotel.room.type']
channel_room_type_avail_obj = self.env['channel.hotel.room.type.availability']
if room_type_id:
room_type_bind = channel_room_type_obj.search([('odoo_id', '=', room_type_id)])
else:
@@ -152,43 +152,32 @@ class ChannelHotelRoomTypeAvailability(models.Model):
room_type_avail_id = channel_room_type_avail_obj.search([
('room_type_id', '=', room_type_bind.odoo_id.id),
('date', '=', ndate_str)], limit=1)
quota = room_type_bind.default_quota
if room_type_avail_id:
if room_type_avail_id.quota >= 0:
if from_channel and room_type_avail_id.quota > 0:
room_type_avail_id.update({
'quota': room_type_avail_id.quota - 1,
})
quota = room_type_avail_id.quota
if room_type_avail_id.max_avail >= 0:
to_eval.append(room_type_avail_id.max_avail)
else:
if room_type_bind.default_max_avail >= 0:
to_eval.append(room_type_bind.default_max_avail)
if from_channel and quota > 0:
quota -= 1
to_eval.append(quota)
quota = room_type_avail_id.quota if room_type_avail_id \
else room_type_bind.default_quota
max_avail = room_type_avail_id.max_avail if room_type_avail_id \
else room_type_bind.default_max_avail
if from_channel and quota > 0:
quota -= 1
# We ignore quota and max_avail if its value is -1
if quota >= 0:
to_eval.append(quota)
if max_avail >= 0:
to_eval.append(max_avail)
# And finally, set the channel avail like the min set value
avail = max(min(to_eval), 0)
_logger.info({
'real_avail': cavail,
'default_avail': room_type_bind.default_availability,
'quota': room_type_avail_id.quota,
'max_avail': room_type_avail_id.max_avail,
})
_logger.info({
'room_type_id': room_type_bind.odoo_id.id,
'date': ndate_str,
'channel_avail': avail,
})
if room_type_avail_id:
# CAVEAT: update channel.hotel.room.type.availability if needed
vals_avail = {}
if room_type_avail_id.quota != quota:
vals_avail.update({'quota': quota})
if room_type_avail_id.channel_avail != avail:
room_type_avail_id.write({'channel_avail': avail})
vals_avail.update({'channel_avail': avail})
if vals_avail:
room_type_avail_id.write(vals_avail)
else:
quota = room_type_bind.default_quota
if from_channel and quota > 0:
quota -= 1
self.env['hotel.room.type.availability'].create({
'room_type_id': room_type_bind.odoo_id.id,
'date': ndate_str,
@@ -246,6 +235,8 @@ class BindingHotelRoomTypeAvailabilityListener(Component):
'channel.hotel.room.type.availability']
backends = self.env['channel.backend'].search([])
for backend in backends:
# REVIEW :: If you create directly channel_binding, this search
# return empty
avail_bind = channel_room_type_avail_obj.search([
('odoo_id', '=', record.id),
('backend_id', '=', backend.id),
@@ -257,15 +248,16 @@ class BindingHotelRoomTypeAvailabilityListener(Component):
'channel_pushed': False,
'backend_id': backend.id,
})
_logger.info("==[on_record_create] :: hotel.room.type.availability==")
_logger.info(avail_bind)
avail_bind.refresh_availability(
record.date,
(datetime.strptime(record.date, DEFAULT_SERVER_DATE_FORMAT).date() +
timedelta(days=1)).strftime(DEFAULT_SERVER_DATE_FORMAT),
backend.id,
# room_type_id=record.room_type_id.channel_bind_ids.id,
room_type_id=record.room_type_id.id)
_logger.info("==[on_record_create] :: hotel.room.type.availability==")
_logger.info(avail_bind)
else:
avail_bind.refresh_availability(
record.date,
(datetime.strptime(record.date, DEFAULT_SERVER_DATE_FORMAT).date() +
timedelta(days=1)).strftime(DEFAULT_SERVER_DATE_FORMAT),
backend.id,
# room_type_id=record.room_type_id.channel_bind_ids.id,
room_type_id=record.room_type_id.id)
class ChannelBindingHotelRoomTypeAvailabilityListener(Component):
@@ -286,12 +278,22 @@ class ChannelBindingHotelRoomTypeAvailabilityListener(Component):
record.channel_pushed = False
record.push_availability(record.backend_id)
@skip_if(lambda self, record, **kwargs: self.no_connector_export(record))
def on_record_create(self, record, fields=None):
if any(record.channel_bind_ids):
for binding in record.channel_bind_ids:
record.refresh_availability(
record.date,
record.date,
binding.backend_id.id,
room_type_id=record.room_type_id.id)
@skip_if(lambda self, record, **kwargs: self.no_connector_export(record))
def on_fix_channel_availability(self, record, fields=None):
if any(record.channel_bind_ids):
for binding in record.channel_bind_ids:
record.refresh_availability(
record.checkin,
record.checkout,
record.date,
record.date,
binding.backend_id.id,
room_type_id=record.room_type_id.id)