diff --git a/hotel/models/hotel_reservation.py b/hotel/models/hotel_reservation.py index 4287ed8fd..94bd2764d 100644 --- a/hotel/models/hotel_reservation.py +++ b/hotel/models/hotel_reservation.py @@ -983,8 +983,7 @@ class HotelReservation(models.Model): date_start_dt = fields.Date.from_string(record.checkin) date_end_dt = fields.Date.from_string(record.checkout) date_diff = abs((date_end_dt - date_start_dt).days) - new_start_date_dt = date_start_dt + \ - timedelta(days=date_diff-nights) + new_start_date_dt = date_start_dt + timedelta(days=date_diff-nights) if nights >= date_diff or nights < 1: raise ValidationError(_("Invalid Nights! Max is \ '%d'") % (date_diff-1)) diff --git a/hotel_calendar/models/inherited_hotel_reservation.py b/hotel_calendar/models/inherited_hotel_reservation.py index c68c109fb..44cfd1ab6 100644 --- a/hotel_calendar/models/inherited_hotel_reservation.py +++ b/hotel_calendar/models/inherited_hotel_reservation.py @@ -184,32 +184,29 @@ class HotelReservation(models.Model): return json_events @api.model - def get_hcalendar_reservations_data(self, dfrom, dto, rooms): - date_start = fields.Date.from_string(dfrom) - timedelta(days=1) - date_start_str = date_start.strftime(DEFAULT_SERVER_DATETIME_FORMAT) + def get_hcalendar_reservations_data(self, dfrom_dt, dto_dt, rooms): + rdfrom_dt = dfrom_dt + timedelta(days=1) # Ignore checkout reservations_raw = self.env['hotel.reservation'].search( [('room_id', 'in', rooms.ids)], order="checkin DESC, checkout ASC, adults DESC, children DESC") reservations_ll = self.env['hotel.reservation'].search([ - ('checkin', '<=', dto), - ('checkout', '>=', date_start_str) + ('checkin', '<=', dto_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)), + ('checkout', '>=', rdfrom_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)) ]) reservations_lr = self.env['hotel.reservation'].search([ - ('checkin', '>=', date_start_str), - ('checkout', '<=', dto) + ('checkin', '>=', dfrom_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)), + ('checkout', '<=', dto_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)) ]) reservations = (reservations_ll | reservations_lr) & reservations_raw return self._hcalendar_reservation_data(reservations) @api.model - def get_hcalendar_pricelist_data(self, dfrom, dto): + def get_hcalendar_pricelist_data(self, dfrom_dt, dto_dt): pricelist_id = self.env['ir.default'].sudo().get( 'res.config.settings', 'default_pricelist_id') if pricelist_id: pricelist_id = int(pricelist_id) - date_start = fields.Date.from_string(dfrom) - timedelta(days=1) - date_end = fields.Date.from_string(dto) - date_diff = abs((date_end - date_start).days) + 1 + date_diff = abs((dfrom_dt - dto_dt).days) + 1 # Get Prices json_rooms_prices = {pricelist_id: []} room_typed_ids = self.env['hotel.room.type'].search( @@ -220,7 +217,7 @@ class HotelReservation(models.Model): for room_type_id in room_typed_ids: days = {} for i in range(0, date_diff): - ndate = date_start + timedelta(days=i) + ndate = dfrom_dt + timedelta(days=i) ndate_str = ndate.strftime(DEFAULT_SERVER_DATE_FORMAT) prod_price_id = room_pr_cached_obj.search([ ('room_id', '=', room_type_id.id), @@ -242,14 +239,12 @@ class HotelReservation(models.Model): return json_rooms_prices @api.model - def get_hcalendar_restrictions_data(self, dfrom, dto): + def get_hcalendar_restrictions_data(self, dfrom_dt, dto_dt): restriction_id = self.env['ir.default'].sudo().get( 'res.config.settings', 'default_restriction_id') if restriction_id: restriction_id = int(restriction_id) - date_start = fields.Date.from_string(dfrom) - timedelta(days=1) - date_end = fields.Date.from_string(dto) - date_diff = abs((date_end - date_start).days) + 1 + date_diff = abs((dto_dt - dfrom_dt).days) + 1 # Get Prices json_rooms_rests = {} room_types = self.env['hotel.room.type'].search( @@ -259,7 +254,7 @@ class HotelReservation(models.Model): for room_type in room_types: days = {} for i in range(0, date_diff): - ndate = date_start + timedelta(days=i) + ndate = dfrom_dt + timedelta(days=i) ndate_str = ndate.strftime(DEFAULT_SERVER_DATE_FORMAT) rest_id = room_type_rest_obj.search([ ('room_type_id', '=', room_type.id), @@ -284,9 +279,7 @@ class HotelReservation(models.Model): return json_rooms_rests @api.model - def get_hcalendar_events_data(self, dfrom, dto): - date_start = fields.Date.from_string(dfrom) - timedelta(days=1) - date_start_str = date_start.strftime(DEFAULT_SERVER_DATETIME_FORMAT) + def get_hcalendar_events_data(self, dfrom_dt, dto_dt): user_id = self.env['res.users'].browse(self.env.uid) domain = [] if user_id.pms_allowed_events_tags: @@ -296,12 +289,12 @@ class HotelReservation(models.Model): ('categ_ids', 'not in', user_id.pms_denied_events_tags)) events_raw = self.env['calendar.event'].search(domain) events_ll = self.env['calendar.event'].search([ - ('start', '<=', dto), - ('stop', '>=', date_start_str) + ('start', '<=', dto_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)), + ('stop', '>=', dfrom_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)) ]) events_lr = self.env['calendar.event'].search([ - ('start', '>=', date_start_str), - ('stop', '<=', dto) + ('start', '>=', dfrom_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)), + ('stop', '<=', dto_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)) ]) events = (events_ll | events_lr) & events_raw return self._hcalendar_event_data(events) @@ -332,18 +325,22 @@ class HotelReservation(models.Model): if not dfrom or not dto: raise ValidationError(_('Input Error: No dates defined!')) + dfrom_dt = fields.Date.from_string(dfrom) + dto_dt = fields.Date.from_string(dto) + rooms = self.env['hotel.room'].search([], order='hcal_sequence ASC') calendars = self.env['hotel.calendar'].search([]) json_res, json_res_tooltips = self.get_hcalendar_reservations_data( - dfrom, dto, rooms) + dfrom_dt, dto_dt, rooms) vals = { 'rooms': withRooms and self._hcalendar_room_data(rooms) or [], 'reservations': json_res, 'tooltips': json_res_tooltips, - 'pricelist': self.get_hcalendar_pricelist_data(dfrom, dto), - 'restrictions': self.get_hcalendar_restrictions_data(dfrom, dto), - 'events': self.get_hcalendar_events_data(dfrom, dto), + 'pricelist': self.get_hcalendar_pricelist_data(dfrom_dt, dto_dt), + 'restrictions': self.get_hcalendar_restrictions_data(dfrom_dt, + dto_dt), + 'events': self.get_hcalendar_events_data(dfrom_dt, dto_dt), 'calendars': self._hcalendar_calendar_data(calendars) } diff --git a/hotel_calendar/static/src/lib/hcalendar/css/hcalendar.css b/hotel_calendar/static/src/lib/hcalendar/css/hcalendar.css index efc66367e..86ac21ee9 100644 --- a/hotel_calendar/static/src/lib/hcalendar/css/hcalendar.css +++ b/hotel_calendar/static/src/lib/hcalendar/css/hcalendar.css @@ -318,9 +318,7 @@ color: white; white-space: nowrap; overflow: hidden; - z-index:8; - vertical-align: middle; - display: table-cell; + z-index: 8; } .hcal-reservation:hover { background-color: #4e97bf; @@ -424,21 +422,25 @@ } .hcal-reservation-divide-l { - background-color: transparent !important; + background-color: transparent; border: 2px dashed black; cursor: copy; pointer-events: none; - border-color: black !important; - border-right-style: solid !important; + border-color: black; + border-right-style: solid; + position: absolute; + z-index: 9; } .hcal-reservation-divide-r { - background-color: transparent !important; + background-color: transparent; border: 2px dashed black; cursor: copy; pointer-events: none; - border-color: black !important; - border-left-style: solid !important; + border-color: black; + border-left-style: solid; + position: absolute; + z-index: 9; } .hcal-row-room-type-group-item { diff --git a/hotel_calendar/static/src/lib/hcalendar/js/hcalendar.js b/hotel_calendar/static/src/lib/hcalendar/js/hcalendar.js index ae1fb0506..9cc202103 100644 --- a/hotel_calendar/static/src/lib/hcalendar/js/hcalendar.js +++ b/hotel_calendar/static/src/lib/hcalendar/js/hcalendar.js @@ -511,6 +511,13 @@ HotelCalendar.prototype = { } while (notFound && nbed <= reservation.room.capacity); reservation._limits = limits; + + // Update Beds + if (limits.isValid()) { + var numBeds = (+limits.right.dataset.hcalBedNum)-(+limits.left.dataset.hcalBedNum); + reservation._beds = []; + for (var i=0; i<=numBeds; reservation._beds.push(+limits.left.dataset.hcalBedNum+i++)); + } }, //==== CELLS @@ -1756,41 +1763,21 @@ HotelCalendar.prototype = { } if (!noRefresh) { - var numBeds = (+reserv._limits.right.dataset.hcalBedNum)-(+reserv._limits.left.dataset.hcalBedNum); - reserv._beds = []; - for (var i=0; i<=numBeds; reserv._beds.push(+reserv._limits.left.dataset.hcalBedNum+i++)); + //reserv._html.removeAttribute('style'); var boundsInit = reserv._limits.left.getBoundingClientRect(); var boundsEnd = reserv._limits.right.getBoundingClientRect(); - - reserv._html.removeAttribute('style'); - - if (reserv.splitted) { - reserv._html.classList.add('hcal-reservation-splitted'); - // 1. Use reservation ID as seed - // 2. Use sinusiudal function - // 3. Only use positive values (This decrease longitude, increase frequency) - // 4. Use the first 5 decimals to make the integer value - // 5. Get integer value (Bitwise tilde method) - // TODO: Improve pseudo-random number generator - var magicNumber = ~~(Math.abs(Math.sin((reserv.getUserData('parent_reservation') || reserv.id))) * 100000); - var bbColor = this._intToRgb(magicNumber); - reserv._html.style.borderColor = `rgb(${bbColor[0]},${bbColor[1]},${bbColor[2]})`; - } else { - reserv._html.classList.remove('hcal-reservation-splitted'); - } - reserv._html.style.backgroundColor = reserv.color; - reserv._html.style.color = reserv.colorText; - var etableOffset = this.etable.getBoundingClientRect(); - - reserv._html.style.top = `${boundsInit.top-etableOffset.top+2}px`; var divHeight = (boundsEnd.bottom-etableOffset.top-4)-(boundsInit.top-etableOffset.top); var fontHeight = 12; var has_changed = false; + + reserv._html.style.backgroundColor = reserv.color; + reserv._html.style.color = reserv.colorText; reserv._html.style.height = `${divHeight}px`; reserv._html.style.lineHeight = `${divHeight}px`; reserv._html.style.fontSize = `${fontHeight}px`; + reserv._html.style.top = `${boundsInit.top-etableOffset.top+2}px`; reserv._html.style.left = `${boundsInit.left-etableOffset.left+2}px`; reserv._html.style.width = `${(boundsEnd.left-boundsInit.left)+boundsEnd.width-4}px`; if (reserv._drawModes[0] === 'soft-start') { @@ -1817,9 +1804,24 @@ HotelCalendar.prototype = { reserv._html.style.width = `${(boundsEnd.left-boundsInit.left)+boundsEnd.width-1}px`; } - if (reserv.splitted && !has_changed) { - reserv._html.style.left = `${boundsInit.left-etableOffset.left-1}px`; - reserv._html.style.width = `${(boundsEnd.left-boundsInit.left)+boundsEnd.width+2}px`; + if (reserv.splitted) { + reserv._html.classList.add('hcal-reservation-splitted'); + // 1. Use reservation ID as seed + // 2. Use sinusiudal function + // 3. Only use positive values (This decrease longitude) + // 4. Use the first 5 decimals to make the integer value + // 5. Get integer value (Bitwise tilde method) + // TODO: Improve pseudo-random number generator + var magicNumber = ~~(Math.abs(Math.sin((reserv.getUserData('parent_reservation') || reserv.id))) * 100000); + var bbColor = this._intToRgb(magicNumber); + reserv._html.style.borderColor = `rgb(${bbColor[0]},${bbColor[1]},${bbColor[2]})`; + + if (!has_changed) { + reserv._html.style.left = `${boundsInit.left-etableOffset.left-1}px`; + reserv._html.style.width = `${(boundsEnd.left-boundsInit.left)+boundsEnd.width+2}px`; + } + } else { + reserv._html.classList.remove('hcal-reservation-splitted'); } } }, @@ -2618,25 +2620,37 @@ HotelCalendar.prototype = { } if (reservs.length) { this._splitReservation = reservs[0]; - this._divideDivs = [$(this._splitReservation._html).clone().text('').appendTo(this.edivr), $(this._splitReservation._html).clone().text('').appendTo(this.edivr)]; + var defStyle = { + top: this._splitReservation._html.style.top, + left: this._splitReservation._html.style.left, + height: this._splitReservation._html.style.height, + }; + this._divideDivs = [ + $('
', {class: 'hcal-reservation-divide-l', css: defStyle}).appendTo(this.edivr), + $('
', {class: 'hcal-reservation-divide-r', css: defStyle}).appendTo(this.edivr) + ]; var diff = this.getDateDiffDays(this._splitReservation.startDate, date_cell); - this._divideDivs[0].addClass('hcal-reservation-divide-l'); - this._divideDivs[1].addClass('hcal-reservation-divide-r'); - var etableOffset = this.etable.getBoundingClientRect(); var boundsCell = ev.target.getBoundingClientRect(); var beginCell = this._splitReservation._limits.left.getBoundingClientRect(); var endCell = this._splitReservation._limits.right.getBoundingClientRect(); - var splitCell = boundsCell; - var splitDate = date_cell.clone(); this._splitDate = date_cell.clone(); if (date_cell.isSame(this._splitReservation.endDate.clone().subtract(1, 'd'), 'day')) { - splitDate.subtract(1, 'd'); - splitCell = this.getCell(this._splitDate, this._splitReservation.room, 0); + this._splitDate.subtract(1, 'd'); + var tcell = this.getCell(this._splitDate, this._splitReservation.room, 0); + if (tcell) { + boundsCell = tcell.getBoundingClientRect(); + } else { + boundsCell = false; + this._splitReservation = false; + this._splitDate = false; + } + } + if (boundsCell) { + this._divideDivs[0][0].style.width = `${(boundsCell.left-beginCell.left)+boundsCell.width}px`; + this._divideDivs[1][0].style.left = `${(boundsCell.left-etableOffset.left)+boundsCell.width}px`; + this._divideDivs[1][0].style.width = `${(endCell.left-boundsCell.left)}px`; } - this._divideDivs[0][0].style.width = `${(splitCell.left-beginCell.left)+splitCell.width}px`; - this._divideDivs[1][0].style.left = `${(splitCell.left-etableOffset.left)+splitCell.width}px`; - this._divideDivs[1][0].style.width = `${(endCell.left-splitCell.left)}px`; } else { this._splitReservation = false; this._splitDate = false;