347 lines
11 KiB
Python
347 lines
11 KiB
Python
#This file is part of Presik. The COPYRIGHT file at the top level of
|
|
# this repository contains the full copyright notices and license terms.
|
|
from datetime import datetime, date, timedelta
|
|
|
|
from trytond.model import ModelView, ModelSQL, Workflow, fields
|
|
from trytond.pyson import Eval
|
|
from trytond.wizard import (
|
|
Wizard, StateView, Button, StateTransition, StateReport
|
|
)
|
|
from trytond.pool import Pool
|
|
from trytond.report import Report
|
|
from trytond.transaction import Transaction
|
|
|
|
ROOM_STATUS = [
|
|
('inspected', 'Inspected'),
|
|
('not_authorized', 'Not Authorized'),
|
|
('dirty', 'Dirty'),
|
|
('clean', 'Clean'),
|
|
('maintenance', 'Maintenance'),
|
|
]
|
|
|
|
|
|
class CleaningType(ModelSQL, ModelView):
|
|
"Room Cleaning Type"
|
|
__name__ = "hotel.room.cleaning_type"
|
|
name = fields.Char('Name', required=True, select=True)
|
|
description = fields.Text('Description')
|
|
kind = fields.Selection([
|
|
('tweak', 'Tweak'),
|
|
('deep', 'Deep'),
|
|
('standard', 'Standard'),
|
|
], 'Kind', required=True)
|
|
|
|
|
|
class Room(Workflow, ModelSQL, ModelView):
|
|
'Hotel Room'
|
|
__name__ = 'hotel.room'
|
|
name = fields.Char('Name', required=True)
|
|
code = fields.Char('Code')
|
|
active = fields.Boolean('Active')
|
|
templates = fields.Many2Many('hotel.room-product.template', 'room',
|
|
'template', 'Hotel Room - Product Accommodation', domain=[
|
|
('type', '=', 'service'),
|
|
('kind', '=', 'accommodation'),
|
|
])
|
|
classification = fields.Many2One('hotel.room.classification',
|
|
'Classification')
|
|
location = fields.Many2One('hotel.location', 'Location',
|
|
select=True)
|
|
amenities = fields.Many2Many('hotel.room-hotel.amenities', 'room',
|
|
'amenities', 'Amenities')
|
|
space = fields.Integer('Space', help='Space on m2')
|
|
channel_id = fields.Char('Channel Manager ID')
|
|
main_accommodation = fields.Many2One('product.template',
|
|
'Main Accommodation', ondelete='RESTRICT', depends=['templates'],
|
|
domain=[('id', 'in', Eval('templates', []))],
|
|
)
|
|
# TODO: Maybe add require a Current State field
|
|
min_unit_price = fields.Numeric('Min. Unit Price', digits=(16, 4))
|
|
max_unit_price = fields.Numeric('Max. Unit Price', digits=(16, 4))
|
|
state = fields.Selection(ROOM_STATUS, 'Status', required=True, readonly=True)
|
|
state_string = state.translated('state')
|
|
cleaning_type = fields.Function(fields.Many2One(
|
|
'hotel.room.cleaning_type', 'Cleaning Type', required=False),
|
|
'get_cleaning_type')
|
|
last_check_in = fields.DateTime('Last Check In')
|
|
last_check_out = fields.DateTime('Last Check Out')
|
|
last_clean = fields.DateTime('Last Clean')
|
|
housekeeping = fields.Many2One('company.employee', 'Employee')
|
|
notes = fields.Text('Notes')
|
|
max_accommodation = fields.Integer('Max. Accommodation')
|
|
guests = fields.Function(fields.Integer('Guests'), 'get_guests')
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super(Room, cls).__setup__()
|
|
cls._transitions |= set((
|
|
('clean', 'dirty'),
|
|
('clean', 'inspected'),
|
|
('clean', 'maintenance'),
|
|
('not_authorized', 'clean'),
|
|
('not_authorized', 'dirty'),
|
|
('dirty', 'clean'),
|
|
('dirty', 'maintenance'),
|
|
('dirty', 'inspected'),
|
|
('dirty', 'not_authorized'),
|
|
('maintenance', 'inspected'),
|
|
('maintenance', 'dirty'),
|
|
('inspected', 'dirty'),
|
|
('inspected', 'maintenance'),
|
|
('inspected', 'clean'),
|
|
))
|
|
cls._buttons.update({
|
|
'clean': {
|
|
'invisible': Eval('state').in_(['maintenance', 'clean']),
|
|
},
|
|
'dirty': {
|
|
'invisible': Eval('state').in_(['dirty']),
|
|
},
|
|
'inspected': {
|
|
'invisible': Eval('state').in_(['inspected']),
|
|
},
|
|
'maintenance': {
|
|
'invisible': Eval('state').in_(['maintenance']),
|
|
},
|
|
'not_authorized': {
|
|
'invisible': Eval('state').in_(['maintenance']),
|
|
},
|
|
})
|
|
|
|
@staticmethod
|
|
def default_active():
|
|
return True
|
|
|
|
@staticmethod
|
|
def default_state():
|
|
return 'dirty'
|
|
|
|
@classmethod
|
|
@ModelView.button
|
|
@Workflow.transition('clean')
|
|
def clean(cls, records):
|
|
for rec in records:
|
|
rec.last_clean = datetime.now()
|
|
rec.cleaning_type = None
|
|
rec.save()
|
|
|
|
@classmethod
|
|
@ModelView.button
|
|
@Workflow.transition('not_authorized')
|
|
def not_authorized(cls, records):
|
|
pass
|
|
|
|
@classmethod
|
|
@ModelView.button
|
|
@Workflow.transition('dirty')
|
|
def dirty(cls, records):
|
|
Config = Pool().get('hotel.configuration')
|
|
config = Config.get_configuration()
|
|
for rec in records:
|
|
rec.cleaning_type = config.cleaning_occupied.id
|
|
|
|
@classmethod
|
|
@ModelView.button
|
|
@Workflow.transition('maintenance')
|
|
def maintenance(cls, records):
|
|
pass
|
|
|
|
@classmethod
|
|
@ModelView.button
|
|
@Workflow.transition('inspected')
|
|
def inspected(cls, records):
|
|
pass
|
|
|
|
def get_guests(self, name=None):
|
|
pool = Pool()
|
|
Folio = pool.get('hotel.folio')
|
|
folios = Folio.search([
|
|
('room', '=', self.id),
|
|
('arrival_date', '<=', date.today()),
|
|
('departure_date', '>', date.today())
|
|
])
|
|
res = []
|
|
for folio in folios:
|
|
res.append(len(folio.guests))
|
|
return sum(res)
|
|
|
|
def get_cleaning_type(self, name=None):
|
|
pool = Pool()
|
|
Config = pool.get('hotel.configuration')
|
|
Folio = pool.get('hotel.folio')
|
|
config = Config.get_configuration()
|
|
today = date.today()
|
|
yesterday = today - timedelta(days=-1)
|
|
read = Folio.search_read
|
|
folios = read([
|
|
('room', '=', self.id),
|
|
('departure_date', '=', today)
|
|
], fields_names=['registration_state'],
|
|
)
|
|
if folios:
|
|
return config.cleaning_check_out.id
|
|
else:
|
|
folios = read([
|
|
('room', '=', self.id),
|
|
('departure_date', '>', today),
|
|
('arrival_date', '<', today),
|
|
], fields_names=['registration_state'],
|
|
)
|
|
if folios:
|
|
return config.cleaning_occupied.id
|
|
else:
|
|
return config.cleaning_check_in.id
|
|
|
|
@classmethod
|
|
def set_dirty_rooms(cls, name=None):
|
|
pool = Pool()
|
|
rooms = cls.search([])
|
|
cls.write(rooms, {'state': 'dirty'})
|
|
|
|
|
|
class RoomAmenities(ModelSQL):
|
|
'Room - Amenities'
|
|
__name__ = 'hotel.room-hotel.amenities'
|
|
_rec_name = 'name'
|
|
room = fields.Many2One('hotel.room', 'Room', required=True,
|
|
ondelete='CASCADE')
|
|
amenities = fields.Many2One('hotel.amenities', 'Amenities',
|
|
required=True, ondelete='CASCADE')
|
|
|
|
|
|
class Amenities(ModelSQL, ModelView):
|
|
'Amenities'
|
|
__name__ = 'hotel.amenities'
|
|
_rec_name = 'name'
|
|
name = fields.Char('Name', required=True)
|
|
notes = fields.Text('Notes')
|
|
type = fields.Selection([
|
|
('', ''),
|
|
('lingerie', 'Lingerie Room'),
|
|
('service', 'Service'),
|
|
], 'Type of Service')
|
|
cleaning_days = fields.One2Many('hotel.cleaning_days', 'amenities',
|
|
'Cleanning Days', states={
|
|
'invisible': Eval('type') != 'lingerie',
|
|
}, depends=['type'])
|
|
|
|
|
|
class RoomClassification(ModelSQL, ModelView):
|
|
'Room Classification'
|
|
__name__ = 'hotel.room.classification'
|
|
name = fields.Char('Name', required=True)
|
|
|
|
|
|
class CleanningDays(ModelSQL, ModelView):
|
|
'Cleanning Days'
|
|
__name__ = 'hotel.cleaning_days'
|
|
amenities = fields.Many2One('hotel.amenities', 'Amenities',
|
|
required=True, ondelete='CASCADE')
|
|
weekday = fields.Selection([
|
|
('1', 'Monday'),
|
|
('2', 'Tuesday'),
|
|
('3', 'Wednesday'),
|
|
('4', 'Thursday'),
|
|
('5', 'Friday'),
|
|
('6', 'Saturday'),
|
|
('7', 'Sunday'),
|
|
], 'Weekday', required=True)
|
|
note = fields.Text('Note')
|
|
|
|
|
|
class RoomTemplate(ModelSQL):
|
|
'Room - Template'
|
|
__name__ = 'hotel.room-product.template'
|
|
room = fields.Many2One('hotel.room', 'Room', required=True,
|
|
ondelete='CASCADE')
|
|
template = fields.Many2One('product.template', 'Product Template',
|
|
required=True, ondelete='CASCADE')
|
|
|
|
|
|
class HousekeepingStart(ModelView):
|
|
'Print Housekeeping Service Start'
|
|
__name__ = 'hotel.print_housekeeping.start'
|
|
date = fields.Date('Date', required=True)
|
|
employee = fields.Many2One('company.employee', 'Employee')
|
|
company = fields.Many2One('company.company', 'Company', required=True)
|
|
|
|
@staticmethod
|
|
def default_date():
|
|
Date_ = Pool().get('ir.date')
|
|
return Date_.today()
|
|
|
|
@staticmethod
|
|
def default_company():
|
|
return Transaction().context.get('company')
|
|
|
|
|
|
class Housekeeping(Wizard):
|
|
'Housekeeping Service'
|
|
__name__ = 'hotel.print_housekeeping'
|
|
start = StateView('hotel.print_housekeeping.start',
|
|
'hotel.print_housekeeping_start_view_form', [
|
|
Button('Cancel', 'end', 'tryton-cancel'),
|
|
Button('Open', 'print_', 'tryton-print', default=True),
|
|
])
|
|
print_ = StateReport('hotel.print_housekeeping.report')
|
|
|
|
def do_print_(self, action):
|
|
company = self.start.company
|
|
data = {
|
|
'date': self.start.date,
|
|
'employee': self.start.employee.id if self.start.employee else None,
|
|
'company': company.id,
|
|
}
|
|
return action, data
|
|
|
|
def transition_print_(self):
|
|
return 'end'
|
|
|
|
|
|
class HousekeepingReport(Report):
|
|
__name__ = 'hotel.print_housekeeping.report'
|
|
|
|
@classmethod
|
|
def get_context(cls, records, header, data):
|
|
report_context = super().get_context(records, header, data)
|
|
pool = Pool()
|
|
Company = pool.get('company.company')
|
|
Room = pool.get('hotel.room')
|
|
|
|
dom = []
|
|
if data['employee']:
|
|
dom.append(('employee.id', '=', data['employee']))
|
|
|
|
rooms = Room.search(dom)
|
|
total_guests = []
|
|
for room in rooms:
|
|
total_guests.append(room.guests)
|
|
report_context['records'] = rooms
|
|
report_context['company'] = Company(data['company'])
|
|
report_context['date'] = datetime.now()
|
|
report_context['total_guests'] = sum(total_guests)
|
|
return report_context
|
|
|
|
|
|
class HotelTask(ModelSQL, ModelView):
|
|
"Hotel Task"
|
|
__name__ = "hotel.task"
|
|
name = fields.Char('Name Task', required=True, select=True)
|
|
frecuency = fields.Integer('Frecuency', select=True, help='In days')
|
|
quantity = fields.Integer('Quantity', select=True)
|
|
|
|
|
|
# class HotelHousekeepingTask(ModelView, ModelSQL):
|
|
# 'Hotel Housekeeping Task'
|
|
# __name__ = 'hotel.housekeeping.task'
|
|
# room = fields.Many2One('hotel.room', 'Hotel Housekeeping',
|
|
# ondelete='CASCADE', select=True, required=True)
|
|
# task = fields.Many2One('hotel.task', 'Task', select=True, required=True)
|
|
# frecuency = fields.Integer('Frecuency', select=True, help='In days')
|
|
# quantity = fields.Integer('Quantity', select=True)
|
|
#
|
|
# @fields.depends('task', 'frecuency')
|
|
# def on_change_task(self, name=None):
|
|
# if self.task:
|
|
# self.frecuency = self.task.frecuency
|