Files
pms/hotel/models/hotel_service.py

125 lines
5.2 KiB
Python

# Copyright 2017 Alexandre Díaz
# Copyright 2017 Dario Lodeiros
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, fields, api
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
from datetime import timedelta
class HotelService(models.Model):
_name = 'hotel.service'
_description = 'Hotel Services and its charges'
@api.model
def _default_ser_room_line(self):
if self.env.context.get('room_lines'):
ids = [item[1] for item in self.env.context['room_lines']]
return self.env['hotel.reservation'].browse([
(ids)], limit=1)
return False
name = fields.Char('Service description')
product_id = fields.Many2one('product.product', 'Service', required=True)
folio_id = fields.Many2one('hotel.folio', 'Folio', ondelete='cascade')
ser_room_line = fields.Many2one('hotel.reservation', 'Room',
default=_default_ser_room_line)
per_day = fields.Boolean(related='product_id.per_day', 'Unit increment per day')
service_line_ids = fields.One2many('hotel.service.line', 'service_id')
product_qty = fields.Integer('Quantity')
pricelist_id = fields.Many2one(related='folio_id.pricelist_id')
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_subtotal = fields.Monetary(string='Subtotal',
readonly=True,
store=True,
compute='_compute_amount_reservation')
price_total = fields.Monetary(string='Total',
readonly=True,
store=True,
compute='_compute_amount_reservation')
price_tax = fields.Float(string='Taxes',
readonly=True,
store=True,
compute='_compute_amount_reservation')
@api.onchange('product_id')
def onchange_product_calc_qty(self):
"""
Compute the default quantity according to the
configuration of the selected product
"""
for record in self:
product = record.product_id
reservation = record.ser_room_line
if product and reservation:
qty = 1
if product.per_day:
qty = qty * reservation.nights
if product.per_person:
qty = qty * (reservation.adults + reservation.children)
record.product_qty = qty
@api.onchange('product_qty')
def onchange_product_qty_days_selection(self):
"""
Try to calculate the days on which the product
should be served as long as the product is per day
"""
for record in self:
reservation = record.ser_room_line
if record.product_id.per_day:
days_diff = (
fields.Date.from_string(reservation.checkout) - fields.Date.from_string(reservation.checkin)
).days
record.update(record.prepare_service_lines(
reservation.checkin,
days_diff))
else:
record.update(record.prepare_service_lines(
reservation.checkin, 1))
##WIP##
@api.multi
def prepare_service_lines(self, dfrom, days, vals=False):
self.ensure_one()
old_qty = 0
cmds = [(5, 0, 0)]
old_lines_days = self.mapped('service_line_ids.date')
for day in self.service_line_ids:
old_qty = old_qty + day.day_qty
qty_day = (self.product_qty - old_qty) // (days - len(old_line_days))
rest_day = (self.product_qty - old_qty) % (days - len(old_line_days))
for i in range(0, days):
idate = (fields.Date.from_string(dfrom) + timedelta(days=i)).strftime(
DEFAULT_SERVER_DATE_FORMAT)
old_line = self.service_line_ids.filtered(lambda r: r.date == idate)
if idate not in old_lines_days:
cmds.append((0, False, {
'date': idate,
'day_qty': qty_day
}))
else:
cmds.append((4, old_line.id))
return {'service_line_ids': cmds}
@api.depends('qty_product', 'tax_id')
def _compute_amount_service(self):
"""
Compute the amounts of the service line.
"""
for record in self:
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)
record.update({
'price_tax': sum(t.get('amount', 0.0) for t in taxes.get('taxes', [])),
'price_total': taxes['total_included'],
'price_subtotal': taxes['total_excluded'],
})