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.
		
		
		
		
		
			
		
			
				
					
					
						
							749 lines
						
					
					
						
							36 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							749 lines
						
					
					
						
							36 KiB
						
					
					
				| # -*- coding: utf-8 -*- | |
| ############################################################################### | |
| # | |
| #    Cybrosys Technologies Pvt. Ltd. | |
| # | |
| #    Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | |
| #    Author: Vishnu K P (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) | |
| 
 | |
|     def unlink(self): | |
|         for rec in self: | |
|             if rec.state != 'cancel' and rec.state != 'draft': | |
|                 raise ValidationError('Cannot delete the Booking. Cancel the Booking ') | |
|         return super().unlink() | |
| 
 | |
|     @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 = False | |
|         if self.env.user.tz: | |
|             tz_name = self.env.user.tz | |
|         today_utc = pytz.timezone('UTC').localize(today, | |
|                                                   is_dst=False) | |
|         if tz_name: | |
|             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 | |
|             } | |
|         else: | |
|             raise ValidationError(_("Please Enter time zone in user settings."))
 | |
| 
 |