171 lines
5.9 KiB
Python
171 lines
5.9 KiB
Python
# This file is part of Presik. The COPYRIGHT file at the top level of
|
|
# this repository contains the full copyright notices and license terms.
|
|
|
|
from trytond.model import ModelView, ModelSQL, fields, Workflow
|
|
from trytond.pool import Pool
|
|
from trytond.exceptions import UserError
|
|
from trytond.i18n import gettext
|
|
|
|
|
|
class RatePlanCalendar(ModelSQL, ModelView):
|
|
'Hotel Rate Plan Calendar'
|
|
__name__ = 'hotel.rate_plan.calendar'
|
|
start_date = fields.Date('Start Date', required=True)
|
|
end_date = fields.Date('End Date', required=True)
|
|
season = fields.Selection([
|
|
('', ''),
|
|
('high', 'High'),
|
|
('low', 'Low'),
|
|
('middle', 'Middle'),
|
|
], 'Season')
|
|
|
|
@staticmethod
|
|
def default_season():
|
|
return 'high'
|
|
|
|
@classmethod
|
|
def __register__(cls, module_name):
|
|
super().__register__(module_name)
|
|
table_h = cls.__table_handler__(module_name)
|
|
table_h.drop_column('type_')
|
|
|
|
|
|
class RatePlan(Workflow, ModelSQL, ModelView):
|
|
'Hotel Rate Plan'
|
|
__name__ = 'hotel.rate_plan'
|
|
active = fields.Boolean('Active')
|
|
name = fields.Char('Name', required=True)
|
|
price_lists = fields.Many2Many('hotel.rate_plan-product.price_list',
|
|
'rate_plan', 'price_list', 'Price Lists', required=True)
|
|
party = fields.Many2One('party.party', 'Party')
|
|
channel = fields.Many2One('hotel.channel', 'Channel')
|
|
minimum_advance = fields.Integer('Minimum Advance', help="In days")
|
|
kind = fields.Selection([
|
|
('channel', 'Channel'),
|
|
('direct', 'Direct'),
|
|
('corporative', 'Corporative'),
|
|
('web', 'Web'),
|
|
('agency', 'Agency'),
|
|
], 'Kind', required=True)
|
|
cancellation_policies = fields.Selection([
|
|
('non_refundable', 'Non-Refundable'),
|
|
('flexible', 'Flexible'),
|
|
], 'Cancellation Policies', required=True)
|
|
minimum_stay = fields.Integer('Minimum Stay',
|
|
help="Minimun stay in days for to apply this plan rate")
|
|
all_inclusive = fields.Boolean('All Inclusive')
|
|
breakfast = fields.Boolean('Breakfast')
|
|
lunch = fields.Boolean('Lunch')
|
|
dinner = fields.Boolean('Dinner')
|
|
# ----------------- variations -----------------
|
|
monday = fields.Char('Monday', help="Example, -15%")
|
|
tuesday = fields.Char('Tuesday', help="Example, -15%")
|
|
wednesday = fields.Char('Wednesday', help="Example, -15%")
|
|
thursday = fields.Char('Thursday', help="Example, -15%")
|
|
friday = fields.Char('Friday', help="Example, -15%")
|
|
saturday = fields.Char('Saturday', help="Example, -15%")
|
|
sunday = fields.Char('Sunday', help="Example, -15%")
|
|
holiday = fields.Char('Holiday', help="Example, -15%")
|
|
price_list = fields.Many2One('product.price_list', 'Default Price List',
|
|
required=False)
|
|
# Add children policy
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super(RatePlan, cls).__setup__()
|
|
|
|
@classmethod
|
|
def __register__(cls, module_name):
|
|
super().__register__(module_name)
|
|
table_h = cls.__table_handler__(module_name)
|
|
table_h.drop_column('start_date')
|
|
table_h.drop_column('end_date')
|
|
table_h.drop_column('cancellation_condition')
|
|
# table_h.drop_column('price_list')
|
|
|
|
@staticmethod
|
|
def default_minimum_stay():
|
|
return 0
|
|
|
|
@staticmethod
|
|
def default_breakfast():
|
|
return True
|
|
|
|
@staticmethod
|
|
def default_active():
|
|
return True
|
|
|
|
@classmethod
|
|
def best_price_list(cls, args):
|
|
"""Get the best available price list for the context
|
|
arrival_date: Date
|
|
departure_date: Date (Optional)
|
|
rate_plan_id: Required
|
|
occupancy_rate for the arrival_date: Computed (Optional)
|
|
"""
|
|
pool = Pool()
|
|
Calendar = pool.get('hotel.rate_plan.calendar')
|
|
Config = pool.get('hotel.configuration')
|
|
rate_plan_id = args.get('rate_plan_id', None)
|
|
arrival_date = args['arrival_date']
|
|
season = 'middle'
|
|
rate_plan = None
|
|
calendars = Calendar.search([
|
|
('start_date', '<=', arrival_date),
|
|
('end_date', '>=', arrival_date),
|
|
])
|
|
print("calendars....", calendars)
|
|
|
|
if calendars:
|
|
season = calendars[0].season
|
|
|
|
price_list = None
|
|
config = Config.get_configuration()
|
|
if rate_plan_id:
|
|
rate_plan = cls(rate_plan_id)
|
|
for pl in rate_plan.price_lists:
|
|
if pl.season == season:
|
|
price_list = pl
|
|
break
|
|
elif config.price_list:
|
|
price_list = config.price_list
|
|
# else:
|
|
# # This is in deprecation
|
|
# price_list = rate_plan.price_list
|
|
|
|
if not price_list:
|
|
raise UserError(gettext('hotel.msg_missing_default_price_list'))
|
|
|
|
# Here add compute of price_list with variations of context,
|
|
# minima estancia, dia de la semana, desayuno incluido, etc
|
|
# including occupancy_rate, IA analysis, and analysis market
|
|
return {'id': price_list.id, 'rec_name': price_list.name}
|
|
|
|
@classmethod
|
|
def best_price(cls, accommodation, price_list):
|
|
"""
|
|
Get the best available rate for the context:::
|
|
price_list: Required
|
|
accommodation: Required (product)
|
|
Return sale price taxed for accommodation
|
|
"""
|
|
PriceList = Pool().get('product.price_list')
|
|
res = accommodation.sale_price_taxed
|
|
if price_list:
|
|
pass
|
|
return res
|
|
|
|
|
|
class RatePlanPriceList(ModelSQL):
|
|
'Rate Plan - Price List'
|
|
__name__ = 'hotel.rate_plan-product.price_list'
|
|
price_list = fields.Many2One('product.price_list', 'Price List',
|
|
required=True, ondelete='CASCADE')
|
|
rate_plan = fields.Many2One('hotel.rate_plan', 'Rate Plan',
|
|
required=True, ondelete='CASCADE')
|
|
|
|
|
|
class RatePlanRule(ModelSQL, ModelView):
|
|
'Hotel Rate Plan'
|
|
__name__ = 'hotel.rate_plan.rule'
|