diff --git a/bda/admin.py b/bda/admin.py index bcbc609c..e1788c6b 100644 --- a/bda/admin.py +++ b/bda/admin.py @@ -5,7 +5,7 @@ from django.contrib.contenttypes.models import ContentType from django.contrib import admin from django.db.models import Sum, Count -from bda.models import Spectacle, Salle, Participant, ChoixSpectacle, Attribution +from bda.models import Spectacle, Salle, Participant, ChoixSpectacle, Attribution, Tirage class ChoixSpectacleInline(admin.TabularInline): model = ChoixSpectacle @@ -155,3 +155,4 @@ admin.site.register(Salle) admin.site.register(Participant, ParticipantAdmin) admin.site.register(Attribution, AttributionAdmin) admin.site.register(ChoixSpectacle, ChoixSpectacleAdmin) +admin.site.register(Tirage) diff --git a/bda/views.py b/bda/views.py index dc91758e..0789b9ff 100644 --- a/bda/views.py +++ b/bda/views.py @@ -6,27 +6,34 @@ from django.contrib.auth.decorators import login_required from django.db import models from django.http import Http404 from django.core import serializers -from django.forms.models import inlineformset_factory, BaseInlineFormSet +from django.forms.models import inlineformset_factory import hashlib from django.core.mail import send_mail +from django.utils import timezone -from datetime import datetime, timedelta +from datetime import timedelta import time from gestioncof.decorators import cof_required, buro_required from gestioncof.shared import send_custom_mail -from bda.models import Spectacle, Participant, ChoixSpectacle, Attribution +from bda.models import Spectacle, Participant, ChoixSpectacle, Attribution, Tirage from bda.algorithm import Algorithm from bda.forms import BaseBdaFormSet, TokenForm, ResellForm @cof_required -def etat_places(request, tirage): - all_spectacles = ChoixSpectacle.objects.filter(tirage = tirage) - spectacles1 = all_spectacles.filter(double_choice="1").all().values('spectacle','spectacle__title').annotate(total=models.Count('spectacle')) - spectacles2 = all_spectacles.exclude(double_choice="1").all().values('spectacle','spectacle__title').annotate(total=models.Count('spectacle')) - spectacles = Spectacle.objects.all() +def etat_places(request, tirage_id): + tirage = get_object_or_404(Tirage, id=tirage_id) + spectacles1 = ChoixSpectacles.objetcs.filter(tirage=tirage + ).filter(double_choice="1" + ).all().values('spectacle','spectacle__title' + ).annotate(total=models.Count('spectacle')) + spectacles2 = ChoixSpectacles.objetcs.filter(tirage=tirage + ).exclude(double_choice="1" + ).all().values('spectacle','spectacle__title' + ).annotate(total=models.Count('spectacle')) + spectacles = Spectacle.objects.filter(tirage__id=num_tirage).all() spectacles_dict = {} total = 0 for spectacle in spectacles: @@ -35,13 +42,18 @@ def etat_places(request, tirage): spectacles_dict[spectacle.id] = spectacle for spectacle in spectacles1: spectacles_dict[spectacle["spectacle"]].total += spectacle["total"] - spectacles_dict[spectacle["spectacle"]].ratio = spectacles_dict[spectacle["spectacle"]].total/float(spectacles_dict[spectacle["spectacle"]].slots) + spectacles_dict[spectacle["spectacle"]].ratio = \ + spectacles_dict[spectacle["spectacle"]].total / \ + float(spectacles_dict[spectacle["spectacle"]].slots) total += spectacle["total"] for spectacle in spectacles2: spectacles_dict[spectacle["spectacle"]].total += 2*spectacle["total"] - spectacles_dict[spectacle["spectacle"]].ratio = spectacles_dict[spectacle["spectacle"]].total/float(spectacles_dict[spectacle["spectacle"]].slots) + spectacles_dict[spectacle["spectacle"]].ratio = \ + spectacles_dict[spectacle["spectacle"]].total / \ + float(spectacles_dict[spectacle["spectacle"]].slots) total += spectacle["total"] - return render(request, "etat-places.html", {"spectacles": spectacles, "total": total}) + return render(request, "etat-places.html", + {"spectacles": spectacles, "total": total, 'tirage': tirage}) def _hash_queryset(queryset): data = serializers.serialize("json", queryset) @@ -50,9 +62,12 @@ def _hash_queryset(queryset): return hasher.hexdigest() @cof_required -def places(request, tirage): - participant, created = Participant.objects.get_or_create(user=request.user) - places = participant.attribution_set.filter(tirage=tirage).order_by("spectacle__date", "spectacle").all() +def places(request, tirage_id): + tirage = get_object_or_404(Tirage, id=tirage_id) + participant, created = Participant.objects.get_or_create( + user=request.user, tirage=tirage) + places = participant.attribution_set.order_by( + "spectacle__date", "spectacle").all() total = sum([place.spectacle.price for place in places]) filtered_places = [] places_dict = {} @@ -75,13 +90,17 @@ def places(request, tirage): return render(request, "resume_places.html", {"participant": participant, "places": filtered_places, + "tirage": tirage, "total": total, "warning": warning}) @cof_required -def places_ics(request, tirage): - participant, created = Participant.objects.get_or_create(user=request.user) - places = participant.attribution_set.filter(tirage=tirage).order_by("spectacle__date", "spectacle").all() +def places_ics(request, tirage_id): + tirage = get_object_or_404(Tirage, id=tirage_id) + participant, created = Participant.objects.get_or_create( + user=request.user, tirage=tirage) + places = participant.attribution_set.order_by( + "spectacle__date", "spectacle").all() filtered_places = [] places_dict = {} spectacles = [] @@ -100,14 +119,20 @@ def places_ics(request, tirage): "places": filtered_places}, content_type="text/calendar") @cof_required -def inscription(request, tirage): - if datetime.now() > datetime(2025, 10, 4, 12, 00): - participant, created = Participant.objects.get_or_create(user=request.user) +def inscription(request, tirage_id): + tirage = get_object_or_404(Tirage, id=tirage_id) + if timezone.now() > tirage.fermeture: + participant, created = Participant.objects.get_or_create( + user=request.user, tirage=tirage) choices = participant.choixspectacle_set.order_by("priority").all() - return render(request, "resume_inscription.html", {"error_title": "C'est fini !", "error_description": u"Tirage au sort dans la journée !", "choices": choices}) + return render(request, "resume_inscription.html", + { "error_title": "C'est fini !", + "error_description": u"Tirage au sort dans la journée !", + "choices": choices}) BdaFormSet = inlineformset_factory(Participant, ChoixSpectacle, fields=("spectacle","double_choice","priority"), formset=BaseBdaFormSet) - participant, created = Participant.objects.get_or_create(user=request.user) + participant, created = Participant.objects.get_or_create( + user=request.user, tirage=tirage) success = False stateerror = False if request.method == "POST": @@ -118,30 +143,35 @@ def inscription(request, tirage): else: formset = BdaFormSet(request.POST, instance=participant) if formset.is_valid(): - choix = formset.save(commit=False) - for c in choix: - c.tirage = tirage - c.save() + formset.save() success = True formset = BdaFormSet(instance=participant) else: formset = BdaFormSet(instance=participant) dbstate = _hash_queryset(participant.choixspectacle_set.all()) total_price = 0 - for choice in participant.choixspectacle_set.filter(tirage=tirage).all(): + 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, "dbstate": dbstate, "stateerror": stateerror}) + return render(request, "inscription-bda.html", + { "formset": formset, + "success": success, + "total_price": total_price, + "dbstate": dbstate, + 'tirage': tirage, + "stateerror": stateerror}) -def do_tirage(request, tirage): +def do_tirage(request, tirage_id): + tirage = get_object_or_404(Tirage, id=tirage_id) form = TokenForm(request.POST) if not form.is_valid(): return tirage(request) start = time.time() data = {} - shows = Spectacle.objects.select_related().all() - members = Participant.objects.all() - choices = ChoixSpectacle.objects.filter(tirage=tirage).order_by('participant', 'priority').select_related().all() + shows = Spectacle.objects.filter(tirage=tirage).select_related().all() + members = Participant.objects.filter(tirage=tirage).all() + choices = ChoixSpectacle.objects.filter(spectacle__tirage=tirage).order_by( + 'participant', 'priority').select_related().all() algo = Algorithm(shows, members, choices) results = algo(form.cleaned_data["token"]) total_slots = 0 @@ -183,23 +213,23 @@ def do_tirage(request, tirage): members2[member].append(show) member.total += show.price members2 = members2.items() - data["members2"] = sorted(members2, key = lambda m: m[0].user.last_name) + data["members2"] = sorted(members2, key=lambda m: m[0].user.last_name) if False and request.user.username in ["seguin", "harazi","fromherz", "ccadiou"]: Attribution.objects.all().delete() for (show, members, _) in results: for (member, _, _, _) in members: - attrib = Attribution(spectacle = show, participant = member) + attrib = Attribution(spectacle=show, participant=member) attrib.save() return render(request, "bda-attrib-extra.html", data) else: return render(request, "bda-attrib.html", data) @login_required -def tirage(request, tirage): +def tirage(request, tirage_id): if request.POST: form = TokenForm(request.POST) if form.is_valid(): - return do_tirage(request, tirage) + return do_tirage(request, tirage_id) else: form = TokenForm() return render(request, "bda-token.html", {"form": form}) @@ -225,15 +255,19 @@ def do_resell(request, form): Je souhaite revendre %s pour %s le %s (%s) à %.02f€. Contactez moi par email si vous êtes intéressé·e·s ! -%s (%s)""" % (places, spectacle.title, spectacle.date_no_seconds(), spectacle.location, spectacle.price, request.user.get_full_name(), request.user.email) +%s (%s)""" % (places, spectacle.title, spectacle.date_no_seconds(), + spectacle.location, spectacle.price, request.user.get_full_name(), + request.user.email) send_mail("%s" % spectacle, mail, request.user.email, ["bda-revente@lists.ens.fr"], fail_silently = False) 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) +def revente(request, tirage_id): + tirage = get_object_or_404(Tirage, id=tirage_id) + participant, created = Participant.objects.get_or_create( + user=request.user, tirage=tirage) if not participant.paid: return render(request, "bda-notpaid.html", {}) if request.POST: @@ -242,21 +276,26 @@ def revente(request): return do_resell(request, form) else: form = ResellForm(participant) - return render(request, "bda-revente.html", {"form": form}) + return render(request, "bda-revente.html", {"form": form, 'tirage': tirage}) @buro_required -def spectacle(request, spectacle_id): - spectacle = get_object_or_404(Spectacle, id = spectacle_id) +def spectacle(request, tirage_id, spectacle_id): + tirage = get_object_or_404(Tirage, id=tirage_id) + spectacle = get_object_or_404(Spectacle, id = spectacle_id, tirage=tirage) 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()}) +def unpaid(request, tirage_id): + tirage = get_object_or_404(Tirage, id=tirage_id) + unpaid = Participants.objects.filter(tirage=tirage, paid=False).all() + return render(request, "bda-unpaid.html", {"unpaid": unpaid}) @buro_required -def liste_spectacles_ics(request, tirage): +def liste_spectacles_ics(request, tirage_id): spectacles = Spectacle.objects.filter(tirage=tirage).order_by("date").all() for spectacle in spectacles: spectacle.dtend = spectacle.date + timedelta(seconds=7200) return render(request, "liste_spectacles.ics", - {"spectacles": spectacles}, content_type="text/calendar") + { "spectacles": spectacles, "tirage": tirage}, + content_type="text/calendar") + diff --git a/cof/urls.py b/cof/urls.py index 332d9ae6..6b55e5dd 100644 --- a/cof/urls.py +++ b/cof/urls.py @@ -40,16 +40,20 @@ urlpatterns = patterns('', url(r'^petitcours/demandes/(?P\d+)$', 'gestioncof.petits_cours_views.details', name = 'petits-cours-demande-details'), url(r'^petitcours/demandes/(?P\d+)/traitement$', 'gestioncof.petits_cours_views.traitement', name = 'petits-cours-demande-traitement'), url(r'^petitcours/demandes/(?P\d+)/retraitement$', 'gestioncof.petits_cours_views.retraitement', name = 'petits-cours-demande-retraitement'), - url(r'^bda/inscription/(?P\d+)$', 'bda.views.inscription', name = 'bda-tirage-inscription'), - url(r'^bda/places/(?P\d+)$', 'bda.views.places', name = "bda-places-attribuees"), - url(r'^bda/places/(?P\d+)/places_bda.ics$', 'bda.views.places_ics', name = "bda-places-attribuees-ics"), - url(r'^bda/revente$', 'bda.views.revente', name = 'bda-revente'), - url(r'^bda/etat-places/(?P\d+)$', 'bda.views.etat_places', name = 'bda-etat-places'), - url(r'^bda/tirage/(?P\d+)$', 'bda.views.tirage'), - url(r'^bda/spectacles/$', ListView.as_view(model = Spectacle), name ="bda-liste-spectacles"), - url(r'^bda/spectacles/liste_spectacles.ics$', 'bda.views.liste_spectacles_ics', name ="bda-liste-spectacles-ics"), - url(r'^bda/spectacles/unpaid$', "bda.views.unpaid", name = "bda-unpaid"), - url(r'^bda/spectacles/(?P\d+)$', "bda.views.spectacle", name = "bda-spectacle"), + + url(r'^bda/inscription/(?P\d+)$', 'bda.views.inscription', name = 'bda-tirage-inscription'), + url(r'^bda/places/(?P\d+)$', 'bda.views.places', name = "bda-places-attribuees"), + url(r'^bda/places/(?P\d+)/places_bda.ics$', 'bda.views.places_ics', name = "bda-places-attribuees-ics"), + url(r'^bda/revente/(?P\d+)$', 'bda.views.revente', name = 'bda-revente'), + url(r'^bda/etat-places/(?P\d+)$', 'bda.views.etat_places', name = 'bda-etat-places'), + url(r'^bda/tirage/(?P\d+)$', 'bda.views.tirage'), + url(r'^bda/spectacles/(?P\d+)/$', lambda tirage_id: ListView(model=Spectacle, + queryset=Spectacle.objects.filter(tirage__id=tirage_id) + ), name ="bda-liste-spectacles"), + url(r'^bda/spectacles/(?P\d+)(?P\d+)$', "bda.views.spectacle", name = "bda-spectacle"), + url(r'^bda/spectacles/(?P)/liste_spectacles.ics$', 'bda.views.liste_spectacles_ics', name ="bda-liste-spectacles-ics"), + url(r'^bda/spectacles/unpaid(?P\d+)$', "bda.views.unpaid", name = "bda-unpaid"), + url(r'^survey/(?P\d+)$', 'gestioncof.views.survey'), url(r'^event/(?P\d+)$', 'gestioncof.views.event'), url(r'^survey/(?P\d+)/status$', 'gestioncof.views.survey_status'),