from odoo import http, _ from odoo.http import request import json import logging _logger = logging.getLogger(__name__) class Dine360SelfOrderController(http.Controller): @http.route('/dine360/menu', type='http', auth='public', website=True) def self_order_menu(self, **kwargs): """Displays the self-order menu for a specific table/kiosk""" table_id = kwargs.get('table_id') table = False if table_id: table = request.env['restaurant.table'].sudo().browse(int(table_id)) values = { 'table': table, 'floor': table.floor_id if table else False, } return request.render('dine360_self_order.self_order_menu_template', values) @http.route('/dine360/self_order/products', type='json', auth='public', methods=['POST']) def get_products(self): """API to fetch products for the self-order menu""" # We only show items available in POS products = request.env['product.product'].sudo().search([ ('available_in_pos', '=', True), ('sale_ok', '=', True) ]) # Group by category if needed, but for now simple list result = [] for p in products: result.append({ 'id': p.id, 'display_name': p.display_name, 'list_price': p.list_price, 'pos_categ_id': p.pos_categ_ids[0].id if p.pos_categ_ids else False, 'pos_categ_name': p.pos_categ_ids[0].name if p.pos_categ_ids else 'General', 'description': p.description_sale or '', # Image URL helper 'image_url': f"/web/image/product.product/{p.id}/image_128", 'is_kitchen_item': p.is_kitchen_item, }) return result @http.route('/dine360/self_order/submit_order', type='json', auth='public', methods=['POST']) def submit_self_order(self, **kwargs): """API to submit a self-order and create a pos.order""" data = kwargs.get('order_data') if not data: return {'error': 'No order data received'} try: # We need an active session to link the order # For self-order, we might have a dedicated "Self-Order POS" config # Here we'll find the first open POS session or one marked as 'self_order' session = request.env['pos.session'].sudo().search([ ('state', '=', 'opened'), ('config_id.module_pos_self_order', '=', True) # Or a custom flag ], limit=1) if not session: # Fallback to any open session session = request.env['pos.session'].sudo().search([ ('state', '=', 'opened') ], limit=1) if not session: return {'error': 'No open POS session found. Please wait for staff to open the store.'} partner = request.env.user.partner_id if not request.env.user._is_public() else False # Prepare order values table_id = data.get('table_id') lines = data.get('lines', []) order_vals = { 'session_id': session.id, 'partner_id': partner.id if partner else False, 'table_id': int(table_id) if table_id else False, 'order_source': 'qr' if table_id else 'kiosk', 'fulfilment_type': data.get('fulfilment_type', 'dine_in'), 'lines': [], } for line in lines: order_vals['lines'].append((0, 0, { 'product_id': line['product_id'], 'qty': line['qty'], 'price_unit': line['price_unit'], 'customer_note': line.get('note', ''), })) # Use sudo to create the order since it's from public flow order = request.env['pos.order'].sudo().create([order_vals]) # To trigger KDS, we might need to call specific methods or the confirmation flow # For self-order, we often mark as "Pending Payment" or "Paid" depending on flow # If kiosk, it might be unpaid until cashier handles it. return { 'success': True, 'order_id': order.id, 'order_name': order.name, 'message': _("Your order has been sent to the kitchen!") } except Exception as e: _logger.error("Error submitting self-order: %s", str(e)) return {'error': str(e)}