gestioCOF/bda/views.py
2013-10-01 15:27:19 +02:00

193 lines
7.8 KiB
Python

# coding: utf-8
from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.db import models
from django.http import Http404
from django import forms
from django.forms.models import inlineformset_factory, BaseInlineFormSet
from django.core.mail import send_mail
import time
from gestioncof.decorators import cof_required, buro_required
from bda.models import Spectacle, Participant, ChoixSpectacle, Attribution
from bda.algorithm import Algorithm
class BaseBdaFormSet(BaseInlineFormSet):
def clean(self):
"""Checks that no two articles have the same title."""
super(BaseBdaFormSet, self).clean()
if any(self.errors):
# Don't bother validating the formset unless each form is valid on its own
return
spectacles = []
for i in range(0, self.total_form_count()):
form = self.forms[i]
if not form.cleaned_data:
continue
spectacle = form.cleaned_data['spectacle']
delete = form.cleaned_data['DELETE']
if not delete and spectacle in spectacles:
raise forms.ValidationError("Vous ne pouvez pas vous inscrire deux fois pour le même spectacle.")
spectacles.append(spectacle)
@cof_required
def etat_places(request):
spectacles1 = ChoixSpectacle.objects.all().values('spectacle','spectacle__title').annotate(total = models.Count('spectacle'))
spectacles2 = ChoixSpectacle.objects.filter(double = True).all().values('spectacle','spectacle__title').annotate(total = models.Count('spectacle'))
spectacles = Spectacle.objects.all()
spectacles_dict = {}
total = 0
for spectacle in spectacles:
spectacle.total = 0
spectacles_dict[spectacle.id] = spectacle
for spectacle in spectacles1:
spectacles_dict[spectacle["spectacle"]].total += spectacle["total"]
total += spectacle["total"]
for spectacle in spectacles2:
spectacles_dict[spectacle["spectacle"]].total += spectacle["total"]
total += spectacle["total"]
return render(request, "etat-places.html", {"spectacles": spectacles, "total": total})
@cof_required
def inscription(request):
if False and time.time() > 1349474400:
return render(request, "error.html", {"error_title": "C'est fini !", "error_description": u"Tirage au sort le 6 octobre dans la soirée "})
BdaFormSet = inlineformset_factory(Participant, ChoixSpectacle, fields = ("spectacle","double","autoquit","priority",), formset = BaseBdaFormSet)
participant, created = Participant.objects.get_or_create(user = request.user)
success = False
if request.method == "POST":
formset = BdaFormSet(request.POST, instance = participant)
if formset.is_valid():
#ChoixSpectacle.objects.filter(participant = participant).delete()
formset.save()
success = True
formset = BdaFormSet(instance = participant)
else:
formset = BdaFormSet(instance = participant)
total_price = 0
for choice in participant.choixspectacle_set.all():
total_price += choice.spectacle.price
if choice.double: total_price += choice.spectacle.price
return render(request, "inscription-bda.html", {"formset": formset, "success": success, "total_price": total_price})
Spectacle.deficit = lambda x: (x.slots-x.nrequests)*x.price
def do_tirage(request):
form = TokenForm(request.POST)
if not form.is_valid():
return tirage(request)
data = {}
shows = Spectacle.objects.all()
members = Participant.objects.all()
choices = ChoixSpectacle.objects.all()
algo = Algorithm(shows, members, choices)
results = algo(form.cleaned_data["token"])
total_slots = 0
total_losers = 0
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
for show in shows:
deficit = show.deficit()
total_sold += show.slots * show.price
if deficit >= 0:
if u"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
if request.user.is_authenticated():
members2 = {}
for (show, members, _) in results:
for (member, _, _, _) in members:
if member not in members2:
members2[member] = []
member.total = 0
members2[member].append(show)
member.total += show.price
members2 = members2.items()
data["members2"] = sorted(members2, key = lambda m: m[0].user.last_name)
if False and request.user.username == "seguin":
Attribution.objects.all().delete()
for (show, members, _) in results:
for (member, _, _, _) in members:
attrib = Attribution(spectacle = show, participant = member)
attrib.save()
return render(request, "bda-attrib-extra.html", data)
else:
return render(request, "bda-attrib.html", data)
class TokenForm(forms.Form):
token = forms.CharField(widget = forms.widgets.Textarea())
@login_required
def tirage(request):
if request.POST:
form = TokenForm(request.POST)
if form.is_valid():
return do_tirage(request)
else:
form = TokenForm()
return render(request, "bda-token.html", {"form": form})
class SpectacleModelChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return u"%s le %s (%s) à %.02f" % (obj.title, obj.date_no_seconds(), obj.location, obj.price)
class ResellForm(forms.Form):
count = forms.ChoiceField(choices = (("1","1"),("2","2"),))
spectacle = SpectacleModelChoiceField(queryset = Spectacle.objects.none())
def __init__(self, participant, *args, **kwargs):
super(ResellForm, self).__init__(*args, **kwargs)
self.fields['spectacle'].queryset = participant.attributions.all().distinct()
def do_resell(request, form):
spectacle = form.cleaned_data["spectacle"]
count = form.cleaned_data["count"]
places = "2 places" if count == "2" else "une place"
mail = u"""Bonjour,
Je souhaite revendre %s pour %s le %s (%s) à %.02f€.
Contactez moi par email si vous êtes intéressés !
%s (%s)""" % (places, spectacle.title, spectacle.date_no_seconds(), spectacle.location, spectacle.price, request.user.get_full_name(), request.user.email)
send_mail("Revente de place: %s" % spectacle, mail,
request.user.email, ["bda-revente@lists.ens.fr"],
fail_silently = True)
return render(request, "bda-success.html", {"show": spectacle, "places": places})
@login_required
def revente(request):
participant, created = Participant.objects.get_or_create(user = request.user)
if not participant.paid:
return render(request, "bda-notpaid.html", {})
if request.POST:
form = ResellForm(participant, request.POST)
if form.is_valid():
return do_resell(request, form)
else:
form = ResellForm(participant)
return render(request, "bda-revente.html", {"form": form})
@buro_required
def spectacle(request, spectacle_id):
spectacle = get_object_or_404(Spectacle, id = spectacle_id)
return render(request, "bda-emails.html", {"spectacle": spectacle})
@buro_required
def unpaid(request):
return render(request, "bda-unpaid.html", {"unpaid": Participant.objects.filter(paid = False).all()})