From ba88b94320194c9325f32c8cff2eb393c1c31a6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Fri, 3 Feb 2017 17:07:50 +0100 Subject: [PATCH] Fixes and cleanup --- bda/management/commands/loadbdadevdata.py | 14 +- bda/views.py | 152 ++++++++++-------- gestioncof/management/commands/loaddevdata.py | 2 + 3 files changed, 98 insertions(+), 70 deletions(-) diff --git a/bda/management/commands/loadbdadevdata.py b/bda/management/commands/loadbdadevdata.py index 999a53e9..a8e3f298 100644 --- a/bda/management/commands/loadbdadevdata.py +++ b/bda/management/commands/loadbdadevdata.py @@ -10,6 +10,7 @@ from django.contrib.auth.models import User from gestioncof.management.base import MyBaseCommand from bda.models import Tirage, Spectacle, Salle, Participant, ChoixSpectacle +from bda.views import do_tirage # Où sont stockés les fichiers json @@ -30,12 +31,14 @@ class Command(MyBaseCommand): Tirage( title="Tirage de test 1", ouverture=timezone.now()-timezone.timedelta(days=7), - fermeture=timezone.now() + fermeture=timezone.now(), + active=True ), Tirage( title="Tirage de test 2", ouverture=timezone.now(), - fermeture=timezone.now()+timezone.timedelta(days=60) + fermeture=timezone.now()+timezone.timedelta(days=60), + active=True ) ]) tirages = Tirage.objects.all() @@ -51,6 +54,10 @@ class Command(MyBaseCommand): # --- def show_callback(show): + """ + Assigne un tirage, une date et un lieu à un spectacle et décide si + les places sont sur listing. + """ show.tirage = random.choice(tirages) show.listing = bool(random.randint(0, 1)) show.date = ( @@ -96,4 +103,5 @@ class Command(MyBaseCommand): # On lance le premier tirage # --- - pass + self.stdout.write("Lancement du premier tirage") + do_tirage(tirages[0], "dummy_token") diff --git a/bda/views.py b/bda/views.py index 3c448f34..1a864c7f 100644 --- a/bda/views.py +++ b/bda/views.py @@ -179,79 +179,96 @@ def inscription(request, tirage_id): "stateerror": stateerror}) -def do_tirage(request, tirage_id): - tirage_elt = get_object_or_404(Tirage, id=tirage_id) - form = TokenForm(request.POST) - if not form.is_valid(): - return tirage(request, tirage_id) +def do_tirage(tirage_elt, token): + """ + Fonction auxiliaire à la vue ``tirage`` qui lance effectivement le tirage + après qu'on a vérifié que c'est légitime et que le token donné en argument + est correct. + Rend les résultats + """ + # Initialisation du dictionnaire data qui va contenir les résultats start = time.time() - data = {} - shows = tirage_elt.spectacle_set.select_related().all() - members = tirage_elt.participant_set.all() - choices = ChoixSpectacle.objects.filter(spectacle__tirage=tirage_elt) \ - .order_by('participant', 'priority').select_related().all() - algo = Algorithm(shows, members, choices) - results = algo(form.cleaned_data["token"]) - total_slots = 0 - total_losers = 0 + data = { + 'shows': tirage_elt.spectacle_set.select_related().all(), + 'token': token, + 'members': tirage_elt.participant_set.all(), + 'total_slots': 0, + 'total_losers': 0, + 'total_sold': 0, + 'total_deficit': 0, + 'opera_deficit': 0, + } + + # On lance le tirage + choices = ( + ChoixSpectacle.objects + .filter(spectacle__tirage=tirage_elt) + .order_by('participant', 'priority') + .select_related().all() + ) + results = Algorithm(data['shows'], data['members'], choices)(token) + + # On compte les places attribuées et les déçus for (_, members, losers) in results: - total_slots += len(members) - total_losers += len(losers) - data["total_slots"] = total_slots - data["total_losers"] = total_losers - data["shows"] = shows - data["token"] = form.cleaned_data["token"] - data["members"] = members - data["results"] = results - total_sold = 0 - total_deficit = 0 - opera_deficit = 0 + data['total_slots'] += len(members) + data['total_losers'] += len(losers) + + # On calcule le déficit et les bénéfices pour le BdA + # FIXME: le traitement de l'opéra est sale for (show, members, _) in results: deficit = (show.slots - len(members)) * show.price - total_sold += show.slots * show.price + data['total_sold'] += show.slots * show.price if deficit >= 0: if "Opéra" in show.location.name: - opera_deficit += deficit - total_deficit += deficit - data["total_sold"] = total_sold - total_deficit - data["total_deficit"] = total_deficit - data["opera_deficit"] = opera_deficit + data['opera_deficit'] += deficit + data['total_deficit'] += deficit + data["total_sold"] -= data['total_deficit'] + + # Participant objects are not shared accross spectacle results, + # so assign a single object for each Participant id + members_uniq = {} + members2 = {} + for (show, members, _) in results: + for (member, _, _, _) in members: + if member.id not in members_uniq: + members_uniq[member.id] = member + members2[member] = [] + member.total = 0 + member = members_uniq[member.id] + members2[member].append(show) + member.total += show.price + members2 = members2.items() + data["members2"] = sorted(members2, key=lambda m: m[0].user.last_name) + + # --- + # À partir d'ici, le tirage devient effectif + # --- + + # On suppression les vieilles attributions, on sauvegarde le token et on + # désactive le tirage + Attribution.objects.filter(spectacle__tirage=tirage_elt).delete() + tirage_elt.tokens += '{:s}\n"""{:s}"""\n'.format( + timezone.now().strftime("%y-%m-%d %H:%M:%S"), + token) + tirage_elt.enable_do_tirage = False + tirage_elt.save() + + # On enregistre les nouvelles attributions + Attribution.objects.bulk_create([ + Attribution(spectacle=show, participant=member) + for show, members, _ in results + for member, _, _, _ in members + ]) + + # On inscrit à BdA-Revente ceux qui n'ont pas eu les places voulues + for (show, _, losers) in results: + for (loser, _, _, _) in losers: + loser.choicesrevente.add(show) + loser.save() + data["duration"] = time.time() - start - if request.user.is_authenticated(): - members2 = {} - # Participant objects are not shared accross spectacle results, - # so assign a single object for each Participant id - members_uniq = {} - for (show, members, _) in results: - for (member, _, _, _) in members: - if member.id not in members_uniq: - members_uniq[member.id] = member - members2[member] = [] - member.total = 0 - member = members_uniq[member.id] - members2[member].append(show) - member.total += show.price - members2 = members2.items() - data["members2"] = sorted(members2, key=lambda m: m[0].user.last_name) - # À partir d'ici, le tirage devient effectif - Attribution.objects.filter(spectacle__tirage=tirage_elt).delete() - tirage_elt.tokens += "%s\n\"\"\"%s\"\"\"\n" % ( - timezone.now().strftime("%y-%m-%d %H:%M:%S"), - form.cleaned_data['token']) - tirage_elt.enable_do_tirage = False - tirage_elt.save() - Attribution.objects.bulk_create([ - Attribution(spectacle=show, participant=member) - for show, members, _ in results - for member, _, _, _ in members]) - # On inscrit à BdA-Revente ceux qui n'ont pas eu les places voulues - for (show, _, losers) in results: - for (loser, _, _, _) in losers: - loser.choicesrevente.add(show) - loser.save() - return render(request, "bda-attrib-extra.html", data) - else: - return render(request, "bda-attrib.html", data) + data["results"] = results + return data @buro_required @@ -263,7 +280,8 @@ def tirage(request, tirage_id): if request.POST: form = TokenForm(request.POST) if form.is_valid(): - return do_tirage(request, tirage_id) + results = do_tirage(tirage_elt, form.cleaned_data['token']) + return render(request, "bda-attrib-extra.html", results) else: form = TokenForm() return render(request, "bda-token.html", {"form": form}) diff --git a/gestioncof/management/commands/loaddevdata.py b/gestioncof/management/commands/loaddevdata.py index cd1d03bd..8eb04fd2 100644 --- a/gestioncof/management/commands/loaddevdata.py +++ b/gestioncof/management/commands/loaddevdata.py @@ -63,6 +63,8 @@ class Command(MyBaseCommand): last_name='user', email='root@localhost') root.set_password('root') + root.is_staff = True + root.is_superuser = True root.profile.is_cof = True root.profile.is_buro = True root.profile.save()