[IMP] Reservation Drawing

This commit is contained in:
Alexandre Díaz
2019-01-10 18:55:07 +01:00
parent de545d5b6b
commit 8a6f5e2aec
4 changed files with 90 additions and 78 deletions

View File

@@ -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))

View File

@@ -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)
}

View File

@@ -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 {

View File

@@ -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;