mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[IMP] Reservation Drawing
This commit is contained in:
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 = [
|
||||
$('<div/>', {class: 'hcal-reservation-divide-l', css: defStyle}).appendTo(this.edivr),
|
||||
$('<div/>', {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;
|
||||
|
||||
Reference in New Issue
Block a user