Files
SKEEN-Proyecto/odoo-addons/skeen_plataforma/models/limites.py

126 lines
4.1 KiB
Python

# -*- coding: utf-8 -*-
"""Aplicación de los límites de la licencia.
Solo actúan con `modo='bloqueo'` y un límite > 0. Con `aviso` (default) o sin
licencia no bloquean nada. Nunca afectan tareas internas: se pueden saltar con
el contexto `skeen_licencia_skip=True` (cron, migraciones, importaciones).
"""
import logging
from datetime import date
from odoo import _, api, fields, models
from odoo.exceptions import UserError
from odoo.addons.skeen_citas.clinic_settings import (
licencia_de, limite_licencia, licencia_bloqueo_activo,
)
_logger = logging.getLogger(__name__)
MENSAJES = {
'usuarios_max': 'usuarios',
'sucursales_max': 'sucursales',
'citas_mes_max': 'citas este mes',
'almacenamiento_mb': 'MB de almacenamiento',
}
def _skip(env):
return bool(env.context.get('skeen_licencia_skip')
or env.context.get('install_mode'))
def exigir_limite(env, clave, etiqueta, actual, agregando=1):
"""Lanza UserError si `actual + agregando` supera el límite de `clave`.
Con modo=aviso solo deja una advertencia en el log. Devuelve False si no
aplica (sin licencia, sin límite o contexto de salto).
"""
limite = limite_licencia(env, clave)
if limite <= 0 or _skip(env):
return False
licencia = licencia_de(env)
if not licencia_bloqueo_activo(licencia):
if actual + agregando > limite:
_logger.info('SKEEN licencia (aviso): %s excede el límite de %s '
'(%s + %s > %s)', etiqueta, limite, actual, agregando, limite)
return False
if actual + agregando > limite:
raise UserError(_(
'Tu plan permite hasta %(limite)s %(etiqueta)s y ya tienes '
'%(actual)s. Para ampliar el límite, contacta a tu proveedor y '
'solicita una licencia con un tope mayor.'
) % {'limite': limite, 'etiqueta': etiqueta, 'actual': actual})
return True
def _contar_usuarios(env):
return env['skeen.frontend.user'].sudo().search_count([('active', '=', True)])
def _contar_sucursales(env):
return env['skeen.sucursal'].sudo().search_count([('active', '=', True)])
def _contar_citas_mes(env):
hoy = date.today()
inicio = hoy.replace(day=1)
if hoy.month == 12:
fin = hoy.replace(year=hoy.year + 1, month=1, day=1)
else:
fin = hoy.replace(month=hoy.month + 1, day=1)
return env['skeen.cita'].sudo().search_count([
('date', '>=', inicio), ('date', '<', fin),
])
def _mb_almacenamiento(env):
env.cr.execute('SELECT COALESCE(SUM(file_size), 0) FROM ir_attachment')
total = env.cr.fetchone()[0] or 0
return total / (1024.0 * 1024.0)
class SkeenFrontendUser(models.Model):
_inherit = 'skeen.frontend.user'
@api.model_create_multi
def create(self, vals_list):
exigir_limite(self.env, 'usuarios_max', MENSAJES['usuarios_max'],
_contar_usuarios(self.env), len(vals_list))
return super().create(vals_list)
class SkeenSucursal(models.Model):
_inherit = 'skeen.sucursal'
@api.model_create_multi
def create(self, vals_list):
exigir_limite(self.env, 'sucursales_max', MENSAJES['sucursales_max'],
_contar_sucursales(self.env), len(vals_list))
return super().create(vals_list)
class SkeenCita(models.Model):
_inherit = 'skeen.cita'
@api.model_create_multi
def create(self, vals_list):
exigir_limite(self.env, 'citas_mes_max', MENSAJES['citas_mes_max'],
_contar_citas_mes(self.env), len(vals_list))
return super().create(vals_list)
class IrAttachment(models.Model):
_inherit = 'ir.attachment'
@api.model_create_multi
def create(self, vals_list):
if limite_licencia(self.env, 'almacenamiento_mb') > 0 and not _skip(self.env):
nuevos_mb = sum(max(0, int(v.get('file_size') or 0)) for v in vals_list) \
/ (1024.0 * 1024.0)
exigir_limite(self.env, 'almacenamiento_mb',
MENSAJES['almacenamiento_mb'],
_mb_almacenamiento(self.env), nuevos_mb)
return super().create(vals_list)