mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[WIP] Refresh Availability
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user