Turn 2 functions into class/objects methods
- `_get_attrib_counter` become a classmethod of `PetitCoursAttributionCounter` - `_get_demande_candidates` become a method of `PetitCoursDemande`
This commit is contained in:
parent
2bc5f3d646
commit
81681ad0e5
2 changed files with 61 additions and 36 deletions
|
@ -3,6 +3,7 @@
|
|||
from functools import reduce
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import Min
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
@ -88,6 +89,32 @@ class PetitCoursDemande(models.Model):
|
|||
blank=True, null=True)
|
||||
created = models.DateTimeField(_("Date de création"), auto_now_add=True)
|
||||
|
||||
def get_candidates(self, redo=False):
|
||||
"""
|
||||
Donne la liste des profs disponibles pour chaque matière de la demande.
|
||||
- On ne donne que les agrégés si c'est demandé
|
||||
- Si ``redo`` vaut ``True``, cela signifie qu'on retraite la demande et
|
||||
il ne faut pas proposer à nouveau des noms qui ont déjà été proposés
|
||||
"""
|
||||
for matiere in self.matieres.all():
|
||||
candidates = PetitCoursAbility.objects.filter(
|
||||
matiere=matiere,
|
||||
niveau=self.niveau,
|
||||
user__profile__is_cof=True,
|
||||
user__profile__petits_cours_accept=True
|
||||
)
|
||||
if self.agrege_requis:
|
||||
candidates = candidates.filter(agrege=True)
|
||||
if redo:
|
||||
attrs = self.petitcoursattribution_set.filter(matiere=matiere)
|
||||
already_proposed = [
|
||||
attr.user
|
||||
for attr in attrs
|
||||
]
|
||||
candidates = candidates.exclude(user__in=already_proposed)
|
||||
candidates = candidates.order_by('?').select_related().all()
|
||||
yield (matiere, candidates)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Demande de petits cours"
|
||||
verbose_name_plural = "Demandes de petits cours"
|
||||
|
@ -122,6 +149,25 @@ class PetitCoursAttributionCounter(models.Model):
|
|||
matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matiere"))
|
||||
count = models.IntegerField("Nombre d'envois", default=0)
|
||||
|
||||
@classmethod
|
||||
def get_uptodate(cls, user, matiere):
|
||||
"""
|
||||
Donne le compteur de l'utilisateur pour cette matière. Si le compteur
|
||||
n'existe pas encore, il est initialisé avec le minimum des valeurs des
|
||||
compteurs de tout le monde.
|
||||
"""
|
||||
counter, created = cls.objects.get_or_create(
|
||||
user=user, matiere=matiere)
|
||||
if created:
|
||||
mincount = (
|
||||
cls.objects.filter(matiere=matiere).exclude(user=user)
|
||||
.aggregate(Min('count'))
|
||||
['count__min']
|
||||
)
|
||||
counter.count = mincount
|
||||
counter.save()
|
||||
return counter
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Compteur d'attribution de petits cours"
|
||||
verbose_name_plural = "Compteurs d'attributions de petits cours"
|
||||
|
|
|
@ -16,7 +16,6 @@ from django.views.decorators.csrf import csrf_exempt
|
|||
from django.template import loader
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.db.models import Min
|
||||
|
||||
from gestioncof.models import CofProfile
|
||||
from gestioncof.petits_cours_models import (
|
||||
|
@ -51,35 +50,6 @@ def details(request, demande_id):
|
|||
"attributions": attributions})
|
||||
|
||||
|
||||
def _get_attrib_counter(user, matiere):
|
||||
counter, created = PetitCoursAttributionCounter \
|
||||
.objects.get_or_create(user=user, matiere=matiere)
|
||||
if created:
|
||||
mincount = PetitCoursAttributionCounter.objects \
|
||||
.filter(matiere=matiere).exclude(user=user).all() \
|
||||
.aggregate(Min('count'))
|
||||
counter.count = mincount['count__min']
|
||||
counter.save()
|
||||
return counter
|
||||
|
||||
|
||||
def _get_demande_candidates(demande, redo=False):
|
||||
for matiere in demande.matieres.all():
|
||||
candidates = PetitCoursAbility.objects.filter(matiere=matiere,
|
||||
niveau=demande.niveau)
|
||||
candidates = candidates.filter(user__profile__is_cof=True,
|
||||
user__profile__petits_cours_accept=True)
|
||||
if demande.agrege_requis:
|
||||
candidates = candidates.filter(agrege=True)
|
||||
if redo:
|
||||
attributions = PetitCoursAttribution.objects \
|
||||
.filter(demande=demande, matiere=matiere).all()
|
||||
for attrib in attributions:
|
||||
candidates = candidates.exclude(user=attrib.user)
|
||||
candidates = candidates.order_by('?').select_related().all()
|
||||
yield (matiere, candidates)
|
||||
|
||||
|
||||
@buro_required
|
||||
def traitement(request, demande_id, redo=False):
|
||||
demande = get_object_or_404(PetitCoursDemande, id=demande_id)
|
||||
|
@ -91,12 +61,15 @@ def traitement(request, demande_id, redo=False):
|
|||
proposed_for = {}
|
||||
unsatisfied = []
|
||||
attribdata = {}
|
||||
for matiere, candidates in _get_demande_candidates(demande, redo):
|
||||
for matiere, candidates in demande.get_candidates(redo):
|
||||
if candidates:
|
||||
tuples = []
|
||||
for candidate in candidates:
|
||||
user = candidate.user
|
||||
tuples.append((candidate, _get_attrib_counter(user, matiere)))
|
||||
tuples.append((
|
||||
candidate,
|
||||
PetitCoursAttributionCounter.get_uptodate(user, matiere)
|
||||
))
|
||||
tuples = sorted(tuples, key=lambda c: c[1].count)
|
||||
candidates, _ = zip(*tuples)
|
||||
candidates = candidates[0:min(3, len(candidates))]
|
||||
|
@ -166,7 +139,7 @@ def _traitement_other_preparing(request, demande):
|
|||
proposed_for = {}
|
||||
attribdata = {}
|
||||
errors = []
|
||||
for matiere, candidates in _get_demande_candidates(demande, redo):
|
||||
for matiere, candidates in demande.get_candidates(redo):
|
||||
if candidates:
|
||||
candidates = dict([(candidate.user.id, candidate.user)
|
||||
for candidate in candidates])
|
||||
|
@ -218,12 +191,15 @@ def _traitement_other(request, demande, redo):
|
|||
proposed_for = {}
|
||||
unsatisfied = []
|
||||
attribdata = {}
|
||||
for matiere, candidates in _get_demande_candidates(demande, redo):
|
||||
for matiere, candidates in demande.get_candidates(redo):
|
||||
if candidates:
|
||||
tuples = []
|
||||
for candidate in candidates:
|
||||
user = candidate.user
|
||||
tuples.append((candidate, _get_attrib_counter(user, matiere)))
|
||||
tuples.append((
|
||||
candidate,
|
||||
PetitCoursAttributionCounter.get_uptodate(user, matiere)
|
||||
))
|
||||
tuples = sorted(tuples, key=lambda c: c[1].count)
|
||||
candidates, _ = zip(*tuples)
|
||||
attribdata[matiere.id] = []
|
||||
|
@ -357,7 +333,10 @@ def inscription(request):
|
|||
PetitCoursAbility.objects.filter(user=request.user).all()
|
||||
)
|
||||
for ability in abilities:
|
||||
_get_attrib_counter(ability.user, ability.matiere)
|
||||
PetitCoursAttributionCounter.get_uptodate(
|
||||
ability.user,
|
||||
ability.matiere
|
||||
)
|
||||
unlock_tables()
|
||||
success = True
|
||||
formset = MatieresFormSet(instance=request.user)
|
||||
|
|
Loading…
Reference in a new issue