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

# -*- 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