Merge branch 'multihotel' of https://github.com/hootel/hootel into multihotel

This commit is contained in:
Dario Lodeiros
2019-09-24 19:11:28 +02:00
20 changed files with 145 additions and 217 deletions

View File

@@ -1,18 +1,29 @@
# HOOTEL PROJECT MODULES [![Build Status](https://travis-ci.org/hootel/hootel.svg?branch=11.0)](https://travis-ci.org/hootel/hootel) [![codecov](https://codecov.io/gh/hootel/hootel/branch/11.0/graph/badge.svg)](https://codecov.io/gh/hootel/hootel) ![Unstable](https://img.shields.io/badge/stability-unstable-yellow.svg)
[![Build Status](https://travis-ci.org/hootel/hootel.svg?branch=11.0)](https://travis-ci.org/hootel/hootel) [![codecov](https://codecov.io/gh/hootel/hootel/branch/11.0/graph/badge.svg)](https://codecov.io/gh/hootel/hootel) ![Unstable](https://img.shields.io/badge/stability-unstable-yellow.svg)
# ROOMDOO
All-in-One Property Management System (PMS) focused on medium-sized hotels for managing every aspect of your property's daily operations.
**IMPORTANT:**
- Set time zone of users that use the calendar
You will find modules for:
**MODULES:**
- [ ] hotel: Base module (Manage Rooms, Reservations, Services, Customers, Mailing, Invoicing, ...)
- [ ] hotel_calendar: Adds calendar for manage hotel reservations and rooms configuration
- [ ] hotel_calendar_channel_connector: Unify 'hotel_channel_connector' and 'hotel_calendar' modules
- [ ] hotel_channel_connector: Base Channel Connector (Using Odoo Connector)
- [ ] hotel_channel_connector_wubook: Wubook API Implementation
- [ ] hotel_node_helper: Configure a node as a helper to serve and get information from a master one
- [ ] hotel_node_master: Configure a node as a master
- Manage hotel properties with multi-hotel and multi-company support.
- Manage your rooms inventory, reservations, check-in, daily reports, board services, rate and restriction plans.
- Handle reservations in a user friendly calendar management view.
- Connect your hotel with a channel manager for booking though Online Travel Agencies, such as, Booking.com, Expedia, Hotelbeds, ...
- Revenue management tools for daily pricing and availability strategies.
**HOW WORKS?**
- The idea is... the hotel sell 'rooms types' and the customer is assigned to one 'real room'.
- The folio have all reservation lines, used services, etc..
Installation
------------
To install this module, you need to:
Configuration
-------------
To configure this module, you need to:
Usage
-----
To use this module, you need to:
Contributing
------------
Do you want to contribute? Please, do not hesitate to contact any of the current contributors :)

View File

@@ -1,53 +1,21 @@
hotel
This Module is for Providing Hotel management Features.
You can manage:
-Hotel Booking,
-Hotel Facilities and Amenities,
-RESTURANTS,
-Currency Exchange,
-REPORTS
-Different reports are also provided, mainly for hotel.
roomdoo :: hotel
----------------
This Module is for providing the core PMS capabilities.
Installation
------------
To install this module, you need to:
install 'product_uos', 'sale_stock', 'point_of_sale', 'report' modules
Configuration
To configure this module, you need to:
have a Hotel management functionality.
Usage
-----
To use this module, you need to:
go to apps, then install module to apply this functionality.
Try me on Runbot
Known issues / Roadmap
...
Bug Tracker
-----------
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed feedback here.
Credits
Contributors
Serpent Consulting Services PVT. LTD. <http://serpentcs.com>
Maintainer
Serpent Consulting Services PVT. LTD.
This module is maintained by the SerpentCS.
To contribute to this module, please visit https://github.com/JayVora-SerpentCS/hotelmgmt_v8.
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed feedback here.

View File

@@ -1,17 +1,20 @@
# -*- coding: utf-8 -*-
# Copyright 2018 Alexandre Díaz
# Copyright 2019 Darío Lodeiros, Alexandre Díaz, Jose Luis Algara, Pablo Quesada
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Hotel Management',
'name': 'roomdoo',
'summary': "A property management system focused on medium-sized hotels",
'version': '11.0.2.0.0',
'author': 'Odoo Community Association (OCA),\
Darío Lodeiros,\
Jose Luis Algara,\
Alexandre Díaz,\
Pablo Quesada,',
'development_status': 'Beta',
'category': 'Generic Modules/Hotel Management',
'website': 'https://github.com/hootel/hootel',
'author': 'Darío Lodeiros, '
'Alexandre Díaz, '
'Jose Luis Algara, '
'Pablo Quesada ',
'license': "AGPL-3",
'application': False,
'installable': True,
'depends': [
'base',
'sale_stock',
@@ -19,56 +22,57 @@
'partner_firstname',
'account_cancel'
],
'license': "AGPL-3",
'demo': ['demo/hotel_demo.xml'],
'data': [
'data/hotel_data.xml',
'security/hotel_security.xml',
'security/ir.model.access.csv',
'wizard/massive_changes.xml',
'wizard/split_reservation.xml',
'wizard/service_on_day.xml',
'data/menus.xml',
'views/inherited_account_payment_views.xml',
'views/inherited_account_invoice_views.xml',
'wizard/massive_price_reservation_days.xml',
'wizard/folio_make_invoice_advance_views.xml',
'data/hotel_sequence.xml',
'views/inherited_res_users_views.xml',
'views/hotel_property_views.xml',
'views/hotel_floor_views.xml',
'views/hotel_folio_views.xml',
'views/inherited_res_partner_views.xml',
'views/hotel_room_type_views.xml',
'views/hotel_room_views.xml',
'views/hotel_shared_room_views.xml',
'views/hotel_room_type_class_views.xml',
'views/general.xml',
'views/inherited_product_template_views.xml',
'views/inherited_product_pricelist_views.xml',
'views/hotel_room_amenities_type_views.xml',
'views/hotel_room_amenities_views.xml',
'views/hotel_room_type_restriction_views.xml',
'views/hotel_room_type_restriction_item_views.xml',
'views/hotel_reservation_views.xml',
'views/hotel_room_closure_reason_views.xml',
'views/hotel_service_views.xml',
'views/hotel_service_line_views.xml',
'views/hotel_board_service_views.xml',
'views/hotel_checkin_partner_views.xml',
'views/hotel_board_service_room_type_views.xml',
'views/hotel_cancelation_rule_views.xml',
'views/inherited_webclient_templates.xml',
'data/cron_jobs.xml',
'data/email_template_cancel.xml',
'data/email_template_reserv.xml',
'data/email_template_exit.xml',
'wizard/wizard_reservation.xml',
'report/hotel_folio_templates.xml',
'data/menus.xml',
'data/hotel_data.xml',
'data/hotel_sequence.xml',
'report/hotel_folio.xml'
'report/hotel_folio_templates.xml',
'security/hotel_security.xml',
'security/ir.model.access.csv',
'views/general.xml',
'views/hotel_amenity_views.xml',
'views/hotel_amenity_type_views.xml',
'views/hotel_board_service_views.xml',
'views/hotel_board_service_room_type_views.xml',
'views/hotel_cancelation_rule_views.xml',
'views/hotel_checkin_partner_views.xml',
'views/hotel_floor_views.xml',
'views/hotel_folio_views.xml',
'views/hotel_property_views.xml',
'views/hotel_reservation_views.xml',
'views/hotel_room_views.xml',
'views/hotel_room_closure_reason_views.xml',
'views/inherited_account_payment_views.xml',
'views/inherited_account_invoice_views.xml',
'views/inherited_res_users_views.xml',
'views/hotel_room_type_views.xml',
'views/hotel_room_type_class_views.xml',
'views/hotel_room_type_restriction_views.xml',
'views/hotel_room_type_restriction_item_views.xml',
'views/hotel_service_views.xml',
'views/hotel_service_line_views.xml',
'views/hotel_shared_room_views.xml',
'views/inherited_res_partner_views.xml',
'views/inherited_product_pricelist_views.xml',
'views/inherited_product_template_views.xml',
'views/inherited_webclient_templates.xml',
'wizard/folio_make_invoice_advance_views.xml',
'wizard/massive_changes.xml',
'wizard/massive_price_reservation_days.xml',
'wizard/service_on_day.xml',
'wizard/split_reservation.xml',
'wizard/wizard_reservation.xml',
],
'demo': [
'demo/hotel_demo.xml'
],
'qweb': [
'static/src/xml/*.xml',
],
'installable': True
}

View File

@@ -8,7 +8,6 @@ from . import inherited_hotel_reservation
from . import inherited_res_company
from . import inherited_res_users
from . import inherited_hotel_room_type_restriction_item
from . import inherited_product_pricelist
from . import inherited_product_pricelist_item
from . import inherited_hotel_folio
from . import ir_actions_act_window_view

View File

@@ -1,8 +1,6 @@
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, api, _, fields
from odoo.exceptions import ValidationError
from odoo import models, fields, api
class HotelCalendar(models.Model):

View File

@@ -6,7 +6,7 @@ from odoo import models, api, _
class HotelFolio(models.Model):
_inherit = 'hotel.folio'
# CRUD methods
# ORM overrides
@api.multi
def write(self, vals):
ret = super(HotelFolio, self).write(vals)

View File

@@ -6,6 +6,7 @@ from odoo import models, fields
class HotelProperty(models.Model):
_inherit = 'hotel.property'
# Fields declaration
pms_show_num_rooms = fields.Integer('Number of rooms to show',
default=0)
pms_divide_rooms_by_capacity = fields.Boolean('Divide rooms by capacity',

View File

@@ -18,7 +18,7 @@ class HotelReservation(models.Model):
reserve_color_text = fields.Char(compute='_compute_color', string='Color',
store=True)
# Business methods
# TODO: Add the following method into _compute_color
@api.multi
def _generate_color(self):
self.ensure_one()
@@ -58,6 +58,7 @@ class HotelReservation(models.Model):
reserv_color_text = company_id.color_letter_payment_pending
return reserv_color, reserv_color_text
# Constraints and onchanges
@api.depends('state', 'reservation_type', 'folio_id.pending_amount', 'to_assign')
def _compute_color(self):
for record in self:
@@ -67,24 +68,30 @@ class HotelReservation(models.Model):
'reserve_color_text': colors[1],
})
# ORM overrides
@api.model
def get_hcalendar_settings(self):
type_move = self.env.user.hotel_id.pms_type_move
return {
'divide_rooms_by_capacity': self.env.user.hotel_id.pms_divide_rooms_by_capacity,
'eday_week': self.env.user.hotel_id.pms_end_day_week,
'eday_week_offset': self.env.user.hotel_id.pms_end_day_week_offset,
'days': self.env.user.hotel_id.pms_default_num_days,
'allow_invalid_actions': type_move == 'allow_invalid',
'assisted_movement': type_move == 'assisted',
'default_arrival_hour': self.env.user.hotel_id.default_arrival_hour,
'default_departure_hour': self.env.user.hotel_id.default_departure_hour,
'show_notifications': self.env.user.pms_show_notifications,
'show_pricelist': self.env.user.pms_show_pricelist,
'show_availability': self.env.user.pms_show_availability,
'show_num_rooms': self.env.user.hotel_id.pms_show_num_rooms,
}
def create(self, vals):
reservation_id = super(HotelReservation, self).create(vals)
reservation_id.send_bus_notification('create',
'notify',
_("Reservation Created"))
return reservation_id
@api.multi
def write(self, vals):
_logger.info("RESERV WRITE")
ret = super(HotelReservation, self).write(vals)
self.send_bus_notification('write', 'noshow')
return ret
@api.multi
def unlink(self):
self.send_bus_notification('unlink',
'warn',
_("Reservation Deleted"))
return super(HotelReservation, self).unlink()
# Business methods
@api.model
def _hcalendar_room_data(self, rooms):
_logger.warning('_found [%s] rooms for hotel [%s]', len(rooms), self.env.user.hotel_id.id)
@@ -404,6 +411,24 @@ class HotelReservation(models.Model):
}
return vals
@api.model
def get_hcalendar_settings(self):
type_move = self.env.user.hotel_id.pms_type_move
return {
'divide_rooms_by_capacity': self.env.user.hotel_id.pms_divide_rooms_by_capacity,
'eday_week': self.env.user.hotel_id.pms_end_day_week,
'eday_week_offset': self.env.user.hotel_id.pms_end_day_week_offset,
'days': self.env.user.hotel_id.pms_default_num_days,
'allow_invalid_actions': type_move == 'allow_invalid',
'assisted_movement': type_move == 'assisted',
'default_arrival_hour': self.env.user.hotel_id.default_arrival_hour,
'default_departure_hour': self.env.user.hotel_id.default_departure_hour,
'show_notifications': self.env.user.pms_show_notifications,
'show_pricelist': self.env.user.pms_show_pricelist,
'show_availability': self.env.user.pms_show_availability,
'show_num_rooms': self.env.user.hotel_id.pms_show_num_rooms,
}
@api.multi
def generate_bus_values(self, naction, ntype, ntitle=''):
self.ensure_one()
@@ -494,26 +519,3 @@ class HotelReservation(models.Model):
})
return True
# CRUD methods
@api.model
def create(self, vals):
reservation_id = super(HotelReservation, self).create(vals)
reservation_id.send_bus_notification('create',
'notify',
_("Reservation Created"))
return reservation_id
@api.multi
def write(self, vals):
_logger.info("RESERV WRITE")
ret = super(HotelReservation, self).write(vals)
self.send_bus_notification('write', 'noshow')
return ret
@api.multi
def unlink(self):
self.send_bus_notification('unlink',
'warn',
_("Reservation Deleted"))
return super(HotelReservation, self).unlink()

View File

@@ -1,9 +0,0 @@
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, fields
class HotelRoom(models.Model):
_inherit = 'hotel.room'
# hcal_sequence = fields.Integer('Calendar Sequence', default=0)

View File

@@ -1,9 +0,0 @@
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, fields
class HotelRoomType(models.Model):
_inherit = 'hotel.room.type'
# hcal_sequence = fields.Integer('Calendar Sequence', default=0)

View File

@@ -1,18 +1,17 @@
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
from odoo import models, fields, api
from odoo import models, api
_logger = logging.getLogger(__name__)
class HotelRoomTypeResrtrictionItem(models.Model):
class HotelRoomTypeRestrictionItem(models.Model):
_inherit = 'hotel.room.type.restriction.item'
# CRUD methods
# ORM overrides
@api.model
def create(self, vals):
res = super(HotelRoomTypeResrtrictionItem, self).create(vals)
# TODO: refactoring res.config.settings', 'default_restriction_id by the current hotel.property.restriction_id
res = super(HotelRoomTypeRestrictionItem, self).create(vals)
if res.restriction_id.id == self.env.user.hotel_id.default_restriction_id.id:
self.env['bus.hotel.calendar'].send_restriction_notification({
'restriction_id': res.restriction_id.id,
@@ -31,7 +30,7 @@ class HotelRoomTypeResrtrictionItem(models.Model):
@api.multi
def write(self, vals):
ret_vals = super(HotelRoomTypeResrtrictionItem, self).write(vals)
ret_vals = super(HotelRoomTypeRestrictionItem, self).write(vals)
bus_hotel_calendar_obj = self.env['bus.hotel.calendar']
for record in self:
bus_hotel_calendar_obj.send_restriction_notification({
@@ -51,7 +50,6 @@ class HotelRoomTypeResrtrictionItem(models.Model):
@api.multi
def unlink(self):
# TODO: refactoring res.config.settings', 'default_restriction_id by the current hotel.property.restriction_id
default_restriction_id = self.env.user.hotel_id.default_restriction_id.id
# Construct dictionary with relevant info of removed records
unlink_vals = []
@@ -71,7 +69,7 @@ class HotelRoomTypeResrtrictionItem(models.Model):
'room_type_id': record.room_type_id.id,
'id': record.id,
})
res = super(HotelRoomTypeResrtrictionItem, self).unlink()
res = super(HotelRoomTypeRestrictionItem, self).unlink()
bus_hotel_calendar_obj = self.env['bus.hotel.calendar']
for uval in unlink_vals:
bus_hotel_calendar_obj.send_restriction_notification(uval)

View File

@@ -1,36 +0,0 @@
# Copyright 2018 Alexandre Díaz <dev@redneboa.es>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, fields, api
class ProductPricelist(models.Model):
_inherit = 'product.pricelist'
# TODO REVIEW: deprecated ?¿
@api.multi
def update_price(self, room_type_id, date, price):
import wdb; wdb.set_trace()
room_type = self.env['hotel.room.type'].browse(room_type_id)
pritem_obj = self.env['product.pricelist.item']
for record in self:
plitem = pritem_obj.search([
('pricelist_id', '=', record.id),
('product_tmpl_id', '=', room_type.product_id.product_tmpl_id.id),
('date_start', '=', date),
('date_end', '=', date),
('applied_on', '=', '1_product'),
('compute_price', '=', 'fixed')
])
if plitem:
plitem.fixed_price = price
else:
pritem_obj.create({
'pricelist_id': record.id,
'product_tmpl_id': room_type.product_id.product_tmpl_id.id,
'date_start': date,
'date_end': date,
'applied_on': '1_product',
'compute_price': 'fixed',
'fixed_price': price
})

View File

@@ -6,7 +6,7 @@ from odoo import models, api
class ProductPricelistItem(models.Model):
_inherit = 'product.pricelist.item'
# CRUD methods
# ORM overrides
@api.model
def create(self, vals):
res = super(ProductPricelistItem, self).create(vals)

View File

@@ -1,13 +1,12 @@
# Copyright 2019 Pablo Quesada
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
from odoo import models, fields
class ResCompany(models.Model):
_inherit = 'res.company'
# background reservation colors
# Fields declaration
color_pre_reservation = fields.Char('Pre-reservation', default='#A24680')
color_reservation = fields.Char('Confirmed Reservation ', default='#7C7BAD')
color_reservation_pay = fields.Char('Paid Reservation', default='#584D76')
@@ -18,7 +17,6 @@ class ResCompany(models.Model):
color_staff = fields.Char('Staff', default='#C08686')
color_to_assign = fields.Char('Ota Reservation to Assign', default='#ED722E')
color_payment_pending = fields.Char('Payment Pending', default='#A24689')
# foreground reservation colors
color_letter_pre_reservation = fields.Char('Letter Pre-reservation', default='#FFFFFF')
color_letter_reservation = fields.Char('Letter Confirmed Reservation ', default='#FFFFFF')
color_letter_reservation_pay = fields.Char('Letter Paid Reservation', default='#FFFFFF')

View File

@@ -6,10 +6,12 @@ from odoo import models, fields
class ResUsers(models.Model):
_inherit = 'res.users'
# Fields declaration
pms_show_notifications = fields.Boolean('Show Notifications', default=True)
pms_show_pricelist = fields.Boolean('Show Pricelist', default=True)
pms_show_availability = fields.Boolean('Show Availability', default=True)
# ORM overrides
def __init__(self, pool, cr):
""" Override of __init__ to add access rights.
Access rights are disabled by default, but allowed on some specific

View File

@@ -6,4 +6,5 @@ from odoo import models, fields
class ActWindowView(models.Model):
_inherit = 'ir.actions.act_window.view'
# Fields declaration
view_mode = fields.Selection(selection_add=[('pms', "PMS"), ('mpms', 'Management PMS')])

View File

@@ -6,4 +6,5 @@ from odoo import models, fields
class View(models.Model):
_inherit = 'ir.ui.view'
# Fields declaration
type = fields.Selection(selection_add=[('pms', "PMS"), ('mpms', 'Management PMS')])

View File

@@ -52,8 +52,7 @@ return AbstractModel.extend({
},
get_restriction_plans: function () {
// TODO: FIXME: search and read restriction plans for current hotel
var domain = [['item_ids.room_type_id.hotel_id', '=', Session.hotel_id]];
var domain = [['hotel_id', '=', Session.hotel_id]];
return this._rpc({
model: 'hotel.room.type.restriction',
method: 'search_read',