trytonpsk-hotel/service.py

338 lines
10 KiB
Python
Raw Normal View History

2020-04-16 14:45:13 +02:00
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from datetime import datetime
from trytond.model import ModelView, Workflow, ModelSQL, fields
from trytond.pool import Pool
2021-07-31 18:17:54 +02:00
from trytond.pyson import Eval, In, If, Get
2020-04-16 14:45:13 +02:00
from trytond.modules.company import CompanyReport
from trytond.wizard import Wizard, StateView, Button, StateTransition
from trytond.transaction import Transaction
2021-10-11 19:03:43 +02:00
from trytond.exceptions import UserError
2021-07-21 14:56:53 +02:00
from trytond.i18n import gettext
2020-04-16 14:45:13 +02:00
STATES = {
'readonly': Eval('state') == 'checked'
}
2020-07-11 17:21:01 +02:00
STATES_LINE = {
'readonly': Eval('state') == 'loaded'
}
2020-04-16 14:45:13 +02:00
2021-07-21 14:56:53 +02:00
2020-04-16 14:45:13 +02:00
class ServiceKind(ModelSQL, ModelView):
'Service Kind'
__name__ = 'hotel.service.kind'
name = fields.Char('Name', select=True, required=True)
product = fields.Many2One('product.product', 'Product')
salable = fields.Boolean('Salable')
category = fields.Selection([
('breakfast', 'Breakfast'),
('restaurant', 'Restaurant'),
('laundry', 'Laundry'),
('spa', 'Spa'),
], 'Category')
2020-04-16 14:45:13 +02:00
class Service(Workflow, ModelSQL, ModelView):
'Service'
__name__ = 'hotel.service'
_rec_name = 'kind.name'
number = fields.Char('Number', select=True, required=False)
kind = fields.Many2One('hotel.service.kind', 'Kind', required=True,
states={
'readonly': Eval('state').in_(['confirmed', 'checked'])
})
service_date = fields.Date('Date', required=True, states={
'readonly': Eval('state').in_(['confirmed', 'checked'])
})
lines = fields.One2Many('hotel.service.line', 'service', 'Lines',
states={'readonly': Eval('state') != 'open'}
)
state = fields.Selection([
('draft', 'Draft'),
('open', 'Open'),
('confirmed', 'Confirmed'),
('checked', 'Checked'),
], 'State', readonly=True, states=STATES)
state_string = state.translated('state')
description = fields.Char('Description', select=True, states=STATES)
count_services = fields.Function(fields.Integer('Count Services',
select=True), 'get_count_services')
2021-07-31 18:17:54 +02:00
company = fields.Many2One('company.company', 'Company', required=True,
states=STATES, domain=[('id', If(In('company',
Eval('context', {})), '=', '!='), Get(Eval('context', {}),
'company', 0))])
2020-04-16 14:45:13 +02:00
@classmethod
def __setup__(cls):
super(Service, cls).__setup__()
cls._order.insert(0, ('service_date', 'DESC'))
cls._transitions |= set((
('draft', 'open'),
('open', 'confirmed'),
('confirmed', 'open'),
('confirmed', 'checked'),
))
cls._buttons.update({
'draft': {
'invisible': Eval('state') != 'open',
},
'open': {
'invisible': Eval('state') != 'draft',
},
'confirm': {
'invisible': Eval('state') != 'open',
},
'checked': {
'invisible': Eval('state') != 'confirmed',
},
})
@staticmethod
def default_state():
return 'draft'
2021-07-31 18:17:54 +02:00
@staticmethod
def default_company():
2021-07-31 18:19:43 +02:00
return Transaction().context.get('company')
2021-07-31 18:17:54 +02:00
2020-04-16 14:45:13 +02:00
@classmethod
@ModelView.button
@Workflow.transition('draft')
def draft(cls, records):
pass
@classmethod
@ModelView.button
@Workflow.transition('open')
def open(cls, records):
cls.set_number(records)
@classmethod
@ModelView.button
@Workflow.transition('confirmed')
def confirm(cls, records):
pass
@classmethod
@ModelView.button
@Workflow.transition('checked')
def checked(cls, records):
pass
def get_count_services(self, name=None):
return len(self.lines)
@classmethod
def set_number(cls, services):
"""
Fill the number field with the service sequence
"""
2021-07-30 17:34:10 +02:00
Config = Pool().get('hotel.configuration')
2020-04-16 14:45:13 +02:00
config = Config.get_configuration()
for service in services:
if service.number or not config.hotel_service_sequence:
continue
2021-07-30 17:34:10 +02:00
number = config.hotel_service_sequence.get()
2020-04-16 14:45:13 +02:00
cls.write([service], {'number': number})
class ServiceLine(Workflow, ModelSQL, ModelView):
'Service Line'
__name__ = 'hotel.service.line'
service = fields.Many2One('hotel.service', 'Service', required=True)
2021-10-11 19:03:43 +02:00
room = fields.Many2One('hotel.room', 'Room', select=True, required=True,
states=STATES_LINE)
2020-07-11 17:21:01 +02:00
time_service = fields.Time('Time Service', select=True, states=STATES_LINE)
2020-04-16 14:45:13 +02:00
product = fields.Many2One('product.product', 'Product',
domain=[
('salable', '=', True),
('active', '=', True),
], required=True)
2020-07-11 17:21:01 +02:00
quantity = fields.Integer('Quantity', required=True, states=STATES_LINE)
description = fields.Char('Description', states=STATES_LINE)
order = fields.Char('Order', select=True, states=STATES_LINE)
2021-10-12 07:18:02 +02:00
folio_line = fields.Many2One('hotel.folio', 'Folio Line',
2021-10-11 19:03:43 +02:00
states={'readonly': True})
2021-10-12 07:18:02 +02:00
guest = fields.Char('Guest', states=STATES_LINE)
2021-10-11 19:03:43 +02:00
charge = fields.Many2One('hotel.folio.charge', 'Operation Line',
2020-04-16 14:45:13 +02:00
states={'readonly': True})
2021-10-12 07:43:22 +02:00
folio = fields.Many2One('hotel.folio', 'Folio', domain=[
('room', '=', Eval('room')),
2021-10-14 06:41:15 +02:00
('registration_state', '=', 'check_in')
2021-10-12 17:25:14 +02:00
], depends=['room'])
2020-04-16 14:45:13 +02:00
state = fields.Selection([
('draft', 'Draft'),
('loaded', 'Loaded'),
('deleted', 'Deleted'),
('done', 'Done'),
2021-10-12 17:25:14 +02:00
], 'State', readonly=True)
2020-04-16 14:45:13 +02:00
state_string = state.translated('state')
@classmethod
def __setup__(cls):
super(ServiceLine, cls).__setup__()
cls._transitions |= set((
('draft', 'invoiced'),
('draft', 'loaded'),
('draft', 'done'),
('loaded', 'draft'),
))
cls._buttons.update({
'draft': {
'invisible': ~Eval('state').in_(['invoiced']),
},
'load': {
'invisible': Eval('state') != 'draft',
},
'done': {
'invisible': Eval('state') != 'draft',
},
})
@staticmethod
def default_quantity():
return 1
@staticmethod
def default_state():
return 'draft'
@staticmethod
def default_time_service():
Company = Pool().get('company.company')
local_date = Company.convert_timezone(datetime.now())
return local_date.time()
@fields.depends('product', 'description')
def on_change_product(self):
if self.product:
self.description = self.product.name
@classmethod
@ModelView.button
@Workflow.transition('loaded')
def load(cls, records):
for record in records:
record.add_product_to_room()
@classmethod
@ModelView.button
@Workflow.transition('draft')
def draft(cls, records):
pass
@classmethod
@ModelView.button
@Workflow.transition('done')
def done(cls, records):
pass
def add_product_to_room(self):
2021-10-12 07:43:22 +02:00
FolioCharge = Pool().get('hotel.folio.charge')
2021-10-12 07:18:02 +02:00
if self.folio_line:
2020-04-16 14:45:13 +02:00
return
2021-10-12 07:18:02 +02:00
# if not folios:
# raise UserError(
# gettext('hotel.msg_room_not_occupied', s=self.room.name)
# )
# elif len(folios) > 1:
# raise UserError(
# gettext('hotel.msg_multiple_rooms_active', s=self.room.name)
# )
# folio = folios[0]
2020-04-16 14:45:13 +02:00
new_line = {
2021-10-12 07:18:02 +02:00
'folio': self.folio.id,
2020-04-16 14:45:13 +02:00
'date_service': self.service.service_date,
'order': self.order,
'description': self.description,
'quantity': int(self.quantity),
2021-10-12 07:18:02 +02:00
'invoice_to': self.folio.main_guest.id,
2020-04-16 14:45:13 +02:00
'unit_price': self.product.template.list_price,
'product': self.product.id,
2021-12-28 00:02:47 +01:00
'to_invoice': True,
2021-10-14 06:41:15 +02:00
'state': '',
2020-04-16 14:45:13 +02:00
}
2021-09-21 06:33:06 +02:00
line, = FolioCharge.create([new_line])
2021-10-11 19:03:43 +02:00
self.write([self], {'charge': line.id})
2020-04-16 14:45:13 +02:00
class ServiceReport(CompanyReport):
__name__ = 'hotel.service'
@classmethod
2021-07-21 14:56:53 +02:00
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
2020-04-16 14:45:13 +02:00
return report_context
class CreateDailyServicesStart(ModelView):
'Create Daily Services Start'
__name__ = 'hotel.daily_services.start'
kind = fields.Many2One('hotel.service.kind', 'Kind', required=True,
domain=[
('category', '=', 'breakfast'),
('product', '!=', None)
])
2020-04-16 14:45:13 +02:00
date = fields.Date('Date', required=True)
company = fields.Many2One('company.company', 'Company', required=True)
description = fields.Char('Description')
@staticmethod
def default_company():
return Transaction().context.get('company')
class CreateDailyServices(Wizard):
'Create Daily Services'
__name__ = 'hotel.daily_services'
start = StateView('hotel.daily_services.start',
'hotel.create_daily_services_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Accept', 'accept_', 'tryton-ok', default=True),
])
accept_ = StateTransition()
def transition_accept_(self):
pool = Pool()
Service = pool.get('hotel.service')
2021-10-11 19:03:43 +02:00
Folio = pool.get('hotel.folio')
2020-04-16 14:45:13 +02:00
2021-10-11 19:03:43 +02:00
folios = Folio.search([
('arrival_date', '<', self.start.date),
2021-10-12 07:18:02 +02:00
# ('departure_date', '<', self.start.date),
2021-10-14 06:41:15 +02:00
('registration_state', 'in', ['check_in']),
2020-04-16 14:45:13 +02:00
])
lines_to_create = []
service, = Service.create([{
'service_date': self.start.date,
'state': 'draft',
'kind': self.start.kind.id,
}])
Service.open([service])
product = self.start.kind.product
2021-10-11 19:03:43 +02:00
for fol in folios:
if not fol.breakfast_included:
continue
2021-10-11 19:03:43 +02:00
for guest in fol.guests:
2021-11-24 17:39:13 +01:00
if guest.party:
guest_name = guest.party.name
else:
guest_name = fol.main_guest.name
lines_to_create.append({
2021-10-12 07:18:02 +02:00
'folio': fol.id,
'service': service.id,
2021-10-11 19:03:43 +02:00
'room': fol.room.id,
2021-11-24 17:39:13 +01:00
'guest': guest_name,
'product': product.id,
'quantity': 1,
})
if lines_to_create:
ServiceLine.create(lines_to_create)
2020-04-16 14:45:13 +02:00
return 'end'