mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[DEV] Board Service, Wizard refact, hotes services configuration, services lines by day
This commit is contained in:
@@ -28,3 +28,4 @@ from . import massive_changes
|
||||
from . import split_reservation
|
||||
from . import duplicate_reservation
|
||||
from . import massive_price_reservation_days
|
||||
from . import wizard_reservation
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</record>
|
||||
|
||||
<!--Action for folio report wizard -->
|
||||
<record model="ir.actions.act_window" id="hotel_folio_wizard">
|
||||
<record model="ir.actions.act_window" id="hotel_report_folio_wizard">
|
||||
<field name="name">Hotel Folio Report</field>
|
||||
<field name="res_model">folio.report.wizard</field>
|
||||
<field name="view_type">form</field>
|
||||
@@ -29,7 +29,7 @@
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<!-- <menuitem name="Hotel Folio Report" action="hotel_folio_wizard"
|
||||
<!-- <menuitem name="Hotel Folio Report" action="hotel_report_folio_wizard"
|
||||
id="wizard_hotel_menu" parent="hotel_report_menu" sequence="31" />-->
|
||||
|
||||
</odoo>
|
||||
|
||||
496
hotel/wizard/wizard_reservation.py
Normal file
496
hotel/wizard/wizard_reservation.py
Normal file
@@ -0,0 +1,496 @@
|
||||
# Copyright 2018 Dario Lodeiros
|
||||
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import time
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
from openerp.exceptions import ValidationError
|
||||
from openerp.tools import (
|
||||
DEFAULT_SERVER_DATE_FORMAT,
|
||||
DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
from openerp import models, fields, api, _
|
||||
import odoo.addons.decimal_precision as dp
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FolioWizard(models.TransientModel):
|
||||
_name = 'hotel.folio.wizard'
|
||||
|
||||
@api.model
|
||||
def _get_default_center_user(self):
|
||||
user = self.env['res.users'].browse(self.env.uid)
|
||||
return user.has_group('hotel.group_hotel_call')
|
||||
|
||||
@api.model
|
||||
def _get_default_checkin(self):
|
||||
folio = False
|
||||
if 'folio_id' in self._context:
|
||||
folio = self.env['hotel.folio'].search([
|
||||
('id', '=', self._context['folio_id'])
|
||||
])
|
||||
if folio and folio.room_lines:
|
||||
return folio.room_lines[0].checkin
|
||||
return fields.Date.today()
|
||||
|
||||
@api.model
|
||||
def _get_default_checkout(self):
|
||||
folio = False
|
||||
if 'folio_id' in self._context:
|
||||
folio = self.env['hotel.folio'].search([
|
||||
('id', '=', self._context['folio_id'])
|
||||
])
|
||||
if folio and folio.room_lines:
|
||||
return folio.room_lines[0].checkout
|
||||
return fields.Date.today()
|
||||
|
||||
@api.model
|
||||
def _get_default_channel_type(self):
|
||||
user = self.env['res.users'].browse(self.env.uid)
|
||||
if user.has_group('hotel.group_hotel_call'):
|
||||
return 'phone'
|
||||
|
||||
partner_id = fields.Many2one('res.partner',string="Customer")
|
||||
checkin = fields.Datetime('Check In', required=True,
|
||||
default=_get_default_checkin)
|
||||
checkout = fields.Datetime('Check Out', required=True,
|
||||
default=_get_default_checkout)
|
||||
reservation_wizard_ids = fields.One2many('hotel.reservation.wizard',
|
||||
'folio_wizard_id',
|
||||
string="Resevations")
|
||||
service_wizard_ids = fields.One2many('hotel.service.wizard',
|
||||
'folio_wizard_id',
|
||||
string='Services')
|
||||
total = fields.Float('Total', compute='_computed_total')
|
||||
confirm = fields.Boolean('Confirm Reservations', default="1")
|
||||
autoassign = fields.Boolean('Autoassign', default="1")
|
||||
channel_type = fields.Selection([
|
||||
('door', 'Door'),
|
||||
('mail', 'Mail'),
|
||||
('phone', 'Phone')
|
||||
], string='Sales Channel', default=_get_default_channel_type)
|
||||
room_type_wizard_ids = fields.Many2many('hotel.room.type.wizard',
|
||||
string="Virtual Rooms")
|
||||
call_center = fields.Boolean(default=_get_default_center_user)
|
||||
|
||||
def assign_rooms(self):
|
||||
self.assign = True
|
||||
|
||||
@api.onchange('autoassign')
|
||||
def create_reservations(self):
|
||||
self.ensure_one()
|
||||
total = 0
|
||||
cmds = []
|
||||
for line in self.room_type_wizard_ids:
|
||||
if line.rooms_num == 0:
|
||||
continue
|
||||
if line.rooms_num > line.max_rooms:
|
||||
raise ValidationError(_("Too many rooms!"))
|
||||
elif line.room_type_id:
|
||||
occupied = self.env['hotel.reservation'].occupied(
|
||||
line.checkin,
|
||||
line.checkout)
|
||||
rooms_occupied = occupied.mapped('product_id.id')
|
||||
free_rooms = self.env['hotel.room'].search([
|
||||
('product_id.id', 'not in', rooms_occupied),
|
||||
('price_room_type.id', '=', line.room_type_id.id)
|
||||
], order='sequence', limit=line.rooms_num)
|
||||
room_ids = free_rooms.mapped('product_id.id')
|
||||
product_list = self.env['product.product'].search([
|
||||
('id', 'in', room_ids)
|
||||
])
|
||||
checkin_dt = fields.Date.from_string(line.checkin)
|
||||
checkout_dt = fields.Date.from_string(line.checkout)
|
||||
nights = abs((checkout_dt - checkin_dt).days)
|
||||
for room in product_list:
|
||||
pricelist_id = self.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'parity_pricelist_id')
|
||||
if pricelist_id:
|
||||
pricelist_id = int(pricelist_id)
|
||||
res_price = 0
|
||||
for i in range(0, nights):
|
||||
ndate = checkin_dt + timedelta(days=i)
|
||||
ndate_str = ndate.strftime(DEFAULT_SERVER_DATE_FORMAT)
|
||||
prod = line.room_type_id.product_id.with_context(
|
||||
lang=self.partner_id.lang,
|
||||
partner=self.partner_id.id,
|
||||
quantity=1,
|
||||
date=ndate_str,
|
||||
pricelist=pricelist_id,
|
||||
uom=room.uom_id.id)
|
||||
res_price += prod.price
|
||||
adults = self.env['hotel.room'].search([
|
||||
('product_id.id', '=', room.id)
|
||||
]).capacity
|
||||
res_price = res_price - (res_price * line.discount)/100
|
||||
total += res_price
|
||||
cmds.append((0, False, {
|
||||
'checkin': line.checkin,
|
||||
'checkout': line.checkout,
|
||||
'discount': line.discount,
|
||||
'product_id': room.id,
|
||||
'nights': nights,
|
||||
'adults': adults,
|
||||
'children': 0,
|
||||
'room_type_id': line.room_type_id,
|
||||
'price': res_price,
|
||||
'amount_reservation': res_price
|
||||
}))
|
||||
self.reservation_wizard_ids = cmds
|
||||
self.total = total
|
||||
|
||||
@api.multi
|
||||
@api.onchange('checkin', 'checkout')
|
||||
def onchange_checks(self):
|
||||
'''
|
||||
When you change checkin or checkout it will checked it
|
||||
and update the qty of hotel folio line
|
||||
-----------------------------------------------------------------
|
||||
@param self: object pointer
|
||||
'''
|
||||
self.ensure_one()
|
||||
checkin_dt = datetime.now() if not self.checkin else fields.Date.from_string(self.checkin)
|
||||
checkout_dt = datetime.now() if not self.checkout else fields.Date.from_string(self.checkout)
|
||||
if checkin_dt >= checkout_dt:
|
||||
checkout_dt = checkin_dt + timedelta(days=1)
|
||||
|
||||
chekin_str = checkin_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)
|
||||
chekout_str = checkout_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)
|
||||
|
||||
room_type_ids = self.env['hotel.room.type'].search([])
|
||||
cmds = room_type_ids.mapped(lambda x: (0, False, {
|
||||
'room_type_id': x.id,
|
||||
'checkin': chekin_str,
|
||||
'checkout': chekout_str,
|
||||
'folio_wizard_id': self.id,
|
||||
}))
|
||||
self.write({
|
||||
'checkin': chekin_str,
|
||||
'checkout': chekout_str,
|
||||
'room_type_wizard_ids': cmds,
|
||||
})
|
||||
for room_type in self.room_type_wizard_ids:
|
||||
room_type.update_price()
|
||||
|
||||
@api.depends('room_type_wizard_ids', 'reservation_wizard_ids', 'service_wizard_ids')
|
||||
def _computed_total(self):
|
||||
total = 0
|
||||
for line in self.service_wizard_ids:
|
||||
total += line.price_total
|
||||
if not self.reservation_wizard_ids:
|
||||
for line in self.room_type_wizard_ids:
|
||||
total += line.total_price
|
||||
self.total = total
|
||||
else:
|
||||
for line in self.reservation_wizard_ids:
|
||||
total += line.price
|
||||
self.total = total
|
||||
|
||||
@api.multi
|
||||
def create_folio(self):
|
||||
self.ensure_one()
|
||||
if not self.partner_id:
|
||||
raise ValidationError(_("We need know the customer!"))
|
||||
reservations = [(5, False, False)]
|
||||
services = [(5, False, False)]
|
||||
if self.autoassign == True:
|
||||
self.create_reservations()
|
||||
for line in self.reservation_wizard_ids:
|
||||
reservations.append((0, False, {
|
||||
'product_id': line.product_id.id,
|
||||
'adults': line.adults,
|
||||
'children': line.children,
|
||||
'checkin': line.checkin,
|
||||
'checkout': line.checkout,
|
||||
'discount': line.discount,
|
||||
'room_type_id': line.room_type_id.id,
|
||||
'to_read': line.to_read, #REFACT: wubook module
|
||||
'to_assign': line.to_assign,
|
||||
}))
|
||||
for line in self.service_wizard_ids:
|
||||
services.append((0, False, {
|
||||
'product_id': line.product_id.id,
|
||||
'discount': line.discount,
|
||||
'price_unit': line.price_unit,
|
||||
'product_uom_qty': line.product_uom_qty,
|
||||
}))
|
||||
vals = {
|
||||
'partner_id': self.partner_id.id,
|
||||
'channel_type': self.channel_type,
|
||||
'room_lines': reservations,
|
||||
'service_lines': services,
|
||||
}
|
||||
newfol = self.env['hotel.folio'].create(vals)
|
||||
for room in newfol.room_lines:
|
||||
room.on_change_checkin_checkout_product_id()
|
||||
newfol.compute_invoices_amount()
|
||||
if self.confirm:
|
||||
newfol.room_lines.confirm()
|
||||
action = self.env.ref('hotel.open_hotel_folio1_form_tree_all').read()[0]
|
||||
if newfol:
|
||||
action['views'] = [(self.env.ref('hotel.view_hotel_folio1_form').id, 'form')]
|
||||
action['res_id'] = newfol.id
|
||||
else:
|
||||
action = {'type': 'ir.actions.act_window_close'}
|
||||
return action
|
||||
|
||||
|
||||
class HotelRoomTypeWizards(models.TransientModel):
|
||||
_name = 'hotel.room.type.wizard'
|
||||
|
||||
@api.multi
|
||||
def _get_default_checkin(self):
|
||||
return self.folio_wizard_id.checkin
|
||||
|
||||
@api.model
|
||||
def _get_default_checkout(self):
|
||||
return self.folio_wizard_id.checkout
|
||||
|
||||
room_type_id = fields.Many2one('hotel.room.type',
|
||||
string="Virtual Rooms")
|
||||
rooms_num = fields.Integer('Number of Rooms')
|
||||
max_rooms = fields.Integer('Max', compute="_compute_max")
|
||||
price = fields.Float(string='Price by Room')
|
||||
total_price = fields.Float(string='Total Price')
|
||||
folio_wizard_id = fields.Many2one('hotel.folio.wizard')
|
||||
amount_reservation = fields.Float(string='Total', readonly=True)
|
||||
discount = fields.Float('discount')
|
||||
min_stay = fields.Integer('Min. Days', compute="_compute_max")
|
||||
checkin = fields.Datetime('Check In', required=True,
|
||||
default=_get_default_checkin)
|
||||
checkout = fields.Datetime('Check Out', required=True,
|
||||
default=_get_default_checkout)
|
||||
can_confirm = fields.Boolean(compute="_can_confirm")
|
||||
|
||||
@api.multi
|
||||
def _can_confirm(self):
|
||||
for record in self:
|
||||
date_start = fields.Date.from_string(record.checkin)
|
||||
date_end = fields.Date.from_string(record.checkout)
|
||||
date_diff = abs((date_end - date_start).days)
|
||||
record.can_confirm = record.max_rooms > 0 and record.min_stay <= date_diff
|
||||
|
||||
def _compute_max(self):
|
||||
for res in self:
|
||||
user = self.env['res.users'].browse(self.env.uid)
|
||||
date_start = fields.Date.from_string(res.checkin)
|
||||
date_end = fields.Date.from_string(res.checkout)
|
||||
date_diff = abs((date_end - date_start).days)
|
||||
minstay_restrictions = self.env['hotel.room.type.restriction.item'].search([
|
||||
('room_type_id', '=', res.room_type_id.id),
|
||||
])
|
||||
avail_restrictions = self.env['hotel.room.type.availability'].search([
|
||||
('room_type_id', '=', res.room_type_id.id)
|
||||
])
|
||||
real_max = len(res.room_type_id.check_availability_room(
|
||||
res.checkin,
|
||||
res.checkout,
|
||||
res.room_type_id.id))
|
||||
avail = 100000
|
||||
min_stay = 0
|
||||
dates = []
|
||||
for i in range(0, date_diff):
|
||||
ndate_dt = date_start + timedelta(days=i)
|
||||
ndate_str = ndate_dt.strftime(DEFAULT_SERVER_DATE_FORMAT)
|
||||
dates.append(ndate_str)
|
||||
if minstay_restrictions:
|
||||
date_min_days = minstay_restrictions.filtered(
|
||||
lambda r: r.date_start <= ndate_str and \
|
||||
r.date_end >= ndate_str).min_stay
|
||||
if date_min_days > min_stay:
|
||||
min_stay = date_min_days
|
||||
if user.has_group('hotel.group_hotel_call'):
|
||||
if avail_restrictions:
|
||||
max_avail = avail_restrictions.filtered(
|
||||
lambda r: r.date == ndate_str).wmax_avail
|
||||
if max_avail < avail:
|
||||
avail = min(max_avail, real_max)
|
||||
else:
|
||||
avail = real_max
|
||||
|
||||
|
||||
if 100000 < avail > 0:
|
||||
res.max_rooms = avail
|
||||
else:
|
||||
res.max_rooms = 0
|
||||
if min_stay > 0:
|
||||
res.min_stay = min_stay
|
||||
|
||||
@api.onchange('rooms_num', 'discount', 'price', 'room_type_id', 'checkin', 'checkout')
|
||||
def update_price(self):
|
||||
for record in self:
|
||||
if record.rooms_num > record.max_rooms:
|
||||
raise ValidationError(_("There are not enough rooms!"))
|
||||
|
||||
checkin = record.checkin or record.folio_wizard_id.checkin
|
||||
checkout = record.checkout or record.folio_wizard_id.checkout
|
||||
chkin_utc_dt = fields.Date.from_string(checkin)
|
||||
chkout_utc_dt = fields.Date.from_string(checkout)
|
||||
if chkin_utc_dt >= chkout_utc_dt:
|
||||
chkout_utc_dt = chkin_utc_dt + timedelta(days=1)
|
||||
chkout_utc_dt -= timedelta(days=1)
|
||||
nights = abs((chkout_utc_dt - chkin_utc_dt).days)
|
||||
|
||||
pricelist_id = self.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'parity_pricelist_id')
|
||||
if pricelist_id:
|
||||
pricelist_id = int(pricelist_id)
|
||||
|
||||
res_price = 0
|
||||
for i in range(0, nights):
|
||||
ndate = chkin_utc_dt + timedelta(days=i)
|
||||
ndate_str = ndate.strftime(DEFAULT_SERVER_DATE_FORMAT)
|
||||
prod = record.room_type_id.product_id.with_context(
|
||||
lang=record.folio_wizard_id.partner_id.lang,
|
||||
partner=record.folio_wizard_id.partner_id.id,
|
||||
quantity=1,
|
||||
date=ndate_str,
|
||||
pricelist=pricelist_id,
|
||||
uom=record.room_type_id.product_id.uom_id.id)
|
||||
res_price += prod.price
|
||||
|
||||
price = (res_price * record.discount) * 0.01
|
||||
total_price = record.rooms_num * price
|
||||
record.write({
|
||||
'checkin': checkin,
|
||||
'checkout': checkout,
|
||||
'price': price,
|
||||
'total_price': total_price,
|
||||
'amount_reservation': total_price,
|
||||
})
|
||||
|
||||
|
||||
class ReservationWizard(models.TransientModel):
|
||||
_name = 'hotel.reservation.wizard'
|
||||
|
||||
product_id = fields.Many2one('product.product',
|
||||
string="Room Types")
|
||||
|
||||
folio_wizard_id = fields.Many2one('hotel.folio.wizard')
|
||||
|
||||
adults = fields.Integer('Adults',
|
||||
help='List of adults there in guest list. ')
|
||||
children = fields.Integer('Children',
|
||||
help='Number of children there in guest list.')
|
||||
checkin = fields.Datetime('Check In', required=True)
|
||||
checkout = fields.Datetime('Check Out', required=True)
|
||||
room_type_id = fields.Many2one('hotel.room.type',
|
||||
string='Virtual Room Type',
|
||||
required=True)
|
||||
nights = fields.Integer('Nights', readonly=True)
|
||||
price = fields.Float(string='Total')
|
||||
amount_reservation = fields.Float(string='Total', readonly=True)
|
||||
partner_id = fields.Many2one(related='folio_wizard_id.partner_id')
|
||||
discount = fields.Float('discount')
|
||||
to_read = fields.Boolean(compute="_compute_to_read_assign")
|
||||
to_assign = fields.Boolean(compute="_compute_to_read_assign")
|
||||
|
||||
@api.multi
|
||||
def _compute_to_read_assign(self):
|
||||
for rec in self:
|
||||
user = self.env['res.users'].browse(self.env.uid)
|
||||
if user.has_group('hotel.group_hotel_call'):
|
||||
rec.to_read = rec.to_assign = True
|
||||
|
||||
@api.multi
|
||||
@api.onchange('product_id')
|
||||
def onchange_product_id(self):
|
||||
for line in self:
|
||||
if line.checkin and line.checkout:
|
||||
room = self.env['hotel.room'].search([
|
||||
('product_id.id', '=', line.product_id.id)
|
||||
])
|
||||
if line.adults == 0:
|
||||
line.adults = room.capacity
|
||||
line.room_type_id = room.price_room_type.id
|
||||
checkout_dt = fields.Date.from_string(line.checkout)
|
||||
checkout_dt -= timedelta(days=1)
|
||||
occupied = self.env['hotel.reservation'].occupied(
|
||||
line.checkin,
|
||||
checkout_dt.strftime(DEFAULT_SERVER_DATE_FORMAT))
|
||||
rooms_occupied = occupied.mapped('product_id.id')
|
||||
if line.product_id.id in rooms_occupied:
|
||||
raise ValidationError(_("This room is occupied!, please, \
|
||||
choice other room or change the reservation date"))
|
||||
|
||||
@api.multi
|
||||
@api.onchange('checkin', 'checkout', 'room_type_id', 'discount')
|
||||
def onchange_dates(self):
|
||||
for line in self:
|
||||
if not self.checkin:
|
||||
self.checkin = self.folio_wizard_id.checkin
|
||||
if not self.checkout:
|
||||
self.checkout = self.folio_wizard_id.checkout
|
||||
|
||||
start_date_utc_dt = fields.Date.from_string(line.checkin)
|
||||
end_date_utc_dt = fields.Date.from_string(line.checkout)
|
||||
|
||||
if line.room_type_id:
|
||||
pricelist_id = self.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'parity_pricelist_id')
|
||||
if pricelist_id:
|
||||
pricelist_id = int(pricelist_id)
|
||||
nights = abs((end_date_utc_dt - start_date_utc_dt).days)
|
||||
res_price = 0
|
||||
for i in range(0, nights):
|
||||
ndate = start_date_utc_dt + timedelta(days=i)
|
||||
ndate_str = ndate.strftime(DEFAULT_SERVER_DATE_FORMAT)
|
||||
prod = line.room_type_id.product_id.with_context(
|
||||
lang=self.partner_id.lang,
|
||||
partner=self.partner_id.id,
|
||||
quantity=1,
|
||||
date=ndate_str,
|
||||
pricelist=pricelist_id,
|
||||
uom=line.product_id.uom_id.id)
|
||||
res_price += prod.price
|
||||
res_price = res_price - (res_price * self.discount) * 0.01
|
||||
line.amount_reservation = res_price
|
||||
line.price = res_price
|
||||
end_date_utc_dt -= timedelta(days=1)
|
||||
occupied = self.env['hotel.reservation'].occupied(
|
||||
line.checkin,
|
||||
end_date_utc_dt.strftime(DEFAULT_SERVER_DATE_FORMAT))
|
||||
rooms_occupied = occupied.mapped('product_id.id')
|
||||
domain_rooms = [
|
||||
('isroom', '=', True),
|
||||
('id', 'not in', rooms_occupied)
|
||||
]
|
||||
return {'domain': {'product_id': domain_rooms}}
|
||||
|
||||
|
||||
class ServiceWizard(models.TransientModel):
|
||||
_name = 'hotel.service.wizard'
|
||||
|
||||
product_id = fields.Many2one('product.product',
|
||||
string="Service")
|
||||
folio_wizard_id = fields.Many2one('hotel.folio.wizard')
|
||||
discount = fields.Float('discount')
|
||||
price_unit = fields.Float('Unit Price', required=True,
|
||||
digits=dp.get_precision('Product Price'),
|
||||
default=0.0)
|
||||
price_total = fields.Float(compute='_compute_amount', string='Subtotal',
|
||||
readonly=True, store=True)
|
||||
product_uom_qty = fields.Float(string='Quantity',
|
||||
digits=dp.get_precision('Product Unit of Measure'),
|
||||
required=True,
|
||||
default=1.0)
|
||||
|
||||
@api.onchange('product_id')
|
||||
def onchange_product_id(self):
|
||||
if self.product_id:
|
||||
#TODO change pricelist for partner
|
||||
pricelist_id = self.env['ir.default'].sudo().get(
|
||||
'res.config.settings', 'parity_pricelist_id')
|
||||
prod = self.product_id.with_context(
|
||||
lang=self.folio_wizard_id.partner_id.lang,
|
||||
partner=self.folio_wizard_id.partner_id.id,
|
||||
quantity=1,
|
||||
date=fields.Datetime.now(),
|
||||
pricelist=pricelist_id,
|
||||
uom=self.product_id.uom_id.id)
|
||||
self.price_unit = prod.price
|
||||
|
||||
@api.depends('price_unit', 'product_uom_qty', 'discount')
|
||||
def _compute_amount(self):
|
||||
for ser in self:
|
||||
total = (ser.price_unit * ser.product_uom_qty)
|
||||
ser.price_total = total - (total * ser.discount) * 0.01
|
||||
101
hotel/wizard/wizard_reservation.xml
Normal file
101
hotel/wizard/wizard_reservation.xml
Normal file
@@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" ?>
|
||||
<odoo>
|
||||
|
||||
<record model="ir.ui.view" id="hotel_folio_wizard">
|
||||
<field name="name">hotel.folio.wizard</field>
|
||||
<field name="model">hotel.folio.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Reservation Wizard" >
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="checkin" required="1" colspan="1"/>
|
||||
<field name="checkout" required="1" colspan="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="call_center" invisible="1" />
|
||||
<field name="channel_type" required="1" attrs="{'readonly':[('call_center','=',True)]}"/>
|
||||
<field name="partner_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="room_type_wizard_ids" nolabel="1"
|
||||
attrs="{'invisible': [('autoassign','=',False)]}">
|
||||
<tree editable="bottom" create="false" delete="false"
|
||||
decoration-danger="max_rooms < rooms_num"
|
||||
decoration-muted="can_confirm == False"
|
||||
decoration-success="max_rooms >= rooms_num and rooms_num > 0">
|
||||
<field name="min_stay" />
|
||||
<field name="max_rooms" />
|
||||
<field name="room_type_id" string="Room Type" readonly="1"/>
|
||||
<field name="rooms_num" attrs="{'readonly': [('can_confirm','=',False)]}" />
|
||||
<field name="checkin" widget="date" />
|
||||
<field name="checkout" widget="date" />
|
||||
<field name="discount" attrs="{'readonly': [('can_confirm','=',False)]}"/>
|
||||
<field name="price" attrs="{'readonly': [('can_confirm','=',False)]}"/>
|
||||
<field name="amount_reservation" readonly="1" />
|
||||
<field name="total_price" invisible="1" />
|
||||
<field name="can_confirm" invisible="1" />
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
<label for="autoassign" attrs="{'invisible': [('autoassign','=', False)]}"/>
|
||||
<field name="autoassign" attrs="{'invisible': [('autoassign','=', False)]}"/>
|
||||
<field name="confirm" invisible="1"/>
|
||||
<group colspan="2" class="oe_subtotal_footer">
|
||||
<field name="total"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="reservation_wizard_ids" colspan="4" string="Room Lines"
|
||||
nolabel="1" attrs="{'invisible': [('autoassign','=',True)]}">
|
||||
<tree string="Room Line" delete="false" editable="buttom">
|
||||
<field name="product_id" string="Room No" options="{'no_create': True}"/>
|
||||
<field name="room_type_id" options="{'no_create': True}" />
|
||||
<field name="checkin" />
|
||||
<field name="checkout" />
|
||||
<field name="nights" />
|
||||
<field name="adults" />
|
||||
<field name="children" />
|
||||
<field name="discount" />
|
||||
<field name="amount_reservation" />
|
||||
<field name="price" invisible = "1"/>
|
||||
<field name="partner_id" invisible = "1" />
|
||||
<field name="folio_wizard_id" invisible = "1" />
|
||||
<field name="to_read" invisible="1" />
|
||||
<field name="to_assign" invisible="1" />
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
<group>
|
||||
<field name="service_wizard_ids" colspan="4" string="Services"
|
||||
nolabel="1" >
|
||||
<tree string="Services" editable="buttom">
|
||||
<field name="product_id" string="Service" options="{'no_create': True}"
|
||||
domain="[('isservice','=',True)]"/>
|
||||
<field name="product_uom_qty" />
|
||||
<field name="price_unit" />
|
||||
<field name="discount" />
|
||||
<field name="price_total" />
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="create_folio" string="Create Reservations" type="object"
|
||||
class="oe_highlight" />
|
||||
</footer>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="open_wizard_reservations" model="ir.actions.act_window">
|
||||
<field name="name">Hotel Reservation Wizard</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">hotel.folio.wizard</field>
|
||||
<field name="view_id" ref="hotel_folio_wizard"/>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user