# apps/participants/services.py from django.db import transaction from .models import Participant from apps.settingsapp.models import GradingSettings def _factor(diff: float) -> float: if diff <= 10: return 1.0 elif diff <= 20: return 0.8 return 0.6 def calculate_scores(): """Recalcula y persiste 'score' para todos los participantes""" settings = GradingSettings.get() participants = list(Participant.objects.all()) # 1) Base Entregable + Presentación for p in participants: p.score = settings.report_weight + settings.presentation_weight # 2) Similitud for diff, weight in [ (p.R_diff, settings.R_weight), (p.L_diff, settings.L_weight), (p.Ph_diff, settings.Ph_weight), (p.Pcu_diff,settings.Pcu_weight), ]: p.score += _factor(diff) * weight # 3) Objetivo (rank por métrica) sorted_by_obj = sorted(participants, key=lambda x: x.s_vol_over_eta) for idx, p in enumerate(sorted_by_obj, start=1): p.score += max(settings.objective_weight - (idx - 1), 0) # 4) Persistimos en batch with transaction.atomic(): for p in participants: p.save(update_fields=["score"])