diff --git a/table_reservation_on_website/__manifest__.py b/table_reservation_on_website/__manifest__.py index 08800ea37..5a6268cc3 100644 --- a/table_reservation_on_website/__manifest__.py +++ b/table_reservation_on_website/__manifest__.py @@ -21,7 +21,7 @@ ############################################################################### { 'name': 'Table Reservation on Website', - 'version': '15.0.1.0.0', + 'version': '15.0.1.1.0', 'category': 'eCommerce,Point of Sale', 'summary': 'We can reserve table through website', 'description': 'We can reserve table through website. And also user can ' @@ -53,6 +53,7 @@ 'web.assets_frontend': [ '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.js', ], }, 'images': ['static/description/banner.png'], diff --git a/table_reservation_on_website/controllers/__init__.py b/table_reservation_on_website/controllers/__init__.py index 4b23b6364..b8593b16c 100644 --- a/table_reservation_on_website/controllers/__init__.py +++ b/table_reservation_on_website/controllers/__init__.py @@ -20,4 +20,5 @@ # ############################################################################### from . import main -from . import table_reservation_on_website +from . import table_reservation +from . import pos_config diff --git a/table_reservation_on_website/controllers/pos_config.py b/table_reservation_on_website/controllers/pos_config.py new file mode 100644 index 000000000..b57f697fb --- /dev/null +++ b/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): + pos_config = request.env['pos.config'].sudo().search([], limit=1, order="id desc") + # Ensure proper time format + 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" + + if pos_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}" diff --git a/table_reservation_on_website/controllers/table_reservation_on_website.py b/table_reservation_on_website/controllers/table_reservation.py similarity index 91% rename from table_reservation_on_website/controllers/table_reservation_on_website.py rename to table_reservation_on_website/controllers/table_reservation.py index bc064dbbd..54d0ed08b 100644 --- a/table_reservation_on_website/controllers/table_reservation_on_website.py +++ b/table_reservation_on_website/controllers/table_reservation.py @@ -30,8 +30,27 @@ class TableReservation(http.Controller): @http.route(['/table_reservation'], type='http', auth='user', website=True) def table_reservation(self): """For render table reservation template""" + pos_config = request.env['pos.config'].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( - "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) def restaurant_floors(self, **kwargs): @@ -54,7 +73,7 @@ class TableReservation(http.Controller): "table_reservation_on_website.restaurant_floors", vals) @http.route(['/restaurant/floors/tables'], type='json', auth='user', - website=True) + website=True ) def restaurant_floors_tables(self, **kwargs): """To get non-reserved table details""" table_inbetween = [] @@ -93,8 +112,8 @@ class TableReservation(http.Controller): data_tables[rec.id]['rate'] = 0 return data_tables - @http.route(['/booking/confirm'], type="http", auth="public", - csrf=False, website=True) + @http.route(['/booking/confirm'], type="http", auth="public", methods=['POST'], website=True + ) def booking_confirm(self, **kwargs): """For booking tables""" company = request.env.company diff --git a/table_reservation_on_website/doc/RELEASE_NOTES.md b/table_reservation_on_website/doc/RELEASE_NOTES.md index c61545b9a..b9314240c 100644 --- a/table_reservation_on_website/doc/RELEASE_NOTES.md +++ b/table_reservation_on_website/doc/RELEASE_NOTES.md @@ -5,3 +5,9 @@ #### ADD - Initial commit for Table Reservation on Website + +#### 01.04.2025 +#### Version 15.0.1.1.0 +#### UPDATE + +- Updated module to set opening and closing hours. diff --git a/table_reservation_on_website/models/pos_config.py b/table_reservation_on_website/models/pos_config.py index 248d81e04..4914ab645 100644 --- a/table_reservation_on_website/models/pos_config.py +++ b/table_reservation_on_website/models/pos_config.py @@ -35,3 +35,15 @@ class PosConfig(models.Model): refund = fields.Text(string="No Refund Notes", help="No refund notes to " "display in website", config_parameter="table_reservation_on_website.refund") + 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." + ) diff --git a/table_reservation_on_website/static/description/assets/screenshots/19.png b/table_reservation_on_website/static/description/assets/screenshots/19.png new file mode 100644 index 000000000..8b6103c47 Binary files /dev/null and b/table_reservation_on_website/static/description/assets/screenshots/19.png differ diff --git a/table_reservation_on_website/static/description/assets/screenshots/4.png b/table_reservation_on_website/static/description/assets/screenshots/4.png index d6433d65c..70ba50406 100644 Binary files a/table_reservation_on_website/static/description/assets/screenshots/4.png and b/table_reservation_on_website/static/description/assets/screenshots/4.png differ diff --git a/table_reservation_on_website/static/description/index.html b/table_reservation_on_website/static/description/index.html index a3c268fef..6be0ba2a5 100644 --- a/table_reservation_on_website/static/description/index.html +++ b/table_reservation_on_website/static/description/index.html @@ -175,7 +175,10 @@ - +
+

Set Opening and Closing hours for table reservation

+ +

Select Your Date and Time

diff --git a/table_reservation_on_website/static/src/js/reservation.js b/table_reservation_on_website/static/src/js/reservation.js new file mode 100644 index 000000000..69d7da8d2 --- /dev/null +++ b/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(); + } +}); \ No newline at end of file diff --git a/table_reservation_on_website/static/src/js/reservation_floor.js b/table_reservation_on_website/static/src/js/reservation_floor.js index 098a134ed..63d9f5de3 100644 --- a/table_reservation_on_website/static/src/js/reservation_floor.js +++ b/table_reservation_on_website/static/src/js/reservation_floor.js @@ -15,20 +15,16 @@ publicWidget.registry.table_reservation_floor = publicWidget.Widget.extend({ var count = this.$el.find('#count_table')[0]; var amount = this.$el.find('#total_amount')[0]; var booked = this.$el.find('#tables_input')[0]; - var table_count = this.$el.find('#tables_counts')[0]; - count.innerText = table_count.value if (current_div_id.style.backgroundColor == 'green'){ booked_table.splice(booked_table.indexOf(Number(current_div_id.id)), 1); current_div_id.style.backgroundColor = '#96ccd5'; count.innerText = Number(count.innerText) - 1; amount.innerText = Number(amount.innerText) - Number(rate) - table_count.value = Number(count.innerText); } else{ current_div_id.style.backgroundColor = 'green' count.innerText = Number(count.innerText) + 1; booked_table.push(Number(current_div_id.id)) - table_count.value = Number(count.innerText); if (amount.innerText){ amount.innerText = Number(rate) + Number(amount.innerText) } diff --git a/table_reservation_on_website/static/src/js/table_reservation.js b/table_reservation_on_website/static/src/js/table_reservation.js index 5b7c2f837..c6f745b18 100644 --- a/table_reservation_on_website/static/src/js/table_reservation.js +++ b/table_reservation_on_website/static/src/js/table_reservation.js @@ -12,15 +12,15 @@ publicWidget.registry.table_reservation = publicWidget.Widget.extend({ **/ _onFloorChange: function () { var floors = this.$el.find("#floors_rest")[0].value; - var date = this.$el.find("#date_id").prevObject[0].offsetParent.lastElementChild[1].defaultValue - var start = this.$el.find("#start_id").prevObject[0].offsetParent.lastElementChild[2].defaultValue + var date = $("#date_id").val(); + var start = $("#start_id").val(); document.getElementById('count_table').innerText = 0; document.getElementById('total_amount').innerText = 0; ajax.jsonRpc("/restaurant/floors/tables", 'call', { 'floors_id' : floors, 'date': date, 'start':start, - }) + }) .then(function (data) { if(floors == 0){ $('#table_container_row').empty(); diff --git a/table_reservation_on_website/views/pos_config_views.xml b/table_reservation_on_website/views/pos_config_views.xml index 61a9c2c47..507f84113 100644 --- a/table_reservation_on_website/views/pos_config_views.xml +++ b/table_reservation_on_website/views/pos_config_views.xml @@ -26,6 +26,26 @@
+ +
+
+ +
+
+
+
+ Opening Hour: +
+
+ Closing Hour: +
+
diff --git a/table_reservation_on_website/views/table_reservation_templates.xml b/table_reservation_on_website/views/table_reservation_templates.xml index 759c30cc5..103f42a12 100644 --- a/table_reservation_on_website/views/table_reservation_templates.xml +++ b/table_reservation_on_website/views/table_reservation_templates.xml @@ -1,11 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -