You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							738 lines
						
					
					
						
							35 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							738 lines
						
					
					
						
							35 KiB
						
					
					
				
								# -*- coding: utf-8 -*-
							 | 
						|
								###############################################################################
							 | 
						|
								#
							 | 
						|
								#    Cybrosys Technologies Pvt. Ltd.
							 | 
						|
								#
							 | 
						|
								#    Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
							 | 
						|
								#    Author: ADARSH K (odoo@cybrosys.com)
							 | 
						|
								#
							 | 
						|
								#    You can modify it under the terms of the GNU LESSER
							 | 
						|
								#    GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
							 | 
						|
								#
							 | 
						|
								#    This program is distributed in the hope that it will be useful,
							 | 
						|
								#    but WITHOUT ANY WARRANTY; without even the implied warranty of
							 | 
						|
								#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
							 | 
						|
								#    GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
							 | 
						|
								#
							 | 
						|
								#    You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
							 | 
						|
								#    (LGPL v3) along with this program.
							 | 
						|
								#    If not, see <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",
							 | 
						|
								                                   default=fields.Datetime.now())
							 | 
						|
								    checkout_date = fields.Datetime(string="Check Out",
							 | 
						|
								                                    help="Date of Checkout",
							 | 
						|
								                                    default=fields.Datetime.now() + timedelta(
							 | 
						|
								                                        hours=23, minutes=59, seconds=59))
							 | 
						|
								    hotel_policy = fields.Selection([("prepaid", "On Booking"),
							 | 
						|
								                                     ("manual", "On Check In"),
							 | 
						|
								                                     ("picking", "On Checkout"),
							 | 
						|
								                                     ],
							 | 
						|
								                                    default="manual", string="Hotel Policy",
							 | 
						|
								                                    help="Hotel policy for payment that "
							 | 
						|
								                                         "either the guest has to pay at "
							 | 
						|
								                                         "booking time, check-in "
							 | 
						|
								                                         "or check-out time.", tracking=True)
							 | 
						|
								    duration = fields.Integer(string="Duration in Days",
							 | 
						|
								                              help="Number of days which will automatically "
							 | 
						|
								                                   "count from the check-in and check-out "
							 | 
						|
								                                   "date.", )
							 | 
						|
								    invoice_button_visible = fields.Boolean(string='Invoice Button Display',
							 | 
						|
								                                            help="Invoice button will be "
							 | 
						|
								                                                 "visible if this button is "
							 | 
						|
								                                                 "True")
							 | 
						|
								    invoice_status = fields.Selection(
							 | 
						|
								        selection=[('no_invoice', 'Nothing To Invoice'),
							 | 
						|
								                   ('to_invoice', 'To Invoice'),
							 | 
						|
								                   ('invoiced', 'Invoiced'),
							 | 
						|
								                   ], string="Invoice Status",
							 | 
						|
								        help="Status of the Invoice",
							 | 
						|
								        default='no_invoice', tracking=True)
							 | 
						|
								    hotel_invoice_id = fields.Many2one("account.move",
							 | 
						|
								                                       string="Invoice",
							 | 
						|
								                                       help="Indicates the invoice",
							 | 
						|
								                                       copy=False)
							 | 
						|
								    duration_visible = fields.Float(string="Duration",
							 | 
						|
								                                    help="A dummy field for Duration")
							 | 
						|
								    need_service = fields.Boolean(default=False, string="Need Service",
							 | 
						|
								                                  help="Check if a Service to be added with"
							 | 
						|
								                                       " the Booking")
							 | 
						|
								    need_fleet = fields.Boolean(default=False, string="Need Vehicle",
							 | 
						|
								                                help="Check if a Fleet to be"
							 | 
						|
								                                     " added with the Booking")
							 | 
						|
								    need_food = fields.Boolean(default=False, string="Need Food",
							 | 
						|
								                               help="Check if a Food to be added with"
							 | 
						|
								                                    " the Booking")
							 | 
						|
								    need_event = fields.Boolean(default=False, string="Need Event",
							 | 
						|
								                                help="Check if a Event to be added with"
							 | 
						|
								                                     " the Booking")
							 | 
						|
								    service_line_ids = fields.One2many("service.booking.line",
							 | 
						|
								                                       "booking_id",
							 | 
						|
								                                       string="Service",
							 | 
						|
								                                       help="Hotel services details provided to"
							 | 
						|
								                                            "Customer and it will included in "
							 | 
						|
								                                            "the main Invoice.")
							 | 
						|
								    event_line_ids = fields.One2many("event.booking.line",
							 | 
						|
								                                     'booking_id',
							 | 
						|
								                                     string="Event",
							 | 
						|
								                                     help="Hotel event reservation detail.")
							 | 
						|
								    vehicle_line_ids = fields.One2many("fleet.booking.line",
							 | 
						|
								                                       "booking_id",
							 | 
						|
								                                       string="Vehicle",
							 | 
						|
								                                       help="Hotel fleet reservation detail.")
							 | 
						|
								    room_line_ids = fields.One2many("room.booking.line",
							 | 
						|
								                                    "booking_id", string="Room",
							 | 
						|
								                                    help="Hotel room reservation detail.")
							 | 
						|
								    food_order_line_ids = fields.One2many("food.booking.line",
							 | 
						|
								                                          "booking_id",
							 | 
						|
								                                          string='Food',
							 | 
						|
								                                          help="Food details provided"
							 | 
						|
								                                               " to Customer and"
							 | 
						|
								                                               " it will included in the "
							 | 
						|
								                                               "main invoice.", )
							 | 
						|
								    state = fields.Selection(selection=[('draft', 'Draft'),
							 | 
						|
								                                        ('reserved', 'Reserved'),
							 | 
						|
								                                        ('check_in', 'Check In'),
							 | 
						|
								                                        ('check_out', 'Check Out'),
							 | 
						|
								                                        ('cancel', 'Cancelled'),
							 | 
						|
								                                        ('done', 'Done')], string='State',
							 | 
						|
								                             help="State of the Booking",
							 | 
						|
								                             default='draft', tracking=True)
							 | 
						|
								    user_id = fields.Many2one(comodel_name='res.partner',
							 | 
						|
								                              string="Invoice Address",
							 | 
						|
								                              compute='_compute_user_id',
							 | 
						|
								                              help="Sets the User automatically",
							 | 
						|
								                              required=True,
							 | 
						|
								                              domain="['|', ('company_id', '=', False), "
							 | 
						|
								                                     "('company_id', '=',"
							 | 
						|
								                                     " company_id)]")
							 | 
						|
								    pricelist_id = fields.Many2one(comodel_name='product.pricelist',
							 | 
						|
								                                   string="Pricelist",
							 | 
						|
								                                   compute='_compute_pricelist_id',
							 | 
						|
								                                   store=True, readonly=False,
							 | 
						|
								                                   required=True,
							 | 
						|
								                                   tracking=1,
							 | 
						|
								                                   help="If you change the pricelist,"
							 | 
						|
								                                        " only newly added lines"
							 | 
						|
								                                        " will be affected.")
							 | 
						|
								    currency_id = fields.Many2one(
							 | 
						|
								        string="Currency", help="This is the Currency used",
							 | 
						|
								        related='pricelist_id.currency_id',
							 | 
						|
								        depends=['pricelist_id.currency_id'],
							 | 
						|
								    )
							 | 
						|
								    invoice_count = fields.Integer(compute='_compute_invoice_count',
							 | 
						|
								                                   string="Invoice "
							 | 
						|
								                                          "Count",
							 | 
						|
								                                   help="The number of invoices created")
							 | 
						|
								    account_move = fields.Integer(string='Invoice Id',
							 | 
						|
								                                  help="Id of the invoice created")
							 | 
						|
								    amount_untaxed = fields.Monetary(string="Total Untaxed Amount",
							 | 
						|
								                                     help="This indicates the total untaxed "
							 | 
						|
								                                          "amount", store=True,
							 | 
						|
								                                     compute='_compute_amount_untaxed',
							 | 
						|
								                                     tracking=5)
							 | 
						|
								    amount_tax = fields.Monetary(string="Taxes", help="Total Tax Amount",
							 | 
						|
								                                 store=True, compute='_compute_amount_untaxed')
							 | 
						|
								    amount_total = fields.Monetary(string="Total", store=True,
							 | 
						|
								                                   help="The total Amount including Tax",
							 | 
						|
								                                   compute='_compute_amount_untaxed',
							 | 
						|
								                                   tracking=4)
							 | 
						|
								    amount_untaxed_room = fields.Monetary(string="Room Untaxed",
							 | 
						|
								                                          help="Untaxed Amount for Room",
							 | 
						|
								                                          compute='_compute_amount_untaxed',
							 | 
						|
								                                          tracking=5)
							 | 
						|
								    amount_untaxed_food = fields.Monetary(string="Food Untaxed",
							 | 
						|
								                                          help="Untaxed Amount for Food",
							 | 
						|
								                                          compute='_compute_amount_untaxed',
							 | 
						|
								                                          tracking=5)
							 | 
						|
								    amount_untaxed_event = fields.Monetary(string="Event Untaxed",
							 | 
						|
								                                           help="Untaxed Amount for Event",
							 | 
						|
								                                           compute='_compute_amount_untaxed',
							 | 
						|
								                                           tracking=5)
							 | 
						|
								    amount_untaxed_service = fields.Monetary(
							 | 
						|
								        string="Service Untaxed", help="Untaxed Amount for Service",
							 | 
						|
								        compute='_compute_amount_untaxed', tracking=5)
							 | 
						|
								    amount_untaxed_fleet = fields.Monetary(string="Amount Untaxed",
							 | 
						|
								                                           help="Untaxed amount for Fleet",
							 | 
						|
								                                           compute='_compute_amount_untaxed',
							 | 
						|
								                                           tracking=5)
							 | 
						|
								    amount_taxed_room = fields.Monetary(string="Rom Tax", help="Tax for Room",
							 | 
						|
								                                        compute='_compute_amount_untaxed',
							 | 
						|
								                                        tracking=5)
							 | 
						|
								    amount_taxed_food = fields.Monetary(string="Food Tax", help="Tax for Food",
							 | 
						|
								                                        compute='_compute_amount_untaxed',
							 | 
						|
								                                        tracking=5)
							 | 
						|
								    amount_taxed_event = fields.Monetary(string="Event Tax",
							 | 
						|
								                                         help="Tax for Event",
							 | 
						|
								                                         compute='_compute_amount_untaxed',
							 | 
						|
								                                         tracking=5)
							 | 
						|
								    amount_taxed_service = fields.Monetary(string="Service Tax",
							 | 
						|
								                                           compute='_compute_amount_untaxed',
							 | 
						|
								                                           help="Tax for Service", tracking=5)
							 | 
						|
								    amount_taxed_fleet = fields.Monetary(string="Fleet Tax",
							 | 
						|
								                                         compute='_compute_amount_untaxed',
							 | 
						|
								                                         help="Tax for Fleet", tracking=5)
							 | 
						|
								    amount_total_room = fields.Monetary(string="Total Amount for Room",
							 | 
						|
								                                        compute='_compute_amount_untaxed',
							 | 
						|
								                                        help="This is the Total Amount for "
							 | 
						|
								                                             "Room", tracking=5)
							 | 
						|
								    amount_total_food = fields.Monetary(string="Total Amount for Food",
							 | 
						|
								                                        compute='_compute_amount_untaxed',
							 | 
						|
								                                        help="This is the Total Amount for "
							 | 
						|
								                                             "Food", tracking=5)
							 | 
						|
								    amount_total_event = fields.Monetary(string="Total Amount for Event",
							 | 
						|
								                                         compute='_compute_amount_untaxed',
							 | 
						|
								                                         help="This is the Total Amount for "
							 | 
						|
								                                              "Event", tracking=5)
							 | 
						|
								    amount_total_service = fields.Monetary(string="Total Amount for Service",
							 | 
						|
								                                           compute='_compute_amount_untaxed',
							 | 
						|
								                                           help="This is the Total Amount for "
							 | 
						|
								                                                "Service", tracking=5)
							 | 
						|
								    amount_total_fleet = fields.Monetary(string="Total Amount for Fleet",
							 | 
						|
								                                         compute='_compute_amount_untaxed',
							 | 
						|
								                                         help="This is the Total Amount for "
							 | 
						|
								                                              "Fleet", tracking=5)
							 | 
						|
								
							 | 
						|
								    @api.model
							 | 
						|
								    def create(self, vals_list):
							 | 
						|
								        """Sequence Generation"""
							 | 
						|
								        if vals_list.get('name', 'New') == 'New':
							 | 
						|
								            vals_list['name'] = self.env['ir.sequence'].next_by_code(
							 | 
						|
								                'room.booking')
							 | 
						|
								        return super().create(vals_list)
							 | 
						|
								
							 | 
						|
								    @api.depends('partner_id')
							 | 
						|
								    def _compute_user_id(self):
							 | 
						|
								        """Computes the User id"""
							 | 
						|
								        for order in self:
							 | 
						|
								            order.user_id = \
							 | 
						|
								                order.partner_id.address_get(['invoice'])[
							 | 
						|
								                    'invoice'] if order.partner_id else False
							 | 
						|
								
							 | 
						|
								    def _compute_invoice_count(self):
							 | 
						|
								        """Compute the invoice count"""
							 | 
						|
								        for record in self:
							 | 
						|
								            record.invoice_count = self.env['account.move'].search_count(
							 | 
						|
								                [('ref', '=', self.name)])
							 | 
						|
								
							 | 
						|
								    @api.depends('partner_id')
							 | 
						|
								    def _compute_pricelist_id(self):
							 | 
						|
								        """Computes PriceList"""
							 | 
						|
								        for order in self:
							 | 
						|
								            if not order.partner_id:
							 | 
						|
								                order.pricelist_id = False
							 | 
						|
								                continue
							 | 
						|
								            order = order.with_company(order.company_id)
							 | 
						|
								            order.pricelist_id = order.partner_id.property_product_pricelist
							 | 
						|
								
							 | 
						|
								    @api.depends('room_line_ids.price_subtotal', 'room_line_ids.price_tax',
							 | 
						|
								                 'room_line_ids.price_total',
							 | 
						|
								                 'food_order_line_ids.price_subtotal',
							 | 
						|
								                 'food_order_line_ids.price_tax',
							 | 
						|
								                 'food_order_line_ids.price_total',
							 | 
						|
								                 'service_line_ids.price_subtotal',
							 | 
						|
								                 'service_line_ids.price_tax', 'service_line_ids.price_total',
							 | 
						|
								                 'vehicle_line_ids.price_subtotal',
							 | 
						|
								                 'vehicle_line_ids.price_tax', 'vehicle_line_ids.price_total',
							 | 
						|
								                 'event_line_ids.price_subtotal', 'event_line_ids.price_tax',
							 | 
						|
								                 'event_line_ids.price_total',
							 | 
						|
								                 )
							 | 
						|
								    def _compute_amount_untaxed(self, flag=False):
							 | 
						|
								        """Compute the total amounts of the Sale Order"""
							 | 
						|
								        amount_untaxed_room = 0.0
							 | 
						|
								        amount_untaxed_food = 0.0
							 | 
						|
								        amount_untaxed_fleet = 0.0
							 | 
						|
								        amount_untaxed_event = 0.0
							 | 
						|
								        amount_untaxed_service = 0.0
							 | 
						|
								        amount_taxed_room = 0.0
							 | 
						|
								        amount_taxed_food = 0.0
							 | 
						|
								        amount_taxed_fleet = 0.0
							 | 
						|
								        amount_taxed_event = 0.0
							 | 
						|
								        amount_taxed_service = 0.0
							 | 
						|
								        amount_total_room = 0.0
							 | 
						|
								        amount_total_food = 0.0
							 | 
						|
								        amount_total_fleet = 0.0
							 | 
						|
								        amount_total_event = 0.0
							 | 
						|
								        amount_total_service = 0.0
							 | 
						|
								        room_lines = self.room_line_ids
							 | 
						|
								        food_lines = self.food_order_line_ids
							 | 
						|
								        service_lines = self.service_line_ids
							 | 
						|
								        fleet_lines = self.vehicle_line_ids
							 | 
						|
								        event_lines = self.event_line_ids
							 | 
						|
								        booking_list = []
							 | 
						|
								        account_move_line = self.env['account.move.line'].search_read(
							 | 
						|
								            domain=[('ref', '=', self.name),
							 | 
						|
								                    ('display_type', '!=', 'payment_term')],
							 | 
						|
								            fields=['name', 'quantity', 'price_unit', 'product_type'], )
							 | 
						|
								        for rec in account_move_line:
							 | 
						|
								            del rec['id']
							 | 
						|
								        if room_lines:
							 | 
						|
								            amount_untaxed_room += sum(room_lines.mapped('price_subtotal'))
							 | 
						|
								            amount_taxed_room += sum(room_lines.mapped('price_tax'))
							 | 
						|
								            amount_total_room += sum(room_lines.mapped('price_total'))
							 | 
						|
								            for room in room_lines:
							 | 
						|
								                booking_dict = {'name': room.room_id.name,
							 | 
						|
								                                'quantity': room.uom_qty,
							 | 
						|
								                                'price_unit': room.price_unit,
							 | 
						|
								                                'product_type': 'room'}
							 | 
						|
								                if booking_dict not in account_move_line:
							 | 
						|
								                    if not account_move_line:
							 | 
						|
								                        booking_list.append(booking_dict)
							 | 
						|
								                    else:
							 | 
						|
								                        for rec in account_move_line:
							 | 
						|
								                            if rec['product_type'] == 'room':
							 | 
						|
								                                if booking_dict['name'] == rec['name'] and \
							 | 
						|
								                                        booking_dict['price_unit'] == rec[
							 | 
						|
								                                    'price_unit'] and booking_dict['quantity']\
							 | 
						|
								                                        != rec['quantity']:
							 | 
						|
								                                    booking_list.append(
							 | 
						|
								                                        {'name': room.room_id.name,
							 | 
						|
								                                         "quantity": booking_dict[
							 | 
						|
								                                                         'quantity'] - rec[
							 | 
						|
								                                                         'quantity'],
							 | 
						|
								                                         "price_unit": room.price_unit,
							 | 
						|
								                                         "product_type": 'room'})
							 | 
						|
								                                else:
							 | 
						|
								                                    booking_list.append(booking_dict)
							 | 
						|
								                    if flag:
							 | 
						|
								                        room.booking_line_visible = True
							 | 
						|
								        if food_lines:
							 | 
						|
								            for food in food_lines:
							 | 
						|
								                booking_list.append(self.create_list(food))
							 | 
						|
								            amount_untaxed_food += sum(food_lines.mapped('price_subtotal'))
							 | 
						|
								            amount_taxed_food += sum(food_lines.mapped('price_tax'))
							 | 
						|
								            amount_total_food += sum(food_lines.mapped('price_total'))
							 | 
						|
								        if service_lines:
							 | 
						|
								            for service in service_lines:
							 | 
						|
								                booking_list.append(self.create_list(service))
							 | 
						|
								            amount_untaxed_service += sum(
							 | 
						|
								                service_lines.mapped('price_subtotal'))
							 | 
						|
								            amount_taxed_service += sum(service_lines.mapped('price_tax'))
							 | 
						|
								            amount_total_service += sum(service_lines.mapped('price_total'))
							 | 
						|
								        if fleet_lines:
							 | 
						|
								            for fleet in fleet_lines:
							 | 
						|
								                booking_list.append(self.create_list(fleet))
							 | 
						|
								            amount_untaxed_fleet += sum(fleet_lines.mapped('price_subtotal'))
							 | 
						|
								            amount_taxed_fleet += sum(fleet_lines.mapped('price_tax'))
							 | 
						|
								            amount_total_fleet += sum(fleet_lines.mapped('price_total'))
							 | 
						|
								        if event_lines:
							 | 
						|
								            for event in event_lines:
							 | 
						|
								                booking_list.append(self.create_list(event))
							 | 
						|
								            amount_untaxed_event += sum(event_lines.mapped('price_subtotal'))
							 | 
						|
								            amount_taxed_event += sum(event_lines.mapped('price_tax'))
							 | 
						|
								            amount_total_event += sum(event_lines.mapped('price_total'))
							 | 
						|
								        for rec in self:
							 | 
						|
								            rec.amount_untaxed = amount_untaxed_food + amount_untaxed_room + \
							 | 
						|
								                                 amount_untaxed_fleet + \
							 | 
						|
								                                 amount_untaxed_event + amount_untaxed_service
							 | 
						|
								            rec.amount_untaxed_food = amount_untaxed_food
							 | 
						|
								            rec.amount_untaxed_room = amount_untaxed_room
							 | 
						|
								            rec.amount_untaxed_fleet = amount_untaxed_fleet
							 | 
						|
								            rec.amount_untaxed_event = amount_untaxed_event
							 | 
						|
								            rec.amount_untaxed_service = amount_untaxed_service
							 | 
						|
								            rec.amount_tax = (amount_taxed_food + amount_taxed_room
							 | 
						|
								                              + amount_taxed_fleet
							 | 
						|
								                              + amount_taxed_event + amount_taxed_service)
							 | 
						|
								            rec.amount_taxed_food = amount_taxed_food
							 | 
						|
								            rec.amount_taxed_room = amount_taxed_room
							 | 
						|
								            rec.amount_taxed_fleet = amount_taxed_fleet
							 | 
						|
								            rec.amount_taxed_event = amount_taxed_event
							 | 
						|
								            rec.amount_taxed_service = amount_taxed_service
							 | 
						|
								            rec.amount_total = (amount_total_food + amount_total_room
							 | 
						|
								                                + amount_total_fleet + amount_total_event
							 | 
						|
								                                + amount_total_service)
							 | 
						|
								            rec.amount_total_food = amount_total_food
							 | 
						|
								            rec.amount_total_room = amount_total_room
							 | 
						|
								            rec.amount_total_fleet = amount_total_fleet
							 | 
						|
								            rec.amount_total_event = amount_total_event
							 | 
						|
								            rec.amount_total_service = amount_total_service
							 | 
						|
								        return booking_list
							 | 
						|
								
							 | 
						|
								    @api.onchange('need_food')
							 | 
						|
								    def _onchange_need_food(self):
							 | 
						|
								        """Unlink Food Booking Line if Need Food is false"""
							 | 
						|
								        if not self.need_food and self.food_order_line_ids:
							 | 
						|
								            for food in self.food_order_line_ids:
							 | 
						|
								                food.unlink()
							 | 
						|
								
							 | 
						|
								    @api.onchange('need_service')
							 | 
						|
								    def _onchange_need_service(self):
							 | 
						|
								        """Unlink Service Booking Line if Need Service is False"""
							 | 
						|
								        if not self.need_service and self.service_line_ids:
							 | 
						|
								            for serv in self.service_line_ids:
							 | 
						|
								                serv.unlink()
							 | 
						|
								
							 | 
						|
								    @api.onchange('need_fleet')
							 | 
						|
								    def _onchange_need_fleet(self):
							 | 
						|
								        """Unlink Fleet Booking Line if Need Fleet is False"""
							 | 
						|
								        if not self.need_fleet:
							 | 
						|
								            if self.vehicle_line_ids:
							 | 
						|
								                for fleet in self.vehicle_line_ids:
							 | 
						|
								                    fleet.unlink()
							 | 
						|
								
							 | 
						|
								    @api.onchange('need_event')
							 | 
						|
								    def _onchange_need_event(self):
							 | 
						|
								        """Unlink Event Booking Line if Need Event is False"""
							 | 
						|
								        if not self.need_event:
							 | 
						|
								            if self.event_line_ids:
							 | 
						|
								                for event in self.event_line_ids:
							 | 
						|
								                    event.unlink()
							 | 
						|
								
							 | 
						|
								    @api.onchange('food_order_line_ids', 'room_line_ids',
							 | 
						|
								                  'service_line_ids', 'vehicle_line_ids', 'event_line_ids')
							 | 
						|
								    def _onchange_room_line_ids(self):
							 | 
						|
								        """Invokes the Compute amounts function"""
							 | 
						|
								        self._compute_amount_untaxed()
							 | 
						|
								        self.invoice_button_visible = False
							 | 
						|
								
							 | 
						|
								    @api.constrains("room_line_ids")
							 | 
						|
								    def _check_duplicate_folio_room_line(self):
							 | 
						|
								        """
							 | 
						|
								        This method is used to validate the room_lines.
							 | 
						|
								        ------------------------------------------------
							 | 
						|
								        @param self: object pointer
							 | 
						|
								        @return: raise warning depending on the validation
							 | 
						|
								        """
							 | 
						|
								        for record in self:
							 | 
						|
								            # Create a set of unique ids
							 | 
						|
								            ids = set()
							 | 
						|
								            for line in record.room_line_ids:
							 | 
						|
								                if line.room_id.id in ids:
							 | 
						|
								                    raise ValidationError(
							 | 
						|
								                        _(
							 | 
						|
								                            """Room Entry Duplicates Found!, """
							 | 
						|
								                            """You Cannot Book "%s" Room More Than Once!"""
							 | 
						|
								                        )
							 | 
						|
								                        % line.room_id.name
							 | 
						|
								                    )
							 | 
						|
								                ids.add(line.room_id.id)
							 | 
						|
								
							 | 
						|
								    def create_list(self, line_ids):
							 | 
						|
								        """Returns a Dictionary containing the Booking line Values"""
							 | 
						|
								        account_move_line = self.env['account.move.line'].search_read(
							 | 
						|
								            domain=[('ref', '=', self.name),
							 | 
						|
								                    ('display_type', '!=', 'payment_term')],
							 | 
						|
								            fields=['name', 'quantity', 'price_unit', 'product_type'], )
							 | 
						|
								        for rec in account_move_line:
							 | 
						|
								            del rec['id']
							 | 
						|
								        booking_dict = {}
							 | 
						|
								        for line in line_ids:
							 | 
						|
								            name = ""
							 | 
						|
								            product_type = ""
							 | 
						|
								            if line_ids._name == 'food.booking.line':
							 | 
						|
								                name = line.food_id.name
							 | 
						|
								                product_type = 'food'
							 | 
						|
								            elif line_ids._name == 'fleet.booking.line':
							 | 
						|
								                name = line.fleet_id.name
							 | 
						|
								                product_type = 'fleet'
							 | 
						|
								            elif line_ids._name == 'service.booking.line':
							 | 
						|
								                name = line.service_id.name
							 | 
						|
								                product_type = 'service'
							 | 
						|
								            elif line_ids._name == 'event.booking.line':
							 | 
						|
								                name = line.event_id.name
							 | 
						|
								                product_type = 'event'
							 | 
						|
								            booking_dict = {'name': name,
							 | 
						|
								                            'quantity': line.uom_qty,
							 | 
						|
								                            'price_unit': line.price_unit,
							 | 
						|
								                            'product_type': product_type}
							 | 
						|
								        return booking_dict
							 | 
						|
								
							 | 
						|
								    def action_reserve(self):
							 | 
						|
								        """Button Reserve Function"""
							 | 
						|
								        if self.state == 'reserved':
							 | 
						|
								            message = _("Room Already Reserved.")
							 | 
						|
								            return {
							 | 
						|
								                'type': 'ir.actions.client',
							 | 
						|
								                'tag': 'display_notification',
							 | 
						|
								                'params': {
							 | 
						|
								                    'type': 'warning',
							 | 
						|
								                    'message': message,
							 | 
						|
								                    'next': {'type': 'ir.actions.act_window_close'},
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        if self.room_line_ids:
							 | 
						|
								            for room in self.room_line_ids:
							 | 
						|
								                room.room_id.write({
							 | 
						|
								                    'status': 'reserved',
							 | 
						|
								                })
							 | 
						|
								                room.room_id.is_room_avail = False
							 | 
						|
								            self.write({"state": "reserved"})
							 | 
						|
								            return {
							 | 
						|
								                'type': 'ir.actions.client',
							 | 
						|
								                'tag': 'display_notification',
							 | 
						|
								                'params': {
							 | 
						|
								                    'type': 'success',
							 | 
						|
								                    'message': "Rooms reserved Successfully!",
							 | 
						|
								                    'next': {'type': 'ir.actions.act_window_close'},
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        raise ValidationError(_("Please Enter Room Details"))
							 | 
						|
								
							 | 
						|
								    def action_cancel(self):
							 | 
						|
								        """
							 | 
						|
								        @param self: object pointer
							 | 
						|
								        """
							 | 
						|
								        if self.room_line_ids:
							 | 
						|
								            for room in self.room_line_ids:
							 | 
						|
								                room.room_id.write({
							 | 
						|
								                    'status': 'available',
							 | 
						|
								                })
							 | 
						|
								                room.room_id.is_room_avail = True
							 | 
						|
								        self.write({"state": "cancel"})
							 | 
						|
								
							 | 
						|
								    def action_maintenance_request(self):
							 | 
						|
								        """
							 | 
						|
								        Function that handles the maintenance request
							 | 
						|
								        """
							 | 
						|
								        room_list = []
							 | 
						|
								        for rec in self.room_line_ids.room_id.ids:
							 | 
						|
								            room_list.append(rec)
							 | 
						|
								        if room_list:
							 | 
						|
								            room_id = self.env['hotel.room'].search([
							 | 
						|
								                ('id', 'in', room_list)])
							 | 
						|
								            self.env['maintenance.request'].sudo().create({
							 | 
						|
								                'date': fields.Date.today(),
							 | 
						|
								                'state': 'draft',
							 | 
						|
								                'type': 'room',
							 | 
						|
								                'room_maintenance_ids': room_id.ids,
							 | 
						|
								            })
							 | 
						|
								            self.maintenance_request_sent = True
							 | 
						|
								            return {
							 | 
						|
								                'type': 'ir.actions.client',
							 | 
						|
								                'tag': 'display_notification',
							 | 
						|
								                'params': {
							 | 
						|
								                    'type': 'success',
							 | 
						|
								                    'message': "Maintenance Request Sent Successfully",
							 | 
						|
								                    'next': {'type': 'ir.actions.act_window_close'},
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        raise ValidationError(_("Please Enter Room Details"))
							 | 
						|
								
							 | 
						|
								    def action_done(self):
							 | 
						|
								        """Button action_confirm function"""
							 | 
						|
								        for rec in self.env['account.move'].search(
							 | 
						|
								                [('ref', '=', self.name)]):
							 | 
						|
								            if rec.payment_state != 'not_paid':
							 | 
						|
								                self.write({"state": "done"})
							 | 
						|
								                self.is_checkin = False
							 | 
						|
								                if self.room_line_ids:
							 | 
						|
								                    return {
							 | 
						|
								                        'type': 'ir.actions.client',
							 | 
						|
								                        'tag': 'display_notification',
							 | 
						|
								                        'params': {
							 | 
						|
								                            'type': 'success',
							 | 
						|
								                            'message': "Booking Checked Out Successfully!",
							 | 
						|
								                            'next': {'type': 'ir.actions.act_window_close'},
							 | 
						|
								                        }
							 | 
						|
								                    }
							 | 
						|
								            raise ValidationError(_('Your Invoice is Due for Payment.'))
							 | 
						|
								        self.write({"state": "done"})
							 | 
						|
								
							 | 
						|
								    def action_checkout(self):
							 | 
						|
								        """Button action_heck_out function"""
							 | 
						|
								        self.write({"state": "check_out"})
							 | 
						|
								        for room in self.room_line_ids:
							 | 
						|
								            room.room_id.write({
							 | 
						|
								                'status': 'available',
							 | 
						|
								                'is_room_avail': True
							 | 
						|
								            })
							 | 
						|
								            room.write({'checkout_date': datetime.today()})
							 | 
						|
								
							 | 
						|
								    def action_invoice(self):
							 | 
						|
								        """Method for creating invoice"""
							 | 
						|
								        if not self.room_line_ids:
							 | 
						|
								            raise ValidationError(_("Please Enter Room Details"))
							 | 
						|
								        booking_list = self._compute_amount_untaxed(True)
							 | 
						|
								        if booking_list:
							 | 
						|
								            account_move = self.env["account.move"].create([{
							 | 
						|
								                'move_type': 'out_invoice',
							 | 
						|
								                'invoice_date': fields.Date.today(),
							 | 
						|
								                'partner_id': self.partner_id.id,
							 | 
						|
								                'ref': self.name,
							 | 
						|
								            }])
							 | 
						|
								            for rec in booking_list:
							 | 
						|
								                account_move.invoice_line_ids.create([{
							 | 
						|
								                    'name': rec['name'],
							 | 
						|
								                    'quantity': rec['quantity'],
							 | 
						|
								                    'price_unit': rec['price_unit'],
							 | 
						|
								                    'move_id': account_move.id,
							 | 
						|
								                    'price_subtotal': rec['quantity'] * rec['price_unit'],
							 | 
						|
								                    'product_type': rec['product_type'],
							 | 
						|
								                }])
							 | 
						|
								            self.write({'invoice_status': "invoiced"})
							 | 
						|
								            self.invoice_button_visible = True
							 | 
						|
								            return {
							 | 
						|
								                'type': 'ir.actions.act_window',
							 | 
						|
								                'name': 'Invoices',
							 | 
						|
								                'view_mode': 'form',
							 | 
						|
								                'view_type': 'form',
							 | 
						|
								                'res_model': 'account.move',
							 | 
						|
								                'view_id': self.env.ref('account.view_move_form').id,
							 | 
						|
								                'res_id': account_move.id,
							 | 
						|
								                'context': "{'create': False}"
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								    def action_view_invoices(self):
							 | 
						|
								        """Method for Returning invoice View"""
							 | 
						|
								        return {
							 | 
						|
								            'type': 'ir.actions.act_window',
							 | 
						|
								            'name': 'Invoices',
							 | 
						|
								            'view_mode': 'list,form',
							 | 
						|
								            'view_type': 'list,form',
							 | 
						|
								            'res_model': 'account.move',
							 | 
						|
								            'domain': [('ref', '=', self.name)],
							 | 
						|
								            'context': "{'create': False}"
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								    def action_checkin(self):
							 | 
						|
								        """
							 | 
						|
								        @param self: object pointer
							 | 
						|
								        """
							 | 
						|
								        if not self.room_line_ids:
							 | 
						|
								            raise ValidationError(_("Please Enter Room Details"))
							 | 
						|
								        else:
							 | 
						|
								            for room in self.room_line_ids:
							 | 
						|
								                room.room_id.write({
							 | 
						|
								                    'status': 'occupied',
							 | 
						|
								                })
							 | 
						|
								                room.room_id.is_room_avail = False
							 | 
						|
								            self.write({"state": "check_in"})
							 | 
						|
								            return {
							 | 
						|
								                'type': 'ir.actions.client',
							 | 
						|
								                'tag': 'display_notification',
							 | 
						|
								                'params': {
							 | 
						|
								                    'type': 'success',
							 | 
						|
								                    'message': "Booking Checked In Successfully!",
							 | 
						|
								                    'next': {'type': 'ir.actions.act_window_close'},
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								    def get_details(self):
							 | 
						|
								        """ Returns different counts for displaying in dashboard"""
							 | 
						|
								        today = datetime.today()
							 | 
						|
								        tz_name = self.env.user.tz
							 | 
						|
								        today_utc = pytz.timezone('UTC').localize(today,
							 | 
						|
								                                                  is_dst=False)
							 | 
						|
								        context_today = today_utc.astimezone(pytz.timezone(tz_name))
							 | 
						|
								        total_room = self.env['hotel.room'].search_count([])
							 | 
						|
								        check_in = self.env['room.booking'].search_count(
							 | 
						|
								            [('state', '=', 'check_in')])
							 | 
						|
								        available_room = self.env['hotel.room'].search(
							 | 
						|
								            [('status', '=', 'available')])
							 | 
						|
								        reservation = self.env['room.booking'].search_count(
							 | 
						|
								            [('state', '=', 'reserved')])
							 | 
						|
								        check_outs = self.env['room.booking'].search([])
							 | 
						|
								        check_out = 0
							 | 
						|
								        staff = 0
							 | 
						|
								        for rec in check_outs:
							 | 
						|
								            for room in rec.room_line_ids:
							 | 
						|
								                if room.checkout_date.date() == context_today.date():
							 | 
						|
								                    check_out += 1
							 | 
						|
								            """staff"""
							 | 
						|
								            staff = self.env['res.users'].search_count(
							 | 
						|
								                [('groups_id', 'in',
							 | 
						|
								                  [self.env.ref('hotel_management_odoo.hotel_group_admin').id,
							 | 
						|
								                   self.env.ref(
							 | 
						|
								                       'hotel_management_odoo.cleaning_team_group_head').id,
							 | 
						|
								                   self.env.ref(
							 | 
						|
								                       'hotel_management_odoo.cleaning_team_group_user').id,
							 | 
						|
								                   self.env.ref(
							 | 
						|
								                       'hotel_management_odoo.hotel_group_reception').id,
							 | 
						|
								                   self.env.ref(
							 | 
						|
								                       'hotel_management_odoo.maintenance_team_group_leader').id,
							 | 
						|
								                   self.env.ref(
							 | 
						|
								                       'hotel_management_odoo.maintenance_team_group_user').id
							 | 
						|
								                   ])])
							 | 
						|
								        total_vehicle = self.env['fleet.vehicle.model'].search_count([])
							 | 
						|
								        available_vehicle = total_vehicle - self.env[
							 | 
						|
								            'fleet.booking.line'].search_count(
							 | 
						|
								            [('state', '=', 'check_in')])
							 | 
						|
								        total_event = self.env['event.event'].search_count([])
							 | 
						|
								        pending_event = self.env['event.event'].search([])
							 | 
						|
								        pending_events = 0
							 | 
						|
								        today_events = 0
							 | 
						|
								        for pending in pending_event:
							 | 
						|
								            if pending.date_end >= fields.datetime.now():
							 | 
						|
								                pending_events += 1
							 | 
						|
								            if pending.date_end.date() == fields.date.today():
							 | 
						|
								                today_events += 1
							 | 
						|
								        food_items = self.env['lunch.product'].search_count([])
							 | 
						|
								        food_order = len(self.env['food.booking.line'].search([]).filtered(
							 | 
						|
								            lambda r: r.booking_id.state not in ['check_out', 'cancel',
							 | 
						|
								                                                 'done']))
							 | 
						|
								        """total Revenue"""
							 | 
						|
								        total_revenue = 0
							 | 
						|
								        today_revenue = 0
							 | 
						|
								        pending_payment = 0
							 | 
						|
								        for rec in self.env['account.move'].search(
							 | 
						|
								                [('payment_state', '=', 'paid')]):
							 | 
						|
								            if rec.ref:
							 | 
						|
								                if 'BOOKING' in rec.ref:
							 | 
						|
								                    total_revenue += rec.amount_total
							 | 
						|
								                    if rec.date == fields.date.today():
							 | 
						|
								                        today_revenue += rec.amount_total
							 | 
						|
								        for rec in self.env['account.move'].search(
							 | 
						|
								                [('payment_state', '=', 'not_paid')]):
							 | 
						|
								            if rec.ref:
							 | 
						|
								                if 'BOOKING' in rec.ref:
							 | 
						|
								                    pending_payment += rec.amount_total
							 | 
						|
								        return {
							 | 
						|
								            'total_room': total_room,
							 | 
						|
								            'available_room': len(available_room),
							 | 
						|
								            'staff': staff,
							 | 
						|
								            'check_in': check_in,
							 | 
						|
								            'reservation': reservation,
							 | 
						|
								            'check_out': check_out,
							 | 
						|
								            'total_vehicle': total_vehicle,
							 | 
						|
								            'available_vehicle': available_vehicle,
							 | 
						|
								            'total_event': total_event,
							 | 
						|
								            'today_events': today_events,
							 | 
						|
								            'pending_events': pending_events,
							 | 
						|
								            'food_items': food_items,
							 | 
						|
								            'food_order': food_order,
							 | 
						|
								            'total_revenue': round(total_revenue, 2),
							 | 
						|
								            'today_revenue': round(today_revenue, 2),
							 | 
						|
								            'pending_payment': round(pending_payment, 2),
							 | 
						|
								            'currency_symbol': self.env.user.company_id.currency_id.symbol,
							 | 
						|
								            'currency_position': self.env.user.company_id.currency_id.position
							 | 
						|
								        }
							 | 
						|
								
							 |