odoo 467cf7812a Merge commit 'a679c57b1652019c31c0c696d07db30e7b69b0c6' as 'theme_m22tc' пре 2 месеци
..
controllers 467cf7812a Merge commit 'a679c57b1652019c31c0c696d07db30e7b69b0c6' as 'theme_m22tc' пре 2 месеци
data 467cf7812a Merge commit 'a679c57b1652019c31c0c696d07db30e7b69b0c6' as 'theme_m22tc' пре 2 месеци
models 467cf7812a Merge commit 'a679c57b1652019c31c0c696d07db30e7b69b0c6' as 'theme_m22tc' пре 2 месеци
static 467cf7812a Merge commit 'a679c57b1652019c31c0c696d07db30e7b69b0c6' as 'theme_m22tc' пре 2 месеци
views 467cf7812a Merge commit 'a679c57b1652019c31c0c696d07db30e7b69b0c6' as 'theme_m22tc' пре 2 месеци
.gitignore 467cf7812a Merge commit 'a679c57b1652019c31c0c696d07db30e7b69b0c6' as 'theme_m22tc' пре 2 месеци
README.md 467cf7812a Merge commit 'a679c57b1652019c31c0c696d07db30e7b69b0c6' as 'theme_m22tc' пре 2 месеци
__init__.py 467cf7812a Merge commit 'a679c57b1652019c31c0c696d07db30e7b69b0c6' as 'theme_m22tc' пре 2 месеци
__manifest__.py 467cf7812a Merge commit 'a679c57b1652019c31c0c696d07db30e7b69b0c6' as 'theme_m22tc' пре 2 месеци

README.md

Theme M22 Tech Consulting

Tema personalizado para Odoo 18 con estilo "Futurismo Cálido" - una combinación de diseño dark mode moderno con acentos vibrantes en naranja y magenta.

📋 Información General

Campo Valor
Nombre técnico theme_m22tc
Versión 1.0.3
Categoría Theme/Corporate
Licencia LGPL-3
Compatibilidad Odoo 18.0
Dependencias website, auth_signup

🎨 Design System

Concepto: Split Theme + Glassmorphism

El tema implementa un "Split Theme" (Tema Dividido) con Glassmorphism aplicado consistentemente:

  • Login/Auth: 100% Dark + Glassmorphism intenso
  • Sidebar: Dark + Glassmorphism sutil
  • Contenido Principal: Light + Glassmorphism elegante

Paleta de Colores

Variable Color Hex Uso
o-color-1 🟠 Naranja M22 #FF7C00 Acento primario, CTAs, links
o-color-2 🩷 Magenta #E0407B Acento secundario, gradientes
o-color-3 🌑 Midnight Blue #0F111A Fondo sidebar (dark mode)
o-color-4 ⚪ Soft Gray #F8F8F8 Fondo contenido principal (light mode)
o-color-5 ⬜ Blanco #FFFFFF Textos sobre fondo oscuro, reportes

Glassmorphism

Efecto glassmorphism aplicado en diferentes intensidades:

// Dark Glassmorphism (Sidebar)
background: rgba(#0F111A, 0.95);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.08);

// Light Glassmorphism (Contenido)
background: rgba(#FFFFFF, 0.75);
backdrop-filter: blur(12px);
border: 1px solid rgba(0, 0, 0, 0.08);

Tipografía

  • Fuente principal: Inter (sans-serif)
  • Fuente alternativa: Montserrat (sans-serif)
  • Pesos disponibles: 300, 400, 500, 600, 700, 800

Gradientes Principales

/* Gradiente primario (botones, logos) */
background: linear-gradient(90deg, #FF6B00, #E1467C);

/* Gradiente para fondos */
background-image:
    radial-gradient(ellipse 80% 50% at 10% 10%, rgba(255, 107, 0, 0.15), transparent),
    radial-gradient(ellipse 80% 50% at 90% 90%, rgba(225, 70, 124, 0.15), transparent);

📁 Estructura del Proyecto

theme_m22tc/
├── __init__.py
├── __manifest__.py
├── README.md
│
├── data/
│   ├── generate_primary_template.xml  # Template generator para snippets
│   ├── ir_asset.xml                   # Registro de assets (SCSS, JS)
│   └── menu_data.xml                  # Datos de menú
│
├── controllers/
│   ├── __init__.py
│   └── helpdesk_portal.py            # Extensiones del portal de helpdesk (dashboard, aprobación)
│
├── models/
│   ├── __init__.py
│   ├── theme_m22tc.py                 # Modelo principal del tema
│   └── website_menu.py                # Extensiones al menú del website
│
├── static/
│   └── src/
│       ├── js/
│       │   ├── m22_sidebar.js         # Widget sidebar interactivo
│       │   └── m22_bottom_sheet.js    # Widget bottom sheet móvil (iOS style)
│       │
│       └── scss/
│           ├── primary_variables.scss  # Variables de diseño (colores, fuentes)
│           ├── bootstrap_overridden.scss # Overrides de Bootstrap
│           └── m22tc_styles.scss       # Estilos personalizados
│
└── views/
    ├── customizations.xml             # Personalizaciones generales (Tailwind, login enforcement)
    ├── frontend_layout.xml            # Layout para usuarios autenticados + sidebar M22
    ├── login_custom.xml               # Login, Signup, Reset Password
    ├── portal_sidebar.xml             # Cleanup de vistas legacy (sin overrides)
    ├── snippets.xml                   # Snippets personalizados (Bento Grid)
    ├── website_menu_view.xml          # Vistas de menú
    ├── helpdesk_dashboard.xml         # Template del dashboard de tickets
    └── helpdesk_portal_approval.xml    # Template de botones de aprobación/rechazo

🛠 Tecnologías Utilizadas

Backend (Odoo)

  • QWeb Templates: Motor de plantillas de Odoo para renderizado HTML
  • ir.asset: Sistema de assets de Odoo 18 para registro de SCSS/JS
  • Template Inheritance: Herencia de vistas con inherit_id y xpath

Frontend

  • SCSS/Sass: Preprocesador CSS para estilos modulares
  • Tailwind CSS (CDN): Framework utility-first para páginas de autenticación y bottom sheet móvil
  • Bootstrap 5: Framework CSS base de Odoo
  • publicWidget: Framework JS de Odoo para widgets frontend interactivos

Fuentes Externas

  • Google Fonts: Inter, Montserrat

📦 Assets y Bundles

Los assets se registran en data/ir_asset.xml usando theme.ir.asset (no ir.asset) para que solo se apliquen cuando el tema está activo:

Asset Bundle Descripción
primary_variables.scss web._assets_primary_variables Variables de diseño (colores claros para reportes)
bootstrap_overridden.scss web._assets_frontend_helpers Overrides Bootstrap (colores base claros)
m22tc_styles.scss web.assets_frontend Estilos personalizados (Split Theme + Glassmorphism)
m22_sidebar.js web.assets_frontend Widget del sidebar interactivo
m22_bottom_sheet.js web.assets_frontend Widget del bottom sheet móvil (iOS style)

Estilos Generalizados

El tema incluye estilos generalizados para elementos nativos de Odoo:

Badges de Bootstrap

Soporte completo para todos los badges de Bootstrap con buen contraste:

  • .badge-primary, .text-bg-primary - Naranja M22
  • .badge-secondary, .text-bg-secondary - Gris
  • .badge-success, .text-bg-success - Verde
  • .badge-warning, .text-bg-warning - Amarillo
  • .badge-danger, .text-bg-danger - Rojo
  • .badge-info, .text-bg-info - Cyan
  • .badge-light, .text-bg-light, .bg-200 - Gris claro con texto oscuro (crítico para helpdesk)

Navegación en Sidebar Nativo

Estilos para elementos de navegación en sidebars nativos de Odoo:

  • .nav.flex-column .nav-link - Links de navegación vertical
  • [role="complementary"] .nav-link - Sidebars complementarios
  • .navspy, .bs-sidenav - Navegación scroll-spy
  • #ticket-nav, #ticket-links - Sidebar específico de helpdesk

Botones en Sidebar Nativo

  • .btn-light - Texto oscuro visible sobre fondo claro
  • .btn-primary - Gradiente M22 con texto blanco
  • .btn-outline-primary - Borde naranja, fondo transparente

🔐 Sistema de Autenticación Personalizado

El tema incluye páginas de autenticación completamente personalizadas con estilo glassmorphism:

Templates (views/login_custom.xml)

Template Hereda de Descripción
m22_tailwind_config web.layout Configuración Tailwind + estilos globales
m22_login_layout_override website.login_layout Layout contenedor
m22_login_form_override web.login Formulario de login
m22_signup_form_override auth_signup.signup Formulario de registro
m22_reset_password_override auth_signup.reset_password Formulario reset password

Características

  • ✅ Logo dinámico del sitio web (request.website.image_url)
  • ✅ Link de registro condicional (signup_enabled)
  • ✅ Link de reset password condicional (reset_password_enabled)
  • ✅ Efecto glassmorphism con backdrop blur
  • ✅ Botones con gradiente naranja-magenta
  • ✅ Inputs con estilo dark mode

URLs

  • /web/login - Iniciar sesión
  • /web/signup - Crear cuenta
  • /web/reset_password - Restablecer contraseña

🎯 Sidebar de Navegación

El tema incluye un sidebar personalizado para usuarios autenticados con inicialización temprana para prevenir flash visual:

Características

  • Ancho fijo de 260px en desktop (72px colapsado)
  • Colapsable con persistencia en localStorage
  • Inicialización temprana: Script inline en <head> previene flash visual al cargar
  • Responsive: drawer en mobile
  • Animaciones suaves con cubic-bezier
  • Prevención de layout shift: Iconos fijos, textos con position: absolute

Sistema de Inicialización

El sidebar usa un sistema de inicialización temprana para evitar efectos visuales desagradables:

  1. Script inline en <head> (views/frontend_layout.xml):

    • Lee localStorage antes del render
    • Aplica clase m22-sidebar-collapsed-init al <html> si está colapsado
  2. CSS de inicialización (m22tc_styles.scss):

    • html.m22-sidebar-collapsed-init: Aplica estado colapsado sin transiciones
    • Iconos fijos con position: relative y flex-shrink: 0
    • Textos ocultos con position: absolute y left: -9999px (sin layout shift)
    • Icono de flecha reemplazado via ::after para evitar rotación visible
  3. JavaScript sincronizado (m22_sidebar.js):

    • Reconoce estado previo aplicado por CSS
    • Sincroniza estado interno sin cambios visuales
    • Habilita transiciones después de inicializar

Clases CSS Principales

.m22-sidebar                    /* Contenedor del sidebar */
.m22-sidebar-collapsed          /* Estado colapsado */
.m22-sidebar-mobile             /* Versión mobile */
.o_has_m22_sidebar              /* Clase en body cuando hay sidebar */
.o_main_with_sidebar            /* Main content con offset */
html.m22-sidebar-collapsed-init /* Estado inicial colapsado (sin transiciones) */
html.m22-sidebar-initialized    /* Sidebar inicializado (transiciones habilitadas) */

📱 Navegación Móvil

El tema incluye una navegación inferior móvil (bottom navigation) con un bottom sheet estilo iOS para mostrar opciones adicionales:

Características de la Bottom Navigation

  • Barra fija inferior: Navegación siempre visible en la parte inferior en dispositivos móviles
  • Items principales: Muestra los primeros 3 items del menú del sidebar (Inicio, Cotizaciones, Pedidos)
  • Item "Cuenta": Siempre visible, enlace directo a /my/account
  • Botón "Más": Siempre al final, abre el bottom sheet con opciones adicionales
  • Diseño responsive: Solo visible en pantallas pequeñas (d-lg-none)

Bottom Sheet Estilo iOS

Modal que se desliza desde la parte inferior mostrando opciones adicionales del menú:

Características

  • Animaciones suaves: Transiciones con cubic-bezier estilo iOS
  • Backdrop blur: Fondo oscuro difuminado (glassmorphism)
  • Handle indicator: Barrita superior que indica que se puede arrastrar
  • Drag to dismiss: Arrastrar hacia abajo desde el handle o header para cerrar
  • Múltiples formas de cierre:
    • Botón "Cerrar" en la parte inferior
    • Tap en el backdrop (fondo oscuro)
    • Tecla Escape
    • Drag hacia abajo
  • Scroll interno: El contenido es scrolleable si hay muchos items
  • Integración con tema: Estilos glassmorphism consistentes con el diseño

Contenido del Bottom Sheet

Muestra los items adicionales del menú (desde el 4to en adelante):

  • Facturas
  • Proyectos
  • Tareas
  • Tickets

Implementación Técnica

Archivos relacionados:

  • views/frontend_layout.xml: Estructura HTML del bottom nav y bottom sheet
  • static/src/js/m22_bottom_sheet.js: Lógica JavaScript con widgets de Odoo
  • static/src/scss/m22tc_styles.scss: Estilos de integración con el tema

Widgets JavaScript:

  • M22BottomSheet: Widget principal que gestiona el bottom sheet
  • M22BottomSheetTrigger: Widget del botón "Más" que abre el sheet

Orden de elementos en bottom nav:

  1. Items principales (primeros 3 del menú)
  2. Cuenta (siempre visible)
  3. Más (siempre al final)

Clases CSS Principales

.m22-bottom-nav              /* Barra de navegación inferior móvil */
.bottom-nav-item             /* Item individual de la barra */
#m22_bottom_sheet            /* Contenedor del bottom sheet */
.m22-bottom-sheet-container  /* Contenedor principal con backdrop */
.m22-bottom-sheet-backdrop   /* Fondo oscuro difuminado */
.m22-bottom-sheet-content    /* Contenido del sheet (scrolleable) */
.m22-sheet-item              /* Item individual dentro del sheet */

🔧 Compatibilidad y Ajustes Técnicos

Filtros del Portal con Tailwind CSS

Problema: Los filtros del portal de Odoo (portal_searchbar) usan clases de Bootstrap (.collapse, .navbar-collapse) que dependen del JavaScript de Bootstrap para expandirse/colapsarse. Cuando Tailwind reemplaza Bootstrap, estos elementos permanecen colapsados por defecto.

Solución: El tema incluye CSS con alta especificidad en m22tc_styles.scss que fuerza la visualización de los filtros en desktop:

.o_portal_wrap nav.o_portal_navbar {
    @media (min-width: 992px) {
        .collapse, .navbar-collapse, #o_portal_navbar_content {
            display: flex !important;
            visibility: visible !important;
            height: auto !important;
        }
    }
}

Resultado: Los controles "Ordenar por", "Filtrar por", "Agrupar por" y la búsqueda son siempre visibles en pantallas de escritorio (≥992px), manteniendo la funcionalidad completa del portal de Odoo.

Arquitectura No-Invasiva

El tema sigue una filosofía de no-interferencia con los templates nativos de Odoo:

  • NO reemplaza el contenedor principal del portal
  • NO modifica la estructura de vistas de Odoo
  • Inyecta la sidebar M22 como componente adicional
  • Ajusta el layout exclusivamente con CSS
  • Preserva toda la funcionalidad nativa (filtros, paginación, breadcrumbs)

El archivo portal_sidebar.xml solo contiene una función de cleanup de vistas legacy. Todos los ajustes visuales se manejan en m22tc_styles.scss.

🧩 Snippets Disponibles

Bento Grid (s_m22_bento_grid)

Grid asimétrico estilo "Bento Box" para mostrar servicios/features:

  • Layout responsive con CSS Grid
  • Tarjetas con efecto hover
  • Iconos con gradiente
  • Compatible con el editor de Odoo

⚙️ Configuración del Website Editor

El tema configura automáticamente:

  • Botones: Border radius 0.5rem, efecto ripple
  • Header: Template "boxed"
  • Footer: Template "centered"

🚀 Instalación y Actualización

Instalar el tema

# Desde el directorio workspace/
source ../venv/bin/activate
python src/odoo/odoo-bin -c ../odoo.conf -d m22_techconsulting_dev -i theme_m22tc --stop-after-init

Actualizar el tema

# Desde el directorio workspace/
source ../venv/bin/activate
python src/odoo/odoo-bin -c ../odoo.conf -d m22_techconsulting_dev -u theme_m22tc --stop-after-init
./odoo_dev.sh restart

Reiniciar Odoo

./odoo_dev.sh restart

🔧 Desarrollo

Modificar estilos

  1. Editar archivos en static/src/scss/
  2. Actualizar el tema: python src/odoo/odoo-bin -c ../odoo.conf -u theme_m22tc --stop-after-init
  3. Reiniciar: ./odoo_dev.sh restart

Modificar templates

  1. Editar archivos en views/
  2. Actualizar el tema
  3. Limpiar caché si es necesario:

    # En Odoo shell
    env.registry.clear_cache()
    env['ir.qweb'].clear_caches()
    

Agregar nuevos assets

  1. Crear archivo en static/src/scss/ o static/src/js/
  2. Registrar en data/ir_asset.xml
  3. Actualizar el tema

📝 Notas Importantes

  1. Tailwind CSS: La plataforma usa Tailwind CSS para reemplazar Bootstrap en toda la aplicación. El tema se carga vía CDN en customizations.xml y es compatible con los componentes nativos de Odoo mediante CSS con alta especificidad que asegura la funcionalidad de elementos que originalmente dependían de Bootstrap (como filtros colapsables).

  2. Assets con theme.ir.asset: Todos los assets usan model="theme.ir.asset" en lugar de ir.asset para que solo se apliquen cuando el tema está activo. Odoo copia estos assets a ir.asset con website_id cuando se activa el tema.

  3. Colores base claros: Las variables $body-bg y $body-color en bootstrap_overridden.scss y primary_variables.scss usan valores claros (blanco/gris oscuro) para compatibilidad con reportes HTML (facturas, órdenes) que requieren fondo blanco.

  4. Especificidad CSS: Los estilos de inicialización usan #wrapwrap.o_has_m22_sidebar para igualar la especificidad de los estilos normales y evitar conflictos.

  5. Prioridades de templates: Los overrides usan priority="100" o superior para asegurar que se apliquen después de otros módulos.

  6. Variables condicionales: Las páginas de auth respetan las configuraciones de Odoo:

    • signup_enabled: Habilitado en Ajustes > Usuarios > Acceso de cliente
    • reset_password_enabled: Habilitado en Ajustes > Usuarios > Restablecer contraseña
  7. Logo del sitio: El logo se obtiene de la configuración del Website (request.website.image_url), no de la compañía.

  8. Prevención de layout shift: Los textos del sidebar usan position: absolute y left: -9999px para sacarlos del flujo sin causar movimiento de iconos durante la carga.

  9. Bottom Sheet móvil: El bottom sheet usa Tailwind CSS vía CDN y está integrado con el sistema de estilos del tema. El botón "Más" siempre aparece al final de la navegación inferior, después del item "Cuenta".

  10. Navegación móvil: La bottom navigation solo muestra los primeros 3 items principales del menú más "Cuenta" y "Más". Los items adicionales se muestran en el bottom sheet al tocar "Más".

  11. Compatibilidad Tailwind + Bootstrap: El tema está diseñado para funcionar en plataformas donde Tailwind reemplaza Bootstrap. Los filtros del portal de Odoo (que originalmente usan clases .collapse de Bootstrap) se fuerzan a mostrarse en desktop mediante CSS con alta especificidad en m22tc_styles.scss. Esto asegura que los controles "Ordenar por", "Filtrar por", "Agrupar por" y la búsqueda siempre sean visibles en pantallas ≥992px.

  12. Arquitectura no-invasiva: El tema NO reemplaza templates del portal de Odoo. La sidebar M22 es un componente adicional que se inyecta vía frontend_layout.xml. Los ajustes de layout se realizan exclusivamente con CSS, preservando toda la funcionalidad nativa de Odoo (filtros, breadcrumbs, paginación, etc.).

🎫 Funcionalidades de Helpdesk

El tema incluye extensiones personalizadas para el módulo de Helpdesk que mejoran la experiencia del cliente en el portal:

Dashboard de Tickets (/my/tickets-dashboard)

Dashboard personalizado que muestra información clave para el cliente:

Métricas Principales

  1. Tiempo Usado/Disponible

    • Calcula horas usadas vs horas disponibles del partner
    • Basado en líneas de pedido prepagadas (sale.order.line)
    • Compatible con sale_timesheet si está instalado
    • Muestra porcentaje de uso
  2. Resumen de Tickets

    • Total de tickets abiertos
    • Total de tickets cerrados
    • Tickets por prioridad (Urgente, Alta, Media, Baja)
    • Tickets por etapa
  3. Cumplimiento SLA

    • Porcentaje de tickets cumpliendo SLA
    • Tickets en riesgo (próximos a vencer)
    • Tickets con SLA fallido
  4. Tickets Esperando Respuesta

    • Tickets que requieren acción del cliente
    • Lógica de cálculo:
      • Prioridad 1: Tickets en etapas excluidas de SLA (exclude_stage_ids)
      • Prioridad 2: Tickets donde el último mensaje es del equipo de helpdesk
    • Solo incluye tickets asignados (excluye tickets nuevos sin asignar)
    • Ordenados por tiempo de espera (más antiguos primero)
  5. Tickets Recientes

    • Últimos 10 tickets creados
    • Enlace directo a cada ticket

Diseño Visual

  • Cards con efecto glassmorphism consistente con el tema
  • Barras de progreso para métricas porcentuales
  • Badges de colores para estados y prioridades
  • Diseño responsive y mobile-friendly
  • Integración con la paleta de colores del tema

Lista de Tickets (/my/tickets)

Agrupamiento por Defecto

  • Por defecto, los tickets se agrupan por Etapa (stage_id)
  • El usuario puede cambiar el agrupamiento usando los controles nativos de Odoo
  • No interfiere con la funcionalidad nativa del portal

Aprobación/Rechazo de Tickets

Sistema de aprobación para tickets en etapas de espera del cliente:

Funcionalidad

  • Botones de Aprobación: Aparecen en tickets que están en etapas excluidas de SLA
  • Aprobar Solución: Mueve el ticket a la siguiente etapa (mayor secuencia)
  • Rechazar / Necesito más ayuda: Mueve el ticket a la etapa anterior no-excluida (menor secuencia)
  • Mensajes automáticos: Cada acción publica un mensaje en el chatter del ticket

Lógica de Etapas Excluidas

  • Las etapas excluidas se definen en los SLAs del equipo (helpdesk.sla.exclude_stage_ids)
  • Cuando un ticket está en una etapa excluida, el SLA se pausa
  • El cliente puede aprobar o rechazar desde el portal
  • Al aprobar, el ticket avanza y el SLA se reanuda

Template

  • Banner de aprobación visible en la página de seguimiento del ticket (/my/ticket/<id>)
  • Estilos glassmorphism consistentes con el tema
  • Botones con gradientes y efectos hover
  • Alertas de confirmación después de cada acción

Mejoras Visuales en Portal

Buscador y Dropdowns

  • Fondo claro con texto oscuro (consistente con glassmorphism)
  • Acentos naranja en elementos seleccionados y focus
  • Posicionamiento corregido de elementos
  • Compatible con el diseño "Futurismo Cálido"

Estilos Específicos

  • .o_portal_navbar: Buscador y controles de filtrado
  • .dropdown-menu: Menús desplegables con estilos personalizados
  • .form-control: Inputs con estilo glassmorphism

Implementación Técnica

Archivos relacionados:

  • controllers/helpdesk_portal.py: Lógica del dashboard y aprobación
  • views/helpdesk_dashboard.xml: Template del dashboard
  • views/helpdesk_portal_approval.xml: Template de botones de aprobación
  • static/src/scss/m22tc_styles.scss: Estilos del dashboard y aprobación

Dependencias:

  • helpdesk: Módulo base de helpdesk de Odoo Enterprise
  • helpdesk_extras: Módulo custom con funcionalidades extendidas (colaboradores, SLAs)

Rutas:

  • /my/tickets-dashboard: Dashboard personalizado
  • /my/tickets: Lista de tickets (nativa, con agrupamiento por defecto)
  • /my/ticket/<id>/<access_token>: Página de seguimiento (con banner de aprobación)
  • /my/ticket/approve/<id>/<access_token>: Endpoint para aprobar ticket
  • /my/ticket/reject/<id>/<access_token>: Endpoint para rechazar ticket

Notas importantes:

  • El dashboard muestra métricas agregadas de todos los equipos donde el usuario es colaborador
  • Las reglas de seguridad (ir.rule) de helpdesk_extras filtran automáticamente los tickets según el rol del usuario en cada equipo
  • Los tickets en etapa "Nuevo" sin asignar NO aparecen en "Esperando Respuesta" (están esperando respuesta del equipo, no del cliente)

📄 Licencia

LGPL-3 - Ver archivo LICENSE para más detalles.


Desarrollado por: M22 Tech Consulting
Versión de Odoo: 18.0