Date: Sun, 4 Sep 2016 11:14:09 +0200
Subject: [PATCH 23/42] =?UTF-8?q?g=C3=A8re=20les=20places=20demand=C3=A9es?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
bda/models.py | 32 +++++++++++++++++++++++++++++++
bda/templates/bda-interested.html | 9 +++++++++
bda/urls.py | 3 +++
bda/views.py | 16 +++++++++++++++-
4 files changed, 59 insertions(+), 1 deletion(-)
create mode 100644 bda/templates/bda-interested.html
diff --git a/bda/models.py b/bda/models.py
index 7856b517..c3621a45 100644
--- a/bda/models.py
+++ b/bda/models.py
@@ -6,6 +6,7 @@ from __future__ import unicode_literals
import calendar
import datetime
+import random
from django.db import models
from django.contrib.auth.models import User
@@ -256,3 +257,34 @@ class SpectacleRevente(models.Model):
connection = mail.get_connection()
connection.send_messages(mails_to_send)
+
+ def tirage(self):
+ inscrits = self.interested
+ spectacle = self.attribution.spectacle
+ user = self.attribution.participant.user
+ if inscrits.exists():
+ idx = random.randint(0, inscrits.count() - 1)
+ winner = inscrits.all()[idx]
+ self.soldTo = winner
+ mail_buyer = """Bonjour,
+
+Tu as été tiré-e au sort pour racheter une place pour %s le %s (%s) à %0.02f€.
+Tu peux contacter le vendeur à l'adresse %s.
+
+Chaleureusement,
+Le BdA""" % (spectacle.title, spectacle.date_no_seconds(),
+ spectacle.location, spectacle.price, user.email)
+
+ mail.send_mail("BdA-Revente : %s" % spectacle.title,
+ mail_buyer, "bda@ens.fr", [winner.user.email],
+ fail_silently=False)
+ mail_seller = """Bonjour,
+La personne tirée au sort pour racheter ta place pour %s est %s.
+Tu peux le/la contacter à l'adresse %s.
+
+Chaleureusement,
+Le BdA""" % (spectacle.title, winner.user.get_full_name(), winner.user.email)
+
+ mail.send_mail("BdA-Revente : %s" % spectacle.title,
+ mail_seller, "bda@ens.fr", [user.email],
+ fail_silently=False)
diff --git a/bda/templates/bda-interested.html b/bda/templates/bda-interested.html
new file mode 100644
index 00000000..acfb1d1e
--- /dev/null
+++ b/bda/templates/bda-interested.html
@@ -0,0 +1,9 @@
+{% extends "base_title.html" %}
+{% load staticfiles %}
+
+{% block realcontent %}
+Inscription à une revente
+ Votre inscription pour a bien été enregistrée !
+Le tirage au sort pour cette revente ({{spectacle}}) sera effectué le {{date}}.
+
+{% endblock %}
diff --git a/bda/urls.py b/bda/urls.py
index 13a163f4..94b797fa 100644
--- a/bda/urls.py
+++ b/bda/urls.py
@@ -38,6 +38,9 @@ urlpatterns = [
url(r'^buy-revente/(?P\d+)$',
"bda.views.buy_revente",
name="bda-buy-revente"),
+ url(r'^revente-interested/(?P\d+)$',
+ "bda.views.revente_interested",
+ name='bda-revente-interested'),
url(r'^mails-rappel/(?P\d+)$', views.send_rappel),
url(r'^descriptions/(?P\d+)$', views.descriptions_spectacles,
name='bda-descriptions'),
diff --git a/bda/views.py b/bda/views.py
index 3641b776..a3fd9168 100644
--- a/bda/views.py
+++ b/bda/views.py
@@ -318,6 +318,20 @@ def revente(request, tirage_id):
"annulform": annulform, "resellform": resellform})
+@login_required
+def revente_interested(request, revente_id):
+ revente = get_object_or_404(SpectacleRevente, id=revente_id)
+ participant, created = Participant.objects.get_or_create(
+ user=request.user, tirage=revente.attribution.spectacle.tirage)
+ if timezone.now() < revente.date + timedelta(hours=1) or revente.shotgun:
+ return render(request, "bda-wrongtime.html", {})
+
+ revente.interested.add(participant)
+ return render(request, "bda-interested.html",
+ {"spectacle": revente.attribution.spectacle,
+ "date": revente.expiration_time})
+
+
@login_required
def list_revente(request, tirage_id):
tirage = get_object_or_404(Tirage, id=tirage_id)
@@ -373,7 +387,7 @@ def buy_revente(request, spectacle_id):
revente.save()
mail = """Bonjour !
-Je souhaiterais racheter ta place pour %s le %s (%s) à %.02f€.
+Je souhaiterais racheter ta place pour %s le %s (%s) à %.02f€.
Contacte-moi si tu es toujours intéressé·e !
%s (%s)""" % (spectacle.title, spectacle.date_no_seconds(),
From 0b40ebb6f75d15f5fafcd06c48f2a926461a81b0 Mon Sep 17 00:00:00 2001
From: Ludovic Stephan
Date: Sun, 4 Sep 2016 11:14:53 +0200
Subject: [PATCH 24/42] corrections de templates
---
bda/templates/bda-no-revente.html | 6 ++++++
bda/templates/mail-revente.txt | 6 +++---
2 files changed, 9 insertions(+), 3 deletions(-)
create mode 100644 bda/templates/bda-no-revente.html
diff --git a/bda/templates/bda-no-revente.html b/bda/templates/bda-no-revente.html
new file mode 100644
index 00000000..eabb3dc7
--- /dev/null
+++ b/bda/templates/bda-no-revente.html
@@ -0,0 +1,6 @@
+{% extends "base_title.html" %}
+
+{% block realcontent %}
+ BdA-Revente
+ Il n'y a plus de places en revente pour ce spectacle, désolé !
+{% endblock %}
diff --git a/bda/templates/mail-revente.txt b/bda/templates/mail-revente.txt
index 16655696..adc61eb9 100644
--- a/bda/templates/mail-revente.txt
+++ b/bda/templates/mail-revente.txt
@@ -1,8 +1,8 @@
Bonjour {{ user.get_full_name }}
-Une place pour le spectacle {{ spectacle.title }} ({{spectacle.date_no_seconds}}) a été postée sur BDA-Revente.
+Une place pour le spectacle {{ spectacle.title }} ({{spectacle.date_no_seconds}}) a été postée sur BdA-Revente.
-Si ce spectacle t'intéresse toujours, merci de nous le signaler en cliquant sur ce lien : {% url "bda-inscr-revente" revente.id %}. Dans le cas où plusieurs personnes seraient intéressées, nous procèderons à un tirage au sort le {{revente.date_no_seconds}}
+Si ce spectacle t'intéresse toujours, merci de nous le signaler en cliquant sur ce lien : {% url "bda-interested-revente" revente.id %}. Dans le cas où plusieurs personnes seraient intéressées, nous procèderons à un tirage au sort le {{revente.date_no_seconds}}
Chaleureusement,
-Le BDA
+Le BdA
From 3bc9880db1f0c92bd29669d81ab03185715d0c23 Mon Sep 17 00:00:00 2001
From: Ludovic Stephan
Date: Mon, 5 Sep 2016 02:29:49 +0200
Subject: [PATCH 25/42] revente de revente + confirmation de transfert de
places
---
bda/forms.py | 7 +++--
bda/models.py | 10 ++++---
bda/templates/bda-revente.html | 23 +++++++++++++++
bda/views.py | 53 ++++++++++++++++++++++++++++++----
4 files changed, 80 insertions(+), 13 deletions(-)
diff --git a/bda/forms.py b/bda/forms.py
index 60fdb0fd..0c886e0f 100644
--- a/bda/forms.py
+++ b/bda/forms.py
@@ -52,8 +52,8 @@ class ResellForm(forms.Form):
def __init__(self, participant, *args, **kwargs):
super(ResellForm, self).__init__(*args, **kwargs)
self.fields['attributions'].queryset = participant.attribution_set\
- .filter(spectacle__date__gte=timezone.now(),
- revente__isnull=True)
+ .filter(spectacle__date__gte=timezone.now())\
+ .exclude(revente__seller=participant)
class AnnulForm(forms.Form):
@@ -67,7 +67,8 @@ class AnnulForm(forms.Form):
self.fields['attributions'].queryset = participant.attribution_set\
.filter(spectacle__date__gte=timezone.now(),
revente__isnull=False,
- revente__date__gte=timezone.now()-timedelta(hours=1))
+ revente__date__gte=timezone.now()-timedelta(hours=1),
+ revente__seller=participant)
class InscriptionReventeForm(forms.Form):
diff --git a/bda/models.py b/bda/models.py
index c3621a45..428dbfb7 100644
--- a/bda/models.py
+++ b/bda/models.py
@@ -221,6 +221,8 @@ class SpectacleRevente(models.Model):
interested = models.ManyToManyField(Participant,
related_name="wanted",
blank=True)
+ seller = models.ForeignKey(Participant,
+ related_name="original_shows")
soldTo = models.ForeignKey(Participant, blank=True, null=True)
def get_expiration_time(self):
@@ -235,7 +237,7 @@ class SpectacleRevente(models.Model):
shotgun = property(get_shotgun)
def __str__(self):
- return "%s -- %s" % (self.attribution.participant.user,
+ return "%s -- %s" % (self.seller,
self.attribution.spectacle.title)
def send_notif(self):
@@ -261,7 +263,7 @@ class SpectacleRevente(models.Model):
def tirage(self):
inscrits = self.interested
spectacle = self.attribution.spectacle
- user = self.attribution.participant.user
+ seller = self.seller
if inscrits.exists():
idx = random.randint(0, inscrits.count() - 1)
winner = inscrits.all()[idx]
@@ -273,7 +275,7 @@ Tu peux contacter le vendeur à l'adresse %s.
Chaleureusement,
Le BdA""" % (spectacle.title, spectacle.date_no_seconds(),
- spectacle.location, spectacle.price, user.email)
+ spectacle.location, spectacle.price, seller.email)
mail.send_mail("BdA-Revente : %s" % spectacle.title,
mail_buyer, "bda@ens.fr", [winner.user.email],
@@ -286,5 +288,5 @@ Chaleureusement,
Le BdA""" % (spectacle.title, winner.user.get_full_name(), winner.user.email)
mail.send_mail("BdA-Revente : %s" % spectacle.title,
- mail_seller, "bda@ens.fr", [user.email],
+ mail_seller, "bda@ens.fr", [seller.email],
fail_silently=False)
diff --git a/bda/templates/bda-revente.html b/bda/templates/bda-revente.html
index 0a5cffb3..a5f64678 100644
--- a/bda/templates/bda-revente.html
+++ b/bda/templates/bda-revente.html
@@ -24,6 +24,7 @@
+{% if annulform.attributions or overdue %}
Places en cours de revente
+{% endif %}
+
+{% if sold %}
+Places revendues
+
+ {% for attrib in sold %}
+
+
+
+ {% endfor %}
+
+{% endif %}
{% endblock %}
diff --git a/bda/views.py b/bda/views.py
index a3fd9168..8c92f4ab 100644
--- a/bda/views.py
+++ b/bda/views.py
@@ -9,7 +9,7 @@ import random
from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.db import models
-from django.db.models import Count
+from django.db.models import Count, Q
from django.core import serializers
from django.forms.models import inlineformset_factory
from django.http import HttpResponseBadRequest
@@ -293,8 +293,14 @@ def revente(request, tirage_id):
if resellform.is_valid():
attributions = resellform.cleaned_data["attributions"]
for attribution in attributions:
- revente = SpectacleRevente(attribution=attribution)
+ revente, created = SpectacleRevente.objects.get_or_create(
+ attribution=attribution,
+ defaults={'seller': participant})
+ if not created:
+ revente.seller = participant
+ revente.date = timezone.now()
revente.save()
+
elif 'annul' in request.POST:
annulform = AnnulForm(participant, request.POST, prefix='annul')
resellform = ResellForm(participant, prefix='resell')
@@ -302,19 +308,54 @@ def revente(request, tirage_id):
attributions = annulform.cleaned_data["attributions"]
for attribution in attributions:
attribution.revente.delete()
+
+ elif 'transfer' in request.POST:
+ resellform = ResellForm(participant, prefix='resell')
+ annulform = AnnulForm(participant, prefix='annul')
+
+ 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()
+
+ elif 'reinit' in request.POST:
+ resellform = ResellForm(participant, prefix='resell')
+ annulform = AnnulForm(participant, prefix='annul')
+ revente_id = request.POST['transfer'][0]
+ rev = SpectacleRevente.objects.filter(soldTo__isnull=False,
+ id=revente_id)
+ if rev.exists():
+ revente = rev.get()
+ revente.date = timezone.now() - timedelta(hours=1)
+ revente.soldTo = None
+ revente.interested = None
+ # schedule job
+
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(
spectacle__date__gte=timezone.now(),
revente__isnull=False,
- revente__date__lte=timezone.now()-timedelta(hours=1))
+ revente__seller=participant,
+ revente__date__lte=timezone.now()-timedelta(hours=1)).filter(
+ 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).exclude(
+ revente__soldTo=participant)
return render(request, "bda-revente.html",
- {'tirage': tirage, 'overdue': overdue,
+ {'tirage': tirage, 'overdue': overdue, "sold": sold,
"annulform": annulform, "resellform": resellform})
@@ -395,10 +436,10 @@ Contacte-moi si tu es toujours intéressé·e !
request.user.get_full_name(), request.user.email)
send_mail("BdA-Revente : %s" % spectacle.title, mail,
request.user.email,
- [revente.attribution.participant.user.email],
+ [revente.seller.user.email],
fail_silently=False)
return render(request, "bda-success.html",
- {"seller": revente.attribution.participant.user,
+ {"seller": revente.seller.user,
"spectacle": spectacle})
return render(request, "revente-confirm.html",
From de522a0035443ab93cdb93533b53c7b3f7c8b8bd Mon Sep 17 00:00:00 2001
From: Ludovic Stephan
Date: Mon, 5 Sep 2016 02:38:46 +0200
Subject: [PATCH 26/42] fixes + deprecated migration
---
bda/forms.py | 6 +++--
bda/migrations/0008_revente.py | 38 -------------------------------
bda/templates/liste-reventes.html | 2 +-
3 files changed, 5 insertions(+), 41 deletions(-)
delete mode 100644 bda/migrations/0008_revente.py
diff --git a/bda/forms.py b/bda/forms.py
index 0c886e0f..c2eec894 100644
--- a/bda/forms.py
+++ b/bda/forms.py
@@ -8,6 +8,7 @@ from datetime import timedelta
from django import forms
from django.forms.models import BaseInlineFormSet
+from django.db.models import Q
from django.utils import timezone
from bda.models import Attribution, Spectacle
@@ -67,8 +68,9 @@ class AnnulForm(forms.Form):
self.fields['attributions'].queryset = participant.attribution_set\
.filter(spectacle__date__gte=timezone.now(),
revente__isnull=False,
- revente__date__gte=timezone.now()-timedelta(hours=1),
- revente__seller=participant)
+ revente__date__gte=timezone.now()-timedelta(hours=1))\
+ .filter(Q(revente__soldTo__isnull=True) |
+ Q(revente__soldTo=participant))
class InscriptionReventeForm(forms.Form):
diff --git a/bda/migrations/0008_revente.py b/bda/migrations/0008_revente.py
deleted file mode 100644
index 4db2c9de..00000000
--- a/bda/migrations/0008_revente.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
-import django.utils.timezone
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('bda', '0007_extends_spectacle'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='SpectacleRevente',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('date', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Date de mise en vente')),
- ('attribution', models.OneToOneField(related_name='revente', to='bda.Attribution')),
- ],
- ),
- migrations.AddField(
- model_name='participant',
- name='choicesrevente',
- field=models.ManyToManyField(related_name='revente', to='bda.Spectacle', blank=True),
- ),
- migrations.AddField(
- model_name='spectaclerevente',
- name='interested',
- field=models.ManyToManyField(related_name='wanted', to='bda.Participant', blank=True),
- ),
- migrations.AddField(
- model_name='spectaclerevente',
- name='soldTo',
- field=models.ForeignKey(blank=True, to='bda.Participant', null=True),
- ),
- ]
diff --git a/bda/templates/liste-reventes.html b/bda/templates/liste-reventes.html
index 9e4acb92..1920256f 100644
--- a/bda/templates/liste-reventes.html
+++ b/bda/templates/liste-reventes.html
@@ -12,7 +12,7 @@
{% if shotgun %}
Places disponibles immédiatement
-
+
{% for spectacle in shotgun %}
- {{spectacle}}
{% endfor %}
From b6655047ed8791cbe467b2a2b5033b1ac42fab87 Mon Sep 17 00:00:00 2001
From: Ludovic Stephan
Date: Mon, 5 Sep 2016 03:10:06 +0200
Subject: [PATCH 27/42] verbose names
---
bda/admin.py | 11 ++++-------
bda/models.py | 9 +++++++--
2 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/bda/admin.py b/bda/admin.py
index b604d65b..37fdf9c7 100644
--- a/bda/admin.py
+++ b/bda/admin.py
@@ -216,16 +216,13 @@ class SpectacleReventeAdmin(admin.ModelAdmin):
def spectacle(self, obj):
return obj.attribution.spectacle
- def participant(self, obj):
- return obj.attribution.participant
-
- list_display = ("spectacle", "participant", "date", "soldTo")
+ list_display = ("spectacle", "seller", "date", "soldTo")
raw_id_fields = ("attribution",)
readonly_fields = ("shotgun", "expiration_time")
search_fields = ("spectacle__title",
- "participant__user__username",
- "participant__user__firstname",
- "participant__user__lastname",)
+ "seller__user__username",
+ "seller__user__firstname",
+ "seller__user__lastname",)
admin.site.register(CategorieSpectacle)
diff --git a/bda/models.py b/bda/models.py
index 428dbfb7..baed138e 100644
--- a/bda/models.py
+++ b/bda/models.py
@@ -222,8 +222,10 @@ class SpectacleRevente(models.Model):
related_name="wanted",
blank=True)
seller = models.ForeignKey(Participant,
- related_name="original_shows")
- soldTo = models.ForeignKey(Participant, blank=True, null=True)
+ related_name="original_shows",
+ verbose_name="Vendeur")
+ soldTo = models.ForeignKey(Participant, blank=True, null=True,
+ verbose_name="Vendue à")
def get_expiration_time(self):
remaining_time = (self.attribution.spectacle.date - self.date)
@@ -240,6 +242,9 @@ class SpectacleRevente(models.Model):
return "%s -- %s" % (self.seller,
self.attribution.spectacle.title)
+ class Meta:
+ verbose_name = "Revente"
+
def send_notif(self):
# On récupère la liste des inscrits
inscrits = self.attribution.spectacle.revente.select_related('user')
From f0553d709e6388211477f6afecf8d00f9fbce9bb Mon Sep 17 00:00:00 2001
From: Ludovic Stephan
Date: Mon, 5 Sep 2016 03:32:29 +0200
Subject: [PATCH 28/42] check lors de l'inscription pour des places en revente
---
bda/templates/liste-reventes.html | 3 +++
bda/views.py | 15 ++++++++++++++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/bda/templates/liste-reventes.html b/bda/templates/liste-reventes.html
index 1920256f..2a5ddc95 100644
--- a/bda/templates/liste-reventes.html
+++ b/bda/templates/liste-reventes.html
@@ -3,6 +3,9 @@
{% block realcontent %}
Inscriptions pour BDA-Revente
+ {% if deja_revente %}
+ Des reventes existent déjà pour certains de ces spectacles ; vérifie les places disponibles sans tirage !
+ {% endif %}