mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
281 lines
11 KiB
Python
281 lines
11 KiB
Python
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
import logging
|
|
from datetime import timedelta
|
|
from odoo.tools import (
|
|
DEFAULT_SERVER_DATE_FORMAT,
|
|
DEFAULT_SERVER_DATETIME_FORMAT)
|
|
from odoo import models, api, _, fields
|
|
from odoo.exceptions import AccessError, ValidationError
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class HotelCalendarManagement(models.TransientModel):
|
|
_name = 'hotel.calendar.management'
|
|
|
|
@api.model
|
|
def _get_prices_values(self, price):
|
|
vals = {
|
|
'fixed_price': price['price'],
|
|
}
|
|
return vals
|
|
|
|
@api.model
|
|
def _get_restrictions_values(self, restriction):
|
|
vals = {
|
|
'min_stay': restriction['min_stay'],
|
|
'min_stay_arrival': restriction['min_stay_arrival'],
|
|
'max_stay': restriction['max_stay'],
|
|
'max_stay_arrival': restriction['max_stay_arrival'],
|
|
'closed': restriction['closed'],
|
|
'closed_arrival': restriction['closed_arrival'],
|
|
'closed_departure': restriction['closed_departure'],
|
|
}
|
|
return vals
|
|
|
|
@api.model
|
|
def save_changes(self, pricelist_id, restriction_id, pricelist,
|
|
restrictions, availability=False):
|
|
room_type_obj = self.env['hotel.room.type']
|
|
product_pricelist_item_obj = self.env['product.pricelist.item']
|
|
room_type_rest_item_obj = self.env['hotel.room.type.restriction.item']
|
|
|
|
# Save Pricelist
|
|
for k_price in pricelist.keys():
|
|
room_type_id = room_type_obj.browse([int(k_price)])
|
|
room_type_prod_tmpl_id = room_type_id.product_id.product_tmpl_id
|
|
for price in pricelist[k_price]:
|
|
price_id = product_pricelist_item_obj.search([
|
|
('date_start', '>=', price['date']),
|
|
('date_end', '<=', price['date']),
|
|
('pricelist_id', '=', int(pricelist_id)),
|
|
('applied_on', '=', '1_product'),
|
|
('compute_price', '=', 'fixed'),
|
|
('product_tmpl_id', '=', room_type_prod_tmpl_id.id),
|
|
], limit=1)
|
|
vals = self._get_prices_values(price)
|
|
if not price_id:
|
|
vals.update({
|
|
'date_start': price['date'],
|
|
'date_end': price['date'],
|
|
'pricelist_id': int(pricelist_id),
|
|
'applied_on': '1_product',
|
|
'compute_price': 'fixed',
|
|
'product_tmpl_id': room_type_prod_tmpl_id.id,
|
|
})
|
|
price_id = product_pricelist_item_obj.create(vals)
|
|
else:
|
|
price_id.write(vals)
|
|
|
|
# Save Restrictions
|
|
for k_res in restrictions.keys():
|
|
for restriction in restrictions[k_res]:
|
|
res_id = room_type_rest_item_obj.search([
|
|
('date', '=', restriction['date']),
|
|
('restriction_id', '=', int(restriction_id)),
|
|
('room_type_id', '=', int(k_res)),
|
|
], limit=1)
|
|
vals = self._get_restrictions_values(restriction)
|
|
if not res_id:
|
|
vals.update({
|
|
'date': restriction['date'],
|
|
'restriction_id': int(restriction_id),
|
|
'room_type_id': int(k_res),
|
|
})
|
|
res_id = room_type_rest_item_obj.create(vals)
|
|
else:
|
|
res_id.write(vals)
|
|
|
|
@api.model
|
|
def _hcalendar_room_json_data(self, rooms):
|
|
json_data = []
|
|
for room in rooms:
|
|
json_data.append({
|
|
'id': room.id,
|
|
'name': room.name,
|
|
'capacity': room.get_capacity(),
|
|
'price': room.list_price,
|
|
'total_rooms': room.total_rooms_count,
|
|
})
|
|
return json_data
|
|
|
|
@api.model
|
|
def _hcalendar_pricelist_json_data(self, prices):
|
|
json_data = {}
|
|
room_type_obj = self.env['hotel.room.type']
|
|
for rec in prices:
|
|
room_type_id = room_type_obj.search([
|
|
('product_id.product_tmpl_id', '=', rec.product_tmpl_id.id)
|
|
], limit=1)
|
|
if not room_type_id:
|
|
continue
|
|
|
|
# TODO: date_end - date_start loop
|
|
json_data.setdefault(room_type_id.id, []).append({
|
|
'id': rec.id,
|
|
'price': rec.fixed_price,
|
|
'date': rec.date_start,
|
|
})
|
|
return json_data
|
|
|
|
@api.model
|
|
def _hcalendar_restriction_json_data(self, restrictions):
|
|
json_data = {}
|
|
for rec in restrictions:
|
|
json_data.setdefault(rec.room_type_id.id, []).append({
|
|
'id': rec.id,
|
|
'date': rec.date,
|
|
'min_stay': rec.min_stay,
|
|
'min_stay_arrival': rec.min_stay_arrival,
|
|
'max_stay': rec.max_stay,
|
|
'max_stay_arrival': rec.max_stay_arrival,
|
|
'closed': rec.closed,
|
|
'closed_departure': rec.closed_departure,
|
|
'closed_arrival': rec.closed_arrival,
|
|
})
|
|
return json_data
|
|
|
|
@api.model
|
|
def _hcalendar_events_json_data(self, dfrom, dto):
|
|
date_start = fields.Date.from_string(dfrom) - timedelta(days=1)
|
|
date_start_str = date_start.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
|
|
user_id = self.env['res.users'].browse(self.env.uid)
|
|
domain = []
|
|
if user_id.pms_allowed_events_tags:
|
|
domain.append(('categ_ids', 'in', user_id.pms_allowed_events_tags))
|
|
if user_id.pms_denied_events_tags:
|
|
domain.append(
|
|
('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)
|
|
])
|
|
events_lr = self.env['calendar.event'].search([
|
|
('start', '>=', date_start_str),
|
|
('stop', '<=', dto)
|
|
])
|
|
events = (events_ll | events_lr) & events_raw
|
|
json_data = []
|
|
for event in events:
|
|
json_data.append([
|
|
event.id,
|
|
event.name,
|
|
event.start,
|
|
event.location,
|
|
])
|
|
return json_data
|
|
|
|
@api.model
|
|
def _hcalendar_get_count_reservations_json_data(self, dfrom, dto):
|
|
date_start = fields.Date.from_string(dfrom)
|
|
date_end = fields.Date.from_string(dto)
|
|
date_diff = abs((date_end - date_start).days) + 1
|
|
room_type_obj = self.env['hotel.room.type']
|
|
room_types = room_type_obj.search([])
|
|
json_data = {}
|
|
|
|
for room_type in room_types:
|
|
for i in range(0, date_diff):
|
|
cur_date = date_start + timedelta(days=i)
|
|
cur_date_str = cur_date.strftime(DEFAULT_SERVER_DATE_FORMAT)
|
|
self.env.cr.execute('''
|
|
SELECT
|
|
hrl.id
|
|
FROM hotel_reservation_line AS hrl
|
|
WHERE date = %s
|
|
''', ((cur_date_str),))
|
|
line_ids = [r[0] for r in self.env.cr.fetchall()]
|
|
reservation_ids = self.env['hotel.reservation.line'].browse(line_ids).\
|
|
mapped('reservation_id.id')
|
|
reservations = self.env['hotel.reservation'].\
|
|
browse(reservation_ids).filtered(
|
|
lambda r: r.state != 'cancelled'
|
|
and not r.overbooking and not r.reselling
|
|
)
|
|
reservations_rooms = reservations.mapped('room_id.id')
|
|
free_rooms = self.env['hotel.room'].search([
|
|
('id', 'not in', reservations_rooms),
|
|
])
|
|
rooms_linked = self.env['hotel.room.type'].search([
|
|
('id', '=', room_type.id)
|
|
]).room_ids
|
|
free_rooms = free_rooms & rooms_linked
|
|
json_data.setdefault(room_type.id, []).append({
|
|
'date': cur_date_str,
|
|
'num': len(free_rooms),
|
|
})
|
|
|
|
return json_data
|
|
|
|
@api.model
|
|
def get_hcalendar_all_data(self, dfrom, dto, pricelist_id, restriction_id,
|
|
withRooms):
|
|
hotel_id = self.env.user.hotel_id.id
|
|
|
|
if not dfrom or not dto:
|
|
raise ValidationError(_('Input Error: No dates defined!'))
|
|
vals = {}
|
|
# TODO: res.config by hotel
|
|
if not pricelist_id:
|
|
pricelist_id = self.env['ir.default'].sudo().get(
|
|
'res.config.settings', 'default_pricelist_id')
|
|
if not restriction_id:
|
|
restriction_id = self.env['ir.default'].sudo().get(
|
|
'res.config.settings', 'default_restriction_id')
|
|
|
|
# TODO: ensure pricelist_id and restriction_id belong to the current hotel
|
|
pricelist_id = int(pricelist_id)
|
|
vals.update({'pricelist_id': pricelist_id})
|
|
restriction_id = int(restriction_id)
|
|
vals.update({'restriction_id': restriction_id})
|
|
|
|
restriction_item_ids = self.env['hotel.room.type.restriction.item'].search([
|
|
('date', '>=', dfrom), ('date', '<=', dto),
|
|
('restriction_id', '=', restriction_id),
|
|
])
|
|
pricelist_item_ids = self.env['product.pricelist.item'].search([
|
|
('date_start', '>=', dfrom), ('date_end', '<=', dto),
|
|
('pricelist_id', '=', pricelist_id),
|
|
('applied_on', '=', '1_product'),
|
|
('compute_price', '=', 'fixed'),
|
|
])
|
|
|
|
json_prices = self._hcalendar_pricelist_json_data(pricelist_item_ids)
|
|
json_rest = self._hcalendar_restriction_json_data(restriction_item_ids)
|
|
# TODO REVIEW: what are json_rc and json_events used for in calendar management ¿?
|
|
json_rc = self._hcalendar_get_count_reservations_json_data(dfrom, dto)
|
|
json_events = self._hcalendar_events_json_data(dfrom, dto)
|
|
vals.update({
|
|
'prices': json_prices or [],
|
|
'restrictions': json_rest or [],
|
|
'count_reservations': json_rc or [],
|
|
'events': json_events or [],
|
|
})
|
|
|
|
if withRooms:
|
|
room_ids = self.env['hotel.room.type'].search([
|
|
('hotel_id', '=', hotel_id)
|
|
], order='sequence ASC') or None
|
|
|
|
if not room_ids:
|
|
raise AccessError(
|
|
_("Wrong hotel and company access settings for this user. "
|
|
"No room types found for hotel %s") % self.env.user.hotel_id.name)
|
|
|
|
json_rooms = self._hcalendar_room_json_data(room_ids)
|
|
vals.update({'rooms': json_rooms or []})
|
|
|
|
return vals
|
|
|
|
@api.multi
|
|
def get_hcalendar_settings(self):
|
|
user_id = self.env['res.users'].browse(self.env.uid)
|
|
return {
|
|
'eday_week': user_id.npms_end_day_week,
|
|
'eday_week_offset': user_id.npms_end_day_week_offset,
|
|
'days': user_id.npms_default_num_days,
|
|
'show_notifications': user_id.pms_show_notifications,
|
|
'show_num_rooms': user_id.pms_show_num_rooms,
|
|
}
|