Browse Source

APR 16: [FIX] Bug fixed 'table_reservation_on_website'

16.0
Cybrosys Technologies 2 weeks ago
parent
commit
a5c15f99db
  1. 3
      table_reservation_on_website/__manifest__.py
  2. 1
      table_reservation_on_website/controllers/__init__.py
  3. 29
      table_reservation_on_website/controllers/pos_config.py
  4. 20
      table_reservation_on_website/controllers/table_reservation_on_website.py
  5. 7
      table_reservation_on_website/doc/RELEASE_NOTES.md
  6. 37
      table_reservation_on_website/models/res_config_settings.py
  7. BIN
      table_reservation_on_website/static/description/assets/screenshots/1.png
  8. BIN
      table_reservation_on_website/static/description/assets/screenshots/11.png
  9. BIN
      table_reservation_on_website/static/description/assets/screenshots/4.png
  10. 2
      table_reservation_on_website/static/description/index.html
  11. 108
      table_reservation_on_website/static/src/js/reservation.js
  12. 20
      table_reservation_on_website/views/res_config_settings_views.xml
  13. 83
      table_reservation_on_website/views/table_reservation_templates.xml

3
table_reservation_on_website/__manifest__.py

@ -21,7 +21,7 @@
############################################################################### ###############################################################################
{ {
'name': 'Table Reservation on Website', 'name': 'Table Reservation on Website',
'version': '16.0.1.0.1', 'version': '16.0.1.1.1',
'category': 'eCommerce,Point of Sale', 'category': 'eCommerce,Point of Sale',
'summary': 'We can reserve table through website', 'summary': 'We can reserve table through website',
'description': 'We can reserve table through website. And also user can ' 'description': 'We can reserve table through website. And also user can '
@ -53,6 +53,7 @@
'web.assets_frontend': [ 'web.assets_frontend': [
'table_reservation_on_website/static/src/js/table_reservation.js', 'table_reservation_on_website/static/src/js/table_reservation.js',
'table_reservation_on_website/static/src/js/reservation_floor.js', 'table_reservation_on_website/static/src/js/reservation_floor.js',
'table_reservation_on_website/static/src/js/reservation.js',
], ],
}, },
'images': ['static/description/banner.jpg'], 'images': ['static/description/banner.jpg'],

1
table_reservation_on_website/controllers/__init__.py

@ -21,3 +21,4 @@
############################################################################### ###############################################################################
from . import main from . import main
from . import table_reservation_on_website from . import table_reservation_on_website
from . import pos_config

29
table_reservation_on_website/controllers/pos_config.py

@ -0,0 +1,29 @@
from odoo import http
from odoo.http import request
class ResConfigSettingsController(http.Controller):
@http.route('/pos/get_opening_closing_hours', type='json', auth='public', methods=['POST'])
def get_opening_closing_hours(self):
res_config = request.env['res.config.settings'].sudo().search([], limit=1, order="id desc")
# Ensure proper time format
try:
opening_hour = self.float_to_time(float(res_config.opening_hour))
closing_hour = self.float_to_time(float(res_config.closing_hour))
except ValueError:
opening_hour = "00:00"
closing_hour = "23:59"
if res_config:
return {
'opening_hour': opening_hour,
'closing_hour': closing_hour
}
return {'error': 'POS configuration not found'}
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}"

20
table_reservation_on_website/controllers/table_reservation_on_website.py

@ -30,8 +30,26 @@ class TableReservation(http.Controller):
@http.route(['/table_reservation'], type='http', auth='user', website=True) @http.route(['/table_reservation'], type='http', auth='user', website=True)
def table_reservation(self): def table_reservation(self):
"""For render table reservation template""" """For render table reservation template"""
pos_config = request.env['res.config.settings'].sudo().search([],
limit=1, order="id desc")
try:
opening_hour = self.float_to_time(
float(pos_config.opening_hour))
closing_hour = self.float_to_time(
float(pos_config.closing_hour))
except ValueError:
opening_hour = "00:00"
closing_hour = "23:59"
return http.request.render( return http.request.render(
"table_reservation_on_website.table_reservation", {}) "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) @http.route(['/restaurant/floors'], type='http', auth='user', website=True)
def restaurant_floors(self, **kwargs): def restaurant_floors(self, **kwargs):

7
table_reservation_on_website/doc/RELEASE_NOTES.md

@ -5,3 +5,10 @@
#### ADD #### ADD
- Initial commit for Table Reservation on Website - Initial commit for Table Reservation on Website
#### 29.03.2025
#### Version 16.0.1.1.1
#### UPDATE
- Updated module to set opening and closing hours.

37
table_reservation_on_website/models/res_config_settings.py

@ -34,17 +34,40 @@ class ResConfigSettings(models.TransientModel):
"_charge") "_charge")
refund = fields.Text(string="No Refund Notes", help="No refund notes to " refund = fields.Text(string="No Refund Notes", help="No refund notes to "
"display in website") "display in website")
set_opening_hours = fields.Boolean(string="Set Opening Hours",
help="Enable to configure restaurant opening and closing hours.",
config_parameter="table_"
"reservation_on_"
"website.reservation"
"set_opening_hours")
opening_hour = fields.Float(string="Opening Hours",
help="Restaurant opening hour in 24-hour format."
)
closing_hour = fields.Float(string="Closing Hours",
help="Restaurant closing hour in 24-hour format."
)
def set_values(self): def set_values(self):
"""To set the value for a fields in config setting""" """To set the value for a fields in config setting"""
self.env['ir.config_parameter'].set_param( """To set the value for fields in config setting"""
'table_reservation_on_website.refund', self.refund) super(ResConfigSettings, self).set_values()
return super(ResConfigSettings, self).set_values() params = self.env['ir.config_parameter'].sudo()
params.set_param('table_reservation_on_website.refund',
self.refund or "")
params.set_param('table_reservation_on_website.opening_hour',
self.opening_hour or 0.0)
params.set_param('table_reservation_on_website.closing_hour',
self.closing_hour or 0.0)
def get_values(self): def get_values(self):
"""To get the value in config settings""" """To get the values in config settings"""
res = super(ResConfigSettings, self).get_values() res = super(ResConfigSettings, self).get_values()
refund = self.env['ir.config_parameter'].sudo().get_param( params = self.env['ir.config_parameter'].sudo()
'table_reservation_on_website.refund')
res.update(refund=refund if refund else False) res.update(
refund=params.get_param('table_reservation_on_website.refund', ""),
opening_hour=float(params.get_param('table_reservation_on_website.opening_hour', 0.0)),
closing_hour=float(params.get_param('table_reservation_on_website.closing_hour', 0.0))
)
return res return res

BIN
table_reservation_on_website/static/description/assets/screenshots/1.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 107 KiB

BIN
table_reservation_on_website/static/description/assets/screenshots/11.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 108 KiB

BIN
table_reservation_on_website/static/description/assets/screenshots/4.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 62 KiB

2
table_reservation_on_website/static/description/index.html

@ -172,7 +172,7 @@
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;"> <p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
If we enable "Reservation Charge" we want to pay for If we enable "Reservation Charge" we want to pay for
reservation. If we disable "Reservation Charge" there is reservation. If we disable "Reservation Charge" there is
no payment for table reservation.</p> no payment for table reservation. Also set opening and closing hours for table reservation.</p>
<img src="assets/screenshots/1.png" <img src="assets/screenshots/1.png"
class="img-thumbnail"> class="img-thumbnail">
</div> </div>

108
table_reservation_on_website/static/src/js/reservation.js

@ -0,0 +1,108 @@
/** @odoo-module **/
import publicWidget from 'web.public.widget';
import { registry } from '@web/core/registry';
import { rpc } from "@web/core/network/rpc_service";
import ajax from "web.ajax";
publicWidget.registry.reservation = publicWidget.Widget.extend({
selector: '.container',
events: {
'change #date': '_onChangeDate',
'change #start_time': '_onChangeTime',
'change #end_time': '_onChangeTime',
'click .close_btn_alert_modal': '_onClickCloseBtn',
'click .close_btn_time_alert_modal': '_onClickCloseAlertBtn',
},
async start() {
this.openingHour = null;
this.closingHour = null;
await this._fetchOpeningClosingHours();
},
async _fetchOpeningClosingHours() {
try {
const result = await ajax.jsonRpc("/pos/get_opening_closing_hours", "call", {});
if (result && !result.error) {
this.openingHour = result.opening_hour;
this.closingHour = result.closing_hour;
} else {
console.error("Error: ", result.error);
}
} catch (error) {
console.error("Failed to fetch opening and closing hours:", error);
}
},
_onChangeDate: function (ev) {
let selectedDate = new Date(this.$el.find("#date").val());
const currentDate = new Date();
if (selectedDate.setHours(0, 0, 0, 0) < currentDate.setHours(0, 0, 0, 0)) {
this.$el.find("#alert_modal").show();
this.$el.find("#date").val('');
}
this._onChangeTime();
},
_onClickCloseBtn: function() {
this.$el.find("#alert_modal").hide();
},
_onChangeTime: function() {
let start_time = this.$el.find("#start_time");
let end_time = this.$el.find("#end_time");
let now = new Date();
let currentHours = now.getHours().toString().padStart(2, '0');
let currentMinutes = now.getMinutes().toString().padStart(2, '0');
let currentTime = `${currentHours}:${currentMinutes}`;
const currentDate = new Date();
const formattedDate = currentDate.toISOString().split('T')[0];
if (start_time.val() && end_time.val()) {
if (start_time.val() > end_time.val() || start_time.val() == end_time.val()) {
this.$el.find("#time_alert_modal").show();
start_time.val('');
end_time.val('');
return;
}
}
if (!this.openingHour || !this.closingHour) {
console.warn("Opening and closing hours are not set.");
return;
}
if (start_time.val() && (start_time.val() < this.openingHour || start_time.val() > this.closingHour)) {
this.$el.find("#time_alert_modal").show();
start_time.val('');
end_time.val('');
return;
}
if (end_time.val() && (end_time.val() < this.openingHour || end_time.val() > this.closingHour)) {
this.$el.find("#time_alert_modal").show();
start_time.val('');
end_time.val('');
return;
}
if (formattedDate == this.$el.find("#date").val()) {
if (start_time.val() && start_time.val() < currentTime) {
this.$el.find("#time_alert_modal").show();
start_time.val('');
end_time.val('');
return;
}
if (end_time.val() && end_time.val() < currentTime) {
this.$el.find("#time_alert_modal").show();
start_time.val('');
end_time.val('');
return;
}
}
},
_onClickCloseAlertBtn: function() {
this.$el.find("#time_alert_modal").hide();
}
});

20
table_reservation_on_website/views/res_config_settings_views.xml

@ -26,6 +26,26 @@
<field name="refund"/> <field name="refund"/>
</div> </div>
</div> </div>
<!-- New Fields for Opening Hours -->
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="set_opening_hours"/>
</div>
<div class="o_setting_right_pane">
<label for="set_opening_hours"/>
<div class="text-muted">
Set opening and closing hours for restaurant reservation
</div>
</div>
<div class="o_setting_right_pane" style="display:flex;"
attrs="{'invisible': [('set_opening_hours', '=', False)]}">
Opening Hour:<field name="opening_hour"/>
</div>
<div class="o_setting_right_pane" style="display:flex;"
attrs="{'invisible': [('set_opening_hours', '=', False)]}">
Closing Hour: <field name="closing_hour"/>
</div>
</div>
</xpath> </xpath>
</field> </field>
</record> </record>

83
table_reservation_on_website/views/table_reservation_templates.xml

@ -19,6 +19,9 @@
<b>Table Reservation</b> <b>Table Reservation</b>
</h1> </h1>
<br/> <br/>
<t t-if="opening_hour and closing_hour">
<h4>Opening Hours: <t t-esc="opening_hour"/> - <t t-esc="closing_hour"/></h4>
</t>
<br/> <br/>
<div> <div>
<div class="form-group row" <div class="form-group row"
@ -77,6 +80,86 @@
</div> </div>
</div> </div>
</center> </center>
<center>
<div class="modal" tabindex="-1" id="alert_modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Invalid
Date
</h5>
</div>
<hr class="m-0"/>
<div class="modal-body">
<p>Please select a valid date.</p>
</div>
<hr class="m-0"/>
<div class="modal-footer">
<button type="button"
class="btn btn-secondary close_btn_alert_modal"
data-bs-dismiss="modal">
Close
</button>
</div>
</div>
</div>
</div>
</center>
<center>
<div class="modal" tabindex="-1"
id="time_alert_modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Invalid
Time
</h5>
</div>
<hr class="m-0"/>
<div class="modal-body">
<p>Please select a valid booking
start and end time.
</p>
</div>
<hr class="m-0"/>
<div class="modal-footer">
<button type="button"
class="btn btn-secondary close_btn_time_alert_modal"
data-bs-dismiss="modal">
Close
</button>
</div>
</div>
</div>
</div>
</center>
<center>
<div class="modal" tabindex="-1"
id="open_hours_alert_modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Invalid
Time
</h5>
</div>
<hr class="m-0"/>
<div class="modal-body">
<p>Select a time between the opening and closing hours
</p>
</div>
<hr class="m-0"/>
<div class="modal-footer">
<button type="button"
class="btn btn-secondary close_btn_time_alert_modal"
data-bs-dismiss="modal">
Close
</button>
</div>
</div>
</div>
</div>
</center>
<br/> <br/>
<div class="row" data-name="Submit Button"> <div class="row" data-name="Submit Button">
<div class="col-sm-2" style="padding-left:45%;"> <div class="col-sm-2" style="padding-left:45%;">

Loading…
Cancel
Save