Merge branch 'supportBDS' of git.eleves.ens.fr:cof-geek/gestioCOF into supportBDS

This commit is contained in:
Qwann 2017-02-23 19:00:58 +01:00
commit 9c6f5533ec
54 changed files with 691 additions and 422 deletions

View file

@ -1,19 +1,16 @@
# -*- coding: utf-8 -*-
from django import forms
from django.contrib import admin
from django.core.urlresolvers import reverse
from django.utils.safestring import mark_safe
import django.utils.six as six
import autocomplete_light
from .petits_cours_models import PetitCoursDemande, \
PetitCoursSubject, PetitCoursAbility, PetitCoursAttribution, \
PetitCoursAttributionCounter
from .models import (
SurveyQuestionAnswer, SurveyQuestion, CofProfile, EventOption,
EventOptionChoice, Event, Club, EventCommentField, EventRegistration,
EventOptionChoice, Event, EventCommentField, EventRegistration,
Survey
)
@ -95,7 +92,6 @@ class EventAdmin(admin.ModelAdmin):
class EventRegistrationAdmin(admin.ModelAdmin):
form = autocomplete_light.modelform_factory(EventRegistration, exclude=[])
list_display = ('__unicode__' if six.PY2 else '__str__', 'event', 'user',
'paid')
list_filter = ('paid',)
@ -135,30 +131,11 @@ class PetitCoursDemandeAdmin(admin.ModelAdmin):
search_fields = ('name', 'email', 'phone', 'lieu', 'remarques')
class ClubAdminForm(forms.ModelForm):
def clean(self):
cleaned_data = super(ClubAdminForm, self).clean()
respos = cleaned_data.get('respos')
members = cleaned_data.get('membres')
for respo in respos.all():
if respo not in members:
raise forms.ValidationError(
"Erreur : le respo %s n'est pas membre du club."
% respo.get_full_name())
return cleaned_data
class ClubAdmin(admin.ModelAdmin):
list_display = ['name']
form = ClubAdminForm
admin.site.register(Survey, SurveyAdmin)
admin.site.register(SurveyQuestion, SurveyQuestionAdmin)
admin.site.register(Event, EventAdmin)
admin.site.register(EventOption, EventOptionAdmin)
admin.site.register(CofProfile)
admin.site.register(Club, ClubAdmin)
admin.site.register(PetitCoursSubject)
admin.site.register(PetitCoursAbility, PetitCoursAbilityAdmin)
admin.site.register(PetitCoursAttribution, PetitCoursAttributionAdmin)

6
cof/apps.py Normal file
View file

@ -0,0 +1,6 @@
from django.apps import AppConfig
class COFConfig(AppConfig):
name = "cof"
verbose_name = "Application de gestion du COF"

View file

@ -1,10 +0,0 @@
# -*- coding: utf-8 -*-
import autocomplete_light
from django.contrib.auth.models import User
autocomplete_light.register(
User, search_fields=('username', 'first_name', 'last_name'),
attrs={'placeholder': 'membre...'}
)

View file

@ -12,8 +12,7 @@ from django.forms.formsets import BaseFormSet, formset_factory
from django.db.models import Max
from django.core.validators import MinLengthValidator
from .models import CofProfile, EventCommentValue, \
CalendarSubscription, Club
from .models import CofProfile, EventCommentValue, CalendarSubscription
from .widgets import TriStateCheckbox
from gestion.models import Profile
@ -362,14 +361,3 @@ class CalendarForm(forms.ModelForm):
model = CalendarSubscription
fields = ['subscribe_to_events', 'subscribe_to_my_shows',
'other_shows']
class ClubsForm(forms.Form):
"""
Formulaire d'inscription d'un membre à plusieurs clubs du COF.
"""
clubs = forms.ModelMultipleChoiceField(
label="Inscriptions aux clubs du COF",
queryset=Club.objects.all(),
widget=forms.CheckboxSelectMultiple,
required=False)

View file

@ -48,7 +48,10 @@ class Migration(migrations.Migration):
('is_buro', models.BooleanField(default=False, verbose_name=b'Membre du Bur\xc3\xb4')),
('petits_cours_accept', models.BooleanField(default=False, verbose_name=b'Recevoir des petits cours')),
('petits_cours_remarques', models.TextField(default=b'', verbose_name='Remarques et pr\xe9cisions pour les petits cours', blank=True)),
('user', models.OneToOneField(related_name='profile', to=settings.AUTH_USER_MODEL)),
('user', models.OneToOneField(
related_name='profile',
on_delete=models.CASCADE,
to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Profil COF',
@ -91,7 +94,10 @@ class Migration(migrations.Migration):
('name', models.CharField(max_length=200, verbose_name=b'Champ')),
('fieldtype', models.CharField(default=b'text', max_length=10, verbose_name=b'Type', choices=[(b'text', 'Texte long'), (b'char', 'Texte court')])),
('default', models.TextField(verbose_name=b'Valeur par d\xc3\xa9faut', blank=True)),
('event', models.ForeignKey(related_name='commentfields', to='cof.Event')),
('event', models.ForeignKey(
related_name='commentfields',
on_delete=models.CASCADE,
to='cof.Event')),
],
options={
'verbose_name': 'Champ',
@ -102,7 +108,10 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('content', models.TextField(null=True, verbose_name=b'Contenu', blank=True)),
('commentfield', models.ForeignKey(related_name='values', to='cof.EventCommentField')),
('commentfield', models.ForeignKey(
related_name='values',
on_delete=models.CASCADE,
to='cof.EventCommentField')),
],
),
migrations.CreateModel(
@ -111,7 +120,10 @@ class Migration(migrations.Migration):
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(max_length=200, verbose_name=b'Option')),
('multi_choices', models.BooleanField(default=False, verbose_name=b'Choix multiples')),
('event', models.ForeignKey(related_name='options', to='cof.Event')),
('event', models.ForeignKey(
related_name='options',
on_delete=models.CASCADE,
to='cof.Event')),
],
options={
'verbose_name': 'Option',
@ -122,7 +134,10 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('value', models.CharField(max_length=200, verbose_name=b'Valeur')),
('event_option', models.ForeignKey(related_name='choices', to='cof.EventOption')),
('event_option', models.ForeignKey(
related_name='choices',
on_delete=models.CASCADE,
to='cof.EventOption')),
],
options={
'verbose_name': 'Choix',
@ -133,10 +148,14 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('paid', models.BooleanField(default=False, verbose_name=b'A pay\xc3\xa9')),
('event', models.ForeignKey(to='cof.Event')),
('event', models.ForeignKey(
on_delete=models.CASCADE,
to='cof.Event')),
('filledcomments', models.ManyToManyField(to='cof.EventCommentField', through='cof.EventCommentValue')),
('options', models.ManyToManyField(to='cof.EventOptionChoice')),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
('user', models.ForeignKey(
on_delete=models.CASCADE,
to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Inscription',
@ -240,7 +259,10 @@ class Migration(migrations.Migration):
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('question', models.CharField(max_length=200, verbose_name=b'Question')),
('multi_answers', models.BooleanField(default=False, verbose_name=b'Choix multiples')),
('survey', models.ForeignKey(related_name='questions', to='cof.Survey')),
('survey', models.ForeignKey(
on_delete=models.CASCADE,
related_name='questions',
to='cof.Survey')),
],
options={
'verbose_name': 'Question',
@ -251,7 +273,10 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('answer', models.CharField(max_length=200, verbose_name=b'R\xc3\xa9ponse')),
('survey_question', models.ForeignKey(related_name='answers', to='cof.SurveyQuestion')),
('survey_question', models.ForeignKey(
related_name='answers',
on_delete=models.CASCADE,
to='cof.SurveyQuestion')),
],
options={
'verbose_name': 'R\xe9ponse',
@ -265,12 +290,16 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='surveyanswer',
name='survey',
field=models.ForeignKey(to='cof.Survey'),
field=models.ForeignKey(
on_delete=models.CASCADE,
to='cof.Survey'),
),
migrations.AddField(
model_name='surveyanswer',
name='user',
field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
field=models.ForeignKey(
on_delete=models.CASCADE,
to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='petitcoursdemande',
@ -280,47 +309,72 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='petitcoursdemande',
name='traitee_par',
field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, null=True),
field=models.ForeignKey(
on_delete=models.PROTECT,
blank=True,
to=settings.AUTH_USER_MODEL,
null=True),
),
migrations.AddField(
model_name='petitcoursattributioncounter',
name='matiere',
field=models.ForeignKey(verbose_name='Matiere', to='cof.PetitCoursSubject'),
field=models.ForeignKey(
on_delete=models.PROTECT,
verbose_name='Matiere',
to='cof.PetitCoursSubject'),
),
migrations.AddField(
model_name='petitcoursattributioncounter',
name='user',
field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
field=models.ForeignKey(
on_delete=models.PROTECT,
to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='petitcoursattribution',
name='demande',
field=models.ForeignKey(verbose_name='Demande', to='cof.PetitCoursDemande'),
field=models.ForeignKey(
on_delete=models.CASCADE,
verbose_name='Demande',
to='cof.PetitCoursDemande'),
),
migrations.AddField(
model_name='petitcoursattribution',
name='matiere',
field=models.ForeignKey(verbose_name='Mati\xe8re', to='cof.PetitCoursSubject'),
field=models.ForeignKey(
on_delete=models.PROTECT,
verbose_name='Mati\xe8re',
to='cof.PetitCoursSubject'),
),
migrations.AddField(
model_name='petitcoursattribution',
name='user',
field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
field=models.ForeignKey(
on_delete=models.CASCADE,
to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='petitcoursability',
name='matiere',
field=models.ForeignKey(verbose_name='Mati\xe8re', to='cof.PetitCoursSubject'),
field=models.ForeignKey(
on_delete=models.CASCADE,
verbose_name='Mati\xe8re',
to='cof.PetitCoursSubject'),
),
migrations.AddField(
model_name='petitcoursability',
name='user',
field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
field=models.ForeignKey(
on_delete=models.CASCADE,
to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='eventcommentvalue',
name='registration',
field=models.ForeignKey(related_name='comments', to='cof.EventRegistration'),
field=models.ForeignKey(
on_delete=models.CASCADE,
related_name='comments',
to='cof.EventRegistration'),
),
migrations.AlterUniqueTogether(
name='surveyanswer',

View file

@ -23,7 +23,9 @@ class Migration(migrations.Migration):
('subscribe_to_events', models.BooleanField(default=True)),
('subscribe_to_my_shows', models.BooleanField(default=True)),
('other_shows', models.ManyToManyField(to='bda.Spectacle')),
('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)),
('user', models.OneToOneField(
on_delete=models.CASCADE,
to=settings.AUTH_USER_MODEL)),
],
),
migrations.AlterModelOptions(

View file

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib.auth.models import Group, Permission
from django.contrib.auth.models import Group
from django.db import migrations, models
@ -23,23 +23,23 @@ def create_profile(apps, schema_editor):
def preserve_perms(apps, schema_editor):
from django.contrib.auth.management import create_permissions
# from django.contrib.auth.management import create_permissions
apps.models_module = True
create_permissions(apps, verbosity=0)
apps.models_module = None
# apps.models_module = True
# create_permissions(apps, verbosity=0)
# apps.models_module = None
CofProfile = apps.get_model("cof", "CofProfile")
memberp = Permission.objects.get(codename='member')
burop = Permission.objects.get(codename='buro')
# memberp = Permission.objects.get(codename='member')
# burop = Permission.objects.get(codename='buro')
# creates the groups for COF members and
member = Group.objects.create(name='cof_members')
buro = Group.objects.create(name='cof_buro')
# associate permissions to the respective groups.
buro.permissions = [burop, memberp]
member.permissions = [memberp]
# buro.permissions = [burop, memberp]
# member.permissions = [memberp]
for cofp in CofProfile.objects.filter(is_cof=True):
cofp.profile.user.groups.add(member)
@ -70,6 +70,7 @@ class Migration(migrations.Migration):
model_name='cofprofile',
name='profile',
field=models.OneToOneField(
on_delete=models.CASCADE,
to='gestion.Profile',
null=True,
related_name='cof'
@ -89,6 +90,7 @@ class Migration(migrations.Migration):
model_name='cofprofile',
name='profile',
field=models.OneToOneField(
on_delete=models.CASCADE,
to='gestion.Profile',
related_name='cof'
),

View file

@ -0,0 +1,23 @@
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('cof', '0011_delete_clipper_and_custommail'),
('gestion', '0002_club_support')
]
operations = [
migrations.RemoveField(
model_name='club',
name='membres',
),
migrations.RemoveField(
model_name='club',
name='respos',
),
migrations.DeleteModel(
name='Club',
),
]

View file

@ -79,18 +79,6 @@ class CofProfile(models.Model):
return self.profile.user.username
@python_2_unicode_compatible
class Club(models.Model):
name = models.CharField("Nom", max_length=200, unique=True)
description = models.TextField("Description", blank=True)
respos = models.ManyToManyField(User, related_name="clubs_geres",
blank=True)
membres = models.ManyToManyField(User, related_name="clubs", blank=True)
def __str__(self):
return self.name
@python_2_unicode_compatible
class Event(models.Model):
title = models.CharField("Titre", max_length=200)
@ -113,7 +101,11 @@ class Event(models.Model):
@python_2_unicode_compatible
class EventCommentField(models.Model):
event = models.ForeignKey(Event, related_name="commentfields")
event = models.ForeignKey(
Event,
on_delete=models.CASCADE,
related_name="commentfields"
)
name = models.CharField("Champ", max_length=200)
fieldtype = models.CharField("Type", max_length=10,
choices=TYPE_COMMENT_FIELD, default="text")
@ -128,9 +120,16 @@ class EventCommentField(models.Model):
@python_2_unicode_compatible
class EventCommentValue(models.Model):
commentfield = models.ForeignKey(EventCommentField, related_name="values")
registration = models.ForeignKey("EventRegistration",
related_name="comments")
commentfield = models.ForeignKey(
EventCommentField,
on_delete=models.CASCADE,
related_name="values"
)
registration = models.ForeignKey(
"EventRegistration",
on_delete=models.CASCADE,
related_name="comments"
)
content = models.TextField("Contenu", blank=True, null=True)
def __str__(self):
@ -139,7 +138,11 @@ class EventCommentValue(models.Model):
@python_2_unicode_compatible
class EventOption(models.Model):
event = models.ForeignKey(Event, related_name="options")
event = models.ForeignKey(
Event,
on_delete=models.CASCADE,
related_name="options"
)
name = models.CharField("Option", max_length=200)
multi_choices = models.BooleanField("Choix multiples", default=False)
@ -152,7 +155,11 @@ class EventOption(models.Model):
@python_2_unicode_compatible
class EventOptionChoice(models.Model):
event_option = models.ForeignKey(EventOption, related_name="choices")
event_option = models.ForeignKey(
EventOption,
on_delete=models.CASCADE,
related_name="choices"
)
value = models.CharField("Valeur", max_length=200)
class Meta:
@ -165,8 +172,14 @@ class EventOptionChoice(models.Model):
@python_2_unicode_compatible
class EventRegistration(models.Model):
user = models.ForeignKey(User)
event = models.ForeignKey(Event)
user = models.ForeignKey(
User,
on_delete=models.CASCADE
)
event = models.ForeignKey(
Event,
on_delete=models.CASCADE
)
options = models.ManyToManyField(EventOptionChoice)
filledcomments = models.ManyToManyField(EventCommentField,
through=EventCommentValue)
@ -197,7 +210,11 @@ class Survey(models.Model):
@python_2_unicode_compatible
class SurveyQuestion(models.Model):
survey = models.ForeignKey(Survey, related_name="questions")
survey = models.ForeignKey(
Survey,
on_delete=models.CASCADE,
related_name="questions"
)
question = models.CharField("Question", max_length=200)
multi_answers = models.BooleanField("Choix multiples", default=False)
@ -210,7 +227,11 @@ class SurveyQuestion(models.Model):
@python_2_unicode_compatible
class SurveyQuestionAnswer(models.Model):
survey_question = models.ForeignKey(SurveyQuestion, related_name="answers")
survey_question = models.ForeignKey(
SurveyQuestion,
on_delete=models.CASCADE,
related_name="answers"
)
answer = models.CharField("Réponse", max_length=200)
class Meta:
@ -222,8 +243,14 @@ class SurveyQuestionAnswer(models.Model):
@python_2_unicode_compatible
class SurveyAnswer(models.Model):
user = models.ForeignKey(User)
survey = models.ForeignKey(Survey)
user = models.ForeignKey(
User,
on_delete=models.CASCADE
)
survey = models.ForeignKey(
Survey,
on_delete=models.CASCADE
)
answers = models.ManyToManyField(SurveyQuestionAnswer,
related_name="selected_by")
@ -240,7 +267,10 @@ class SurveyAnswer(models.Model):
@python_2_unicode_compatible
class CalendarSubscription(models.Model):
token = models.UUIDField()
user = models.OneToOneField(User)
user = models.OneToOneField(
User,
on_delete=models.CASCADE
)
other_shows = models.ManyToManyField(Spectacle)
subscribe_to_events = models.BooleanField(default=True)
subscribe_to_my_shows = models.BooleanField(default=True)

View file

@ -35,8 +35,15 @@ class PetitCoursSubject(models.Model):
class PetitCoursAbility(models.Model):
user = models.ForeignKey(User)
matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matière"))
user = models.ForeignKey(
User,
on_delete=models.CASCADE
)
matiere = models.ForeignKey(
PetitCoursSubject,
on_delete=models.CASCADE,
verbose_name=_("Matière")
)
niveau = models.CharField(_("Niveau"),
choices=LEVELS_CHOICES,
max_length=choices_length(LEVELS_CHOICES))
@ -84,7 +91,11 @@ class PetitCoursDemande(models.Model):
remarques = models.TextField(_("Remarques et précisions"), blank=True)
traitee = models.BooleanField(_("Traitée"), default=False)
traitee_par = models.ForeignKey(User, blank=True, null=True)
traitee_par = models.ForeignKey(
User,
on_delete=models.CASCADE,
blank=True, null=True
)
processed = models.DateTimeField(_("Date de traitement"),
blank=True, null=True)
created = models.DateTimeField(_("Date de création"), auto_now_add=True)
@ -126,9 +137,20 @@ class PetitCoursDemande(models.Model):
class PetitCoursAttribution(models.Model):
user = models.ForeignKey(User)
demande = models.ForeignKey(PetitCoursDemande, verbose_name=_("Demande"))
matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matière"))
user = models.ForeignKey(
User,
on_delete=models.CASCADE
)
demande = models.ForeignKey(
PetitCoursDemande,
on_delete=models.CASCADE,
verbose_name=_("Demande")
)
matiere = models.ForeignKey(
PetitCoursSubject,
on_delete=models.CASCADE,
verbose_name=_("Matière")
)
date = models.DateTimeField(_("Date d'attribution"), auto_now_add=True)
rank = models.IntegerField("Rang dans l'email")
selected = models.BooleanField(_("Sélectionné par le demandeur"),
@ -145,8 +167,15 @@ class PetitCoursAttribution(models.Model):
class PetitCoursAttributionCounter(models.Model):
user = models.ForeignKey(User)
matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matiere"))
user = models.ForeignKey(
User,
on_delete=models.CASCADE
)
matiere = models.ForeignKey(
PetitCoursSubject,
on_delete=models.CASCADE,
verbose_name=_("Matiere")
)
count = models.IntegerField("Nombre d'envois", default=0)
@classmethod

View file

@ -3,7 +3,7 @@
{% block content %}
<header>
<div class="container banner">
<a href="{% url "cof.views.home" %}">
<a href="{% url "home" %}">
<h1>GestioCOF</h1>
{% block homelink %}
<span class="glyphicon glyphicon-home" aria-hidden=true></span>

View file

@ -12,7 +12,7 @@ souscrire aux événements du COF et/ou aux spectacles BdA.
{% if token %}
<p>Votre calendrier (compatible avec toutes les applications d'agenda) se trouve à
<a href="{% url 'cof.views.calendar_ics' token %}">cette adresse</a>.</p>
<a href="{% url 'calendar.ics' token %}">cette adresse</a>.</p>
<ul>
<li>Pour l'ajouter à Thunderbird (lightning), il faut copier ce lien et aller

View file

@ -8,7 +8,7 @@
{% if event.details %}
<p>{{ event.details }}</p>
{% endif %}
<form method="post" action="{% url 'cof.views.event' event.id %}">
<form method="post" action="{% url 'event' event.id %}">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" class="btn-submit" value="Enregistrer" />

View file

@ -7,7 +7,7 @@
{% else %}
<h3>Inscription d'un nouveau compte (extérieur ?)</h3>
{% endif %}
<form role="form" id="profile" method="post" action="{% url 'cof.views.registration' %}">
<form role="form" id="profile" method="post" action="{% url 'registration' %}">
{% csrf_token %}
<table>
{{ user_form | bootstrap }}
@ -16,7 +16,6 @@
<hr />
<table>
{{ cofprofile_form | bootstrap }}
{{ clubs_form | bootstrap }}
</table>
{{ event_formset.management_form }}
{% for event_form in event_formset %}

View file

@ -15,7 +15,7 @@
{% if survey.details %}
<p>{{ survey.details }}</p>
{% endif %}
<form class="form-horizontal" method="post" action="{% url 'cof.views.survey' survey.id %}">
<form class="form-horizontal" method="post" action="{% url 'survey' survey.id %}">
{% csrf_token %}
{{ form | bootstrap}}

View file

@ -7,15 +7,15 @@
<h2>Liens utiles du COF</h2>
<h3>COF</h3>
<ul>
<li><a href="{% url 'cof.views.export_members' %}">Export des membres du COF</a></li>
<li><a href="{% url 'cof.views.liste_diffcof' %}">Diffusion COF</a></li>
<li><a href="{% url 'export.members' %}">Export des membres du COF</a></li>
<li><a href="{% url 'liste_diffcof' %}">Diffusion COF</a></li>
</ul>
<h3>Mega</h3>
<ul>
<li><a href="{% url 'cof.views.export_mega_participants' %}">Export des non-orgas uniquement</a></li>
<li><a href="{% url 'cof.views.export_mega_orgas' %}">Export des orgas uniquement</a></li>
<li><a href="{% url 'cof.views.export_mega' %}">Export de tout le monde</a></li>
<li><a href="{% url 'export.mega.participants' %}">Export des non-orgas uniquement</a></li>
<li><a href="{% url 'export.mega.orgas' %}">Export des orgas uniquement</a></li>
<li><a href="{% url 'export.mega' %}">Export de tout le monde</a></li>
</ul>
<p>Note&nbsp;: pour ouvrir les fichiers .csv avec Excel, il faut

View file

@ -11,7 +11,7 @@
{% endif %}
{% include "tristate_js.html" %}
<h3>Filtres</h3>
<form method="post" action="{% url 'cof.views.event_status' event.id %}">
<form method="post" action="{% url 'event.status' event.id %}">
{% csrf_token %}
{{ form.as_p }}
<input style="margin-top:10px;" type="submit" class="btn btn-primary" value="Filtrer" />

View file

@ -13,7 +13,7 @@
<div class="hm-block">
<ul>
{% for event in open_events %}
<li><a href="{% url "cof.views.event" event.id %}">{{ event.title }}</a></li>
<li><a href="{% url "event" event.id %}">{{ event.title }}</a></li>
{% endfor %}
</ul>
</div>
@ -23,7 +23,7 @@
<div class="hm-block">
<ul>
{% for survey in open_surveys %}
<li><a href="{% url "cof.views.survey" survey.id %}">{{ survey.title }}</a></li>
<li><a href="{% url "survey" survey.id %}">{{ survey.title }}</a></li>
{% endfor %}
</ul>
</div>
@ -54,11 +54,11 @@
<h3 class="block-title">Divers<span class="pull-right glyphicon glyphicon-question-sign"></span></h3>
<div class="hm-block">
<ul>
<li><a href="{% url "cof.views.calendar" %}">Calendrier dynamique</a></li>
<li><a href="{% url "calendar" %}">Calendrier dynamique</a></li>
{% if user.profile.cof.is_cof %}<li><a href="{% url "petits-cours-inscription" %}">Inscription pour donner des petits cours</a></li>{% endif %}
<li><a href="{% url "gestion:profile" %}">Éditer mon profil</a></li>
{% if not user.profile.login_clipper %}<li><a href="{% url "django.contrib.auth.views.password_change" %}">Changer mon mot de passe</a></li>{% endif %}
{% if not user.profile.login_clipper %}<li><a href="{% url "password_change" %}">Changer mon mot de passe</a></li>{% endif %}
</ul>
</div>
{% endif %}
@ -71,16 +71,15 @@
<h4>Général</h4>
<li><a href="{% url "admin:index" %}">Administration générale</a></li>
<li><a href="{% url "petits-cours-demandes-list" %}">Demandes de petits cours</a></li>
<li><a href="{% url "cof.views.registration" %}">Inscription d'un nouveau membre</a></li>
<li><a href="{% url "liste-clubs" %}">Gestion des clubs</a></li>
<li><a href="{% url "registration" %}">Inscription d'un nouveau membre</a></li>
</ul>
<ul>
<h4>Évènements & Sondages</h4>
{% for event in events %}
<li><a href="{% url "cof.views.event_status" event.id %}">Événement : {{ event.title }}</a></li>
<li><a href="{% url "event.status" event.id %}">Événement : {{ event.title }}</a></li>
{% endfor %}
{% for survey in surveys %}
<li><a href="{% url "cof.views.survey_status" survey.id %}">Sondage : {{ survey.title }}</a></li>
<li><a href="{% url "survey.status" survey.id %}">Sondage : {{ survey.title }}</a></li>
{% endfor %}
</ul>
</div>
@ -105,8 +104,8 @@
<h3 class="block-title">Liens utiles<span class="pull-right glyphicon glyphicon-link"></span></h3>
<div class="hm-block">
<ul>
<li><a href="{% url "cof.views.utile_cof" %}">Liens utiles du COF</a></li>
<li><a href="{% url "cof.views.utile_bda" %}">Liens utiles BdA</a></li>
<li><a href="{% url "utile_cof" %}">Liens utiles du COF</a></li>
<li><a href="{% url "utile_bda" %}">Liens utiles BdA</a></li>
</ul>
</div>
</div>

View file

@ -1,25 +0,0 @@
{% extends "base_title.html" %}
{% block page_size %}col-sm-8{% endblock %}
{% block realcontent %}
<h2>Clubs enregistrés sur GestioCOF</h2>
<ul>
{% for club in owned_clubs %}
<li>
<a href="{% url "membres-club" club.name %}">
{{ club }} ({% for respo in club.respos.all %}{{ respo.get_full_name }}, {% empty %}pas de respo{% endfor %})
</a>
</li>
{% endfor %}
{% if other_clubs %}
{% for club in other_clubs %}
<li>
<p>
{{ club }} ({% for respo in club.respos.all %}{{ respo.get_full_name }}, {% empty %}pas de respo{% endfor %})
</p>
</li>
{% endfor %}
{% endif %}
</ul>
{% endblock %}

View file

@ -1,41 +0,0 @@
{% extends "base_title.html" %}
{% block realcontent %}
<h2>{{ club }}</h2>
{% if club.respos.exists %}
<h3>Respo{{ club.respos.all|pluralize }}</h3>
<table class="table table-striped">
{% for member in club.respos.all %}
<tr>
<td>{{ member }}</td>
<td>{{ member.email }}</td>
<td><a class="glyphicon glyphicon-arrow-down"
href="{% url "change-respo" club.name member.id %}"></a></td>
</tr>
{% endfor %}
</table>
{% else %}
<h3>Pas de respo</h3>
{% endif %}
{% if club.membres.exists %}
<h3>Liste des membres</h3>
<table class="table table-striped">
{% for member in members_no_respo %}
<tr>
<td>{{ member }}</td>
<td>{{ member.email }}</td>
<td><a class="glyphicon glyphicon-arrow-up"
href="{% url "change-respo" club.name member.id %}"></a></td>
</tr>
{% endfor %}
</table>
{% else %}
Ce club ne comporte actuellement aucun membre.
{% endif %}
{% endblock %}

View file

@ -16,7 +16,7 @@
// On attend que la page soit prête pour executer le code
$(document).ready(function() {
$('input#search_autocomplete').yourlabsAutocomplete({
url: '{% url 'cof.autocomplete.autocomplete' %}',
url: '{% url 'autocomplete' %}',
minimumCharacters: 3,
id: 'search_autocomplete',
choiceSelector: 'li:has(a)',

View file

@ -5,5 +5,5 @@
{% block realcontent %}
<h2>Mot de passe modifié avec succès !</h2>
<h3><a href="{% url "cof.views.home" %}">Retour au menu principal</a></h3>
<h3><a href="{% url "home" %}">Retour au menu principal</a></h3>
{% endblock %}

View file

@ -5,7 +5,7 @@
{% block realcontent %}
<h2>Changement de mot de passe</h2>
<form class="form-horizontal" method="post" action="{% url 'django.contrib.auth.views.password_change' %}">
<form class="form-horizontal" method="post" action="{% url 'password_change' %}">
{% csrf_token %}
{{ form | bootstrap }}
<input type="submit" class="btn btn-primary pull-right" value="Changer" />

View file

@ -11,7 +11,7 @@
{% endif %}
<h3>Filtres</h3>
{% include "tristate_js.html" %}
<form method="post" action="{% url 'cof.views.survey_status' survey.id %}">
<form method="post" action="{% url 'survey.status' survey.id %}">
{% csrf_token %}
{{ form.as_p }}
<input style="margin-top:10px;" type="submit" class="btn btn-primary" value="Filtrer" />

View file

@ -7,7 +7,7 @@
<h2>Liens utiles du BdA</h2>
<h3>Listes mail</h3>
<ul>
<li><a href="{% url 'cof.views.liste_bdadiff' %}">BdA diffusion</a></li>
<li><a href="{% url 'cof.views.liste_bdarevente' %}">BdA revente</a></li>
<li><a href="{% url 'liste_bdadiff' %}">BdA diffusion</a></li>
<li><a href="{% url 'liste_bdarevente' %}">BdA revente</a></li>
</ul>
{% endblock %}

View file

@ -7,12 +7,20 @@ from . import views, petits_cours_views
export_patterns = [
url(r'^members$', views.export_members),
url(r'^members$',
views.export_members,
name="export.members"),
url(r'^mega/avecremarques$', views.export_mega_remarksonly),
url(r'^mega/participants$', views.export_mega_participants),
url(r'^mega/orgas$', views.export_mega_orgas),
url(r'^mega/participants$',
views.export_mega_participants,
name="export.mega.participants"),
url(r'^mega/orgas$',
views.export_mega_orgas,
name="export.mega.orgas"),
url(r'^mega/(?P<type>.+)$', views.export_mega_bytype),
url(r'^mega$', views.export_mega),
url(r'^mega$',
views.export_mega,
name="export.mega"),
]
petitcours_patterns = [
@ -37,24 +45,28 @@ petitcours_patterns = [
]
surveys_patterns = [
url(r'^(?P<survey_id>\d+)/status$', views.survey_status),
url(r'^(?P<survey_id>\d+)$', views.survey),
url(r'^(?P<survey_id>\d+)/status$',
views.survey_status,
name="survey.status"),
url(r'^(?P<survey_id>\d+)$',
views.survey,
name="survey"),
]
events_patterns = [
url(r'^(?P<event_id>\d+)$', views.event),
url(r'^(?P<event_id>\d+)/status$', views.event_status),
url(r'^(?P<event_id>\d+)$',
views.event,
name="event"),
url(r'^(?P<event_id>\d+)/status$',
views.event_status,
name="event.status"),
]
calendar_patterns = [
url(r'^subscription$', 'cof.views.calendar'),
url(r'^subscription$',
views.calendar,
name="calendar"),
url(r'^(?P<token>[a-z0-9-]+)/calendar.ics$',
'cof.views.calendar_ics')
]
clubs_patterns = [
url(r'^membres/(?P<name>\w+)', views.membres_club, name='membres-club'),
url(r'^liste', views.liste_clubs, name='liste-clubs'),
url(r'^change_respo/(?P<club_name>\w+)/(?P<user_id>\d+)',
views.change_respo, name='change-respo'),
views.calendar_ics,
name="calendar.ics")
]

View file

@ -6,8 +6,8 @@ from datetime import timedelta
from icalendar import Calendar, Event as Vevent
from custommail.shortcuts import send_custom_mail
from django.shortcuts import redirect, get_object_or_404, render
from django.http import Http404, HttpResponse, HttpResponseForbidden
from django.shortcuts import get_object_or_404, render
from django.http import Http404, HttpResponse
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
@ -21,12 +21,12 @@ from .models import Event, EventRegistration, EventOption, \
EventOptionChoice
from .models import EventCommentField, EventCommentValue, \
CalendarSubscription
from .models import CofProfile, Club
from .models import CofProfile
from .decorators import buro_required, cof_required
from .forms import (
EventStatusFilterForm, SurveyForm, SurveyStatusFilterForm,
RegistrationUserForm, RegistrationProfileForm, RegistrationCofProfileForm,
EventForm, CalendarForm, EventFormset, RegistrationPassUserForm, ClubsForm
EventForm, CalendarForm, EventFormset, RegistrationPassUserForm
)
from bda.models import Tirage, Spectacle
@ -305,9 +305,8 @@ def registration_form2(request, login_clipper=None, username=None,
# COF - profile
cofprofile_form = RegistrationCofProfileForm()
registration_set_ro_fields(user_form, profile_form)
# events & clubs
# events
event_formset = EventFormset(events=events, prefix='events')
clubs_form = ClubsForm()
if username:
member = get_object_or_404(User, username=username)
(profile, _) = Profile.objects.get_or_create(user=member)
@ -328,8 +327,6 @@ def registration_form2(request, login_clipper=None, username=None,
event_formset = EventFormset(
events=events, prefix='events',
current_registrations=current_registrations)
# Clubs
clubs_form = ClubsForm(initial={'clubs': member.clubs.all()})
elif not login_clipper:
# new user
user_form = RegistrationPassUserForm()
@ -337,14 +334,12 @@ def registration_form2(request, login_clipper=None, username=None,
profile_form = RegistrationProfileForm()
cofprofile_form = RegistrationCofProfileForm()
event_formset = EventFormset(events=events, prefix='events')
clubs_form = ClubsForm()
return render(request, "cof/registration_form.html",
{"member": member, "login_clipper": login_clipper,
"user_form": user_form,
"profile_form": profile_form,
"cofprofile_form": cofprofile_form,
"event_formset": event_formset,
"clubs_form": clubs_form})
"event_formset": event_formset})
@buro_required
@ -368,7 +363,6 @@ def registration(request):
user_form = RegistrationUserForm(request_dict)
profile_form = RegistrationProfileForm(request_dict)
cofprofile_form = RegistrationCofProfileForm(request_dict)
clubs_form = ClubsForm(request_dict)
events = Event.objects.filter(old=False).all()
event_formset = EventFormset(events=events, data=request_dict,
prefix='events')
@ -409,7 +403,6 @@ def registration(request):
profile_form.is_valid(),
cofprofile_form.is_valid(),
event_formset.is_valid(),
clubs_form.is_valid()
))
if forms_are_valid:
# Enregistrement du profil
@ -455,11 +448,6 @@ def registration(request):
# l'inscription aux événements et/ou donner la
# possibilité d'associer un mail aux événements
# send_custom_mail(...)
# Enregistrement des inscriptions aux clubs
member.clubs.clear()
for club in clubs_form.cleaned_data['clubs']:
club.membres.add(member)
club.save()
success = True
# Messages
if success:
@ -476,56 +464,11 @@ def registration(request):
"cofprofile_form": cofprofile_form,
"member": member,
"login_clipper": login_clipper,
"event_formset": event_formset,
"clubs_form": clubs_form})
"event_formset": event_formset})
else:
return render(request, "registration.html")
# -----
# Clubs
# -----
@login_required
def membres_club(request, name):
# Vérification des permissions : l'utilisateur doit être membre du burô
# ou respo du club.
user = request.user
club = get_object_or_404(Club, name=name)
if not request.user.profile.is_buro \
and club not in user.clubs_geres.all():
return HttpResponseForbidden('<h1>Permission denied</h1>')
members_no_respo = club.membres.exclude(clubs_geres=club).all()
return render(request, 'membres_clubs.html',
{'club': club,
'members_no_respo': members_no_respo})
@buro_required
def change_respo(request, club_name, user_id):
club = get_object_or_404(Club, name=club_name)
user = get_object_or_404(User, id=user_id)
if user in club.respos.all():
club.respos.remove(user)
elif user in club.membres.all():
club.respos.add(user)
else:
raise Http404
return redirect('membres-club', name=club_name)
@cof_required
def liste_clubs(request):
clubs = Club.objects
if request.user.profile.is_buro:
data = {'owned_clubs': clubs.all()}
else:
data = {'owned_clubs': request.user.clubs_geres,
'other_clubs': clubs.exclude(respos=request.user)}
return render(request, 'liste_clubs.html', data)
@buro_required
def export_members(request):
response = HttpResponse(content_type='text/csv')