# -*- coding: utf-8 -*- """Roles del frontend React y matriz de permisos de menú por rol. Módulo sin dependencias de Odoo para poder importarse tanto desde modelos como desde controladores sin problemas de orden de carga. La matriz se persiste en ir.config_parameter 'skeen.menu_roles' como JSON {href: [roles...]}. Si no existe, se usan los defaults de DEFAULT_MENU_ROLES (mismos que MENU_ROLES hardcodeado del frontend) y los 5 roles nuevos heredan el mismo set de secciones que 'lectura'. """ import json ROLE_SELECTION = [ ('admin', 'Administrador'), ('medico', 'Médico'), ('recepcion', 'Recepción'), ('enfermeria', 'Enfermería'), ('cosmetologia', 'Cosmetología'), ('psicologa', 'Psicóloga'), ('farmacia', 'Farmacia'), ('gerencia', 'Gerencia'), ('marketing', 'Marketing'), ('lectura', 'Lectura'), ] ROLE_KEYS = tuple(k for k, _ in ROLE_SELECTION) ROLE_RANKS = { 'admin': 100, 'medico': 50, 'recepcion': 50, 'enfermeria': 50, 'cosmetologia': 50, 'psicologa': 50, 'farmacia': 50, 'gerencia': 50, # marketing pasó a 50: puede agendar citas y escribir en el WACRM, igual # que recepción (los permisos de ESCRITURA dependen del rango). 'marketing': 50, 'lectura': 10, } MENU_ROLES_KEY = 'skeen.menu_roles' # Defaults = MENU_ROLES de src/lib/auth.tsx (4 roles originales). # 'gerencia' (gerencia de la clínica) ve toda la # operación EXCEPTO /configuracion (solo admin del sistema), /mis-ventas, # /cumpleanos y /wacrm/*. DEFAULT_MENU_ROLES = { '/' : ['admin', 'medico', 'recepcion', 'enfermeria', 'cosmetologia', 'psicologa', 'farmacia', 'gerencia', 'marketing', 'lectura'], '/agenda': ['admin', 'recepcion', 'medico', 'gerencia', 'cosmetologia', 'marketing'], '/mis-ventas': ['medico'], '/pacientes': ['admin', 'recepcion', 'medico', 'lectura', 'gerencia', 'marketing'], '/pos': ['admin', 'recepcion', 'gerencia'], '/visitas': ['admin', 'recepcion', 'medico', 'gerencia', 'marketing'], '/consultas': ['admin', 'recepcion', 'medico', 'gerencia'], '/medicos': ['admin', 'recepcion', 'gerencia'], '/servicios': ['admin', 'recepcion', 'medico', 'lectura', 'gerencia'], '/productos': ['admin', 'recepcion', 'lectura', 'gerencia'], '/ventas': ['admin', 'recepcion', 'gerencia'], '/tickets': ['admin', 'gerencia'], '/pagos': ['admin', 'recepcion', 'gerencia'], '/monedero': ['admin', 'recepcion', 'lectura', 'gerencia'], '/inventario': ['admin', 'recepcion', 'lectura', 'gerencia'], '/cortes': ['admin', 'recepcion', 'gerencia'], '/reportes': ['admin', 'recepcion', 'lectura', 'gerencia'], '/reportes?tab=adeudos': ['admin', 'recepcion', 'lectura', 'gerencia'], '/reportes?tab=comisiones': ['admin', 'recepcion', 'lectura', 'gerencia'], '/reportes?tab=horas-agenda': ['admin', 'recepcion', 'lectura', 'gerencia'], '/reportes?tab=paquetes': ['admin', 'recepcion', 'lectura', 'gerencia'], '/reportes?tab=vendedores': ['admin', 'recepcion', 'lectura', 'gerencia'], '/reportes?tab=concentrado': ['admin', 'recepcion', 'lectura', 'gerencia'], '/reportes?tab=recomendaciones': ['admin', 'recepcion', 'lectura', 'gerencia'], '/reportes?tab=exportar': ['admin', 'recepcion', 'lectura', 'gerencia'], '/configuracion': ['admin', 'gerencia'], '/cumpleanos': ['admin', 'recepcion', 'gerencia', 'marketing'], '/wacrm/messages': ['admin', 'recepcion', 'gerencia', 'marketing'], '/wacrm/leads': ['admin', 'recepcion', 'gerencia', 'marketing'], # El chat interno se lista explícitamente para dejar fuera a marketing # (antes, al no estar listado, lo veía todo el mundo). '/chat': ['admin', 'medico', 'recepcion', 'enfermeria', 'cosmetologia', 'psicologa', 'farmacia', 'gerencia', 'lectura'], } # Marketing NO hereda los menús de 'lectura': sólo estos (mínimo privilegio). MARKETING_MENUS = ( '/', '/agenda', '/pacientes', '/cumpleanos', '/visitas', '/wacrm/messages', '/wacrm/leads', ) # Roles nuevos que por default ven lo mismo que 'lectura'. READ_ONLY_NEW_ROLES = ('enfermeria', 'cosmetologia', 'psicologa', 'farmacia', 'marketing') def default_menu_roles(): """Matriz por default: MENU_ROLES + roles nuevos donde esté 'lectura'. Marketing es la excepción: no hereda lo de 'lectura', sólo entra en sus menús explícitos (agenda, pacientes, cumpleaños, visitas y WACRM). """ matrix = {} for href, roles in DEFAULT_MENU_ROLES.items(): r = list(roles) if 'lectura' in roles: r.extend(nr for nr in READ_ONLY_NEW_ROLES if nr not in r) matrix[href] = r for href in matrix: matrix[href] = [r for r in matrix[href] if r != 'marketing'] for href in MARKETING_MENUS: matrix.setdefault(href, []) if 'marketing' not in matrix[href]: matrix[href].append('marketing') return matrix def get_menu_roles(env): """Matriz vigente: la guardada en ir.config_parameter o los defaults.""" raw = env['ir.config_parameter'].sudo().get_param(MENU_ROLES_KEY) if raw: try: val = json.loads(raw) if isinstance(val, dict): return val except Exception: pass return default_menu_roles()