trytonpsk-hotel/room.py

325 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
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):
'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([
('inspected', 'Inspected'),
('dirty', 'Dirty'),
('clean', 'Clean'),
('maintenance', 'Maintenance'),
], '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')
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'),
('dirty', 'clean'),
('dirty', 'maintenance'),
('dirty', 'inspected'),
('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']),
},
})
@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('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
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