Merge branch 'Aufinal/fix_revente' into 'master'

Répare les boutons de transfert/réinitialisation de revente. Le problème
était dû à une mauvaise conversion `str` -> `int` de l'id de la revente 
et l'utilisation d'un formulaire Django élimine ce problème.

fixes #122

See merge request !172
This commit is contained in:
Martin Pepin 2017-02-22 14:08:00 +01:00
commit a0a7be43e1
4 changed files with 103 additions and 119 deletions

View file

@ -4,8 +4,6 @@ from __future__ import division
from __future__ import print_function from __future__ import print_function
from __future__ import unicode_literals from __future__ import unicode_literals
from datetime import timedelta
from django import forms from django import forms
from django.forms.models import BaseInlineFormSet from django.forms.models import BaseInlineFormSet
from django.utils import timezone from django.utils import timezone
@ -45,6 +43,7 @@ class AttributionModelMultipleChoiceField(forms.ModelMultipleChoiceField):
class ResellForm(forms.Form): class ResellForm(forms.Form):
attributions = AttributionModelMultipleChoiceField( attributions = AttributionModelMultipleChoiceField(
label='',
queryset=Attribution.objects.none(), queryset=Attribution.objects.none(),
widget=forms.CheckboxSelectMultiple, widget=forms.CheckboxSelectMultiple,
required=False) required=False)
@ -58,6 +57,7 @@ class ResellForm(forms.Form):
class AnnulForm(forms.Form): class AnnulForm(forms.Form):
attributions = AttributionModelMultipleChoiceField( attributions = AttributionModelMultipleChoiceField(
label='',
queryset=Attribution.objects.none(), queryset=Attribution.objects.none(),
widget=forms.CheckboxSelectMultiple, widget=forms.CheckboxSelectMultiple,
required=False) required=False)
@ -67,7 +67,7 @@ class AnnulForm(forms.Form):
self.fields['attributions'].queryset = participant.attribution_set\ self.fields['attributions'].queryset = participant.attribution_set\
.filter(spectacle__date__gte=timezone.now(), .filter(spectacle__date__gte=timezone.now(),
revente__isnull=False, revente__isnull=False,
revente__date__gt=timezone.now()-timedelta(hours=1), revente__notif_sent=False,
revente__soldTo__isnull=True) revente__soldTo__isnull=True)
@ -81,3 +81,19 @@ class InscriptionReventeForm(forms.Form):
super(InscriptionReventeForm, self).__init__(*args, **kwargs) super(InscriptionReventeForm, self).__init__(*args, **kwargs)
self.fields['spectacles'].queryset = tirage.spectacle_set.filter( self.fields['spectacles'].queryset = tirage.spectacle_set.filter(
date__gte=timezone.now()) date__gte=timezone.now())
class SoldForm(forms.Form):
attributions = AttributionModelMultipleChoiceField(
label='',
queryset=Attribution.objects.none(),
widget=forms.CheckboxSelectMultiple)
def __init__(self, participant, *args, **kwargs):
super(SoldForm, self).__init__(*args, **kwargs)
self.fields['attributions'].queryset = (
participant.attribution_set
.filter(revente__isnull=False,
revente__soldTo__isnull=False)
.exclude(revente__soldTo=participant)
)

View file

@ -1,73 +0,0 @@
{% extends "base_title.html" %}
{% load bootstrap %}
{% block realcontent %}
<h2>Revente de place</h2>
<h3>Places non revendues</h3>
<form class="form-horizontal" action="" method="post">
{% csrf_token %}
<div class="form-group">
<div class="multiple-checkbox">
<ul>
{% for box in resellform.attributions %}
<li>
{{box.tag}}
{{box.choice_label}}
</li>
{% endfor %}
</ul>
</div>
</div>
<div class="form-actions">
<input type="submit" class="btn btn-primary" name="resell" value="Revendre les places sélectionnées">
</div>
</form>
<br>
{% if annulform.attributions or overdue %}
<h3>Places en cours de revente</h3>
<form action="" method="post">
{% csrf_token %}
<div class="form-group">
<div class="multiple-checkbox">
<ul>
{% for box in annulform.attributions %}
<li>
{{box.tag}}
{{box.choice_label}}
</li>
{% endfor %}
{% for attrib in overdue %}
<li>
<input type="checkbox" style="visibility:hidden">
{{attrib.spectacle}}
</li>
{% endfor %}
</ul>
</div>
</div>
{% if annulform.attributions %}
<input type="submit" class="btn btn-primary" name="annul" value="Annuler les reventes sélectionnées">
{% endif %}
</form>
{% endif %}
<br>
{% if sold %}
<h3>Places revendues</h3>
<table class="table">
{% for attrib in sold %}
<tr>
<form action="" method="post">
{% csrf_token %}
<td>{{attrib.spectacle}}</td>
<td>{{attrib.revente.soldTo.user.get_full_name}}</td>
<td><button type="submit" class="btn btn-primary" name="transfer"
value="{{attrib.revente.id}}">Transférer</button></td>
<td><button type="submit" class="btn btn-primary" name="reinit"
value="{{attrib.revente.id}}">Réinitialiser</button></td>
</form>
</tr>
{% endfor %}
</table>
{% endif %}
{% endblock %}

View file

@ -0,0 +1,53 @@
{% extends "base_title.html" %}
{% load bootstrap %}
{% block realcontent %}
<h2>Revente de place</h2>
{% if resellform.attributions %}
<h3>Places non revendues</h3>
<form class="form-horizontal" action="" method="post">
{% csrf_token %}
{{resellform|bootstrap}}
<div class="form-actions">
<input type="submit" class="btn btn-primary" name="resell" value="Revendre les places sélectionnées">
</div>
</form>
{% endif %}
<br>
{% if annulform.attributions or overdue %}
<h3>Places en cours de revente</h3>
<form action="" method="post">
{% csrf_token %}
<div class='form-group'>
<div class='multiple-checkbox'>
<ul>
{% for attrib in annulform.attributions %}
<li>{{attrib.tag}} {{attrib.choice_label}}</li>
{% endfor %}
{% for attrib in overdue %}
<li>
<input type="checkbox" style="visibility:hidden">
{{attrib.spectacle}}
</li>
{% endfor %}
{% if annulform.attributions %}
<input type="submit" class="btn btn-primary" name="annul" value="Annuler les reventes sélectionnées">
{% endif %}
</form>
{% endif %}
<br>
{% if soldform.attributions %}
<h3>Places revendues</h3>
<form action="" method="post">
{% csrf_token %}
{{soldform|bootstrap}}
<button type="submit" class="btn btn-primary" name="transfer">Transférer</button>
<button type="submit" class="btn btn-primary" name="reinit">Réinitialiser</button>
</form>
{% endif %}
{% if not resellform.attributions and not soldform.attributions and not overdue and not annulform.attributions %}
<p>Plus de reventes possibles !</p>
{% endif %}
{% endblock %}

View file

@ -26,7 +26,7 @@ from bda.models import Spectacle, Participant, ChoixSpectacle, Attribution,\
Tirage, SpectacleRevente Tirage, SpectacleRevente
from bda.algorithm import Algorithm from bda.algorithm import Algorithm
from bda.forms import BaseBdaFormSet, TokenForm, ResellForm, AnnulForm,\ from bda.forms import BaseBdaFormSet, TokenForm, ResellForm, AnnulForm,\
InscriptionReventeForm InscriptionReventeForm, SoldForm
@cof_required @cof_required
@ -316,13 +316,18 @@ def revente(request, tirage_id):
tirage = get_object_or_404(Tirage, id=tirage_id) tirage = get_object_or_404(Tirage, id=tirage_id)
participant, created = Participant.objects.get_or_create( participant, created = Participant.objects.get_or_create(
user=request.user, tirage=tirage) user=request.user, tirage=tirage)
if not participant.paid: if not participant.paid:
return render(request, "bda-notpaid.html", {}) return render(request, "bda-notpaid.html", {})
resellform = ResellForm(participant, prefix='resell')
annulform = AnnulForm(participant, prefix='annul')
soldform = SoldForm(participant, prefix='sold')
if request.method == 'POST': if request.method == 'POST':
# On met en vente une place # On met en vente une place
if 'resell' in request.POST: if 'resell' in request.POST:
resellform = ResellForm(participant, request.POST, prefix='resell') resellform = ResellForm(participant, request.POST, prefix='resell')
annulform = AnnulForm(participant, prefix='annul')
if resellform.is_valid(): if resellform.is_valid():
datatuple = [] datatuple = []
attributions = resellform.cleaned_data["attributions"] attributions = resellform.cleaned_data["attributions"]
@ -354,7 +359,6 @@ def revente(request, tirage_id):
# On annule une revente # On annule une revente
elif 'annul' in request.POST: elif 'annul' in request.POST:
annulform = AnnulForm(participant, request.POST, prefix='annul') annulform = AnnulForm(participant, request.POST, prefix='annul')
resellform = ResellForm(participant, prefix='resell')
if annulform.is_valid(): if annulform.is_valid():
attributions = annulform.cleaned_data["attributions"] attributions = annulform.cleaned_data["attributions"]
for attribution in attributions: for attribution in attributions:
@ -362,58 +366,42 @@ def revente(request, tirage_id):
# On confirme une vente en transférant la place à la personne qui a # On confirme une vente en transférant la place à la personne qui a
# gagné le tirage # gagné le tirage
elif 'transfer' in request.POST: elif 'transfer' in request.POST:
resellform = ResellForm(participant, prefix='resell') soldform = SoldForm(participant, request.POST, prefix='sold')
annulform = AnnulForm(participant, prefix='annul') if soldform.is_valid():
attributions = soldform.cleaned_data['attributions']
for attribution in attributions:
attribution.participant = attribution.revente.soldTo
attribution.save()
revente_id = request.POST['transfer'][0]
rev = SpectacleRevente.objects.filter(soldTo__isnull=False,
id=revente_id)
if rev.exists():
revente = rev.get()
attrib = revente.attribution
attrib.participant = revente.soldTo
attrib.save()
# On annule la revente après le tirage au sort (par exemple si # On annule la revente après le tirage au sort (par exemple si
# la personne qui a gagné le tirage ne se manifeste pas). La place est # la personne qui a gagné le tirage ne se manifeste pas). La place est
# alors remise en vente # alors remise en vente
elif 'reinit' in request.POST: elif 'reinit' in request.POST:
resellform = ResellForm(participant, prefix='resell') soldform = SoldForm(participant, request.POST, prefix='sold')
annulform = AnnulForm(participant, prefix='annul') if soldform.is_valid():
revente_id = request.POST['reinit'][0] attributions = soldform.cleaned_data['attributions']
rev = SpectacleRevente.objects.filter(soldTo__isnull=False, for attribution in attributions:
id=revente_id) if attribution.spectacle.date > timezone.now():
if rev.exists(): revente = attribution.revente
revente = rev.get() revente.date = timezone.now() - timedelta(minutes=65)
if revente.attribution.spectacle.date > timezone.now(): revente.soldTo = None
revente.date = timezone.now() - timedelta(hours=1) revente.notif_sent = False
revente.soldTo = None revente.tirage_done = False
revente.notif_sent = False revente.shotgun = False
revente.tirage_done = False if revente.answered_mail:
revente.shotgun = False revente.answered_mail.clear()
if revente.answered_mail: revente.save()
revente.answered_mail.clear()
revente.save()
else:
resellform = ResellForm(participant, prefix='resell')
annulform = AnnulForm(participant, prefix='annul')
else:
resellform = ResellForm(participant, prefix='resell')
annulform = AnnulForm(participant, prefix='annul')
overdue = participant.attribution_set.filter( overdue = participant.attribution_set.filter(
spectacle__date__gte=timezone.now(), spectacle__date__gte=timezone.now(),
revente__isnull=False, revente__isnull=False,
revente__seller=participant, revente__seller=participant,
revente__date__lte=timezone.now()-timedelta(hours=1)).filter( revente__notif_sent=True)\
.filter(
Q(revente__soldTo__isnull=True) | Q(revente__soldTo=participant)) Q(revente__soldTo__isnull=True) | Q(revente__soldTo=participant))
sold = participant.attribution_set.filter(
spectacle__date__gte=timezone.now(),
revente__isnull=False,
revente__soldTo__isnull=False)
return render(request, "bda-revente.html", return render(request, "bda/reventes.html",
{'tirage': tirage, 'overdue': overdue, "sold": sold, {'tirage': tirage, 'overdue': overdue, "soldform": soldform,
"annulform": annulform, "resellform": resellform}) "annulform": annulform, "resellform": resellform})