mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[WIP] refactoring hotel settings
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright 2018 Tecnotel - Alexandre Díaz
|
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
from . import models
|
from . import models
|
||||||
from . import wizard
|
from . import wizard
|
||||||
|
|||||||
@@ -28,7 +28,6 @@
|
|||||||
'wizard/massive_changes.xml',
|
'wizard/massive_changes.xml',
|
||||||
'wizard/split_reservation.xml',
|
'wizard/split_reservation.xml',
|
||||||
'wizard/service_on_day.xml',
|
'wizard/service_on_day.xml',
|
||||||
'views/res_config.xml',
|
|
||||||
'data/menus.xml',
|
'data/menus.xml',
|
||||||
'views/inherited_account_payment_views.xml',
|
'views/inherited_account_payment_views.xml',
|
||||||
'views/inherited_account_invoice_views.xml',
|
'views/inherited_account_invoice_views.xml',
|
||||||
@@ -62,7 +61,6 @@
|
|||||||
'views/hotel_cancelation_rule_views.xml',
|
'views/hotel_cancelation_rule_views.xml',
|
||||||
'views/inherited_webclient_templates.xml',
|
'views/inherited_webclient_templates.xml',
|
||||||
'data/cron_jobs.xml',
|
'data/cron_jobs.xml',
|
||||||
'data/records.xml',
|
|
||||||
'data/email_template_cancel.xml',
|
'data/email_template_cancel.xml',
|
||||||
'data/email_template_reserv.xml',
|
'data/email_template_reserv.xml',
|
||||||
'data/email_template_exit.xml',
|
'data/email_template_exit.xml',
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<!-- keep noupdate to zero for development -->
|
|
||||||
<data noupdate="1">
|
<data noupdate="1">
|
||||||
<!-- Basic hotel -->
|
<!-- Basic hotel -->
|
||||||
|
<record id="main_hotel_room_type_restriction" model="hotel.room.type.restriction">
|
||||||
|
<field name="name">Restriction Plan</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
<record id="main_hotel_property" model="hotel.property">
|
<record id="main_hotel_property" model="hotel.property">
|
||||||
<field name="name">My Hotel</field>
|
<field name="name">My Hotel</field>
|
||||||
<field name="company_id" ref="base.main_company"/>
|
<field name="company_id" ref="base.main_company"/>
|
||||||
|
<field name="pricelist_id" ref="product.list0"/>
|
||||||
|
<field name="restriction_id" ref="main_hotel_room_type_restriction"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="res.users" id="base.user_root">
|
<record model="res.users" id="base.user_root">
|
||||||
|
|||||||
@@ -364,6 +364,7 @@
|
|||||||
})]"/>
|
})]"/>
|
||||||
</record>
|
</record>
|
||||||
<!-- reservation of 3 single rooms for 3 people with 1 cancelled -->
|
<!-- reservation of 3 single rooms for 3 people with 1 cancelled -->
|
||||||
|
<!-- TODO: The third reservation is marked from State: Cancelled to Pending Entry at Folio creation -->
|
||||||
<record id="hotel_folio_2" model="hotel.folio">
|
<record id="hotel_folio_2" model="hotel.folio">
|
||||||
<field name="partner_id" ref="base.res_partner_address_10"/>
|
<field name="partner_id" ref="base.res_partner_address_10"/>
|
||||||
<field name="room_lines"
|
<field name="room_lines"
|
||||||
@@ -406,19 +407,20 @@
|
|||||||
'state': 'confirm',
|
'state': 'confirm',
|
||||||
})]"/>
|
})]"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<!-- out of service room -->
|
<!-- out of service room -->
|
||||||
<record id="hotel_folio_4" model="hotel.folio">
|
<record id="hotel_folio_4" model="hotel.folio">
|
||||||
<field name="partner_id" ref="base.res_partner_1"/>
|
<field name="partner_id" ref="main_hotel_property"/>
|
||||||
<field name="reservation_type">out</field>
|
<field name="reservation_type">out</field>
|
||||||
<field name="closure_reason_id" ref="hotel_room_closure_reason_0"/>
|
|
||||||
<field name="room_lines"
|
<field name="room_lines"
|
||||||
eval="[(5, 0), (0, 0, {
|
eval="[(5, 0), (0, 0, {
|
||||||
'pricelist_id': 1,
|
'pricelist_id': 1,
|
||||||
'room_type_id': ref('hotel_room_type_1'),
|
'room_type_id': ref('hotel_room_type_1'),
|
||||||
'checkin': DateTime.today().strftime('%Y-%m-%d'),
|
'checkin': DateTime.today().strftime('%Y-%m-%d'),
|
||||||
'checkout': (DateTime.today() + timedelta(days=2)).strftime('%Y-%m-%d'),
|
'checkout': (DateTime.today() + timedelta(days=2)).strftime('%Y-%m-%d'),
|
||||||
|
'adults': 1,
|
||||||
'state': 'confirm',
|
'state': 'confirm',
|
||||||
|
'reservation_type': 'out',
|
||||||
|
'closure_reason_id': ref('hotel_room_closure_reason_0'),
|
||||||
'out_service_description': 'Change of lighting',
|
'out_service_description': 'Change of lighting',
|
||||||
})]"/>
|
})]"/>
|
||||||
</record>
|
</record>
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
<odoo>
|
|
||||||
<data noupdate="1">
|
|
||||||
|
|
||||||
<record model="hotel.room.type.restriction">
|
|
||||||
<field name="name">Default Restrictions</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
|
|
||||||
<function id="default_pricelist_id"
|
|
||||||
model="ir.default" name="set"
|
|
||||||
eval="('res.config.settings', 'default_pricelist_id', 1)"/>
|
|
||||||
|
|
||||||
<function id="default_restriction_id"
|
|
||||||
model="ir.default" name="set"
|
|
||||||
eval="('res.config.settings', 'default_restriction_id', 1)"/>
|
|
||||||
|
|
||||||
<function id="default_generate_default_arrival_hour"
|
|
||||||
model="ir.default" name="set"
|
|
||||||
eval="('res.config.settings', 'default_arrival_hour', '14:00')"/>
|
|
||||||
|
|
||||||
<function id="default_generate_default_departure_hour"
|
|
||||||
model="ir.default" name="set"
|
|
||||||
eval="('res.config.settings', 'default_departure_hour', '12:00')"/>
|
|
||||||
|
|
||||||
</data>
|
|
||||||
</odoo>
|
|
||||||
@@ -25,7 +25,6 @@ from . import hotel_room_type_restriction_item
|
|||||||
from . import hotel_reservation_line
|
from . import hotel_reservation_line
|
||||||
from . import hotel_checkin_partner
|
from . import hotel_checkin_partner
|
||||||
from . import inherited_product_pricelist
|
from . import inherited_product_pricelist
|
||||||
from . import res_config
|
|
||||||
from . import inherited_res_partner
|
from . import inherited_res_partner
|
||||||
from . import inherited_mail_compose_message
|
from . import inherited_mail_compose_message
|
||||||
from . import hotel_room_type_class
|
from . import hotel_room_type_class
|
||||||
|
|||||||
@@ -12,6 +12,6 @@ class HotelRoomAmenitie(models.Model):
|
|||||||
default_code = fields.Char('Internal Reference')
|
default_code = fields.Char('Internal Reference')
|
||||||
room_amenity_type_id = fields.Many2one('hotel.amenity.type',
|
room_amenity_type_id = fields.Many2one('hotel.amenity.type',
|
||||||
'Amenity Catagory')
|
'Amenity Catagory')
|
||||||
hotel_ids = fields.Many2many('hotel.property', 'Hotels', required=False, ondelete='restrict')
|
hotel_ids = fields.Many2many('hotel.property', string='Hotels', required=False, ondelete='restrict')
|
||||||
|
|
||||||
#TODO: Constrain coherence hotel_ids with amenity types hotel_ids
|
#TODO: Constrain coherence hotel_ids with amenity types hotel_ids
|
||||||
|
|||||||
@@ -13,6 +13,6 @@ class HotelRoomAmenitieType(models.Model):
|
|||||||
room_amenity_ids = fields.One2many('hotel.amenity',
|
room_amenity_ids = fields.One2many('hotel.amenity',
|
||||||
'room_amenity_type_id',
|
'room_amenity_type_id',
|
||||||
'Amenities in this category')
|
'Amenities in this category')
|
||||||
hotel_ids = fields.Many2many('hotel.property', 'Hotels', required=False, ondelete='restrict')
|
hotel_ids = fields.Many2many('hotel.property', string='Hotels', required=False, ondelete='restrict')
|
||||||
|
|
||||||
#TODO: Constrain coherence hotel_ids with amenities hotel_ids
|
#TODO: Constrain coherence hotel_ids with amenities hotel_ids
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
from odoo import models, fields
|
from odoo import models, fields
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: refactoring to cancellation.rule
|
||||||
class HotelCancelationRule(models.Model):
|
class HotelCancelationRule(models.Model):
|
||||||
_name = 'hotel.cancelation.rule'
|
_name = 'hotel.cancelation.rule'
|
||||||
_description = 'Cancelation Rules'
|
_description = 'Cancelation Rules'
|
||||||
|
|||||||
@@ -189,14 +189,12 @@ class HotelCheckinPartner(models.Model):
|
|||||||
|
|
||||||
def _get_arrival_hour(self):
|
def _get_arrival_hour(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
tz_hotel = self.env['ir.default'].sudo().get(
|
tz_hotel = self.env.user.hotel_id.tz
|
||||||
'res.config.settings', 'tz_hotel')
|
|
||||||
today = fields.Datetime.context_timestamp(
|
today = fields.Datetime.context_timestamp(
|
||||||
self.with_context(tz=tz_hotel),
|
self.with_context(tz=tz_hotel),
|
||||||
datetime.datetime.strptime(fields.Date.today(),
|
datetime.datetime.strptime(fields.Date.today(),
|
||||||
DEFAULT_SERVER_DATE_FORMAT))
|
DEFAULT_SERVER_DATE_FORMAT))
|
||||||
default_arrival_hour = self.env['ir.default'].sudo().get(
|
default_arrival_hour = self.env.user.hotel_id.arrival_hour
|
||||||
'res.config.settings', 'default_arrival_hour')
|
|
||||||
if self.reservation_id.checkin < today.strftime(DEFAULT_SERVER_DATE_FORMAT):
|
if self.reservation_id.checkin < today.strftime(DEFAULT_SERVER_DATE_FORMAT):
|
||||||
return default_arrival_hour
|
return default_arrival_hour
|
||||||
now = fields.Datetime.context_timestamp(
|
now = fields.Datetime.context_timestamp(
|
||||||
@@ -208,14 +206,12 @@ class HotelCheckinPartner(models.Model):
|
|||||||
|
|
||||||
def _get_departure_hour(self):
|
def _get_departure_hour(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
tz_hotel = self.env['ir.default'].sudo().get(
|
tz_hotel = self.env.user.hotel_id.tz
|
||||||
'res.config.settings', 'tz_hotel')
|
|
||||||
today = fields.Datetime.context_timestamp(
|
today = fields.Datetime.context_timestamp(
|
||||||
self.with_context(tz=tz_hotel),
|
self.with_context(tz=tz_hotel),
|
||||||
datetime.datetime.strptime(fields.Date.today(),
|
datetime.datetime.strptime(fields.Date.today(),
|
||||||
DEFAULT_SERVER_DATE_FORMAT))
|
DEFAULT_SERVER_DATE_FORMAT))
|
||||||
default_departure_hour = self.env['ir.default'].sudo().get(
|
default_departure_hour = self.env.user.hotel_id.departure_hour
|
||||||
'res.config.settings', 'default_departure_hour')
|
|
||||||
if self.reservation_id.checkout < today.strftime(DEFAULT_SERVER_DATE_FORMAT):
|
if self.reservation_id.checkout < today.strftime(DEFAULT_SERVER_DATE_FORMAT):
|
||||||
return default_departure_hour
|
return default_departure_hour
|
||||||
now = fields.Datetime.context_timestamp(
|
now = fields.Datetime.context_timestamp(
|
||||||
|
|||||||
@@ -462,8 +462,8 @@ class HotelFolio(models.Model):
|
|||||||
|
|
||||||
addr = self.partner_id.address_get(['invoice'])
|
addr = self.partner_id.address_get(['invoice'])
|
||||||
pricelist = self.partner_id.property_product_pricelist and \
|
pricelist = self.partner_id.property_product_pricelist and \
|
||||||
self.partner_id.property_product_pricelist.id or \
|
self.partner_id.property_product_pricelist.id or \
|
||||||
self.env['ir.default'].sudo().get('res.config.settings', 'default_pricelist_id')
|
self.env.user.hotel_id.pricelist_id.id
|
||||||
values = {
|
values = {
|
||||||
'pricelist_id': pricelist,
|
'pricelist_id': pricelist,
|
||||||
'payment_term_id': self.partner_id.property_payment_term_id and self.partner_id.property_payment_term_id.id or False,
|
'payment_term_id': self.partner_id.property_payment_term_id and self.partner_id.property_payment_term_id.id or False,
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
# Copyright 2019 Dario Lodeiros
|
# Copyright 2019 Dario Lodeiros
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from odoo import models, api, fields
|
import re
|
||||||
|
from odoo import models, fields, api, _
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
class HotelProperty(models.Model):
|
class HotelProperty(models.Model):
|
||||||
@@ -18,4 +20,29 @@ class HotelProperty(models.Model):
|
|||||||
string='Accepted Users')
|
string='Accepted Users')
|
||||||
|
|
||||||
room_type_ids = fields.One2many('hotel.room.type', 'hotel_id', 'Room Types')
|
room_type_ids = fields.One2many('hotel.room.type', 'hotel_id', 'Room Types')
|
||||||
room_ids = fields.One2many('hotel.room', 'hotel_id', 'Room')
|
room_ids = fields.One2many('hotel.room', 'hotel_id', 'Rooms')
|
||||||
|
|
||||||
|
# TODO: refactoring res.config.settings', 'default_pricelist_id' by the current hotel.property.pricelist_id
|
||||||
|
pricelist_id = fields.Many2one('product.pricelist', 'Product Pricelist',
|
||||||
|
help='The default pricelist used in this hotel.',
|
||||||
|
required=True)
|
||||||
|
# TODO: refactoring res.config.settings', 'default_restriction_id by the current hotel.property.restriction_id
|
||||||
|
restriction_id = fields.Many2one('hotel.room.type.restriction', 'Restriction Plan',
|
||||||
|
help='The default restriction plan used in this hotel.',
|
||||||
|
required=True)
|
||||||
|
|
||||||
|
# TODO: refactoring 'res.config.settings', 'default_arrival_hour' by the current hotel.property.arrival_hour
|
||||||
|
arrival_hour = fields.Char('Arrival Hour (GMT)',
|
||||||
|
help="HH:mm Format", default="14:00")
|
||||||
|
# TODO: refactoring 'res.config.settings', 'default_departure_hour' by the current hotel.property.departure_hour
|
||||||
|
departure_hour = fields.Char('Departure Hour (GMT)',
|
||||||
|
help="HH:mm Format", default="12:00")
|
||||||
|
|
||||||
|
# TODO: refactoring 'res.config.settings', 'tz_hotel' by the current hotel.property.tz (inherited in res.partner)
|
||||||
|
|
||||||
|
def _check_hours(self):
|
||||||
|
r = re.compile('[0-2][0-9]:[0-5][0-9]')
|
||||||
|
if not r.match(self.arrival_hour):
|
||||||
|
raise ValidationError(_("Invalid arrival hour (Format: HH:mm)"))
|
||||||
|
if not r.match(self.departure_hour):
|
||||||
|
raise ValidationError(_("Invalid departure hour (Format: HH:mm)"))
|
||||||
|
|||||||
@@ -31,8 +31,7 @@ class HotelReservation(models.Model):
|
|||||||
if folio and folio.room_lines:
|
if folio and folio.room_lines:
|
||||||
return folio.room_lines[0].checkin
|
return folio.room_lines[0].checkin
|
||||||
else:
|
else:
|
||||||
tz_hotel = self.env['ir.default'].sudo().get(
|
tz_hotel = self.env.user.hotel_id.tz
|
||||||
'res.config.settings', 'tz_hotel')
|
|
||||||
today = fields.Date.context_today(self.with_context(tz=tz_hotel))
|
today = fields.Date.context_today(self.with_context(tz=tz_hotel))
|
||||||
return fields.Date.from_string(today).strftime(DEFAULT_SERVER_DATE_FORMAT)
|
return fields.Date.from_string(today).strftime(DEFAULT_SERVER_DATE_FORMAT)
|
||||||
|
|
||||||
@@ -45,16 +44,14 @@ class HotelReservation(models.Model):
|
|||||||
if folio and folio.room_lines:
|
if folio and folio.room_lines:
|
||||||
return folio.room_lines[0].checkout
|
return folio.room_lines[0].checkout
|
||||||
else:
|
else:
|
||||||
tz_hotel = self.env['ir.default'].sudo().get(
|
tz_hotel = self.env.user.hotel_id.tz
|
||||||
'res.config.settings', 'tz_hotel')
|
|
||||||
today = fields.Date.context_today(self.with_context(tz=tz_hotel))
|
today = fields.Date.context_today(self.with_context(tz=tz_hotel))
|
||||||
return (fields.Date.from_string(today) + timedelta(days=1)).strftime(
|
return (fields.Date.from_string(today) + timedelta(days=1)).strftime(
|
||||||
DEFAULT_SERVER_DATE_FORMAT)
|
DEFAULT_SERVER_DATE_FORMAT)
|
||||||
|
|
||||||
def _get_default_arrival_hour(self):
|
def _get_default_arrival_hour(self):
|
||||||
folio = False
|
folio = False
|
||||||
default_arrival_hour = self.env['ir.default'].sudo().get(
|
default_arrival_hour = self.env.user.hotel_id.arrival_hour
|
||||||
'res.config.settings', 'default_arrival_hour')
|
|
||||||
if 'folio_id' in self._context:
|
if 'folio_id' in self._context:
|
||||||
folio = self.env['hotel.folio'].search([
|
folio = self.env['hotel.folio'].search([
|
||||||
('id', '=', self._context['folio_id'])
|
('id', '=', self._context['folio_id'])
|
||||||
@@ -66,8 +63,7 @@ class HotelReservation(models.Model):
|
|||||||
|
|
||||||
def _get_default_departure_hour(self):
|
def _get_default_departure_hour(self):
|
||||||
folio = False
|
folio = False
|
||||||
default_departure_hour = self.env['ir.default'].sudo().get(
|
default_departure_hour = self.env.user.hotel_id.departure_hour
|
||||||
'res.config.settings', 'default_departure_hour')
|
|
||||||
if 'folio_id' in self._context:
|
if 'folio_id' in self._context:
|
||||||
folio = self.env['hotel.folio'].search([
|
folio = self.env['hotel.folio'].search([
|
||||||
('id', '=', self._context['folio_id'])
|
('id', '=', self._context['folio_id'])
|
||||||
@@ -226,7 +222,7 @@ class HotelReservation(models.Model):
|
|||||||
|
|
||||||
partner_id = fields.Many2one(related='folio_id.partner_id')
|
partner_id = fields.Many2one(related='folio_id.partner_id')
|
||||||
tour_operator_id = fields.Many2one(related='folio_id.tour_operator_id')
|
tour_operator_id = fields.Many2one(related='folio_id.tour_operator_id')
|
||||||
partner_invoice_id = fields.Many2one(related='folio_id.partner_invoice_id')
|
partner_invoice_id = fields.Many2one(related='folio_id.partner_invoice_id')
|
||||||
partner_invoice_vat = fields.Char(related="partner_invoice_id.vat")
|
partner_invoice_vat = fields.Char(related="partner_invoice_id.vat")
|
||||||
partner_invoice_name = fields.Char(related="partner_invoice_id.name")
|
partner_invoice_name = fields.Char(related="partner_invoice_id.name")
|
||||||
partner_invoice_street = fields.Char(related="partner_invoice_id.street")
|
partner_invoice_street = fields.Char(related="partner_invoice_id.street")
|
||||||
@@ -673,8 +669,8 @@ class HotelReservation(models.Model):
|
|||||||
def onchange_partner_id(self):
|
def onchange_partner_id(self):
|
||||||
addr = self.partner_id.address_get(['invoice'])
|
addr = self.partner_id.address_get(['invoice'])
|
||||||
pricelist = self.partner_id.property_product_pricelist and \
|
pricelist = self.partner_id.property_product_pricelist and \
|
||||||
self.partner_id.property_product_pricelist.id or \
|
self.partner_id.property_product_pricelist.id or \
|
||||||
self.env['ir.default'].sudo().get('res.config.settings', 'default_pricelist_id')
|
self.env.user.hotel_id.pricelist_id.id
|
||||||
values = {
|
values = {
|
||||||
'pricelist_id': pricelist,
|
'pricelist_id': pricelist,
|
||||||
'partner_invoice_id': addr['invoice'],
|
'partner_invoice_id': addr['invoice'],
|
||||||
@@ -896,8 +892,7 @@ class HotelReservation(models.Model):
|
|||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
pricelist = self.pricelist_id
|
pricelist = self.pricelist_id
|
||||||
if pricelist and pricelist.cancelation_rule_id:
|
if pricelist and pricelist.cancelation_rule_id:
|
||||||
tz_hotel = self.env['ir.default'].sudo().get(
|
tz_hotel = self.env.user.hotel_id.tz
|
||||||
'res.config.settings', 'tz_hotel')
|
|
||||||
today = fields.Date.context_today(self.with_context(
|
today = fields.Date.context_today(self.with_context(
|
||||||
tz=tz_hotel))
|
tz=tz_hotel))
|
||||||
days_diff = (fields.Date.from_string(self.real_checkin) -
|
days_diff = (fields.Date.from_string(self.real_checkin) -
|
||||||
|
|||||||
@@ -14,20 +14,18 @@ class HotelRoomTypeRestriction(models.Model):
|
|||||||
item_ids = fields.One2many('hotel.room.type.restriction.item',
|
item_ids = fields.One2many('hotel.room.type.restriction.item',
|
||||||
'restriction_id', string='Restriction Items',
|
'restriction_id', string='Restriction Items',
|
||||||
copy=True)
|
copy=True)
|
||||||
active = fields.Boolean('Active',
|
active = fields.Boolean('Active', default=True,
|
||||||
help='If unchecked, it will allow you to hide the \
|
help='If unchecked, it will allow you to hide the '
|
||||||
restriction plan without removing it.',
|
'restriction plan without removing it.')
|
||||||
default=True)
|
hotel_ids = fields.One2many('hotel.property',
|
||||||
hotel_id = fields.Many2one('hotel.property', default=_get_default_hotel,
|
'restriction_id', string='Restriction Plan',
|
||||||
required=True, ondelete='cascade')
|
default=_get_default_hotel, required=True)
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
@api.depends('name')
|
@api.depends('name')
|
||||||
def name_get(self):
|
def name_get(self):
|
||||||
restriction_id = self.env['ir.default'].sudo().get(
|
# TODO: refactoring res.config.settings', 'default_restriction_id by the current hotel.property.restriction_id
|
||||||
'res.config.settings', 'default_restriction_id')
|
restriction_id = self.env.user.hotel_id.restriction_id.id
|
||||||
if restriction_id:
|
|
||||||
restriction_id = int(restriction_id)
|
|
||||||
names = []
|
names = []
|
||||||
for record in self:
|
for record in self:
|
||||||
if record.id == restriction_id:
|
if record.id == restriction_id:
|
||||||
|
|||||||
@@ -21,8 +21,10 @@ class HotelRoomTypeRestrictionItem(models.Model):
|
|||||||
closed = fields.Boolean('Closed')
|
closed = fields.Boolean('Closed')
|
||||||
closed_departure = fields.Boolean('Closed Departure')
|
closed_departure = fields.Boolean('Closed Departure')
|
||||||
closed_arrival = fields.Boolean('Closed Arrival')
|
closed_arrival = fields.Boolean('Closed Arrival')
|
||||||
hotel_id = fields.Many2one('hotel.property', store=True, readonly=True,
|
hotel_ids = fields.One2many('hotel.property',
|
||||||
related='restriction_id.hotel_id')
|
'restriction_id', string='Restriction Plan',
|
||||||
|
store=True, readonly=True,
|
||||||
|
related='restriction_id.hotel_ids')
|
||||||
|
|
||||||
_sql_constraints = [('room_type_registry_unique',
|
_sql_constraints = [('room_type_registry_unique',
|
||||||
'unique(restriction_id, room_type_id, date)',
|
'unique(restriction_id, room_type_id, date)',
|
||||||
@@ -37,7 +39,7 @@ class HotelRoomTypeRestrictionItem(models.Model):
|
|||||||
raise ValidationError(_("Min. Stay can't be less than zero"))
|
raise ValidationError(_("Min. Stay can't be less than zero"))
|
||||||
elif record.min_stay_arrival < 0:
|
elif record.min_stay_arrival < 0:
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
("Min. Stay Arrival can't be less than zero"))
|
_("Min. Stay Arrival can't be less than zero"))
|
||||||
elif record.max_stay < 0:
|
elif record.max_stay < 0:
|
||||||
raise ValidationError(_("Max. Stay can't be less than zero"))
|
raise ValidationError(_("Max. Stay can't be less than zero"))
|
||||||
elif record.max_stay_arrival < 0:
|
elif record.max_stay_arrival < 0:
|
||||||
|
|||||||
@@ -14,21 +14,7 @@ class ProductPricelist(models.Model):
|
|||||||
cancelation_rule_id = fields.Many2one(
|
cancelation_rule_id = fields.Many2one(
|
||||||
'hotel.cancelation.rule',
|
'hotel.cancelation.rule',
|
||||||
string="Cancelation Policy")
|
string="Cancelation Policy")
|
||||||
|
|
||||||
hotel_ids = fields.Many2many('hotel.property', string='Hotels', required=False,
|
hotel_ids = fields.Many2many('hotel.property', string='Hotels', required=False,
|
||||||
ondelete='restrict')
|
ondelete='restrict')
|
||||||
|
|
||||||
@api.multi
|
|
||||||
@api.depends('name')
|
|
||||||
def name_get(self):
|
|
||||||
pricelist_id = self.env['ir.default'].sudo().get(
|
|
||||||
'res.config.settings', 'default_pricelist_id')
|
|
||||||
if pricelist_id:
|
|
||||||
pricelist_id = int(pricelist_id)
|
|
||||||
org_names = super(ProductPricelist, self).name_get()
|
|
||||||
names = []
|
|
||||||
for name in org_names:
|
|
||||||
if name[0] == pricelist_id:
|
|
||||||
names.append((name[0], '%s (Default)' % name[1]))
|
|
||||||
else:
|
|
||||||
names.append((name[0], name[1]))
|
|
||||||
return names
|
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
# Copyright 2017-2018 Alexandre Díaz
|
|
||||||
# Copyright 2017 Dario Lodeiros
|
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
||||||
import re
|
|
||||||
import pytz
|
|
||||||
from openerp import models, fields, api, _
|
|
||||||
from openerp.exceptions import ValidationError
|
|
||||||
|
|
||||||
|
|
||||||
@api.model
|
|
||||||
def _tz_get(self):
|
|
||||||
# put POSIX 'Etc/*' entries at the end to avoid confusing users
|
|
||||||
# see bug 1086728
|
|
||||||
return [(tz, tz) for tz in sorted(pytz.all_timezones,
|
|
||||||
key=lambda tz: tz
|
|
||||||
if not tz.startswith('Etc/') else '_')]
|
|
||||||
|
|
||||||
|
|
||||||
class HotelConfiguration(models.TransientModel):
|
|
||||||
_inherit = 'res.config.settings'
|
|
||||||
|
|
||||||
default_pricelist_id = fields.Many2one('product.pricelist',
|
|
||||||
'Product Pricelist')
|
|
||||||
default_restriction_id = fields.Many2one('hotel.room.type.restriction',
|
|
||||||
'Restrictions')
|
|
||||||
default_arrival_hour = fields.Char('Default Arrival Hour (GMT)',
|
|
||||||
help="HH:mm Format", default="14:00")
|
|
||||||
default_departure_hour = fields.Char('Default Departure Hour (GMT)',
|
|
||||||
help="HH:mm Format", default="12:00")
|
|
||||||
tz_hotel = fields.Selection(_tz_get, string='Timezone',
|
|
||||||
default=lambda self: self._context.get('tz'),
|
|
||||||
help="The hotel's timezone, used to manage \
|
|
||||||
date and time values in reservations \
|
|
||||||
It is important to set a value for this \
|
|
||||||
field.")
|
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def set_values(self):
|
|
||||||
super(HotelConfiguration, self).set_values()
|
|
||||||
|
|
||||||
self.env['ir.default'].sudo().set(
|
|
||||||
'res.config.settings', 'default_pricelist_id',
|
|
||||||
self.default_pricelist_id.id)
|
|
||||||
self.env['ir.default'].sudo().set(
|
|
||||||
'res.config.settings', 'default_restriction_id',
|
|
||||||
self.default_restriction_id.id)
|
|
||||||
self.env['ir.default'].sudo().set(
|
|
||||||
'res.config.settings', 'tz_hotel', self.tz_hotel)
|
|
||||||
self.env['ir.default'].sudo().set(
|
|
||||||
'res.config.settings', 'default_arrival_hour',
|
|
||||||
self.default_arrival_hour)
|
|
||||||
self.env['ir.default'].sudo().set(
|
|
||||||
'res.config.settings', 'default_departure_hour',
|
|
||||||
self.default_departure_hour)
|
|
||||||
|
|
||||||
@api.model
|
|
||||||
def get_values(self):
|
|
||||||
res = super(HotelConfiguration, self).get_values()
|
|
||||||
|
|
||||||
# ONLY FOR v11. DO NOT FORWARD-PORT
|
|
||||||
default_pricelist_id = self.env['ir.default'].sudo().get(
|
|
||||||
'res.config.settings', 'default_pricelist_id')
|
|
||||||
default_restriction_id = self.env['ir.default'].sudo().get(
|
|
||||||
'res.config.settings', 'default_restriction_id')
|
|
||||||
tz_hotel = self.env['ir.default'].sudo().get(
|
|
||||||
'res.config.settings', 'tz_hotel')
|
|
||||||
default_arrival_hour = self.env['ir.default'].sudo().get(
|
|
||||||
'res.config.settings', 'default_arrival_hour')
|
|
||||||
default_departure_hour = self.env['ir.default'].sudo().get(
|
|
||||||
'res.config.settings', 'default_departure_hour')
|
|
||||||
res.update(
|
|
||||||
default_pricelist_id=default_pricelist_id,
|
|
||||||
default_restriction_id=default_restriction_id,
|
|
||||||
tz_hotel=tz_hotel,
|
|
||||||
default_arrival_hour=default_arrival_hour,
|
|
||||||
default_departure_hour=default_departure_hour,
|
|
||||||
)
|
|
||||||
return res
|
|
||||||
|
|
||||||
@api.constrains('default_arrival_hour', 'default_departure_hour')
|
|
||||||
def _check_hours(self):
|
|
||||||
r = re.compile('[0-2][0-9]:[0-5][0-9]')
|
|
||||||
if not r.match(self.default_arrival_hour):
|
|
||||||
raise ValidationError(_("Invalid arrival hour (Format: HH:mm)"))
|
|
||||||
if not r.match(self.default_departure_hour):
|
|
||||||
raise ValidationError(_("Invalid departure hour (Format: HH:mm)"))
|
|
||||||
@@ -64,7 +64,6 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<field name="hotel_id" invisible="0"/>
|
|
||||||
<h2><field name="name"/></h2>
|
<h2><field name="name"/></h2>
|
||||||
<h1>
|
<h1>
|
||||||
<field name="partner_id" default_focus="1" placeholder="Guest" attrs="{'invisible':[('reservation_type','in',('out'))]}"/>
|
<field name="partner_id" default_focus="1" placeholder="Guest" attrs="{'invisible':[('reservation_type','in',('out'))]}"/>
|
||||||
@@ -80,8 +79,8 @@
|
|||||||
<field name="cancelled_reason" attrs="{'invisible':[('state','not in',('cancel'))]}"/>
|
<field name="cancelled_reason" attrs="{'invisible':[('state','not in',('cancel'))]}"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
|
<field name="hotel_id" invisible="0"/>
|
||||||
<field name="pricelist_id" />
|
<field name="pricelist_id" />
|
||||||
<field name="hotel_id" invisible="1"/>
|
|
||||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||||
<field name="reservation_type" attrs="{'readonly':[('state','not in',('draft'))]}"/>
|
<field name="reservation_type" attrs="{'readonly':[('state','not in',('draft'))]}"/>
|
||||||
<field name="channel_type" attrs="{'required':[('reservation_type','=','normal')]}"/>
|
<field name="channel_type" attrs="{'required':[('reservation_type','=','normal')]}"/>
|
||||||
|
|||||||
@@ -13,12 +13,29 @@
|
|||||||
<h1>
|
<h1>
|
||||||
<field name="name" class="oe_inline" />
|
<field name="name" class="oe_inline" />
|
||||||
</h1>
|
</h1>
|
||||||
|
<field name="company_id" class="oe_inline" />
|
||||||
<notebook>
|
<notebook>
|
||||||
<page string="Hotel Settings" name="hotel_settings">
|
<page string="General Information" name="hotel_general">
|
||||||
|
<group>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="Settings" name="hotel_settings">
|
||||||
<group colspan="4" col="4">
|
<group colspan="4" col="4">
|
||||||
<field name="company_id" class="oe_inline" />
|
<field name="pricelist_id" required="True" />
|
||||||
|
<field name="restriction_id" required="True" />
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="tz" widget="timezone_mismatch"/>
|
||||||
</group>
|
</group>
|
||||||
<group colspan="4" col="4">
|
<group colspan="4" col="4">
|
||||||
|
<field name="arrival_hour" />
|
||||||
|
<field name="departure_hour" />
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="Rooms" name="hotel_settings">
|
||||||
|
<group>
|
||||||
|
<field name="room_type_ids"/>
|
||||||
|
<field name="room_ids"/>
|
||||||
</group>
|
</group>
|
||||||
</page>
|
</page>
|
||||||
</notebook>
|
</notebook>
|
||||||
@@ -41,10 +58,14 @@
|
|||||||
<!-- actions -->
|
<!-- actions -->
|
||||||
|
|
||||||
<record id="hotel_property_action" model="ir.actions.act_window">
|
<record id="hotel_property_action" model="ir.actions.act_window">
|
||||||
<field name="name">Hotel Property</field>
|
<field name="name">Hotels</field>
|
||||||
<field name="res_model">hotel.property</field>
|
<field name="res_model">hotel.property</field>
|
||||||
<field name="view_type">form</field>
|
<field name="view_type">form</field>
|
||||||
<field name="view_mode">tree,form</field>
|
<field name="view_mode">tree,form</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<!-- menus -->
|
||||||
|
|
||||||
|
<menuitem action="hotel_property_action" id="hotel_property_menu" parent="base.menu_users" sequence="10"/>
|
||||||
|
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<group>
|
<group>
|
||||||
<field name="hotel_id" invisible="0"/>
|
<field name="hotel_ids" invisible="0"/>
|
||||||
</group>
|
</group>
|
||||||
<div>
|
<div>
|
||||||
<separator string="Pricelist Items"/>
|
<separator string="Pricelist Items"/>
|
||||||
|
|||||||
@@ -16,4 +16,8 @@
|
|||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<menuitem name="Pricelist" id="pricelist_menu"
|
||||||
|
action="product.product_pricelist_action2" sequence="22"
|
||||||
|
parent="hotel.configuration_others" />
|
||||||
|
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<odoo>
|
|
||||||
|
|
||||||
<!-- Hotel Settings -->
|
|
||||||
<record id="view_hotel_config_settings" model="ir.ui.view">
|
|
||||||
<field name="name">res.config.settings.view.form.inherit.hotel</field>
|
|
||||||
<field name="model">res.config.settings</field>
|
|
||||||
<field name="priority" eval="80"/>
|
|
||||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
|
||||||
<div class="app_settings_block" data-string="Hotel" string="Hotel" data-key="hotel" groups="hotel.group_hotel_manager">
|
|
||||||
<h2 id="default_hotel">Hotel Default</h2>
|
|
||||||
<div class="row mt16 o_settings_container">
|
|
||||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
|
||||||
<label for="default_pricelist_id"/>
|
|
||||||
<div class="text-muted">
|
|
||||||
Set pricelist default
|
|
||||||
</div>
|
|
||||||
<div class="content-group">
|
|
||||||
<div class="mt16">
|
|
||||||
<field name="default_pricelist_id" required="True" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
|
||||||
<label for="default_restriction_id"/>
|
|
||||||
<div class="text-muted">
|
|
||||||
Set restrictions default
|
|
||||||
</div>
|
|
||||||
<div class="content-group">
|
|
||||||
<div class="mt16">
|
|
||||||
<field name="default_restriction_id" required="True" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<h2 id="default_hours">Hotel Default Hours</h2>
|
|
||||||
<div class="row mt16 o_settings_container">
|
|
||||||
<div class="col-xs-12 col-md-12 o_setting_box">
|
|
||||||
<label for="tz_hotel"/>
|
|
||||||
<div class="text-muted">
|
|
||||||
Set time-zone
|
|
||||||
</div>
|
|
||||||
<div class="content-group">
|
|
||||||
<div class="mt16">
|
|
||||||
<field name="tz_hotel"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
|
||||||
<label for="default_arrival_hour"/>
|
|
||||||
<div class="text-muted">
|
|
||||||
Set default arrival hour
|
|
||||||
</div>
|
|
||||||
<div class="content-group">
|
|
||||||
<div class="mt16">
|
|
||||||
<field name="default_arrival_hour" required="True" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
|
||||||
<label for="default_departure_hour"/>
|
|
||||||
<div class="text-muted">
|
|
||||||
Set default departure hour
|
|
||||||
</div>
|
|
||||||
<div class="content-group">
|
|
||||||
<div class="mt16">
|
|
||||||
<field name="default_departure_hour" required="True" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</xpath>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
</odoo>
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Copyright 2017 Darío Lodeiros
|
# Copyright 2017 Darío Lodeiros
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
from openerp import models, fields, api
|
from odoo import models, fields, api
|
||||||
from odoo.tools import (
|
from odoo.tools import (
|
||||||
DEFAULT_SERVER_DATE_FORMAT)
|
DEFAULT_SERVER_DATE_FORMAT)
|
||||||
|
|
||||||
@@ -9,12 +9,10 @@ class ServiceOnDay(models.TransientModel):
|
|||||||
_name = 'service.on.day'
|
_name = 'service.on.day'
|
||||||
|
|
||||||
def _get_default_date(self):
|
def _get_default_date(self):
|
||||||
tz_hotel = self.env['ir.default'].sudo().get(
|
tz_hotel = self.env.user.hotel_id.tz
|
||||||
'res.config.settings', 'tz_hotel')
|
|
||||||
today = fields.Date.context_today(self.with_context(tz=tz_hotel))
|
today = fields.Date.context_today(self.with_context(tz=tz_hotel))
|
||||||
return fields.Date.from_string(today).strftime(DEFAULT_SERVER_DATE_FORMAT)
|
return fields.Date.from_string(today).strftime(DEFAULT_SERVER_DATE_FORMAT)
|
||||||
|
|
||||||
|
|
||||||
product_id = fields.Many2one('product.product', 'Service', required=True,
|
product_id = fields.Many2one('product.product', 'Service', required=True,
|
||||||
domain=[('per_day', '=', True)])
|
domain=[('per_day', '=', True)])
|
||||||
product_qty = fields.Integer('Quantity', default=1)
|
product_qty = fields.Integer('Quantity', default=1)
|
||||||
|
|||||||
@@ -51,8 +51,7 @@ class FolioWizard(models.TransientModel):
|
|||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _get_default_pricelist(self):
|
def _get_default_pricelist(self):
|
||||||
return self.env['ir.default'].sudo().get(
|
return self.env.user.hotel_id.pricelist_id.id
|
||||||
'res.config.settings', 'default_pricelist_id')
|
|
||||||
|
|
||||||
partner_id = fields.Many2one('res.partner', required=True, string="Customer")
|
partner_id = fields.Many2one('res.partner', required=True, string="Customer")
|
||||||
email = fields.Char('E-mail')
|
email = fields.Char('E-mail')
|
||||||
@@ -107,8 +106,7 @@ class FolioWizard(models.TransientModel):
|
|||||||
vals = {}
|
vals = {}
|
||||||
pricelist = self.partner_id.property_product_pricelist and \
|
pricelist = self.partner_id.property_product_pricelist and \
|
||||||
self.partner_id.property_product_pricelist.id or \
|
self.partner_id.property_product_pricelist.id or \
|
||||||
self.env['ir.default'].sudo().get(
|
self.env.user.hotel_id.pricelist_id.id
|
||||||
'res.config.settings', 'default_pricelist_id')
|
|
||||||
vals.update({
|
vals.update({
|
||||||
'pricelist_id': pricelist,
|
'pricelist_id': pricelist,
|
||||||
'email': self.partner_id.email,
|
'email': self.partner_id.email,
|
||||||
@@ -171,8 +169,7 @@ class FolioWizard(models.TransientModel):
|
|||||||
@param self: object pointer
|
@param self: object pointer
|
||||||
'''
|
'''
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
tz_hotel = self.env['ir.default'].sudo().get(
|
tz_hotel = self.env.user.hotel_id.tz
|
||||||
'res.config.settings', 'tz_hotel')
|
|
||||||
today = fields.Date.context_today(self.with_context(tz=tz_hotel))
|
today = fields.Date.context_today(self.with_context(tz=tz_hotel))
|
||||||
checkin_dt = fields.Date.from_string(today) if not self.checkin else fields.Date.from_string(self.checkin)
|
checkin_dt = fields.Date.from_string(today) if not self.checkin else fields.Date.from_string(self.checkin)
|
||||||
checkout_dt = fields.Date.from_string(today) if not self.checkout else fields.Date.from_string(self.checkout)
|
checkout_dt = fields.Date.from_string(today) if not self.checkout else fields.Date.from_string(self.checkout)
|
||||||
|
|||||||
@@ -22,8 +22,4 @@
|
|||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<menuitem name="Pricelist" id="pricelist_menu"
|
|
||||||
action="product.product_pricelist_action2" sequence="22"
|
|
||||||
parent="hotel.configuration_others" />
|
|
||||||
|
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ class ChannelBackend(models.Model):
|
|||||||
return 'https://wired.wubook.net/xrws/'
|
return 'https://wired.wubook.net/xrws/'
|
||||||
|
|
||||||
def _get_default_wubook_parity(self):
|
def _get_default_wubook_parity(self):
|
||||||
|
# TODO: refactoring res.config.settings', 'default_pricelist_id' by the current hotel.property.pricelist_id
|
||||||
return self.env['ir.default'].sudo().get('res.config.settings', 'default_pricelist_id')
|
return self.env['ir.default'].sudo().get('res.config.settings', 'default_pricelist_id')
|
||||||
|
|
||||||
lcode = fields.Char('Channel Service lcode')
|
lcode = fields.Char('Channel Service lcode')
|
||||||
|
|||||||
Reference in New Issue
Block a user