Refactory 08
This commit is contained in:
parent
75ee48a402
commit
d2ddb3c3dc
29
__init__.py
29
__init__.py
|
@ -38,22 +38,22 @@ def register():
|
|||
company.Company,
|
||||
folio.Folio,
|
||||
folio.FolioCharge,
|
||||
# folio.folioMaintenance,
|
||||
# folio.folioGuest,
|
||||
# folio.TransferfolioStart,
|
||||
# folio.TransferChargeStart,
|
||||
folio.FolioStockMove,
|
||||
folio.OpenMigrationStart,
|
||||
party.Party,
|
||||
channel.ChannelTax,
|
||||
booking.Guest,
|
||||
booking.SelectRoomsAsk,
|
||||
booking.BookingVoucher,
|
||||
booking.RoomsOccupancyStart,
|
||||
booking.BookingForecastStart,
|
||||
# folio.OpenMigrationStart,
|
||||
folio.FolioGuest,
|
||||
folio.GuestsListStart,
|
||||
# folio.TransferfolioStart,
|
||||
# folio.TransferChargeStart,
|
||||
# folio.CheckOutfolioFailed,
|
||||
# folio.ChangeRoomStart,
|
||||
# folio.folioVoucher,
|
||||
# folio.StatisticsByMonthStart,
|
||||
folio.StatisticsByMonthStart,
|
||||
sale.InvoiceIncomeDailyStart,
|
||||
service.Service,
|
||||
service.ServiceLine,
|
||||
|
@ -64,39 +64,38 @@ def register():
|
|||
housekeeping.HotelTask,
|
||||
housekeeping.HousekeepingServiceStart,
|
||||
room.CleanningDays,
|
||||
booking.GuestsListStart,
|
||||
module='hotel', type_='model')
|
||||
Pool.register(
|
||||
booking.BookingReport,
|
||||
booking.BookingForecastReport,
|
||||
booking.RoomsOccupancyReport,
|
||||
booking.BookingDailyReport,
|
||||
# folio.Migration,
|
||||
folio.Migration,
|
||||
folio.GuestsListReport,
|
||||
folio.RegistrationCardReport,
|
||||
# folio.folioReport,
|
||||
# folio.folioByConsumerReport,
|
||||
# folio.StatisticsByMonthReport,
|
||||
folio.StatisticsByMonthReport,
|
||||
sale.InvoiceIncomeDailyReport,
|
||||
sale.InvoiceSimplifiedReport,
|
||||
service.ServiceReport,
|
||||
booking.RegistrationCardReport,
|
||||
housekeeping.HousekeepingServiceReport,
|
||||
booking.GuestsListReport,
|
||||
module='hotel', type_='report')
|
||||
Pool.register(
|
||||
booking.SelectRooms,
|
||||
booking.BookingForecast,
|
||||
booking.RoomsOccupancy,
|
||||
booking.BookingDaily,
|
||||
# folio.OpenMigration,
|
||||
folio.OpenMigration,
|
||||
folio.GuestsList,
|
||||
# folio.CheckOutfolio,
|
||||
# folio.folioBill,
|
||||
# folio.ChangeRoom,
|
||||
# folio.Transferfolio,
|
||||
# folio.TransferCharge,
|
||||
# folio.StatisticsByMonth,
|
||||
folio.StatisticsByMonth,
|
||||
service.CreateDailyServices,
|
||||
housekeeping.HousekeepingService,
|
||||
booking.GuestsList,
|
||||
sale.InvoiceIncomeDaily,
|
||||
party.CreateGuest,
|
||||
module='hotel', type_='wizard')
|
||||
|
|
250
booking.py
250
booking.py
|
@ -563,146 +563,6 @@ class BookingVoucher(ModelSQL):
|
|||
}])
|
||||
|
||||
|
||||
class Guest(ModelSQL, ModelView):
|
||||
'Guest'
|
||||
__name__ = 'hotel.booking.guest'
|
||||
_rec_name = 'party'
|
||||
booking_line = fields.Many2One('hotel.folio', 'Booking Line',
|
||||
required=True, ondelete='CASCADE')
|
||||
party = fields.Many2One('party.party', 'Party', required=False)
|
||||
type_guest = fields.Selection([
|
||||
('adult', 'Adult'),
|
||||
('child', 'Child'),
|
||||
], 'Type Guest')
|
||||
type_guest_string = type_guest.translated('type_guest')
|
||||
nationality = fields.Many2One('party.nationality', 'Nationality')
|
||||
origin_country = fields.Many2One('party.nationality', 'Origin Country',
|
||||
select=True)
|
||||
target_country = fields.Many2One('party.nationality', 'Target Country',
|
||||
select=True)
|
||||
|
||||
# New fields for speed reason
|
||||
type_document = fields.Selection([
|
||||
('12', 'Tarjeta de Identidad'),
|
||||
('13', 'Cedula de Ciudadania'),
|
||||
('21', 'Tarjeta de Extranjeria'),
|
||||
('22', 'Cedula de Extranjeria'),
|
||||
('41', 'Pasaporte'),
|
||||
], 'Document Type')
|
||||
doc_number = fields.Char('Doc. Id', select=True)
|
||||
name = fields.Char('Name', select=True)
|
||||
mobile = fields.Char('Mobile', select=True)
|
||||
email = fields.Char('Email', select=True)
|
||||
birthday = fields.Date('Birthday', select=True)
|
||||
sex = fields.Selection([
|
||||
('female', 'Female'),
|
||||
('male', 'Male'),
|
||||
('', ''),
|
||||
], 'Sex')
|
||||
first_name = fields.Char('First Name')
|
||||
second_name = fields.Char('Second Name')
|
||||
first_family_name = fields.Char('First Family Name')
|
||||
second_family_name = fields.Char('Second Family Name')
|
||||
type_person = fields.Selection([
|
||||
('persona_natural', 'Persona Natural'),
|
||||
('persona_juridica', 'Persona Juridica'),
|
||||
], 'Type Person')
|
||||
|
||||
@fields.depends('name', 'first_name', 'second_name',
|
||||
'first_family_name', 'second_family_name', 'type_person')
|
||||
def on_change_name(self):
|
||||
second_family_name = None
|
||||
first_family_name = None
|
||||
second_name = None
|
||||
first_name = None
|
||||
if self.name and self.type_person == 'persona_natural':
|
||||
names = self.name.split(' ')
|
||||
first_name = names[0]
|
||||
second_family_name = names[-1]
|
||||
if len(names) > 1:
|
||||
first_family_name = names[-2]
|
||||
if len(names) == 2:
|
||||
second_family_name = None
|
||||
first_family_name = names[1]
|
||||
elif len(names) == 5:
|
||||
second_name = names[1] + ' ' + names[2]
|
||||
elif len(names) == 4:
|
||||
second_name = names[1]
|
||||
|
||||
self.second_family_name = second_family_name
|
||||
self.first_family_name = first_family_name
|
||||
self.second_name = second_name
|
||||
self.first_name = first_name
|
||||
|
||||
def get_rec_name(self, name):
|
||||
if self.party:
|
||||
return self.party.name
|
||||
|
||||
@staticmethod
|
||||
def default_type_guest():
|
||||
return 'adult'
|
||||
|
||||
@staticmethod
|
||||
def default_sex():
|
||||
return 'male'
|
||||
|
||||
@staticmethod
|
||||
def default_type_person():
|
||||
return 'persona_natural'
|
||||
|
||||
@staticmethod
|
||||
def default_type_document():
|
||||
return '13'
|
||||
|
||||
@staticmethod
|
||||
def default_principal_guest():
|
||||
return False
|
||||
|
||||
@fields.depends('nationality', 'origin_country', 'target_country')
|
||||
def on_change_nationality(self):
|
||||
if self.nationality:
|
||||
self.target_country = self.nationality.id
|
||||
self.origin_country = self.nationality.id
|
||||
|
||||
@classmethod
|
||||
def create(cls, vlist):
|
||||
Party = Pool().get('party.party')
|
||||
new_values = []
|
||||
for v in vlist:
|
||||
# if not v.get('doc_number'):
|
||||
# continue
|
||||
party = v.get('party')
|
||||
if not party:
|
||||
parties = Party.search([
|
||||
('id_number', '=', v['doc_number']),
|
||||
])
|
||||
if parties:
|
||||
party = parties[0]
|
||||
else:
|
||||
party, = Party.create([{
|
||||
'name': v['name'],
|
||||
'id_number': v['doc_number'],
|
||||
'type_document': v['type_document'],
|
||||
'birthday': v['birthday'],
|
||||
'sex': v['sex'],
|
||||
'first_name': v['first_name'],
|
||||
'second_name': v['second_name'],
|
||||
'first_family_name': v['first_family_name'],
|
||||
'second_family_name': v['second_family_name'],
|
||||
'type_person': v['type_person'],
|
||||
'contact_mechanisms': [
|
||||
('create', [
|
||||
{'type': 'email', 'value': v['email']},
|
||||
{'type': 'mobile', 'value': v['mobile']},
|
||||
])
|
||||
]
|
||||
}])
|
||||
v['party'] = party.id
|
||||
new_values.append(v)
|
||||
|
||||
super(Guest, cls).create(new_values)
|
||||
|
||||
|
||||
class BookingForecastStart(ModelView):
|
||||
'Booking Forecast Start'
|
||||
__name__ = 'hotel.print_booking_forecast.start'
|
||||
|
@ -769,8 +629,7 @@ class BookingForecastReport(Report):
|
|||
date_init = data['date']
|
||||
date_limit = data['date'] + timedelta(MAX_DAYS)
|
||||
|
||||
dom = [['OR',
|
||||
[
|
||||
dom = [['OR', [
|
||||
('arrival_date', '<=', date_init),
|
||||
('departure_date', '>=', date_init),
|
||||
], [
|
||||
|
@ -807,113 +666,6 @@ class BookingForecastReport(Report):
|
|||
return report_context
|
||||
|
||||
|
||||
class RegistrationCardReport(Report):
|
||||
__name__ = 'hotel.occupancy.registration_card'
|
||||
|
||||
@classmethod
|
||||
def get_context(cls, records, header, data):
|
||||
report_context = super().get_context(records, header, data)
|
||||
user = Pool().get('res.user')(Transaction().user)
|
||||
report_context['company'] = user.company
|
||||
return report_context
|
||||
|
||||
|
||||
class GuestsListStart(ModelView):
|
||||
'Guests List Start'
|
||||
__name__ = 'hotel.print_guests_list.start'
|
||||
date = fields.Date('Date', required=True)
|
||||
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 GuestsList(Wizard):
|
||||
'Guests List'
|
||||
__name__ = 'hotel.print_guests_list'
|
||||
start = StateView('hotel.print_guests_list.start',
|
||||
'hotel.print_guests_list_start_view_form', [
|
||||
Button('Cancel', 'end', 'tryton-cancel'),
|
||||
Button('Open', 'print_', 'tryton-print', default=True),
|
||||
])
|
||||
print_ = StateReport('hotel.guests_list.report')
|
||||
|
||||
def do_print_(self, action):
|
||||
company = self.start.company
|
||||
data = {
|
||||
'date': self.start.date,
|
||||
'company': company.id,
|
||||
}
|
||||
return action, data
|
||||
|
||||
def transition_print_(self):
|
||||
return 'end'
|
||||
|
||||
|
||||
class GuestsListReport(Report):
|
||||
__name__ = 'hotel.guests_list.report'
|
||||
|
||||
@classmethod
|
||||
def get_context(cls, records, header, data):
|
||||
report_context = super().get_context(records, header, data)
|
||||
pool = Pool()
|
||||
Company = pool.get('company.company')
|
||||
# Operation = pool.get('hotel.operation')
|
||||
Room = pool.get('hotel.room')
|
||||
User = pool.get('res.user')
|
||||
user_id = Transaction().user
|
||||
|
||||
user = User(user_id)
|
||||
start_date = data['date']
|
||||
# operations = Operation.search([
|
||||
# ('start_date', '<=', start_date),
|
||||
# ('kind', '=', 'occupancy'),
|
||||
# ('state', '=', 'open'),
|
||||
# ], order=[('room.code', 'ASC')])
|
||||
#
|
||||
# total_guests = []
|
||||
# rooms_occupied = []
|
||||
# for op in operations:
|
||||
# total_guests.append(len(op.guests))
|
||||
# rooms_occupied.append(op.room.id)
|
||||
#
|
||||
# rooms = Room.search_read([])
|
||||
#
|
||||
# _rooms_occupied = len(set(rooms_occupied))
|
||||
# num_rooms = len(rooms)
|
||||
# if num_rooms:
|
||||
# occupancy_rate = round(_rooms_occupied / num_rooms, 2)
|
||||
# else:
|
||||
# occupancy_rate = 0
|
||||
#
|
||||
# operations_ = []
|
||||
# for op in operations:
|
||||
# for guest in op.guests:
|
||||
# operations_.append({
|
||||
# 'room': op.room.code,
|
||||
# 'guest': guest.party.name,
|
||||
# 'party': op.party.code,
|
||||
# 'start_date': op.start_date,
|
||||
# 'end_date': op.end_date,
|
||||
# 'nights_quantity': op.nights_quantity,
|
||||
# })
|
||||
# report_context['records'] = operations_
|
||||
# report_context['total_rooms'] = _rooms_occupied
|
||||
# report_context['total_guests'] = sum(total_guests)
|
||||
# report_context['occupancy_rate'] = occupancy_rate
|
||||
# report_context['company'] = Company(data['company']).party.name
|
||||
# report_context['date'] = data['date']
|
||||
# report_context['print_date'] = datetime.now()
|
||||
# report_context['user'] = user.name
|
||||
return report_context
|
||||
|
||||
|
||||
class RoomsOccupancyStart(ModelView):
|
||||
'Rooms Occupancy Start'
|
||||
__name__ = 'hotel.print_rooms_occupancy.start'
|
||||
|
|
Binary file not shown.
286
folio.py
286
folio.py
|
@ -7,7 +7,8 @@ from trytond.model import ModelView, Workflow, ModelSQL, fields
|
|||
from trytond.pyson import Eval, Bool
|
||||
from trytond.pool import Pool
|
||||
from trytond.report import Report
|
||||
from trytond.wizard import Wizard, StateView, StateAction, Button, StateTransition
|
||||
from trytond.wizard import (Wizard, StateView, StateAction,
|
||||
Button, StateTransition, StateReport)
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.model.exceptions import AccessError
|
||||
from trytond.exceptions import UserError
|
||||
|
@ -91,7 +92,7 @@ class Folio(ModelSQL, ModelView):
|
|||
digits=(16, 2)), 'get_total_amount')
|
||||
total_commission = fields.Function(fields.Numeric('Channel Commission',
|
||||
digits=(16, 2)), 'get_channel_commission')
|
||||
guests = fields.One2Many('hotel.booking.guest', 'booking_line', 'Guests',
|
||||
guests = fields.One2Many('hotel.folio.guest', 'folio', 'Guests',
|
||||
states={'readonly': ~Eval('registration_state').in_(['check_in'])})
|
||||
nationality = fields.Many2One('party.nationality', 'Nationality',
|
||||
states=STATES_CHECKIN)
|
||||
|
@ -118,9 +119,10 @@ class Folio(ModelSQL, ModelView):
|
|||
'invisible': ~Bool(Eval('complementary')),
|
||||
'required': Bool(Eval('complementary')),
|
||||
})
|
||||
breakfast_included = fields.Boolean('Breakfast Included')
|
||||
room_amount = fields.Function(fields.Numeric('Room Amount',
|
||||
digits=(16, 2)), 'get_room_amount')
|
||||
stock_moves = fields.Many2Many('hotel.operation-stock.move', 'operation',
|
||||
stock_moves = fields.Many2Many('hotel.folio-stock.move', 'folio',
|
||||
'move', 'Stock Moves', states={'readonly': True})
|
||||
|
||||
@classmethod
|
||||
|
@ -161,12 +163,6 @@ class Folio(ModelSQL, ModelView):
|
|||
@classmethod
|
||||
@ModelView.button
|
||||
def check_in(cls, records):
|
||||
config_party = Pool().get('party.configuration')(1)
|
||||
validate_party = config_party.validate_party
|
||||
if not validate_party:
|
||||
config_party.validate_party = True
|
||||
config_party.save()
|
||||
|
||||
for rec in records:
|
||||
# rec.booking.party.pre_validate()
|
||||
if rec.booking.state == 'offer':
|
||||
|
@ -177,18 +173,7 @@ class Folio(ModelSQL, ModelView):
|
|||
raise UserError(gettext('hotel.msg_missing_select_room'))
|
||||
rec.set_registration_number()
|
||||
rec.booking.check_rooms()
|
||||
|
||||
cls.write(records, {'registration_state': 'check_in'})
|
||||
# change_state = all(
|
||||
# [rl.registration_state == 'check_in' for rl in booking.lines]
|
||||
# )
|
||||
# print('change_state..', change_state)
|
||||
# if change_state:
|
||||
# booking.registration_state = 'check_in'
|
||||
# booking.save()
|
||||
if config_party.validate_party != validate_party:
|
||||
config_party.validate_party = validate_party
|
||||
config_party.save()
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
|
@ -375,10 +360,13 @@ class Folio(ModelSQL, ModelView):
|
|||
def default_accommodation():
|
||||
Configuration = Pool().get('hotel.configuration')
|
||||
configuration = Configuration.get_configuration()
|
||||
|
||||
if configuration.default_accommodation:
|
||||
return configuration.default_accommodation.id
|
||||
|
||||
@staticmethod
|
||||
def default_breakfast_included():
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def validate(cls, lines):
|
||||
super(Folio, cls).validate(lines)
|
||||
|
@ -694,6 +682,145 @@ class Folio(ModelSQL, ModelView):
|
|||
)
|
||||
|
||||
|
||||
class FolioGuest(ModelSQL, ModelView):
|
||||
'Folio Guest'
|
||||
__name__ = 'hotel.folio.guest'
|
||||
_rec_name = 'party'
|
||||
folio = fields.Many2One('hotel.folio', 'Booking Line', required=True,
|
||||
ondelete='CASCADE')
|
||||
party = fields.Many2One('party.party', 'Party', required=False)
|
||||
type_guest = fields.Selection([
|
||||
('adult', 'Adult'),
|
||||
('child', 'Child'),
|
||||
], 'Type Guest')
|
||||
type_guest_string = type_guest.translated('type_guest')
|
||||
nationality = fields.Many2One('party.nationality', 'Nationality')
|
||||
origin_country = fields.Many2One('party.nationality', 'Origin Country',
|
||||
select=True)
|
||||
target_country = fields.Many2One('party.nationality', 'Target Country',
|
||||
select=True)
|
||||
# New fields for speed reason
|
||||
type_document = fields.Selection([
|
||||
('12', 'Tarjeta de Identidad'),
|
||||
('13', 'Cedula de Ciudadania'),
|
||||
('21', 'Tarjeta de Extranjeria'),
|
||||
('22', 'Cedula de Extranjeria'),
|
||||
('41', 'Pasaporte'),
|
||||
], 'Document Type')
|
||||
doc_number = fields.Char('Doc. Id', select=True)
|
||||
name = fields.Char('Name', select=True)
|
||||
mobile = fields.Char('Mobile', select=True)
|
||||
email = fields.Char('Email', select=True)
|
||||
birthday = fields.Date('Birthday', select=True)
|
||||
sex = fields.Selection([
|
||||
('female', 'Female'),
|
||||
('male', 'Male'),
|
||||
('', ''),
|
||||
], 'Sex')
|
||||
first_name = fields.Char('First Name')
|
||||
second_name = fields.Char('Second Name')
|
||||
first_family_name = fields.Char('First Family Name')
|
||||
second_family_name = fields.Char('Second Family Name')
|
||||
type_person = fields.Selection([
|
||||
('persona_natural', 'Persona Natural'),
|
||||
('persona_juridica', 'Persona Juridica'),
|
||||
], 'Type Person')
|
||||
|
||||
@fields.depends('name', 'first_name', 'second_name',
|
||||
'first_family_name', 'second_family_name', 'type_person')
|
||||
def on_change_name(self):
|
||||
second_family_name = None
|
||||
first_family_name = None
|
||||
second_name = None
|
||||
first_name = None
|
||||
if self.name and self.type_person == 'persona_natural':
|
||||
names = self.name.split(' ')
|
||||
first_name = names[0]
|
||||
second_family_name = names[-1]
|
||||
if len(names) > 1:
|
||||
first_family_name = names[-2]
|
||||
if len(names) == 2:
|
||||
second_family_name = None
|
||||
first_family_name = names[1]
|
||||
elif len(names) == 5:
|
||||
second_name = names[1] + ' ' + names[2]
|
||||
elif len(names) == 4:
|
||||
second_name = names[1]
|
||||
|
||||
self.second_family_name = second_family_name
|
||||
self.first_family_name = first_family_name
|
||||
self.second_name = second_name
|
||||
self.first_name = first_name
|
||||
|
||||
def get_rec_name(self, name):
|
||||
if self.party:
|
||||
return self.party.name
|
||||
|
||||
@staticmethod
|
||||
def default_type_guest():
|
||||
return 'adult'
|
||||
|
||||
@staticmethod
|
||||
def default_sex():
|
||||
return 'male'
|
||||
|
||||
@staticmethod
|
||||
def default_type_person():
|
||||
return 'persona_natural'
|
||||
|
||||
@staticmethod
|
||||
def default_type_document():
|
||||
return '13'
|
||||
|
||||
@staticmethod
|
||||
def default_principal_guest():
|
||||
return False
|
||||
|
||||
@fields.depends('nationality', 'origin_country', 'target_country')
|
||||
def on_change_nationality(self):
|
||||
if self.nationality:
|
||||
self.target_country = self.nationality.id
|
||||
self.origin_country = self.nationality.id
|
||||
|
||||
@classmethod
|
||||
def create(cls, vlist):
|
||||
Party = Pool().get('party.party')
|
||||
new_values = []
|
||||
for v in vlist:
|
||||
# if not v.get('doc_number'):
|
||||
# continue
|
||||
party = v.get('party')
|
||||
if not party:
|
||||
parties = Party.search([
|
||||
('id_number', '=', v['doc_number']),
|
||||
])
|
||||
if parties:
|
||||
party = parties[0]
|
||||
else:
|
||||
party, = Party.create([{
|
||||
'name': v['name'],
|
||||
'id_number': v['doc_number'],
|
||||
'type_document': v['type_document'],
|
||||
'birthday': v['birthday'],
|
||||
'sex': v['sex'],
|
||||
'first_name': v['first_name'],
|
||||
'second_name': v['second_name'],
|
||||
'first_family_name': v['first_family_name'],
|
||||
'second_family_name': v['second_family_name'],
|
||||
'type_person': v['type_person'],
|
||||
'contact_mechanisms': [
|
||||
('create', [
|
||||
{'type': 'email', 'value': v['email']},
|
||||
{'type': 'mobile', 'value': v['mobile']},
|
||||
])
|
||||
]
|
||||
}])
|
||||
v['party'] = party.id
|
||||
new_values.append(v)
|
||||
|
||||
super(FolioGuest, cls).create(new_values)
|
||||
|
||||
|
||||
class HotelCharge(Workflow, ModelSQL, ModelView):
|
||||
'Hotel Charge'
|
||||
__name__ = 'hotel.charge'
|
||||
|
@ -1629,6 +1756,16 @@ class OperationVoucher(ModelSQL):
|
|||
}])
|
||||
|
||||
|
||||
class FolioStockMove(ModelSQL):
|
||||
'Folio - Stock Move'
|
||||
__name__ = 'hotel.folio-stock.move'
|
||||
_table = 'hotel_folio_stock_move_rel'
|
||||
folio = fields.Many2One('hotel.folio', 'Folio',
|
||||
ondelete='CASCADE', select=True, required=True)
|
||||
move = fields.Many2One('stock.move', 'Move', select=True,
|
||||
ondelete='RESTRICT', required=True)
|
||||
|
||||
|
||||
class StatisticsByMonthStart(ModelView):
|
||||
'Statistics By Month Start'
|
||||
__name__ = 'hotel.statistics_by_month.start'
|
||||
|
@ -1857,3 +1994,110 @@ class StatisticsByMonthReport(Report):
|
|||
report_context['reason_other'] = sum(reason_other)
|
||||
|
||||
return report_context
|
||||
|
||||
|
||||
class GuestsListStart(ModelView):
|
||||
'Guests List Start'
|
||||
__name__ = 'hotel.print_guests_list.start'
|
||||
date = fields.Date('Date', required=True)
|
||||
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 GuestsList(Wizard):
|
||||
'Guests List'
|
||||
__name__ = 'hotel.print_guests_list'
|
||||
start = StateView('hotel.print_guests_list.start',
|
||||
'hotel.print_guests_list_start_view_form', [
|
||||
Button('Cancel', 'end', 'tryton-cancel'),
|
||||
Button('Open', 'print_', 'tryton-print', default=True),
|
||||
])
|
||||
print_ = StateReport('hotel.guests_list.report')
|
||||
|
||||
def do_print_(self, action):
|
||||
company = self.start.company
|
||||
data = {
|
||||
'date': self.start.date,
|
||||
'company': company.id,
|
||||
}
|
||||
return action, data
|
||||
|
||||
def transition_print_(self):
|
||||
return 'end'
|
||||
|
||||
|
||||
class GuestsListReport(Report):
|
||||
__name__ = 'hotel.guests_list.report'
|
||||
|
||||
@classmethod
|
||||
def get_context(cls, records, header, data):
|
||||
report_context = super().get_context(records, header, data)
|
||||
pool = Pool()
|
||||
Company = pool.get('company.company')
|
||||
# Operation = pool.get('hotel.operation')
|
||||
Room = pool.get('hotel.room')
|
||||
User = pool.get('res.user')
|
||||
user_id = Transaction().user
|
||||
|
||||
user = User(user_id)
|
||||
start_date = data['date']
|
||||
# operations = Operation.search([
|
||||
# ('start_date', '<=', start_date),
|
||||
# ('kind', '=', 'occupancy'),
|
||||
# ('state', '=', 'open'),
|
||||
# ], order=[('room.code', 'ASC')])
|
||||
#
|
||||
# total_guests = []
|
||||
# rooms_occupied = []
|
||||
# for op in operations:
|
||||
# total_guests.append(len(op.guests))
|
||||
# rooms_occupied.append(op.room.id)
|
||||
#
|
||||
# rooms = Room.search_read([])
|
||||
#
|
||||
# _rooms_occupied = len(set(rooms_occupied))
|
||||
# num_rooms = len(rooms)
|
||||
# if num_rooms:
|
||||
# occupancy_rate = round(_rooms_occupied / num_rooms, 2)
|
||||
# else:
|
||||
# occupancy_rate = 0
|
||||
#
|
||||
# operations_ = []
|
||||
# for op in operations:
|
||||
# for guest in op.guests:
|
||||
# operations_.append({
|
||||
# 'room': op.room.code,
|
||||
# 'guest': guest.party.name,
|
||||
# 'party': op.party.code,
|
||||
# 'start_date': op.start_date,
|
||||
# 'end_date': op.end_date,
|
||||
# 'nights_quantity': op.nights_quantity,
|
||||
# })
|
||||
# report_context['records'] = operations_
|
||||
# report_context['total_rooms'] = _rooms_occupied
|
||||
# report_context['total_guests'] = sum(total_guests)
|
||||
# report_context['occupancy_rate'] = occupancy_rate
|
||||
# report_context['company'] = Company(data['company']).party.name
|
||||
# report_context['date'] = data['date']
|
||||
# report_context['print_date'] = datetime.now()
|
||||
# report_context['user'] = user.name
|
||||
return report_context
|
||||
|
||||
|
||||
class RegistrationCardReport(Report):
|
||||
__name__ = 'hotel.folio.registration_card'
|
||||
|
||||
@classmethod
|
||||
def get_context(cls, records, header, data):
|
||||
report_context = super().get_context(records, header, data)
|
||||
user = Pool().get('res.user')(Transaction().user)
|
||||
report_context['company'] = user.company
|
||||
return report_context
|
||||
|
|
Binary file not shown.
12
sale.xml
12
sale.xml
|
@ -22,17 +22,5 @@ The COPYRIGHT file at the top level of this repository contains the full copyrig
|
|||
<menuitem parent="hotel.menu_reporting" id="menu_invoice_income_daily"
|
||||
action="wizard_print_invoice_income_daily"/>
|
||||
|
||||
<!-- <record model="ir.action.report" id="report_invoice_simplified">
|
||||
<field name="name">Invoice Simplified</field>
|
||||
<field name="model">account.invoice</field>
|
||||
<field name="report_name">account.invoice_simplified</field>
|
||||
<field name="report">hotel/invoice_simplified.fodt</field>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_invoice_simplified_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">account.invoice,-1</field>
|
||||
<field name="action" ref="report_invoice_simplified"/>
|
||||
</record> -->
|
||||
|
||||
</data>
|
||||
</tryton>
|
||||
|
|
86
service.py
86
service.py
|
@ -7,7 +7,7 @@ from trytond.pyson import Eval, In, If, Get
|
|||
from trytond.modules.company import CompanyReport
|
||||
from trytond.wizard import Wizard, StateView, Button, StateTransition
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.model.exceptions import AccessError
|
||||
from trytond.exceptions import UserError
|
||||
from trytond.i18n import gettext
|
||||
|
||||
STATES = {
|
||||
|
@ -141,33 +141,32 @@ class ServiceLine(Workflow, ModelSQL, ModelView):
|
|||
'Service Line'
|
||||
__name__ = 'hotel.service.line'
|
||||
service = fields.Many2One('hotel.service', 'Service', required=True)
|
||||
room = fields.Many2One('hotel.room', 'Room', select=True, required=True, states=STATES_LINE)
|
||||
room = fields.Many2One('hotel.room', 'Room', select=True, required=True,
|
||||
states=STATES_LINE)
|
||||
time_service = fields.Time('Time Service', select=True, states=STATES_LINE)
|
||||
product = fields.Many2One('product.product', 'Product',
|
||||
domain=[
|
||||
('salable', '=', True),
|
||||
('active', '=', True),
|
||||
], required=True)
|
||||
# ('template.kind', '!=', 'accommodation'),
|
||||
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)
|
||||
sale_line = fields.Many2One('sale.line', 'Sale Line', states={
|
||||
'readonly': True,
|
||||
})
|
||||
# guest = fields.Many2One('hotel.folio.guest', 'Guest', states=STATES_LINE,
|
||||
# domain=[
|
||||
# # ('operation.room', '=', Eval('room')),
|
||||
# # # ('operation.start_date', '<=', Eval('')),
|
||||
# # ('id', 'in', Eval('current_guests')),
|
||||
# ], depends=['current_guests'])
|
||||
operation_line = fields.Many2One('hotel.folio.charge', 'Operation Line',
|
||||
invoice_line = fields.Many2One('account.invoice.line', 'Invoice Line',
|
||||
states={'readonly': True})
|
||||
guest = fields.Many2One('hotel.folio.guest', 'Guest', states=STATES_LINE,
|
||||
domain=[
|
||||
('folio.room', '=', Eval('room')),
|
||||
# ('operation.start_date', '<=', Eval('')),
|
||||
('id', 'in', Eval('current_guests')),
|
||||
], depends=['current_guests'])
|
||||
charge = fields.Many2One('hotel.folio.charge', 'Operation Line',
|
||||
states={'readonly': True})
|
||||
current_guests = fields.Function(fields.Many2Many(
|
||||
'hotel.operation.guest', None, None, 'Current Guests'),
|
||||
'hotel.folio.guest', None, None, 'Current Guests'),
|
||||
'on_change_with_current_guests')
|
||||
operation = fields.Function(fields.Many2One('hotel.operation',
|
||||
'Operation'), 'get_operation')
|
||||
folio = fields.Function(fields.Many2One('hotel.folio',
|
||||
'Folio'), 'get_folio')
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('loaded', 'Loaded'),
|
||||
|
@ -237,9 +236,9 @@ class ServiceLine(Workflow, ModelSQL, ModelView):
|
|||
|
||||
@fields.depends('room')
|
||||
def on_change_with_current_guests(self, name=None):
|
||||
Operation = Pool().get('hotel.operation')
|
||||
Folio = Pool().get('hotel.folio')
|
||||
if self.room:
|
||||
operations = Operation.search([
|
||||
operations = Folio.search([
|
||||
('room', '=', self.room.id),
|
||||
('state', '=', 'check_in'),
|
||||
])
|
||||
|
@ -249,15 +248,15 @@ class ServiceLine(Workflow, ModelSQL, ModelView):
|
|||
|
||||
return guests
|
||||
|
||||
def get_operation(self, name=None):
|
||||
if self.operation_line:
|
||||
return self.operation_line.operation.id
|
||||
def get_folio(self, name=None):
|
||||
if self.folio_line:
|
||||
return self.folio_line.folio.id
|
||||
|
||||
def add_product_to_room(self):
|
||||
pool = Pool()
|
||||
Operation = pool.get('hotel.operation')
|
||||
Folio = pool.get('hotel.folio')
|
||||
FolioCharge = pool.get('hotel.folio.charge')
|
||||
if self.sale_line:
|
||||
if self.invoice_line:
|
||||
return
|
||||
|
||||
dom = [
|
||||
|
@ -269,27 +268,31 @@ class ServiceLine(Workflow, ModelSQL, ModelView):
|
|||
if self.guest:
|
||||
dom.append(('guests', '=', self.guest.id))
|
||||
|
||||
operations = Operation.search(dom)
|
||||
if not operations:
|
||||
raise AccessError(gettext('hotel.msg_room_not_occupied', s=self.room.name))
|
||||
elif len(operations) > 1:
|
||||
raise AccessError(gettext('hotel.msg_multiple_rooms_active', s=self.room.name))
|
||||
folios = Folio.search(dom)
|
||||
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)
|
||||
)
|
||||
|
||||
operation = operations[0]
|
||||
folio = folios[0]
|
||||
new_line = {
|
||||
'operation': operation.id,
|
||||
'operation': folio.id,
|
||||
'date_service': self.service.service_date,
|
||||
'order': self.order,
|
||||
'description': self.description,
|
||||
# FIXME: not use int
|
||||
'quantity': int(self.quantity),
|
||||
'invoice_to': operation.main_guest.id,
|
||||
'invoice_to': folio.main_guest.id,
|
||||
'unit_price': self.product.template.list_price,
|
||||
'product': self.product.id,
|
||||
}
|
||||
# FIXME: not use int
|
||||
|
||||
line, = FolioCharge.create([new_line])
|
||||
self.write([self], {'operation_line': line.id})
|
||||
self.write([self], {'charge': line.id})
|
||||
|
||||
|
||||
class ServiceReport(CompanyReport):
|
||||
|
@ -331,15 +334,14 @@ class CreateDailyServices(Wizard):
|
|||
def transition_accept_(self):
|
||||
pool = Pool()
|
||||
Service = pool.get('hotel.service')
|
||||
Operation = pool.get('hotel.operation')
|
||||
Folio = pool.get('hotel.folio')
|
||||
|
||||
operations = Operation.search([
|
||||
('start_date', '<', self.start.date),
|
||||
('state', 'in', ['open']),
|
||||
folios = Folio.search([
|
||||
('arrival_date', '<', self.start.date),
|
||||
('registration_state', 'in', ['check_in', 'check_out']),
|
||||
])
|
||||
|
||||
lines_to_create = []
|
||||
|
||||
service, = Service.create([{
|
||||
'service_date': self.start.date,
|
||||
'state': 'draft',
|
||||
|
@ -347,13 +349,13 @@ class CreateDailyServices(Wizard):
|
|||
}])
|
||||
Service.open([service])
|
||||
product = self.start.kind.product
|
||||
for op in operations:
|
||||
if not op.breakfast_included:
|
||||
for fol in folios:
|
||||
if not fol.breakfast_included:
|
||||
continue
|
||||
for guest in op.guests:
|
||||
for guest in fol.guests:
|
||||
lines_to_create.append({
|
||||
'service': service.id,
|
||||
'room': op.room.id,
|
||||
'room': fol.room.id,
|
||||
'guest': guest.id,
|
||||
'product': product.id,
|
||||
'quantity': 1,
|
||||
|
|
|
@ -22,10 +22,10 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<field name="unit_price"/>
|
||||
<label name="party"/>
|
||||
<field name="party"/>
|
||||
<label name="invoice"/>
|
||||
<field name="invoice"/>
|
||||
<label name="host_quantity"/>
|
||||
<field name="host_quantity"/>
|
||||
<label name="breakfast_included"/>
|
||||
<field name="breakfast_included"/>
|
||||
<notebook colspan="6">
|
||||
<page string="Charges" id="hotel_charges">
|
||||
<field name="charges" colspan="4"/>
|
||||
|
@ -47,13 +47,15 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<field name="total_commission"/>
|
||||
<label name="invoice_line"/>
|
||||
<field name="invoice_line"/>
|
||||
<label name="invoice_state"/>
|
||||
<field name="invoice_state"/>
|
||||
<separator name="notes" colspan="4"/>
|
||||
<field name="notes" colspan="4"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<group col="7" colspan="4" id="state_buttons">
|
||||
<group col="6" colspan="6" id="state_buttons">
|
||||
<label name="invoice"/>
|
||||
<field name="invoice"/>
|
||||
<label name="invoice_state"/>
|
||||
<field name="invoice_state"/>
|
||||
<label name="total_amount"/>
|
||||
<field name="total_amount"/>
|
||||
<label name="registration_state"/>
|
||||
|
@ -61,5 +63,6 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<button name="check_in" string="Check In"/>
|
||||
<button name="check_out" string="Check Out"/>
|
||||
<button name="bill" string="Bill"/>
|
||||
<!-- <button name="pay" string="Pay"/> -->
|
||||
</group>
|
||||
</form>
|
||||
|
|
|
@ -20,8 +20,8 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<field name="total_amount"/>
|
||||
<label name="host_quantity"/>
|
||||
<field name="host_quantity"/>
|
||||
<label name="invoice"/>
|
||||
<field name="invoice"/>
|
||||
<label name="breakfast_included"/>
|
||||
<field name="breakfast_included"/>
|
||||
<notebook colspan="6">
|
||||
<page string="Charges" id="hotel_charges">
|
||||
<field name="charges" colspan="4"/>
|
||||
|
@ -44,8 +44,11 @@ this repository contains the full copyright notices and license terms. -->
|
|||
</notebook>
|
||||
<label name="registration_state"/>
|
||||
<field name="registration_state"/>
|
||||
<group col="2" colspan="2" id="state_buttons">
|
||||
<button name="bill" string="Bill" icon="tryton-forward"/>
|
||||
</group>
|
||||
<label name="invoice"/>
|
||||
<field name="invoice"/>
|
||||
<label name="invoice_state"/>
|
||||
<field name="invoice_state"/>
|
||||
<button name="bill" string="Bill"
|
||||
icon="tryton-forward"/>
|
||||
</form>
|
||||
|
|
|
@ -12,8 +12,8 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<field name="quantity"/>
|
||||
<label name="order"/>
|
||||
<field name="order"/>
|
||||
<label name="sale_line"/>
|
||||
<field name="sale_line"/>
|
||||
<label name="invoice_line"/>
|
||||
<field name="invoice_line"/>
|
||||
<label name="description"/>
|
||||
<field name="description"/>
|
||||
<label name="state"/>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
this repository contains the full copyright notices and license terms. -->
|
||||
<tree editable="1">
|
||||
<field name="room" widget="selection"/>
|
||||
<!-- <field name="guest" widget="selection"/> -->
|
||||
<field name="guest" widget="selection"/>
|
||||
<field name="time_service"/>
|
||||
<field name="product"/>
|
||||
<button name="load" string="Load"/>
|
||||
|
@ -11,6 +11,6 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<field name="description"/>
|
||||
<field name="order"/>
|
||||
<field name="state"/>
|
||||
<field name="operation"/>
|
||||
<field name="sale_line"/>
|
||||
<field name="folio"/>
|
||||
<field name="invoice_line"/>
|
||||
</tree>
|
||||
|
|
Loading…
Reference in New Issue