bloque 3: lealtad configurable (motor de puntos con multiplicadores por servicio/categoria/sucursal/dia/nivel, niveles VIP con descuento y factor, expiracion, ajuste manual con motivo y reportes) + propinas en punto de venta con reparto entre el personal, desglose en ticket y corte, y opcion en la liquidacion de comisiones; modo clasico y propinas apagadas preservan el comportamiento actual

This commit is contained in:
2026-10-12 01:37:07 +00:00
parent 1bd4cad6a0
commit 705b5a2842
28 changed files with 2748 additions and 59 deletions

View File

@@ -15,10 +15,29 @@ import json
from odoo import models, fields, api
from odoo.exceptions import UserError
from odoo.addons.skeen_citas.clinic_settings import get_propinas
ESTADOS = ('borrador', 'pagada', 'cancelada')
ESTADO_LABEL = {'borrador': 'Borrador', 'pagada': 'Pagada', 'cancelada': 'Cancelada'}
def propinas_de_empleado(env, empleado_id, start, end):
"""Propina que le toca a un empleado en el periodo (0 si no aplica).
Solo se suma a la liquidación cuando la configuración de propinas lo pide
(`incluir_en_liquidacion_comisiones`); apagado, devuelve 0 y no altera
ninguna liquidación.
"""
cfg = get_propinas(env)
if not cfg.get('activo') or not cfg.get('incluir_en_liquidacion_comisiones'):
return 0.0
repartos = env['skeen.propina.reparto'].sudo().search([
('employee_id', '=', empleado_id),
('date', '>=', start), ('date', '<=', end),
])
return sum(r.monto or 0.0 for r in repartos)
class SkeenComisionLiquidacion(models.Model):
_name = 'skeen.comision.liquidacion'
_description = 'Liquidación de comisiones SKEEN'
@@ -33,6 +52,10 @@ class SkeenComisionLiquidacion(models.Model):
store=True, index=True)
total_calculado = fields.Float(string='Comisión calculada', default=0.0)
# Propina del empleado en el periodo. Solo tiene valor con
# `propinas.incluir_en_liquidacion_comisiones = true`; en cualquier otro
# caso queda en 0 y no cambia la liquidación.
total_propinas = fields.Float(string='Propinas', default=0.0)
total_ajustes = fields.Float(string='Ajustes', compute='_compute_total',
store=True)
total = fields.Float(string='Total a pagar', compute='_compute_total', store=True)
@@ -62,11 +85,11 @@ class SkeenComisionLiquidacion(models.Model):
for l in self:
l.periodo = l.periodo_inicio.strftime('%Y-%m') if l.periodo_inicio else ''
@api.depends('ajuste_ids.monto', 'total_calculado')
@api.depends('ajuste_ids.monto', 'total_calculado', 'total_propinas')
def _compute_total(self):
for l in self:
l.total_ajustes = sum(a.monto for a in l.ajuste_ids)
l.total = (l.total_calculado or 0.0) + l.total_ajustes
l.total = (l.total_calculado or 0.0) + l.total_ajustes + (l.total_propinas or 0.0)
@api.model_create_multi
def create(self, vals_list):