mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
@@ -40,6 +40,7 @@
|
|||||||
'views/inherited_res_partner_views.xml',
|
'views/inherited_res_partner_views.xml',
|
||||||
'views/hotel_room_type_views.xml',
|
'views/hotel_room_type_views.xml',
|
||||||
'views/hotel_room_views.xml',
|
'views/hotel_room_views.xml',
|
||||||
|
'views/hotel_shared_room_views.xml',
|
||||||
'views/hotel_room_type_class_views.xml',
|
'views/hotel_room_type_class_views.xml',
|
||||||
'views/general.xml',
|
'views/general.xml',
|
||||||
'views/inherited_product_template_views.xml',
|
'views/inherited_product_template_views.xml',
|
||||||
|
|||||||
3220
hotel/i18n/es.po
3220
hotel/i18n/es.po
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@ from . import hotel_floor
|
|||||||
from . import hotel_folio
|
from . import hotel_folio
|
||||||
from . import hotel_reservation
|
from . import hotel_reservation
|
||||||
from . import hotel_room
|
from . import hotel_room
|
||||||
|
from . import hotel_shared_room
|
||||||
from . import hotel_amenity
|
from . import hotel_amenity
|
||||||
from . import hotel_amenity_type
|
from . import hotel_amenity_type
|
||||||
from . import hotel_room_type
|
from . import hotel_room_type
|
||||||
|
|||||||
@@ -99,7 +99,8 @@ class HotelFolio(models.Model):
|
|||||||
default=lambda self: _('New'))
|
default=lambda self: _('New'))
|
||||||
client_order_ref = fields.Char(string='Customer Reference', copy=False)
|
client_order_ref = fields.Char(string='Customer Reference', copy=False)
|
||||||
partner_id = fields.Many2one('res.partner',
|
partner_id = fields.Many2one('res.partner',
|
||||||
track_visibility='onchange')
|
track_visibility='onchange',
|
||||||
|
ondelete='restrict',)
|
||||||
|
|
||||||
room_lines = fields.One2many('hotel.reservation', 'folio_id',
|
room_lines = fields.One2many('hotel.reservation', 'folio_id',
|
||||||
readonly=False,
|
readonly=False,
|
||||||
@@ -107,19 +108,20 @@ class HotelFolio(models.Model):
|
|||||||
help="Hotel room reservation detail.",)
|
help="Hotel room reservation detail.",)
|
||||||
|
|
||||||
service_ids = fields.One2many('hotel.service', 'folio_id',
|
service_ids = fields.One2many('hotel.service', 'folio_id',
|
||||||
readonly=False,
|
readonly=False,
|
||||||
states={'done': [('readonly', True)]},
|
states={'done': [('readonly', True)]},
|
||||||
help="Hotel services detail provide to "
|
help="Hotel services detail provide to "
|
||||||
"customer and it will include in "
|
"customer and it will include in "
|
||||||
"main Invoice.")
|
"main Invoice.")
|
||||||
company_id = fields.Many2one('res.company', 'Company', default=lambda self: self.env['res.company']._company_default_get('hotel.folio'))
|
company_id = fields.Many2one('res.company', 'Company', default=lambda self: self.env['res.company']._company_default_get('hotel.folio'))
|
||||||
analytic_account_id = fields.Many2one('account.analytic.account', 'Analytic Account', readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, help="The analytic account related to a folio.", copy=False)
|
analytic_account_id = fields.Many2one('account.analytic.account', 'Analytic Account', readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, help="The analytic account related to a folio.", copy=False)
|
||||||
currency_id = fields.Many2one('res.currency', related='pricelist_id.currency_id',
|
currency_id = fields.Many2one('res.currency', related='pricelist_id.currency_id',
|
||||||
string='Currency', readonly=True, required=True)
|
string='Currency', readonly=True, required=True, ondelete='restrict',)
|
||||||
|
|
||||||
pricelist_id = fields.Many2one('product.pricelist',
|
pricelist_id = fields.Many2one('product.pricelist',
|
||||||
string='Pricelist',
|
string='Pricelist',
|
||||||
required=True,
|
required=True,
|
||||||
|
ondelete='restrict',
|
||||||
states={'draft': [('readonly', False)],
|
states={'draft': [('readonly', False)],
|
||||||
'sent': [('readonly', False)]},
|
'sent': [('readonly', False)]},
|
||||||
help="Pricelist for current folio.")
|
help="Pricelist for current folio.")
|
||||||
@@ -136,10 +138,11 @@ class HotelFolio(models.Model):
|
|||||||
('agency', 'Agencia'),
|
('agency', 'Agencia'),
|
||||||
('operator', 'Tour operador'),
|
('operator', 'Tour operador'),
|
||||||
('virtualdoor', 'Virtual Door'),], 'Sales Channel', default='door')
|
('virtualdoor', 'Virtual Door'),], 'Sales Channel', default='door')
|
||||||
user_id = fields.Many2one('res.users', string='Salesperson', index=True,
|
user_id = fields.Many2one('res.users', string='Salesperson', index=True, ondelete='restrict',
|
||||||
track_visibility='onchange', default=lambda self: self.env.user)
|
track_visibility='onchange', default=lambda self: self.env.user)
|
||||||
tour_operator_id = fields.Many2one('res.partner',
|
tour_operator_id = fields.Many2one('res.partner',
|
||||||
'Tour Operator',
|
'Tour Operator',
|
||||||
|
ondelete='restrict',
|
||||||
domain=[('is_tour_operator', '=', True)])
|
domain=[('is_tour_operator', '=', True)])
|
||||||
date_order = fields.Datetime(
|
date_order = fields.Datetime(
|
||||||
string='Order Date',
|
string='Order Date',
|
||||||
@@ -245,12 +248,14 @@ class HotelFolio(models.Model):
|
|||||||
help='Margin in days to create a notice if a payment \
|
help='Margin in days to create a notice if a payment \
|
||||||
advance has not been recorded')
|
advance has not been recorded')
|
||||||
segmentation_ids = fields.Many2many('res.partner.category',
|
segmentation_ids = fields.Many2many('res.partner.category',
|
||||||
string='Segmentation')
|
string='Segmentation',
|
||||||
|
ondelete='restrict')
|
||||||
client_order_ref = fields.Char(string='Customer Reference', copy=False)
|
client_order_ref = fields.Char(string='Customer Reference', copy=False)
|
||||||
note = fields.Text('Terms and conditions')
|
note = fields.Text('Terms and conditions')
|
||||||
sequence = fields.Integer(string='Sequence', default=10)
|
sequence = fields.Integer(string='Sequence', default=10)
|
||||||
team_id = fields.Many2one('crm.team',
|
team_id = fields.Many2one('crm.team',
|
||||||
'Sales Channel',
|
'Sales Channel',
|
||||||
|
ondelete='restrict',
|
||||||
change_default=True,
|
change_default=True,
|
||||||
default=_get_default_team,
|
default=_get_default_team,
|
||||||
oldname='section_id')
|
oldname='section_id')
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ class HotelReservation(models.Model):
|
|||||||
name = fields.Text('Reservation Description', required=True)
|
name = fields.Text('Reservation Description', required=True)
|
||||||
sequence = fields.Integer(string='Sequence', default=10)
|
sequence = fields.Integer(string='Sequence', default=10)
|
||||||
|
|
||||||
room_id = fields.Many2one('hotel.room', string='Room')
|
room_id = fields.Many2one('hotel.room', string='Room', ondelete='restrict')
|
||||||
|
|
||||||
reservation_no = fields.Char('Reservation No', size=64, readonly=True)
|
reservation_no = fields.Char('Reservation No', size=64, readonly=True)
|
||||||
adults = fields.Integer('Adults', size=64, readonly=False,
|
adults = fields.Integer('Adults', size=64, readonly=False,
|
||||||
@@ -316,8 +316,9 @@ class HotelReservation(models.Model):
|
|||||||
], string='Invoice Status', compute='_compute_invoice_status',
|
], string='Invoice Status', compute='_compute_invoice_status',
|
||||||
store=True, readonly=True, default='no')
|
store=True, readonly=True, default='no')
|
||||||
tax_ids = fields.Many2many('account.tax',
|
tax_ids = fields.Many2many('account.tax',
|
||||||
string='Taxes',
|
string='Taxes',
|
||||||
domain=['|', ('active', '=', False), ('active', '=', True)])
|
ondelete='restrict',
|
||||||
|
domain=['|', ('active', '=', False), ('active', '=', True)])
|
||||||
qty_to_invoice = fields.Float(
|
qty_to_invoice = fields.Float(
|
||||||
compute='_get_to_invoice_qty', string='To Invoice', store=True, readonly=True,
|
compute='_get_to_invoice_qty', string='To Invoice', store=True, readonly=True,
|
||||||
digits=dp.get_precision('Product Unit of Measure'))
|
digits=dp.get_precision('Product Unit of Measure'))
|
||||||
|
|||||||
@@ -17,16 +17,16 @@ class HotelRoom(models.Model):
|
|||||||
active = fields.Boolean('Active', default=True)
|
active = fields.Boolean('Active', default=True)
|
||||||
sequence = fields.Integer('Sequence', default=0)
|
sequence = fields.Integer('Sequence', default=0)
|
||||||
room_type_id = fields.Many2one('hotel.room.type', 'Hotel Room Type',
|
room_type_id = fields.Many2one('hotel.room.type', 'Hotel Room Type',
|
||||||
required=True,
|
required=True,
|
||||||
ondelete='restrict')
|
ondelete='restrict')
|
||||||
floor_id = fields.Many2one('hotel.floor', 'Ubication',
|
floor_id = fields.Many2one('hotel.floor', 'Ubication',
|
||||||
help='At which floor the room is located.')
|
help='At which floor the room is located.')
|
||||||
max_adult = fields.Integer('Max Adult')
|
max_adult = fields.Integer('Max Adult')
|
||||||
max_child = fields.Integer('Max Child')
|
max_child = fields.Integer('Max Child')
|
||||||
capacity = fields.Integer('Capacity')
|
capacity = fields.Integer('Capacity')
|
||||||
# FIXME not used
|
|
||||||
to_be_cleaned = fields.Boolean('To be Cleaned', default=False)
|
to_be_cleaned = fields.Boolean('To be Cleaned', default=False)
|
||||||
shared_room = fields.Boolean('Shared Room', default=False)
|
shared_room_id = fields.Many2one('hotel.shared.room', 'Shared Room',
|
||||||
|
default=False)
|
||||||
description_sale = fields.Text(
|
description_sale = fields.Text(
|
||||||
'Sale Description', translate=True,
|
'Sale Description', translate=True,
|
||||||
help="A description of the Product that you want to communicate to "
|
help="A description of the Product that you want to communicate to "
|
||||||
@@ -36,11 +36,36 @@ class HotelRoom(models.Model):
|
|||||||
default='0',
|
default='0',
|
||||||
required=True)
|
required=True)
|
||||||
|
|
||||||
|
@api.constrains('room_type_id')
|
||||||
|
def _constrain_shared_room_type(self):
|
||||||
|
for record in self:
|
||||||
|
if record.shared_room_id:
|
||||||
|
if not record.room_type_id.shared_room:
|
||||||
|
raise ValidationError(_('We cant save normal rooms \
|
||||||
|
in a shared room type'))
|
||||||
|
else:
|
||||||
|
if record.room_type_id.shared_room:
|
||||||
|
raise ValidationError(_('We cant save shared rooms \
|
||||||
|
in a normal room type'))
|
||||||
|
|
||||||
|
@api.constrains('shared_room_id')
|
||||||
|
def _constrain_shared_room(self):
|
||||||
|
for record in self:
|
||||||
|
if record.shared_room_id:
|
||||||
|
if not record.capacity > 1:
|
||||||
|
raise ValidationError(_('We cant save normal rooms \
|
||||||
|
in a shared room type'))
|
||||||
|
|
||||||
@api.constrains('capacity')
|
@api.constrains('capacity')
|
||||||
def _check_capacity(self):
|
def _check_capacity(self):
|
||||||
if self.capacity < 1:
|
for record in self:
|
||||||
raise ValidationError(_("Room capacity can't be less than one"))
|
if record.shared_room_id and record.capacity != 1:
|
||||||
|
raise ValidationError(_("A Bed only can has capacity one"))
|
||||||
|
if record.capacity < 1:
|
||||||
|
raise ValidationError(_("Room capacity can't be less than one"))
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def get_capacity(self, extra_bed=0):
|
def get_capacity(self, extra_bed=0):
|
||||||
return self.capacity + extra_bed
|
if not self.shared_room_id:
|
||||||
|
return self.capacity + extra_bed
|
||||||
|
return self.capacity
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ class HotelRoomType(models.Model):
|
|||||||
active = fields.Boolean('Active', default=True,
|
active = fields.Boolean('Active', default=True,
|
||||||
help="The active field allows you to hide the \
|
help="The active field allows you to hide the \
|
||||||
category without removing it.")
|
category without removing it.")
|
||||||
|
shared_room = fields.Boolean('Shared Room', default=False,
|
||||||
|
help="This room type is reservation by beds")
|
||||||
# Used for ordering
|
# Used for ordering
|
||||||
sequence = fields.Integer('Sequence', default=0)
|
sequence = fields.Integer('Sequence', default=0)
|
||||||
|
|
||||||
@@ -47,7 +49,7 @@ class HotelRoomType(models.Model):
|
|||||||
_sql_constraints = [('code_unique', 'unique(code_type)',
|
_sql_constraints = [('code_unique', 'unique(code_type)',
|
||||||
'Room Type Code must be unique!')]
|
'Room Type Code must be unique!')]
|
||||||
|
|
||||||
@api.depends('room_ids')
|
@api.depends('room_ids', 'room_ids.active')
|
||||||
def _compute_total_rooms(self):
|
def _compute_total_rooms(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
record.total_rooms_count = len(record.room_ids)
|
record.total_rooms_count = len(record.room_ids)
|
||||||
@@ -107,6 +109,18 @@ class HotelRoomType(models.Model):
|
|||||||
})
|
})
|
||||||
return super().create(vals)
|
return super().create(vals)
|
||||||
|
|
||||||
|
@api.constrains('shared_room', 'room_ids')
|
||||||
|
def _constrain_shared_room(self):
|
||||||
|
for record in self:
|
||||||
|
if record.shared_room:
|
||||||
|
if any(not room.shared_room_id for room in record.room_ids):
|
||||||
|
raise ValidationError(_('We cant save normal rooms \
|
||||||
|
in a shared room type'))
|
||||||
|
else:
|
||||||
|
if any(room.shared_room_id for room in record.room_ids):
|
||||||
|
raise ValidationError(_('We cant save shared rooms \
|
||||||
|
in a normal room type'))
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def unlink(self):
|
def unlink(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
|
|||||||
@@ -115,7 +115,8 @@ class HotelService(models.Model):
|
|||||||
|
|
||||||
name = fields.Char('Service description', required=True)
|
name = fields.Char('Service description', required=True)
|
||||||
sequence = fields.Integer(string='Sequence', default=10)
|
sequence = fields.Integer(string='Sequence', default=10)
|
||||||
product_id = fields.Many2one('product.product', 'Service', required=True)
|
product_id = fields.Many2one('product.product', 'Service',
|
||||||
|
ondelete='restrict', required=True)
|
||||||
folio_id = fields.Many2one('hotel.folio', 'Folio',
|
folio_id = fields.Many2one('hotel.folio', 'Folio',
|
||||||
ondelete='cascade',
|
ondelete='cascade',
|
||||||
default=_default_folio_id)
|
default=_default_folio_id)
|
||||||
@@ -132,10 +133,11 @@ class HotelService(models.Model):
|
|||||||
product_image = fields.Binary('Product Image', related="product_id.image", store=False, related_sudo=True)
|
product_image = fields.Binary('Product Image', related="product_id.image", store=False, related_sudo=True)
|
||||||
company_id = fields.Many2one(related='folio_id.company_id', string='Company', store=True, readonly=True)
|
company_id = fields.Many2one(related='folio_id.company_id', string='Company', store=True, readonly=True)
|
||||||
invoice_status = fields.Selection([
|
invoice_status = fields.Selection([
|
||||||
('invoiced', 'Fully Invoiced'),
|
('invoiced', 'Fully Invoiced'),
|
||||||
('to invoice', 'To Invoice'),
|
('to invoice', 'To Invoice'),
|
||||||
('no', 'Nothing to Invoice')
|
('no', 'Nothing to Invoice')
|
||||||
], string='Invoice Status', compute='_compute_invoice_status', store=True, readonly=True, default='no')
|
], string='Invoice Status', compute='_compute_invoice_status',
|
||||||
|
store=True, readonly=True, default='no')
|
||||||
channel_type = fields.Selection([
|
channel_type = fields.Selection([
|
||||||
('door', 'Door'),
|
('door', 'Door'),
|
||||||
('mail', 'Mail'),
|
('mail', 'Mail'),
|
||||||
|
|||||||
101
hotel/models/hotel_shared_room.py
Normal file
101
hotel/models/hotel_shared_room.py
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
# Copyright 2017 Alexandre Díaz
|
||||||
|
# Copyright 2017 Dario Lodeiros
|
||||||
|
# Copyright 2018 Pablo Quesada
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
from odoo import models, fields, api, _
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
|
class HotelSharedRoom(models.Model):
|
||||||
|
_name = 'hotel.shared.room'
|
||||||
|
_description = 'Hotel Shared Room'
|
||||||
|
_order = "room_type_id, name"
|
||||||
|
|
||||||
|
name = fields.Char('Room Name', required=True)
|
||||||
|
active = fields.Boolean('Active', default=True)
|
||||||
|
room_type_id = fields.Many2one(
|
||||||
|
'hotel.room.type', 'Hotel Room Type',
|
||||||
|
required=True, ondelete='restrict',
|
||||||
|
domain=[('shared_room', '=', True)]
|
||||||
|
)
|
||||||
|
floor_id = fields.Many2one('hotel.floor', 'Ubication',
|
||||||
|
help='At which floor the room is located.',
|
||||||
|
ondelete='restrict',)
|
||||||
|
sequence = fields.Integer('Sequence', required=True)
|
||||||
|
beds = fields.Integer('Beds')
|
||||||
|
bed_ids = fields.One2many('hotel.room',
|
||||||
|
'shared_room_id',
|
||||||
|
readonly=True,
|
||||||
|
ondelete='restrict',)
|
||||||
|
description_sale = fields.Text(
|
||||||
|
'Sale Description', translate=True,
|
||||||
|
help="A description of the Product that you want to communicate to "
|
||||||
|
" your customers. This description will be copied to every Sales "
|
||||||
|
" Order, Delivery Order and Customer Invoice/Credit Note")
|
||||||
|
|
||||||
|
@api.constrains('beds')
|
||||||
|
def _constrain_beds(self):
|
||||||
|
self.ensure_one()
|
||||||
|
if self.beds < 1:
|
||||||
|
raise ValidationError(_("Room beds can't be less than one"))
|
||||||
|
if len(self.bed_ids) > self.beds:
|
||||||
|
raise ValidationError(_(
|
||||||
|
"If you want to eliminate beds in the \
|
||||||
|
room you must deactivate the beds from your form"))
|
||||||
|
beds = []
|
||||||
|
inactive_beds = self.env['hotel.room'].search([
|
||||||
|
('active', '=', False),
|
||||||
|
('shared_room_id', '=', self.id)
|
||||||
|
])
|
||||||
|
for i in range(len(self.bed_ids), self.beds):
|
||||||
|
if inactive_beds:
|
||||||
|
bed = inactive_beds[0]
|
||||||
|
bed.update({'active': True})
|
||||||
|
inactive_beds -= bed
|
||||||
|
continue
|
||||||
|
name = u'%s (%s)' % (self.name, i)
|
||||||
|
bed_vals = {
|
||||||
|
'name': name,
|
||||||
|
'max_adult': 1,
|
||||||
|
'max_child': 0,
|
||||||
|
'capacity': 1,
|
||||||
|
'room_type_id': self.room_type_id.id,
|
||||||
|
'sequence': self.sequence,
|
||||||
|
'floor_id': self.floor_id.id if self.floor_id else False,
|
||||||
|
'shared_room_id': self.id,
|
||||||
|
}
|
||||||
|
beds.append((0, False, bed_vals))
|
||||||
|
if beds:
|
||||||
|
self.update({
|
||||||
|
'bed_ids': beds
|
||||||
|
})
|
||||||
|
|
||||||
|
@api.constrains('active')
|
||||||
|
def _constrain_active(self):
|
||||||
|
self.bed_ids.write({
|
||||||
|
'active': self.active,
|
||||||
|
})
|
||||||
|
|
||||||
|
@api.constrains('room_type_id')
|
||||||
|
def _constrain_room_type_id(self):
|
||||||
|
self.bed_ids.write({
|
||||||
|
'room_type_id': self.room_type_id.id,
|
||||||
|
})
|
||||||
|
|
||||||
|
@api.constrains('floor_id')
|
||||||
|
def _constrain_floor_id(self):
|
||||||
|
self.bed_ids.write({
|
||||||
|
'floor_id': self.floor_id.id,
|
||||||
|
})
|
||||||
|
|
||||||
|
@api.constrains('sequence')
|
||||||
|
def _constrain_sequence(self):
|
||||||
|
self.bed_ids.write({
|
||||||
|
'sequence': self.sequence,
|
||||||
|
})
|
||||||
|
|
||||||
|
@api.constrains('descrition_sale')
|
||||||
|
def _constrain_descrition_sale(self):
|
||||||
|
self.bed_ids.write({
|
||||||
|
'description_sale': self.descrition_sale,
|
||||||
|
})
|
||||||
@@ -11,6 +11,7 @@ user_access_hotel_board_service,user_access_hotel_board_service,model_hotel_boar
|
|||||||
user_access_hotel_checkin_partner,user_access_hotel_checkin_partner,model_hotel_checkin_partner,hotel.group_hotel_user,1,1,1,1
|
user_access_hotel_checkin_partner,user_access_hotel_checkin_partner,model_hotel_checkin_partner,hotel.group_hotel_user,1,1,1,1
|
||||||
user_access_hotel_room_type_class,user_access_hotel_room_type_class,model_hotel_room_type_class,hotel.group_hotel_user,1,0,0,0
|
user_access_hotel_room_type_class,user_access_hotel_room_type_class,model_hotel_room_type_class,hotel.group_hotel_user,1,0,0,0
|
||||||
user_access_hotel_room,user_access_hotel_room,model_hotel_room,hotel.group_hotel_user,1,0,0,0
|
user_access_hotel_room,user_access_hotel_room,model_hotel_room,hotel.group_hotel_user,1,0,0,0
|
||||||
|
user_access_shared_hotel_room,user_access_hotel_shared_room,model_hotel_shared_room,hotel.group_hotel_user,1,0,0,0
|
||||||
user_access_hotel_room_type_restriction_item,user_access_hotel_room_type_restriction_item,model_hotel_room_type_restriction_item,hotel.group_hotel_user,1,0,0,0
|
user_access_hotel_room_type_restriction_item,user_access_hotel_room_type_restriction_item,model_hotel_room_type_restriction_item,hotel.group_hotel_user,1,0,0,0
|
||||||
user_access_hotel_reservation,user_access_hotel_reservation,model_hotel_reservation,hotel.group_hotel_user,1,1,1,1
|
user_access_hotel_reservation,user_access_hotel_reservation,model_hotel_reservation,hotel.group_hotel_user,1,1,1,1
|
||||||
user_access_hotel_folio,user_access_hotel_folio,model_hotel_folio,hotel.group_hotel_user,1,1,1,1
|
user_access_hotel_folio,user_access_hotel_folio,model_hotel_folio,hotel.group_hotel_user,1,1,1,1
|
||||||
@@ -32,6 +33,7 @@ manager_access_hotel_board_service,manager_access_hotel_board_service,model_hote
|
|||||||
manager_access_hotel_checkin_partner,manager_access_hotel_checkin_partner,model_hotel_checkin_partner,hotel.group_hotel_manager,1,1,1,1
|
manager_access_hotel_checkin_partner,manager_access_hotel_checkin_partner,model_hotel_checkin_partner,hotel.group_hotel_manager,1,1,1,1
|
||||||
manager_access_hotel_room_type_class,manager_access_hotel_room_type_class,model_hotel_room_type_class,hotel.group_hotel_manager,1,1,1,1
|
manager_access_hotel_room_type_class,manager_access_hotel_room_type_class,model_hotel_room_type_class,hotel.group_hotel_manager,1,1,1,1
|
||||||
manager_access_hotel_room,manager_access_hotel_room,model_hotel_room,hotel.group_hotel_manager,1,1,1,1
|
manager_access_hotel_room,manager_access_hotel_room,model_hotel_room,hotel.group_hotel_manager,1,1,1,1
|
||||||
|
manager_access_hotel_shared_room,manager_access_hotel_shared_room,model_hotel_shared_room,hotel.group_hotel_manager,1,1,1,1
|
||||||
manager_access_hotel_room_type_restriction_item,manager_access_hotel_room_type_restriction_item,model_hotel_room_type_restriction_item,hotel.group_hotel_manager,1,1,1,1
|
manager_access_hotel_room_type_restriction_item,manager_access_hotel_room_type_restriction_item,model_hotel_room_type_restriction_item,hotel.group_hotel_manager,1,1,1,1
|
||||||
manager_access_hotel_reservation,manager_access_hotel_reservation,model_hotel_reservation,hotel.group_hotel_manager,1,1,1,1
|
manager_access_hotel_reservation,manager_access_hotel_reservation,model_hotel_reservation,hotel.group_hotel_manager,1,1,1,1
|
||||||
manager_access_hotel_folio,manager_access_hotel_folio,model_hotel_folio,hotel.group_hotel_manager,1,1,1,1
|
manager_access_hotel_folio,manager_access_hotel_folio,model_hotel_folio,hotel.group_hotel_manager,1,1,1,1
|
||||||
@@ -52,6 +54,7 @@ call_access_hotel_board_service,call_access_hotel_board_service,model_hotel_boar
|
|||||||
call_access_hotel_checkin_partner,call_access_hotel_checkin_partner,model_hotel_checkin_partner,hotel.group_hotel_call,1,1,1,1
|
call_access_hotel_checkin_partner,call_access_hotel_checkin_partner,model_hotel_checkin_partner,hotel.group_hotel_call,1,1,1,1
|
||||||
call_access_hotel_room_type_class,call_access_hotel_room_type_class,model_hotel_room_type_class,hotel.group_hotel_call,1,0,0,0
|
call_access_hotel_room_type_class,call_access_hotel_room_type_class,model_hotel_room_type_class,hotel.group_hotel_call,1,0,0,0
|
||||||
call_access_hotel_room,call_access_hotel_room,model_hotel_room,hotel.group_hotel_call,1,0,0,0
|
call_access_hotel_room,call_access_hotel_room,model_hotel_room,hotel.group_hotel_call,1,0,0,0
|
||||||
|
call_access_hotel_shared_room,call_access_hotel_shared_room,model_hotel_shared_room,hotel.group_hotel_call,1,0,0,0
|
||||||
call_access_hotel_room_type_restriction_item,call_access_hotel_room_type_restriction_item,model_hotel_room_type_restriction_item,hotel.group_hotel_call,1,0,0,0
|
call_access_hotel_room_type_restriction_item,call_access_hotel_room_type_restriction_item,model_hotel_room_type_restriction_item,hotel.group_hotel_call,1,0,0,0
|
||||||
call_access_hotel_reservation,call_access_hotel_reservation,model_hotel_reservation,hotel.group_hotel_call,1,1,1,1
|
call_access_hotel_reservation,call_access_hotel_reservation,model_hotel_reservation,hotel.group_hotel_call,1,1,1,1
|
||||||
call_access_hotel_folio,call_access_hotel_folio,model_hotel_folio,hotel.group_hotel_call,1,1,1,1
|
call_access_hotel_folio,call_access_hotel_folio,model_hotel_folio,hotel.group_hotel_call,1,1,1,1
|
||||||
|
|||||||
|
@@ -27,6 +27,7 @@
|
|||||||
</group>
|
</group>
|
||||||
<group colspan="2">
|
<group colspan="2">
|
||||||
<group name="room_ids_group">
|
<group name="room_ids_group">
|
||||||
|
<field name="shared_room" />
|
||||||
<field name="room_ids" widget="many2many_tags"/>
|
<field name="room_ids" widget="many2many_tags"/>
|
||||||
<field name="total_rooms_count"/>
|
<field name="total_rooms_count"/>
|
||||||
</group>
|
</group>
|
||||||
|
|||||||
@@ -19,7 +19,10 @@
|
|||||||
<div class="oe_title">
|
<div class="oe_title">
|
||||||
<label for="name" string="Name" />
|
<label for="name" string="Name" />
|
||||||
<h1>
|
<h1>
|
||||||
<field name="name" />
|
<field name="name"
|
||||||
|
attrs="{'readonly':[('shared_room_id','!=', False)]}" />
|
||||||
|
<field name="shared_room_id" string="Ubication"
|
||||||
|
invisible='True' />
|
||||||
</h1>
|
</h1>
|
||||||
<!-- <label for="to_be_cleaned" string="To be Cleaned" />
|
<!-- <label for="to_be_cleaned" string="To be Cleaned" />
|
||||||
<h2>
|
<h2>
|
||||||
@@ -29,12 +32,15 @@
|
|||||||
<notebook>
|
<notebook>
|
||||||
<page name="information_hotel_room" string="Information">
|
<page name="information_hotel_room" string="Information">
|
||||||
<group colspan="4" col="4">
|
<group colspan="4" col="4">
|
||||||
<field name="floor_id" string="Ubication" />
|
<field name="floor_id" string="Ubication"
|
||||||
|
attrs="{'readonly':[('shared_room_id','!=', False)]}" />
|
||||||
<!-- <field name="categ_id" select="1" domain="[('isroomtype','=',True)]" string="Room Type" /> -->
|
<!-- <field name="categ_id" select="1" domain="[('isroomtype','=',True)]" string="Room Type" /> -->
|
||||||
<field name="room_type_id" string="Room Type" />
|
<field name="room_type_id" string="Room Type"
|
||||||
<field name="capacity" />
|
attrs="{'readonly':[('shared_room_id','!=', False)]}"/>
|
||||||
<field name="shared_room" help="It allows several reservations on the same room simultaneously based on the capacity of people"/>
|
<field name="capacity"
|
||||||
<field name="extra_beds_allowed" />
|
attrs="{'readonly':[('shared_room_id','!=', False)]}" />
|
||||||
|
<field name="extra_beds_allowed"
|
||||||
|
attrs="{'invisible':[('shared_room_id','!=', False)]}"/>
|
||||||
<!-- <field name="uom_id" invisible="1" /> -->
|
<!-- <field name="uom_id" invisible="1" /> -->
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
@@ -56,7 +62,7 @@
|
|||||||
</page>
|
</page>
|
||||||
</notebook>
|
</notebook>
|
||||||
<group>
|
<group>
|
||||||
<field name="sequence" />
|
<field name="sequence" attrs="{'readonly':[('shared_room_id','!=', False)]}"/>
|
||||||
</group>
|
</group>
|
||||||
</sheet>
|
</sheet>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
121
hotel/views/hotel_shared_room_views.xml
Normal file
121
hotel/views/hotel_shared_room_views.xml
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<!-- =================================================== Rooms =================================================== -->
|
||||||
|
<!-- Form view of hotel room -->
|
||||||
|
<record model="ir.ui.view" id="hotel_shared_room_view_form">
|
||||||
|
<field name="name">hotel.shared.room.form</field>
|
||||||
|
<field name="model">hotel.shared.room</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Hotel Shared Room">
|
||||||
|
<sheet>
|
||||||
|
<div class="oe_button_box" name="button_box">
|
||||||
|
<button name="toggle_active" type="object"
|
||||||
|
class="oe_stat_button" icon="fa-archive">
|
||||||
|
<field name="active" widget="boolean_button"
|
||||||
|
options='{"terminology": "archive"}'/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="oe_title">
|
||||||
|
<label for="name" string="Name" />
|
||||||
|
<h1>
|
||||||
|
<field name="name" />
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<notebook>
|
||||||
|
<page name="information_hotel_shared_shared_room" string="Information">
|
||||||
|
<group colspan="4" col="4">
|
||||||
|
<field name="floor_id" string="Ubication" />
|
||||||
|
<field name="room_type_id" string="Room Type" />
|
||||||
|
<field name="beds" />
|
||||||
|
<field name="sequence" />
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="bed_ids" />
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="Descriptions">
|
||||||
|
<group>
|
||||||
|
<field name="description_sale" colspan="2" string="Name in reports"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- Kanban view of hotel room -->
|
||||||
|
<record model="ir.ui.view" id="hotel_shared_shared_room_view_kanban">
|
||||||
|
<field name="name">hotel.shared.room.kanban</field>
|
||||||
|
<field name="model">hotel.shared.room</field>
|
||||||
|
<field name="type">kanban</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<kanban class="o_kanban_mobile" >
|
||||||
|
<attribute name="group_create">false</attribute>
|
||||||
|
<field name="id"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<templates>
|
||||||
|
<t t-name="kanban-box">
|
||||||
|
<div t-attf-class="oe_kanban_global_click">
|
||||||
|
<div class="oe_kanban_details">
|
||||||
|
<ul>
|
||||||
|
<li class="mb4">
|
||||||
|
<strong><field name="name"/></strong>
|
||||||
|
</li>
|
||||||
|
<li class="mb4">Room Type: <field name="room_type_id"/></li>
|
||||||
|
<li class="badge mb4">
|
||||||
|
<strong>Beds <field name="beds"/></strong>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
</templates>
|
||||||
|
</kanban>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- Search view of hotel room -->
|
||||||
|
<record model="ir.ui.view" id="hotel_shared_shared_room_view_search">
|
||||||
|
<field name="name">hotel.shared.room.search</field>
|
||||||
|
<field name="model">hotel.shared.room</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<search string="Hotel Shared Room">
|
||||||
|
<field name="name" />
|
||||||
|
<field name="room_type_id" />
|
||||||
|
<field name="beds" />
|
||||||
|
</search>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- Tree view of hotel room -->
|
||||||
|
<record model="ir.ui.view" id="hotel_shared_room_view_tree">
|
||||||
|
<field name="name">hotel.shared.room.tree</field>
|
||||||
|
<field name="model">hotel.shared.room</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree string="Hotel Shared Room">
|
||||||
|
<field name="name" />
|
||||||
|
<field name="room_type_id" />
|
||||||
|
<field name="beds" />
|
||||||
|
<field name="sequence" />
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Action for hotel room -->
|
||||||
|
<record model="ir.actions.act_window" id="action_hotel_shared_room_form">
|
||||||
|
<field name="name">Hotel Shared Room</field>
|
||||||
|
<field name="res_model">hotel.shared.room</field>
|
||||||
|
<field name="view_type">form</field>
|
||||||
|
<!-- <field name="context">{'default_isroom':1,'default_rental':1}
|
||||||
|
</field> -->
|
||||||
|
<field name="view_id" ref="hotel_shared_room_view_tree" />
|
||||||
|
<field name="view_mode">kanban,tree,form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<menuitem name="Shared Rooms" id="menu_open_hotel_shared_room_form" action="action_hotel_shared_room_form"
|
||||||
|
sequence="5" parent="hotel.menu_hotel_room" />
|
||||||
|
|
||||||
|
</odoo>
|
||||||
@@ -141,7 +141,7 @@ class HotelReservation(models.Model):
|
|||||||
'capacity': room.capacity,
|
'capacity': room.capacity,
|
||||||
'class_name': room.room_type_id.class_id.name,
|
'class_name': room.room_type_id.class_id.name,
|
||||||
'class_id': room.room_type_id.class_id.id,
|
'class_id': room.room_type_id.class_id.id,
|
||||||
'shared': room.shared_room,
|
'shared_id': room.shared_room_id,
|
||||||
'price': room.room_type_id
|
'price': room.room_type_id
|
||||||
and ['pricelist', room.room_type_id.id, pricelist_id,
|
and ['pricelist', room.room_type_id.id, pricelist_id,
|
||||||
room.room_type_id.name] or 0,
|
room.room_type_id.name] or 0,
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ class ChannelHotelRoomType(models.Model):
|
|||||||
string='Room Type',
|
string='Room Type',
|
||||||
required=True,
|
required=True,
|
||||||
ondelete='cascade')
|
ondelete='cascade')
|
||||||
channel_short_code = fields.Char("Channel Short Code", old_name='wscode')
|
channel_short_code = fields.Char("Channel Short Code")
|
||||||
ota_capacity = fields.Integer("OTA's Capacity", default=1, old_name='wcapacity',
|
ota_capacity = fields.Integer("OTA's Capacity", default=1,
|
||||||
help="The capacity of the room for OTAs.")
|
help="The capacity of the room for OTAs.")
|
||||||
|
|
||||||
default_quota = fields.Integer("Default Quota",
|
default_quota = fields.Integer("Default Quota",
|
||||||
@@ -52,8 +52,8 @@ class ChannelHotelRoomType(models.Model):
|
|||||||
max_price = fields.Float('Max. Price', default=200.0, digits=dp.get_precision('Product Price'),
|
max_price = fields.Float('Max. Price', default=200.0, digits=dp.get_precision('Product Price'),
|
||||||
help="Setup the max price to prevent incidents while editing your prices.")
|
help="Setup the max price to prevent incidents while editing your prices.")
|
||||||
|
|
||||||
@api.onchange('default_quota', 'default_max_avail')
|
@api.constrains('default_quota', 'default_max_avail', 'total_rooms_count')
|
||||||
def _onchange_availability(self):
|
def _constrains_availability(self):
|
||||||
for rec in self:
|
for rec in self:
|
||||||
to_eval = []
|
to_eval = []
|
||||||
to_eval.append(rec.total_rooms_count)
|
to_eval.append(rec.total_rooms_count)
|
||||||
@@ -64,8 +64,8 @@ class ChannelHotelRoomType(models.Model):
|
|||||||
|
|
||||||
rec.default_availability = min(to_eval)
|
rec.default_availability = min(to_eval)
|
||||||
|
|
||||||
@api.onchange('room_ids')
|
@api.constrains('room_ids')
|
||||||
def _get_capacity(self):
|
def _constrain_capacity(self):
|
||||||
for rec in self:
|
for rec in self:
|
||||||
rec.ota_capacity = rec.odoo_id.get_capacity()
|
rec.ota_capacity = rec.odoo_id.get_capacity()
|
||||||
|
|
||||||
|
|||||||
@@ -145,9 +145,14 @@ class HotelReservationImporter(Component):
|
|||||||
tprice += room_day_price
|
tprice += room_day_price
|
||||||
rate_id = brday['rate_id']
|
rate_id = brday['rate_id']
|
||||||
# TODO: Review different pricelist in the different booked rooms (folio in Odoo)
|
# TODO: Review different pricelist in the different booked rooms (folio in Odoo)
|
||||||
rate_id = rate_id > 0 and rate_id or self.env['channel.backend'].sudo().search([
|
if rate_id > 0:
|
||||||
|
rate_id = self.env['channel.product.pricelist'].search(
|
||||||
|
'external_id', '=', rate_id).odoo_id.id
|
||||||
|
if rate_id <= 0:
|
||||||
|
rate_id = self.env['channel.backend'].sudo().search([
|
||||||
('id', '=', self.backend_record.id)
|
('id', '=', self.backend_record.id)
|
||||||
]).wubook_parity_pricelist_id.id
|
]).wubook_parity_pricelist_id.id
|
||||||
|
|
||||||
# Get OTA
|
# Get OTA
|
||||||
ota_id = self.env['channel.ota.info'].search([
|
ota_id = self.env['channel.ota.info'].search([
|
||||||
('backend_id', '=', self.backend_record.id),
|
('backend_id', '=', self.backend_record.id),
|
||||||
@@ -170,7 +175,7 @@ class HotelReservationImporter(Component):
|
|||||||
'checkout': checkout_str,
|
'checkout': checkout_str,
|
||||||
'adults': persons,
|
'adults': persons,
|
||||||
'children': book['children'],
|
'children': book['children'],
|
||||||
#'pricelist_id': rate_id,
|
'pricelist_id': rate_id,
|
||||||
'reservation_line_ids': reservation_lines,
|
'reservation_line_ids': reservation_lines,
|
||||||
'to_assign': True,
|
'to_assign': True,
|
||||||
'state': is_cancellation and 'cancelled' or 'confirm',
|
'state': is_cancellation and 'cancelled' or 'confirm',
|
||||||
|
|||||||
Reference in New Issue
Block a user