forked from DGNum/gestioCOF
Merge branch 'master' into Kerl/fix_32_do_tirage
This commit is contained in:
commit
87da29ee59
12 changed files with 246 additions and 83 deletions
32
bda/admin.py
32
bda/admin.py
|
@ -20,10 +20,25 @@ class ChoixSpectacleInline(admin.TabularInline):
|
||||||
|
|
||||||
class AttributionInline(admin.TabularInline):
|
class AttributionInline(admin.TabularInline):
|
||||||
model = Attribution
|
model = Attribution
|
||||||
|
extra = 0
|
||||||
|
|
||||||
|
def get_queryset(self, request):
|
||||||
|
qs = super(AttributionInline, self).get_queryset(request)
|
||||||
|
return qs.filter(spectacle__listing=False)
|
||||||
|
|
||||||
|
|
||||||
|
class AttributionInlineListing(admin.TabularInline):
|
||||||
|
model = Attribution
|
||||||
|
exclude = ('given', )
|
||||||
|
extra = 0
|
||||||
|
|
||||||
|
def get_queryset(self, request):
|
||||||
|
qs = super(AttributionInlineListing, self).get_queryset(request)
|
||||||
|
return qs.filter(spectacle__listing=True)
|
||||||
|
|
||||||
|
|
||||||
class ParticipantAdmin(admin.ModelAdmin):
|
class ParticipantAdmin(admin.ModelAdmin):
|
||||||
inlines = [AttributionInline]
|
inlines = [AttributionInline, AttributionInlineListing]
|
||||||
|
|
||||||
def get_queryset(self, request):
|
def get_queryset(self, request):
|
||||||
return Participant.objects.annotate(nb_places=Count('attributions'),
|
return Participant.objects.annotate(nb_places=Count('attributions'),
|
||||||
|
@ -159,14 +174,17 @@ class ChoixSpectacleAdmin(admin.ModelAdmin):
|
||||||
list_filter = ("double_choice", "participant__tirage")
|
list_filter = ("double_choice", "participant__tirage")
|
||||||
search_fields = ('participant__user__username',
|
search_fields = ('participant__user__username',
|
||||||
'participant__user__first_name',
|
'participant__user__first_name',
|
||||||
'participant__user__last_name')
|
'participant__user__last_name',
|
||||||
|
'spectacle__title')
|
||||||
|
|
||||||
|
|
||||||
class SpectacleAdmin(admin.ModelAdmin):
|
class SpectacleAdmin(admin.ModelAdmin):
|
||||||
model = Spectacle
|
model = Spectacle
|
||||||
list_display = ("title", "date", "tirage", "location", "slots", "price")
|
list_display = ("title", "date", "tirage", "location", "slots", "price",
|
||||||
|
"listing")
|
||||||
list_filter = ("location", "tirage",)
|
list_filter = ("location", "tirage",)
|
||||||
search_fields = ("title", "location__name")
|
search_fields = ("title", "location__name")
|
||||||
|
readonly_fields = ("rappel_sent", )
|
||||||
|
|
||||||
|
|
||||||
class TirageAdmin(admin.ModelAdmin):
|
class TirageAdmin(admin.ModelAdmin):
|
||||||
|
@ -177,8 +195,14 @@ class TirageAdmin(admin.ModelAdmin):
|
||||||
list_filter = ("active", )
|
list_filter = ("active", )
|
||||||
search_fields = ("title", )
|
search_fields = ("title", )
|
||||||
|
|
||||||
|
|
||||||
|
class SalleAdmin(admin.ModelAdmin):
|
||||||
|
model = Salle
|
||||||
|
search_fields = ('name', 'address')
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Spectacle, SpectacleAdmin)
|
admin.site.register(Spectacle, SpectacleAdmin)
|
||||||
admin.site.register(Salle)
|
admin.site.register(Salle, SalleAdmin)
|
||||||
admin.site.register(Participant, ParticipantAdmin)
|
admin.site.register(Participant, ParticipantAdmin)
|
||||||
admin.site.register(Attribution, AttributionAdmin)
|
admin.site.register(Attribution, AttributionAdmin)
|
||||||
admin.site.register(ChoixSpectacle, ChoixSpectacleAdmin)
|
admin.site.register(ChoixSpectacle, ChoixSpectacleAdmin)
|
||||||
|
|
25
bda/migrations/0004_mails-rappel.py
Normal file
25
bda/migrations/0004_mails-rappel.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('bda', '0003_update_tirage_and_spectacle'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='spectacle',
|
||||||
|
name='listing',
|
||||||
|
field=models.BooleanField(default=False, verbose_name=b'Les places sont sur listing'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='spectacle',
|
||||||
|
name='rappel_sent',
|
||||||
|
field=models.DateTimeField(null=True, verbose_name=b'Mail de rappel envoy\xc3\xa9', blank=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -4,7 +4,16 @@ import calendar
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.template import loader, Context
|
||||||
|
from django.core import mail
|
||||||
|
from django.conf import settings
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
|
||||||
|
def render_template(template_name, data):
|
||||||
|
tmpl = loader.get_template(template_name)
|
||||||
|
ctxt = Context(data)
|
||||||
|
return tmpl.render(ctxt)
|
||||||
|
|
||||||
|
|
||||||
class Tirage(models.Model):
|
class Tirage(models.Model):
|
||||||
|
@ -41,6 +50,9 @@ class Spectacle(models.Model):
|
||||||
slots = models.IntegerField("Places")
|
slots = models.IntegerField("Places")
|
||||||
priority = models.IntegerField("Priorité", default=1000)
|
priority = models.IntegerField("Priorité", default=1000)
|
||||||
tirage = models.ForeignKey(Tirage)
|
tirage = models.ForeignKey(Tirage)
|
||||||
|
listing = models.BooleanField("Les places sont sur listing")
|
||||||
|
rappel_sent = models.DateTimeField("Mail de rappel envoyé", blank=True,
|
||||||
|
null=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = "Spectacle"
|
verbose_name = "Spectacle"
|
||||||
|
@ -59,6 +71,38 @@ class Spectacle(models.Model):
|
||||||
return u"%s - %s, %s, %.02f€" % (self.title, self.date_no_seconds(),
|
return u"%s - %s, %s, %.02f€" % (self.title, self.date_no_seconds(),
|
||||||
self.location, self.price)
|
self.location, self.price)
|
||||||
|
|
||||||
|
def send_rappel(self):
|
||||||
|
# On récupère la liste des participants
|
||||||
|
members = {}
|
||||||
|
for attr in Attribution.objects.filter(spectacle=self).all():
|
||||||
|
member = attr.participant.user
|
||||||
|
if member.id in members:
|
||||||
|
members[member.id].nb_attr = 2
|
||||||
|
else:
|
||||||
|
member.nb_attr = 1
|
||||||
|
members[member.id] = member
|
||||||
|
# On écrit un mail personnalisé à chaque participant
|
||||||
|
mails_to_send = []
|
||||||
|
mail_object = "%s - %s - %s" % (self.title, self.date_no_seconds(),
|
||||||
|
self.location)
|
||||||
|
for member in members.values():
|
||||||
|
mail_body = render_template('mail-rappel.txt', {
|
||||||
|
'member': member,
|
||||||
|
'show': self})
|
||||||
|
mail_tot = mail.EmailMessage(
|
||||||
|
mail_object, mail_body,
|
||||||
|
settings.RAPPEL_FROM, [member.email],
|
||||||
|
[], headers={'Reply-To': settings.RAPPEL_REPLY_TO})
|
||||||
|
mails_to_send.append(mail_tot)
|
||||||
|
# On envoie les mails
|
||||||
|
connection = mail.get_connection()
|
||||||
|
connection.send_messages(mails_to_send)
|
||||||
|
# On enregistre le fait que l'envoi a bien eu lieu
|
||||||
|
self.rappel_sent = timezone.now()
|
||||||
|
self.save()
|
||||||
|
# On renvoie la liste des destinataires
|
||||||
|
return members.values()
|
||||||
|
|
||||||
PAYMENT_TYPES = (
|
PAYMENT_TYPES = (
|
||||||
("cash", u"Cash"),
|
("cash", u"Cash"),
|
||||||
("cb", "CB"),
|
("cb", "CB"),
|
||||||
|
|
23
bda/templates/mail-rappel.txt
Normal file
23
bda/templates/mail-rappel.txt
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
Bonjour {{ member.get_full_name }},
|
||||||
|
|
||||||
|
Nous te rappellons que tu as eu la chance d'obtenir {{ member.nb_attr|pluralize:"une place,deux places" }}
|
||||||
|
pour {{ show.title }}, le {{ show.date_no_seconds }} au {{ show.location }}. N'oublie pas de t'y rendre !
|
||||||
|
{% if member.nb_attr == 2 %}
|
||||||
|
Tu as obtenu deux places pour ce spectacle. Nous te rappelons que
|
||||||
|
ces places sont strictement réservées aux personnes de moins de 28 ans.
|
||||||
|
{% endif %}
|
||||||
|
{% if show.listing %}Pour ce spectacle, tu as reçu des places sur
|
||||||
|
listing. Il te faudra donc te rendre 15 minutes en avance sur les lieux de la représentation
|
||||||
|
pour retirer {{ member.nb_attr|pluralize:"ta place,tes places" }}.
|
||||||
|
{% else %}Pour assister à ce spectacle, tu dois présenter les billets qui ont
|
||||||
|
été distribués au burô.
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
Si tu ne peux plus assister à cette représentation, tu peux
|
||||||
|
revendre ta place via BdA-revente, accessible directement sur
|
||||||
|
GestioCOF (lien "revendre une place du premier tirage" sur la page
|
||||||
|
d'accueil https://www.cof.ens.fr/gestion/).
|
||||||
|
|
||||||
|
En te souhaitant un excellent spectacle,
|
||||||
|
|
||||||
|
Le Bureau des Arts
|
35
bda/templates/mails-rappel.html
Normal file
35
bda/templates/mails-rappel.html
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
{% extends "base_title.html" %}
|
||||||
|
|
||||||
|
{% block realcontent %}
|
||||||
|
{% if sent %}
|
||||||
|
<h3>Les mails de rappel pour le spectacle {{ show.title }} ont bien été envoyés aux personnes suivantes</h3>
|
||||||
|
<ul>
|
||||||
|
{% for member in members %}
|
||||||
|
<li>{{ member.get_full_name }} ({{ member.email }})</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<h3>Voulez vous envoyer les mails de rappel pour le spectacle
|
||||||
|
{{ show.title }} ?</h3>
|
||||||
|
{% if show.rappel_sent %}
|
||||||
|
<p class="error">Attention, les mails ont déjà été envoyés le
|
||||||
|
{{ show.rappel_sent }}</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if not sent %}
|
||||||
|
<form action="" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<br />
|
||||||
|
<input type="submit" value="Envoyer" />
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h3>Forme des mails</h3>
|
||||||
|
|
||||||
|
<br />Une seule place<br /><br />
|
||||||
|
<pre>{{ exemple_mail_1place }}</pre>
|
||||||
|
|
||||||
|
<br />Deux places<br /><br />
|
||||||
|
<pre>{{ exemple_mail_2places }}</pre>
|
||||||
|
{% endblock %}
|
21
bda/urls.py
21
bda/urls.py
|
@ -5,32 +5,33 @@ from bda.views import SpectacleListView
|
||||||
|
|
||||||
urlpatterns = patterns(
|
urlpatterns = patterns(
|
||||||
'',
|
'',
|
||||||
url(r'inscription/(?P<tirage_id>\d+)$',
|
url(r'^inscription/(?P<tirage_id>\d+)$',
|
||||||
'bda.views.inscription',
|
'bda.views.inscription',
|
||||||
name='bda-tirage-inscription'),
|
name='bda-tirage-inscription'),
|
||||||
url(r'places/(?P<tirage_id>\d+)$',
|
url(r'^places/(?P<tirage_id>\d+)$',
|
||||||
'bda.views.places',
|
'bda.views.places',
|
||||||
name="bda-places-attribuees"),
|
name="bda-places-attribuees"),
|
||||||
url(r'places/(?P<tirage_id>\d+)/places_bda.ics$',
|
url(r'^places/(?P<tirage_id>\d+)/places_bda.ics$',
|
||||||
'bda.views.places_ics',
|
'bda.views.places_ics',
|
||||||
name="bda-places-attribuees-ics"),
|
name="bda-places-attribuees-ics"),
|
||||||
url(r'revente/(?P<tirage_id>\d+)$',
|
url(r'^revente/(?P<tirage_id>\d+)$',
|
||||||
'bda.views.revente',
|
'bda.views.revente',
|
||||||
name='bda-revente'),
|
name='bda-revente'),
|
||||||
url(r'etat-places/(?P<tirage_id>\d+)$',
|
url(r'^etat-places/(?P<tirage_id>\d+)$',
|
||||||
'bda.views.etat_places',
|
'bda.views.etat_places',
|
||||||
name='bda-etat-places'),
|
name='bda-etat-places'),
|
||||||
url(r'tirage/(?P<tirage_id>\d+)$', 'bda.views.tirage'),
|
url(r'^tirage/(?P<tirage_id>\d+)$', 'bda.views.tirage'),
|
||||||
url(r'spectacles/(?P<tirage_id>\d+)$',
|
url(r'^spectacles/(?P<tirage_id>\d+)$',
|
||||||
SpectacleListView.as_view(),
|
SpectacleListView.as_view(),
|
||||||
name="bda-liste-spectacles"),
|
name="bda-liste-spectacles"),
|
||||||
url(r'spectacles/(?P<tirage_id>\d+)/(?P<spectacle_id>\d+)$',
|
url(r'^spectacles/(?P<tirage_id>\d+)/(?P<spectacle_id>\d+)$',
|
||||||
"bda.views.spectacle",
|
"bda.views.spectacle",
|
||||||
name="bda-spectacle"),
|
name="bda-spectacle"),
|
||||||
url(r'spectacles-ics/(?P<tirage_id>\d+)$',
|
url(r'^spectacles-ics/(?P<tirage_id>\d+)$',
|
||||||
'bda.views.liste_spectacles_ics',
|
'bda.views.liste_spectacles_ics',
|
||||||
name="bda-liste-spectacles-ics"),
|
name="bda-liste-spectacles-ics"),
|
||||||
url(r'spectacles/unpaid/(?P<tirage_id>\d+)$',
|
url(r'^spectacles/unpaid/(?P<tirage_id>\d+)$',
|
||||||
"bda.views.unpaid",
|
"bda.views.unpaid",
|
||||||
name="bda-unpaid"),
|
name="bda-unpaid"),
|
||||||
|
url(r'^mails-rappel/(?P<spectacle_id>\d+)$', "bda.views.send_rappel"),
|
||||||
)
|
)
|
||||||
|
|
30
bda/views.py
30
bda/views.py
|
@ -19,7 +19,7 @@ import time
|
||||||
|
|
||||||
from gestioncof.decorators import cof_required, buro_required
|
from gestioncof.decorators import cof_required, buro_required
|
||||||
from bda.models import Spectacle, Participant, ChoixSpectacle, Attribution,\
|
from bda.models import Spectacle, Participant, ChoixSpectacle, Attribution,\
|
||||||
Tirage
|
Tirage, render_template
|
||||||
from bda.algorithm import Algorithm
|
from bda.algorithm import Algorithm
|
||||||
|
|
||||||
from bda.forms import BaseBdaFormSet, TokenForm, ResellForm
|
from bda.forms import BaseBdaFormSet, TokenForm, ResellForm
|
||||||
|
@ -371,3 +371,31 @@ def liste_spectacles_ics(request, tirage_id):
|
||||||
return render(request, "liste_spectacles.ics",
|
return render(request, "liste_spectacles.ics",
|
||||||
{"spectacles": spectacles, "tirage": tirage},
|
{"spectacles": spectacles, "tirage": tirage},
|
||||||
content_type="text/calendar")
|
content_type="text/calendar")
|
||||||
|
|
||||||
|
|
||||||
|
@buro_required
|
||||||
|
def send_rappel(request, spectacle_id):
|
||||||
|
show = get_object_or_404(Spectacle, id=spectacle_id)
|
||||||
|
# Mails d'exemples
|
||||||
|
fake_member = request.user
|
||||||
|
fake_member.nb_attr = 1
|
||||||
|
exemple_mail_1place = render_template('mail-rappel.txt', {
|
||||||
|
'member': fake_member,
|
||||||
|
'show': show})
|
||||||
|
fake_member.nb_attr = 2
|
||||||
|
exemple_mail_2places = render_template('mail-rappel.txt', {
|
||||||
|
'member': fake_member,
|
||||||
|
'show': show})
|
||||||
|
# Contexte
|
||||||
|
ctxt = {'show': show,
|
||||||
|
'exemple_mail_1place': exemple_mail_1place,
|
||||||
|
'exemple_mail_2places': exemple_mail_2places}
|
||||||
|
# Envoi confirmé
|
||||||
|
if request.method == 'POST':
|
||||||
|
members = show.send_rappel()
|
||||||
|
ctxt['sent'] = True
|
||||||
|
ctxt['members'] = members
|
||||||
|
# Demande de confirmation
|
||||||
|
else:
|
||||||
|
ctxt['sent'] = False
|
||||||
|
return render(request, "mails-rappel.html", ctxt)
|
||||||
|
|
|
@ -136,6 +136,9 @@ PETITS_COURS_FROM = "Le COF <cof@ens.fr>"
|
||||||
PETITS_COURS_BCC = "archivescof@gmail.com"
|
PETITS_COURS_BCC = "archivescof@gmail.com"
|
||||||
PETITS_COURS_REPLYTO = "cof@ens.fr"
|
PETITS_COURS_REPLYTO = "cof@ens.fr"
|
||||||
|
|
||||||
|
RAPPEL_FROM = 'Le BdA <bda@ens.fr>'
|
||||||
|
RAPPEL_REPLY_TO = RAPPEL_FROM
|
||||||
|
|
||||||
LOGIN_URL = "/login"
|
LOGIN_URL = "/login"
|
||||||
LOGIN_REDIRECT_URL = "/"
|
LOGIN_REDIRECT_URL = "/"
|
||||||
|
|
||||||
|
|
|
@ -46,12 +46,14 @@ class SurveyQuestionInline(admin.TabularInline):
|
||||||
|
|
||||||
|
|
||||||
class SurveyQuestionAdmin(admin.ModelAdmin):
|
class SurveyQuestionAdmin(admin.ModelAdmin):
|
||||||
|
search_fields = ('survey__title', 'answer')
|
||||||
inlines = [
|
inlines = [
|
||||||
SurveyQuestionAnswerInline,
|
SurveyQuestionAnswerInline,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class SurveyAdmin(admin.ModelAdmin):
|
class SurveyAdmin(admin.ModelAdmin):
|
||||||
|
search_fields = ('title', 'details')
|
||||||
inlines = [
|
inlines = [
|
||||||
SurveyQuestionInline,
|
SurveyQuestionInline,
|
||||||
]
|
]
|
||||||
|
@ -72,12 +74,14 @@ class EventCommentFieldInline(admin.TabularInline):
|
||||||
|
|
||||||
|
|
||||||
class EventOptionAdmin(admin.ModelAdmin):
|
class EventOptionAdmin(admin.ModelAdmin):
|
||||||
|
search_fields = ('event__title', 'name')
|
||||||
inlines = [
|
inlines = [
|
||||||
EventOptionChoiceInline,
|
EventOptionChoiceInline,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class EventAdmin(admin.ModelAdmin):
|
class EventAdmin(admin.ModelAdmin):
|
||||||
|
search_fields = ('title', 'location', 'description')
|
||||||
inlines = [
|
inlines = [
|
||||||
EventOptionInline,
|
EventOptionInline,
|
||||||
EventCommentFieldInline,
|
EventCommentFieldInline,
|
||||||
|
@ -189,6 +193,7 @@ class PetitCoursAbilityAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
class PetitCoursAttributionAdmin(admin.ModelAdmin):
|
class PetitCoursAttributionAdmin(admin.ModelAdmin):
|
||||||
list_display = ('user', 'demande', 'matiere', 'rank', )
|
list_display = ('user', 'demande', 'matiere', 'rank', )
|
||||||
|
search_fields = ('user__username', 'matiere__name')
|
||||||
|
|
||||||
|
|
||||||
class PetitCoursAttributionCounterAdmin(admin.ModelAdmin):
|
class PetitCoursAttributionCounterAdmin(admin.ModelAdmin):
|
||||||
|
@ -208,6 +213,11 @@ class PetitCoursDemandeAdmin(admin.ModelAdmin):
|
||||||
list_display = ('name', 'email', 'agrege_requis', 'niveau', 'created',
|
list_display = ('name', 'email', 'agrege_requis', 'niveau', 'created',
|
||||||
'traitee', 'processed')
|
'traitee', 'processed')
|
||||||
list_filter = ('traitee', 'niveau')
|
list_filter = ('traitee', 'niveau')
|
||||||
|
search_fields = ('name', 'email', 'phone', 'lieu', 'remarques')
|
||||||
|
|
||||||
|
|
||||||
|
class CustomMailAdmin(admin.ModelAdmin):
|
||||||
|
search_fields = ('shortname', 'title')
|
||||||
|
|
||||||
admin.site.register(Survey, SurveyAdmin)
|
admin.site.register(Survey, SurveyAdmin)
|
||||||
admin.site.register(SurveyQuestion, SurveyQuestionAdmin)
|
admin.site.register(SurveyQuestion, SurveyQuestionAdmin)
|
||||||
|
|
34
gestioncof/migrations/0004_registration_mail.py
Normal file
34
gestioncof/migrations/0004_registration_mail.py
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
def create_mail(apps, schema_editor):
|
||||||
|
CustomMail = apps.get_model("gestioncof", "CustomMail")
|
||||||
|
db_alias = schema_editor.connection.alias
|
||||||
|
if CustomMail.objects.filter(shortname="bienvenue").count() == 0:
|
||||||
|
CustomMail.objects.using(db_alias).bulk_create([
|
||||||
|
CustomMail(
|
||||||
|
shortname="bienvenue",
|
||||||
|
title="Bienvenue au COF",
|
||||||
|
content="Mail de bienvenue au COF, envoyé automatiquement à " \
|
||||||
|
+ "l'inscription.\n\n" \
|
||||||
|
+ "Les balises {{ ... }} sont interprétées comme expliqué " \
|
||||||
|
+ "ci-dessous à l'envoi.",
|
||||||
|
comments="{{ nom }} \t fullname de la personne.\n"\
|
||||||
|
+ "{{ prenom }} \t prénom de la personne.")
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('gestioncof', '0003_event_image'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
# Pas besoin de supprimer le mail lors de la migration dans l'autre
|
||||||
|
# sens.
|
||||||
|
migrations.RunPython(create_mail, migrations.RunPython.noop),
|
||||||
|
]
|
|
@ -94,7 +94,8 @@ class CustomMail(models.Model):
|
||||||
blank=True)
|
blank=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = "Mails personnalisables"
|
verbose_name = "Mail personnalisable"
|
||||||
|
verbose_name_plural = "Mails personnalisables"
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s: %s" % (self.shortname, self.title)
|
return u"%s: %s" % (self.shortname, self.title)
|
||||||
|
@ -158,6 +159,7 @@ class EventOptionChoice(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = "Choix"
|
verbose_name = "Choix"
|
||||||
|
verbose_name_plural = "Choix"
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return unicode(self.value)
|
return unicode(self.value)
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# coding: utf-8
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cof.settings")
|
|
||||||
from django.conf import settings
|
|
||||||
settings.DEBUG = True
|
|
||||||
from bda.models import Spectacle, Participant, ChoixSpectacle
|
|
||||||
from bda.algorithm import Algorithm
|
|
||||||
from django.db.models import Sum
|
|
||||||
from django.db import connection
|
|
||||||
start = time.time()
|
|
||||||
shows = Spectacle.objects.all()
|
|
||||||
members = Participant.objects.all()
|
|
||||||
choices = ChoixSpectacle.objects.order_by('participant', 'priority') \
|
|
||||||
.select_related().all()
|
|
||||||
available_slots = Spectacle.objects.aggregate(Sum('slots'))['slots__sum']
|
|
||||||
cursor = connection.cursor()
|
|
||||||
cursor.execute(
|
|
||||||
"SELECT SUM(`slots` * `price`) AS `total` FROM `bda_spectacle`;")
|
|
||||||
total_price = cursor.fetchone()[0]
|
|
||||||
print "%d spectacles" % len(shows)
|
|
||||||
print "%d places" % available_slots
|
|
||||||
print "%d participants" % len(members)
|
|
||||||
print "%d demandes" % len(choices)
|
|
||||||
print "%d places demandées" % (len(choices)
|
|
||||||
+ len(choices.filter(double=True).all()))
|
|
||||||
print "%.02f€ à brasser" % total_price
|
|
||||||
print "Récupération: %.2fs" % (time.time() - start)
|
|
||||||
start_init = time.time()
|
|
||||||
algo = Algorithm(shows, members, choices)
|
|
||||||
print "Initialisation: %.2fs" % (time.time() - start_init)
|
|
||||||
start_algo = time.time()
|
|
||||||
results = algo(sys.argv[1])
|
|
||||||
print "Traitement: %.2fs" % (time.time() - start_algo)
|
|
||||||
print len(connection.queries), "requêtes SQL effectuées"
|
|
||||||
queries = list(connection.queries)
|
|
||||||
total_slots = 0
|
|
||||||
total_losers = 0
|
|
||||||
for (_, members, losers) in results:
|
|
||||||
total_slots += len(members)
|
|
||||||
total_losers += len(losers)
|
|
||||||
print "Placés %d\nDécus %d" % (total_slots, total_losers)
|
|
||||||
print "Total %d" % (total_slots + total_losers)
|
|
||||||
members2 = {}
|
|
||||||
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
|
|
||||||
if len(members) < show.slots:
|
|
||||||
print "%d place(s) invendue(s) pour %s" \
|
|
||||||
% (show.slots - len(members), show)
|
|
||||||
members2 = members2.items()
|
|
||||||
print "Temps total: %.2fs" % (time.time() - start)
|
|
||||||
print "Requêtes SQL:"
|
|
||||||
for query in queries:
|
|
||||||
print query['sql']
|
|
Loading…
Reference in a new issue