Fixes and cleanup

This commit is contained in:
Martin Pépin 2017-02-03 17:07:50 +01:00
parent 18b186929c
commit ba88b94320
3 changed files with 98 additions and 70 deletions

View file

@ -10,6 +10,7 @@ from django.contrib.auth.models import User
from gestioncof.management.base import MyBaseCommand from gestioncof.management.base import MyBaseCommand
from bda.models import Tirage, Spectacle, Salle, Participant, ChoixSpectacle from bda.models import Tirage, Spectacle, Salle, Participant, ChoixSpectacle
from bda.views import do_tirage
# Où sont stockés les fichiers json # Où sont stockés les fichiers json
@ -30,12 +31,14 @@ class Command(MyBaseCommand):
Tirage( Tirage(
title="Tirage de test 1", title="Tirage de test 1",
ouverture=timezone.now()-timezone.timedelta(days=7), ouverture=timezone.now()-timezone.timedelta(days=7),
fermeture=timezone.now() fermeture=timezone.now(),
active=True
), ),
Tirage( Tirage(
title="Tirage de test 2", title="Tirage de test 2",
ouverture=timezone.now(), ouverture=timezone.now(),
fermeture=timezone.now()+timezone.timedelta(days=60) fermeture=timezone.now()+timezone.timedelta(days=60),
active=True
) )
]) ])
tirages = Tirage.objects.all() tirages = Tirage.objects.all()
@ -51,6 +54,10 @@ class Command(MyBaseCommand):
# --- # ---
def show_callback(show): 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.tirage = random.choice(tirages)
show.listing = bool(random.randint(0, 1)) show.listing = bool(random.randint(0, 1))
show.date = ( show.date = (
@ -96,4 +103,5 @@ class Command(MyBaseCommand):
# On lance le premier tirage # On lance le premier tirage
# --- # ---
pass self.stdout.write("Lancement du premier tirage")
do_tirage(tirages[0], "dummy_token")

View file

@ -179,79 +179,96 @@ def inscription(request, tirage_id):
"stateerror": stateerror}) "stateerror": stateerror})
def do_tirage(request, tirage_id): def do_tirage(tirage_elt, token):
tirage_elt = get_object_or_404(Tirage, id=tirage_id) """
form = TokenForm(request.POST) Fonction auxiliaire à la vue ``tirage`` qui lance effectivement le tirage
if not form.is_valid(): après qu'on a vérifié que c'est légitime et que le token donné en argument
return tirage(request, tirage_id) est correct.
Rend les résultats
"""
# Initialisation du dictionnaire data qui va contenir les résultats
start = time.time() start = time.time()
data = {} data = {
shows = tirage_elt.spectacle_set.select_related().all() 'shows': tirage_elt.spectacle_set.select_related().all(),
members = tirage_elt.participant_set.all() 'token': token,
choices = ChoixSpectacle.objects.filter(spectacle__tirage=tirage_elt) \ 'members': tirage_elt.participant_set.all(),
.order_by('participant', 'priority').select_related().all() 'total_slots': 0,
algo = Algorithm(shows, members, choices) 'total_losers': 0,
results = algo(form.cleaned_data["token"]) 'total_sold': 0,
total_slots = 0 'total_deficit': 0,
total_losers = 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: for (_, members, losers) in results:
total_slots += len(members) data['total_slots'] += len(members)
total_losers += len(losers) data['total_losers'] += len(losers)
data["total_slots"] = total_slots
data["total_losers"] = total_losers # On calcule le déficit et les bénéfices pour le BdA
data["shows"] = shows # FIXME: le traitement de l'opéra est sale
data["token"] = form.cleaned_data["token"]
data["members"] = members
data["results"] = results
total_sold = 0
total_deficit = 0
opera_deficit = 0
for (show, members, _) in results: for (show, members, _) in results:
deficit = (show.slots - len(members)) * show.price deficit = (show.slots - len(members)) * show.price
total_sold += show.slots * show.price data['total_sold'] += show.slots * show.price
if deficit >= 0: if deficit >= 0:
if "Opéra" in show.location.name: if "Opéra" in show.location.name:
opera_deficit += deficit data['opera_deficit'] += deficit
total_deficit += deficit data['total_deficit'] += deficit
data["total_sold"] = total_sold - total_deficit data["total_sold"] -= data['total_deficit']
data["total_deficit"] = total_deficit
data["opera_deficit"] = opera_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 data["duration"] = time.time() - start
if request.user.is_authenticated(): data["results"] = results
members2 = {} return data
# 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)
@buro_required @buro_required
@ -263,7 +280,8 @@ def tirage(request, tirage_id):
if request.POST: if request.POST:
form = TokenForm(request.POST) form = TokenForm(request.POST)
if form.is_valid(): 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: else:
form = TokenForm() form = TokenForm()
return render(request, "bda-token.html", {"form": form}) return render(request, "bda-token.html", {"form": form})

View file

@ -63,6 +63,8 @@ class Command(MyBaseCommand):
last_name='user', last_name='user',
email='root@localhost') email='root@localhost')
root.set_password('root') root.set_password('root')
root.is_staff = True
root.is_superuser = True
root.profile.is_cof = True root.profile.is_cof = True
root.profile.is_buro = True root.profile.is_buro = True
root.profile.save() root.profile.save()