Mejoras integrales: visitas, POS, WACRM, reportes, temas y módulos legacy
- Módulo Visitas completo (auto desde agenda, insumos con descargo de inventario, fotos antes/después y documentos, receta imprimible) - Punto de Venta (catálogo + ticket sticky, cobro con cambio, pago con puntos monedero, ticket imprimible) - WACRM: leads automáticos desde WhatsApp, asignación de conversaciones y leads a agentes, conversión lead→paciente, ficha del paciente en chat - Pacientes: completitud de expediente, alertas clínicas, historial unificado con detalle, foto, WhatsApp, estado de cuenta, filtros rápidos (VIP/recientes/médico), documentos (expediente escaneado + galería) - Agenda: vistas por médico y por hora, filtros rápidos (libres, primera vez, check-in, no-show), modal de acciones, bloqueos por médico, drag&drop para mover citas - Reportes: 18 pestañas (diario, cortes, ingresos, inventario, adeudos, comisiones, pagos, devoluciones, top clientes, horas, paquetes, vendedores, concentrado, recomendaciones, KPIs) con exportación Excel - Temas: nuevo tema Clásico (look legacy AdminLTE) con submenús tipo treeview, selector de tema; accesos rápidos personalizables con 3 presentaciones; búsqueda global; notificaciones reales - Configuración: secciones (clínica, usuarios con permisos por sección, recetas, catálogos de diagnósticos y procedimientos) - Inventario: alertas de caducidad y sugerencia de compra, cron diario que descuenta artículos caducados, compras/bajas - Consultas Médicas, página Expedientes, importadores delta (citas/visitas legacy idempotentes), depuración de duplicados - Infra: tema Tailwind conectado (@config), gzip en nginx, secuencias Odoo corregidas (noupdate, company_id), rollback en validaciones
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import json
|
||||
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
@@ -29,6 +31,8 @@ class SkeenFrontendUser(models.Model):
|
||||
must_change_password = fields.Boolean(string='Debe cambiar contraseña', default=False)
|
||||
last_login = fields.Datetime(string='Último acceso', readonly=True)
|
||||
notes = fields.Text(string='Notas')
|
||||
allowed_menus = fields.Text(string='Menús Permitidos',
|
||||
help='JSON array de hrefs visibles; vacío = defaults por rol')
|
||||
|
||||
_sql_constraints = [
|
||||
('unique_login', 'unique(login)', 'El usuario ya existe.'),
|
||||
@@ -61,6 +65,17 @@ class SkeenFrontendUser(models.Model):
|
||||
'admin': 100,
|
||||
}.get(self.role, 0)
|
||||
|
||||
def _allowed_menus_list(self):
|
||||
"""Devuelve la lista de hrefs permitidos o None (usar defaults por rol)"""
|
||||
self.ensure_one()
|
||||
if not self.allowed_menus:
|
||||
return None
|
||||
try:
|
||||
val = json.loads(self.allowed_menus)
|
||||
except Exception:
|
||||
return None
|
||||
return val if isinstance(val, list) and val else None
|
||||
|
||||
def to_public_dict(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
@@ -70,4 +85,5 @@ class SkeenFrontendUser(models.Model):
|
||||
'role': self.role,
|
||||
'must_change_password': self.must_change_password,
|
||||
'last_login': self.last_login.strftime('%Y-%m-%d %H:%M') if self.last_login else None,
|
||||
'allowed_menus': self._allowed_menus_list(),
|
||||
}
|
||||
|
||||
@@ -137,5 +137,7 @@ class SkeenWacrmDeal(models.Model):
|
||||
expected_close_date = fields.Date('Cierre esperado')
|
||||
notes = fields.Text('Notas')
|
||||
assigned_to = fields.Char('Asignado a')
|
||||
partner_id = fields.Many2one('res.partner', string='Paciente', index=True,
|
||||
help='Paciente SKEEN ligado al convertir el lead')
|
||||
created_at = fields.Datetime('Creado en WACRM')
|
||||
updated_at = fields.Datetime('Actualizado en WACRM')
|
||||
|
||||
Reference in New Issue
Block a user