diff --git a/hotel_management_odoo/README.rst b/hotel_management_odoo/README.rst new file mode 100755 index 000000000..0aa4739d4 --- /dev/null +++ b/hotel_management_odoo/README.rst @@ -0,0 +1,48 @@ +.. image:: https://img.shields.io/badge/license-LGPL--3-green.svg + :target: https://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 + +Hotel Management +================ +A complete Hotel Management System that cover all areas of hotel services. + +Configuration +============= +* No additional configurations needed + +License +------- +General Public License, Version 3 (LGPL v3). +https://www.gnu.org/licenses/lgpl-3.0-standalone.html + +Company +------- +* `Cybrosys Techno Solutions `__ + +Credits +------- +* Developer:(V18) Adarsh K, + (V17) Vishnu K P + Contact: odoo@cybrosys.com + +Contacts +-------- +* Mail Contact : odoo@cybrosys.com +* Website : https://cybrosys.com + +Bug Tracker +----------- +Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. + +Maintainer +========== +.. image:: https://cybrosys.com/images/logo.png + :target: https://cybrosys.com + +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit `Our Website `__ + +Further information +=================== +HTML Description: ``__ diff --git a/hotel_management_odoo/__init__.py b/hotel_management_odoo/__init__.py new file mode 100644 index 000000000..460df2a17 --- /dev/null +++ b/hotel_management_odoo/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from . import controllers +from . import models +from . import wizard diff --git a/hotel_management_odoo/__manifest__.py b/hotel_management_odoo/__manifest__.py new file mode 100644 index 000000000..047e16103 --- /dev/null +++ b/hotel_management_odoo/__manifest__.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +{ + 'name': 'Hotel Management', + 'version': '18.0.1.0.0', + 'category': 'Industries', + 'summary': """A complete Hotel Management System that cover all areas of + Hotel services""" , + 'description': """The module helps you to manage rooms, amenities, + services, food, events and vehicles. End Users can book rooms and reserve + foods from hotel.""", + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'website': 'https://www.cybrosys.com', + 'depends': ['account', 'event', 'fleet', 'lunch'], + 'data': [ + 'security/hotel_management_odoo_groups.xml', + 'security/hotel_management_odoo_security.xml', + 'security/ir.model.access.csv', + 'data/ir_data_sequence.xml', + 'views/account_move_views.xml', + 'views/hotel_menu_views.xml', + 'views/hotel_amenity_views.xml', + 'views/hotel_service_views.xml', + 'views/hotel_floor_views.xml', + 'views/hotel_room_views.xml', + 'views/lunch_product_views.xml', + 'views/fleet_vehicle_model_views.xml', + 'views/room_booking_views.xml', + 'views/maintenance_team_views.xml', + 'views/maintenance_request_views.xml', + 'views/cleaning_team_views.xml', + 'views/cleaning_request_views.xml', + 'views/food_booking_line_views.xml', + 'views/dashboard_view.xml', + 'wizard/room_booking_detail_views.xml', + 'wizard/sale_order_detail_views.xml', + 'views/reporting_views.xml', + 'report/room_booking_reports.xml', + 'report/sale_order_reports.xml', + ], + 'assets': { + 'web.assets_backend': [ + 'hotel_management_odoo/static/src/js/action_manager.js', + 'hotel_management_odoo/static/src/css/dashboard.css', + 'hotel_management_odoo/static/src/js/dashboard_action.js', + 'hotel_management_odoo/static/src/xml/dashboard_templates.xml', + ], + }, + 'images': ['static/description/banner.jpg'], + 'license': 'LGPL-3', + 'installable': True, + 'auto_install': False, + 'application': True, +} diff --git a/hotel_management_odoo/controllers/__init__.py b/hotel_management_odoo/controllers/__init__.py new file mode 100644 index 000000000..3b568c0d9 --- /dev/null +++ b/hotel_management_odoo/controllers/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from . import hotel_management_odoo diff --git a/hotel_management_odoo/controllers/hotel_management_odoo.py b/hotel_management_odoo/controllers/hotel_management_odoo.py new file mode 100644 index 000000000..4f881a010 --- /dev/null +++ b/hotel_management_odoo/controllers/hotel_management_odoo.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +import json +from odoo import http +from odoo.http import content_disposition, request +from odoo.tools import html_escape + + +class XLSXReportController(http.Controller): + """Controller for XlsX report""" + + @http.route('/xlsx_reports', type='http', auth='user', + methods=['POST'], csrf=False) + def get_room_booking_report_xlsx(self, model, options, output_format, + report_name): + """Function for generating xlsx report""" + report_obj = request.env[model].sudo() + options = json.loads(options) + try: + if output_format == 'xlsx': + response = request.make_response( + None, + headers=[('Content-Type', 'application/vnd.ms-excel'), + ('Content-Disposition', + content_disposition(report_name + '.xlsx'))] + ) + report_obj.get_xlsx_report(options, response) + response.set_cookie('fileToken', 'dummy token') + return response + except Exception as e: + s_error = http.serialize_exception(e) + error = { + 'code': 200, + 'message': 'Odoo Server Error', + 'data': s_error + } + return request.make_response(html_escape(json.dumps(error))) diff --git a/hotel_management_odoo/data/ir_data_sequence.xml b/hotel_management_odoo/data/ir_data_sequence.xml new file mode 100644 index 000000000..9d5f51fd5 --- /dev/null +++ b/hotel_management_odoo/data/ir_data_sequence.xml @@ -0,0 +1,26 @@ + + + + + + Hotel Folio + room.booking + BOOKING/ + 5 + + + + Cleaning Request + cleaning.request + CLEANING/ + 4 + + + + Maintenance Request + maintenance.request + MNTC/ + 5 + + + diff --git a/hotel_management_odoo/doc/RELEASE_NOTES.md b/hotel_management_odoo/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..e6c8567d2 --- /dev/null +++ b/hotel_management_odoo/doc/RELEASE_NOTES.md @@ -0,0 +1,6 @@ +## Module + +#### 11.08.2024 +#### Version 18.0.1.0.0 +#### ADD +- Initial commit for Hotel Management diff --git a/hotel_management_odoo/models/__init__.py b/hotel_management_odoo/models/__init__.py new file mode 100644 index 000000000..b0fa726ba --- /dev/null +++ b/hotel_management_odoo/models/__init__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from . import account_move +from . import account_move_line +from . import cleaning_request +from . import cleaning_team +from . import event_booking_line +from . import fleet_booking_line +from . import fleet_vehicle_model +from . import food_booking_line +from . import hotel_amenity +from . import hotel_floor +from . import hotel_room +from . import hotel_service +from . import maintenance_request +from . import maintenance_team +from . import room_booking +from . import room_booking_line +from . import service_booking_line diff --git a/hotel_management_odoo/models/account_move.py b/hotel_management_odoo/models/account_move.py new file mode 100644 index 000000000..6b2f2beaa --- /dev/null +++ b/hotel_management_odoo/models/account_move.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import fields, models + + +class AccountMove(models.Model): + """Inherited account. move for adding hotel booking reference field to + invoicing model.""" + _inherit = "account.move" + + hotel_booking_id = fields.Many2one('room.booking', + string="Booking Reference", + readonly=True, help="Choose the Booking" + "Reference") diff --git a/hotel_management_odoo/models/account_move_line.py b/hotel_management_odoo/models/account_move_line.py new file mode 100644 index 000000000..c618ef1d9 --- /dev/null +++ b/hotel_management_odoo/models/account_move_line.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import fields, models + + +class AccountMoveLine(models.Model): + """Adding Product Type field to Account Move Line model.""" + _inherit = "account.move.line" + + product_type = fields.Selection([('room', 'Room'), ('food', 'Food'), + ('event', 'Event'), + ('service', 'Service'), + ('fleet', 'Fleet')], + string="Product Type", + help="Choose the product type") diff --git a/hotel_management_odoo/models/cleaning_request.py b/hotel_management_odoo/models/cleaning_request.py new file mode 100644 index 000000000..f174b9b24 --- /dev/null +++ b/hotel_management_odoo/models/cleaning_request.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import api, fields, models, _ +from odoo.exceptions import ValidationError + + +class CleaningRequest(models.Model): + """Class for creating and assigning Cleaning Request""" + _name = "cleaning.request" + _inherit = ["mail.thread", "mail.activity.mixin"] + _rec_name = "sequence" + _description = "Cleaning Request" + + sequence = fields.Char(string="Sequence", readonly=True, default='New', + copy=False, tracking=True, + help="Sequence for identifying the request") + state = fields.Selection([('draft', 'Draft'), + ('assign', 'Assigned'), + ('ongoing', 'Cleaning'), + ('support', 'Waiting For Support'), + ('done', 'Completed')], + string="State", + default='draft', help="State of cleaning request") + cleaning_type = fields.Selection(selection=[('room', 'Room'), + ('hotel', 'Hotel'), + ('vehicle', 'Vehicle')], + required=True, tracking=True, + string="Cleaning Type", + help="Choose what is to be cleaned") + room_id = fields.Many2one('hotel.room', string="Room", + help="Choose the room") + hotel = fields.Char(string="Hotel", help="Cleaning request space in hotel") + vehicle_id = fields.Many2one('fleet.vehicle.model', + string="Vehicle", + help="Cleaning request from vehicle") + support_team_ids = fields.Many2many('res.users', + string="Support Team", + help="Support team members") + support_reason = fields.Char(string='Support', help="Support Reason") + description = fields.Char(string="Description", + help="Description about the cleaning") + team_id = fields.Many2one('cleaning.team', string="Team", + required=True, + tracking=True, + help="Choose the team") + head_id = fields.Many2one('res.users', string="Head", + related='team_id.team_head_id', + help="Head of cleaning team") + assigned_id = fields.Many2one('res.users', string="Assigned To", + help="The team member to whom the request is" + "Assigned To") + domain_partner_ids = fields.Many2many('res.partner', + string="Domain Partner", + help="Choose the Domain Partner") + + @api.model + def create(self, vals_list): + """Sequence Generation""" + if vals_list.get('sequence', 'New') == 'New': + vals_list['sequence'] = self.env['ir.sequence'].next_by_code( + 'cleaning.request') + return super().create(vals_list) + + @api.onchange('team_id') + def _onchange_team_id(self): + """Function for updating the domain partner ids""" + self.update( + {'domain_partner_ids': self.team_id.member_ids.ids}) + + def action_assign_cleaning(self): + """Button action for updating the state to assign""" + self.update({'state': 'assign'}) + + def action_start_cleaning(self): + """Button action for updating the state to ongoing""" + self.write({'state': 'ongoing'}) + + def action_done_cleaning(self): + """Button action for updating the state to done""" + self.write({'state': 'done'}) + + def action_assign_support(self): + """Button action for updating the state to support""" + if self.support_reason: + self.write({'state': 'support'}) + else: + raise ValidationError(_('Please enter the reason')) + + def action_assign_assign_support(self): + """Button action for updating the state to ongoing""" + if self.support_team_ids: + self.write({'state': 'ongoing'}) + else: + raise ValidationError(_('Please choose a support')) + + def action_maintain_request(self): + """Button action for creating the maintenance request""" + self.env['maintenance.request'].sudo().create({ + 'date': fields.Date.today(), + 'state': 'draft', + 'type': self.cleaning_type, + 'vehicle_maintenance_id': self.vehicle_id.id + }) + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'type': 'success', + 'message': "Maintenance Request Sent Successfully", + 'next': {'type': 'ir.actions.act_window_close'}, + } + } diff --git a/hotel_management_odoo/models/cleaning_team.py b/hotel_management_odoo/models/cleaning_team.py new file mode 100644 index 000000000..2de3db0fe --- /dev/null +++ b/hotel_management_odoo/models/cleaning_team.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import fields, models + + +class CleaningTeam(models.Model): + """ Model for creating Cleaning team and assigns Cleaning requests to + each team""" + _name = "cleaning.team" + _description = "Cleaning Team" + + name = fields.Char(string="Team Name", help="Name of the Team") + team_head_id = fields.Many2one('res.users', string="Team Head", + help="Choose the Team Head", + domain=lambda self: [ + ('groups_id', 'in', self.env.ref( + 'hotel_management_odoo.' + 'cleaning_team_group_head').id)]) + member_ids = fields.Many2many('res.users', string="Member", + domain=lambda self: [ + ('groups_id', 'in', self.env.ref( + 'hotel_management_odoo.' + 'cleaning_team_group_user').id)], + help="Team Members") diff --git a/hotel_management_odoo/models/event_booking_line.py b/hotel_management_odoo/models/event_booking_line.py new file mode 100644 index 000000000..3a689f7ec --- /dev/null +++ b/hotel_management_odoo/models/event_booking_line.py @@ -0,0 +1,109 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import api, fields, models + + +class EventBookingLine(models.Model): + """Model that handles the event booking form""" + _name = "event.booking.line" + _description = "Hotel Event Line" + _rec_name = 'event_id' + + booking_id = fields.Many2one("room.booking", string="Booking", + help="Choose room booking reference", + ondelete="cascade") + event_id = fields.Many2one('event.event', string="Event", + help="Choose the Event") + ticket_id = fields.Many2one('product.product', string="Ticket", + help="Choose the Ticket Type", + domain=[('service_tracking', '=', 'event')] + ) + description = fields.Char(string='Description', help="Detailed " + "description of the " + "event", + related='event_id.display_name') + uom_qty = fields.Float(string="Quantity", default=1, + help="The quantity converted into the UoM used by " + "the product") + uom_id = fields.Many2one('uom.uom', readonly=True, + string="Unit of Measure", + related='ticket_id.uom_id', help="This will set " + "the unit of" + " measure used") + price_unit = fields.Float(related='ticket_id.lst_price', string='Price', + digits='Product Price', + help="The selling price of the selected ticket.") + tax_ids = fields.Many2many('account.tax', + 'hotel_event_order_line_taxes_rel', + 'event_id', + 'tax_id', related='ticket_id.taxes_id', + string='Taxes', + help="Default taxes used when selling the event" + "tickets.", + domain=[('type_tax_use', '=', 'sale')]) + currency_id = fields.Many2one( + related='booking_id.pricelist_id.currency_id', string='Currency', + help='The currency used', store=True, precompute=True) + price_subtotal = fields.Float(string="Subtotal", + compute='_compute_price_subtotal', + help="Total Price Excluding Tax", store=True) + price_tax = fields.Float(string="Total Tax", + compute='_compute_price_subtotal', + help="Tax Amount", store=True) + price_total = fields.Float(string="Total", + compute='_compute_price_subtotal', + help="Total Price Including Tax", store=True) + state = fields.Selection(related='booking_id.state', + string="Order Status", + help="State of Room Booking", copy=False) + + @api.depends('uom_qty', 'price_unit', 'tax_ids') + def _compute_price_subtotal(self): + """Compute the amounts of the room booking line.""" + for line in self: + base_line = line._prepare_base_line_for_taxes_computation() + self.env['account.tax']._add_tax_details_in_base_line(base_line, self.env.company) + line.price_subtotal = base_line['tax_details']['total_excluded_currency'] + line.price_total = base_line['tax_details']['total_included_currency'] + line.price_tax = line.price_total - line.price_subtotal + if self.env.context.get('import_file', + False) and not self.env.user. \ + user_has_groups('account.group_account_manager'): + line.tax_id.invalidate_recordset( + ['invoice_repartition_line_ids']) + + def _prepare_base_line_for_taxes_computation(self): + """ Convert the current record to a dictionary in order to use the generic taxes computation method + defined on account.tax. + + :return: A python dictionary. + """ + self.ensure_one() + return self.env['account.tax']._prepare_base_line_for_taxes_computation( + self, + **{ + 'tax_ids': self.tax_ids, + 'quantity': self.uom_qty, + 'partner_id': self.booking_id.partner_id, + 'currency_id': self.currency_id, + }, + ) \ No newline at end of file diff --git a/hotel_management_odoo/models/fleet_booking_line.py b/hotel_management_odoo/models/fleet_booking_line.py new file mode 100644 index 000000000..cd50f3721 --- /dev/null +++ b/hotel_management_odoo/models/fleet_booking_line.py @@ -0,0 +1,119 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import api, fields, models, tools + + +class FleetBookingLine(models.Model): + """Model that handles the fleet booking""" + _name = "fleet.booking.line" + _description = "Hotel Fleet Line" + _rec_name = 'fleet_id' + + @tools.ormcache() + def _get_default_uom_id(self): + """Method for getting the default uom id""" + return self.env.ref('uom.product_uom_km') + + booking_id = fields.Many2one("room.booking", string="Booking", + ondelete="cascade", + help="Shows the room Booking") + fleet_id = fields.Many2one('fleet.vehicle.model', + string="Vehicle", + help='Indicates the Vehicle') + description = fields.Char(string='Description', + related='fleet_id.display_name', + help="Description of Vehicle") + uom_qty = fields.Float(string="Total KM", default=1, + help="The quantity converted into the UoM used by " + "the product") + uom_id = fields.Many2one('uom.uom', readonly=True, + string="Unit of Measure", + default=_get_default_uom_id, help="This will set " + "the unit of" + " measure used") + price_unit = fields.Float(string='Rent/KM', + related='fleet_id.price_per_km', + digits='Product Price', + help="The rent/km of the selected fleet.") + tax_ids = fields.Many2many('account.tax', + 'hotel_fleet_order_line_taxes_rel', + 'fleet_id', + 'tax_id', string='Taxes', + help="Default taxes used when renting the fleet" + "models.", + domain=[('type_tax_use', '=', 'sale')]) + currency_id = fields.Many2one( + related='booking_id.pricelist_id.currency_id', + string="Currency", help='The currency used') + price_subtotal = fields.Float(string="Subtotal", + compute='_compute_price_subtotal', + help="Total price excluding tax", + store=True) + price_tax = fields.Float(string="Total Tax", + compute='_compute_price_subtotal', + help="Total tax amount", + store=True) + price_total = fields.Float(string="Total", + compute='_compute_price_subtotal', + help="Total Price Including Tax", + store=True) + state = fields.Selection(related='booking_id.state', + string="Order Status", + help=" Status of the Order", + copy=False) + + @api.depends('uom_qty', 'price_unit', 'tax_ids') + def _compute_price_subtotal(self): + """Compute the amounts of the room booking line.""" + for line in self: + base_line = line._prepare_base_line_for_taxes_computation() + self.env['account.tax']._add_tax_details_in_base_line(base_line, self.env.company) + line.price_subtotal = base_line['tax_details']['total_excluded_currency'] + line.price_total = base_line['tax_details']['total_included_currency'] + line.price_tax = line.price_total - line.price_subtotal + if self.env.context.get('import_file', + False) and not self.env.user. \ + user_has_groups('account.group_account_manager'): + line.tax_id.invalidate_recordset( + ['invoice_repartition_line_ids']) + + def _prepare_base_line_for_taxes_computation(self): + """ Convert the current record to a dictionary in order to use the generic taxes computation method + defined on account.tax. + + :return: A python dictionary. + """ + self.ensure_one() + return self.env['account.tax']._prepare_base_line_for_taxes_computation( + self, + **{ + 'tax_ids': self.tax_ids, + 'quantity': self.uom_qty, + 'partner_id': self.booking_id.partner_id, + 'currency_id': self.currency_id, + }, + ) + + def search_available_vehicle(self): + """Returns list of booked vehicles""" + return (self.env['fleet.vehicle.model'].search( + [('id', 'in', self.search([]).mapped('fleet_id').ids)]).ids) diff --git a/hotel_management_odoo/models/fleet_vehicle_model.py b/hotel_management_odoo/models/fleet_vehicle_model.py new file mode 100644 index 000000000..eb4c12955 --- /dev/null +++ b/hotel_management_odoo/models/fleet_vehicle_model.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import fields, models, tools + + +class FleetVehicleModel(models.Model): + """Inherits Fleet Model for Booking vehicles for hotel Customers""" + _inherit = 'fleet.vehicle.model' + + @tools.ormcache() + def _set_default_uom_id(self): + """Method for getting the default uom id""" + return self.env.ref('uom.product_uom_km') + + price_per_km = fields.Float(string="Price/KM", default=1.0, + help="Rent for Vehicle") + uom_id = fields.Many2one('uom.uom', + string='Reference Uom', + help="UOM of the product", + default=_set_default_uom_id, required=True) diff --git a/hotel_management_odoo/models/food_booking_line.py b/hotel_management_odoo/models/food_booking_line.py new file mode 100644 index 000000000..6c822c548 --- /dev/null +++ b/hotel_management_odoo/models/food_booking_line.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import api, fields, models, tools + + +class FoodBookingLine(models.Model): + """Model that handles the food booking""" + _name = "food.booking.line" + _description = "Hotel Food Line" + _rec_name = 'food_id' + + @tools.ormcache() + def _get_default_uom_id(self): + """Method for getting the default uom id""" + return self.env.ref('uom.product_uom_unit') + + booking_id = fields.Many2one("room.booking", string="Booking", + help="Shows the room Booking", + ondelete="cascade") + food_id = fields.Many2one('lunch.product', string="Product", + help="Indicates the Food Product") + description = fields.Char(string='Description', + help="Description of Food Product", + related='food_id.display_name') + uom_qty = fields.Float(string="Qty", default=1, + help="The quantity converted into the UoM used by " + "the product") + uom_id = fields.Many2one('uom.uom', readonly=True, + string="Unit of Measure", + default=_get_default_uom_id, help="This will set " + "the unit of" + " measure used") + price_unit = fields.Float(related='food_id.price', string='Price', + digits='Product Price', + help="The price of the selected food item.") + tax_ids = fields.Many2many('account.tax', + 'hotel_food_order_line_taxes_rel', + 'food_id', 'tax_id', + string='Taxes', + help="Default taxes used when selling the food" + " products.", + domain=[('type_tax_use', '=', 'sale')]) + currency_id = fields.Many2one(related='booking_id.pricelist_id.currency_id' + , string="Currency", + help='The currency used') + price_subtotal = fields.Float(string="Subtotal", + compute='_compute_price_subtotal', + help="Total Price Excluding Tax", + store=True) + price_tax = fields.Float(string="Total Tax", + compute='_compute_price_subtotal', + help="Tax Amount", + store=True) + price_total = fields.Float(string="Total", + compute='_compute_price_subtotal', + help="Total Price Including Tax", + store=True) + state = fields.Selection(related='booking_id.state', + string="Order Status", + help=" Status of the Order", + copy=False) + + @api.depends('uom_qty', 'price_unit', 'tax_ids') + def _compute_price_subtotal(self): + """Compute the amounts of the room booking line.""" + for line in self: + base_line = line._prepare_base_line_for_taxes_computation() + self.env['account.tax']._add_tax_details_in_base_line(base_line, self.env.company) + line.price_subtotal = base_line['tax_details']['total_excluded_currency'] + line.price_total = base_line['tax_details']['total_included_currency'] + line.price_tax = line.price_total - line.price_subtotal + if self.env.context.get('import_file', + False) and not self.env.user. \ + user_has_groups('account.group_account_manager'): + line.tax_id.invalidate_recordset( + ['invoice_repartition_line_ids']) + + def _prepare_base_line_for_taxes_computation(self): + """ Convert the current record to a dictionary in order to use the generic taxes computation method + defined on account.tax. + + :return: A python dictionary. + """ + self.ensure_one() + return self.env['account.tax']._prepare_base_line_for_taxes_computation( + self, + **{ + 'tax_ids': self.tax_ids, + 'quantity': self.uom_qty, + 'partner_id': self.booking_id.partner_id, + 'currency_id': self.currency_id, + }, + ) + + def search_food_orders(self): + """Returns list of food orders""" + return (self.search([]).filtered(lambda r: r.booking_id.state not in [ + 'check_out', 'cancel', 'done']).ids) diff --git a/hotel_management_odoo/models/hotel_amenity.py b/hotel_management_odoo/models/hotel_amenity.py new file mode 100644 index 000000000..fca64a139 --- /dev/null +++ b/hotel_management_odoo/models/hotel_amenity.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import fields, models + + +class HotelAmenity(models.Model): + """Model that handles all amenities of the hotel""" + _name = 'hotel.amenity' + _description = "Hotel Amenity" + _inherit = 'mail.thread' + _order = 'id desc' + + name = fields.Char(string='Name', help="Name of the amenity") + icon = fields.Image(string="Icon", required=True, + help="Image of the amenity") + description = fields.Html(string="About", + help="Specify the amenity description") diff --git a/hotel_management_odoo/models/hotel_floor.py b/hotel_management_odoo/models/hotel_floor.py new file mode 100644 index 000000000..971f428a7 --- /dev/null +++ b/hotel_management_odoo/models/hotel_floor.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import fields, models + + +class HotelFloor(models.Model): + """Model that holds the Hotel Floors.""" + _name = "hotel.floor" + _description = "Floor" + _order = 'id desc' + + name = fields.Char(string="Name", help="Name of the floor", required=True) + user_id = fields.Many2one('res.users', string='Manager', + help="Manager of the Floor", + required=True) diff --git a/hotel_management_odoo/models/hotel_room.py b/hotel_management_odoo/models/hotel_room.py new file mode 100644 index 000000000..61ed51782 --- /dev/null +++ b/hotel_management_odoo/models/hotel_room.py @@ -0,0 +1,104 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import api, fields, models, tools, _ +from odoo.exceptions import ValidationError + + +class HotelRoom(models.Model): + """Model that holds all details regarding hotel room""" + _name = 'hotel.room' + _description = 'Rooms' + _inherit = ['mail.thread', 'mail.activity.mixin'] + + @tools.ormcache() + def _get_default_uom_id(self): + """Method for getting the default uom id""" + return self.env.ref('uom.product_uom_unit') + + name = fields.Char(string='Name', help="Name of the Room", index='trigram', + required=True, translate=True) + status = fields.Selection([("available", "Available"), + ("reserved", "Reserved"), + ("occupied", "Occupied")], + default="available", string="Status", + help="Status of The Room", + tracking=True) + is_room_avail = fields.Boolean(default=True, string="Available", + help="Check if the room is available") + list_price = fields.Float(string='Rent', digits='Product Price', + help="The rent of the room.") + uom_id = fields.Many2one('uom.uom', string='Unit of Measure', + default=_get_default_uom_id, required=True, + help="Default unit of measure used for all stock" + " operations.") + room_image = fields.Image(string="Room Image", max_width=1920, + max_height=1920, help='Image of the room') + taxes_ids = fields.Many2many('account.tax', + 'hotel_room_taxes_rel', + 'room_id', 'tax_id', + help="Default taxes used when selling the" + " room.", string='Customer Taxes', + domain=[('type_tax_use', '=', 'sale')], + default=lambda self: self.env.company. + account_sale_tax_id) + room_amenities_ids = fields.Many2many("hotel.amenity", + string="Room Amenities", + help="List of room amenities.") + floor_id = fields.Many2one('hotel.floor', string='Floor', + help="Automatically selects the Floor", + tracking=True) + user_id = fields.Many2one('res.users', string="User", + related='floor_id.user_id', + help="Automatically selects the manager", + tracking=True) + room_type = fields.Selection([('single', 'Single'), + ('double', 'Double'), + ('dormitory', 'Dormitory')], + required=True, string="Room Type", + help="Automatically selects the Room Type", + tracking=True, + default="single") + num_person = fields.Integer(string='Number Of Persons', + required=True, + help="Automatically chooses the No. of Persons", + tracking=True) + description = fields.Html(string='Description', help="Add description", + translate=True) + + @api.constrains("num_person") + def _check_capacity(self): + """Check capacity function""" + for room in self: + if room.num_person <= 0: + raise ValidationError(_("Room capacity must be more than 0")) + + @api.onchange("room_type") + def _onchange_room_type(self): + """Based on selected room type, number of person will be updated. + ---------------------------------------- + @param self: object pointer""" + if self.room_type == "single": + self.num_person = 1 + elif self.room_type == "double": + self.num_person = 2 + else: + self.num_person = 4 diff --git a/hotel_management_odoo/models/hotel_service.py b/hotel_management_odoo/models/hotel_service.py new file mode 100644 index 000000000..35318aa3f --- /dev/null +++ b/hotel_management_odoo/models/hotel_service.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import fields, models + + +class HotelService(models.Model): + """Model that holds the all hotel services""" + _name = 'hotel.service' + _description = "Hotel Service" + _inherit = 'mail.thread' + _order = 'id desc' + + name = fields.Char(string="Service", help="Name of the service", + required=True) + unit_price = fields.Float(string="Price", help="Price of the service", + default=0.0) + taxes_ids = fields.Many2many('account.tax', + 'hotel_service_taxes_rel', + 'service_id', 'tax_id', + string='Customer Taxes', + help="Default taxes used when selling the" + " service product.", + domain=[('type_tax_use', '=', 'sale')], + default=lambda self: + self.env.company.account_sale_tax_id) diff --git a/hotel_management_odoo/models/maintenance_request.py b/hotel_management_odoo/models/maintenance_request.py new file mode 100644 index 000000000..ccae6f691 --- /dev/null +++ b/hotel_management_odoo/models/maintenance_request.py @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import api, fields, models, _ +from odoo.exceptions import ValidationError + + +class MaintenanceRequest(models.Model): + """Model that handles the maintenance requests""" + + _name = 'maintenance.request' + _inherit = ['mail.thread', 'mail.activity.mixin'] + _rec_name = 'sequence' + _description = "Maintenance Request" + + sequence = fields.Char(readonly=True, string="Sequence", copy=False, + default='New', help='Sequence number for' + ' identifying maintenance' + ' request') + date = fields.Date(string="Date", help="Date of maintenance request", + default=fields.Date.today) + state = fields.Selection(selection=[('draft', 'Draft'), + ('team_leader_approve', + 'Waiting For User Assign'), + ('pending', 'Waiting For User To ' + 'Accept'), + ('ongoing', 'Ongoing'), + ('support', 'Waiting For Support'), + ('done', 'Done'), + ('verify', 'Pending For Verify'), + ('cancel', 'Canceled')], + default='draft', string="State", + help="State of maintenance request", + tracking=True) + team_id = fields.Many2one('maintenance.team', + string='Maintenance Team', + help="Team for which this request is assigned", + tracking=True) + team_head_id = fields.Many2one('res.users', + related='team_id.user_id', + string='Team Leader', + help="Head of the maintenance team") + assigned_user_id = fields.Many2one('res.users', + string='Assigned User', + tracking=True, + help="User to whom the request is " + "assigned") + type = fields.Selection(selection=[('room', 'Room'), + ('vehicle', 'Vehicle'), + ('hotel', 'Hotel'), + ('cleaning', 'Cleaning')], string="Type", + help="The type for which the request is creating", + tracking=True) + room_maintenance_ids = fields.Many2many('hotel.room', + string="Room Maintenance", + help="Choose Room Maintenance") + hotel_maintenance = fields.Char(string='Hotel Maintenance', + help="This is the Hotel Maintenance") + cleaning_maintenance = fields.Char(string='Cleaning Maintenance', + help="This is the Cleaning Maintenance") + vehicle_maintenance_id = fields.Many2one('fleet.vehicle.model', + string="Vehicle", + help="Choose Vehicle") + support_team_ids = fields.Many2many('res.users', + string="Support Team", + help="Choose Support Team") + support_reason = fields.Char(string='Support', + help="Reason for adding Support") + remarks = fields.Char(string='Remarks', help="Add Remarks") + domain_partner_ids = fields.Many2many('res.partner', + string="Partner", + help="For filtering Users") + + @api.model + def create(self, vals_list): + """Sequence Generation""" + if vals_list.get('sequence', 'New') == 'New': + vals_list['sequence'] = self.env['ir.sequence'].next_by_code( + 'maintenance.request') + return super().create(vals_list) + + @api.onchange('team_id') + def _onchange_team_id(self): + """Function for filtering the maintenance team user""" + self.update({ + 'domain_partner_ids': self.team_id.member_ids.ids + }) + + def action_assign_team(self): + """Button action for changing the state to team_leader_approve""" + if self.team_id: + self.state = 'team_leader_approve' + else: + raise ValidationError( + _("Please assign a Team")) + + def action_assign_user(self): + """Button action for changing the state to pending""" + if self.assigned_user_id: + self.state = 'pending' + else: + raise ValidationError( + _("Please assign a User")) + + def action_start(self): + """Button action for changing the state to ongoing""" + self.state = 'ongoing' + + def action_support(self): + """Button action for changing the state to support""" + if self.support_reason: + self.state = 'support' + else: + raise ValidationError(_('Please enter the reason')) + + def action_complete(self): + """Button action for changing the state to verify""" + if self.remarks: + self.state = 'verify' + else: + raise ValidationError(_('Please Add remark')) + + def action_assign_support(self): + """Button action for changing the state to ongoing""" + if self.support_team_ids: + self.state = 'ongoing' + else: + raise ValidationError(_('Please choose support')) + + def action_verify(self): + """Button action for changing the state to done""" + self.state = 'done' + if self.vehicle_maintenance_id: + self.vehicle_maintenance_id.status = 'available' diff --git a/hotel_management_odoo/models/maintenance_team.py b/hotel_management_odoo/models/maintenance_team.py new file mode 100644 index 000000000..8bc97f05e --- /dev/null +++ b/hotel_management_odoo/models/maintenance_team.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import fields, models + + +class MaintenanceTeam(models.Model): + """Model that handles the maintenance team """ + _name = "maintenance.team" + _description = "Maintenance Team" + + name = fields.Char(string='Maintenance Team', + help='Name of the maintenance team') + user_id = fields.Many2one('res.users', string='Team Leader', + help="Leader of Team", + domain=lambda self: [ + ('groups_id', 'in', self.env.ref( + 'hotel_management_odoo.' + 'maintenance_team_group_' + 'leader').id)]) + member_ids = fields.Many2many('res.users', string='Members', + help="Members of the Team", + domain=lambda self: [ + ('groups_id', 'in', self.env.ref( + 'hotel_management_odoo.' + 'maintenance_' + 'team_group_user').id)]) diff --git a/hotel_management_odoo/models/room_booking.py b/hotel_management_odoo/models/room_booking.py new file mode 100644 index 000000000..74c66955b --- /dev/null +++ b/hotel_management_odoo/models/room_booking.py @@ -0,0 +1,738 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from datetime import datetime, timedelta +from odoo import api, fields, models, _ +from odoo.exceptions import ValidationError +from odoo.tools.safe_eval import pytz + + +class RoomBooking(models.Model): + """Model that handles the hotel room booking and all operations related + to booking""" + _name = "room.booking" + _description = "Hotel Room Reservation" + _inherit = ['mail.thread', 'mail.activity.mixin'] + + name = fields.Char(string="Folio Number", readonly=True, index=True, + default="New", help="Name of Folio") + company_id = fields.Many2one('res.company', string="Company", + help="Choose the Company", + required=True, index=True, + default=lambda self: self.env.company) + partner_id = fields.Many2one('res.partner', string="Customer", + help="Customers of hotel", + required=True, index=True, tracking=1, + domain="[('type', '!=', 'private')," + " ('company_id', 'in', " + "(False, company_id))]") + date_order = fields.Datetime(string="Order Date", + required=True, copy=False, + help="Creation date of draft/sent orders," + " Confirmation date of confirmed orders", + default=fields.Datetime.now) + is_checkin = fields.Boolean(default=False, string="Is Checkin", + help="sets to True if the room is occupied") + maintenance_request_sent = fields.Boolean(default=False, + string="Maintenance Request sent" + "or Not", + help="sets to True if the " + "maintenance request send " + "once") + checkin_date = fields.Datetime(string="Check In", + help="Date of Checkin", + default=fields.Datetime.now()) + checkout_date = fields.Datetime(string="Check Out", + help="Date of Checkout", + default=fields.Datetime.now() + timedelta( + hours=23, minutes=59, seconds=59)) + hotel_policy = fields.Selection([("prepaid", "On Booking"), + ("manual", "On Check In"), + ("picking", "On Checkout"), + ], + default="manual", string="Hotel Policy", + help="Hotel policy for payment that " + "either the guest has to pay at " + "booking time, check-in " + "or check-out time.", tracking=True) + duration = fields.Integer(string="Duration in Days", + help="Number of days which will automatically " + "count from the check-in and check-out " + "date.", ) + invoice_button_visible = fields.Boolean(string='Invoice Button Display', + help="Invoice button will be " + "visible if this button is " + "True") + invoice_status = fields.Selection( + selection=[('no_invoice', 'Nothing To Invoice'), + ('to_invoice', 'To Invoice'), + ('invoiced', 'Invoiced'), + ], string="Invoice Status", + help="Status of the Invoice", + default='no_invoice', tracking=True) + hotel_invoice_id = fields.Many2one("account.move", + string="Invoice", + help="Indicates the invoice", + copy=False) + duration_visible = fields.Float(string="Duration", + help="A dummy field for Duration") + need_service = fields.Boolean(default=False, string="Need Service", + help="Check if a Service to be added with" + " the Booking") + need_fleet = fields.Boolean(default=False, string="Need Vehicle", + help="Check if a Fleet to be" + " added with the Booking") + need_food = fields.Boolean(default=False, string="Need Food", + help="Check if a Food to be added with" + " the Booking") + need_event = fields.Boolean(default=False, string="Need Event", + help="Check if a Event to be added with" + " the Booking") + service_line_ids = fields.One2many("service.booking.line", + "booking_id", + string="Service", + help="Hotel services details provided to" + "Customer and it will included in " + "the main Invoice.") + event_line_ids = fields.One2many("event.booking.line", + 'booking_id', + string="Event", + help="Hotel event reservation detail.") + vehicle_line_ids = fields.One2many("fleet.booking.line", + "booking_id", + string="Vehicle", + help="Hotel fleet reservation detail.") + room_line_ids = fields.One2many("room.booking.line", + "booking_id", string="Room", + help="Hotel room reservation detail.") + food_order_line_ids = fields.One2many("food.booking.line", + "booking_id", + string='Food', + help="Food details provided" + " to Customer and" + " it will included in the " + "main invoice.", ) + state = fields.Selection(selection=[('draft', 'Draft'), + ('reserved', 'Reserved'), + ('check_in', 'Check In'), + ('check_out', 'Check Out'), + ('cancel', 'Cancelled'), + ('done', 'Done')], string='State', + help="State of the Booking", + default='draft', tracking=True) + user_id = fields.Many2one(comodel_name='res.partner', + string="Invoice Address", + compute='_compute_user_id', + help="Sets the User automatically", + required=True, + domain="['|', ('company_id', '=', False), " + "('company_id', '='," + " company_id)]") + pricelist_id = fields.Many2one(comodel_name='product.pricelist', + string="Pricelist", + compute='_compute_pricelist_id', + store=True, readonly=False, + required=True, + tracking=1, + help="If you change the pricelist," + " only newly added lines" + " will be affected.") + currency_id = fields.Many2one( + string="Currency", help="This is the Currency used", + related='pricelist_id.currency_id', + depends=['pricelist_id.currency_id'], + ) + invoice_count = fields.Integer(compute='_compute_invoice_count', + string="Invoice " + "Count", + help="The number of invoices created") + account_move = fields.Integer(string='Invoice Id', + help="Id of the invoice created") + amount_untaxed = fields.Monetary(string="Total Untaxed Amount", + help="This indicates the total untaxed " + "amount", store=True, + compute='_compute_amount_untaxed', + tracking=5) + amount_tax = fields.Monetary(string="Taxes", help="Total Tax Amount", + store=True, compute='_compute_amount_untaxed') + amount_total = fields.Monetary(string="Total", store=True, + help="The total Amount including Tax", + compute='_compute_amount_untaxed', + tracking=4) + amount_untaxed_room = fields.Monetary(string="Room Untaxed", + help="Untaxed Amount for Room", + compute='_compute_amount_untaxed', + tracking=5) + amount_untaxed_food = fields.Monetary(string="Food Untaxed", + help="Untaxed Amount for Food", + compute='_compute_amount_untaxed', + tracking=5) + amount_untaxed_event = fields.Monetary(string="Event Untaxed", + help="Untaxed Amount for Event", + compute='_compute_amount_untaxed', + tracking=5) + amount_untaxed_service = fields.Monetary( + string="Service Untaxed", help="Untaxed Amount for Service", + compute='_compute_amount_untaxed', tracking=5) + amount_untaxed_fleet = fields.Monetary(string="Amount Untaxed", + help="Untaxed amount for Fleet", + compute='_compute_amount_untaxed', + tracking=5) + amount_taxed_room = fields.Monetary(string="Rom Tax", help="Tax for Room", + compute='_compute_amount_untaxed', + tracking=5) + amount_taxed_food = fields.Monetary(string="Food Tax", help="Tax for Food", + compute='_compute_amount_untaxed', + tracking=5) + amount_taxed_event = fields.Monetary(string="Event Tax", + help="Tax for Event", + compute='_compute_amount_untaxed', + tracking=5) + amount_taxed_service = fields.Monetary(string="Service Tax", + compute='_compute_amount_untaxed', + help="Tax for Service", tracking=5) + amount_taxed_fleet = fields.Monetary(string="Fleet Tax", + compute='_compute_amount_untaxed', + help="Tax for Fleet", tracking=5) + amount_total_room = fields.Monetary(string="Total Amount for Room", + compute='_compute_amount_untaxed', + help="This is the Total Amount for " + "Room", tracking=5) + amount_total_food = fields.Monetary(string="Total Amount for Food", + compute='_compute_amount_untaxed', + help="This is the Total Amount for " + "Food", tracking=5) + amount_total_event = fields.Monetary(string="Total Amount for Event", + compute='_compute_amount_untaxed', + help="This is the Total Amount for " + "Event", tracking=5) + amount_total_service = fields.Monetary(string="Total Amount for Service", + compute='_compute_amount_untaxed', + help="This is the Total Amount for " + "Service", tracking=5) + amount_total_fleet = fields.Monetary(string="Total Amount for Fleet", + compute='_compute_amount_untaxed', + help="This is the Total Amount for " + "Fleet", tracking=5) + + @api.model + def create(self, vals_list): + """Sequence Generation""" + if vals_list.get('name', 'New') == 'New': + vals_list['name'] = self.env['ir.sequence'].next_by_code( + 'room.booking') + return super().create(vals_list) + + @api.depends('partner_id') + def _compute_user_id(self): + """Computes the User id""" + for order in self: + order.user_id = \ + order.partner_id.address_get(['invoice'])[ + 'invoice'] if order.partner_id else False + + def _compute_invoice_count(self): + """Compute the invoice count""" + for record in self: + record.invoice_count = self.env['account.move'].search_count( + [('ref', '=', self.name)]) + + @api.depends('partner_id') + def _compute_pricelist_id(self): + """Computes PriceList""" + for order in self: + if not order.partner_id: + order.pricelist_id = False + continue + order = order.with_company(order.company_id) + order.pricelist_id = order.partner_id.property_product_pricelist + + @api.depends('room_line_ids.price_subtotal', 'room_line_ids.price_tax', + 'room_line_ids.price_total', + 'food_order_line_ids.price_subtotal', + 'food_order_line_ids.price_tax', + 'food_order_line_ids.price_total', + 'service_line_ids.price_subtotal', + 'service_line_ids.price_tax', 'service_line_ids.price_total', + 'vehicle_line_ids.price_subtotal', + 'vehicle_line_ids.price_tax', 'vehicle_line_ids.price_total', + 'event_line_ids.price_subtotal', 'event_line_ids.price_tax', + 'event_line_ids.price_total', + ) + def _compute_amount_untaxed(self, flag=False): + """Compute the total amounts of the Sale Order""" + amount_untaxed_room = 0.0 + amount_untaxed_food = 0.0 + amount_untaxed_fleet = 0.0 + amount_untaxed_event = 0.0 + amount_untaxed_service = 0.0 + amount_taxed_room = 0.0 + amount_taxed_food = 0.0 + amount_taxed_fleet = 0.0 + amount_taxed_event = 0.0 + amount_taxed_service = 0.0 + amount_total_room = 0.0 + amount_total_food = 0.0 + amount_total_fleet = 0.0 + amount_total_event = 0.0 + amount_total_service = 0.0 + room_lines = self.room_line_ids + food_lines = self.food_order_line_ids + service_lines = self.service_line_ids + fleet_lines = self.vehicle_line_ids + event_lines = self.event_line_ids + booking_list = [] + account_move_line = self.env['account.move.line'].search_read( + domain=[('ref', '=', self.name), + ('display_type', '!=', 'payment_term')], + fields=['name', 'quantity', 'price_unit', 'product_type'], ) + for rec in account_move_line: + del rec['id'] + if room_lines: + amount_untaxed_room += sum(room_lines.mapped('price_subtotal')) + amount_taxed_room += sum(room_lines.mapped('price_tax')) + amount_total_room += sum(room_lines.mapped('price_total')) + for room in room_lines: + booking_dict = {'name': room.room_id.name, + 'quantity': room.uom_qty, + 'price_unit': room.price_unit, + 'product_type': 'room'} + if booking_dict not in account_move_line: + if not account_move_line: + booking_list.append(booking_dict) + else: + for rec in account_move_line: + if rec['product_type'] == 'room': + if booking_dict['name'] == rec['name'] and \ + booking_dict['price_unit'] == rec[ + 'price_unit'] and booking_dict['quantity']\ + != rec['quantity']: + booking_list.append( + {'name': room.room_id.name, + "quantity": booking_dict[ + 'quantity'] - rec[ + 'quantity'], + "price_unit": room.price_unit, + "product_type": 'room'}) + else: + booking_list.append(booking_dict) + if flag: + room.booking_line_visible = True + if food_lines: + for food in food_lines: + booking_list.append(self.create_list(food)) + amount_untaxed_food += sum(food_lines.mapped('price_subtotal')) + amount_taxed_food += sum(food_lines.mapped('price_tax')) + amount_total_food += sum(food_lines.mapped('price_total')) + if service_lines: + for service in service_lines: + booking_list.append(self.create_list(service)) + amount_untaxed_service += sum( + service_lines.mapped('price_subtotal')) + amount_taxed_service += sum(service_lines.mapped('price_tax')) + amount_total_service += sum(service_lines.mapped('price_total')) + if fleet_lines: + for fleet in fleet_lines: + booking_list.append(self.create_list(fleet)) + amount_untaxed_fleet += sum(fleet_lines.mapped('price_subtotal')) + amount_taxed_fleet += sum(fleet_lines.mapped('price_tax')) + amount_total_fleet += sum(fleet_lines.mapped('price_total')) + if event_lines: + for event in event_lines: + booking_list.append(self.create_list(event)) + amount_untaxed_event += sum(event_lines.mapped('price_subtotal')) + amount_taxed_event += sum(event_lines.mapped('price_tax')) + amount_total_event += sum(event_lines.mapped('price_total')) + for rec in self: + rec.amount_untaxed = amount_untaxed_food + amount_untaxed_room + \ + amount_untaxed_fleet + \ + amount_untaxed_event + amount_untaxed_service + rec.amount_untaxed_food = amount_untaxed_food + rec.amount_untaxed_room = amount_untaxed_room + rec.amount_untaxed_fleet = amount_untaxed_fleet + rec.amount_untaxed_event = amount_untaxed_event + rec.amount_untaxed_service = amount_untaxed_service + rec.amount_tax = (amount_taxed_food + amount_taxed_room + + amount_taxed_fleet + + amount_taxed_event + amount_taxed_service) + rec.amount_taxed_food = amount_taxed_food + rec.amount_taxed_room = amount_taxed_room + rec.amount_taxed_fleet = amount_taxed_fleet + rec.amount_taxed_event = amount_taxed_event + rec.amount_taxed_service = amount_taxed_service + rec.amount_total = (amount_total_food + amount_total_room + + amount_total_fleet + amount_total_event + + amount_total_service) + rec.amount_total_food = amount_total_food + rec.amount_total_room = amount_total_room + rec.amount_total_fleet = amount_total_fleet + rec.amount_total_event = amount_total_event + rec.amount_total_service = amount_total_service + return booking_list + + @api.onchange('need_food') + def _onchange_need_food(self): + """Unlink Food Booking Line if Need Food is false""" + if not self.need_food and self.food_order_line_ids: + for food in self.food_order_line_ids: + food.unlink() + + @api.onchange('need_service') + def _onchange_need_service(self): + """Unlink Service Booking Line if Need Service is False""" + if not self.need_service and self.service_line_ids: + for serv in self.service_line_ids: + serv.unlink() + + @api.onchange('need_fleet') + def _onchange_need_fleet(self): + """Unlink Fleet Booking Line if Need Fleet is False""" + if not self.need_fleet: + if self.vehicle_line_ids: + for fleet in self.vehicle_line_ids: + fleet.unlink() + + @api.onchange('need_event') + def _onchange_need_event(self): + """Unlink Event Booking Line if Need Event is False""" + if not self.need_event: + if self.event_line_ids: + for event in self.event_line_ids: + event.unlink() + + @api.onchange('food_order_line_ids', 'room_line_ids', + 'service_line_ids', 'vehicle_line_ids', 'event_line_ids') + def _onchange_room_line_ids(self): + """Invokes the Compute amounts function""" + self._compute_amount_untaxed() + self.invoice_button_visible = False + + @api.constrains("room_line_ids") + def _check_duplicate_folio_room_line(self): + """ + This method is used to validate the room_lines. + ------------------------------------------------ + @param self: object pointer + @return: raise warning depending on the validation + """ + for record in self: + # Create a set of unique ids + ids = set() + for line in record.room_line_ids: + if line.room_id.id in ids: + raise ValidationError( + _( + """Room Entry Duplicates Found!, """ + """You Cannot Book "%s" Room More Than Once!""" + ) + % line.room_id.name + ) + ids.add(line.room_id.id) + + def create_list(self, line_ids): + """Returns a Dictionary containing the Booking line Values""" + account_move_line = self.env['account.move.line'].search_read( + domain=[('ref', '=', self.name), + ('display_type', '!=', 'payment_term')], + fields=['name', 'quantity', 'price_unit', 'product_type'], ) + for rec in account_move_line: + del rec['id'] + booking_dict = {} + for line in line_ids: + name = "" + product_type = "" + if line_ids._name == 'food.booking.line': + name = line.food_id.name + product_type = 'food' + elif line_ids._name == 'fleet.booking.line': + name = line.fleet_id.name + product_type = 'fleet' + elif line_ids._name == 'service.booking.line': + name = line.service_id.name + product_type = 'service' + elif line_ids._name == 'event.booking.line': + name = line.event_id.name + product_type = 'event' + booking_dict = {'name': name, + 'quantity': line.uom_qty, + 'price_unit': line.price_unit, + 'product_type': product_type} + return booking_dict + + def action_reserve(self): + """Button Reserve Function""" + if self.state == 'reserved': + message = _("Room Already Reserved.") + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'type': 'warning', + 'message': message, + 'next': {'type': 'ir.actions.act_window_close'}, + } + } + if self.room_line_ids: + for room in self.room_line_ids: + room.room_id.write({ + 'status': 'reserved', + }) + room.room_id.is_room_avail = False + self.write({"state": "reserved"}) + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'type': 'success', + 'message': "Rooms reserved Successfully!", + 'next': {'type': 'ir.actions.act_window_close'}, + } + } + raise ValidationError(_("Please Enter Room Details")) + + def action_cancel(self): + """ + @param self: object pointer + """ + if self.room_line_ids: + for room in self.room_line_ids: + room.room_id.write({ + 'status': 'available', + }) + room.room_id.is_room_avail = True + self.write({"state": "cancel"}) + + def action_maintenance_request(self): + """ + Function that handles the maintenance request + """ + room_list = [] + for rec in self.room_line_ids.room_id.ids: + room_list.append(rec) + if room_list: + room_id = self.env['hotel.room'].search([ + ('id', 'in', room_list)]) + self.env['maintenance.request'].sudo().create({ + 'date': fields.Date.today(), + 'state': 'draft', + 'type': 'room', + 'room_maintenance_ids': room_id.ids, + }) + self.maintenance_request_sent = True + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'type': 'success', + 'message': "Maintenance Request Sent Successfully", + 'next': {'type': 'ir.actions.act_window_close'}, + } + } + raise ValidationError(_("Please Enter Room Details")) + + def action_done(self): + """Button action_confirm function""" + for rec in self.env['account.move'].search( + [('ref', '=', self.name)]): + if rec.payment_state != 'not_paid': + self.write({"state": "done"}) + self.is_checkin = False + if self.room_line_ids: + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'type': 'success', + 'message': "Booking Checked Out Successfully!", + 'next': {'type': 'ir.actions.act_window_close'}, + } + } + raise ValidationError(_('Your Invoice is Due for Payment.')) + self.write({"state": "done"}) + + def action_checkout(self): + """Button action_heck_out function""" + self.write({"state": "check_out"}) + for room in self.room_line_ids: + room.room_id.write({ + 'status': 'available', + 'is_room_avail': True + }) + room.write({'checkout_date': datetime.today()}) + + def action_invoice(self): + """Method for creating invoice""" + if not self.room_line_ids: + raise ValidationError(_("Please Enter Room Details")) + booking_list = self._compute_amount_untaxed(True) + if booking_list: + account_move = self.env["account.move"].create([{ + 'move_type': 'out_invoice', + 'invoice_date': fields.Date.today(), + 'partner_id': self.partner_id.id, + 'ref': self.name, + }]) + for rec in booking_list: + account_move.invoice_line_ids.create([{ + 'name': rec['name'], + 'quantity': rec['quantity'], + 'price_unit': rec['price_unit'], + 'move_id': account_move.id, + 'price_subtotal': rec['quantity'] * rec['price_unit'], + 'product_type': rec['product_type'], + }]) + self.write({'invoice_status': "invoiced"}) + self.invoice_button_visible = True + return { + 'type': 'ir.actions.act_window', + 'name': 'Invoices', + 'view_mode': 'form', + 'view_type': 'form', + 'res_model': 'account.move', + 'view_id': self.env.ref('account.view_move_form').id, + 'res_id': account_move.id, + 'context': "{'create': False}" + } + + def action_view_invoices(self): + """Method for Returning invoice View""" + return { + 'type': 'ir.actions.act_window', + 'name': 'Invoices', + 'view_mode': 'list,form', + 'view_type': 'list,form', + 'res_model': 'account.move', + 'domain': [('ref', '=', self.name)], + 'context': "{'create': False}" + } + + def action_checkin(self): + """ + @param self: object pointer + """ + if not self.room_line_ids: + raise ValidationError(_("Please Enter Room Details")) + else: + for room in self.room_line_ids: + room.room_id.write({ + 'status': 'occupied', + }) + room.room_id.is_room_avail = False + self.write({"state": "check_in"}) + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'type': 'success', + 'message': "Booking Checked In Successfully!", + 'next': {'type': 'ir.actions.act_window_close'}, + } + } + + def get_details(self): + """ Returns different counts for displaying in dashboard""" + today = datetime.today() + tz_name = self.env.user.tz + today_utc = pytz.timezone('UTC').localize(today, + is_dst=False) + context_today = today_utc.astimezone(pytz.timezone(tz_name)) + total_room = self.env['hotel.room'].search_count([]) + check_in = self.env['room.booking'].search_count( + [('state', '=', 'check_in')]) + available_room = self.env['hotel.room'].search( + [('status', '=', 'available')]) + reservation = self.env['room.booking'].search_count( + [('state', '=', 'reserved')]) + check_outs = self.env['room.booking'].search([]) + check_out = 0 + staff = 0 + for rec in check_outs: + for room in rec.room_line_ids: + if room.checkout_date.date() == context_today.date(): + check_out += 1 + """staff""" + staff = self.env['res.users'].search_count( + [('groups_id', 'in', + [self.env.ref('hotel_management_odoo.hotel_group_admin').id, + self.env.ref( + 'hotel_management_odoo.cleaning_team_group_head').id, + self.env.ref( + 'hotel_management_odoo.cleaning_team_group_user').id, + self.env.ref( + 'hotel_management_odoo.hotel_group_reception').id, + self.env.ref( + 'hotel_management_odoo.maintenance_team_group_leader').id, + self.env.ref( + 'hotel_management_odoo.maintenance_team_group_user').id + ])]) + total_vehicle = self.env['fleet.vehicle.model'].search_count([]) + available_vehicle = total_vehicle - self.env[ + 'fleet.booking.line'].search_count( + [('state', '=', 'check_in')]) + total_event = self.env['event.event'].search_count([]) + pending_event = self.env['event.event'].search([]) + pending_events = 0 + today_events = 0 + for pending in pending_event: + if pending.date_end >= fields.datetime.now(): + pending_events += 1 + if pending.date_end.date() == fields.date.today(): + today_events += 1 + food_items = self.env['lunch.product'].search_count([]) + food_order = len(self.env['food.booking.line'].search([]).filtered( + lambda r: r.booking_id.state not in ['check_out', 'cancel', + 'done'])) + """total Revenue""" + total_revenue = 0 + today_revenue = 0 + pending_payment = 0 + for rec in self.env['account.move'].search( + [('payment_state', '=', 'paid')]): + if rec.ref: + if 'BOOKING' in rec.ref: + total_revenue += rec.amount_total + if rec.date == fields.date.today(): + today_revenue += rec.amount_total + for rec in self.env['account.move'].search( + [('payment_state', '=', 'not_paid')]): + if rec.ref: + if 'BOOKING' in rec.ref: + pending_payment += rec.amount_total + return { + 'total_room': total_room, + 'available_room': len(available_room), + 'staff': staff, + 'check_in': check_in, + 'reservation': reservation, + 'check_out': check_out, + 'total_vehicle': total_vehicle, + 'available_vehicle': available_vehicle, + 'total_event': total_event, + 'today_events': today_events, + 'pending_events': pending_events, + 'food_items': food_items, + 'food_order': food_order, + 'total_revenue': round(total_revenue, 2), + 'today_revenue': round(today_revenue, 2), + 'pending_payment': round(pending_payment, 2), + 'currency_symbol': self.env.user.company_id.currency_id.symbol, + 'currency_position': self.env.user.company_id.currency_id.position + } diff --git a/hotel_management_odoo/models/room_booking_line.py b/hotel_management_odoo/models/room_booking_line.py new file mode 100644 index 000000000..1cae38336 --- /dev/null +++ b/hotel_management_odoo/models/room_booking_line.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import api, fields, models, tools, _ +from odoo.exceptions import ValidationError + + +class RoomBookingLine(models.Model): + """Model that handles the room booking form""" + _name = "room.booking.line" + _description = "Hotel Folio Line" + _rec_name = 'room_id' + + @tools.ormcache() + def _set_default_uom_id(self): + return self.env.ref('uom.product_uom_day') + + booking_id = fields.Many2one("room.booking", string="Booking", + help="Indicates the Room", + ondelete="cascade") + checkin_date = fields.Datetime(string="Check In", + help="You can choose the date," + " Otherwise sets to current Date", + required=True) + checkout_date = fields.Datetime(string="Check Out", + help="You can choose the date," + " Otherwise sets to current Date", + required=True) + room_id = fields.Many2one('hotel.room', string="Room", + domain=[('status', '=', 'available')], + help="Indicates the Room", + required=True) + uom_qty = fields.Float(string="Duration", + help="The quantity converted into the UoM used by " + "the product", readonly=True) + uom_id = fields.Many2one('uom.uom', + default=_set_default_uom_id, + string="Unit of Measure", + help="This will set the unit of measure used", + readonly=True) + price_unit = fields.Float(related='room_id.list_price', string='Rent', + digits='Product Price', + help="The rent price of the selected room.") + tax_ids = fields.Many2many('account.tax', + 'hotel_room_order_line_taxes_rel', + 'room_id', 'tax_id', + related='room_id.taxes_ids', + string='Taxes', + help="Default taxes used when selling the room." + , domain=[('type_tax_use', '=', 'sale')]) + currency_id = fields.Many2one(string='Currency', + related='booking_id.pricelist_id.currency_id' + , help='The currency used') + price_subtotal = fields.Float(string="Subtotal", + compute='_compute_price_subtotal', + help="Total Price excluding Tax", + store=True) + price_tax = fields.Float(string="Total Tax", + compute='_compute_price_subtotal', + help="Tax Amount", + store=True) + price_total = fields.Float(string="Total", + compute='_compute_price_subtotal', + help="Total Price including Tax", + store=True) + state = fields.Selection(related='booking_id.state', + string="Order Status", + help=" Status of the Order", + copy=False) + booking_line_visible = fields.Boolean(default=False, + string="Booking Line Visible", + help="If True, then Booking Line " + "will be visible") + + @api.onchange("checkin_date", "checkout_date") + def _onchange_checkin_date(self): + """When you change checkin_date or checkout_date it will check + and update the qty of hotel service line + ----------------------------------------------------------------- + @param self: object pointer""" + if self.checkout_date < self.checkin_date: + raise ValidationError( + _("Checkout must be greater or equal checkin date")) + if self.checkin_date and self.checkout_date: + diffdate = self.checkout_date - self.checkin_date + qty = diffdate.days + if diffdate.total_seconds() > 0: + qty = qty + 1 + self.uom_qty = qty + + @api.depends('uom_qty', 'price_unit', 'tax_ids') + def _compute_price_subtotal(self): + """Compute the amounts of the room booking line.""" + for line in self: + base_line = line._prepare_base_line_for_taxes_computation() + self.env['account.tax']._add_tax_details_in_base_line(base_line, self.env.company) + line.price_subtotal = base_line['tax_details']['total_excluded_currency'] + line.price_total = base_line['tax_details']['total_included_currency'] + line.price_tax = line.price_total - line.price_subtotal + if self.env.context.get('import_file', + False) and not self.env.user. \ + user_has_groups('account.group_account_manager'): + line.tax_id.invalidate_recordset( + ['invoice_repartition_line_ids']) + + def _prepare_base_line_for_taxes_computation(self): + """ Convert the current record to a dictionary in order to use the generic taxes computation method + defined on account.tax. + + :return: A python dictionary. + """ + self.ensure_one() + return self.env['account.tax']._prepare_base_line_for_taxes_computation( + self, + **{ + 'tax_ids': self.tax_ids, + 'quantity': self.uom_qty, + 'partner_id': self.booking_id.partner_id, + 'currency_id': self.currency_id, + }, + ) diff --git a/hotel_management_odoo/models/service_booking_line.py b/hotel_management_odoo/models/service_booking_line.py new file mode 100644 index 000000000..675ef3491 --- /dev/null +++ b/hotel_management_odoo/models/service_booking_line.py @@ -0,0 +1,113 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import api, fields, models, tools + + +class ServiceBookingLine(models.Model): + """Model that handles the service booking form""" + _name = "service.booking.line" + _description = "Hotel service Line" + + @tools.ormcache() + def _get_default_uom_id(self): + """Returns default product uom unit""" + return self.env.ref('uom.product_uom_unit') + + booking_id = fields.Many2one("room.booking", string="Booking", + help="Indicates the Room Booking", + ondelete="cascade") + service_id = fields.Many2one('hotel.service', string="Service", + help="Indicates the Service") + description = fields.Char(string='Description', related='service_id.name', + help="Description of the Service") + uom_qty = fields.Float(string="Qty", default=1.0, + help="The quantity converted into the UoM used by " + "the product") + uom_id = fields.Many2one('uom.uom', readonly=True, + string="Unit of Measure", + help="This will set the unit of measure used", + default=_get_default_uom_id) + price_unit = fields.Float(string='Price', related='service_id.unit_price', + digits='Product Price', + help="The price of the selected service.") + tax_ids = fields.Many2many('account.tax', + 'hotel_service_order_line_taxes_rel', + 'service_id', 'tax_id', + related='service_id.taxes_ids', string='Taxes', + help="Default taxes used when selling the " + "services.", + domain=[('type_tax_use', '=', 'sale')]) + currency_id = fields.Many2one(string='Currency', + related='booking_id.pricelist_id.currency_id', + help='The currency used') + price_subtotal = fields.Float(string="Subtotal", + compute='_compute_price_subtotal', + help="Total Price Excluding Tax", + store=True) + price_tax = fields.Float(string="Total Tax", + compute='_compute_price_subtotal', + help="Tax Amount", + store=True) + price_total = fields.Float(string="Total", + compute='_compute_price_subtotal', + help="Total Price Including Tax", + store=True) + state = fields.Selection(related='booking_id.state', + string="Order Status", + help=" Status of the Order", + copy=False) + booking_line_visible = fields.Boolean(default=False, + string="Booking Line Visible", + help="If true, Booking line will be" + " visible") + + @api.depends('uom_qty', 'price_unit', 'tax_ids') + def _compute_price_subtotal(self): + """Compute the amounts of the room booking line.""" + for line in self: + base_line = line._prepare_base_line_for_taxes_computation() + self.env['account.tax']._add_tax_details_in_base_line(base_line, self.env.company) + line.price_subtotal = base_line['tax_details']['total_excluded_currency'] + line.price_total = base_line['tax_details']['total_included_currency'] + line.price_tax = line.price_total - line.price_subtotal + if self.env.context.get('import_file', + False) and not self.env.user. \ + user_has_groups('account.group_account_manager'): + line.tax_id.invalidate_recordset( + ['invoice_repartition_line_ids']) + + def _prepare_base_line_for_taxes_computation(self): + """ Convert the current record to a dictionary in order to use the generic taxes computation method + defined on account.tax. + + :return: A python dictionary. + """ + self.ensure_one() + return self.env['account.tax']._prepare_base_line_for_taxes_computation( + self, + **{ + 'tax_ids': self.tax_ids, + 'quantity': self.uom_qty, + 'partner_id': self.booking_id.partner_id, + 'currency_id': self.currency_id, + }, + ) \ No newline at end of file diff --git a/hotel_management_odoo/report/room_booking_reports.xml b/hotel_management_odoo/report/room_booking_reports.xml new file mode 100644 index 000000000..3b18685c8 --- /dev/null +++ b/hotel_management_odoo/report/room_booking_reports.xml @@ -0,0 +1,60 @@ + + + + + Room Booking Order + room.booking + qweb-pdf + hotel_management_odoo.report_room_booking + hotel_management_odoo.report_room_booking + + report + + + + diff --git a/hotel_management_odoo/report/sale_order_reports.xml b/hotel_management_odoo/report/sale_order_reports.xml new file mode 100644 index 000000000..48ba3f885 --- /dev/null +++ b/hotel_management_odoo/report/sale_order_reports.xml @@ -0,0 +1,61 @@ + + + + + Sale Order + room.booking + qweb-pdf + hotel_management_odoo.report_sale_order + hotel_management_odoo.report_sale_order + + report + + + + diff --git a/hotel_management_odoo/security/hotel_management_odoo_groups.xml b/hotel_management_odoo/security/hotel_management_odoo_groups.xml new file mode 100644 index 000000000..b1d55d31b --- /dev/null +++ b/hotel_management_odoo/security/hotel_management_odoo_groups.xml @@ -0,0 +1,53 @@ + + + + + Hotel Management + Hotel Access Groups + 20 + + + + Maintenance Team User + + + + + Maintenance Team Leader + + + + + + Receptionist + + + + + Cleaning Team User + + + + + Cleaning Team Head + + + + + + Admin + + + + diff --git a/hotel_management_odoo/security/hotel_management_odoo_security.xml b/hotel_management_odoo/security/hotel_management_odoo_security.xml new file mode 100644 index 000000000..1ee6c3bce --- /dev/null +++ b/hotel_management_odoo/security/hotel_management_odoo_security.xml @@ -0,0 +1,67 @@ + + + + + Record Rule for Maintenance team leader + + + [('team_head_id', '=', user.id)] + + + + + + + + Record Rule for Maintenance User + + + [('assigned_user_id', '=', user.id)] + + + + + + + + Record Rule for hotel Admin + + + [(1,'=',1)] + + + + + + + + Cleaning Head Record Rule + + + [('team_id.team_head_id.id', '=', user.id)] + + + + + Cleaning User Record Rule + + + [('assigned_id.id', '=', user.id)] + + + + Cleaning Admin Record Rule + + + [(1, '=', 1)] + + diff --git a/hotel_management_odoo/security/ir.model.access.csv b/hotel_management_odoo/security/ir.model.access.csv new file mode 100644 index 000000000..7ac9c04ef --- /dev/null +++ b/hotel_management_odoo/security/ir.model.access.csv @@ -0,0 +1,21 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_hotel_amenity_user,access.hotel.amenity.user,model_hotel_amenity,base.group_user,1,1,1,1 +access_hotel_service_user,access.hotel.service.user,model_hotel_service,base.group_user,1,1,1,1 +access_hotel_floor_user,access.hotel.floor.user,model_hotel_floor,base.group_user,1,1,1,1 +access_hotel_room_user,access.hotel.room.user,model_hotel_room,base.group_user,1,1,1,1 +access_room_booking_user,access.room.booking.user,model_room_booking,base.group_user,1,1,1,1 +access_room_booking_line_user,access.room.booking.line.user,model_room_booking_line,base.group_user,1,1,1,1 +access_food_booking_line_user,access.food.booking.line.user,model_food_booking_line,base.group_user,1,1,1,1 +access_service_booking_line_user,access.service.booking.line.user,model_service_booking_line,base.group_user,1,1,1,1 +access_fleet_booking_line_user,access.fleet.booking.line.user,model_fleet_booking_line,base.group_user,1,1,1,1 +access_event_booking_line_user,access.event.booking.line.user,model_event_booking_line,base.group_user,1,1,1,1 +access_room_booking_detail_user,access.room.booking.detail.user,model_room_booking_detail,base.group_user,1,1,1,1 +access_sale_order_detail_user,access.sale.order.detail.user,model_sale_order_detail,base.group_user,1,1,1,1 +access_maintenance_team_maintenance_team_group_leader,access.maintenance.team.maintenance_team_group_leader,model_maintenance_team,hotel_management_odoo.maintenance_team_group_leader,1,1,1,1 +access_maintenance_request_hotel_group_admin,access.maintenance.request.hotel_group_admin,model_maintenance_request,hotel_management_odoo.hotel_group_admin,1,1,1,1 +access_maintenance_request_maintenance_team_group_leader,access.maintenance.request.maintenance_team_group_leader,model_maintenance_request,hotel_management_odoo.maintenance_team_group_leader,1,1,1,1 +access_maintenance_request_maintenance_team_group_user,access.maintenance.request.maintenance_team_group_user,model_maintenance_request,hotel_management_odoo.maintenance_team_group_user,1,1,1,1 +access_cleaning_team_cleaning_team_group_head,access.cleaning.team.cleaning_team_group_head,model_cleaning_team,hotel_management_odoo.cleaning_team_group_head,1,1,1,1 +access_cleaning_request_hotel_group_admin,access.cleaning.request.hotel_group_admin,model_cleaning_request,hotel_management_odoo.hotel_group_admin,1,1,1,1 +access_cleaning_request_cleaning_team_group_head,access.cleaning.request.cleaning_team_group_head,model_cleaning_request,hotel_management_odoo.cleaning_team_group_head,1,1,1,1 +access_cleaning_request_cleaning_team_group_user,access.cleaning.request.cleaning_team_group_user,model_cleaning_request,hotel_management_odoo.cleaning_team_group_user,1,1,1,1 diff --git a/hotel_management_odoo/static/description/assets/cybro-icon.png b/hotel_management_odoo/static/description/assets/cybro-icon.png new file mode 100755 index 000000000..06e73e11d Binary files /dev/null and b/hotel_management_odoo/static/description/assets/cybro-icon.png differ diff --git a/hotel_management_odoo/static/description/assets/cybro-odoo.png b/hotel_management_odoo/static/description/assets/cybro-odoo.png new file mode 100755 index 000000000..ed02e07a4 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/cybro-odoo.png differ diff --git a/hotel_management_odoo/static/description/assets/h2.png b/hotel_management_odoo/static/description/assets/h2.png new file mode 100755 index 000000000..0bfc4707d Binary files /dev/null and b/hotel_management_odoo/static/description/assets/h2.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/arrows-repeat.svg b/hotel_management_odoo/static/description/assets/icons/arrows-repeat.svg new file mode 100755 index 000000000..1d7efabc5 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/arrows-repeat.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/banner-1.png b/hotel_management_odoo/static/description/assets/icons/banner-1.png new file mode 100755 index 000000000..c180db172 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/banner-1.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/banner-2.svg b/hotel_management_odoo/static/description/assets/icons/banner-2.svg new file mode 100755 index 000000000..e606d97d9 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/banner-2.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/banner-bg.png b/hotel_management_odoo/static/description/assets/icons/banner-bg.png new file mode 100755 index 000000000..a8238d3c0 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/banner-bg.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/banner-bg.svg b/hotel_management_odoo/static/description/assets/icons/banner-bg.svg new file mode 100755 index 000000000..b1378103e --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/banner-bg.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/banner-call.svg b/hotel_management_odoo/static/description/assets/icons/banner-call.svg new file mode 100755 index 000000000..96c687e81 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/banner-call.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/banner-mail.svg b/hotel_management_odoo/static/description/assets/icons/banner-mail.svg new file mode 100755 index 000000000..cbf0d158d --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/banner-mail.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/banner-pattern.svg b/hotel_management_odoo/static/description/assets/icons/banner-pattern.svg new file mode 100755 index 000000000..9c1c7e101 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/banner-pattern.svg @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/banner-promo.svg b/hotel_management_odoo/static/description/assets/icons/banner-promo.svg new file mode 100755 index 000000000..d52791b11 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/banner-promo.svg @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/brand-pair.svg b/hotel_management_odoo/static/description/assets/icons/brand-pair.svg new file mode 100755 index 000000000..d8db7fc1e --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/brand-pair.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/check.png b/hotel_management_odoo/static/description/assets/icons/check.png new file mode 100755 index 000000000..c8e85f51d Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/check.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/chevron.png b/hotel_management_odoo/static/description/assets/icons/chevron.png new file mode 100755 index 000000000..2089293d6 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/chevron.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/close-icon.svg b/hotel_management_odoo/static/description/assets/icons/close-icon.svg new file mode 100755 index 000000000..df8cce37a --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/close-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/cogs.png b/hotel_management_odoo/static/description/assets/icons/cogs.png new file mode 100755 index 000000000..95d0bad62 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/cogs.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/collabarate-icon.svg b/hotel_management_odoo/static/description/assets/icons/collabarate-icon.svg new file mode 100755 index 000000000..dd4e10518 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/collabarate-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/hotel_management_odoo/static/description/assets/icons/consultation.png b/hotel_management_odoo/static/description/assets/icons/consultation.png new file mode 100755 index 000000000..8319d4baa Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/consultation.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/cybro-logo.png b/hotel_management_odoo/static/description/assets/icons/cybro-logo.png new file mode 100755 index 000000000..ff4b78220 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/cybro-logo.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/down.svg b/hotel_management_odoo/static/description/assets/icons/down.svg new file mode 100755 index 000000000..f21c36271 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hotel_management_odoo/static/description/assets/icons/ecom-black.png b/hotel_management_odoo/static/description/assets/icons/ecom-black.png new file mode 100755 index 000000000..a9385ff13 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/ecom-black.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/education-black.png b/hotel_management_odoo/static/description/assets/icons/education-black.png new file mode 100755 index 000000000..3eb09b27b Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/education-black.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/faq.png b/hotel_management_odoo/static/description/assets/icons/faq.png new file mode 100755 index 000000000..4250b5b81 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/faq.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/feature-icon.svg b/hotel_management_odoo/static/description/assets/icons/feature-icon.svg new file mode 100755 index 000000000..fa0ea6850 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/feature-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/feature.png b/hotel_management_odoo/static/description/assets/icons/feature.png new file mode 100755 index 000000000..ac7a785c0 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/feature.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/gear.svg b/hotel_management_odoo/static/description/assets/icons/gear.svg new file mode 100755 index 000000000..0cc66b6ea --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/gear.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/hero.gif b/hotel_management_odoo/static/description/assets/icons/hero.gif new file mode 100644 index 000000000..2a0e29bdd Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/hero.gif differ diff --git a/hotel_management_odoo/static/description/assets/icons/hire-odoo.svg b/hotel_management_odoo/static/description/assets/icons/hire-odoo.svg new file mode 100755 index 000000000..e1ac089b0 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/hire-odoo.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/hotel-black.png b/hotel_management_odoo/static/description/assets/icons/hotel-black.png new file mode 100755 index 000000000..130f613be Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/hotel-black.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/license.png b/hotel_management_odoo/static/description/assets/icons/license.png new file mode 100755 index 000000000..a5869797e Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/license.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/life-ring-icon.svg b/hotel_management_odoo/static/description/assets/icons/life-ring-icon.svg new file mode 100755 index 000000000..3ae6e1d89 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/life-ring-icon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/lifebuoy.png b/hotel_management_odoo/static/description/assets/icons/lifebuoy.png new file mode 100755 index 000000000..658d56ccc Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/lifebuoy.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/mail.svg b/hotel_management_odoo/static/description/assets/icons/mail.svg new file mode 100755 index 000000000..1eedde695 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/mail.svg @@ -0,0 +1,3 @@ + + + diff --git a/hotel_management_odoo/static/description/assets/icons/manufacturing-black.png b/hotel_management_odoo/static/description/assets/icons/manufacturing-black.png new file mode 100755 index 000000000..697eb0e9f Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/manufacturing-black.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/notes.png b/hotel_management_odoo/static/description/assets/icons/notes.png new file mode 100755 index 000000000..ee5e95404 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/notes.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/notification icon.svg b/hotel_management_odoo/static/description/assets/icons/notification icon.svg new file mode 100755 index 000000000..053189973 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/notification icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/odoo-consultancy.svg b/hotel_management_odoo/static/description/assets/icons/odoo-consultancy.svg new file mode 100755 index 000000000..e05f65bde --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/odoo-consultancy.svg @@ -0,0 +1,4 @@ + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/odoo-licencing.svg b/hotel_management_odoo/static/description/assets/icons/odoo-licencing.svg new file mode 100755 index 000000000..2606c88b0 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/odoo-licencing.svg @@ -0,0 +1,3 @@ + + + diff --git a/hotel_management_odoo/static/description/assets/icons/odoo-logo.png b/hotel_management_odoo/static/description/assets/icons/odoo-logo.png new file mode 100755 index 000000000..0e4d0eb5a Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/odoo-logo.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/patter.svg b/hotel_management_odoo/static/description/assets/icons/patter.svg new file mode 100755 index 000000000..25c9c0a8f --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/patter.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/pattern1.png b/hotel_management_odoo/static/description/assets/icons/pattern1.png new file mode 100755 index 000000000..09ab0fb2d Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/pattern1.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/pos-black.png b/hotel_management_odoo/static/description/assets/icons/pos-black.png new file mode 100755 index 000000000..97c0f90c1 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/pos-black.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/puzzle-piece-icon.svg b/hotel_management_odoo/static/description/assets/icons/puzzle-piece-icon.svg new file mode 100755 index 000000000..3e9ad9373 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/puzzle-piece-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/puzzle.png b/hotel_management_odoo/static/description/assets/icons/puzzle.png new file mode 100755 index 000000000..65cf854e7 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/puzzle.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/replace-icon.svg b/hotel_management_odoo/static/description/assets/icons/replace-icon.svg new file mode 100755 index 000000000..d0e3a7af1 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/replace-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/restaurant-black.png b/hotel_management_odoo/static/description/assets/icons/restaurant-black.png new file mode 100755 index 000000000..4a35eb939 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/restaurant-black.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/screenshot-main.png b/hotel_management_odoo/static/description/assets/icons/screenshot-main.png new file mode 100755 index 000000000..575f8e676 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/screenshot-main.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/screenshot.png b/hotel_management_odoo/static/description/assets/icons/screenshot.png new file mode 100755 index 000000000..cef272529 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/screenshot.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/service-black.png b/hotel_management_odoo/static/description/assets/icons/service-black.png new file mode 100755 index 000000000..301ab51cb Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/service-black.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/skype-fill.svg b/hotel_management_odoo/static/description/assets/icons/skype-fill.svg new file mode 100755 index 000000000..c17423639 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/skype-fill.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/skype.png b/hotel_management_odoo/static/description/assets/icons/skype.png new file mode 100755 index 000000000..51b409fb3 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/skype.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/skype.svg b/hotel_management_odoo/static/description/assets/icons/skype.svg new file mode 100755 index 000000000..df3dad39b --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/skype.svg @@ -0,0 +1,3 @@ + + + diff --git a/hotel_management_odoo/static/description/assets/icons/star-1.svg b/hotel_management_odoo/static/description/assets/icons/star-1.svg new file mode 100755 index 000000000..7e55ab162 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/star-1.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/star-2.svg b/hotel_management_odoo/static/description/assets/icons/star-2.svg new file mode 100755 index 000000000..5ae9f507a --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/star-2.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/support.png b/hotel_management_odoo/static/description/assets/icons/support.png new file mode 100755 index 000000000..4f18b8b82 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/support.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/test-1 - Copy.png b/hotel_management_odoo/static/description/assets/icons/test-1 - Copy.png new file mode 100755 index 000000000..f6a902663 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/test-1 - Copy.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/test-1.png b/hotel_management_odoo/static/description/assets/icons/test-1.png new file mode 100755 index 000000000..0908add2b Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/test-1.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/test-2.png b/hotel_management_odoo/static/description/assets/icons/test-2.png new file mode 100755 index 000000000..4671fe91e Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/test-2.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/trading-black.png b/hotel_management_odoo/static/description/assets/icons/trading-black.png new file mode 100755 index 000000000..9398ba2f1 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/trading-black.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/training.png b/hotel_management_odoo/static/description/assets/icons/training.png new file mode 100755 index 000000000..884ca024d Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/training.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/translate.svg b/hotel_management_odoo/static/description/assets/icons/translate.svg new file mode 100755 index 000000000..af9c8a1aa --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/translate.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/update.png b/hotel_management_odoo/static/description/assets/icons/update.png new file mode 100755 index 000000000..ecbc5a01a Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/update.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/user.png b/hotel_management_odoo/static/description/assets/icons/user.png new file mode 100755 index 000000000..6ffb23d9f Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/user.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/video.png b/hotel_management_odoo/static/description/assets/icons/video.png new file mode 100755 index 000000000..576705b17 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/video.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/whatsapp.png b/hotel_management_odoo/static/description/assets/icons/whatsapp.png new file mode 100755 index 000000000..d513a5356 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/whatsapp.png differ diff --git a/hotel_management_odoo/static/description/assets/icons/wrench-icon.svg b/hotel_management_odoo/static/description/assets/icons/wrench-icon.svg new file mode 100755 index 000000000..174b5a465 --- /dev/null +++ b/hotel_management_odoo/static/description/assets/icons/wrench-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/hotel_management_odoo/static/description/assets/icons/wrench.png b/hotel_management_odoo/static/description/assets/icons/wrench.png new file mode 100755 index 000000000..6c04dea0f Binary files /dev/null and b/hotel_management_odoo/static/description/assets/icons/wrench.png differ diff --git a/hotel_management_odoo/static/description/assets/modules/1.jpg b/hotel_management_odoo/static/description/assets/modules/1.jpg new file mode 100644 index 000000000..3cb15fe01 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/modules/1.jpg differ diff --git a/hotel_management_odoo/static/description/assets/modules/2.jpg b/hotel_management_odoo/static/description/assets/modules/2.jpg new file mode 100644 index 000000000..662cadcc3 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/modules/2.jpg differ diff --git a/hotel_management_odoo/static/description/assets/modules/3.jpg b/hotel_management_odoo/static/description/assets/modules/3.jpg new file mode 100644 index 000000000..717a00443 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/modules/3.jpg differ diff --git a/hotel_management_odoo/static/description/assets/modules/4.png b/hotel_management_odoo/static/description/assets/modules/4.png new file mode 100644 index 000000000..00ebf54ad Binary files /dev/null and b/hotel_management_odoo/static/description/assets/modules/4.png differ diff --git a/hotel_management_odoo/static/description/assets/modules/5.jpg b/hotel_management_odoo/static/description/assets/modules/5.jpg new file mode 100644 index 000000000..7c67e2eec Binary files /dev/null and b/hotel_management_odoo/static/description/assets/modules/5.jpg differ diff --git a/hotel_management_odoo/static/description/assets/modules/6.gif b/hotel_management_odoo/static/description/assets/modules/6.gif new file mode 100644 index 000000000..a35ece8df Binary files /dev/null and b/hotel_management_odoo/static/description/assets/modules/6.gif differ diff --git a/hotel_management_odoo/static/description/assets/screenshots/ss1.png b/hotel_management_odoo/static/description/assets/screenshots/ss1.png new file mode 100644 index 000000000..14ca7c8cd Binary files /dev/null and b/hotel_management_odoo/static/description/assets/screenshots/ss1.png differ diff --git a/hotel_management_odoo/static/description/assets/screenshots/ss10.png b/hotel_management_odoo/static/description/assets/screenshots/ss10.png new file mode 100644 index 000000000..c5c1ce72f Binary files /dev/null and b/hotel_management_odoo/static/description/assets/screenshots/ss10.png differ diff --git a/hotel_management_odoo/static/description/assets/screenshots/ss11.png b/hotel_management_odoo/static/description/assets/screenshots/ss11.png new file mode 100644 index 000000000..51637067f Binary files /dev/null and b/hotel_management_odoo/static/description/assets/screenshots/ss11.png differ diff --git a/hotel_management_odoo/static/description/assets/screenshots/ss12.png b/hotel_management_odoo/static/description/assets/screenshots/ss12.png new file mode 100644 index 000000000..90e305fe3 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/screenshots/ss12.png differ diff --git a/hotel_management_odoo/static/description/assets/screenshots/ss13.png b/hotel_management_odoo/static/description/assets/screenshots/ss13.png new file mode 100644 index 000000000..1de39d75f Binary files /dev/null and b/hotel_management_odoo/static/description/assets/screenshots/ss13.png differ diff --git a/hotel_management_odoo/static/description/assets/screenshots/ss14.png b/hotel_management_odoo/static/description/assets/screenshots/ss14.png new file mode 100644 index 000000000..cf1e55054 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/screenshots/ss14.png differ diff --git a/hotel_management_odoo/static/description/assets/screenshots/ss15.png b/hotel_management_odoo/static/description/assets/screenshots/ss15.png new file mode 100644 index 000000000..17fa0f896 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/screenshots/ss15.png differ diff --git a/hotel_management_odoo/static/description/assets/screenshots/ss2.png b/hotel_management_odoo/static/description/assets/screenshots/ss2.png new file mode 100644 index 000000000..cb43db85e Binary files /dev/null and b/hotel_management_odoo/static/description/assets/screenshots/ss2.png differ diff --git a/hotel_management_odoo/static/description/assets/screenshots/ss3.png b/hotel_management_odoo/static/description/assets/screenshots/ss3.png new file mode 100644 index 000000000..14ca7c8cd Binary files /dev/null and b/hotel_management_odoo/static/description/assets/screenshots/ss3.png differ diff --git a/hotel_management_odoo/static/description/assets/screenshots/ss4.png b/hotel_management_odoo/static/description/assets/screenshots/ss4.png new file mode 100644 index 000000000..91c0046f9 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/screenshots/ss4.png differ diff --git a/hotel_management_odoo/static/description/assets/screenshots/ss5.png b/hotel_management_odoo/static/description/assets/screenshots/ss5.png new file mode 100644 index 000000000..0d2d98e82 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/screenshots/ss5.png differ diff --git a/hotel_management_odoo/static/description/assets/screenshots/ss6.png b/hotel_management_odoo/static/description/assets/screenshots/ss6.png new file mode 100644 index 000000000..a87983d59 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/screenshots/ss6.png differ diff --git a/hotel_management_odoo/static/description/assets/screenshots/ss7.png b/hotel_management_odoo/static/description/assets/screenshots/ss7.png new file mode 100644 index 000000000..5746bad9b Binary files /dev/null and b/hotel_management_odoo/static/description/assets/screenshots/ss7.png differ diff --git a/hotel_management_odoo/static/description/assets/screenshots/ss8.png b/hotel_management_odoo/static/description/assets/screenshots/ss8.png new file mode 100644 index 000000000..3b87461a1 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/screenshots/ss8.png differ diff --git a/hotel_management_odoo/static/description/assets/screenshots/ss9.png b/hotel_management_odoo/static/description/assets/screenshots/ss9.png new file mode 100644 index 000000000..d087a4d93 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/screenshots/ss9.png differ diff --git a/hotel_management_odoo/static/description/assets/y18.jpg b/hotel_management_odoo/static/description/assets/y18.jpg new file mode 100755 index 000000000..eea1714f2 Binary files /dev/null and b/hotel_management_odoo/static/description/assets/y18.jpg differ diff --git a/hotel_management_odoo/static/description/banner.jpg b/hotel_management_odoo/static/description/banner.jpg new file mode 100644 index 000000000..c5d22e2df Binary files /dev/null and b/hotel_management_odoo/static/description/banner.jpg differ diff --git a/hotel_management_odoo/static/description/icon.png b/hotel_management_odoo/static/description/icon.png new file mode 100644 index 000000000..34bc6ec7f Binary files /dev/null and b/hotel_management_odoo/static/description/icon.png differ diff --git a/hotel_management_odoo/static/description/index.html b/hotel_management_odoo/static/description/index.html new file mode 100644 index 000000000..7934e09d5 --- /dev/null +++ b/hotel_management_odoo/static/description/index.html @@ -0,0 +1,1361 @@ + + + + + + Hotel Management + + + + + + + + + + +
+
+ + + +
+
+ Community +
+
+ Enterprise +
+ + + + +
+
+ +
+
+
+
+

+ A Complete Hotel Management System that Cover All Areas of Hotel Services. +

+

Hotel Management +

+
+
+ +
+ +
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+

Key + Highlights

+
+
+
+
+ +
+
+ Odoo 18 Community & Enterprise Edition Support +
+

+ Hotel Management in Odoo 18 Community & Enterprise Edition.

+
+
+
+
+
+ +
+
+ Room Reservation +
+

+ Reserve Hotel Rooms based on requirement of Room Capacity and Room Type. +

+
+
+
+
+
+ +
+
+ Service, Food & Vehicle Management +
+

+ Order Service, Food and vehicle as per need. +

+
+
+
+
+
+ +
+
+ Event Management +
+

+ Book Slots for your favorite Event. +

+
+
+
+
+
+ +
+
+ Maintenance Management +
+

+ Request for Maintenance work as per need. +

+
+
+
+
+ +
+
+
+ Hotel Management +

+ Are you ready to make your business more + organized? +
Improve now! +

+ +
+
+ +
+
+
+ + + + +
+
+ +
+
+
+
+ acc_bg +
+ +
+
+
+
+

+ User + Configuration + +

+
+
+

+ In the user Form Page there is Some fields to give the access Permission. +

+
+
+
+ +
+
+
+
+
+
+
+
+

+ Dashboard +

+
+
+ +
+
+
+
+
+
+
+
+
+

+ User + access Level + +

+
+
+

+ Can Set up the User access Level in user form page. +

+
+
+
+ +
+
+
+
+
+
+
+
+
+

+ Room booking + form page + +

+
+
+

+ User-friendly Room booking form page, easy to use. +

+
+
+
+ +
+
+
+
+
+
+
+
+
+

+ Room booking + Tree view + +

+
+
+

+ User can easily manage the list of records. +

+
+
+
+ +
+
+
+
+
+
+
+
+
+

+ Vendor + section. + +

+
+
+

+ Can Set up the vendor from here. +

+
+
+
+ +
+
+
+
+
+
+
+
+
+

+ Report +

+
+
+

+ Can Print out the sale order reports. +

+
+
+
+ +
+
+
+
+
+
+
+
+
+

+ Different + + Report types +

+
+
+

+ Can Download XLSX and PDF report. +

+
+
+
+ +
+
+
+
+
+
+
+
+
+

+ Product + section. + +

+
+
+

+ Can Manage Product from the Product model. +

+
+
+
+ +
+
+
+
+
+
+
+
+
+

+ Manufactures + section. + +

+
+
+

+ Can Manage Manufactures from the Manufactures model. +

+
+
+
+ +
+
+
+
+
+
+
+
+
+

+ Room maintaining team + section. + +

+
+
+

+ Can Manage Room maintaining team from here. +

+
+
+
+ +
+
+
+
+
+
+
+
+
+

+ Maintain request + section. + +

+
+
+

+ Can Manage Maintain request with the Maintain request model. +

+
+
+
+ +
+
+
+
+
+
+
+
+
+

+ Configuration + menu + +

+
+
+

+ Can configure Room , services , floor etc. with the Configuration model. +

+
+
+
+ +
+
+
+
+
+
+
+
+
+

+ Room cleaning team + section. + +

+
+
+

+ Can Manage Room cleaning team from here. +

+
+
+
+ +
+
+
+
+
+
+
+
+
+

+ Cleaning request + section. + +

+
+
+

+ Can Manage Cleaning request with the Cleaning request model. +

+
+
+
+ +
+
+
+
+
+
+
+
+ +
+
+
+
+ +
+

+ Reserve Hotel Rooms based on requirement.

+
+
+
+
+
+
+
+ +
+

+ Book Slots for your favorite Event. +

+
+
+
+
+
+
+
+ +
+

+ Request for Maintenance work as per need. +

+
+
+
+
+
+
+
+ +
+

+ Order Service, Food and vehicle as per need. +

+
+
+
+
+
+
+
+ +
+

+ Can Set up the User access Level. +

+
+
+
+
+
+
+
+ +
+

+ Can Download XLSX and PDF reports. +

+
+
+
+
+
+
+
+
+
+
+ +
+ +
+ +
+

+ Yes, the module allows you to generate detailed reports in both XLSX and PDF formats. +

+
+
+ +
+ +
+

+ Yes, you can monitor the status of your room reservations, Available Rooms, and Available Vehicle in real-time within the module’s dashboard. +

+
+
+
+ +
+
+
+
+
+
+ +
+
+

+ Latest Release 18.0.1.0.0 +

+ + 1st October, 2024 + +
+
+
+
+
+ Add +
+
+
+
    +
  • + Initial Commit +
  • + +
+
+
+
+
+
+
+
+
+
+ + +
+

+ Related Products +

+ +
+ + + +
+

+ Our Services

+ +
+ +
+
+ .... +
+
+ +
+ + +
+
+ + + + + + diff --git a/hotel_management_odoo/static/src/css/dashboard.css b/hotel_management_odoo/static/src/css/dashboard.css new file mode 100644 index 000000000..eb0da9423 --- /dev/null +++ b/hotel_management_odoo/static/src/css/dashboard.css @@ -0,0 +1,35 @@ +html .o_web_client > .o_action_manager{ + overflow: scroll; +} +.main-section{ + margin:25px; + padding:0px; + background: none; +} +.oh_dashboards { + padding: 0px !important; +} +.dash-card .card{ + text-align:center; + border:none; + margin:20px; +} +.dash-card .card:hover { + + transform: translateY(-2px) translateZ(0) !important; + box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important; + +} +.dash-card .dash-count{ + font-size:35px; +} +.dash-card .dash-icon-1{ + width:100%; + font-size: 36px; + font-weight: 900; + margin-top:10px; +} +.dash-card .dash-head{ + font-weight: 300; + font-size: 18px; +} diff --git a/hotel_management_odoo/static/src/js/action_manager.js b/hotel_management_odoo/static/src/js/action_manager.js new file mode 100644 index 000000000..112f4f92d --- /dev/null +++ b/hotel_management_odoo/static/src/js/action_manager.js @@ -0,0 +1,23 @@ +/** @odoo-module **/ +import { registry } from "@web/core/registry"; +import { BlockUI } from "@web/core/ui/block_ui"; +import { download } from "@web/core/network/download"; +/** +XLSX Handler +This handler is responsible for generating XLSX reports. +It sends a request to the server to generate the report in XLSX format +and downloads the generated file. +@param {Object} action - The action object containing the report details. +@returns {Promise} - A promise that resolves when the report generation is complete. +*/ +registry.category("ir.actions.report handlers").add("xlsx", async function (action) { + if (action.report_type === 'xlsx') { + BlockUI; + await download({ + url: '/xlsx_reports', + data: action.data, + complete: () => unblockUI, + error: (error) => self.call('crash_manager', 'rpc_error', error), + }); + } +}); diff --git a/hotel_management_odoo/static/src/js/dashboard_action.js b/hotel_management_odoo/static/src/js/dashboard_action.js new file mode 100644 index 000000000..7066e0161 --- /dev/null +++ b/hotel_management_odoo/static/src/js/dashboard_action.js @@ -0,0 +1,296 @@ +/** @odoo-module */ +import { registry} from '@web/core/registry'; +import { useService } from "@web/core/utils/hooks"; +const { Component, onWillStart, onMounted} = owl +import { rpc } from "@web/core/network/rpc"; +import { Domain } from "@web/core/domain"; +import { _t } from "@web/core/l10n/translation"; +import {serializeDate,serializeDateTime,} from "@web/core/l10n/dates"; +const today = new Date(); +const day = today.getDate(); // Returns the day of the month (1-31) +const month = today.getMonth() + 1; // Returns the month (0-11); Adding 1 to match regular months (1-12) +const year = today.getFullYear(); // Returns the year (4 digits) +// Display the current date in a specific format (e.g., MM/DD/YYYY) +const formattedDate = `${year}-${month}-${day}`; +export class CustomDashBoard extends Component { + /** + * Setup method to initialize required services and register event handlers. + */ +setup() { + this.action = useService("action"); + this.orm = useService("orm"); + onWillStart(this.onWillStart); + onMounted(this.onMounted); +} +async onWillStart() { + await this.fetch_data(); +} +async onMounted() { +// Render other components after fetching data +// this.render_project_task(); +// this.render_top_employees_graph(); +// this.render_filter(); +} +async fetch_data() { + var self = this; + //RPC call for retrieving data for displaying on dashboard tiles + var def1= await rpc('/web/dataset/call_kw/room.booking/get_details' + ,{ model:'room.booking', + method:'get_details', + args: [{}], + kwargs: {}, + }).then(function(result){ + document.getElementsByClassName("total_room").innerHTML=['total_room'] + self.total_room=result['total_room'] + self.available_room=result['available_room'] + self.staff=result['staff'] + self.check_in=result['check_in'] + self.reservation=result['reservation'] + self.check_out=result['check_out'] + self.total_vehicle=result['total_vehicle'] + self.available_vehicle=result['available_vehicle'] + self.total_event=result['total_event'] + self.today_events=result['today_events'] + self.pending_events=result['pending_events'] + self.food_items=result['food_items'] + self.food_order=result['food_order'] + if(result['currency_position']=='before'){ + self.total_revenue=result['currency_symbol']+" "+result['total_revenue'] + self.today_revenue=result['currency_symbol']+" "+result['today_revenue'] + self.pending_payment=result['currency_symbol']+" "+result['pending_payment'] + } + else{ + self.total_revenue=+result['total_revenue']+" "+result['currency_symbol'] + self.today_revenue=result['today_revenue']+" "+result['currency_symbol'] + self.pending_payment=result['pending_payment']+" "+result['currency_symbol'] + } + + }); + + return def1; + } + total_rooms(e){ + var self = this; + e.stopPropagation(); + e.preventDefault(); + var options={on_reverse_breadcrum:this.on_reverse_breadcrum,}; + this.action.doAction({ + name: _t("Rooms"), + type:'ir.actions.act_window', + res_model:'hotel.room', + view_mode:'list,form', + view_type:'form', + views:[[false,'list'],[false,'form']], + target:'current' + },options) + } + check_ins(e){ + var self = this; + e.stopPropagation(); + e.preventDefault(); + var options={on_reverse_breadcrum:this.on_reverse_breadcrum,}; + this.action.doAction({ + name: _t("Check-In"), + type:'ir.actions.act_window', + res_model:'room.booking', + view_mode:'list,form', + view_type:'form', + views:[[false,'list'],[false,'form']], + domain: [['state', '=', 'check_in']], + target:'current' + },options) + } + // Total Events + view_total_events(e){ + var self = this; + e.stopPropagation(); + e.preventDefault(); + var options={on_reverse_breadcrum:this.on_reverse_breadcrum,}; + this.action.doAction({ + name: _t("Total Events"), + type:'ir.actions.act_window', + res_model:'event.event', + view_mode:'kanban,list,form', + view_type:'form', + views:[[false,'kanban'],[false,'list'],[false,'form']], + domain: [], + target:'current' + },options) + } +// // Today's Events + fetch_today_events(e){ + var self = this; + e.stopPropagation(); + e.preventDefault(); + var options={on_reverse_breadcrum:this.on_reverse_breadcrum,}; + this.action.doAction({ + name: _t("Today's Events"), + type:'ir.actions.act_window', + res_model:'event.event', + view_mode:'kanban,list,form', + view_type:'form', + views:[[false,'kanban'],[false,'list'],[false,'form']], + domain: [['date_end', '=', formattedDate]], + target:'current' + },options) + } +// // Pending Events + fetch_pending_events(e){ + var self = this; + e.stopPropagation(); + e.preventDefault(); + var options={on_reverse_breadcrum:this.on_reverse_breadcrum,}; + this.action.doAction({ + name: _t("Pending Events"), + type:'ir.actions.act_window', + res_model:'event.event', + view_mode:'kanban,list,form', + view_type:'form', + views:[[false,'kanban'],[false,'list'],[false,'form']], + domain: [['date_end', '>=', formattedDate]], + target:'current' + },options) + } +// // Total staff + fetch_total_staff(e){ + var self = this; + e.stopPropagation(); + e.preventDefault(); + var options={on_reverse_breadcrum:this.on_reverse_breadcrum,}; + this.action.doAction({ + name: _t("Total Staffs"), + type:'ir.actions.act_window', + res_model:'res.users', + view_mode:'list,form', + view_type:'form', + views:[[false,'list'],[false,'form']], + domain: [['groups_id.name', 'in',['Admin', + 'Cleaning Team User', + 'Cleaning Team Head', + 'Receptionist', + 'Maintenance Team User', + 'Maintenance Team Leader' + ]]], + target:'current' + },options) + } + // check-out + check_outs(e){ + var self = this; + var options={on_reverse_breadcrum:this.on_reverse_breadcrum,}; + this.action.doAction({ + name: _t("Today's Check-Out"), + type:'ir.actions.act_window', + res_model:'room.booking', + view_mode:'list,form', + view_type:'form', + views:[[false,'list'],[false,'form']], + domain: [['room_line_ids.checkout_date', '=', formattedDate]], + target:'current' + },options) + } +// Available rooms + available_rooms(e){ + var self = this; + e.stopPropagation(); + e.preventDefault(); + var options={on_reverse_breadcrum:this.on_reverse_breadcrum,}; + this.action.doAction({ + name: _t("Available Room"), + type:'ir.actions.act_window', + res_model:'hotel.room', + view_mode:'list,form', + view_type:'form', + views:[[false,'list'],[false,'form']], + domain: [['status', '=', 'available']], + target:'current' + },options) + } +// Reservations + reservations(e){ + var self = this; + e.stopPropagation(); + e.preventDefault(); + var options={on_reverse_breadcrum:this.on_reverse_breadcrum,}; + this.action.doAction({ + name: _t("Total Reservations"), + type:'ir.actions.act_window', + res_model:'room.booking', + view_mode:'list,form', + view_type:'form', + views:[[false,'list'],[false,'form']], + domain: [['state', '=', 'reserved']], + target:'current' + },options) + } +// Food Items + fetch_food_item(e){ + var self = this; + e.stopPropagation(); + e.preventDefault(); + var options={on_reverse_breadcrum:this.on_reverse_breadcrum,}; + this.action.doAction({ + name: _t("Food Items"), + type:'ir.actions.act_window', + res_model:'lunch.product', + view_mode:'list,form', + view_type:'form', + views:[[false,'list'],[false,'form']], + domain: [], + target:'current' + },options) + } +// food Orders + async fetch_food_order(e){ + var self = this; + const result = await this.orm.call('food.booking.line', 'search_food_orders',[{}],{}); + e.stopPropagation(); + e.preventDefault(); + var options={on_reverse_breadcrum:this.on_reverse_breadcrum,}; + this.action.doAction({ + name: _t("Food Orders"), + type:'ir.actions.act_window', + res_model:'food.booking.line', + view_mode:'list,form', + view_type:'form', + views:[[false,'list'],[false,'form']], + domain: [['id','in', result]], + target:'current' + },options) + } +// total vehicle + fetch_total_vehicle(e){ + var self = this; + e.stopPropagation(); + e.preventDefault(); + var options={on_reverse_breadcrum:this.on_reverse_breadcrum,}; + this.action.doAction({name: _t("Total Vehicles"), + type:'ir.actions.act_window', + res_model:'fleet.vehicle.model', + view_mode:'list,form', + view_type:'form', + views:[[false,'list'],[false,'form']], + target:'current' + },options) + } +// Available Vehicle + async fetch_available_vehicle(e){ + const result = await this.orm.call('fleet.booking.line', 'search_available_vehicle',[{}],{}); + var self = this; + var options={on_reverse_breadcrum:this.on_reverse_breadcrum,}; + e.stopPropagation(); + e.preventDefault(); + this.action.doAction({ + name: _t("Available Vehicle"), + type:'ir.actions.act_window', + res_model:'fleet.vehicle.model', + view_mode:'list,form', + view_type:'form', + views:[[false,'list'],[false,'form']], + domain: [['id','not in', result]], + target:'current' + },options) + } +} +CustomDashBoard.template = "CustomDashBoard" +registry.category("actions").add("custom_dashboard_tags", CustomDashBoard) \ No newline at end of file diff --git a/hotel_management_odoo/static/src/xml/dashboard_templates.xml b/hotel_management_odoo/static/src/xml/dashboard_templates.xml new file mode 100644 index 000000000..c91dfeafa --- /dev/null +++ b/hotel_management_odoo/static/src/xml/dashboard_templates.xml @@ -0,0 +1,287 @@ + + + diff --git a/hotel_management_odoo/views/account_move_views.xml b/hotel_management_odoo/views/account_move_views.xml new file mode 100644 index 000000000..4736ce654 --- /dev/null +++ b/hotel_management_odoo/views/account_move_views.xml @@ -0,0 +1,16 @@ + + + + + + account.move.view.form.inherit.odoo.hotel.management + + account.move + + + + + + + + diff --git a/hotel_management_odoo/views/cleaning_request_views.xml b/hotel_management_odoo/views/cleaning_request_views.xml new file mode 100644 index 000000000..25a132ef0 --- /dev/null +++ b/hotel_management_odoo/views/cleaning_request_views.xml @@ -0,0 +1,114 @@ + + + + + cleaning.request.view.tree + cleaning.request + + + + + + + + + + + + cleaning.request.view.form + cleaning.request + +
+
+
+ +

+ +

+ + + + + + + + + + + + + + + + +
+ + +
+
+ + + cleaning.team.view.tree + cleaning.team + + + + + + + + + + Cleaning Request + cleaning.request + ir.actions.act_window + list,form + {} + + + +
diff --git a/hotel_management_odoo/views/cleaning_team_views.xml b/hotel_management_odoo/views/cleaning_team_views.xml new file mode 100644 index 000000000..1edd1b94f --- /dev/null +++ b/hotel_management_odoo/views/cleaning_team_views.xml @@ -0,0 +1,77 @@ + + + + + cleaning.team.view.tree + cleaning.team + + + + + + + + + + cleaning.team.view.form + cleaning.team + +
+ + + + + + + + + + + + + + + + + + +
+
+
+ + + Cleaning Team + cleaning.team + ir.actions.act_window + list,form + {} + + + + + +
diff --git a/hotel_management_odoo/views/dashboard_view.xml b/hotel_management_odoo/views/dashboard_view.xml new file mode 100644 index 000000000..d94d05589 --- /dev/null +++ b/hotel_management_odoo/views/dashboard_view.xml @@ -0,0 +1,13 @@ + + + + + Dashboard + custom_dashboard_tags + + + + diff --git a/hotel_management_odoo/views/fleet_vehicle_model_views.xml b/hotel_management_odoo/views/fleet_vehicle_model_views.xml new file mode 100644 index 000000000..19611192d --- /dev/null +++ b/hotel_management_odoo/views/fleet_vehicle_model_views.xml @@ -0,0 +1,48 @@ + + + + + + fleet.vehicle.model.view.form.inherit.odoo.hotel.management + + fleet.vehicle.model + + + + + + + + + + + Vehicles + fleet.vehicle.model + list,form + +

+ No Vehicles found ! Let's create one +

+
+
+ + + Manufacturers + fleet.vehicle.model.brand + kanban,list,form + +

+ No Manufacturers found ! Let's create one +

+
+
+ + + + +
diff --git a/hotel_management_odoo/views/food_booking_line_views.xml b/hotel_management_odoo/views/food_booking_line_views.xml new file mode 100644 index 000000000..cde8643b5 --- /dev/null +++ b/hotel_management_odoo/views/food_booking_line_views.xml @@ -0,0 +1,48 @@ + + + + + food.booking.line.view.form + food.booking.line + +
+ +

+ +

+ + + + + + + + + + + + + +
+
+
+
+ + + food.booking.line.view.tree + food.booking.line + + + + + + + + + + + + + +
+ diff --git a/hotel_management_odoo/views/hotel_amenity_views.xml b/hotel_management_odoo/views/hotel_amenity_views.xml new file mode 100644 index 000000000..0b59db641 --- /dev/null +++ b/hotel_management_odoo/views/hotel_amenity_views.xml @@ -0,0 +1,54 @@ + + + + + hotel.amenity.view.tree + hotel.amenity + + + + + + + + + hotel.amenity.view.form + hotel.amenity + +
+ + + + + + + + + + + + + +
+
+ + + Amenity + ir.actions.act_window + hotel.amenity + list,form + {'default_detailed_type': 'service'} + +

+ No Amenity found ! Let's create one +

+
+
+ + +
diff --git a/hotel_management_odoo/views/hotel_detail_views.xml b/hotel_management_odoo/views/hotel_detail_views.xml new file mode 100644 index 000000000..bbf316490 --- /dev/null +++ b/hotel_management_odoo/views/hotel_detail_views.xml @@ -0,0 +1,43 @@ + + + + + hotel.details.view.tree + hotel.detail + + + + + + + + + + hotel.details.view.form + hotel.detail + +
+ + + + + + + +
+
+
+ + + Hotel Details + ir.actions.act_window + hotel.detail + list,form + + + +
diff --git a/hotel_management_odoo/views/hotel_floor_views.xml b/hotel_management_odoo/views/hotel_floor_views.xml new file mode 100644 index 000000000..d0147dd27 --- /dev/null +++ b/hotel_management_odoo/views/hotel_floor_views.xml @@ -0,0 +1,32 @@ + + + + + hotel.floor.view.tree + hotel.floor + + + + + + + + + + Floors + ir.actions.act_window + hotel.floor + list + +

+ No Floors found ! Let's create one +

+
+
+ + +
diff --git a/hotel_management_odoo/views/hotel_menu_views.xml b/hotel_management_odoo/views/hotel_menu_views.xml new file mode 100644 index 000000000..323b9e47e --- /dev/null +++ b/hotel_management_odoo/views/hotel_menu_views.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + diff --git a/hotel_management_odoo/views/hotel_room_views.xml b/hotel_management_odoo/views/hotel_room_views.xml new file mode 100644 index 000000000..719f15ebe --- /dev/null +++ b/hotel_management_odoo/views/hotel_room_views.xml @@ -0,0 +1,96 @@ + + + + + hotel.room.view.tree + hotel.room + + + + + + + + + + + + + hotel.room.view.form + hotel.room + +
+
+ +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ + + Rooms + ir.actions.act_window + hotel.room + list,form + {'default_is_room_avail':True} + +

+ No Rooms found ! Let's create one +

+
+
+ + +
diff --git a/hotel_management_odoo/views/hotel_service_views.xml b/hotel_management_odoo/views/hotel_service_views.xml new file mode 100644 index 000000000..a75cc022a --- /dev/null +++ b/hotel_management_odoo/views/hotel_service_views.xml @@ -0,0 +1,32 @@ + + + + + hotel.service.view.tree + hotel.service + + + + + + + + + + + Services + hotel.service + list + +

+ No Services found ! Let's create one +

+
+
+ + +
diff --git a/hotel_management_odoo/views/lunch_product_views.xml b/hotel_management_odoo/views/lunch_product_views.xml new file mode 100644 index 000000000..56983efc0 --- /dev/null +++ b/hotel_management_odoo/views/lunch_product_views.xml @@ -0,0 +1,37 @@ + + + + + Products + lunch.product + list,kanban,form + +

+ No Products found ! Let's create one +

+
+
+ + + Vendors + lunch.supplier + kanban,list,form + +

+ No Vendors found ! Let's create one +

+
+
+ + + + +
diff --git a/hotel_management_odoo/views/maintenance_request_views.xml b/hotel_management_odoo/views/maintenance_request_views.xml new file mode 100644 index 000000000..c11d753ee --- /dev/null +++ b/hotel_management_odoo/views/maintenance_request_views.xml @@ -0,0 +1,49 @@ + + + + + maintenance.request.view.form + maintenance.request + +
+
+
+ +
+

+ +

+
+ + + + + + + + + + +
+
+
+
+ + + Maintenance Request + ir.actions.act_window + maintenance.request + list,form + + + +
diff --git a/hotel_management_odoo/views/maintenance_team_views.xml b/hotel_management_odoo/views/maintenance_team_views.xml new file mode 100644 index 000000000..1d062de6f --- /dev/null +++ b/hotel_management_odoo/views/maintenance_team_views.xml @@ -0,0 +1,78 @@ + + + + + maintenance.team.view.form + maintenance.team + +
+ + + + + + + + + + + + + + + + + +
+
+ +
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+ + + maintenance.team.view.tree + maintenance.team + + + + + + + + + + Maintenance Team + maintenance.team + ir.actions.act_window + list,form + + + + + +
diff --git a/hotel_management_odoo/views/reporting_views.xml b/hotel_management_odoo/views/reporting_views.xml new file mode 100644 index 000000000..66f91de78 --- /dev/null +++ b/hotel_management_odoo/views/reporting_views.xml @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/hotel_management_odoo/views/room_booking_views.xml b/hotel_management_odoo/views/room_booking_views.xml new file mode 100644 index 000000000..27e83589b --- /dev/null +++ b/hotel_management_odoo/views/room_booking_views.xml @@ -0,0 +1,338 @@ + + + + + room.booking.view.form + room.booking + +
+
+
+ +
+ +
+
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + room.booking.view.tree + room.booking + + + + + + + + + + + + Room Booking + ir.actions.act_window + room.booking + list,form + +

+ Book your rooms here! +

+
+
+ + + diff --git a/hotel_management_odoo/wizard/__init__.py b/hotel_management_odoo/wizard/__init__.py new file mode 100644 index 000000000..e135fd3be --- /dev/null +++ b/hotel_management_odoo/wizard/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from .import room_booking_detail +from .import sale_order_detail diff --git a/hotel_management_odoo/wizard/room_booking_detail.py b/hotel_management_odoo/wizard/room_booking_detail.py new file mode 100644 index 000000000..f7a611447 --- /dev/null +++ b/hotel_management_odoo/wizard/room_booking_detail.py @@ -0,0 +1,151 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +import io +import json +from odoo import fields, models, _ +from odoo.exceptions import ValidationError +from odoo.tools import json_default + +try: + from odoo.tools.misc import xlsxwriter +except ImportError: + import xlsxwriter + + +class RoomBookingWizard(models.TransientModel): + """Pdf Report for room Booking""" + + _name = "room.booking.detail" + _description = "Room Booking Details" + + checkin = fields.Date(help="Choose the Checkin Date", string="Checkin") + checkout = fields.Date(help="Choose the Checkout Date", string="Checkout") + room_id = fields.Many2one("hotel.room", string="Room", + help="Choose The Room") + + def action_room_booking_pdf(self): + """Button action_room_booking_pdf function""" + data = { + "booking": self.generate_data(), + } + return self.env.ref( + "hotel_management_odoo.action_report_room_booking" + ).report_action(self, data=data) + + def action_room_booking_excel(self): + """Button action for creating Room Booking Excel report""" + data = { + "booking": self.generate_data(), + } + return { + "type": "ir.actions.report", + "data": { + "model": "room.booking.detail", + "options": json.dumps(data, default=json_default), + "output_format": "xlsx", + "report_name": "Excel Report", + }, + "report_type": "xlsx", + } + + def generate_data(self): + """Generate data to be printed in the report""" + domain = [] + room_list = [] + if self.checkin and self.checkout: + if self.checkin > self.checkout: + raise ValidationError( + _("Check-in date should be less than Check-out date") + ) + if self.checkin: + domain.append( + ("checkin_date", ">=", self.checkin), + ) + if self.checkout: + domain.append( + ("checkout_date", "<=", self.checkout), + ) + room_booking = self.env["room.booking"].search_read( + domain=domain, + fields=["partner_id", "name", "checkin_date", "checkout_date"], + ) + for rec in room_booking: + rooms = ( + self.env["room.booking"] + .browse(rec["id"]) + .room_line_ids.room_id.mapped("name") + ) + rec["partner_id"] = rec["partner_id"][1] + for room in rooms: + if self.room_id: + if self.room_id.name == room: + rec_copy = rec.copy() + rec_copy["room"] = room # Ensure this key is added + room_list.append(rec_copy) + else: + rec_copy = rec.copy() + rec_copy["room"] = room # Ensure this key is added + room_list.append(rec_copy) + + return room_list + + def get_xlsx_report(self, data, response): + """Organizing xlsx report""" + output = io.BytesIO() + workbook = xlsxwriter.Workbook(output, {"in_memory": True}) + sheet = workbook.add_worksheet() + cell_format = workbook.add_format( + {"font_size": "14px", "bold": True, "align": "center", + "border": True} + ) + head = workbook.add_format( + {"align": "center", "bold": True, "font_size": "23px", + "border": True} + ) + body = workbook.add_format( + {"align": "left", "text_wrap": True, "border": True}) + sheet.merge_range("A1:F1", "Room Booking", head) + sheet.set_column("A2:F2", 18) + sheet.set_row(0, 30) + sheet.set_row(1, 20) + sheet.write("A2", "Sl No.", cell_format) + sheet.write("B2", "Guest Name", cell_format) + sheet.write("C2", "Room No.", cell_format) + sheet.write("D2", "Check In", cell_format) + sheet.write("E2", "Check Out", cell_format) + sheet.write("F2", "Reference No.", cell_format) + row = 2 + column = 0 + value = 1 + for i in data["booking"]: + sheet.write(row, column, value, body) + sheet.write(row, column + 1, i["partner_id"], body) + sheet.write(row, column + 2, i["room"], body) + sheet.write(row, column + 3, i["checkin_date"], body) + sheet.write(row, column + 4, i["checkout_date"], body) + sheet.write(row, column + 5, i["name"], body) + row = row + 1 + value = value + 1 + workbook.close() + output.seek(0) + response.stream.write(output.read()) + output.close() diff --git a/hotel_management_odoo/wizard/room_booking_detail_views.xml b/hotel_management_odoo/wizard/room_booking_detail_views.xml new file mode 100644 index 000000000..e8cdf2313 --- /dev/null +++ b/hotel_management_odoo/wizard/room_booking_detail_views.xml @@ -0,0 +1,42 @@ + + + + + room.booking.detail.view.form + room.booking.detail + +
+ + + + + +
+ + +
+ +
+
+ + + Room Booking Report + ir.actions.act_window + room.booking.detail + form + + new + +
diff --git a/hotel_management_odoo/wizard/sale_order_detail.py b/hotel_management_odoo/wizard/sale_order_detail.py new file mode 100644 index 000000000..99327feb9 --- /dev/null +++ b/hotel_management_odoo/wizard/sale_order_detail.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: ADARSH K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +import io +import json +from odoo import fields, models, _ +from odoo.exceptions import ValidationError +from odoo.tools import json_default + +try: + from odoo.tools.misc import xlsxwriter +except ImportError: + import xlsxwriter + + +class SaleOrderWizard(models.TransientModel): + """Pdf Report for Sale Order""" + _name = "sale.order.detail" + _description = "Room Booking Details" + + checkin = fields.Date(help="Choose the Checkin Date", string="Check In") + checkout = fields.Date(help="Choose the Checkout Date", string="Check Out") + + def action_sale_order_pdf(self): + """Button action for creating Sale Order Pdf Report""" + data = { + 'booking': self.generate_data(), + } + return self.env.ref( + 'hotel_management_odoo.action_report_sale_order').report_action( + self, data=data) + + def action_sale_order_excel(self): + """Button action for creating Sale Order Report""" + data = { + 'booking': self.generate_data(), + } + return { + 'type': 'ir.actions.report', + 'data': {'model': 'sale.order.detail', + 'options': json.dumps(data, + default=json_default), + 'output_format': 'xlsx', + 'report_name': 'Excel Report', + }, + 'report_type': 'xlsx', + } + + def generate_data(self): + """Generate data to be printed in the report""" + domain = [] + if self.checkin and self.checkout: + if self.checkin > self.checkout: + raise ValidationError(_( + 'Check-in date should be less than Check-out date')) + if self.checkin: + domain.append(('checkin_date', '>=', self.checkin), ) + if self.checkout: + domain.append(('checkout_date', '<=', self.checkout), ) + room_booking = self.env['room.booking'].search_read(domain=domain, + fields=[ + 'partner_id', + 'name', + 'checkin_date', + 'checkout_date', + 'amount_total']) + for rec in room_booking: + rec['partner_id'] = rec['partner_id'][1] + return room_booking + + def get_xlsx_report(self, data, response): + """Organizing xlsx report""" + output = io.BytesIO() + workbook = xlsxwriter.Workbook(output, {'in_memory': True}) + sheet = workbook.add_worksheet() + cell_format = workbook.add_format( + {'font_size': '14px', 'bold': True, 'align': 'center', + 'border': True}) + head = workbook.add_format( + {'align': 'center', 'bold': True, 'font_size': '23px', + 'border': True}) + body = workbook.add_format( + {'align': 'left', 'text_wrap': True, 'border': True}) + sheet.merge_range('A1:F1', 'Sale Order', head) + sheet.set_column('A2:F2', 18) + sheet.set_row(0, 30) + sheet.set_row(1, 20) + sheet.write('A2', 'Sl No.', cell_format) + sheet.write('B2', 'Guest Name', cell_format) + sheet.write('C2', 'Check In', cell_format) + sheet.write('D2', 'Check Out', cell_format) + sheet.write('E2', 'Reference No.', cell_format) + sheet.write('F2', 'Total Amount', cell_format) + row = 2 + column = 0 + value = 1 + for i in data['booking']: + sheet.write(row, column, value, body) + sheet.write(row, column + 1, i['partner_id'], body) + sheet.write(row, column + 2, i['checkin_date'], body) + sheet.write(row, column + 3, i['checkout_date'], body) + sheet.write(row, column + 4, i['name'], body) + sheet.write(row, column + 5, "{:.2f}".format(i['amount_total']), + body) + row = row + 1 + value = value + 1 + workbook.close() + output.seek(0) + response.stream.write(output.read()) + output.close() diff --git a/hotel_management_odoo/wizard/sale_order_detail_views.xml b/hotel_management_odoo/wizard/sale_order_detail_views.xml new file mode 100644 index 000000000..139428ff8 --- /dev/null +++ b/hotel_management_odoo/wizard/sale_order_detail_views.xml @@ -0,0 +1,39 @@ + + + + + sale.order.detail.view.form + sale.order.detail + +
+ + + + +
+ + +
+ +
+
+ + + Sale Order Report + ir.actions.act_window + sale.order.detail + form + + new + +