diff --git a/addons/dine360_kds/views/pos_order_line_views.xml b/addons/dine360_kds/views/pos_order_line_views.xml
index d79521a..563ac13 100644
--- a/addons/dine360_kds/views/pos_order_line_views.xml
+++ b/addons/dine360_kds/views/pos_order_line_views.xml
@@ -25,8 +25,8 @@
-
-
+
+
diff --git a/addons/dine360_online_orders/__init__.py b/addons/dine360_online_orders/__init__.py
index 0650744..f7209b1 100644
--- a/addons/dine360_online_orders/__init__.py
+++ b/addons/dine360_online_orders/__init__.py
@@ -1 +1,2 @@
from . import models
+from . import controllers
diff --git a/addons/dine360_online_orders/__manifest__.py b/addons/dine360_online_orders/__manifest__.py
index 92b15e3..bc4ae0f 100644
--- a/addons/dine360_online_orders/__manifest__.py
+++ b/addons/dine360_online_orders/__manifest__.py
@@ -16,6 +16,8 @@
'security/ir.model.access.csv',
'views/pos_order_views.xml',
'views/kds_override_views.xml',
+ 'views/pos_config_views.xml',
+ 'views/website_sale_templates.xml',
],
'assets': {
'point_of_sale._assets_pos': [
@@ -24,6 +26,9 @@
'dine360_online_orders/static/src/js/online_orders_navbar.js',
'dine360_online_orders/static/src/xml/online_orders_screen.xml',
],
+ 'web.assets_frontend': [
+ 'dine360_online_orders/static/src/js/service_mode.js',
+ ],
},
'installable': True,
'application': False,
diff --git a/addons/dine360_online_orders/controllers/__init__.py b/addons/dine360_online_orders/controllers/__init__.py
new file mode 100644
index 0000000..12a7e52
--- /dev/null
+++ b/addons/dine360_online_orders/controllers/__init__.py
@@ -0,0 +1 @@
+from . import main
diff --git a/addons/dine360_online_orders/controllers/main.py b/addons/dine360_online_orders/controllers/main.py
new file mode 100644
index 0000000..4b6e196
--- /dev/null
+++ b/addons/dine360_online_orders/controllers/main.py
@@ -0,0 +1,14 @@
+from odoo import http
+from odoo.http import request
+
+class Dine360OnlineOrders(http.Controller):
+
+ @http.route('/shop/update_service_mode', type='json', auth="public", website=True)
+ def update_service_mode(self, service_mode, **post):
+ order = request.website.sale_get_order()
+ if order and service_mode in ['pickup', 'delivery', 'dine_in']:
+ order.sudo().write({
+ 'dine360_service_mode': service_mode,
+ 'dine360_order_source': 'web'
+ })
+ return True
diff --git a/addons/dine360_online_orders/models/__init__.py b/addons/dine360_online_orders/models/__init__.py
index 5055bda..8a88826 100644
--- a/addons/dine360_online_orders/models/__init__.py
+++ b/addons/dine360_online_orders/models/__init__.py
@@ -1,2 +1,5 @@
from . import pos_order
from . import sale_order
+from . import pos_config
+from . import res_config_settings
+from . import pos_order_line
diff --git a/addons/dine360_online_orders/models/pos_config.py b/addons/dine360_online_orders/models/pos_config.py
new file mode 100644
index 0000000..3a413ef
--- /dev/null
+++ b/addons/dine360_online_orders/models/pos_config.py
@@ -0,0 +1,10 @@
+from odoo import models, fields
+
+class PosConfig(models.Model):
+ _inherit = 'pos.config'
+
+ is_kiosk = fields.Boolean(string='Is Self-Order Kiosk', default=False)
+ kiosk_service_mode = fields.Selection([
+ ('pickup', 'Pickup'),
+ ('dine_in', 'Dine-In')
+ ], string='Default Kiosk Service Mode', default='dine_in')
diff --git a/addons/dine360_online_orders/models/pos_order.py b/addons/dine360_online_orders/models/pos_order.py
index 27ae89f..389eb84 100644
--- a/addons/dine360_online_orders/models/pos_order.py
+++ b/addons/dine360_online_orders/models/pos_order.py
@@ -31,6 +31,18 @@ class PosOrder(models.Model):
default=fields.Datetime.now
)
+ dine360_order_source = fields.Selection([
+ ('web', 'Customer Self (Web)'),
+ ('kiosk', 'Store Self (Kiosk)'),
+ ('pos', 'Standard POS')
+ ], string='Order Source', default='pos')
+
+ dine360_service_mode = fields.Selection([
+ ('pickup', 'Pickup'),
+ ('delivery', 'Delivery'),
+ ('dine_in', 'Dine-In')
+ ], string='Service Mode', default='dine_in')
+
@api.depends('partner_id', 'partner_id.name')
def _compute_online_customer_name(self):
for order in self:
@@ -80,6 +92,16 @@ class PosOrder(models.Model):
_logger.info("Online order %s rejected", self.name)
return True
+ @api.model_create_multi
+ def create(self, vals_list):
+ for vals in vals_list:
+ if 'session_id' in vals:
+ session = self.env['pos.session'].browse(vals['session_id'])
+ if session.config_id.is_kiosk:
+ vals['dine360_order_source'] = 'kiosk'
+ vals['dine360_service_mode'] = session.config_id.kiosk_service_mode
+ return super().create(vals_list)
+
@api.model
def get_online_orders(self, config_id):
"""Fetch pending online orders for a specific POS config"""
@@ -112,6 +134,8 @@ class PosOrder(models.Model):
'amount_total': order.amount_total,
'date_order': order.date_order.isoformat() if order.date_order else '',
'sale_order_name': order.sale_order_id.name if order.sale_order_id else '',
+ 'service_mode': order.dine360_service_mode,
+ 'order_source': order.dine360_order_source,
'note': order.note or '',
'lines': lines,
})
diff --git a/addons/dine360_online_orders/models/pos_order_line.py b/addons/dine360_online_orders/models/pos_order_line.py
new file mode 100644
index 0000000..cd3a7b3
--- /dev/null
+++ b/addons/dine360_online_orders/models/pos_order_line.py
@@ -0,0 +1,15 @@
+from odoo import models, fields, api
+
+class PosOrderLine(models.Model):
+ _inherit = 'pos.order.line'
+
+ dine360_order_source = fields.Selection(
+ related='order_id.dine360_order_source',
+ string='Order Source',
+ store=True
+ )
+ dine360_service_mode = fields.Selection(
+ related='order_id.dine360_service_mode',
+ string='Service Mode',
+ store=True
+ )
diff --git a/addons/dine360_online_orders/models/res_config_settings.py b/addons/dine360_online_orders/models/res_config_settings.py
new file mode 100644
index 0000000..3c49767
--- /dev/null
+++ b/addons/dine360_online_orders/models/res_config_settings.py
@@ -0,0 +1,7 @@
+from odoo import models, fields
+
+class ResConfigSettings(models.TransientModel):
+ _inherit = 'res.config.settings'
+
+ is_kiosk = fields.Boolean(related='pos_config_id.is_kiosk', readonly=False)
+ kiosk_service_mode = fields.Selection(related='pos_config_id.kiosk_service_mode', readonly=False)
diff --git a/addons/dine360_online_orders/models/sale_order.py b/addons/dine360_online_orders/models/sale_order.py
index 139693a..bfdab3c 100644
--- a/addons/dine360_online_orders/models/sale_order.py
+++ b/addons/dine360_online_orders/models/sale_order.py
@@ -12,6 +12,18 @@ class SaleOrderOnline(models.Model):
help='The POS order created from this website sale order'
)
+ dine360_order_source = fields.Selection([
+ ('web', 'Customer Self (Web)'),
+ ('kiosk', 'Store Self (Kiosk)'),
+ ('pos', 'Standard POS')
+ ], string='Order Source', default='web')
+
+ dine360_service_mode = fields.Selection([
+ ('pickup', 'Pickup'),
+ ('delivery', 'Delivery'),
+ ('dine_in', 'Dine-In')
+ ], string='Service Mode', default='pickup')
+
def _create_pos_order_for_kds(self, sale_order):
"""
Override from dine360_kds to also mark the POS order as an online order.
@@ -35,6 +47,8 @@ class SaleOrderOnline(models.Model):
'online_order_status': 'pending',
'sale_order_id': sale_order.id,
'online_order_date': fields.Datetime.now(),
+ 'dine360_order_source': sale_order.dine360_order_source,
+ 'dine360_service_mode': sale_order.dine360_service_mode,
})
# Link back to sale order
diff --git a/addons/dine360_online_orders/static/src/js/service_mode.js b/addons/dine360_online_orders/static/src/js/service_mode.js
new file mode 100644
index 0000000..3cde396
--- /dev/null
+++ b/addons/dine360_online_orders/static/src/js/service_mode.js
@@ -0,0 +1,62 @@
+/** @odoo-module **/
+
+import publicWidget from "@web/legacy/js/public/public_widget";
+import { jsonrpc } from "@web/core/network/rpc_service";
+
+publicWidget.registry.ServiceModeSelector = publicWidget.Widget.extend({
+ selector: '#service_mode_selector',
+ events: {
+ 'change input[name="dine360_service_mode"]': '_onChangeServiceMode',
+ },
+
+ start: function () {
+ // Init visual selection
+ this.$('input[name="dine360_service_mode"]:checked').closest('.service-option').find('.service-card')
+ .css({ 'border-color': '#FECD4F', 'background-color': '#fffdf6', 'box-shadow': '0 4px 10px rgba(254, 205, 79, 0.2)' });
+ return this._super.apply(this, arguments);
+ },
+
+ _onChangeServiceMode: function (ev) {
+ var $input = $(ev.currentTarget);
+ var mode = $input.val();
+
+ // Reset styles
+ this.$('.service-card').css({ 'border-color': '', 'background-color': '', 'box-shadow': '' });
+ // Apply active styles
+ $input.closest('.service-option').find('.service-card')
+ .css({ 'border-color': '#FECD4F', 'background-color': '#fffdf6', 'box-shadow': '0 4px 10px rgba(254, 205, 79, 0.2)' });
+
+ // Hide error if present
+ this.$('#service_mode_error').addClass('d-none');
+
+ // RPC Call to update order
+ jsonrpc('/shop/update_service_mode', {
+ service_mode: mode
+ });
+ }
+});
+
+// Intercept checkout to ensure a service mode is selected
+publicWidget.registry.CartCheckoutValidation = publicWidget.Widget.extend({
+ selector: '.oe_cart',
+ events: {
+ 'click a[href="/shop/checkout"]': '_onCheckoutClicked',
+ },
+
+ _onCheckoutClicked: function (ev) {
+ // If there's a selector on the page
+ if (this.$('#service_mode_selector').length > 0) {
+ var selectedMode = this.$('input[name="dine360_service_mode"]:checked').val();
+ if (!selectedMode) {
+ ev.preventDefault();
+ this.$('#service_mode_error').removeClass('d-none');
+
+ // Highlight the box
+ this.$('#service_mode_selector').css('border', '1px solid #dc3545').addClass('shake-animation');
+ setTimeout(() => {
+ this.$('#service_mode_selector').removeClass('shake-animation');
+ }, 500);
+ }
+ }
+ }
+});
diff --git a/addons/dine360_online_orders/views/kds_override_views.xml b/addons/dine360_online_orders/views/kds_override_views.xml
index b922ec8..e31d236 100644
--- a/addons/dine360_online_orders/views/kds_override_views.xml
+++ b/addons/dine360_online_orders/views/kds_override_views.xml
@@ -10,4 +10,31 @@
'|', ('order_id.is_online_order', '=', False), ('order_id.online_order_status', '!=', 'pending')
]
+
+
+
+ pos.order.line.kds.kanban.inherit
+ pos.order.line
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/dine360_online_orders/views/pos_config_views.xml b/addons/dine360_online_orders/views/pos_config_views.xml
new file mode 100644
index 0000000..6ce0ca6
--- /dev/null
+++ b/addons/dine360_online_orders/views/pos_config_views.xml
@@ -0,0 +1,22 @@
+
+
+
+ res.config.settings.view.form.inherit.dine360
+ res.config.settings
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/dine360_online_orders/views/pos_order_views.xml b/addons/dine360_online_orders/views/pos_order_views.xml
index 83e90a4..d8f4858 100644
--- a/addons/dine360_online_orders/views/pos_order_views.xml
+++ b/addons/dine360_online_orders/views/pos_order_views.xml
@@ -15,6 +15,11 @@
decoration-success="online_order_status=='confirmed'"
decoration-danger="online_order_status=='rejected'"/>
+
+
@@ -33,6 +38,8 @@
decoration-success="online_order_status=='confirmed'"
decoration-danger="online_order_status=='rejected'"/>
+
+
diff --git a/addons/dine360_online_orders/views/website_sale_templates.xml b/addons/dine360_online_orders/views/website_sale_templates.xml
new file mode 100644
index 0000000..da39bd5
--- /dev/null
+++ b/addons/dine360_online_orders/views/website_sale_templates.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
How would you like your order?
+
+
Please select Pickup or Delivery to continue.
+
+
+
+