diff --git a/hotel/__manifest__.py b/hotel/__manifest__.py
index 56728c424..98c2551c5 100644
--- a/hotel/__manifest__.py
+++ b/hotel/__manifest__.py
@@ -46,6 +46,7 @@
'views/hotel_room_type_restriction_item_views.xml',
'views/hotel_reservation_views.xml',
'views/hotel_room_closure_reason_views.xml',
+ 'views/hotel_service_views.xml',
'views/hotel_board_service_views.xml',
'views/hotel_checkin_partner_views.xml',
'views/hotel_room_type_availability_views.xml',
diff --git a/hotel/models/hotel_folio.py b/hotel/models/hotel_folio.py
index 7dba397b6..46da5abb3 100644
--- a/hotel/models/hotel_folio.py
+++ b/hotel/models/hotel_folio.py
@@ -44,30 +44,11 @@ class HotelFolio(models.Model):
def _amount_all(self):
pass
+ #Main Fields--------------------------------------------------------
name = fields.Char('Folio Number', readonly=True, index=True,
default=lambda self: _('New'))
partner_id = fields.Many2one('res.partner',
track_visibility='onchange')
- closure_reason_id = fields.Many2one('room.closure.reason')
- # partner_invoice_id = fields.Many2one('res.partner',
- # string='Invoice Address',
- # readonly=True, required=True,
- # states={'draft': [('readonly', False)],
- # 'sent': [('readonly', False)]},
- # help="Invoice address for current sales order.")
-
- # For being used directly in the Folio views
- email = fields.Char('E-mail', related='partner_id.email')
- mobile = fields.Char('Mobile', related='partner_id.mobile')
- phone = fields.Char('Phone', related='partner_id.phone')
-
- #Review: How to use state in folio?
- state = fields.Selection([('draft', 'Pre-reservation'), ('confirm', 'Pending Entry'),
- ('booking', 'On Board'), ('done', 'Out'),
- ('cancelled', 'Cancelled')],
- 'State', readonly=True,
- default=lambda *a: 'draft',
- track_visibility='onchange')
room_lines = fields.One2many('hotel.reservation', 'folio_id',
readonly=False,
@@ -80,8 +61,6 @@ class HotelFolio(models.Model):
help="Hotel services detail provide to "
"customer and it will include in "
"main Invoice.")
- hotel_invoice_id = fields.Many2one('account.invoice', 'Invoice')
-
company_id = fields.Many2one('res.company', 'Company')
currency_id = fields.Many2one('res.currency', related='pricelist_id.currency_id',
@@ -90,10 +69,50 @@ class HotelFolio(models.Model):
pricelist_id = fields.Many2one('product.pricelist',
string='Pricelist',
required=True,
- readonly=True,
states={'draft': [('readonly', False)],
'sent': [('readonly', False)]},
help="Pricelist for current folio.")
+ reservation_type = fields.Selection([('normal', 'Normal'),
+ ('staff', 'Staff'),
+ ('out', 'Out of Service')],
+ 'Type', default=lambda *a: 'normal')
+ channel_type = fields.Selection([('door', 'Door'),
+ ('mail', 'Mail'),
+ ('phone', 'Phone'),
+ ('web', 'Web')], 'Sales Channel', default='door')
+ user_id = fields.Many2one('res.users', string='Salesperson', index=True,
+ track_visibility='onchange', default=lambda self: self.env.user)
+ date_order = fields.Datetime(
+ string='Order Date',
+ required=True, readonly=True, index=True,
+ states={'draft': [('readonly', False)], 'sent': [('readonly', False)]},
+ copy=False, default=fields.Datetime.now)
+ state = fields.Selection([
+ ('draft', 'Quotation'),
+ ('sent', 'Quotation Sent'),
+ ('confirm', 'Confirmed'),
+ ('done', 'Locked'),
+ ('cancel', 'Cancelled'),
+ ], string='Status',
+ readonly=True, copy=False,
+ index=True, track_visibility='onchange',
+ default='draft')
+
+
+ # Partner fields for being used directly in the Folio views---------
+ email = fields.Char('E-mail', related='partner_id.email')
+ mobile = fields.Char('Mobile', related='partner_id.mobile')
+ phone = fields.Char('Phone', related='partner_id.phone')
+ partner_internal_comment = fields.Text(string='Internal Partner Notes',
+ related='partner_id.comment')
+
+ #Payment Fields-----------------------------------------------------
+ payment_ids = fields.One2many('account.payment', 'folio_id',
+ readonly=True)
+ return_ids = fields.One2many('payment.return', 'folio_id',
+ readonly=True)
+
+ #Amount Fields------------------------------------------------------
pending_amount = fields.Monetary(compute='compute_amount',
store=True,
string="Pending in Folio")
@@ -103,50 +122,25 @@ class HotelFolio(models.Model):
invoices_paid = fields.Monetary(compute='compute_amount',
store=True, track_visibility='onchange',
string="Payments")
+ amount_untaxed = fields.Monetary(string='Untaxed Amount', store=True,
+ readonly=True, compute='_amount_all',
+ track_visibility='onchange')
+ amount_tax = fields.Monetary(string='Taxes', store=True,
+ readonly=True, compute='_amount_all')
+ amount_total = fields.Monetary(string='Total', store=True, readonly=True,
+ compute='_amount_all', track_visibility='always')
+ #Checkin Fields-----------------------------------------------------
booking_pending = fields.Integer('Booking pending',
compute='_compute_checkin_partner_count')
checkin_partner_count = fields.Integer('Checkin counter',
compute='_compute_checkin_partner_count')
checkin_partner_pending_count = fields.Integer('Checkin Pending',
compute='_compute_checkin_partner_count')
- partner_internal_comment = fields.Text(string='Internal Partner Notes',
- related='partner_id.comment')
- internal_comment = fields.Text(string='Internal Folio Notes')
- cancelled_reason = fields.Text('Cause of cancelled')
- payment_ids = fields.One2many('account.payment', 'folio_id',
- readonly=True)
- return_ids = fields.One2many('payment.return', 'folio_id',
- readonly=True)
- prepaid_warning_days = fields.Integer(
- 'Prepaid Warning Days',
- help='Margin in days to create a notice if a payment \
- advance has not been recorded')
- reservation_type = fields.Selection([('normal', 'Normal'),
- ('staff', 'Staff'),
- ('out', 'Out of Service')],
- 'Type', default=lambda *a: 'normal')
- channel_type = fields.Selection([('door', 'Door'),
- ('mail', 'Mail'),
- ('phone', 'Phone'),
- ('web', 'Web')], 'Sales Channel', default='door')
- num_invoices = fields.Integer(compute='_compute_num_invoices')
- rooms_char = fields.Char('Rooms', compute='_computed_rooms_char')
- segmentation_ids = fields.Many2many('res.partner.category',
- string='Segmentation')
- has_confirmed_reservations_to_send = fields.Boolean(
- compute='_compute_has_confirmed_reservations_to_send')
- has_cancelled_reservations_to_send = fields.Boolean(
- compute='_compute_has_cancelled_reservations_to_send')
- has_checkout_to_send = fields.Boolean(
- compute='_compute_has_checkout_to_send')
- # fix_price = fields.Boolean(compute='_compute_fix_price')
- date_order = fields.Datetime(
- string='Order Date',
- required=True, readonly=True, index=True,
- states={'draft': [('readonly', False)], 'sent': [('readonly', False)]},
- copy=False, default=fields.Datetime.now)
+ #Invoice Fields-----------------------------------------------------
+ hotel_invoice_id = fields.Many2one('account.invoice', 'Invoice')
+ num_invoices = fields.Integer(compute='_compute_num_invoices')
invoice_ids = fields.Many2many('account.invoice', string='Invoices',
compute='_get_invoiced', readonly=True, copy=False)
invoice_status = fields.Selection([('upselling', 'Upselling Opportunity'),
@@ -156,17 +150,52 @@ class HotelFolio(models.Model):
string='Invoice Status',
compute='_compute_invoice_status',
store=True, readonly=True, default='no')
+ #~ partner_invoice_id = fields.Many2one('res.partner',
+ #~ string='Invoice Address',
+ #~ readonly=True, required=True,
+ #~ states={'draft': [('readonly', False)],
+ #~ 'sent': [('readonly', False)]},
+ #~ help="Invoice address for current sales order.")
+
+ #WorkFlow Mail Fields-----------------------------------------------
+ has_confirmed_reservations_to_send = fields.Boolean(
+ compute='_compute_has_confirmed_reservations_to_send')
+ has_cancelled_reservations_to_send = fields.Boolean(
+ compute='_compute_has_cancelled_reservations_to_send')
+ has_checkout_to_send = fields.Boolean(
+ compute='_compute_has_checkout_to_send')
+
+ #Generic Fields-----------------------------------------------------
+ internal_comment = fields.Text(string='Internal Folio Notes')
+ cancelled_reason = fields.Text('Cause of cancelled')
+ closure_reason_id = fields.Many2one('room.closure.reason')
+ prepaid_warning_days = fields.Integer(
+ 'Prepaid Warning Days',
+ help='Margin in days to create a notice if a payment \
+ advance has not been recorded')
+ rooms_char = fields.Char('Rooms', compute='_computed_rooms_char')
+ segmentation_ids = fields.Many2many('res.partner.category',
+ string='Segmentation')
client_order_ref = fields.Char(string='Customer Reference', copy=False)
note = fields.Text('Terms and conditions')
- # layout_category_id = fields.Many2one('sale.layout_category', string='Section')
-
- user_id = fields.Many2one('res.users', string='Salesperson', index=True,
- track_visibility='onchange', default=lambda self: self.env.user)
-
sequence = fields.Integer(string='Sequence', default=10)
- # sale.order
- amount_total = fields.Float(string='Total', store=True, readonly=True,
- track_visibility='always')
+
+ @api.depends('room_lines.price_total','service_ids.price_total')
+ def _amount_all(self):
+ """
+ Compute the total amounts of the SO.
+ """
+ for record in self:
+ amount_untaxed = amount_tax = 0.0
+ amount_untaxed = sum(record.room_lines.mapped('price_subtotal')) + \
+ sum(record.service_ids.mapped('price_subtotal'))
+ amount_tax = sum(record.room_lines.mapped('price_tax')) + \
+ sum(record.service_ids.mapped('price_tax'))
+ record.update({
+ 'amount_untaxed': record.pricelist_id.currency_id.round(amount_untaxed),
+ 'amount_tax': record.pricelist_id.currency_id.round(amount_tax),
+ 'amount_total': amount_untaxed + amount_tax,
+ })
def _computed_rooms_char(self):
for record in self:
@@ -317,7 +346,7 @@ class HotelFolio(models.Model):
if 'company_id' in vals:
vals['name'] = self.env['ir.sequence'].with_context(
force_company=vals['company_id']
- ).next_by_code('sale.order') or _('New')
+ ).next_by_code('hotel.folio') or _('New')
else:
vals['name'] = self.env['ir.sequence'].next_by_code('hotel.folio') or _('New')
diff --git a/hotel/models/hotel_reservation.py b/hotel/models/hotel_reservation.py
index 8aae087c3..be1bcf201 100644
--- a/hotel/models/hotel_reservation.py
+++ b/hotel/models/hotel_reservation.py
@@ -173,8 +173,7 @@ class HotelReservation(models.Model):
service_ids = fields.One2many('hotel.service', 'ser_room_line')
pricelist_id = fields.Many2one('product.pricelist',
- related='folio_id.pricelist_id',
- readonly="1")
+ related='folio_id.pricelist_id') #TODO: Warning Mens to update pricelist
checkin_partner_ids = fields.One2many('hotel.checkin.partner', 'reservation_id')
# TODO: As checkin_partner_count is a computed field, it can't not be used in a domain filer
# Non-stored field hotel.reservation.checkin_partner_count cannot be searched
@@ -259,6 +258,14 @@ class HotelReservation(models.Model):
readonly=True,
store=True,
compute='_compute_amount_reservation')
+ price_services = fields.Monetary(string='Services Total',
+ readonly=True,
+ store=True,
+ compute='_compute_amount_room_services')
+ price_room_services_set = fields.Monetary(string='Room Services Total',
+ readonly=True,
+ store=True,
+ compute='_compute_amount_set')
# FIXME discount per night
discount = fields.Float(string='Discount (%)', digits=dp.get_precision('Discount'), default=0.0)
@@ -290,6 +297,7 @@ class HotelReservation(models.Model):
board_services.append((0, False, {
'product_id': product.id,
'is_board_service': True,
+ 'folio_id': vals.get('folio_id'),
}))
vals.update({'service_ids': board_services})
if self.compute_price_out_vals(vals):
@@ -327,6 +335,7 @@ class HotelReservation(models.Model):
board_services.append((0, False, {
'product_id': product.id,
'is_board_service': True,
+ 'folio_id': record.folio_id.id or vals.get('folio_id')
}))
# NEED REVIEW: Why I need add manually the old IDs if board service is (0,0,(-)) ¿?¿?¿
record.update({'service_ids': [(6, 0, record.service_ids.ids)] + board_services})
@@ -610,6 +619,7 @@ class HotelReservation(models.Model):
vals = {
'product_id': product.id,
'is_board_service': True,
+ 'folio_id': self.folio_id.id,
}
vals.update(self.env['hotel.service'].prepare_service_lines(
dfrom=self.checkin,
@@ -619,8 +629,10 @@ class HotelReservation(models.Model):
old_line_days=False))
board_services.append((0, False, vals))
other_services = self.service_ids.filtered(lambda r: r.is_board_service == False)
-
self.update({'service_ids': [(6, 0, other_services.ids)] + board_services})
+ for service in self.service_ids.filtered(lambda r: r.is_board_service == True):
+ service._compute_tax_ids()
+ service.price_unit = service._compute_price_unit()
"""
STATE WORKFLOW -----------------------------------------------------
@@ -706,6 +718,16 @@ class HotelReservation(models.Model):
"""
PRICE PROCESS ------------------------------------------------------
"""
+ @api.depends('service_ids.price_total')
+ def _compute_amount_room_services(self):
+ for record in self:
+ record.price_services = sum(record.mapped('service_ids.price_total'))
+
+ @api.depends('price_services','price_total')
+ def _compute_amount_set(self):
+ for record in self:
+ record.price_room_services_set = record.price_services + record.price_total
+
@api.multi
def compute_price_out_vals(self, vals):
"""
diff --git a/hotel/models/hotel_service.py b/hotel/models/hotel_service.py
index c19aaddbc..459dcded3 100644
--- a/hotel/models/hotel_service.py
+++ b/hotel/models/hotel_service.py
@@ -5,6 +5,10 @@ from odoo import models, fields, api, _
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
from datetime import timedelta
from odoo.exceptions import ValidationError
+from odoo.addons import decimal_precision as dp
+import logging
+_logger = logging.getLogger(__name__)
+
class HotelService(models.Model):
_name = 'hotel.service'
@@ -50,31 +54,34 @@ class HotelService(models.Model):
product_qty = fields.Integer('Quantity')
days_qty = fields.Integer(compute="_compute_days_qty", store=True)
is_board_service = fields.Boolean()
- pricelist_id = fields.Many2one(related='folio_id.pricelist_id')
+ # Non-stored related field to allow portal user to see the image of the product he has ordered
+ product_image = fields.Binary('Product Image', related="product_id.image", store=False)
channel_type = fields.Selection([
('door', 'Door'),
('mail', 'Mail'),
('phone', 'Phone'),
('call', 'Call Center'),
('web', 'Web')], 'Sales Channel')
- currency_id = fields.Many2one('res.currency',
- related='pricelist_id.currency_id',
- string='Currency', readonly=True, required=True)
+ price_unit = fields.Float('Unit Price', required=True, digits=dp.get_precision('Product Price'), default=0.0)
+ tax_ids = fields.Many2many('account.tax', string='Taxes', domain=['|', ('active', '=', False), ('active', '=', True)])
+ discount = fields.Float(string='Discount (%)', digits=dp.get_precision('Discount'), default=0.0)
+ currency_id = fields.Many2one(related='folio_id.currency_id', store=True, string='Currency', readonly=True)
price_subtotal = fields.Monetary(string='Subtotal',
readonly=True,
store=True,
- compute='_compute_amount_reservation')
+ compute='_compute_amount_service')
price_total = fields.Monetary(string='Total',
readonly=True,
store=True,
- compute='_compute_amount_reservation')
+ compute='_compute_amount_service')
price_tax = fields.Float(string='Taxes',
readonly=True,
store=True,
- compute='_compute_amount_reservation')
+ compute='_compute_amount_service')
@api.model
def create(self, vals):
+ vals.update(self._prepare_add_missing_fields(vals))
if self.compute_lines_out_vals(vals):
reservation = self.env['hotel.reservation'].browse(vals['ser_room_line'])
product = self.env['product.product'].browse(vals['product_id'])
@@ -114,6 +121,20 @@ class HotelService(models.Model):
res = super(HotelService, self).write(vals)
return res
+ @api.model
+ def _prepare_add_missing_fields(self, values):
+ """ Deduce missing required fields from the onchange """
+ res = {}
+ onchange_fields = ['price_unit','tax_ids']
+ if values.get('product_id'):
+ line = self.new(values)
+ if any(f not in values for f in onchange_fields):
+ line.onchange_product_calc_qty()
+ for field in onchange_fields:
+ if field not in values:
+ res[field] = line._fields[field].convert_to_write(line[field], line)
+ return res
+
@api.multi
def compute_lines_out_vals(self, vals):
"""
@@ -128,6 +149,26 @@ class HotelService(models.Model):
return True
return False
+ @api.multi
+ def _compute_tax_ids(self):
+ for record in self:
+ # If company_id is set, always filter taxes by the company
+ folio = self.folio_id or self.env.context.get('default_folio_id')
+ record.tax_id = record.product_id.taxes_id.filtered(lambda r: not record.company_id or r.company_id == folio.company_id)
+
+ @api.multi
+ def _get_display_price(self, product):
+ folio = self.folio_id or self.env.context.get('default_folio_id')
+ if folio.pricelist_id.discount_policy == 'with_discount':
+ return product.with_context(pricelist=folio.pricelist_id.id).price
+ product_context = dict(self.env.context, partner_id=folio.partner_id.id, date=folio.date_order, uom=self.product_id.uom_id.id)
+ final_price, rule_id = folio.pricelist_id.with_context(product_context).get_product_price_rule(self.product_id, self.product_qty or 1.0, folio.partner_id)
+ base_price, currency_id = self.with_context(product_context)._get_real_price_currency(product, rule_id, self.product_qty, product_id.uom_id, folio.pricelist_id.id)
+ if currency_id != folio.pricelist_id.currency_id.id:
+ base_price = self.env['res.currency'].browse(currency_id).with_context(product_context).compute(base_price, folio.pricelist_id.currency_id)
+ # negative discounts (= surcharge) are included in the display price
+ return max(base_price, final_price)
+
@api.onchange('product_id')
def onchange_product_calc_qty(self):
"""
@@ -135,11 +176,15 @@ class HotelService(models.Model):
configuration of the selected product, in per_day product configuration,
the qty is autocalculated and readonly based on service_lines qty
"""
+ if not self.product_id:
+ return
+ vals = {}
+ vals['product_qty'] = 1.0
for record in self:
if record.per_day and record.ser_room_line:
product = record.product_id
reservation = record.ser_room_line
- record.update(self.prepare_service_lines(
+ vals.update(self.prepare_service_lines(
dfrom=reservation.checkin,
days=reservation.nights,
per_person=product.per_person,
@@ -148,6 +193,30 @@ class HotelService(models.Model):
if record.product_id.daily_limit > 0:
for day in record.service_line_ids:
day.no_free_resources()
+ """
+ Compute tax and price unit
+ """
+ self._compute_tax_ids()
+ vals['price_unit'] = self._compute_price_unit()
+ record.update(vals)
+
+ @api.multi
+ def _compute_price_unit(self):
+ """
+ Compute tax and price unit
+ """
+ folio = self.folio_id or self.env.context.get('default_folio_id')
+ product = self.product_id.with_context(
+ lang=folio.partner_id.lang,
+ partner=folio.partner_id.id,
+ quantity=self.product_qty,
+ date=folio.date_order,
+ pricelist=folio.pricelist_id.id,
+ uom=self.product_id.uom_id.id,
+ fiscal_position=False
+ )
+ return self.env['account.tax']._fix_tax_included_price_company(self._get_display_price(product), product.taxes_id, self.tax_ids, folio.company_id)
+
@api.model
def prepare_service_lines(self, **kwargs):
@@ -155,16 +224,15 @@ class HotelService(models.Model):
Prepare line and respect the old manual changes on lines
"""
cmds = [(5, 0, 0)]
- old_lines_days = kwargs.get('old_lines_days')
+ old_line_days = kwargs.get('old_line_days')
total_qty = 0
day_qty = 1
if kwargs.get('per_person'): #WARNING: Change adults in reservation NOT update qty service!!
day_qty = kwargs.get('persons')
- old_line_days = self.env['hotel.service.line'].browse(kwargs.get('old_line_days'))
for i in range(0, kwargs.get('days')):
idate = (fields.Date.from_string(kwargs.get('dfrom')) + timedelta(days=i)).strftime(
DEFAULT_SERVER_DATE_FORMAT)
- if not old_lines_days or idate not in old_lines_days.mapped('date'):
+ if not old_line_days or idate not in old_line_days.mapped('date'):
cmds.append((0, False, {
'date': idate,
'day_qty': day_qty
@@ -176,15 +244,16 @@ class HotelService(models.Model):
total_qty = total_qty + old_line.day_qty
return {'service_line_ids': cmds, 'product_qty': total_qty}
- @api.depends('qty_product', 'tax_id')
+ @api.depends('product_qty', 'discount', 'price_unit', 'tax_ids')
def _compute_amount_service(self):
"""
Compute the amounts of the service line.
"""
for record in self:
+ folio = record.folio_id or self.env.context.get('default_folio_id')
product = record.product_id
- price = amount_room * (1 - (record.discount or 0.0) * 0.01)
- taxes = record.tax_id.compute_all(price, record.currency_id, 1, product=product)
+ price = record.price_unit * (1 - (record.discount or 0.0) * 0.01)
+ taxes = record.tax_ids.compute_all(price, folio.currency_id, record.product_qty, product=product)
record.update({
'price_tax': sum(t.get('amount', 0.0) for t in taxes.get('taxes', [])),
'price_total': taxes['total_included'],
@@ -203,12 +272,20 @@ class HotelService(models.Model):
else:
vals = {'days_qty': 0}
record.update(vals)
+
+ @api.multi
+ def open_service_lines(self):
+ action = self.env.ref('hotel.action_hotel_services_form').read()[0]
+ action['views'] = [(self.env.ref('hotel.hotel_service_view_form').id, 'form')]
+ action['res_id'] = self.id
+ action['target'] = 'new'
+ return action
- @api.constrains('qty_product')
- def constrains_qty_per_day(self):
- for record in self:
- if record.per_day:
- service_lines = self.env['hotel.service_line']
- total_day_qty = sum(service_lines.with_context({'service_id': record.id}).mapped('day_qty'))
- if record.qty_product != total_day_qty:
- raise ValidationError (_('The quantity per line and per day does not correspond'))
+ #~ @api.constrains('product_qty')
+ #~ def constrains_qty_per_day(self):
+ #~ for record in self:
+ #~ if record.per_day:
+ #~ service_lines = self.env['hotel.service_line']
+ #~ total_day_qty = sum(service_lines.with_context({'service_id': record.id}).mapped('day_qty'))
+ #~ if record.product_qty != total_day_qty:
+ #~ raise ValidationError (_('The quantity per line and per day does not correspond'))
diff --git a/hotel/views/hotel_folio_views.xml b/hotel/views/hotel_folio_views.xml
index bec9ab38f..91de623b4 100644
--- a/hotel/views/hotel_folio_views.xml
+++ b/hotel/views/hotel_folio_views.xml
@@ -135,6 +135,7 @@
+
@@ -149,14 +150,12 @@
-
-
@@ -287,19 +286,24 @@
-
+
+
+
-
+
+
+
+
+ attrs="{'readonly':[('state','not in',('draft'))]}"/>
@@ -417,7 +419,6 @@
domain="[('sale_ok', '=', True)]"
options="{'create': False, 'create_edit': False}" />
-
@@ -224,6 +224,8 @@
+
+
@@ -231,29 +233,36 @@
-
-
-
-
+
-
-
+ context="{'default_ser_room_line': active_id, 'default_folio_id': folio_id}"
+ nolabel="1">
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
@@ -261,26 +270,9 @@
-
-
+
@@ -289,7 +281,6 @@
-
diff --git a/hotel/views/hotel_service_views.xml b/hotel/views/hotel_service_views.xml
index 563db4faf..fc8409123 100644
--- a/hotel/views/hotel_service_views.xml
+++ b/hotel/views/hotel_service_views.xml
@@ -9,19 +9,29 @@