6.2 KiB
6.2 KiB
Análisis del Módulo Mail de Odoo
Módulo: mail Prioridad: P0 Mapeo MGN: MGN-014 (Mensajería y Notificaciones)
Descripción
Módulo transversal que proporciona:
- Sistema de mensajería interna
- Tracking de cambios (auditoría)
- Notificaciones
- Followers (seguidores de registros)
- Actividades programadas
- Chatter UI
Modelos Principales
mail.thread (Mixin)
Casi todos los modelos heredan de mail.thread:
class SaleOrder(models.Model):
_name = 'sale.order'
_inherit = ['mail.thread', 'mail.activity.mixin']
state = fields.Selection(tracking=True) # Cambios tracked
amount_total = fields.Monetary(tracking=True)
mail.message (Mensajes)
- Mensajes en timeline (chatter)
- Tipos: notification, comment, email
- Adjuntos
- Followers notificados
mail.followers (Seguidores)
- Usuarios que siguen un registro
- Notificaciones automáticas
- Tipos de eventos suscritos
mail.activity (Actividades)
- Tareas pendientes vinculadas a registros
- Recordatorios
- Asignación a usuarios
Patrones Destacables
1. Tracking Automático de Cambios
# Con tracking=True
state = fields.Selection([...], tracking=True)
# Odoo automáticamente crea mensaje:
# "Estado cambió de 'Draft' a 'Confirmed' por John Doe"
2. Sistema de Notificaciones
# Notificar a followers
self.message_post(
body="Orden de venta confirmada",
subject="Orden #SO001",
message_type='notification'
)
# Todos los followers reciben notificación
3. Followers
# Agregar follower
self.message_subscribe(partner_ids=[partner.id])
# Los followers reciben:
# - Mensajes nuevos
# - Cambios en campos tracked
# - Notificaciones del registro
4. Actividades
# Crear actividad (recordatorio)
self.activity_schedule(
'mail.mail_activity_data_call',
date_deadline=fields.Date.today() + timedelta(days=7),
summary='Llamar al cliente',
user_id=salesperson.id
)
Mapeo a MGN-014
Requerimientos Funcionales
RF-NOT-001: Sistema de notificaciones
- Notificaciones en tiempo real (WebSocket)
- Notificaciones por email
- Centro de notificaciones en UI
RF-NOT-002: Mensajería interna
- Chat entre usuarios
- Mensajes vinculados a registros
- Adjuntos
RF-NOT-003: Tracking de cambios
- Auditoría automática de modificaciones
- Timeline de actividad
- Quién cambió qué y cuándo
RF-NOT-004: Actividades y tareas
- Recordatorios programados
- Asignación a usuarios
- Follow-up automático
Implementación Recomendada MGN-014
Schema: notifications
CREATE TABLE notifications.messages (
id SERIAL PRIMARY KEY,
tenant_id INT NOT NULL,
model VARCHAR(100) NOT NULL, -- 'sales.orders', 'purchase.orders'
record_id INT NOT NULL,
message_type VARCHAR(50), -- 'comment', 'notification', 'email'
subject VARCHAR(200),
body TEXT,
author_id INT REFERENCES auth.users(id),
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE notifications.followers (
id SERIAL PRIMARY KEY,
tenant_id INT NOT NULL,
model VARCHAR(100) NOT NULL,
record_id INT NOT NULL,
user_id INT REFERENCES auth.users(id),
subscribed_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE (model, record_id, user_id)
);
CREATE TABLE notifications.activities (
id SERIAL PRIMARY KEY,
tenant_id INT NOT NULL,
model VARCHAR(100) NOT NULL,
record_id INT NOT NULL,
activity_type VARCHAR(50), -- 'call', 'email', 'meeting', 'todo'
summary VARCHAR(200),
description TEXT,
assigned_to INT REFERENCES auth.users(id),
due_date DATE,
completed BOOLEAN DEFAULT FALSE,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE notifications.tracking (
id SERIAL PRIMARY KEY,
tenant_id INT NOT NULL,
model VARCHAR(100) NOT NULL,
record_id INT NOT NULL,
field_name VARCHAR(100),
old_value TEXT,
new_value TEXT,
changed_by INT REFERENCES auth.users(id),
changed_at TIMESTAMPTZ DEFAULT NOW()
);
Backend: Tracking Middleware
// Middleware para tracking automático
export function trackingMiddleware(Model: any) {
const originalUpdate = Model.update;
Model.update = async function(id: number, data: any, userId: number) {
// Leer valores actuales
const oldRecord = await Model.findById(id);
// Actualizar
const updatedRecord = await originalUpdate.call(this, id, data);
// Identificar cambios
const changes = detectChanges(oldRecord, updatedRecord, Model.trackedFields);
// Crear registros de tracking
for (const change of changes) {
await createTrackingRecord({
model: Model.tableName,
record_id: id,
field_name: change.field,
old_value: change.oldValue,
new_value: change.newValue,
changed_by: userId
});
// Notificar a followers
await notifyFollowers(Model.tableName, id, {
type: 'field_change',
field: change.field,
old: change.oldValue,
new: change.newValue
});
}
return updatedRecord;
};
}
Frontend: Notificaciones en Tiempo Real
// WebSocket para notificaciones
const socket = io(WS_URL);
socket.on('notification', (notification) => {
// Mostrar toast
toast.info(notification.message);
// Actualizar contador
notificationStore.incrementUnread();
// Reproducir sonido
playNotificationSound();
});
Patrón de Chatter UI
Odoo tiene un "Chatter" en cada formulario:
- Timeline de mensajes
- Actividades pendientes
- Formulario para escribir mensajes
- Lista de followers
MGN-014 debe implementar componente similar:
<RecordChatter
model="sales.orders"
recordId={order.id}
userId={currentUser.id}
/>
WebSocket vs Polling
Odoo usa: Polling (cada 30 segundos consulta nuevas notificaciones)
MGN-014 debe usar: WebSocket (Socket.IO o native WebSockets)
- Notificaciones en tiempo real
- Menor carga en servidor
- Mejor UX
Aplicabilidad
⭐⭐⭐⭐⭐ - ESENCIAL
El patrón de mail.thread es uno de los más valiosos de Odoo. Permite:
- Auditoría completa sin código adicional
- Colaboración en registros
- Sistema de notificaciones unificado
Recomendación: Implementar tracking automático desde el inicio
Fecha: 2025-11-23 Estado: ✅ Análisis completo