| @ -0,0 +1,46 @@ | |||
| .. 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 <https://cybrosys.com/>`__ | |||
| 
 | |||
| Credits | |||
| ------- | |||
| * Developer:(V16) Unnimaya C O, 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 <https://cybrosys.com/>`__ | |||
| 
 | |||
| Further information | |||
| =================== | |||
| HTML Description: `<static/description/index.html>`__ | |||
| @ -0,0 +1,24 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| from . import controllers | |||
| from . import models | |||
| from . import wizard | |||
| @ -0,0 +1,75 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| { | |||
|     'name': 'Hotel Management', | |||
|     'version': '16.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, | |||
| } | |||
| @ -0,0 +1,22 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| from . import hotel_management_odoo | |||
| @ -0,0 +1,56 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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))) | |||
| @ -0,0 +1,26 @@ | |||
| <?xml version="1.0" encoding="UTF-8" ?> | |||
| <odoo> | |||
|     <data noupdate="1"> | |||
|         <!--         Room Booking Sequence--> | |||
|         <record id="seq_hotel_folio" model="ir.sequence"> | |||
|             <field name="name">Hotel Folio</field> | |||
|             <field name="code">room.booking</field> | |||
|             <field name="prefix">BOOKING/</field> | |||
|             <field name="padding">5</field> | |||
|         </record> | |||
|         <!--        Cleaning Request sequence--> | |||
|         <record id="seq_cleaning" model="ir.sequence"> | |||
|             <field name="name">Cleaning Request</field> | |||
|             <field name="code">cleaning.request</field> | |||
|             <field name="prefix">CLEANING/</field> | |||
|             <field name="padding">4</field> | |||
|         </record> | |||
|         <!--        Maintenance Request Sequence--> | |||
|         <record id="seq_maintenance" model="ir.sequence"> | |||
|             <field name="name">Maintenance Request</field> | |||
|             <field name="code">maintenance.request</field> | |||
|             <field name="prefix">MNTC/</field> | |||
|             <field name="padding">5</field> | |||
|         </record> | |||
|     </data> | |||
| </odoo> | |||
| @ -0,0 +1,7 @@ | |||
| ## Module <hotel_management_odoo> | |||
| 
 | |||
| #### 27.11.2023 | |||
| #### Version 16.0.1.0.0 | |||
| #### ADD | |||
| 
 | |||
| - Initial commit for Hotel Management | |||
| @ -0,0 +1,38 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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 | |||
| @ -0,0 +1,35 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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") | |||
| @ -0,0 +1,37 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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") | |||
| @ -0,0 +1,131 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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'}, | |||
|             } | |||
|         } | |||
| @ -0,0 +1,43 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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") | |||
| @ -0,0 +1,123 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| from odoo import api, fields, models, tools | |||
| 
 | |||
| 
 | |||
| 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=[('detailed_type', '=', '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") | |||
|     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 Event booking line. | |||
|         """ | |||
|         for line in self: | |||
|             tax_results = self.env['account.tax']._compute_taxes( | |||
|                 [line._convert_to_tax_base_line_dict()]) | |||
|             totals = list(tax_results['totals'].values())[0] | |||
|             amount_untaxed = totals['amount_untaxed'] | |||
|             amount_tax = totals['amount_tax'] | |||
|             line.update({ | |||
|                 'price_subtotal': amount_untaxed, | |||
|                 'price_tax': amount_tax, | |||
|                 'price_total': amount_untaxed + amount_tax, | |||
|             }) | |||
|             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 _convert_to_tax_base_line_dict(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']._convert_to_tax_base_line_dict( | |||
|             self, | |||
|             partner=self.booking_id.partner_id, | |||
|             currency=self.currency_id, | |||
|             taxes=self.tax_ids, | |||
|             price_unit=self.price_unit, | |||
|             quantity=self.uom_qty, | |||
|             price_subtotal=self.price_subtotal, | |||
|         ) | |||
| @ -0,0 +1,128 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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: | |||
|             tax_results = self.env['account.tax']._compute_taxes( | |||
|                 [line._convert_to_tax_base_line_dict()]) | |||
|             totals = list(tax_results['totals'].values())[0] | |||
|             amount_untaxed = totals['amount_untaxed'] | |||
|             amount_tax = totals['amount_tax'] | |||
|             line.update({ | |||
|                 'price_subtotal': amount_untaxed, | |||
|                 'price_tax': amount_tax, | |||
|                 'price_total': amount_untaxed + amount_tax, | |||
|             }) | |||
|             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 _convert_to_tax_base_line_dict(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']._convert_to_tax_base_line_dict( | |||
|             self, | |||
|             partner=self.booking_id.partner_id, | |||
|             currency=self.currency_id, | |||
|             taxes=self.tax_ids, | |||
|             price_unit=self.price_unit, | |||
|             quantity=self.uom_qty, | |||
|             price_subtotal=self.price_subtotal, | |||
|         ) | |||
| 
 | |||
|     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) | |||
| @ -0,0 +1,39 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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) | |||
| @ -0,0 +1,124 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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: | |||
|             tax_results = self.env['account.tax']._compute_taxes( | |||
|                 [line._convert_to_tax_base_line_dict()]) | |||
|             totals = list(tax_results['totals'].values())[0] | |||
|             amount_untaxed = totals['amount_untaxed'] | |||
|             amount_tax = totals['amount_tax'] | |||
|             line.update({ | |||
|                 'price_subtotal': amount_untaxed, | |||
|                 'price_tax': amount_tax, | |||
|                 'price_total': amount_untaxed + amount_tax, | |||
|             }) | |||
|             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 _convert_to_tax_base_line_dict(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']._convert_to_tax_base_line_dict( | |||
|             self, | |||
|             partner=self.booking_id.partner_id, | |||
|             currency=self.currency_id, | |||
|             taxes=self.tax_ids, | |||
|             price_unit=self.price_unit, | |||
|             quantity=self.uom_qty, | |||
|             price_subtotal=self.price_subtotal, | |||
|         ) | |||
| 
 | |||
|     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) | |||
| @ -0,0 +1,36 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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") | |||
| @ -0,0 +1,34 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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) | |||
| @ -0,0 +1,106 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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 | |||
| @ -0,0 +1,46 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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) | |||
| @ -0,0 +1,151 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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' | |||
| @ -0,0 +1,45 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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)]) | |||
| @ -0,0 +1,743 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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", | |||
|                                    states={"draft": [("readonly", False)]}, | |||
|                                    default=fields.Datetime.now() | |||
|                                    ) | |||
|     checkout_date = fields.Datetime(string="Check Out", | |||
|                                     help="Date of Checkout", | |||
|                                     states={"draft": [("readonly", False)]}, | |||
|                                     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': 'tree,form', | |||
|             'view_type': 'tree,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 | |||
|         } | |||
| @ -0,0 +1,149 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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, precompute=True) | |||
|     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: | |||
|             tax_results = self.env['account.tax']._compute_taxes( | |||
|                 [line._convert_to_tax_base_line_dict()]) | |||
|             totals = list(tax_results['totals'].values())[0] | |||
|             amount_untaxed = totals['amount_untaxed'] | |||
|             amount_tax = totals['amount_tax'] | |||
|             line.update({ | |||
|                 'price_subtotal': amount_untaxed, | |||
|                 'price_tax': amount_tax, | |||
|                 'price_total': amount_untaxed + amount_tax, | |||
|             }) | |||
|             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 _convert_to_tax_base_line_dict(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']._convert_to_tax_base_line_dict( | |||
|             self, | |||
|             partner=self.booking_id.partner_id, | |||
|             currency=self.currency_id, | |||
|             taxes=self.tax_ids, | |||
|             price_unit=self.price_unit, | |||
|             quantity=self.uom_qty, | |||
|             price_subtotal=self.price_subtotal, | |||
|         ) | |||
| @ -0,0 +1,121 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ################################################################################ | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| # | |||
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Unnimaya C O (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 <http://www.gnu.org/licenses/>. | |||
| # | |||
| ################################################################################ | |||
| 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: | |||
|             tax_results = self.env['account.tax']._compute_taxes( | |||
|                 [line._convert_to_tax_base_line_dict()]) | |||
|             totals = list(tax_results['totals'].values())[0] | |||
|             amount_untaxed = totals['amount_untaxed'] | |||
|             amount_tax = totals['amount_tax'] | |||
| 
 | |||
|             line.update({ | |||
|                 'price_subtotal': amount_untaxed, | |||
|                 'price_tax': amount_tax, | |||
|                 'price_total': amount_untaxed + amount_tax, | |||
|             }) | |||
|             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 _convert_to_tax_base_line_dict(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']._convert_to_tax_base_line_dict( | |||
|             self, | |||
|             partner=self.booking_id.partner_id, | |||
|             currency=self.currency_id, | |||
|             taxes=self.tax_ids, | |||
|             price_unit=self.price_unit, | |||
|             quantity=self.uom_qty, | |||
|             price_subtotal=self.price_subtotal, | |||
|         ) | |||
| @ -0,0 +1,60 @@ | |||
| <?xml version = "1.0" encoding = "UTF-8" ?> | |||
| <odoo> | |||
|     <!--    Room booking report action--> | |||
|     <record id="action_report_room_booking" model="ir.actions.report"> | |||
|         <field name="name">Room Booking Order</field> | |||
|         <field name="model">room.booking</field> | |||
|         <field name="report_type">qweb-pdf</field> | |||
|         <field name="report_name">hotel_management_odoo.report_room_booking</field> | |||
|         <field name="report_file">hotel_management_odoo.report_room_booking</field> | |||
|         <field name="binding_model_id" ref="model_room_booking"/> | |||
|         <field name="binding_type">report</field> | |||
|     </record> | |||
|     <!--    Room booking template--> | |||
|     <template id="report_room_booking"> | |||
|         <t t-call="web.html_container"> | |||
|             <t t-call="web.external_layout"> | |||
|                 <div class="page"> | |||
|                     <h2>Room Booking</h2> | |||
|                     <br/> | |||
|                     <table class="table"> | |||
|                         <thead> | |||
|                             <tr> | |||
|                                 <th>Sl No.</th> | |||
|                                 <th>Guest Name</th> | |||
|                                 <th>Room No.</th> | |||
|                                 <th>Check-In</th> | |||
|                                 <th>Check-Out</th> | |||
|                                 <th>Reference No.</th> | |||
|                             </tr> | |||
|                         </thead> | |||
|                         <t t-set="i" t-value="0"/> | |||
|                         <t t-foreach="booking" t-as="line"> | |||
|                             <t t-set="i" t-value="i+1"/> | |||
|                             <tr> | |||
|                                 <td> | |||
|                                     <t t-esc="i"/> | |||
|                                 </td> | |||
|                                 <td> | |||
|                                     <t t-esc="line['partner_id']"/> | |||
|                                 </td> | |||
|                                 <td> | |||
|                                     <t t-esc="line['room']"/> | |||
|                                 </td> | |||
|                                 <td> | |||
|                                     <t t-esc="line['checkin_date']"/> | |||
|                                 </td> | |||
|                                 <td> | |||
|                                     <t t-esc="line['checkin_date']"/> | |||
|                                 </td> | |||
|                                 <td> | |||
|                                     <t t-esc="line['name']"/> | |||
|                                 </td> | |||
|                             </tr> | |||
|                         </t> | |||
|                     </table> | |||
|                 </div> | |||
|             </t> | |||
|         </t> | |||
|     </template> | |||
| </odoo> | |||
| @ -0,0 +1,61 @@ | |||
| <?xml version = "1.0" encoding = "UTF-8" ?> | |||
| <odoo> | |||
|     <!--    Sale order report action--> | |||
|     <record id="action_report_sale_order" model="ir.actions.report"> | |||
|    <field name="name">Sale Order</field> | |||
|    <field name="model">room.booking</field> | |||
|    <field name="report_type">qweb-pdf</field> | |||
|    <field name="report_name">hotel_management_odoo.report_sale_order</field> | |||
|    <field name="report_file">hotel_management_odoo.report_sale_order</field> | |||
|    <field name="binding_model_id" ref="model_room_booking"/> | |||
|    <field name="binding_type">report</field> | |||
| </record> | |||
|     <!--    Sale order report template--> | |||
|     <template id="report_sale_order"> | |||
|         <t t-call="web.html_container"> | |||
|             <t t-call="web.external_layout"> | |||
|                 <div class="page"> | |||
|                     <div class="oe_structure"/> | |||
|                     <h2>Sale Order</h2> | |||
|                     <br/> | |||
|                     <table class="table"> | |||
|                         <thead> | |||
|                             <tr> | |||
|                                 <th>Sl No.</th> | |||
|                                 <th>Guest Name</th> | |||
|                                 <th>Check-In</th> | |||
|                                 <th>Check-Out</th> | |||
|                                 <th>Reference No.</th> | |||
|                                 <th>Amount Total</th> | |||
|                             </tr> | |||
|                         </thead> | |||
|                         <t t-set="i" t-value="0"/> | |||
|                         <t t-foreach="booking" t-as="line"> | |||
|                             <t t-set="i" t-value="i+1"/> | |||
|                             <tr> | |||
|                                 <td> | |||
|                                     <t t-esc="i"/> | |||
|                                 </td> | |||
|                                 <td> | |||
|                                     <t t-esc="line['partner_id']"/> | |||
|                                 </td> | |||
|                                 <td> | |||
|                                     <t t-esc="line['checkin_date']"/> | |||
|                                 </td> | |||
|                                 <td> | |||
|                                     <t t-esc="line['checkin_date']"/> | |||
|                                 </td> | |||
|                                 <td> | |||
|                                     <t t-esc="line['name']"/> | |||
|                                 </td> | |||
|                                 <td> | |||
|                                     <t t-esc="line['amount_total']"/> | |||
|                                 </td> | |||
|                             </tr> | |||
|                         </t> | |||
|                     </table> | |||
|                 </div> | |||
|             </t> | |||
|         </t> | |||
|     </template> | |||
| </odoo> | |||
| @ -0,0 +1,53 @@ | |||
| <?xml version="1.0" encoding="utf-8" ?> | |||
| <odoo> | |||
|     <!--    Hotel Access Groups--> | |||
|     <record id="module_category_hotel_management" model="ir.module.category"> | |||
|         <field name="name">Hotel Management</field> | |||
|         <field name="description">Hotel Access Groups</field> | |||
|         <field name="sequence">20</field> | |||
|     </record> | |||
|     <!--    Maintenance Team User groups--> | |||
|     <record id="maintenance_team_group_user" model="res.groups"> | |||
|         <field name="name">Maintenance Team User</field> | |||
|         <field name="category_id" | |||
|                ref="hotel_management_odoo.module_category_hotel_management"/> | |||
|     </record> | |||
|     <!--    Maintenance Team Leader group--> | |||
|     <record id="maintenance_team_group_leader" model="res.groups"> | |||
|         <field name="name">Maintenance Team Leader</field> | |||
|         <field name="category_id" | |||
|                ref="hotel_management_odoo.module_category_hotel_management"/> | |||
|         <field name="implied_ids" | |||
|                eval="[(4, ref('hotel_management_odoo.maintenance_team_group_user'))]"/> | |||
|     </record> | |||
|     <!--    Reception groups--> | |||
|     <record id="hotel_group_reception" model="res.groups"> | |||
|         <field name="name">Receptionist</field> | |||
|         <field name="category_id" | |||
|                ref="hotel_management_odoo.module_category_hotel_management"/> | |||
|     </record> | |||
|     <!--    Cleaning Team User group--> | |||
|     <record id="cleaning_team_group_user" model="res.groups"> | |||
|         <field name="name">Cleaning Team User</field> | |||
|         <field name="category_id" | |||
|                ref="hotel_management_odoo.module_category_hotel_management"/> | |||
|     </record> | |||
|     <!--    Cleaning Team Head group--> | |||
|     <record id="cleaning_team_group_head" model="res.groups"> | |||
|         <field name="name">Cleaning Team Head</field> | |||
|         <field name="category_id" | |||
|                ref="hotel_management_odoo.module_category_hotel_management"/> | |||
|         <field name="implied_ids" | |||
|                eval="[(4, ref('hotel_management_odoo.cleaning_team_group_user'))]"/> | |||
|     </record> | |||
|     <!--Hotel Admin group--> | |||
|     <record id="hotel_group_admin" model="res.groups"> | |||
|         <field name="name">Admin</field> | |||
|         <field name="category_id" | |||
|                ref="hotel_management_odoo.module_category_hotel_management"/> | |||
|         <field name="implied_ids" | |||
|                eval="[(4, ref('hotel_management_odoo.maintenance_team_group_leader')), | |||
|                        (4, ref('hotel_management_odoo.cleaning_team_group_head')), | |||
|                        (4, ref('hotel_group_reception')), ]"/> | |||
|     </record> | |||
| </odoo> | |||
| @ -0,0 +1,67 @@ | |||
| <?xml version="1.0" encoding="utf-8" ?> | |||
| <odoo> | |||
|     <!--  MAINTENANCE RECORD RULE--> | |||
|     <record id="maintenance_request_rule_leader" | |||
|             model="ir.rule"> | |||
|         <field name="name">Record Rule for Maintenance team leader</field> | |||
|         <field ref="model_maintenance_request" name="model_id"/> | |||
|         <field name="groups" | |||
|                eval="[(4, ref('hotel_management_odoo.maintenance_team_group_leader'))]"/> | |||
|         <field name="domain_force">[('team_head_id', '=', user.id)]</field> | |||
|         <field name="perm_read" eval="True"/> | |||
|         <field name="perm_write" eval="True"/> | |||
|         <field name="perm_create" eval="True"/> | |||
|         <field name="perm_unlink" eval="True"/> | |||
|     </record> | |||
|     <!--    Record Rule for Maintenance User--> | |||
|     <record id="maintenance_request_rule_user" | |||
|             model="ir.rule"> | |||
|         <field name="name">Record Rule for Maintenance User</field> | |||
|         <field ref="model_maintenance_request" name="model_id"/> | |||
|         <field name="groups" | |||
|                eval="[(4, ref('hotel_management_odoo.maintenance_team_group_user'))]"/> | |||
|         <field name="domain_force">[('assigned_user_id', '=', user.id)]</field> | |||
|         <field name="perm_read" eval="True"/> | |||
|         <field name="perm_write" eval="True"/> | |||
|         <field name="perm_create" eval="True"/> | |||
|         <field name="perm_unlink" eval="True"/> | |||
|     </record> | |||
|     <!--    Record Rule for hotel Admin--> | |||
|     <record id="maintenance_request_rule_admin" | |||
|             model="ir.rule"> | |||
|         <field name="name">Record Rule for hotel Admin</field> | |||
|         <field ref="model_maintenance_request" name="model_id"/> | |||
|         <field name="groups" | |||
|                eval="[(4, ref('hotel_management_odoo.hotel_group_admin'))]"/> | |||
|         <field name="domain_force">[(1,'=',1)]</field> | |||
|         <field name="perm_read" eval="True"/> | |||
|         <field name="perm_write" eval="True"/> | |||
|         <field name="perm_create" eval="True"/> | |||
|         <field name="perm_unlink" eval="True"/> | |||
|     </record> | |||
|     <!--    CLEANING HEAD RECORD RULE--> | |||
|     <record id="cleaning_request_rule_head" model="ir.rule"> | |||
|         <field name="name">Cleaning Head Record Rule</field> | |||
|         <field name="model_id" ref="model_cleaning_request"/> | |||
|         <field name="groups" | |||
|                eval="[(4, ref('hotel_management_odoo.cleaning_team_group_head'))]"/> | |||
|         <field name="domain_force">[('team_id.team_head_id.id', '=', user.id)] | |||
|         </field> | |||
|     </record> | |||
|     <!--    CLEANING USER RECORD RULE--> | |||
|     <record id="cleaning_request_rule_user" model="ir.rule"> | |||
|         <field name="name">Cleaning User Record Rule</field> | |||
|         <field name="model_id" ref="model_cleaning_request"/> | |||
|         <field name="groups" | |||
|                eval="[(4, ref('hotel_management_odoo.cleaning_team_group_user'))]"/> | |||
|         <field name="domain_force">[('assigned_id.id', '=', user.id)]</field> | |||
|     </record> | |||
|     <!--    CLEANING ADMIN RECORD RULE--> | |||
|     <record id="cleaning_request_rule_admin" model="ir.rule"> | |||
|         <field name="name">Cleaning Admin Record Rule</field> | |||
|         <field name="model_id" ref="model_cleaning_request"/> | |||
|         <field name="groups" | |||
|                eval="[(4, ref('hotel_management_odoo.hotel_group_admin'))]"/> | |||
|         <field name="domain_force">[(1, '=', 1)]</field> | |||
|     </record> | |||
| </odoo> | |||
| 
 | 
| After Width: | Height: | Size: 3.6 KiB | 
| After Width: | Height: | Size: 310 B | 
| After Width: | Height: | Size: 1.3 KiB | 
| After Width: | Height: | Size: 1.4 KiB | 
| After Width: | Height: | Size: 576 B | 
| After Width: | Height: | Size: 733 B | 
| After Width: | Height: | Size: 911 B | 
| After Width: | Height: | Size: 1.1 KiB | 
| After Width: | Height: | Size: 1.2 KiB | 
| After Width: | Height: | Size: 673 B | 
| After Width: | Height: | Size: 878 B | 
| After Width: | Height: | Size: 653 B | 
| After Width: | Height: | Size: 905 B | 
| After Width: | Height: | Size: 839 B | 
| After Width: | Height: | Size: 427 B | 
| After Width: | Height: | Size: 627 B | 
| After Width: | Height: | Size: 1.2 KiB | 
| After Width: | Height: | Size: 988 B | 
| After Width: | Height: | Size: 1.2 KiB | 
| After Width: | Height: | Size: 1.5 KiB | 
| After Width: | Height: | Size: 1.1 KiB | 
| After Width: | Height: | Size: 1.9 KiB | 
| After Width: | Height: | Size: 1.1 KiB | 
| After Width: | Height: | Size: 2.1 KiB | 
| After Width: | Height: | Size: 4.4 KiB | 
| After Width: | Height: | Size: 589 B | 
| After Width: | Height: | Size: 3.4 KiB | 
| After Width: | Height: | Size: 1.7 KiB | 
| After Width: | Height: | Size: 2.3 KiB | 
| After Width: | Height: | Size: 967 B | 
| After Width: | Height: | Size: 1.6 KiB | 
| After Width: | Height: | Size: 3.8 KiB | 
| After Width: | Height: | Size: 5.0 KiB | 
| After Width: | Height: | Size: 92 KiB | 
| After Width: | Height: | Size: 81 KiB | 
| After Width: | Height: | Size: 94 KiB | 
| After Width: | Height: | Size: 91 KiB | 
| After Width: | Height: | Size: 92 KiB | 
| After Width: | Height: | Size: 91 KiB | 
| After Width: | Height: | Size: 89 KiB | 
| After Width: | Height: | Size: 486 KiB | 
| After Width: | Height: | Size: 54 KiB | 
| After Width: | Height: | Size: 87 KiB | 
| After Width: | Height: | Size: 360 KiB | 
| After Width: | Height: | Size: 174 KiB | 
| After Width: | Height: | Size: 53 KiB | 
| After Width: | Height: | Size: 45 KiB | 
| After Width: | Height: | Size: 52 KiB | 
| After Width: | Height: | Size: 40 KiB | 
| After Width: | Height: | Size: 86 KiB | 
| After Width: | Height: | Size: 103 KiB | 
| After Width: | Height: | Size: 53 KiB | 
| After Width: | Height: | Size: 99 KiB | 
| After Width: | Height: | Size: 108 KiB | 
| After Width: | Height: | Size: 118 KiB | 
| After Width: | Height: | Size: 87 KiB | 
| After Width: | Height: | Size: 66 KiB | 
| After Width: | Height: | Size: 82 KiB | 
| After Width: | Height: | Size: 96 KiB | 
| After Width: | Height: | Size: 103 KiB | 
| After Width: | Height: | Size: 95 KiB | 
| After Width: | Height: | Size: 83 KiB | 
| After Width: | Height: | Size: 75 KiB | 
| After Width: | Height: | Size: 116 KiB | 
| After Width: | Height: | Size: 78 KiB | 
| After Width: | Height: | Size: 107 KiB | 
| After Width: | Height: | Size: 63 KiB | 
| After Width: | Height: | Size: 70 KiB | 
| After Width: | Height: | Size: 95 KiB |