287 lines
13 KiB
Python
287 lines
13 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from odoo import http, fields
|
|
from odoo.http import request
|
|
import json
|
|
import logging
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class ExpertController(http.Controller):
|
|
|
|
@http.route('/expert_theme/test', type='http', auth='user')
|
|
def test_controller(self):
|
|
"""Simple test endpoint to verify controller is working"""
|
|
return request.make_json_response({
|
|
'success': True,
|
|
'message': 'Controller is working!',
|
|
'timestamp': fields.Datetime.now()
|
|
})
|
|
|
|
@http.route('/expert_theme/get_css_variables', type='http', auth='user')
|
|
def get_css_variables(self):
|
|
"""Get CSS variables for the active theme configuration"""
|
|
try:
|
|
config = request.env['expert.theme.config'].get_active_config()
|
|
css_variables = config.get_css_variables()
|
|
return request.make_json_response({
|
|
'success': True,
|
|
'css_variables': css_variables
|
|
})
|
|
except Exception as e:
|
|
return request.make_json_response({
|
|
'success': False,
|
|
'error': str(e)
|
|
})
|
|
|
|
@http.route('/expert_theme/apply_theme', type='http', auth='user', methods=['POST'])
|
|
def apply_theme(self):
|
|
"""Apply theme changes immediately"""
|
|
try:
|
|
# Get the active configuration
|
|
config = request.env['expert.theme.config'].get_active_config()
|
|
|
|
# Apply the theme (this could trigger cache invalidation, etc.)
|
|
config.apply_theme()
|
|
|
|
return request.make_json_response({
|
|
'success': True,
|
|
'message': 'Theme applied successfully!'
|
|
})
|
|
except Exception as e:
|
|
return request.make_json_response({
|
|
'success': False,
|
|
'error': str(e)
|
|
})
|
|
|
|
@http.route('/web/login', type='http', auth='none', methods=['GET', 'POST'], csrf=False)
|
|
def web_login(self, redirect=None, **kw):
|
|
"""Override Odoo login to use expert login templates when configured.
|
|
|
|
- POST: delegate to standard Odoo login logic (authentication, redirects, etc.).
|
|
- GET: render the active expert login template if not 'default', otherwise use standard login.
|
|
"""
|
|
# Import Home from its new location in Odoo 18
|
|
from odoo.addons.web.controllers.home import Home
|
|
|
|
# Handle login submission via standard controller
|
|
if request.httprequest.method == 'POST':
|
|
home = Home()
|
|
return home.web_login(redirect=redirect, **kw)
|
|
|
|
# GET: decide which template to render
|
|
try:
|
|
login_template = request.env['expert.login.template'].sudo().get_active_template()
|
|
template_name = login_template.get_template_name()
|
|
except Exception as e:
|
|
_logger.error("Error getting active login template: %s", e)
|
|
template_name = 'web.login'
|
|
|
|
# For default template, just call the standard login
|
|
if template_name == 'web.login':
|
|
home = Home()
|
|
return home.web_login(redirect=redirect, **kw)
|
|
|
|
# Try to render the selected expert template; fall back to default on error
|
|
try:
|
|
return request.render(template_name, {
|
|
'redirect': redirect or '',
|
|
'login': kw.get('login', ''),
|
|
'login_template': login_template,
|
|
})
|
|
except Exception as e:
|
|
_logger.error("Error rendering login template '%s': %s", template_name, e)
|
|
home = Home()
|
|
return home.web_login(redirect=redirect, **kw)
|
|
|
|
@http.route('/expert_theme/get_login_template_styles', type='http', auth='public', methods=['GET'])
|
|
def get_login_template_styles(self):
|
|
"""Get CSS styles for the active login template (public access for login page)"""
|
|
try:
|
|
template = request.env['expert.login.template'].sudo().get_active_template()
|
|
styles = template.get_template_styles()
|
|
return request.make_json_response({
|
|
'success': True,
|
|
'styles': styles
|
|
})
|
|
except Exception as e:
|
|
# Return default styles if error
|
|
return request.make_json_response({
|
|
'success': False,
|
|
'error': str(e),
|
|
'styles': {'background_color': '#FFFFFF'}
|
|
})
|
|
|
|
@http.route('/expert_theme/get_installed_modules_http', type='http', auth='user')
|
|
def get_installed_modules_http(self):
|
|
"""Return list of installed modules for the home page via HTTP"""
|
|
try:
|
|
# Get all installed modules
|
|
installed_modules = request.env['ir.module.module'].search([
|
|
('state', '=', 'installed'),
|
|
('name', '!=', 'expert_theme') # Exclude our own module
|
|
])
|
|
|
|
# Get all top-level menu items that belong to installed modules
|
|
menu_items = request.env['ir.ui.menu'].search([
|
|
('parent_id', '=', False), # Top level menus only
|
|
('active', '=', True),
|
|
('name', 'not in', ['Expert Home', 'Dashboard']) # Exclude our own menus
|
|
])
|
|
|
|
result = []
|
|
installed_module_names = installed_modules.mapped('name')
|
|
|
|
debug_info = {
|
|
'total_installed_modules': len(installed_modules),
|
|
'total_menu_items': len(menu_items)
|
|
}
|
|
|
|
for menu in menu_items:
|
|
# Check if this menu belongs to an installed module
|
|
module_name = None
|
|
if menu.web_icon and ',' in menu.web_icon:
|
|
module_name = menu.web_icon.split(',')[0]
|
|
|
|
# Include menu if it belongs to an installed module OR if it has no web_icon (base modules)
|
|
if (module_name and module_name in installed_module_names) or not menu.web_icon:
|
|
|
|
# Create URL based on action type - use proper Odoo navigation
|
|
if menu.action and menu.action.type == 'ir.actions.act_window':
|
|
# For act_window, use the action ID
|
|
url = f'/web#action={menu.action.id}'
|
|
elif menu.action and menu.action.type == 'ir.actions.client':
|
|
# For client actions, use the action ID
|
|
url = f'/web#action={menu.action.id}'
|
|
elif menu.action and menu.action.type == 'ir.actions.server':
|
|
# For server actions, use the action ID
|
|
url = f'/web#action={menu.action.id}'
|
|
else:
|
|
# For menus without actions, use menu_id
|
|
url = f'/web#menu_id={menu.id}'
|
|
|
|
result.append({
|
|
'id': menu.id,
|
|
'name': menu.name,
|
|
'web_icon': menu.web_icon or 'base,static/description/icon.png',
|
|
'action': menu.action.id if menu.action else False,
|
|
'url': url,
|
|
'module_name': module_name
|
|
})
|
|
|
|
return request.make_json_response({
|
|
'success': True,
|
|
'modules': result,
|
|
'debug_info': debug_info
|
|
})
|
|
except Exception as e:
|
|
return request.make_json_response({
|
|
'success': False,
|
|
'error': str(e)
|
|
})
|
|
|
|
@http.route('/web/signup', type='http', auth='public', methods=['GET', 'POST'], website=True, csrf=False)
|
|
def web_auth_signup(self, redirect=None, **kw):
|
|
"""Override Odoo signup to use expert signup templates when modern template is active.
|
|
|
|
- POST: delegate to standard Odoo signup logic (authentication, redirects, etc.).
|
|
- GET: render the active expert signup template if modern template is active, otherwise use standard signup.
|
|
"""
|
|
# Import AuthSignupHome from auth_signup module
|
|
try:
|
|
from odoo.addons.auth_signup.controllers.main import AuthSignupHome
|
|
except ImportError:
|
|
# If auth_signup is not installed, return 404
|
|
from werkzeug.exceptions import NotFound
|
|
raise NotFound()
|
|
|
|
# Handle signup submission via standard controller
|
|
if request.httprequest.method == 'POST':
|
|
auth_signup_home = AuthSignupHome()
|
|
return auth_signup_home.web_auth_signup(redirect=redirect, **kw)
|
|
|
|
# GET: decide which template to render
|
|
try:
|
|
login_template = request.env['expert.login.template'].sudo().get_active_template()
|
|
template_name = login_template.get_signup_template_name()
|
|
except Exception as e:
|
|
_logger.error("Error getting active signup template: %s", e)
|
|
template_name = 'auth_signup.signup'
|
|
|
|
# For default template, just call the standard signup
|
|
if template_name == 'auth_signup.signup':
|
|
auth_signup_home = AuthSignupHome()
|
|
return auth_signup_home.web_auth_signup(redirect=redirect, **kw)
|
|
|
|
# Try to render the selected expert template; fall back to default on error
|
|
try:
|
|
# Get signup context from auth_signup
|
|
auth_signup_home = AuthSignupHome()
|
|
qcontext = auth_signup_home.get_auth_signup_qcontext()
|
|
qcontext.update({
|
|
'redirect': redirect or '',
|
|
'login': kw.get('login', ''),
|
|
'login_template': login_template,
|
|
})
|
|
response = request.render(template_name, qcontext)
|
|
response.headers['X-Frame-Options'] = 'SAMEORIGIN'
|
|
response.headers['Content-Security-Policy'] = "frame-ancestors 'self'"
|
|
return response
|
|
except Exception as e:
|
|
_logger.error("Error rendering signup template '%s': %s", template_name, e)
|
|
auth_signup_home = AuthSignupHome()
|
|
return auth_signup_home.web_auth_signup(redirect=redirect, **kw)
|
|
|
|
@http.route('/web/reset_password', type='http', auth='public', methods=['GET', 'POST'], website=True, csrf=False)
|
|
def web_auth_reset_password(self, redirect=None, **kw):
|
|
"""Override Odoo reset password to use expert reset password templates when modern template is active.
|
|
|
|
- POST: delegate to standard Odoo reset password logic (authentication, redirects, etc.).
|
|
- GET: render the active expert reset password template if modern template is active, otherwise use standard reset password.
|
|
"""
|
|
# Import AuthSignupHome from auth_signup module
|
|
try:
|
|
from odoo.addons.auth_signup.controllers.main import AuthSignupHome
|
|
except ImportError:
|
|
# If auth_signup is not installed, return 404
|
|
from werkzeug.exceptions import NotFound
|
|
raise NotFound()
|
|
|
|
# Handle reset password submission via standard controller
|
|
if request.httprequest.method == 'POST':
|
|
auth_signup_home = AuthSignupHome()
|
|
return auth_signup_home.web_auth_reset_password(redirect=redirect, **kw)
|
|
|
|
# GET: decide which template to render
|
|
try:
|
|
login_template = request.env['expert.login.template'].sudo().get_active_template()
|
|
template_name = login_template.get_reset_password_template_name()
|
|
except Exception as e:
|
|
_logger.error("Error getting active reset password template: %s", e)
|
|
template_name = 'auth_signup.reset_password'
|
|
|
|
# For default template, just call the standard reset password
|
|
if template_name == 'auth_signup.reset_password':
|
|
auth_signup_home = AuthSignupHome()
|
|
return auth_signup_home.web_auth_reset_password(redirect=redirect, **kw)
|
|
|
|
# Try to render the selected expert template; fall back to default on error
|
|
try:
|
|
# Get reset password context from auth_signup
|
|
auth_signup_home = AuthSignupHome()
|
|
qcontext = auth_signup_home.get_auth_signup_qcontext()
|
|
qcontext.update({
|
|
'redirect': redirect or '',
|
|
'login': kw.get('login', ''),
|
|
'login_template': login_template,
|
|
})
|
|
response = request.render(template_name, qcontext)
|
|
response.headers['X-Frame-Options'] = 'SAMEORIGIN'
|
|
response.headers['Content-Security-Policy'] = "frame-ancestors 'self'"
|
|
return response
|
|
except Exception as e:
|
|
_logger.error("Error rendering reset password template '%s': %s", template_name, e)
|
|
auth_signup_home = AuthSignupHome()
|
|
return auth_signup_home.web_auth_reset_password(redirect=redirect, **kw)
|