from odoo import http from odoo.http import request from odoo.addons.web.controllers.home import Home class CustomHome(Home): @http.route('/web/login', type='http', auth="public", website=True) def web_login(self, *args, **kw): response = super(CustomHome, self).web_login(*args, **kw) if request.params.get('login_success') and request.session.uid: # Use relative redirect to maintain HTTPS/HTTP protocol return request.redirect('/') return response from odoo.addons.website.controllers.main import Website class ImageHome(Website): @http.route('/', type='http', auth='public', website=True, sitemap=True) def index(self, **kwargs): # ----------------------------------------------------------- # SUPER SAFE EDITOR & IFRAME DETECTION # ----------------------------------------------------------- path = request.httprequest.path params = request.params headers = request.httprequest.headers referer = headers.get('Referer', '') fetch_dest = headers.get('Sec-Fetch-Dest', '') # 1. If not logged in, always show standard homepage if not request.session.uid: return super(ImageHome, self).index(**kwargs) # 2. Check for ANY editor or backend signal # - Sec-Fetch-Dest: iframe (Chrome/Firefox standard) # - Any of these common Odoo params: editor_params = ['enable_editor', 'edit', 'path', 'website_id', 'frontend_edit', 'model', 'id'] is_editor_request = any(p in params for p in editor_params) # - Referer contains backend markers is_from_backend = any(m in referer for m in ['/web', '/website/force', 'enable_editor']) # - Odoo often passes things in kwargs that are not in params has_kwargs = len(kwargs) > 0 # if it looks like Odoo internal business, return the real website if fetch_dest == 'iframe' or is_editor_request or is_from_backend or has_kwargs: return super(ImageHome, self).index(**kwargs) # 3. Final safety check: if we are not at exactly '/', don't intercept if path != '/': return super(ImageHome, self).index(**kwargs) # Remove sudo() to respect Odoo's standard menu group restrictions menus = request.env['ir.ui.menu'].search([ ('parent_id', '=', False) ], order='sequence') # User role checks try: is_admin = request.env.user.has_group('base.group_system') or \ request.env.user.has_group('dine360_restaurant.group_restaurant_admin') is_kitchen = request.env.user.has_group('dine360_restaurant.group_restaurant_kitchen') except Exception: is_admin = request.env.user.has_group('base.group_system') is_kitchen = False filtered_menus = [] seen_names = set() for menu in menus: # 1. Hide "Apps" for non-admins if (menu.name == 'Apps' or (menu.web_icon and menu.web_icon.startswith('base,'))) and not is_admin: continue # 2. Hide "Kitchen (KDS)" for non-kitchen/non-admin users if 'Kitchen' in menu.name or 'KDS' in menu.name: if not (is_kitchen or is_admin): continue # 3. De-duplicate by name if menu.name in seen_names: continue seen_names.add(menu.name) # 4. Dynamic Icon Override (Dine360 Branding) # This maps menu names to our custom SVG icons dynamically icon_mapping = { 'Discuss': 'dine360_dashboard,static/src/img/icons/discuss.svg', 'Calendar': 'dine360_dashboard,static/src/img/icons/calendar.svg', 'Contacts': 'dine360_dashboard,static/src/img/icons/contacts.svg', 'CRM': 'dine360_dashboard,static/src/img/icons/crm.svg', 'Sales': 'dine360_dashboard,static/src/img/icons/sales.svg', 'Dashboards': 'dine360_dashboard,static/src/img/icons/dashboards.svg', 'Point of Sale': 'dine360_dashboard,static/src/img/icons/point_of_sale.svg', 'Invoicing': 'dine360_dashboard,static/src/img/icons/invoicing.svg', 'Website': 'dine360_dashboard,static/src/img/icons/website.svg', 'Purchase': 'dine360_dashboard,static/src/img/icons/purchase.svg', 'Inventory': 'dine360_dashboard,static/src/img/icons/inventory.svg', 'Employees': 'dine360_dashboard,static/src/img/icons/employees.svg', 'Apps': 'dine360_dashboard,static/src/img/icons/apps.svg', 'Settings': 'dine360_dashboard,static/src/img/icons/settings.svg', 'Kitchen (KDS)': 'dine360_dashboard,static/src/img/icons/kitchen_kds.svg', 'Table Reservation': 'dine360_dashboard,static/src/img/icons/table_reservation.svg', 'Uber Integration': 'dine360_dashboard,static/src/img/icons/uber_integration.svg', } # Find the best match in the mapping current_name = menu.name for key, icon_path in icon_mapping.items(): if key.lower() in current_name.lower(): # We use a virtual field assignment so it doesn't try to save to DB # but the template picks it up menu.web_icon = icon_path break filtered_menus.append(menu) # Low Stock Alerts (Ingredients) low_stock_products = [] try: ProductTemplate = request.env['product.template'].sudo() if hasattr(ProductTemplate, 'get_low_stock_products'): low_stock_products = ProductTemplate.get_low_stock_products(limit=5) except Exception: low_stock_products = [] return request.render('dine360_dashboard.image_home_template', { 'menus': filtered_menus, 'user_id': request.env.user, 'low_stock_products': low_stock_products }) @http.route('/home', type='http', auth="public", website=True, sitemap=True) def website_home(self, **kw): # Explicit route for standard Website Homepage return request.render('website.homepage')