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.
		
		
		
		
		
			
		
			
				
					
					
						
							327 lines
						
					
					
						
							16 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							327 lines
						
					
					
						
							16 KiB
						
					
					
				| # -*- coding: utf-8 -*- | |
| ############################################################################### | |
| # | |
| #    Cybrosys Technologies Pvt. Ltd. | |
| # | |
| #    Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | |
| #    Author: Aysha Shalin (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 http, _ | |
| from odoo.exceptions import ValidationError | |
| from odoo.http import request | |
| 
 | |
| 
 | |
| class TableReservation(http.Controller): | |
|     """ For reservation of tables """ | |
|     @http.route(['/table_reservation'], type='http', auth='user', website=True) | |
|     def table_reservation(self): | |
|         """ For rendering table reservation template """ | |
|         pos_config = request.env['res.config.settings'].sudo().search([], | |
|                                                                       limit=1) | |
|         try: | |
|             opening_hour = self.float_to_time(float(pos_config.pos_opening_hour)) | |
|             closing_hour = self.float_to_time(float(pos_config.pos_closing_hour)) | |
|         except ValueError: | |
|             opening_hour = "00:00" | |
|             closing_hour = "23:59" | |
| 
 | |
|         return http.request.render( | |
|             "table_reservation_on_website.table_reservation", {'opening_hour': opening_hour, | |
|             'closing_hour': closing_hour}) | |
| 
 | |
|     def float_to_time(self, hour_float): | |
|         """ Convert float hours (e.g., 8.5 → 08:30) to HH:MM format """ | |
|         hours = int(hour_float) | |
|         minutes = int((hour_float - hours) * 60) | |
|         return f"{hours:02d}:{minutes:02d}" | |
| 
 | |
|     @http.route(['/restaurant/floors'], type='http', auth='user', website=True) | |
|     def restaurant_floors(self, **kwargs): | |
|         """ To get floor details """ | |
|         floors = request.env['restaurant.floor'].sudo().search([]) | |
|         payment = request.env['ir.config_parameter'].sudo().get_param( | |
|             "table_reservation_on_website.reservation_charge") | |
|         refund = request.env['ir.config_parameter'].sudo().get_param( | |
|             'table_reservation_on_website.refund') | |
|         vals = { | |
|             'floors': floors, | |
|             'date': kwargs.get('date'), | |
|             'start_time': kwargs.get('start_time'), | |
|             'end_time': kwargs.get('end_time'), | |
|             'payment': payment, | |
|             'refund': refund, | |
|         } | |
|         return http.request.render( | |
|             "table_reservation_on_website.restaurant_floors", vals) | |
| 
 | |
|     @http.route(['/restaurant/floors/tables'], type='json', auth='user', | |
|                 website=True) | |
|     def restaurant_floors_tables(self, **kwargs): | |
|         """ To get non-reserved table details """ | |
|         table_inbetween = [] | |
|         payment = request.env['ir.config_parameter'].sudo().get_param( | |
|             "table_reservation_on_website.reservation_charge") | |
|         tables = request.env['restaurant.table'].sudo().search( | |
|             [('floor_id', '=', int(kwargs.get('floors_id')))]) | |
|         reserved = request.env['table.reservation'].sudo().search( | |
|             [('floor_id', '=', int(kwargs.get('floors_id'))), ( | |
|                 'date', '=', datetime.strptime(kwargs.get('date'), | |
|                                                "%Y-%m-%d")), ( | |
|                 'state', '=', 'reserved')]) | |
|         start_time_new = datetime.strptime(kwargs.get("start").strip(), | |
|                                            "%H:%M").time() | |
|         for rec in reserved: | |
|             start_time = datetime.strptime(rec.starting_at, "%H:%M") | |
|             start_at = start_time - timedelta( | |
|                 hours=int(rec.lead_time), | |
|                 minutes=int((rec.lead_time % 1) * 100)) | |
|             end_at = datetime.strptime(rec.ending_at, "%H:%M").time() | |
|             if start_at.time() <= start_time_new <= end_at: | |
|                 for table in rec.booked_tables_ids: | |
|                     table_inbetween.append(table.id) | |
|         data_tables = {} | |
|         for rec in tables: | |
|             if rec.id not in table_inbetween: | |
|                 if payment: | |
|                     data_tables[rec.id] = {} | |
|                     data_tables[rec.id]['id'] = rec.id | |
|                     data_tables[rec.id]['name'] = rec.name | |
|                     data_tables[rec.id]['seats'] = rec.seats | |
|                     data_tables[rec.id]['rate'] = rec.rate | |
|                 else: | |
|                     data_tables[rec.id] = {} | |
|                     data_tables[rec.id]['id'] = rec.id | |
|                     data_tables[rec.id]['name'] = rec.name | |
|                     data_tables[rec.id]['seats'] = rec.seats | |
|                     data_tables[rec.id]['rate'] = 0 | |
|         return data_tables | |
| 
 | |
|     @http.route(['/booking/confirm'], type="http", auth="public", | |
|                 csrf=False, website=True) | |
|     def booking_confirm(self, **kwargs): | |
|         """ For booking tables """ | |
|         company = request.env.company | |
|         if kwargs.get("tables"): | |
|             list_tables = [rec for rec in kwargs.get("tables").split(',')] | |
|             record_tables = request.env['restaurant.table'].sudo().search( | |
|                 [('id', 'in', list_tables)]) | |
|             amount = [rec.rate for rec in record_tables] | |
|             payment = request.env['ir.config_parameter'].sudo().get_param( | |
|                 "table_reservation_on_website.reservation_charge") | |
|             if payment: | |
|                 table = request.env.ref( | |
|                     'table_reservation_on_website' | |
|                     '.product_product_table_booking').sudo() | |
|                 table.write({ | |
|                     'list_price': sum(amount) | |
|                 }) | |
|                 sale_order = request.website.sale_get_order(force_create=True) | |
|                 if sale_order.state != 'draft': | |
|                     request.session['sale_order_id'] = None | |
|                     sale_order = request.website.sale_get_order( | |
|                         force_create=True) | |
|                 sale_order.sudo().write({ | |
|                     'tables_ids': record_tables, | |
|                     'floors': kwargs.get('floors'), | |
|                     'date': kwargs.get('date'), | |
|                     'starting_at': kwargs.get('start_time'), | |
|                     "ending_at": kwargs.get('end_time'), | |
|                     'booking_amount': sum(amount), | |
|                     'order_line': [ | |
|                         (0, 0, { | |
|                             'name': request.env.ref( | |
|                                 'table_reservation_on_website' | |
|                                 '.product_product_table_booking').name, | |
|                             'product_id': request.env.ref( | |
|                                 'table_reservation_on_website' | |
|                                 '.product_product_table_booking').id, | |
|                             'product_uom_qty': 1, | |
|                             'price_unit': sum(amount), | |
|                         })], | |
|                 }) | |
|                 sale_order.website_id = request.env['website'].sudo().search( | |
|                     [('company_id', '=', company.id)], limit=1) | |
|                 return request.redirect("/shop/cart") | |
|             else: | |
|                 reservation = request.env['table.reservation'].sudo().create({ | |
|                     "customer_id": request.env.user.partner_id.id, | |
|                     "booked_tables_ids": record_tables, | |
|                     "floor_id": kwargs.get('floors'), | |
|                     "date": kwargs.get('date'), | |
|                     "starting_at": kwargs.get('start_time'), | |
|                     "ending_at": kwargs.get('end_time'), | |
|                     'booking_amount': 0, | |
|                     'state': 'reserved', | |
|                     'type': 'website', | |
|                 }) | |
|                 string = f'The reservation amount for the selected table is {reservation.booking_amount}.' if reservation.booking_amount > 0 else '' | |
|                 list_of_tables = record_tables.mapped('name') | |
|                 if len(list_of_tables) > 1: | |
|                     tables_sentence = ', '.join( | |
|                         list_of_tables[:-1]) + ', and ' + list_of_tables[-1] | |
|                 else: | |
|                     tables_sentence = list_of_tables[0] | |
|                 final_sentence = string + " You have reserved " + tables_sentence + "." | |
|                 request.env['mail.mail'].sudo().create({ | |
|                     'subject': "Table reservation", | |
|                     'email_to': request.env.user.login, | |
|                     'recipient_ids': [request.env.user.partner_id.id], | |
|                     'body_html': | |
|                         '<table border=0 cellpadding=0 cellspacing=0 ' | |
|                         'style="padding-top: 16px; background-color: ' | |
|                         '#F1F1F1; font-family:Verdana, Arial,sans-serif; ' | |
|                         'color: #454748; width: 100%; ' | |
|                         'border-collapse:separate;"><tr><td align=center>' | |
|                         '<table border=0 cellpadding=0 cellspacing=0 width=590 style="padding: 16px; background-color: white; color: #454748; border-collapse:separate;">' | |
|                         '<tbody>' | |
|                         '<!-- HEADER -->' | |
|                         '<tr>' | |
|                         '<td align=center style="min-width: 590px;">' | |
|                         '<table border=0 cellpadding=0 cellspacing=0 width=590 style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">' | |
|                         '<tr>' | |
|                         '<td valign=middle>' | |
|                         '<span style="font-size: 10px;">'+reservation.sequence+'</span><br/>' | |
|                         '<span style="font-size: 20px; font-weight: bold;">' + 'Table Reservation' + '</span>' | |
|                          '</td>' | |
|                          '<td valign="middle" align="right">' | |
|                          '<img src="/logo.png?company=" + self.company_id.id + style="padding: 0px; margin: 0px; height: auto; width: 80px;"/>' | |
|                          '</td>' | |
|                          '</tr>' | |
|                          '<tr>''<td colspan="2" style="text-align:center;">' | |
|                          '<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;"/>' | |
|                          '</td>''</tr>' | |
|                          '</table>' | |
|                          '</td>' | |
|                          '</tr>' | |
|                          '<!-- CONTENT -->' | |
|                          '<tr>' | |
|                          '<td align="center" style="min-width: 590px;">' | |
|                          '<table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">' | |
|                          '<tr>' | |
|                          '<td valign="top" style="font-size: 13px;">' | |
|                          '<div>' | |
|                          'Dear' + ' ' + request.env.user.name + ',' '<br/>''<br/>' | |
|                          'Your table booking at ' + request.env['restaurant.floor'].sudo().browse(int(kwargs.get('floors'))).name + ' ' + 'has been confirmed on '+str(reservation.date)+' for '+reservation.starting_at+' to '+reservation.ending_at + '.' + final_sentence + | |
|                         '<br/>''<br/>' | |
|                         '</span>' | |
|                         '</div>' | |
|                         '<br/>' | |
|                         'Best regards''<br/>' | |
|                         '</div>' | |
|                         '</td>' | |
|                         '</tr>' | |
|                         '<tr>' | |
|                         '<td style="text-align:center;">' | |
|                         '<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;"/>' | |
|                         '</td>' | |
|                         '</tr>' | |
|                         '</table>' | |
|                         '</td>' | |
|                         '</tr>' | |
|                         '<!-- FOOTER -->' | |
|                         '<tr>' | |
|                         '<td align="center" style="min-width: 590px;">' | |
|                         '<table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: white; font-size: 11px; padding: 0px 8px 0px 8px; border-collapse:separate;">' | |
|                         '<tr>' | |
|                         '<td valign="middle" align="left">' | |
|                         + request.env.company.name + | |
|                         '<br/>' | |
|                         + request.env.company.phone + | |
|                         '</td>' | |
|                         '<td valign="middle" align="right">' | |
|                         '<t t-if="%s" % +self.env.company_id.email>' | |
|                         '<a href="mailto:%s % +request.env.company_id.email+" style="text-decoration:none; color: #5e6061;">' | |
|                         + request.env.company.email + | |
|                         '</a>' | |
|                         '</t>' | |
|                         '<br/>' | |
|                         '<t t-if="%s % +self.env.company.website+ ">' | |
|                         '</table>' | |
|                 }).send() | |
|             return request.render( | |
|                 "table_reservation_on_website.table_reserved_template") | |
|         else: | |
|             raise ValidationError(_("Please select table.")) | |
| 
 | |
|     @http.route(['/table/reservation/pos'], type='json', auth='user', | |
|                 website=True) | |
|     def table_reservation_pos(self, table_id): | |
|         """ For pos table booking """ | |
|         table = request.env['restaurant.table'].sudo().browse(table_id) | |
|         date_and_time = datetime.now() | |
|         starting_at = ( | |
|             (date_and_time + timedelta(hours=5, minutes=30)).time()).strftime( | |
|             "%H:%M") | |
|         end_time = ( | |
|             (date_and_time + timedelta(hours=6, minutes=30)).time()).strftime( | |
|             "%H:%M") | |
|         payment = request.env['ir.config_parameter'].sudo().get_param( | |
|             "table_reservation_on_website.reservation_charge") | |
|         if payment: | |
|             request.env['table.reservation'].sudo().create({ | |
|                 'floor_id': table.floor_id.id, | |
|                 'booked_tables_ids': table, | |
|                 'date': date_and_time.date(), | |
|                 'starting_at': starting_at, | |
|                 'ending_at': end_time, | |
|                 'booking_amount': table.rate, | |
|                 'state': 'reserved', | |
|                 'type': 'pos' | |
|             }) | |
|         else: | |
|             request.env['table.reservation'].sudo().create({ | |
|                 'floor_id': table.floor_id.id, | |
|                 'booked_tables_ids': table, | |
|                 'date': date_and_time.date(), | |
|                 'starting_at': starting_at, | |
|                 'ending_at': end_time, | |
|                 'booking_amount': 0, | |
|                 'state': 'reserved', | |
|                 'type': 'pos' | |
|             }) | |
|         return | |
| 
 | |
|     @http.route(['/active/floor/tables'], type='json', auth='user', | |
|                 website=True) | |
|     def active_floor_tables(self, floor_id): | |
|         """ To get active floors """ | |
|         table_inbetween = [] | |
|         product_id = request.env.ref( | |
|             'table_reservation_on_website.' | |
|             'product_product_table_booking_pos') | |
|         for rec in request.env['pos.category'].sudo().search([]): | |
|             if rec: | |
|                 product_id.pos_categ_ids = [(4, rec.id, 0)] | |
| 
 | |
|         table_reservation = request.env['table.reservation'].sudo().search([( | |
|             'floor_id', "=", floor_id), ('date', '=', datetime.now().date()), | |
|             ('state', '=', 'reserved')]) | |
|         for rec in table_reservation: | |
|             start_time = datetime.strptime(rec.starting_at, "%H:%M") | |
|             start_at = start_time - timedelta( | |
|                 hours=int(rec.lead_time), | |
|                 minutes=int((rec.lead_time % 1) * 100)) | |
|             end_at = datetime.strptime(rec.ending_at, "%H:%M").time() | |
|             now = ( | |
|                 (datetime.now() + timedelta(hours=5, | |
|                                             minutes=30)).time()).strftime( | |
|                 "%H:%M") | |
|             if start_at.time() <= datetime.strptime( | |
|                     now, "%H:%M").time() <= end_at: | |
|                 for table in rec.booked_tables_ids: | |
|                     table_inbetween.append(table.id) | |
|         return table_inbetween
 | |
| 
 |