forked from DGNum/gestioCOF
core -- Apply black + isort to all files
This commit is contained in:
parent
104e71dcf6
commit
fdd2b35289
196 changed files with 10727 additions and 8365 deletions
|
@ -1 +1 @@
|
|||
default_app_config = 'gestioncof.apps.GestioncofConfig'
|
||||
default_app_config = "gestioncof.apps.GestioncofConfig"
|
||||
|
|
|
@ -1,23 +1,35 @@
|
|||
from dal.autocomplete import ModelSelect2
|
||||
from django import forms
|
||||
from django.contrib import admin
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from gestioncof.models import SurveyQuestionAnswer, SurveyQuestion, \
|
||||
CofProfile, EventOption, EventOptionChoice, Event, Club, \
|
||||
Survey, EventCommentField, EventRegistration
|
||||
from gestioncof.petits_cours_models import PetitCoursDemande, \
|
||||
PetitCoursSubject, PetitCoursAbility, PetitCoursAttribution, \
|
||||
PetitCoursAttributionCounter
|
||||
from django.contrib.auth.models import User, Group, Permission
|
||||
from django.contrib.auth.admin import UserAdmin
|
||||
from django.contrib.auth.models import Group, Permission, User
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.db.models import Q
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from dal.autocomplete import ModelSelect2
|
||||
from gestioncof.models import (
|
||||
Club,
|
||||
CofProfile,
|
||||
Event,
|
||||
EventCommentField,
|
||||
EventOption,
|
||||
EventOptionChoice,
|
||||
EventRegistration,
|
||||
Survey,
|
||||
SurveyQuestion,
|
||||
SurveyQuestionAnswer,
|
||||
)
|
||||
from gestioncof.petits_cours_models import (
|
||||
PetitCoursAbility,
|
||||
PetitCoursAttribution,
|
||||
PetitCoursAttributionCounter,
|
||||
PetitCoursDemande,
|
||||
PetitCoursSubject,
|
||||
)
|
||||
|
||||
|
||||
def add_link_field(target_model='', field='', link_text=str,
|
||||
desc_text=str):
|
||||
def add_link_field(target_model="", field="", link_text=str, desc_text=str):
|
||||
def add_link(cls):
|
||||
reverse_name = target_model or cls.model.__name__.lower()
|
||||
|
||||
|
@ -28,14 +40,14 @@ def add_link_field(target_model='', field='', link_text=str,
|
|||
if not link_obj.id:
|
||||
return ""
|
||||
url = reverse(reverse_path, args=(link_obj.id,))
|
||||
return mark_safe("<a href='%s'>%s</a>"
|
||||
% (url, link_text(link_obj)))
|
||||
return mark_safe("<a href='%s'>%s</a>" % (url, link_text(link_obj)))
|
||||
|
||||
link.allow_tags = True
|
||||
link.short_description = desc_text(reverse_name + ' link')
|
||||
link.short_description = desc_text(reverse_name + " link")
|
||||
cls.link = link
|
||||
cls.readonly_fields =\
|
||||
list(getattr(cls, 'readonly_fields', [])) + ['link']
|
||||
cls.readonly_fields = list(getattr(cls, "readonly_fields", [])) + ["link"]
|
||||
return cls
|
||||
|
||||
return add_link
|
||||
|
||||
|
||||
|
@ -43,32 +55,28 @@ class SurveyQuestionAnswerInline(admin.TabularInline):
|
|||
model = SurveyQuestionAnswer
|
||||
|
||||
|
||||
@add_link_field(desc_text=lambda x: "Réponses",
|
||||
link_text=lambda x: "Éditer les réponses")
|
||||
@add_link_field(
|
||||
desc_text=lambda x: "Réponses", link_text=lambda x: "Éditer les réponses"
|
||||
)
|
||||
class SurveyQuestionInline(admin.TabularInline):
|
||||
model = SurveyQuestion
|
||||
|
||||
|
||||
class SurveyQuestionAdmin(admin.ModelAdmin):
|
||||
search_fields = ('survey__title', 'answer')
|
||||
inlines = [
|
||||
SurveyQuestionAnswerInline,
|
||||
]
|
||||
search_fields = ("survey__title", "answer")
|
||||
inlines = [SurveyQuestionAnswerInline]
|
||||
|
||||
|
||||
class SurveyAdmin(admin.ModelAdmin):
|
||||
search_fields = ('title', 'details')
|
||||
inlines = [
|
||||
SurveyQuestionInline,
|
||||
]
|
||||
search_fields = ("title", "details")
|
||||
inlines = [SurveyQuestionInline]
|
||||
|
||||
|
||||
class EventOptionChoiceInline(admin.TabularInline):
|
||||
model = EventOptionChoice
|
||||
|
||||
|
||||
@add_link_field(desc_text=lambda x: "Choix",
|
||||
link_text=lambda x: "Éditer les choix")
|
||||
@add_link_field(desc_text=lambda x: "Choix", link_text=lambda x: "Éditer les choix")
|
||||
class EventOptionInline(admin.TabularInline):
|
||||
model = EventOption
|
||||
|
||||
|
@ -78,18 +86,13 @@ class EventCommentFieldInline(admin.TabularInline):
|
|||
|
||||
|
||||
class EventOptionAdmin(admin.ModelAdmin):
|
||||
search_fields = ('event__title', 'name')
|
||||
inlines = [
|
||||
EventOptionChoiceInline,
|
||||
]
|
||||
search_fields = ("event__title", "name")
|
||||
inlines = [EventOptionChoiceInline]
|
||||
|
||||
|
||||
class EventAdmin(admin.ModelAdmin):
|
||||
search_fields = ('title', 'location', 'description')
|
||||
inlines = [
|
||||
EventOptionInline,
|
||||
EventCommentFieldInline,
|
||||
]
|
||||
search_fields = ("title", "location", "description")
|
||||
inlines = [EventOptionInline, EventCommentFieldInline]
|
||||
|
||||
|
||||
class CofProfileInline(admin.StackedInline):
|
||||
|
@ -98,10 +101,9 @@ class CofProfileInline(admin.StackedInline):
|
|||
|
||||
|
||||
class FkeyLookup(object):
|
||||
def __init__(self, fkeydecl, short_description=None,
|
||||
admin_order_field=None):
|
||||
self.fk, fkattrs = fkeydecl.split('__', 1)
|
||||
self.fkattrs = fkattrs.split('__')
|
||||
def __init__(self, fkeydecl, short_description=None, admin_order_field=None):
|
||||
self.fk, fkattrs = fkeydecl.split("__", 1)
|
||||
self.fkattrs = fkattrs.split("__")
|
||||
|
||||
self.short_description = short_description or self.fkattrs[-1]
|
||||
self.admin_order_field = admin_order_field or fkeydecl
|
||||
|
@ -126,19 +128,19 @@ def ProfileInfo(field, short_description, boolean=False):
|
|||
return getattr(self.profile, field)
|
||||
except CofProfile.DoesNotExist:
|
||||
return ""
|
||||
|
||||
getter.short_description = short_description
|
||||
getter.boolean = boolean
|
||||
return getter
|
||||
|
||||
User.profile_login_clipper = FkeyLookup("profile__login_clipper",
|
||||
"Login clipper")
|
||||
|
||||
User.profile_login_clipper = FkeyLookup("profile__login_clipper", "Login clipper")
|
||||
User.profile_phone = ProfileInfo("phone", "Téléphone")
|
||||
User.profile_occupation = ProfileInfo("occupation", "Occupation")
|
||||
User.profile_departement = ProfileInfo("departement", "Departement")
|
||||
User.profile_mailing_cof = ProfileInfo("mailing_cof", "ML COF", True)
|
||||
User.profile_mailing_bda = ProfileInfo("mailing_bda", "ML BdA", True)
|
||||
User.profile_mailing_bda_revente = ProfileInfo("mailing_bda_revente",
|
||||
"ML BdA-R", True)
|
||||
User.profile_mailing_bda_revente = ProfileInfo("mailing_bda_revente", "ML BdA-R", True)
|
||||
|
||||
|
||||
class UserProfileAdmin(UserAdmin):
|
||||
|
@ -147,7 +149,8 @@ class UserProfileAdmin(UserAdmin):
|
|||
return obj.profile.is_buro
|
||||
except CofProfile.DoesNotExist:
|
||||
return False
|
||||
is_buro.short_description = 'Membre du Buro'
|
||||
|
||||
is_buro.short_description = "Membre du Buro"
|
||||
is_buro.boolean = True
|
||||
|
||||
def is_cof(self, obj):
|
||||
|
@ -155,27 +158,33 @@ class UserProfileAdmin(UserAdmin):
|
|||
return obj.profile.is_cof
|
||||
except CofProfile.DoesNotExist:
|
||||
return False
|
||||
is_cof.short_description = 'Membre du COF'
|
||||
|
||||
is_cof.short_description = "Membre du COF"
|
||||
is_cof.boolean = True
|
||||
|
||||
list_display = (
|
||||
UserAdmin.list_display
|
||||
+ ('profile_login_clipper', 'profile_phone', 'profile_occupation',
|
||||
'profile_mailing_cof', 'profile_mailing_bda',
|
||||
'profile_mailing_bda_revente', 'is_cof', 'is_buro', )
|
||||
list_display = UserAdmin.list_display + (
|
||||
"profile_login_clipper",
|
||||
"profile_phone",
|
||||
"profile_occupation",
|
||||
"profile_mailing_cof",
|
||||
"profile_mailing_bda",
|
||||
"profile_mailing_bda_revente",
|
||||
"is_cof",
|
||||
"is_buro",
|
||||
)
|
||||
list_display_links = ('username', 'email', 'first_name', 'last_name')
|
||||
list_filter = UserAdmin.list_filter \
|
||||
+ ('profile__is_cof', 'profile__is_buro', 'profile__mailing_cof',
|
||||
'profile__mailing_bda')
|
||||
search_fields = UserAdmin.search_fields + ('profile__phone',)
|
||||
inlines = [
|
||||
CofProfileInline,
|
||||
]
|
||||
list_display_links = ("username", "email", "first_name", "last_name")
|
||||
list_filter = UserAdmin.list_filter + (
|
||||
"profile__is_cof",
|
||||
"profile__is_buro",
|
||||
"profile__mailing_cof",
|
||||
"profile__mailing_bda",
|
||||
)
|
||||
search_fields = UserAdmin.search_fields + ("profile__phone",)
|
||||
inlines = [CofProfileInline]
|
||||
|
||||
staff_fieldsets = [
|
||||
(None, {'fields': ['username', 'password']}),
|
||||
(_('Personal info'), {'fields': ['first_name', 'last_name', 'email']}),
|
||||
(None, {"fields": ["username", "password"]}),
|
||||
(_("Personal info"), {"fields": ["first_name", "last_name", "email"]}),
|
||||
]
|
||||
|
||||
def get_fieldsets(self, request, user=None):
|
||||
|
@ -184,15 +193,15 @@ class UserProfileAdmin(UserAdmin):
|
|||
return super().get_fieldsets(request, user)
|
||||
|
||||
def save_model(self, request, user, form, change):
|
||||
cof_group, created = Group.objects.get_or_create(name='COF')
|
||||
cof_group, created = Group.objects.get_or_create(name="COF")
|
||||
if created:
|
||||
# Si le groupe COF n'était pas déjà dans la bdd
|
||||
# On lui assigne les bonnes permissions
|
||||
perms = Permission.objects.filter(
|
||||
Q(content_type__app_label='gestioncof')
|
||||
| Q(content_type__app_label='bda')
|
||||
| (Q(content_type__app_label='auth')
|
||||
& Q(content_type__model='user')))
|
||||
Q(content_type__app_label="gestioncof")
|
||||
| Q(content_type__app_label="bda")
|
||||
| (Q(content_type__app_label="auth") & Q(content_type__model="user"))
|
||||
)
|
||||
cof_group.permissions = perms
|
||||
# On y associe les membres du Burô
|
||||
cof_group.user_set = User.objects.filter(profile__is_buro=True)
|
||||
|
@ -214,72 +223,97 @@ def user_str(self):
|
|||
return "{} ({})".format(self.get_full_name(), self.username)
|
||||
else:
|
||||
return self.username
|
||||
|
||||
|
||||
User.__str__ = user_str
|
||||
|
||||
|
||||
class EventRegistrationAdminForm(forms.ModelForm):
|
||||
class Meta:
|
||||
widgets = {
|
||||
'user': ModelSelect2(url='cof-user-autocomplete'),
|
||||
}
|
||||
widgets = {"user": ModelSelect2(url="cof-user-autocomplete")}
|
||||
|
||||
|
||||
class EventRegistrationAdmin(admin.ModelAdmin):
|
||||
form = EventRegistrationAdminForm
|
||||
|
||||
list_display = ('__str__', 'event', 'user', 'paid')
|
||||
list_filter = ('paid',)
|
||||
search_fields = ('user__username', 'user__first_name', 'user__last_name',
|
||||
'user__email', 'event__title')
|
||||
list_display = ("__str__", "event", "user", "paid")
|
||||
list_filter = ("paid",)
|
||||
search_fields = (
|
||||
"user__username",
|
||||
"user__first_name",
|
||||
"user__last_name",
|
||||
"user__email",
|
||||
"event__title",
|
||||
)
|
||||
|
||||
|
||||
class PetitCoursAbilityAdmin(admin.ModelAdmin):
|
||||
list_display = ('user', 'matiere', 'niveau', 'agrege')
|
||||
search_fields = ('user__username', 'user__first_name', 'user__last_name',
|
||||
'user__email', 'matiere__name', 'niveau')
|
||||
list_filter = ('matiere', 'niveau', 'agrege')
|
||||
list_display = ("user", "matiere", "niveau", "agrege")
|
||||
search_fields = (
|
||||
"user__username",
|
||||
"user__first_name",
|
||||
"user__last_name",
|
||||
"user__email",
|
||||
"matiere__name",
|
||||
"niveau",
|
||||
)
|
||||
list_filter = ("matiere", "niveau", "agrege")
|
||||
|
||||
|
||||
class PetitCoursAttributionAdmin(admin.ModelAdmin):
|
||||
list_display = ('user', 'demande', 'matiere', 'rank', )
|
||||
search_fields = ('user__username', 'matiere__name')
|
||||
list_display = ("user", "demande", "matiere", "rank")
|
||||
search_fields = ("user__username", "matiere__name")
|
||||
|
||||
|
||||
class PetitCoursAttributionCounterAdmin(admin.ModelAdmin):
|
||||
list_display = ('user', 'matiere', 'count', )
|
||||
list_filter = ('matiere',)
|
||||
search_fields = ('user__username', 'user__first_name', 'user__last_name',
|
||||
'user__email', 'matiere__name')
|
||||
actions = ['reset', ]
|
||||
list_display = ("user", "matiere", "count")
|
||||
list_filter = ("matiere",)
|
||||
search_fields = (
|
||||
"user__username",
|
||||
"user__first_name",
|
||||
"user__last_name",
|
||||
"user__email",
|
||||
"matiere__name",
|
||||
)
|
||||
actions = ["reset"]
|
||||
actions_on_bottom = True
|
||||
|
||||
def reset(self, request, queryset):
|
||||
queryset.update(count=0)
|
||||
|
||||
reset.short_description = "Remise à zéro du compteur"
|
||||
|
||||
|
||||
class PetitCoursDemandeAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'email', 'agrege_requis', 'niveau', 'created',
|
||||
'traitee', 'processed')
|
||||
list_filter = ('traitee', 'niveau')
|
||||
search_fields = ('name', 'email', 'phone', 'lieu', 'remarques')
|
||||
list_display = (
|
||||
"name",
|
||||
"email",
|
||||
"agrege_requis",
|
||||
"niveau",
|
||||
"created",
|
||||
"traitee",
|
||||
"processed",
|
||||
)
|
||||
list_filter = ("traitee", "niveau")
|
||||
search_fields = ("name", "email", "phone", "lieu", "remarques")
|
||||
|
||||
|
||||
class ClubAdminForm(forms.ModelForm):
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
respos = cleaned_data.get('respos')
|
||||
members = cleaned_data.get('membres')
|
||||
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())
|
||||
% respo.get_full_name()
|
||||
)
|
||||
return cleaned_data
|
||||
|
||||
|
||||
class ClubAdmin(admin.ModelAdmin):
|
||||
list_display = ['name']
|
||||
list_display = ["name"]
|
||||
form = ClubAdminForm
|
||||
|
||||
|
||||
|
@ -294,7 +328,6 @@ admin.site.register(Club, ClubAdmin)
|
|||
admin.site.register(PetitCoursSubject)
|
||||
admin.site.register(PetitCoursAbility, PetitCoursAbilityAdmin)
|
||||
admin.site.register(PetitCoursAttribution, PetitCoursAttributionAdmin)
|
||||
admin.site.register(PetitCoursAttributionCounter,
|
||||
PetitCoursAttributionCounterAdmin)
|
||||
admin.site.register(PetitCoursAttributionCounter, PetitCoursAttributionCounterAdmin)
|
||||
admin.site.register(PetitCoursDemande, PetitCoursDemandeAdmin)
|
||||
admin.site.register(EventRegistration, EventRegistrationAdmin)
|
||||
|
|
|
@ -2,14 +2,16 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class GestioncofConfig(AppConfig):
|
||||
name = 'gestioncof'
|
||||
name = "gestioncof"
|
||||
verbose_name = "Gestion des adhérents du COF"
|
||||
|
||||
def ready(self):
|
||||
from . import signals
|
||||
|
||||
self.register_config()
|
||||
|
||||
def register_config(self):
|
||||
import djconfig
|
||||
from .forms import GestioncofConfigForm
|
||||
|
||||
djconfig.register(GestioncofConfigForm)
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
from django import shortcuts
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.db.models import Q
|
||||
from django.http import Http404
|
||||
from ldap3 import Connection
|
||||
|
||||
from django import shortcuts
|
||||
from django.http import Http404
|
||||
from django.db.models import Q
|
||||
from django.contrib.auth.models import User
|
||||
from django.conf import settings
|
||||
|
||||
from gestioncof.models import CofProfile
|
||||
from gestioncof.decorators import buro_required
|
||||
from gestioncof.models import CofProfile
|
||||
|
||||
|
||||
class Clipper(object):
|
||||
|
@ -20,74 +19,70 @@ class Clipper(object):
|
|||
self.fullname = fullname
|
||||
|
||||
def __str__(self):
|
||||
return '{} ({})'.format(self.clipper, self.fullname)
|
||||
return "{} ({})".format(self.clipper, self.fullname)
|
||||
|
||||
def __eq__(self, other):
|
||||
return (
|
||||
self.clipper == other.clipper and self.fullname == other.fullname)
|
||||
return self.clipper == other.clipper and self.fullname == other.fullname
|
||||
|
||||
|
||||
@buro_required
|
||||
def autocomplete(request):
|
||||
if "q" not in request.GET:
|
||||
raise Http404
|
||||
q = request.GET['q']
|
||||
data = {
|
||||
'q': q,
|
||||
}
|
||||
q = request.GET["q"]
|
||||
data = {"q": q}
|
||||
|
||||
queries = {}
|
||||
bits = q.split()
|
||||
|
||||
# Fetching data from User and CofProfile tables
|
||||
queries['members'] = CofProfile.objects.filter(is_cof=True)
|
||||
queries['users'] = User.objects.filter(profile__is_cof=False)
|
||||
queries["members"] = CofProfile.objects.filter(is_cof=True)
|
||||
queries["users"] = User.objects.filter(profile__is_cof=False)
|
||||
for bit in bits:
|
||||
queries['members'] = queries['members'].filter(
|
||||
queries["members"] = queries["members"].filter(
|
||||
Q(user__first_name__icontains=bit)
|
||||
| Q(user__last_name__icontains=bit)
|
||||
| Q(user__username__icontains=bit)
|
||||
| Q(login_clipper__icontains=bit))
|
||||
queries['users'] = queries['users'].filter(
|
||||
| Q(login_clipper__icontains=bit)
|
||||
)
|
||||
queries["users"] = queries["users"].filter(
|
||||
Q(first_name__icontains=bit)
|
||||
| Q(last_name__icontains=bit)
|
||||
| Q(username__icontains=bit))
|
||||
queries['members'] = queries['members'].distinct()
|
||||
queries['users'] = queries['users'].distinct()
|
||||
| Q(username__icontains=bit)
|
||||
)
|
||||
queries["members"] = queries["members"].distinct()
|
||||
queries["users"] = queries["users"].distinct()
|
||||
|
||||
# Clearing redundancies
|
||||
usernames = (
|
||||
set(queries['members'].values_list('login_clipper', flat='True'))
|
||||
| set(queries['users'].values_list('profile__login_clipper',
|
||||
flat='True'))
|
||||
usernames = set(queries["members"].values_list("login_clipper", flat="True")) | set(
|
||||
queries["users"].values_list("profile__login_clipper", flat="True")
|
||||
)
|
||||
|
||||
# Fetching data from the SPI
|
||||
if getattr(settings, 'LDAP_SERVER_URL', None):
|
||||
if getattr(settings, "LDAP_SERVER_URL", None):
|
||||
# Fetching
|
||||
ldap_query = '(&{:s})'.format(''.join(
|
||||
'(|(cn=*{bit:s}*)(uid=*{bit:s}*))'.format(bit=bit)
|
||||
for bit in bits if bit.isalnum()
|
||||
))
|
||||
ldap_query = "(&{:s})".format(
|
||||
"".join(
|
||||
"(|(cn=*{bit:s}*)(uid=*{bit:s}*))".format(bit=bit)
|
||||
for bit in bits
|
||||
if bit.isalnum()
|
||||
)
|
||||
)
|
||||
if ldap_query != "(&)":
|
||||
# If none of the bits were legal, we do not perform the query
|
||||
entries = None
|
||||
with Connection(settings.LDAP_SERVER_URL) as conn:
|
||||
conn.search(
|
||||
'dc=spi,dc=ens,dc=fr', ldap_query,
|
||||
attributes=['uid', 'cn']
|
||||
)
|
||||
conn.search("dc=spi,dc=ens,dc=fr", ldap_query, attributes=["uid", "cn"])
|
||||
entries = conn.entries
|
||||
# Clearing redundancies
|
||||
queries['clippers'] = [
|
||||
queries["clippers"] = [
|
||||
Clipper(entry.uid.value, entry.cn.value)
|
||||
for entry in entries
|
||||
if entry.uid.value
|
||||
and entry.uid.value not in usernames
|
||||
if entry.uid.value and entry.uid.value not in usernames
|
||||
]
|
||||
|
||||
# Resulting data
|
||||
data.update(queries)
|
||||
data['options'] = sum(len(query) for query in queries)
|
||||
data["options"] = sum(len(query) for query in queries)
|
||||
|
||||
return shortcuts.render(request, "autocomplete_user.html", data)
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
import csv
|
||||
|
||||
from django.apps import apps
|
||||
from django.http import HttpResponse, HttpResponseForbidden
|
||||
from django.template.defaultfilters import slugify
|
||||
from django.apps import apps
|
||||
|
||||
|
||||
def export(qs, fields=None):
|
||||
model = qs.model
|
||||
response = HttpResponse(content_type='text/csv')
|
||||
response['Content-Disposition'] = 'attachment; filename=%s.csv' \
|
||||
% slugify(model.__name__)
|
||||
response = HttpResponse(content_type="text/csv")
|
||||
response["Content-Disposition"] = "attachment; filename=%s.csv" % slugify(
|
||||
model.__name__
|
||||
)
|
||||
writer = csv.writer(response)
|
||||
# Write headers to CSV file
|
||||
if fields:
|
||||
|
@ -32,8 +34,9 @@ def export(qs, fields=None):
|
|||
return response
|
||||
|
||||
|
||||
def admin_list_export(request, model_name, app_label, queryset=None,
|
||||
fields=None, list_display=True):
|
||||
def admin_list_export(
|
||||
request, model_name, app_label, queryset=None, fields=None, list_display=True
|
||||
):
|
||||
"""
|
||||
Put the following line in your urls.py BEFORE your admin include
|
||||
(r'^admin/(?P<app_label>[\d\w]+)/(?P<model_name>[\d\w]+)/csv/',
|
||||
|
|
|
@ -8,6 +8,7 @@ def is_cof(user):
|
|||
except:
|
||||
return False
|
||||
|
||||
|
||||
cof_required = user_passes_test(is_cof)
|
||||
|
||||
|
||||
|
@ -18,4 +19,5 @@ def is_buro(user):
|
|||
except:
|
||||
return False
|
||||
|
||||
|
||||
buro_required = user_passes_test(is_buro)
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.contrib.auth.models import User
|
||||
from django.forms.widgets import RadioSelect, CheckboxSelectMultiple
|
||||
from django.forms.formsets import BaseFormSet, formset_factory
|
||||
|
||||
from django.forms.widgets import CheckboxSelectMultiple, RadioSelect
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from djconfig.forms import ConfigForm
|
||||
|
||||
from gestioncof.models import CofProfile, EventCommentValue, \
|
||||
CalendarSubscription, Club
|
||||
from gestioncof.widgets import TriStateCheckbox
|
||||
|
||||
from bda.models import Spectacle
|
||||
from gestioncof.models import CalendarSubscription, Club, CofProfile, EventCommentValue
|
||||
from gestioncof.widgets import TriStateCheckbox
|
||||
|
||||
|
||||
class EventForm(forms.Form):
|
||||
|
@ -28,31 +25,33 @@ class EventForm(forms.Form):
|
|||
choices[choice.event_option.id].append(choice.id)
|
||||
all_choices = choices
|
||||
for option in event.options.all():
|
||||
choices = [(choice.id, choice.value)
|
||||
for choice in option.choices.all()]
|
||||
choices = [(choice.id, choice.value) for choice in option.choices.all()]
|
||||
if option.multi_choices:
|
||||
initial = [] if option.id not in all_choices \
|
||||
else all_choices[option.id]
|
||||
initial = [] if option.id not in all_choices else all_choices[option.id]
|
||||
field = forms.MultipleChoiceField(
|
||||
label=option.name,
|
||||
choices=choices,
|
||||
widget=CheckboxSelectMultiple,
|
||||
required=False,
|
||||
initial=initial)
|
||||
initial=initial,
|
||||
)
|
||||
else:
|
||||
initial = None if option.id not in all_choices \
|
||||
else all_choices[option.id][0]
|
||||
field = forms.ChoiceField(label=option.name,
|
||||
choices=choices,
|
||||
widget=RadioSelect,
|
||||
required=False,
|
||||
initial=initial)
|
||||
initial = (
|
||||
None if option.id not in all_choices else all_choices[option.id][0]
|
||||
)
|
||||
field = forms.ChoiceField(
|
||||
label=option.name,
|
||||
choices=choices,
|
||||
widget=RadioSelect,
|
||||
required=False,
|
||||
initial=initial,
|
||||
)
|
||||
field.option_id = option.id
|
||||
self.fields["option_%d" % option.id] = field
|
||||
|
||||
def choices(self):
|
||||
for name, value in self.cleaned_data.items():
|
||||
if name.startswith('option_'):
|
||||
if name.startswith("option_"):
|
||||
yield (self.fields[name].option_id, value)
|
||||
|
||||
|
||||
|
@ -69,31 +68,33 @@ class SurveyForm(forms.Form):
|
|||
else:
|
||||
answers[answer.survey_question.id].append(answer.id)
|
||||
for question in survey.questions.all():
|
||||
choices = [(answer.id, answer.answer)
|
||||
for answer in question.answers.all()]
|
||||
choices = [(answer.id, answer.answer) for answer in question.answers.all()]
|
||||
if question.multi_answers:
|
||||
initial = [] if question.id not in answers\
|
||||
else answers[question.id]
|
||||
initial = [] if question.id not in answers else answers[question.id]
|
||||
field = forms.MultipleChoiceField(
|
||||
label=question.question,
|
||||
choices=choices,
|
||||
widget=CheckboxSelectMultiple,
|
||||
required=False,
|
||||
initial=initial)
|
||||
initial=initial,
|
||||
)
|
||||
else:
|
||||
initial = None if question.id not in answers\
|
||||
else answers[question.id][0]
|
||||
field = forms.ChoiceField(label=question.question,
|
||||
choices=choices,
|
||||
widget=RadioSelect,
|
||||
required=False,
|
||||
initial=initial)
|
||||
initial = (
|
||||
None if question.id not in answers else answers[question.id][0]
|
||||
)
|
||||
field = forms.ChoiceField(
|
||||
label=question.question,
|
||||
choices=choices,
|
||||
widget=RadioSelect,
|
||||
required=False,
|
||||
initial=initial,
|
||||
)
|
||||
field.question_id = question.id
|
||||
self.fields["question_%d" % question.id] = field
|
||||
|
||||
def answers(self):
|
||||
for name, value in self.cleaned_data.items():
|
||||
if name.startswith('question_'):
|
||||
if name.startswith("question_"):
|
||||
yield (self.fields[name].question_id, value)
|
||||
|
||||
|
||||
|
@ -104,8 +105,7 @@ class SurveyStatusFilterForm(forms.Form):
|
|||
for question in survey.questions.all():
|
||||
for answer in question.answers.all():
|
||||
name = "question_%d_answer_%d" % (question.id, answer.id)
|
||||
if self.is_bound \
|
||||
and self.data.get(self.add_prefix(name), None):
|
||||
if self.is_bound and self.data.get(self.add_prefix(name), None):
|
||||
initial = self.data.get(self.add_prefix(name), None)
|
||||
else:
|
||||
initial = "none"
|
||||
|
@ -114,16 +114,20 @@ class SurveyStatusFilterForm(forms.Form):
|
|||
choices=[("yes", "yes"), ("no", "no"), ("none", "none")],
|
||||
widget=TriStateCheckbox,
|
||||
required=False,
|
||||
initial=initial)
|
||||
initial=initial,
|
||||
)
|
||||
field.question_id = question.id
|
||||
field.answer_id = answer.id
|
||||
self.fields[name] = field
|
||||
|
||||
def filters(self):
|
||||
for name, value in self.cleaned_data.items():
|
||||
if name.startswith('question_'):
|
||||
yield (self.fields[name].question_id,
|
||||
self.fields[name].answer_id, value)
|
||||
if name.startswith("question_"):
|
||||
yield (
|
||||
self.fields[name].question_id,
|
||||
self.fields[name].answer_id,
|
||||
value,
|
||||
)
|
||||
|
||||
|
||||
class EventStatusFilterForm(forms.Form):
|
||||
|
@ -133,8 +137,7 @@ class EventStatusFilterForm(forms.Form):
|
|||
for option in event.options.all():
|
||||
for choice in option.choices.all():
|
||||
name = "option_%d_choice_%d" % (option.id, choice.id)
|
||||
if self.is_bound \
|
||||
and self.data.get(self.add_prefix(name), None):
|
||||
if self.is_bound and self.data.get(self.add_prefix(name), None):
|
||||
initial = self.data.get(self.add_prefix(name), None)
|
||||
else:
|
||||
initial = "none"
|
||||
|
@ -143,7 +146,8 @@ class EventStatusFilterForm(forms.Form):
|
|||
choices=[("yes", "yes"), ("no", "no"), ("none", "none")],
|
||||
widget=TriStateCheckbox,
|
||||
required=False,
|
||||
initial=initial)
|
||||
initial=initial,
|
||||
)
|
||||
field.option_id = option.id
|
||||
field.choice_id = choice.id
|
||||
self.fields[name] = field
|
||||
|
@ -153,19 +157,19 @@ class EventStatusFilterForm(forms.Form):
|
|||
initial = self.data.get(self.add_prefix(name), None)
|
||||
else:
|
||||
initial = "none"
|
||||
field = forms.ChoiceField(label="Événement payé",
|
||||
choices=[("yes", "yes"), ("no", "no"),
|
||||
("none", "none")],
|
||||
widget=TriStateCheckbox,
|
||||
required=False,
|
||||
initial=initial)
|
||||
field = forms.ChoiceField(
|
||||
label="Événement payé",
|
||||
choices=[("yes", "yes"), ("no", "no"), ("none", "none")],
|
||||
widget=TriStateCheckbox,
|
||||
required=False,
|
||||
initial=initial,
|
||||
)
|
||||
self.fields[name] = field
|
||||
|
||||
def filters(self):
|
||||
for name, value in self.cleaned_data.items():
|
||||
if name.startswith('option_'):
|
||||
yield (self.fields[name].option_id,
|
||||
self.fields[name].choice_id, value)
|
||||
if name.startswith("option_"):
|
||||
yield (self.fields[name].option_id, self.fields[name].choice_id, value)
|
||||
elif name == "event_has_paid":
|
||||
yield ("has_paid", None, value)
|
||||
|
||||
|
@ -184,14 +188,14 @@ class ProfileForm(forms.ModelForm):
|
|||
"mailing_cof",
|
||||
"mailing_bda",
|
||||
"mailing_bda_revente",
|
||||
"mailing_unernestaparis"
|
||||
"mailing_unernestaparis",
|
||||
]
|
||||
|
||||
|
||||
class RegistrationUserForm(forms.ModelForm):
|
||||
def __init__(self, *args, **kw):
|
||||
super().__init__(*args, **kw)
|
||||
self.fields['username'].help_text = ""
|
||||
self.fields["username"].help_text = ""
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
|
@ -202,22 +206,23 @@ class RegistrationPassUserForm(RegistrationUserForm):
|
|||
"""
|
||||
Formulaire pour changer le mot de passe d'un utilisateur.
|
||||
"""
|
||||
password1 = forms.CharField(label=_('Mot de passe'),
|
||||
widget=forms.PasswordInput)
|
||||
password2 = forms.CharField(label=_('Confirmation du mot de passe'),
|
||||
widget=forms.PasswordInput)
|
||||
|
||||
password1 = forms.CharField(label=_("Mot de passe"), widget=forms.PasswordInput)
|
||||
password2 = forms.CharField(
|
||||
label=_("Confirmation du mot de passe"), widget=forms.PasswordInput
|
||||
)
|
||||
|
||||
def clean_password2(self):
|
||||
pass1 = self.cleaned_data['password1']
|
||||
pass2 = self.cleaned_data['password2']
|
||||
pass1 = self.cleaned_data["password1"]
|
||||
pass2 = self.cleaned_data["password2"]
|
||||
if pass1 and pass2:
|
||||
if pass1 != pass2:
|
||||
raise forms.ValidationError(_('Mots de passe non identiques.'))
|
||||
raise forms.ValidationError(_("Mots de passe non identiques."))
|
||||
return pass2
|
||||
|
||||
def save(self, commit=True, *args, **kwargs):
|
||||
user = super().save(commit, *args, **kwargs)
|
||||
user.set_password(self.cleaned_data['password2'])
|
||||
user.set_password(self.cleaned_data["password2"])
|
||||
if commit:
|
||||
user.save()
|
||||
return user
|
||||
|
@ -226,48 +231,62 @@ class RegistrationPassUserForm(RegistrationUserForm):
|
|||
class RegistrationProfileForm(forms.ModelForm):
|
||||
def __init__(self, *args, **kw):
|
||||
super().__init__(*args, **kw)
|
||||
self.fields['mailing_cof'].initial = True
|
||||
self.fields['mailing_bda'].initial = True
|
||||
self.fields['mailing_bda_revente'].initial = True
|
||||
self.fields['mailing_unernestaparis'].initial = True
|
||||
self.fields["mailing_cof"].initial = True
|
||||
self.fields["mailing_bda"].initial = True
|
||||
self.fields["mailing_bda_revente"].initial = True
|
||||
self.fields["mailing_unernestaparis"].initial = True
|
||||
|
||||
self.fields.keyOrder = [
|
||||
'login_clipper',
|
||||
'phone',
|
||||
'occupation',
|
||||
'departement',
|
||||
'is_cof',
|
||||
'type_cotiz',
|
||||
'mailing_cof',
|
||||
'mailing_bda',
|
||||
'mailing_bda_revente',
|
||||
"login_clipper",
|
||||
"phone",
|
||||
"occupation",
|
||||
"departement",
|
||||
"is_cof",
|
||||
"type_cotiz",
|
||||
"mailing_cof",
|
||||
"mailing_bda",
|
||||
"mailing_bda_revente",
|
||||
"mailing_unernestaparis",
|
||||
'comments'
|
||||
"comments",
|
||||
]
|
||||
|
||||
class Meta:
|
||||
model = CofProfile
|
||||
fields = ("login_clipper", "phone", "occupation",
|
||||
"departement", "is_cof", "type_cotiz", "mailing_cof",
|
||||
"mailing_bda", "mailing_bda_revente",
|
||||
"mailing_unernestaparis", "comments")
|
||||
fields = (
|
||||
"login_clipper",
|
||||
"phone",
|
||||
"occupation",
|
||||
"departement",
|
||||
"is_cof",
|
||||
"type_cotiz",
|
||||
"mailing_cof",
|
||||
"mailing_bda",
|
||||
"mailing_bda_revente",
|
||||
"mailing_unernestaparis",
|
||||
"comments",
|
||||
)
|
||||
|
||||
|
||||
STATUS_CHOICES = (('no', 'Non'),
|
||||
('wait', 'Oui mais attente paiement'),
|
||||
('paid', 'Oui payé'),)
|
||||
STATUS_CHOICES = (
|
||||
("no", "Non"),
|
||||
("wait", "Oui mais attente paiement"),
|
||||
("paid", "Oui payé"),
|
||||
)
|
||||
|
||||
|
||||
class AdminEventForm(forms.Form):
|
||||
status = forms.ChoiceField(label="Inscription", initial="no",
|
||||
choices=STATUS_CHOICES, widget=RadioSelect)
|
||||
status = forms.ChoiceField(
|
||||
label="Inscription", initial="no", choices=STATUS_CHOICES, widget=RadioSelect
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.event = kwargs.pop("event")
|
||||
registration = kwargs.pop("current_registration", None)
|
||||
current_choices, paid = \
|
||||
(registration.options.all(), registration.paid) \
|
||||
if registration is not None else ([], None)
|
||||
current_choices, paid = (
|
||||
(registration.options.all(), registration.paid)
|
||||
if registration is not None
|
||||
else ([], None)
|
||||
)
|
||||
if paid is True:
|
||||
kwargs["initial"] = {"status": "paid"}
|
||||
elif paid is False:
|
||||
|
@ -283,66 +302,69 @@ class AdminEventForm(forms.Form):
|
|||
choices[choice.event_option.id].append(choice.id)
|
||||
all_choices = choices
|
||||
for option in self.event.options.all():
|
||||
choices = [(choice.id, choice.value)
|
||||
for choice in option.choices.all()]
|
||||
choices = [(choice.id, choice.value) for choice in option.choices.all()]
|
||||
if option.multi_choices:
|
||||
initial = [] if option.id not in all_choices\
|
||||
else all_choices[option.id]
|
||||
initial = [] if option.id not in all_choices else all_choices[option.id]
|
||||
field = forms.MultipleChoiceField(
|
||||
label=option.name,
|
||||
choices=choices,
|
||||
widget=CheckboxSelectMultiple,
|
||||
required=False,
|
||||
initial=initial)
|
||||
initial=initial,
|
||||
)
|
||||
else:
|
||||
initial = None if option.id not in all_choices\
|
||||
else all_choices[option.id][0]
|
||||
field = forms.ChoiceField(label=option.name,
|
||||
choices=choices,
|
||||
widget=RadioSelect,
|
||||
required=False,
|
||||
initial=initial)
|
||||
initial = (
|
||||
None if option.id not in all_choices else all_choices[option.id][0]
|
||||
)
|
||||
field = forms.ChoiceField(
|
||||
label=option.name,
|
||||
choices=choices,
|
||||
widget=RadioSelect,
|
||||
required=False,
|
||||
initial=initial,
|
||||
)
|
||||
field.option_id = option.id
|
||||
self.fields["option_%d" % option.id] = field
|
||||
for commentfield in self.event.commentfields.all():
|
||||
initial = commentfield.default
|
||||
if registration is not None:
|
||||
try:
|
||||
initial = registration.comments \
|
||||
.get(commentfield=commentfield).content
|
||||
initial = registration.comments.get(
|
||||
commentfield=commentfield
|
||||
).content
|
||||
except EventCommentValue.DoesNotExist:
|
||||
pass
|
||||
widget = forms.Textarea if commentfield.fieldtype == "text" \
|
||||
else forms.TextInput
|
||||
field = forms.CharField(label=commentfield.name,
|
||||
widget=widget,
|
||||
required=False,
|
||||
initial=initial)
|
||||
widget = (
|
||||
forms.Textarea if commentfield.fieldtype == "text" else forms.TextInput
|
||||
)
|
||||
field = forms.CharField(
|
||||
label=commentfield.name, widget=widget, required=False, initial=initial
|
||||
)
|
||||
field.comment_id = commentfield.id
|
||||
self.fields["comment_%d" % commentfield.id] = field
|
||||
|
||||
def choices(self):
|
||||
for name, value in self.cleaned_data.items():
|
||||
if name.startswith('option_'):
|
||||
if name.startswith("option_"):
|
||||
yield (self.fields[name].option_id, value)
|
||||
|
||||
def comments(self):
|
||||
for name, value in self.cleaned_data.items():
|
||||
if name.startswith('comment_'):
|
||||
if name.startswith("comment_"):
|
||||
yield (self.fields[name].comment_id, value)
|
||||
|
||||
|
||||
class BaseEventRegistrationFormset(BaseFormSet):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.events = kwargs.pop('events')
|
||||
self.current_registrations = kwargs.pop('current_registrations', None)
|
||||
self.events = kwargs.pop("events")
|
||||
self.current_registrations = kwargs.pop("current_registrations", None)
|
||||
self.extra = len(self.events)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def _construct_form(self, index, **kwargs):
|
||||
kwargs['event'] = self.events[index]
|
||||
kwargs["event"] = self.events[index]
|
||||
if self.current_registrations is not None:
|
||||
kwargs['current_registration'] = self.current_registrations[index]
|
||||
kwargs["current_registration"] = self.current_registrations[index]
|
||||
return super()._construct_form(index, **kwargs)
|
||||
|
||||
|
||||
|
@ -351,34 +373,36 @@ EventFormset = formset_factory(AdminEventForm, BaseEventRegistrationFormset)
|
|||
|
||||
class CalendarForm(forms.ModelForm):
|
||||
subscribe_to_events = forms.BooleanField(
|
||||
initial=True,
|
||||
label="Événements du COF",
|
||||
required=False)
|
||||
initial=True, label="Événements du COF", required=False
|
||||
)
|
||||
subscribe_to_my_shows = forms.BooleanField(
|
||||
initial=True,
|
||||
label="Les spectacles pour lesquels j'ai obtenu une place",
|
||||
required=False)
|
||||
initial=True,
|
||||
label="Les spectacles pour lesquels j'ai obtenu une place",
|
||||
required=False,
|
||||
)
|
||||
other_shows = forms.ModelMultipleChoiceField(
|
||||
label="Spectacles supplémentaires",
|
||||
queryset=Spectacle.objects.filter(tirage__active=True),
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
required=False)
|
||||
label="Spectacles supplémentaires",
|
||||
queryset=Spectacle.objects.filter(tirage__active=True),
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
required=False,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = CalendarSubscription
|
||||
fields = ['subscribe_to_events', 'subscribe_to_my_shows',
|
||||
'other_shows']
|
||||
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)
|
||||
label="Inscriptions aux clubs du COF",
|
||||
queryset=Club.objects.all(),
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
required=False,
|
||||
)
|
||||
|
||||
|
||||
# ---
|
||||
|
@ -386,9 +410,10 @@ class ClubsForm(forms.Form):
|
|||
# TODO: move this to the `gestion` app once the supportBDS branch is merged
|
||||
# ---
|
||||
|
||||
|
||||
class GestioncofConfigForm(ConfigForm):
|
||||
gestion_banner = forms.CharField(
|
||||
label=_("Announcements banner"),
|
||||
help_text=_("An empty banner disables annoucements"),
|
||||
max_length=2048
|
||||
max_length=2048,
|
||||
)
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
Un mixin à utiliser avec BaseCommand pour charger des objets depuis un json
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
import os
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
|
@ -13,15 +13,14 @@ class MyBaseCommand(BaseCommand):
|
|||
Ajoute une méthode ``from_json`` qui charge des objets à partir d'un json.
|
||||
"""
|
||||
|
||||
def from_json(self, filename, data_dir, klass,
|
||||
callback=lambda obj: obj):
|
||||
def from_json(self, filename, data_dir, klass, callback=lambda obj: obj):
|
||||
"""
|
||||
Charge les objets contenus dans le fichier json référencé par
|
||||
``filename`` dans la base de donnée. La fonction callback est appelées
|
||||
sur chaque objet avant enregistrement.
|
||||
"""
|
||||
self.stdout.write("Chargement de {:s}".format(filename))
|
||||
with open(os.path.join(data_dir, filename), 'r') as file:
|
||||
with open(os.path.join(data_dir, filename), "r") as file:
|
||||
descriptions = json.load(file)
|
||||
objects = []
|
||||
nb_new = 0
|
||||
|
@ -36,6 +35,7 @@ class MyBaseCommand(BaseCommand):
|
|||
objects.append(obj)
|
||||
nb_new += 1
|
||||
self.stdout.write("- {:d} objets créés".format(nb_new))
|
||||
self.stdout.write("- {:d} objets gardés en l'état"
|
||||
.format(len(objects)-nb_new))
|
||||
self.stdout.write(
|
||||
"- {:d} objets gardés en l'état".format(len(objects) - nb_new)
|
||||
)
|
||||
return objects
|
||||
|
|
|
@ -15,13 +15,14 @@ from django.core.management import call_command
|
|||
|
||||
from gestioncof.management.base import MyBaseCommand
|
||||
from gestioncof.petits_cours_models import (
|
||||
PetitCoursAbility, PetitCoursSubject, LEVELS_CHOICES,
|
||||
PetitCoursAttributionCounter
|
||||
LEVELS_CHOICES,
|
||||
PetitCoursAbility,
|
||||
PetitCoursAttributionCounter,
|
||||
PetitCoursSubject,
|
||||
)
|
||||
|
||||
# Où sont stockés les fichiers json
|
||||
DATA_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)),
|
||||
'data')
|
||||
DATA_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "data")
|
||||
|
||||
|
||||
class Command(MyBaseCommand):
|
||||
|
@ -32,11 +33,11 @@ class Command(MyBaseCommand):
|
|||
Permet de ne pas créer l'utilisateur "root".
|
||||
"""
|
||||
parser.add_argument(
|
||||
'--no-root',
|
||||
action='store_true',
|
||||
dest='no-root',
|
||||
"--no-root",
|
||||
action="store_true",
|
||||
dest="no-root",
|
||||
default=False,
|
||||
help='Ne crée pas l\'utilisateur "root"'
|
||||
help='Ne crée pas l\'utilisateur "root"',
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
|
@ -45,24 +46,25 @@ class Command(MyBaseCommand):
|
|||
# ---
|
||||
|
||||
# Gaulois
|
||||
gaulois = self.from_json('gaulois.json', DATA_DIR, User)
|
||||
gaulois = self.from_json("gaulois.json", DATA_DIR, User)
|
||||
for user in gaulois:
|
||||
user.profile.is_cof = True
|
||||
user.profile.save()
|
||||
|
||||
# Romains
|
||||
self.from_json('romains.json', DATA_DIR, User)
|
||||
self.from_json("romains.json", DATA_DIR, User)
|
||||
|
||||
# Root
|
||||
no_root = options.get('no-root', False)
|
||||
no_root = options.get("no-root", False)
|
||||
if not no_root:
|
||||
self.stdout.write("Création de l'utilisateur root")
|
||||
root, _ = User.objects.get_or_create(
|
||||
username='root',
|
||||
first_name='super',
|
||||
last_name='user',
|
||||
email='root@localhost')
|
||||
root.set_password('root')
|
||||
username="root",
|
||||
first_name="super",
|
||||
last_name="user",
|
||||
email="root@localhost",
|
||||
)
|
||||
root.set_password("root")
|
||||
root.is_staff = True
|
||||
root.is_superuser = True
|
||||
root.profile.is_cof = True
|
||||
|
@ -87,18 +89,17 @@ class Command(MyBaseCommand):
|
|||
# L'utilisateur est compétent dans une matière
|
||||
subject = random.choice(subjects)
|
||||
if not PetitCoursAbility.objects.filter(
|
||||
user=user,
|
||||
matiere=subject).exists():
|
||||
user=user, matiere=subject
|
||||
).exists():
|
||||
PetitCoursAbility.objects.create(
|
||||
user=user,
|
||||
matiere=subject,
|
||||
niveau=random.choice(levels),
|
||||
agrege=bool(random.randint(0, 1))
|
||||
agrege=bool(random.randint(0, 1)),
|
||||
)
|
||||
# On initialise son compteur d'attributions
|
||||
PetitCoursAttributionCounter.objects.get_or_create(
|
||||
user=user,
|
||||
matiere=subject
|
||||
user=user, matiere=subject
|
||||
)
|
||||
self.stdout.write("- {:d} inscriptions".format(nb_of_teachers))
|
||||
|
||||
|
@ -106,10 +107,10 @@ class Command(MyBaseCommand):
|
|||
# Le BdA
|
||||
# ---
|
||||
|
||||
call_command('loadbdadevdata')
|
||||
call_command("loadbdadevdata")
|
||||
|
||||
# ---
|
||||
# La K-Fêt
|
||||
# ---
|
||||
|
||||
call_command('loadkfetdevdata')
|
||||
call_command("loadkfetdevdata")
|
||||
|
|
|
@ -4,11 +4,10 @@ Import des mails de GestioCOF dans la base de donnée
|
|||
|
||||
import json
|
||||
import os
|
||||
from custommail.models import Type, CustomMail, Variable
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from custommail.models import CustomMail, Type, Variable
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
DATA_LOCATION = os.path.join(os.path.dirname(__file__), "..", "data", "custommail.json")
|
||||
|
||||
|
@ -19,15 +18,15 @@ def dummy_log(__):
|
|||
|
||||
# XXX. this should probably be in the custommail package
|
||||
def load_from_file(log=dummy_log, verbosity=1):
|
||||
with open(DATA_LOCATION, 'r') as jsonfile:
|
||||
with open(DATA_LOCATION, "r") as jsonfile:
|
||||
mail_data = json.load(jsonfile)
|
||||
|
||||
# On se souvient à quel objet correspond quel pk du json
|
||||
assoc = {'types': {}, 'mails': {}}
|
||||
status = {'synced': 0, 'unchanged': 0}
|
||||
assoc = {"types": {}, "mails": {}}
|
||||
status = {"synced": 0, "unchanged": 0}
|
||||
|
||||
for obj in mail_data:
|
||||
fields = obj['fields']
|
||||
fields = obj["fields"]
|
||||
|
||||
# Pour les trois types d'objets :
|
||||
# - On récupère les objets référencés par les clefs étrangères
|
||||
|
@ -36,58 +35,55 @@ def load_from_file(log=dummy_log, verbosity=1):
|
|||
# plus haut
|
||||
|
||||
# Variable types
|
||||
if obj['model'] == 'custommail.variabletype':
|
||||
fields['inner1'] = assoc['types'].get(fields['inner1'])
|
||||
fields['inner2'] = assoc['types'].get(fields['inner2'])
|
||||
if fields['kind'] == 'model':
|
||||
fields['content_type'] = (
|
||||
ContentType.objects
|
||||
.get_by_natural_key(*fields['content_type'])
|
||||
if obj["model"] == "custommail.variabletype":
|
||||
fields["inner1"] = assoc["types"].get(fields["inner1"])
|
||||
fields["inner2"] = assoc["types"].get(fields["inner2"])
|
||||
if fields["kind"] == "model":
|
||||
fields["content_type"] = ContentType.objects.get_by_natural_key(
|
||||
*fields["content_type"]
|
||||
)
|
||||
var_type, _ = Type.objects.get_or_create(**fields)
|
||||
assoc['types'][obj['pk']] = var_type
|
||||
assoc["types"][obj["pk"]] = var_type
|
||||
|
||||
# Custom mails
|
||||
if obj['model'] == 'custommail.custommail':
|
||||
if obj["model"] == "custommail.custommail":
|
||||
mail = None
|
||||
try:
|
||||
mail = CustomMail.objects.get(shortname=fields['shortname'])
|
||||
status['unchanged'] += 1
|
||||
mail = CustomMail.objects.get(shortname=fields["shortname"])
|
||||
status["unchanged"] += 1
|
||||
except CustomMail.DoesNotExist:
|
||||
mail = CustomMail.objects.create(**fields)
|
||||
status['synced'] += 1
|
||||
status["synced"] += 1
|
||||
if verbosity:
|
||||
log('SYNCED {:s}'.format(fields['shortname']))
|
||||
assoc['mails'][obj['pk']] = mail
|
||||
log("SYNCED {:s}".format(fields["shortname"]))
|
||||
assoc["mails"][obj["pk"]] = mail
|
||||
|
||||
# Variables
|
||||
if obj['model'] == 'custommail.custommailvariable':
|
||||
fields['custommail'] = assoc['mails'].get(fields['custommail'])
|
||||
fields['type'] = assoc['types'].get(fields['type'])
|
||||
if obj["model"] == "custommail.custommailvariable":
|
||||
fields["custommail"] = assoc["mails"].get(fields["custommail"])
|
||||
fields["type"] = assoc["types"].get(fields["type"])
|
||||
try:
|
||||
Variable.objects.get(
|
||||
custommail=fields['custommail'],
|
||||
name=fields['name']
|
||||
custommail=fields["custommail"], name=fields["name"]
|
||||
)
|
||||
except Variable.DoesNotExist:
|
||||
Variable.objects.create(**fields)
|
||||
|
||||
if verbosity:
|
||||
log(
|
||||
'{synced:d} mails synchronized {unchanged:d} unchanged'
|
||||
.format(**status)
|
||||
)
|
||||
log("{synced:d} mails synchronized {unchanged:d} unchanged".format(**status))
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = ("Va chercher les données mails de GestioCOF stocké au format json "
|
||||
"dans /gestioncof/management/data/custommails.json. Le format des "
|
||||
"données est celui donné par la commande :"
|
||||
" `python manage.py dumpdata custommail --natural-foreign` "
|
||||
"La bonne façon de mettre à jour ce fichier est donc de le "
|
||||
"charger à l'aide de syncmails, le faire les modifications à "
|
||||
"l'aide de l'interface administration et/ou du shell puis de le "
|
||||
"remplacer par le nouveau résultat de la commande précédente.")
|
||||
help = (
|
||||
"Va chercher les données mails de GestioCOF stocké au format json "
|
||||
"dans /gestioncof/management/data/custommails.json. Le format des "
|
||||
"données est celui donné par la commande :"
|
||||
" `python manage.py dumpdata custommail --natural-foreign` "
|
||||
"La bonne façon de mettre à jour ce fichier est donc de le "
|
||||
"charger à l'aide de syncmails, le faire les modifications à "
|
||||
"l'aide de l'interface administration et/ou du shell puis de le "
|
||||
"remplacer par le nouveau résultat de la commande précédente."
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
load_from_file(log=self.stdout.write)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,14 +6,14 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestioncof', '0001_initial'),
|
||||
]
|
||||
dependencies = [("gestioncof", "0001_initial")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='petitcoursdemande',
|
||||
name='processed',
|
||||
field=models.DateTimeField(null=True, verbose_name='Date de traitement', blank=True),
|
||||
),
|
||||
model_name="petitcoursdemande",
|
||||
name="processed",
|
||||
field=models.DateTimeField(
|
||||
null=True, verbose_name="Date de traitement", blank=True
|
||||
),
|
||||
)
|
||||
]
|
||||
|
|
|
@ -6,14 +6,14 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestioncof', '0002_enable_unprocessed_demandes'),
|
||||
]
|
||||
dependencies = [("gestioncof", "0002_enable_unprocessed_demandes")]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='event',
|
||||
name='image',
|
||||
field=models.ImageField(upload_to=b'imgs/events/', null=True, verbose_name=b'Image', blank=True),
|
||||
),
|
||||
model_name="event",
|
||||
name="image",
|
||||
field=models.ImageField(
|
||||
upload_to=b"imgs/events/", null=True, verbose_name=b"Image", blank=True
|
||||
),
|
||||
)
|
||||
]
|
||||
|
|
|
@ -8,27 +8,28 @@ 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é " \
|
||||
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.")
|
||||
])
|
||||
comments="{{ nom }} \t fullname de la personne.\n"
|
||||
+ "{{ prenom }} \t prénom de la personne.",
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestioncof', '0003_event_image'),
|
||||
]
|
||||
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),
|
||||
migrations.RunPython(create_mail, migrations.RunPython.noop)
|
||||
]
|
||||
|
|
|
@ -6,62 +6,71 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestioncof', '0004_registration_mail'),
|
||||
]
|
||||
dependencies = [("gestioncof", "0004_registration_mail")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='custommail',
|
||||
options={'verbose_name': 'Mail personnalisable', 'verbose_name_plural': 'Mails personnalisables'},
|
||||
name="custommail",
|
||||
options={
|
||||
"verbose_name": "Mail personnalisable",
|
||||
"verbose_name_plural": "Mails personnalisables",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='eventoptionchoice',
|
||||
options={'verbose_name': 'Choix', 'verbose_name_plural': 'Choix'},
|
||||
name="eventoptionchoice",
|
||||
options={"verbose_name": "Choix", "verbose_name_plural": "Choix"},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cofprofile',
|
||||
name='is_buro',
|
||||
field=models.BooleanField(default=False, verbose_name='Membre du Bur\xf4'),
|
||||
model_name="cofprofile",
|
||||
name="is_buro",
|
||||
field=models.BooleanField(default=False, verbose_name="Membre du Bur\xf4"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cofprofile',
|
||||
name='num',
|
||||
field=models.IntegerField(default=0, verbose_name="Num\xe9ro d'adh\xe9rent", blank=True),
|
||||
model_name="cofprofile",
|
||||
name="num",
|
||||
field=models.IntegerField(
|
||||
default=0, verbose_name="Num\xe9ro d'adh\xe9rent", blank=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cofprofile',
|
||||
name='phone',
|
||||
field=models.CharField(max_length=20, verbose_name='T\xe9l\xe9phone', blank=True),
|
||||
model_name="cofprofile",
|
||||
name="phone",
|
||||
field=models.CharField(
|
||||
max_length=20, verbose_name="T\xe9l\xe9phone", blank=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='old',
|
||||
field=models.BooleanField(default=False, verbose_name='Archiver (\xe9v\xe9nement fini)'),
|
||||
model_name="event",
|
||||
name="old",
|
||||
field=models.BooleanField(
|
||||
default=False, verbose_name="Archiver (\xe9v\xe9nement fini)"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='start_date',
|
||||
field=models.DateField(null=True, verbose_name='Date de d\xe9but', blank=True),
|
||||
model_name="event",
|
||||
name="start_date",
|
||||
field=models.DateField(
|
||||
null=True, verbose_name="Date de d\xe9but", blank=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='eventcommentfield',
|
||||
name='default',
|
||||
field=models.TextField(verbose_name='Valeur par d\xe9faut', blank=True),
|
||||
model_name="eventcommentfield",
|
||||
name="default",
|
||||
field=models.TextField(verbose_name="Valeur par d\xe9faut", blank=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='eventregistration',
|
||||
name='paid',
|
||||
field=models.BooleanField(default=False, verbose_name='A pay\xe9'),
|
||||
model_name="eventregistration",
|
||||
name="paid",
|
||||
field=models.BooleanField(default=False, verbose_name="A pay\xe9"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='survey',
|
||||
name='details',
|
||||
field=models.TextField(verbose_name='D\xe9tails', blank=True),
|
||||
model_name="survey",
|
||||
name="details",
|
||||
field=models.TextField(verbose_name="D\xe9tails", blank=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='surveyquestionanswer',
|
||||
name='answer',
|
||||
field=models.CharField(max_length=200, verbose_name='R\xe9ponse'),
|
||||
model_name="surveyquestionanswer",
|
||||
name="answer",
|
||||
field=models.CharField(max_length=200, verbose_name="R\xe9ponse"),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,51 +1,66 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('bda', '0004_mails-rappel'),
|
||||
("bda", "0004_mails-rappel"),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('gestioncof', '0005_encoding'),
|
||||
("gestioncof", "0005_encoding"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='CalendarSubscription',
|
||||
name="CalendarSubscription",
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False,
|
||||
auto_created=True, primary_key=True)),
|
||||
('token', models.UUIDField()),
|
||||
('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,
|
||||
on_delete=models.CASCADE)),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
verbose_name="ID",
|
||||
serialize=False,
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
),
|
||||
),
|
||||
("token", models.UUIDField()),
|
||||
("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, on_delete=models.CASCADE
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='custommail',
|
||||
options={'verbose_name': 'Mail personnalisable',
|
||||
'verbose_name_plural': 'Mails personnalisables'},
|
||||
name="custommail",
|
||||
options={
|
||||
"verbose_name": "Mail personnalisable",
|
||||
"verbose_name_plural": "Mails personnalisables",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='eventoptionchoice',
|
||||
options={'verbose_name': 'Choix', 'verbose_name_plural': 'Choix'},
|
||||
name="eventoptionchoice",
|
||||
options={"verbose_name": "Choix", "verbose_name_plural": "Choix"},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='end_date',
|
||||
field=models.DateTimeField(null=True, verbose_name=b'Date de fin',
|
||||
blank=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='start_date',
|
||||
model_name="event",
|
||||
name="end_date",
|
||||
field=models.DateTimeField(
|
||||
null=True, verbose_name=b'Date de d\xc3\xa9but', blank=True),
|
||||
null=True, verbose_name=b"Date de fin", blank=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="event",
|
||||
name="start_date",
|
||||
field=models.DateTimeField(
|
||||
null=True, verbose_name=b"Date de d\xc3\xa9but", blank=True
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,47 +1,44 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestioncof', '0006_add_calendar'),
|
||||
]
|
||||
dependencies = [("gestioncof", "0006_add_calendar")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='club',
|
||||
name='name',
|
||||
field=models.CharField(unique=True, max_length=200,
|
||||
verbose_name='Nom')
|
||||
model_name="club",
|
||||
name="name",
|
||||
field=models.CharField(unique=True, max_length=200, verbose_name="Nom"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='club',
|
||||
name='description',
|
||||
field=models.TextField(verbose_name='Description', blank=True)
|
||||
model_name="club",
|
||||
name="description",
|
||||
field=models.TextField(verbose_name="Description", blank=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='club',
|
||||
name='membres',
|
||||
field=models.ManyToManyField(related_name='clubs',
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
blank=True),
|
||||
model_name="club",
|
||||
name="membres",
|
||||
field=models.ManyToManyField(
|
||||
related_name="clubs", to=settings.AUTH_USER_MODEL, blank=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='club',
|
||||
name='respos',
|
||||
field=models.ManyToManyField(related_name='clubs_geres',
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
blank=True),
|
||||
model_name="club",
|
||||
name="respos",
|
||||
field=models.ManyToManyField(
|
||||
related_name="clubs_geres", to=settings.AUTH_USER_MODEL, blank=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='start_date',
|
||||
field=models.DateTimeField(null=True,
|
||||
verbose_name='Date de d\xe9but',
|
||||
blank=True),
|
||||
model_name="event",
|
||||
name="start_date",
|
||||
field=models.DateTimeField(
|
||||
null=True, verbose_name="Date de d\xe9but", blank=True
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
def forwards(apps, schema_editor):
|
||||
|
@ -11,243 +11,266 @@ def forwards(apps, schema_editor):
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestioncof', '0007_alter_club'),
|
||||
]
|
||||
dependencies = [("gestioncof", "0007_alter_club")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='clipper',
|
||||
name='fullname',
|
||||
field=models.CharField(verbose_name='Nom complet', max_length=200),
|
||||
model_name="clipper",
|
||||
name="fullname",
|
||||
field=models.CharField(verbose_name="Nom complet", max_length=200),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='clipper',
|
||||
name='username',
|
||||
field=models.CharField(verbose_name='Identifiant', max_length=20),
|
||||
model_name="clipper",
|
||||
name="username",
|
||||
field=models.CharField(verbose_name="Identifiant", max_length=20),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cofprofile',
|
||||
name='comments',
|
||||
model_name="cofprofile",
|
||||
name="comments",
|
||||
field=models.TextField(
|
||||
verbose_name="Commentaires visibles par l'utilisateur",
|
||||
blank=True),
|
||||
verbose_name="Commentaires visibles par l'utilisateur", blank=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cofprofile',
|
||||
name='is_cof',
|
||||
field=models.BooleanField(verbose_name='Membre du COF',
|
||||
default=False),
|
||||
model_name="cofprofile",
|
||||
name="is_cof",
|
||||
field=models.BooleanField(verbose_name="Membre du COF", default=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cofprofile',
|
||||
name='login_clipper',
|
||||
field=models.CharField(verbose_name='Login clipper', max_length=8,
|
||||
blank=True),
|
||||
model_name="cofprofile",
|
||||
name="login_clipper",
|
||||
field=models.CharField(
|
||||
verbose_name="Login clipper", max_length=8, blank=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cofprofile',
|
||||
name='mailing_bda',
|
||||
field=models.BooleanField(verbose_name='Recevoir les mails BdA',
|
||||
default=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cofprofile',
|
||||
name='mailing_bda_revente',
|
||||
model_name="cofprofile",
|
||||
name="mailing_bda",
|
||||
field=models.BooleanField(
|
||||
verbose_name='Recevoir les mails de revente de places BdA',
|
||||
default=False),
|
||||
verbose_name="Recevoir les mails BdA", default=False
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cofprofile',
|
||||
name='mailing_cof',
|
||||
field=models.BooleanField(verbose_name='Recevoir les mails COF',
|
||||
default=False),
|
||||
model_name="cofprofile",
|
||||
name="mailing_bda_revente",
|
||||
field=models.BooleanField(
|
||||
verbose_name="Recevoir les mails de revente de places BdA",
|
||||
default=False,
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cofprofile',
|
||||
name='occupation',
|
||||
field=models.CharField(verbose_name='Occupation',
|
||||
choices=[('exterieur', 'Extérieur'),
|
||||
('1A', '1A'),
|
||||
('2A', '2A'),
|
||||
('3A', '3A'),
|
||||
('4A', '4A'),
|
||||
('archicube', 'Archicube'),
|
||||
('doctorant', 'Doctorant'),
|
||||
('CST', 'CST')],
|
||||
max_length=9, default='1A'),
|
||||
model_name="cofprofile",
|
||||
name="mailing_cof",
|
||||
field=models.BooleanField(
|
||||
verbose_name="Recevoir les mails COF", default=False
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cofprofile',
|
||||
name='petits_cours_accept',
|
||||
field=models.BooleanField(verbose_name='Recevoir des petits cours',
|
||||
default=False),
|
||||
model_name="cofprofile",
|
||||
name="occupation",
|
||||
field=models.CharField(
|
||||
verbose_name="Occupation",
|
||||
choices=[
|
||||
("exterieur", "Extérieur"),
|
||||
("1A", "1A"),
|
||||
("2A", "2A"),
|
||||
("3A", "3A"),
|
||||
("4A", "4A"),
|
||||
("archicube", "Archicube"),
|
||||
("doctorant", "Doctorant"),
|
||||
("CST", "CST"),
|
||||
],
|
||||
max_length=9,
|
||||
default="1A",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cofprofile',
|
||||
name='petits_cours_remarques',
|
||||
model_name="cofprofile",
|
||||
name="petits_cours_accept",
|
||||
field=models.BooleanField(
|
||||
verbose_name="Recevoir des petits cours", default=False
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="cofprofile",
|
||||
name="petits_cours_remarques",
|
||||
field=models.TextField(
|
||||
blank=True,
|
||||
verbose_name='Remarques et précisions pour les petits cours',
|
||||
default=''),
|
||||
verbose_name="Remarques et précisions pour les petits cours",
|
||||
default="",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cofprofile',
|
||||
name='type_cotiz',
|
||||
model_name="cofprofile",
|
||||
name="type_cotiz",
|
||||
field=models.CharField(
|
||||
verbose_name='Type de cotisation',
|
||||
choices=[('etudiant', 'Normalien étudiant'),
|
||||
('normalien', 'Normalien élève'),
|
||||
('exterieur', 'Extérieur')],
|
||||
max_length=9, default='normalien'),
|
||||
verbose_name="Type de cotisation",
|
||||
choices=[
|
||||
("etudiant", "Normalien étudiant"),
|
||||
("normalien", "Normalien élève"),
|
||||
("exterieur", "Extérieur"),
|
||||
],
|
||||
max_length=9,
|
||||
default="normalien",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='custommail',
|
||||
name='comments',
|
||||
model_name="custommail",
|
||||
name="comments",
|
||||
field=models.TextField(
|
||||
verbose_name='Informations contextuelles sur le mail',
|
||||
blank=True),
|
||||
verbose_name="Informations contextuelles sur le mail", blank=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='custommail',
|
||||
name='content',
|
||||
field=models.TextField(verbose_name='Contenu'),
|
||||
model_name="custommail",
|
||||
name="content",
|
||||
field=models.TextField(verbose_name="Contenu"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='custommail',
|
||||
name='title',
|
||||
field=models.CharField(verbose_name='Titre', max_length=200),
|
||||
model_name="custommail",
|
||||
name="title",
|
||||
field=models.CharField(verbose_name="Titre", max_length=200),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='description',
|
||||
field=models.TextField(verbose_name='Description', blank=True),
|
||||
model_name="event",
|
||||
name="description",
|
||||
field=models.TextField(verbose_name="Description", blank=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='end_date',
|
||||
field=models.DateTimeField(null=True, verbose_name='Date de fin',
|
||||
blank=True),
|
||||
model_name="event",
|
||||
name="end_date",
|
||||
field=models.DateTimeField(
|
||||
null=True, verbose_name="Date de fin", blank=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='image',
|
||||
field=models.ImageField(upload_to='imgs/events/', null=True,
|
||||
verbose_name='Image', blank=True),
|
||||
model_name="event",
|
||||
name="image",
|
||||
field=models.ImageField(
|
||||
upload_to="imgs/events/", null=True, verbose_name="Image", blank=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='location',
|
||||
field=models.CharField(verbose_name='Lieu', max_length=200),
|
||||
model_name="event",
|
||||
name="location",
|
||||
field=models.CharField(verbose_name="Lieu", max_length=200),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='registration_open',
|
||||
field=models.BooleanField(verbose_name='Inscriptions ouvertes',
|
||||
default=True),
|
||||
model_name="event",
|
||||
name="registration_open",
|
||||
field=models.BooleanField(
|
||||
verbose_name="Inscriptions ouvertes", default=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='title',
|
||||
field=models.CharField(verbose_name='Titre', max_length=200),
|
||||
model_name="event",
|
||||
name="title",
|
||||
field=models.CharField(verbose_name="Titre", max_length=200),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='eventcommentfield',
|
||||
name='fieldtype',
|
||||
field=models.CharField(verbose_name='Type',
|
||||
choices=[('text', 'Texte long'),
|
||||
('char', 'Texte court')],
|
||||
max_length=10, default='text'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='eventcommentfield',
|
||||
name='name',
|
||||
field=models.CharField(verbose_name='Champ', max_length=200),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='eventcommentvalue',
|
||||
name='content',
|
||||
field=models.TextField(null=True, verbose_name='Contenu',
|
||||
blank=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='eventoption',
|
||||
name='multi_choices',
|
||||
field=models.BooleanField(verbose_name='Choix multiples',
|
||||
default=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='eventoption',
|
||||
name='name',
|
||||
field=models.CharField(verbose_name='Option', max_length=200),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='eventoptionchoice',
|
||||
name='value',
|
||||
field=models.CharField(verbose_name='Valeur', max_length=200),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='petitcoursability',
|
||||
name='niveau',
|
||||
model_name="eventcommentfield",
|
||||
name="fieldtype",
|
||||
field=models.CharField(
|
||||
choices=[('college', 'Collège'), ('lycee', 'Lycée'),
|
||||
('prepa1styear', 'Prépa 1ère année / L1'),
|
||||
('prepa2ndyear', 'Prépa 2ème année / L2'),
|
||||
('licence3', 'Licence 3'),
|
||||
('other', 'Autre (préciser dans les commentaires)')],
|
||||
max_length=12, verbose_name='Niveau'),
|
||||
verbose_name="Type",
|
||||
choices=[("text", "Texte long"), ("char", "Texte court")],
|
||||
max_length=10,
|
||||
default="text",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='petitcoursattribution',
|
||||
name='rank',
|
||||
model_name="eventcommentfield",
|
||||
name="name",
|
||||
field=models.CharField(verbose_name="Champ", max_length=200),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="eventcommentvalue",
|
||||
name="content",
|
||||
field=models.TextField(null=True, verbose_name="Contenu", blank=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="eventoption",
|
||||
name="multi_choices",
|
||||
field=models.BooleanField(verbose_name="Choix multiples", default=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="eventoption",
|
||||
name="name",
|
||||
field=models.CharField(verbose_name="Option", max_length=200),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="eventoptionchoice",
|
||||
name="value",
|
||||
field=models.CharField(verbose_name="Valeur", max_length=200),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="petitcoursability",
|
||||
name="niveau",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("college", "Collège"),
|
||||
("lycee", "Lycée"),
|
||||
("prepa1styear", "Prépa 1ère année / L1"),
|
||||
("prepa2ndyear", "Prépa 2ème année / L2"),
|
||||
("licence3", "Licence 3"),
|
||||
("other", "Autre (préciser dans les commentaires)"),
|
||||
],
|
||||
max_length=12,
|
||||
verbose_name="Niveau",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="petitcoursattribution",
|
||||
name="rank",
|
||||
field=models.IntegerField(verbose_name="Rang dans l'email"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='petitcoursattributioncounter',
|
||||
name='count',
|
||||
field=models.IntegerField(verbose_name="Nombre d'envois",
|
||||
default=0),
|
||||
model_name="petitcoursattributioncounter",
|
||||
name="count",
|
||||
field=models.IntegerField(verbose_name="Nombre d'envois", default=0),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='petitcoursdemande',
|
||||
name='niveau',
|
||||
model_name="petitcoursdemande",
|
||||
name="niveau",
|
||||
field=models.CharField(
|
||||
verbose_name='Niveau',
|
||||
choices=[('college', 'Collège'), ('lycee', 'Lycée'),
|
||||
('prepa1styear', 'Prépa 1ère année / L1'),
|
||||
('prepa2ndyear', 'Prépa 2ème année / L2'),
|
||||
('licence3', 'Licence 3'),
|
||||
('other', 'Autre (préciser dans les commentaires)')],
|
||||
max_length=12, default=''),
|
||||
verbose_name="Niveau",
|
||||
choices=[
|
||||
("college", "Collège"),
|
||||
("lycee", "Lycée"),
|
||||
("prepa1styear", "Prépa 1ère année / L1"),
|
||||
("prepa2ndyear", "Prépa 2ème année / L2"),
|
||||
("licence3", "Licence 3"),
|
||||
("other", "Autre (préciser dans les commentaires)"),
|
||||
],
|
||||
max_length=12,
|
||||
default="",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='survey',
|
||||
name='old',
|
||||
field=models.BooleanField(verbose_name='Archiver (sondage fini)',
|
||||
default=False),
|
||||
model_name="survey",
|
||||
name="old",
|
||||
field=models.BooleanField(
|
||||
verbose_name="Archiver (sondage fini)", default=False
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='survey',
|
||||
name='survey_open',
|
||||
field=models.BooleanField(verbose_name='Sondage ouvert',
|
||||
default=True),
|
||||
model_name="survey",
|
||||
name="survey_open",
|
||||
field=models.BooleanField(verbose_name="Sondage ouvert", default=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='survey',
|
||||
name='title',
|
||||
field=models.CharField(verbose_name='Titre', max_length=200),
|
||||
model_name="survey",
|
||||
name="title",
|
||||
field=models.CharField(verbose_name="Titre", max_length=200),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='surveyquestion',
|
||||
name='multi_answers',
|
||||
field=models.BooleanField(verbose_name='Choix multiples',
|
||||
default=False),
|
||||
model_name="surveyquestion",
|
||||
name="multi_answers",
|
||||
field=models.BooleanField(verbose_name="Choix multiples", default=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='surveyquestion',
|
||||
name='question',
|
||||
field=models.CharField(verbose_name='Question', max_length=200),
|
||||
model_name="surveyquestion",
|
||||
name="question",
|
||||
field=models.CharField(verbose_name="Question", max_length=200),
|
||||
),
|
||||
migrations.RunPython(forwards, migrations.RunPython.noop),
|
||||
]
|
||||
|
|
|
@ -6,12 +6,6 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestioncof', '0008_py3'),
|
||||
]
|
||||
dependencies = [("gestioncof", "0008_py3")]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(
|
||||
name='Clipper',
|
||||
),
|
||||
]
|
||||
operations = [migrations.DeleteModel(name="Clipper")]
|
||||
|
|
|
@ -5,12 +5,6 @@ from django.db import migrations
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestioncof', '0009_delete_clipper'),
|
||||
]
|
||||
dependencies = [("gestioncof", "0009_delete_clipper")]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(
|
||||
name='CustomMail',
|
||||
),
|
||||
]
|
||||
operations = [migrations.DeleteModel(name="CustomMail")]
|
||||
|
|
|
@ -6,14 +6,14 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestioncof', '0010_delete_custommail'),
|
||||
]
|
||||
dependencies = [("gestioncof", "0010_delete_custommail")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='cofprofile',
|
||||
name='login_clipper',
|
||||
field=models.CharField(verbose_name='Login clipper', blank=True, max_length=32),
|
||||
),
|
||||
model_name="cofprofile",
|
||||
name="login_clipper",
|
||||
field=models.CharField(
|
||||
verbose_name="Login clipper", blank=True, max_length=32
|
||||
),
|
||||
)
|
||||
]
|
||||
|
|
|
@ -6,13 +6,6 @@ from django.db import migrations
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestioncof', '0010_delete_custommail'),
|
||||
]
|
||||
dependencies = [("gestioncof", "0010_delete_custommail")]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='cofprofile',
|
||||
name='num',
|
||||
),
|
||||
]
|
||||
operations = [migrations.RemoveField(model_name="cofprofile", name="num")]
|
||||
|
|
|
@ -7,9 +7,8 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestioncof', '0011_remove_cofprofile_num'),
|
||||
('gestioncof', '0011_longer_clippers'),
|
||||
("gestioncof", "0011_remove_cofprofile_num"),
|
||||
("gestioncof", "0011_longer_clippers"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
||||
operations = []
|
||||
|
|
|
@ -6,42 +6,42 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestioncof', '0012_merge'),
|
||||
]
|
||||
dependencies = [("gestioncof", "0012_merge")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='cofprofile',
|
||||
name='occupation',
|
||||
model_name="cofprofile",
|
||||
name="occupation",
|
||||
field=models.CharField(
|
||||
verbose_name='Occupation',
|
||||
verbose_name="Occupation",
|
||||
max_length=9,
|
||||
default='1A',
|
||||
default="1A",
|
||||
choices=[
|
||||
('exterieur', 'Extérieur'),
|
||||
('1A', '1A'),
|
||||
('2A', '2A'),
|
||||
('3A', '3A'),
|
||||
('4A', '4A'),
|
||||
('archicube', 'Archicube'),
|
||||
('doctorant', 'Doctorant'),
|
||||
('CST', 'CST'),
|
||||
('PEI', 'PEI')
|
||||
]),
|
||||
("exterieur", "Extérieur"),
|
||||
("1A", "1A"),
|
||||
("2A", "2A"),
|
||||
("3A", "3A"),
|
||||
("4A", "4A"),
|
||||
("archicube", "Archicube"),
|
||||
("doctorant", "Doctorant"),
|
||||
("CST", "CST"),
|
||||
("PEI", "PEI"),
|
||||
],
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cofprofile',
|
||||
name='type_cotiz',
|
||||
model_name="cofprofile",
|
||||
name="type_cotiz",
|
||||
field=models.CharField(
|
||||
verbose_name='Type de cotisation',
|
||||
verbose_name="Type de cotisation",
|
||||
max_length=9,
|
||||
default='normalien',
|
||||
default="normalien",
|
||||
choices=[
|
||||
('etudiant', 'Normalien étudiant'),
|
||||
('normalien', 'Normalien élève'),
|
||||
('exterieur', 'Extérieur'),
|
||||
('gratis', 'Gratuit')
|
||||
]),
|
||||
("etudiant", "Normalien étudiant"),
|
||||
("normalien", "Normalien élève"),
|
||||
("exterieur", "Extérieur"),
|
||||
("gratis", "Gratuit"),
|
||||
],
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -7,14 +7,14 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestioncof', '0013_pei'),
|
||||
]
|
||||
dependencies = [("gestioncof", "0013_pei")]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='cofprofile',
|
||||
name='mailing_unernestaparis',
|
||||
field=models.BooleanField(default=False, verbose_name='Recevoir les mails unErnestAParis'),
|
||||
),
|
||||
model_name="cofprofile",
|
||||
name="mailing_unernestaparis",
|
||||
field=models.BooleanField(
|
||||
default=False, verbose_name="Recevoir les mails unErnestAParis"
|
||||
),
|
||||
)
|
||||
]
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
from django.db import models
|
||||
from django.dispatch import receiver
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import models
|
||||
from django.db.models.signals import post_delete, post_save
|
||||
from django.dispatch import receiver
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.db.models.signals import post_save, post_delete
|
||||
|
||||
from gestioncof.petits_cours_models import choices_length
|
||||
|
||||
from bda.models import Spectacle
|
||||
from gestioncof.petits_cours_models import choices_length
|
||||
|
||||
TYPE_COMMENT_FIELD = (
|
||||
('text', _("Texte long")),
|
||||
('char', _("Texte court")),
|
||||
)
|
||||
TYPE_COMMENT_FIELD = (("text", _("Texte long")), ("char", _("Texte court")))
|
||||
|
||||
|
||||
class CofProfile(models.Model):
|
||||
|
@ -49,40 +45,39 @@ class CofProfile(models.Model):
|
|||
(COTIZ_GRATIS, _("Gratuit")),
|
||||
)
|
||||
|
||||
user = models.OneToOneField(
|
||||
User, on_delete=models.CASCADE,
|
||||
related_name="profile",
|
||||
)
|
||||
login_clipper = models.CharField(
|
||||
"Login clipper", max_length=32, blank=True
|
||||
)
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
|
||||
login_clipper = models.CharField("Login clipper", max_length=32, blank=True)
|
||||
is_cof = models.BooleanField("Membre du COF", default=False)
|
||||
phone = models.CharField("Téléphone", max_length=20, blank=True)
|
||||
occupation = models.CharField(_("Occupation"),
|
||||
default="1A",
|
||||
choices=OCCUPATION_CHOICES,
|
||||
max_length=choices_length(
|
||||
OCCUPATION_CHOICES))
|
||||
departement = models.CharField(_("Département"), max_length=50,
|
||||
blank=True)
|
||||
type_cotiz = models.CharField(_("Type de cotisation"),
|
||||
default="normalien",
|
||||
choices=TYPE_COTIZ_CHOICES,
|
||||
max_length=choices_length(
|
||||
TYPE_COTIZ_CHOICES))
|
||||
occupation = models.CharField(
|
||||
_("Occupation"),
|
||||
default="1A",
|
||||
choices=OCCUPATION_CHOICES,
|
||||
max_length=choices_length(OCCUPATION_CHOICES),
|
||||
)
|
||||
departement = models.CharField(_("Département"), max_length=50, blank=True)
|
||||
type_cotiz = models.CharField(
|
||||
_("Type de cotisation"),
|
||||
default="normalien",
|
||||
choices=TYPE_COTIZ_CHOICES,
|
||||
max_length=choices_length(TYPE_COTIZ_CHOICES),
|
||||
)
|
||||
mailing_cof = models.BooleanField("Recevoir les mails COF", default=False)
|
||||
mailing_bda = models.BooleanField("Recevoir les mails BdA", default=False)
|
||||
mailing_unernestaparis = models.BooleanField("Recevoir les mails unErnestAParis", default=False)
|
||||
mailing_unernestaparis = models.BooleanField(
|
||||
"Recevoir les mails unErnestAParis", default=False
|
||||
)
|
||||
mailing_bda_revente = models.BooleanField(
|
||||
"Recevoir les mails de revente de places BdA", default=False)
|
||||
comments = models.TextField(
|
||||
"Commentaires visibles par l'utilisateur", blank=True)
|
||||
"Recevoir les mails de revente de places BdA", default=False
|
||||
)
|
||||
comments = models.TextField("Commentaires visibles par l'utilisateur", blank=True)
|
||||
is_buro = models.BooleanField("Membre du Burô", default=False)
|
||||
petits_cours_accept = models.BooleanField(
|
||||
"Recevoir des petits cours", default=False)
|
||||
"Recevoir des petits cours", default=False
|
||||
)
|
||||
petits_cours_remarques = models.TextField(
|
||||
_("Remarques et précisions pour les petits cours"),
|
||||
blank=True, default="")
|
||||
_("Remarques et précisions pour les petits cours"), blank=True, default=""
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Profil COF"
|
||||
|
@ -106,8 +101,7 @@ def post_delete_user(sender, instance, *args, **kwargs):
|
|||
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)
|
||||
respos = models.ManyToManyField(User, related_name="clubs_geres", blank=True)
|
||||
membres = models.ManyToManyField(User, related_name="clubs", blank=True)
|
||||
|
||||
def __str__(self):
|
||||
|
@ -120,10 +114,8 @@ class Event(models.Model):
|
|||
start_date = models.DateTimeField("Date de début", blank=True, null=True)
|
||||
end_date = models.DateTimeField("Date de fin", blank=True, null=True)
|
||||
description = models.TextField("Description", blank=True)
|
||||
image = models.ImageField("Image", blank=True, null=True,
|
||||
upload_to="imgs/events/")
|
||||
registration_open = models.BooleanField("Inscriptions ouvertes",
|
||||
default=True)
|
||||
image = models.ImageField("Image", blank=True, null=True, upload_to="imgs/events/")
|
||||
registration_open = models.BooleanField("Inscriptions ouvertes", default=True)
|
||||
old = models.BooleanField("Archiver (événement fini)", default=False)
|
||||
|
||||
class Meta:
|
||||
|
@ -135,12 +127,12 @@ class Event(models.Model):
|
|||
|
||||
class EventCommentField(models.Model):
|
||||
event = models.ForeignKey(
|
||||
Event, on_delete=models.CASCADE,
|
||||
related_name="commentfields",
|
||||
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")
|
||||
fieldtype = models.CharField(
|
||||
"Type", max_length=10, choices=TYPE_COMMENT_FIELD, default="text"
|
||||
)
|
||||
default = models.TextField("Valeur par défaut", blank=True)
|
||||
|
||||
class Meta:
|
||||
|
@ -152,12 +144,10 @@ class EventCommentField(models.Model):
|
|||
|
||||
class EventCommentValue(models.Model):
|
||||
commentfield = models.ForeignKey(
|
||||
EventCommentField, on_delete=models.CASCADE,
|
||||
related_name="values",
|
||||
EventCommentField, on_delete=models.CASCADE, related_name="values"
|
||||
)
|
||||
registration = models.ForeignKey(
|
||||
"EventRegistration", on_delete=models.CASCADE,
|
||||
related_name="comments",
|
||||
"EventRegistration", on_delete=models.CASCADE, related_name="comments"
|
||||
)
|
||||
content = models.TextField("Contenu", blank=True, null=True)
|
||||
|
||||
|
@ -166,10 +156,7 @@ class EventCommentValue(models.Model):
|
|||
|
||||
|
||||
class EventOption(models.Model):
|
||||
event = models.ForeignKey(
|
||||
Event, on_delete=models.CASCADE,
|
||||
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)
|
||||
|
||||
|
@ -182,8 +169,7 @@ class EventOption(models.Model):
|
|||
|
||||
class EventOptionChoice(models.Model):
|
||||
event_option = models.ForeignKey(
|
||||
EventOption, on_delete=models.CASCADE,
|
||||
related_name="choices",
|
||||
EventOption, on_delete=models.CASCADE, related_name="choices"
|
||||
)
|
||||
value = models.CharField("Valeur", max_length=200)
|
||||
|
||||
|
@ -199,8 +185,9 @@ class EventRegistration(models.Model):
|
|||
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)
|
||||
filledcomments = models.ManyToManyField(
|
||||
EventCommentField, through=EventCommentValue
|
||||
)
|
||||
paid = models.BooleanField("A payé", default=False)
|
||||
|
||||
class Meta:
|
||||
|
@ -226,8 +213,7 @@ class Survey(models.Model):
|
|||
|
||||
class SurveyQuestion(models.Model):
|
||||
survey = models.ForeignKey(
|
||||
Survey, on_delete=models.CASCADE,
|
||||
related_name="questions",
|
||||
Survey, on_delete=models.CASCADE, related_name="questions"
|
||||
)
|
||||
question = models.CharField("Question", max_length=200)
|
||||
multi_answers = models.BooleanField("Choix multiples", default=False)
|
||||
|
@ -241,8 +227,7 @@ class SurveyQuestion(models.Model):
|
|||
|
||||
class SurveyQuestionAnswer(models.Model):
|
||||
survey_question = models.ForeignKey(
|
||||
SurveyQuestion, on_delete=models.CASCADE,
|
||||
related_name="answers",
|
||||
SurveyQuestion, on_delete=models.CASCADE, related_name="answers"
|
||||
)
|
||||
answer = models.CharField("Réponse", max_length=200)
|
||||
|
||||
|
@ -256,8 +241,7 @@ class SurveyQuestionAnswer(models.Model):
|
|||
class SurveyAnswer(models.Model):
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
survey = models.ForeignKey(Survey, on_delete=models.CASCADE)
|
||||
answers = models.ManyToManyField(SurveyQuestionAnswer,
|
||||
related_name="selected_by")
|
||||
answers = models.ManyToManyField(SurveyQuestionAnswer, related_name="selected_by")
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Réponses"
|
||||
|
@ -265,8 +249,9 @@ class SurveyAnswer(models.Model):
|
|||
|
||||
def __str__(self):
|
||||
return "Réponse de %s sondage %s" % (
|
||||
self.user.get_full_name(),
|
||||
self.survey.title)
|
||||
self.user.get_full_name(),
|
||||
self.survey.title,
|
||||
)
|
||||
|
||||
|
||||
class CalendarSubscription(models.Model):
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
from captcha.fields import ReCaptchaField
|
||||
|
||||
from django import forms
|
||||
from django.forms import ModelForm
|
||||
from django.forms.models import inlineformset_factory, BaseInlineFormSet
|
||||
from django.contrib.auth.models import User
|
||||
from django.forms import ModelForm
|
||||
from django.forms.models import BaseInlineFormSet, inlineformset_factory
|
||||
|
||||
from gestioncof.petits_cours_models import PetitCoursDemande, PetitCoursAbility
|
||||
from gestioncof.petits_cours_models import PetitCoursAbility, PetitCoursDemande
|
||||
|
||||
|
||||
class BaseMatieresFormSet(BaseInlineFormSet):
|
||||
|
@ -20,33 +19,44 @@ class BaseMatieresFormSet(BaseInlineFormSet):
|
|||
form = self.forms[i]
|
||||
if not form.cleaned_data:
|
||||
continue
|
||||
matiere = form.cleaned_data['matiere']
|
||||
niveau = form.cleaned_data['niveau']
|
||||
delete = form.cleaned_data['DELETE']
|
||||
matiere = form.cleaned_data["matiere"]
|
||||
niveau = form.cleaned_data["niveau"]
|
||||
delete = form.cleaned_data["DELETE"]
|
||||
if not delete and (matiere, niveau) in matieres:
|
||||
raise forms.ValidationError(
|
||||
"Vous ne pouvez pas vous inscrire deux fois pour la "
|
||||
"même matiere avec le même niveau.")
|
||||
"même matiere avec le même niveau."
|
||||
)
|
||||
matieres.append((matiere, niveau))
|
||||
|
||||
|
||||
class DemandeForm(ModelForm):
|
||||
captcha = ReCaptchaField(attrs={'theme': 'clean', 'lang': 'fr'})
|
||||
captcha = ReCaptchaField(attrs={"theme": "clean", "lang": "fr"})
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields['matieres'].help_text = ''
|
||||
self.fields["matieres"].help_text = ""
|
||||
|
||||
class Meta:
|
||||
model = PetitCoursDemande
|
||||
fields = ('name', 'email', 'phone', 'quand', 'freq', 'lieu',
|
||||
'matieres', 'agrege_requis', 'niveau', 'remarques')
|
||||
widgets = {'matieres': forms.CheckboxSelectMultiple}
|
||||
fields = (
|
||||
"name",
|
||||
"email",
|
||||
"phone",
|
||||
"quand",
|
||||
"freq",
|
||||
"lieu",
|
||||
"matieres",
|
||||
"agrege_requis",
|
||||
"niveau",
|
||||
"remarques",
|
||||
)
|
||||
widgets = {"matieres": forms.CheckboxSelectMultiple}
|
||||
|
||||
|
||||
MatieresFormSet = inlineformset_factory(
|
||||
User,
|
||||
PetitCoursAbility,
|
||||
fields=("matiere", "niveau", "agrege"),
|
||||
formset=BaseMatieresFormSet
|
||||
formset=BaseMatieresFormSet,
|
||||
)
|
||||
|
|
|
@ -1,28 +1,30 @@
|
|||
from functools import reduce
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import models
|
||||
from django.db.models import Min
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
def choices_length(choices):
|
||||
return reduce(lambda m, choice: max(m, len(choice[0])), choices, 0)
|
||||
|
||||
|
||||
LEVELS_CHOICES = (
|
||||
('college', _("Collège")),
|
||||
('lycee', _("Lycée")),
|
||||
('prepa1styear', _("Prépa 1ère année / L1")),
|
||||
('prepa2ndyear', _("Prépa 2ème année / L2")),
|
||||
('licence3', _("Licence 3")),
|
||||
('other', _("Autre (préciser dans les commentaires)")),
|
||||
("college", _("Collège")),
|
||||
("lycee", _("Lycée")),
|
||||
("prepa1styear", _("Prépa 1ère année / L1")),
|
||||
("prepa2ndyear", _("Prépa 2ème année / L2")),
|
||||
("licence3", _("Licence 3")),
|
||||
("other", _("Autre (préciser dans les commentaires)")),
|
||||
)
|
||||
|
||||
|
||||
class PetitCoursSubject(models.Model):
|
||||
name = models.CharField(_("Matière"), max_length=30)
|
||||
users = models.ManyToManyField(User, related_name="petits_cours_matieres",
|
||||
through="PetitCoursAbility")
|
||||
users = models.ManyToManyField(
|
||||
User, related_name="petits_cours_matieres", through="PetitCoursAbility"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Matière de petits cours"
|
||||
|
@ -35,12 +37,11 @@ class PetitCoursSubject(models.Model):
|
|||
class PetitCoursAbility(models.Model):
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
matiere = models.ForeignKey(
|
||||
PetitCoursSubject, on_delete=models.CASCADE,
|
||||
verbose_name=_("Matière"),
|
||||
PetitCoursSubject, on_delete=models.CASCADE, verbose_name=_("Matière")
|
||||
)
|
||||
niveau = models.CharField(
|
||||
_("Niveau"), choices=LEVELS_CHOICES, max_length=choices_length(LEVELS_CHOICES)
|
||||
)
|
||||
niveau = models.CharField(_("Niveau"),
|
||||
choices=LEVELS_CHOICES,
|
||||
max_length=choices_length(LEVELS_CHOICES))
|
||||
agrege = models.BooleanField(_("Agrégé"), default=False)
|
||||
|
||||
class Meta:
|
||||
|
@ -56,41 +57,50 @@ class PetitCoursAbility(models.Model):
|
|||
class PetitCoursDemande(models.Model):
|
||||
name = models.CharField(_("Nom/prénom"), max_length=200)
|
||||
email = models.CharField(_("Adresse email"), max_length=300)
|
||||
phone = models.CharField(_("Téléphone (facultatif)"),
|
||||
max_length=20, blank=True)
|
||||
phone = models.CharField(_("Téléphone (facultatif)"), max_length=20, blank=True)
|
||||
quand = models.CharField(
|
||||
_("Quand ?"),
|
||||
help_text=_("Indiquez ici la période désirée pour les petits"
|
||||
" cours (vacances scolaires, semaine, week-end)."),
|
||||
max_length=300, blank=True)
|
||||
help_text=_(
|
||||
"Indiquez ici la période désirée pour les petits"
|
||||
" cours (vacances scolaires, semaine, week-end)."
|
||||
),
|
||||
max_length=300,
|
||||
blank=True,
|
||||
)
|
||||
freq = models.CharField(
|
||||
_("Fréquence"),
|
||||
help_text=_("Indiquez ici la fréquence envisagée "
|
||||
"(hebdomadaire, 2 fois par semaine, ...)"),
|
||||
max_length=300, blank=True)
|
||||
help_text=_(
|
||||
"Indiquez ici la fréquence envisagée "
|
||||
"(hebdomadaire, 2 fois par semaine, ...)"
|
||||
),
|
||||
max_length=300,
|
||||
blank=True,
|
||||
)
|
||||
lieu = models.CharField(
|
||||
_("Lieu (si préférence)"),
|
||||
help_text=_("Si vous avez avez une préférence sur le lieu."),
|
||||
max_length=300, blank=True)
|
||||
max_length=300,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
matieres = models.ManyToManyField(
|
||||
PetitCoursSubject, verbose_name=_("Matières"),
|
||||
related_name="demandes")
|
||||
PetitCoursSubject, verbose_name=_("Matières"), related_name="demandes"
|
||||
)
|
||||
agrege_requis = models.BooleanField(_("Agrégé requis"), default=False)
|
||||
niveau = models.CharField(_("Niveau"),
|
||||
default="",
|
||||
choices=LEVELS_CHOICES,
|
||||
max_length=choices_length(LEVELS_CHOICES))
|
||||
niveau = models.CharField(
|
||||
_("Niveau"),
|
||||
default="",
|
||||
choices=LEVELS_CHOICES,
|
||||
max_length=choices_length(LEVELS_CHOICES),
|
||||
)
|
||||
|
||||
remarques = models.TextField(_("Remarques et précisions"), blank=True)
|
||||
|
||||
traitee = models.BooleanField(_("Traitée"), default=False)
|
||||
traitee_par = models.ForeignKey(
|
||||
User, on_delete=models.CASCADE,
|
||||
blank=True, null=True,
|
||||
User, on_delete=models.CASCADE, blank=True, null=True
|
||||
)
|
||||
processed = models.DateTimeField(_("Date de traitement"),
|
||||
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)
|
||||
|
||||
def get_candidates(self, redo=False):
|
||||
|
@ -105,18 +115,15 @@ class PetitCoursDemande(models.Model):
|
|||
matiere=matiere,
|
||||
niveau=self.niveau,
|
||||
user__profile__is_cof=True,
|
||||
user__profile__petits_cours_accept=True
|
||||
user__profile__petits_cours_accept=True,
|
||||
)
|
||||
if self.agrege_requis:
|
||||
candidates = candidates.filter(agrege=True)
|
||||
if redo:
|
||||
attrs = self.petitcoursattribution_set.filter(matiere=matiere)
|
||||
already_proposed = [
|
||||
attr.user
|
||||
for attr in attrs
|
||||
]
|
||||
already_proposed = [attr.user for attr in attrs]
|
||||
candidates = candidates.exclude(user__in=already_proposed)
|
||||
candidates = candidates.order_by('?').select_related().all()
|
||||
candidates = candidates.order_by("?").select_related().all()
|
||||
yield (matiere, candidates)
|
||||
|
||||
class Meta:
|
||||
|
@ -124,25 +131,20 @@ class PetitCoursDemande(models.Model):
|
|||
verbose_name_plural = "Demandes de petits cours"
|
||||
|
||||
def __str__(self):
|
||||
return "Demande {:d} du {:s}".format(
|
||||
self.id, self.created.strftime("%d %b %Y")
|
||||
)
|
||||
return "Demande {:d} du {:s}".format(self.id, self.created.strftime("%d %b %Y"))
|
||||
|
||||
|
||||
class PetitCoursAttribution(models.Model):
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
demande = models.ForeignKey(
|
||||
PetitCoursDemande, on_delete=models.CASCADE,
|
||||
verbose_name=_("Demande"),
|
||||
PetitCoursDemande, on_delete=models.CASCADE, verbose_name=_("Demande")
|
||||
)
|
||||
matiere = models.ForeignKey(
|
||||
PetitCoursSubject, on_delete=models.CASCADE,
|
||||
verbose_name=_("Matière"),
|
||||
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"),
|
||||
default=False)
|
||||
selected = models.BooleanField(_("Sélectionné par le demandeur"), default=False)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Attribution de petits cours"
|
||||
|
@ -157,8 +159,7 @@ class PetitCoursAttribution(models.Model):
|
|||
class PetitCoursAttributionCounter(models.Model):
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
matiere = models.ForeignKey(
|
||||
PetitCoursSubject, on_delete=models.CASCADE,
|
||||
verbose_name=_("Matiere"),
|
||||
PetitCoursSubject, on_delete=models.CASCADE, verbose_name=_("Matiere")
|
||||
)
|
||||
count = models.IntegerField("Nombre d'envois", default=0)
|
||||
|
||||
|
@ -169,15 +170,12 @@ class PetitCoursAttributionCounter(models.Model):
|
|||
n'existe pas encore, il est initialisé avec le minimum des valeurs des
|
||||
compteurs de tout le monde.
|
||||
"""
|
||||
counter, created = cls.objects.get_or_create(
|
||||
user=user,
|
||||
matiere=matiere,
|
||||
)
|
||||
counter, created = cls.objects.get_or_create(user=user, matiere=matiere)
|
||||
if created:
|
||||
mincount = (
|
||||
cls.objects.filter(matiere=matiere).exclude(user=user)
|
||||
.aggregate(Min('count'))
|
||||
['count__min']
|
||||
cls.objects.filter(matiere=matiere)
|
||||
.exclude(user=user)
|
||||
.aggregate(Min("count"))["count__min"]
|
||||
)
|
||||
counter.count = mincount or 0
|
||||
counter.save()
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
import json
|
||||
|
||||
from custommail.shortcuts import render_custom_mail
|
||||
|
||||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
from django.core import mail
|
||||
from django.contrib.auth.models import User
|
||||
from django.views.generic import ListView, DetailView
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.models import User
|
||||
from django.core import mail
|
||||
from django.db import transaction
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.utils import timezone
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.generic import DetailView, ListView
|
||||
|
||||
from gestioncof.models import CofProfile
|
||||
from gestioncof.petits_cours_models import (
|
||||
PetitCoursDemande, PetitCoursAttribution, PetitCoursAttributionCounter,
|
||||
PetitCoursAbility
|
||||
)
|
||||
from gestioncof.petits_cours_forms import DemandeForm, MatieresFormSet
|
||||
from gestioncof.decorators import buro_required
|
||||
from gestioncof.models import CofProfile
|
||||
from gestioncof.petits_cours_forms import DemandeForm, MatieresFormSet
|
||||
from gestioncof.petits_cours_models import (
|
||||
PetitCoursAbility,
|
||||
PetitCoursAttribution,
|
||||
PetitCoursAttributionCounter,
|
||||
PetitCoursDemande,
|
||||
)
|
||||
|
||||
|
||||
class DemandeListView(ListView):
|
||||
queryset = (
|
||||
PetitCoursDemande.objects
|
||||
.prefetch_related('matieres')
|
||||
.order_by('traitee', '-id')
|
||||
queryset = PetitCoursDemande.objects.prefetch_related("matieres").order_by(
|
||||
"traitee", "-id"
|
||||
)
|
||||
template_name = "petits_cours_demandes_list.html"
|
||||
paginate_by = 20
|
||||
|
@ -33,10 +33,8 @@ class DemandeListView(ListView):
|
|||
|
||||
class DemandeDetailView(DetailView):
|
||||
model = PetitCoursDemande
|
||||
queryset = (
|
||||
PetitCoursDemande.objects
|
||||
.prefetch_related('petitcoursattribution_set',
|
||||
'matieres')
|
||||
queryset = PetitCoursDemande.objects.prefetch_related(
|
||||
"petitcoursattribution_set", "matieres"
|
||||
)
|
||||
template_name = "gestioncof/details_demande_petit_cours.html"
|
||||
context_object_name = "demande"
|
||||
|
@ -44,7 +42,7 @@ class DemandeDetailView(DetailView):
|
|||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
obj = self.object
|
||||
context['attributions'] = obj.petitcoursattribution_set.all()
|
||||
context["attributions"] = obj.petitcoursattribution_set.all()
|
||||
return context
|
||||
|
||||
|
||||
|
@ -64,13 +62,15 @@ def traitement(request, demande_id, redo=False):
|
|||
tuples = []
|
||||
for candidate in candidates:
|
||||
user = candidate.user
|
||||
tuples.append((
|
||||
candidate,
|
||||
PetitCoursAttributionCounter.get_uptodate(user, matiere)
|
||||
))
|
||||
tuples.append(
|
||||
(
|
||||
candidate,
|
||||
PetitCoursAttributionCounter.get_uptodate(user, matiere),
|
||||
)
|
||||
)
|
||||
tuples = sorted(tuples, key=lambda c: c[1].count)
|
||||
candidates, _ = zip(*tuples)
|
||||
candidates = candidates[0:min(3, len(candidates))]
|
||||
candidates = candidates[0 : min(3, len(candidates))]
|
||||
attribdata[matiere.id] = []
|
||||
proposals[matiere] = []
|
||||
for candidate in candidates:
|
||||
|
@ -83,8 +83,9 @@ def traitement(request, demande_id, redo=False):
|
|||
proposed_for[user].append(matiere)
|
||||
else:
|
||||
unsatisfied.append(matiere)
|
||||
return _finalize_traitement(request, demande, proposals,
|
||||
proposed_for, unsatisfied, attribdata, redo)
|
||||
return _finalize_traitement(
|
||||
request, demande, proposals, proposed_for, unsatisfied, attribdata, redo
|
||||
)
|
||||
|
||||
|
||||
@buro_required
|
||||
|
@ -92,43 +93,56 @@ def retraitement(request, demande_id):
|
|||
return traitement(request, demande_id, redo=True)
|
||||
|
||||
|
||||
def _finalize_traitement(request, demande, proposals, proposed_for,
|
||||
unsatisfied, attribdata, redo=False, errors=None):
|
||||
def _finalize_traitement(
|
||||
request,
|
||||
demande,
|
||||
proposals,
|
||||
proposed_for,
|
||||
unsatisfied,
|
||||
attribdata,
|
||||
redo=False,
|
||||
errors=None,
|
||||
):
|
||||
proposals = proposals.items()
|
||||
proposed_for = proposed_for.items()
|
||||
attribdata = list(attribdata.items())
|
||||
proposed_mails = _generate_eleve_email(demande, proposed_for)
|
||||
mainmail = render_custom_mail("petits-cours-mail-demandeur", {
|
||||
"proposals": proposals,
|
||||
"unsatisfied": unsatisfied,
|
||||
"extra":
|
||||
'<textarea name="extra" '
|
||||
mainmail = render_custom_mail(
|
||||
"petits-cours-mail-demandeur",
|
||||
{
|
||||
"proposals": proposals,
|
||||
"unsatisfied": unsatisfied,
|
||||
"extra": '<textarea name="extra" '
|
||||
'style="width:99%; height: 90px;">'
|
||||
'</textarea>'
|
||||
})
|
||||
"</textarea>",
|
||||
},
|
||||
)
|
||||
if errors is not None:
|
||||
for error in errors:
|
||||
messages.error(request, error)
|
||||
return render(request, "gestioncof/traitement_demande_petit_cours.html",
|
||||
{"demande": demande,
|
||||
"unsatisfied": unsatisfied,
|
||||
"proposals": proposals,
|
||||
"proposed_for": proposed_for,
|
||||
"proposed_mails": proposed_mails,
|
||||
"mainmail": mainmail,
|
||||
"attribdata": json.dumps(attribdata),
|
||||
"redo": redo,
|
||||
})
|
||||
return render(
|
||||
request,
|
||||
"gestioncof/traitement_demande_petit_cours.html",
|
||||
{
|
||||
"demande": demande,
|
||||
"unsatisfied": unsatisfied,
|
||||
"proposals": proposals,
|
||||
"proposed_for": proposed_for,
|
||||
"proposed_mails": proposed_mails,
|
||||
"mainmail": mainmail,
|
||||
"attribdata": json.dumps(attribdata),
|
||||
"redo": redo,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def _generate_eleve_email(demande, proposed_for):
|
||||
return [
|
||||
(
|
||||
user,
|
||||
render_custom_mail('petit-cours-mail-eleve', {
|
||||
"demande": demande,
|
||||
"matieres": matieres
|
||||
})
|
||||
render_custom_mail(
|
||||
"petit-cours-mail-eleve", {"demande": demande, "matieres": matieres}
|
||||
),
|
||||
)
|
||||
for user, matieres in proposed_for
|
||||
]
|
||||
|
@ -143,25 +157,30 @@ def _traitement_other_preparing(request, demande):
|
|||
errors = []
|
||||
for matiere, candidates in demande.get_candidates(redo):
|
||||
if candidates:
|
||||
candidates = dict([(candidate.user.id, candidate.user)
|
||||
for candidate in candidates])
|
||||
candidates = dict(
|
||||
[(candidate.user.id, candidate.user) for candidate in candidates]
|
||||
)
|
||||
attribdata[matiere.id] = []
|
||||
proposals[matiere] = []
|
||||
for choice_id in range(min(3, len(candidates))):
|
||||
choice = int(
|
||||
request.POST["proposal-{:d}-{:d}"
|
||||
.format(matiere.id, choice_id)]
|
||||
request.POST["proposal-{:d}-{:d}".format(matiere.id, choice_id)]
|
||||
)
|
||||
if choice == -1:
|
||||
continue
|
||||
if choice not in candidates:
|
||||
errors.append("Choix invalide pour la proposition {:d}"
|
||||
"en {!s}".format(choice_id + 1, matiere))
|
||||
errors.append(
|
||||
"Choix invalide pour la proposition {:d}"
|
||||
"en {!s}".format(choice_id + 1, matiere)
|
||||
)
|
||||
continue
|
||||
user = candidates[choice]
|
||||
if user in proposals[matiere]:
|
||||
errors.append("La proposition {:d} en {!s} est un doublon"
|
||||
.format(choice_id + 1, matiere))
|
||||
errors.append(
|
||||
"La proposition {:d} en {!s} est un doublon".format(
|
||||
choice_id + 1, matiere
|
||||
)
|
||||
)
|
||||
continue
|
||||
proposals[matiere].append(user)
|
||||
attribdata[matiere.id].append(user.id)
|
||||
|
@ -172,15 +191,24 @@ def _traitement_other_preparing(request, demande):
|
|||
if not proposals[matiere]:
|
||||
errors.append("Aucune proposition pour {!s}".format(matiere))
|
||||
elif len(proposals[matiere]) < 3:
|
||||
errors.append("Seulement {:d} proposition{:s} pour {!s}"
|
||||
.format(
|
||||
len(proposals[matiere]),
|
||||
"s" if len(proposals[matiere]) > 1 else "",
|
||||
matiere))
|
||||
errors.append(
|
||||
"Seulement {:d} proposition{:s} pour {!s}".format(
|
||||
len(proposals[matiere]),
|
||||
"s" if len(proposals[matiere]) > 1 else "",
|
||||
matiere,
|
||||
)
|
||||
)
|
||||
else:
|
||||
unsatisfied.append(matiere)
|
||||
return _finalize_traitement(request, demande, proposals, proposed_for,
|
||||
unsatisfied, attribdata, errors=errors)
|
||||
return _finalize_traitement(
|
||||
request,
|
||||
demande,
|
||||
proposals,
|
||||
proposed_for,
|
||||
unsatisfied,
|
||||
attribdata,
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
|
||||
def _traitement_other(request, demande, redo):
|
||||
|
@ -198,10 +226,12 @@ def _traitement_other(request, demande, redo):
|
|||
tuples = []
|
||||
for candidate in candidates:
|
||||
user = candidate.user
|
||||
tuples.append((
|
||||
candidate,
|
||||
PetitCoursAttributionCounter.get_uptodate(user, matiere)
|
||||
))
|
||||
tuples.append(
|
||||
(
|
||||
candidate,
|
||||
PetitCoursAttributionCounter.get_uptodate(user, matiere),
|
||||
)
|
||||
)
|
||||
tuples = sorted(tuples, key=lambda c: c[1].count)
|
||||
candidates, _ = zip(*tuples)
|
||||
attribdata[matiere.id] = []
|
||||
|
@ -218,13 +248,16 @@ def _traitement_other(request, demande, redo):
|
|||
unsatisfied.append(matiere)
|
||||
proposals = proposals.items()
|
||||
proposed_for = proposed_for.items()
|
||||
return render(request,
|
||||
"gestioncof/traitement_demande_petit_cours_autre_niveau.html",
|
||||
{"demande": demande,
|
||||
"unsatisfied": unsatisfied,
|
||||
"proposals": proposals,
|
||||
"proposed_for": proposed_for,
|
||||
})
|
||||
return render(
|
||||
request,
|
||||
"gestioncof/traitement_demande_petit_cours_autre_niveau.html",
|
||||
{
|
||||
"demande": demande,
|
||||
"unsatisfied": unsatisfied,
|
||||
"proposals": proposals,
|
||||
"proposed_for": proposed_for,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def _traitement_post(request, demande):
|
||||
|
@ -252,24 +285,32 @@ def _traitement_post(request, demande):
|
|||
proposed_mails = _generate_eleve_email(demande, proposed_for)
|
||||
mainmail_object, mainmail_body = render_custom_mail(
|
||||
"petits-cours-mail-demandeur",
|
||||
{
|
||||
"proposals": proposals_list,
|
||||
"unsatisfied": unsatisfied,
|
||||
"extra": extra
|
||||
}
|
||||
{"proposals": proposals_list, "unsatisfied": unsatisfied, "extra": extra},
|
||||
)
|
||||
frommail = settings.MAIL_DATA['petits_cours']['FROM']
|
||||
bccaddress = settings.MAIL_DATA['petits_cours']['BCC']
|
||||
replyto = settings.MAIL_DATA['petits_cours']['REPLYTO']
|
||||
frommail = settings.MAIL_DATA["petits_cours"]["FROM"]
|
||||
bccaddress = settings.MAIL_DATA["petits_cours"]["BCC"]
|
||||
replyto = settings.MAIL_DATA["petits_cours"]["REPLYTO"]
|
||||
mails_to_send = []
|
||||
for (user, (mail_object, body)) in proposed_mails:
|
||||
msg = mail.EmailMessage(mail_object, body, frommail, [user.email],
|
||||
[bccaddress], headers={'Reply-To': replyto})
|
||||
msg = mail.EmailMessage(
|
||||
mail_object,
|
||||
body,
|
||||
frommail,
|
||||
[user.email],
|
||||
[bccaddress],
|
||||
headers={"Reply-To": replyto},
|
||||
)
|
||||
mails_to_send.append(msg)
|
||||
mails_to_send.append(mail.EmailMessage(mainmail_object, mainmail_body,
|
||||
frommail, [demande.email],
|
||||
[bccaddress],
|
||||
headers={'Reply-To': replyto}))
|
||||
mails_to_send.append(
|
||||
mail.EmailMessage(
|
||||
mainmail_object,
|
||||
mainmail_body,
|
||||
frommail,
|
||||
[demande.email],
|
||||
[bccaddress],
|
||||
headers={"Reply-To": replyto},
|
||||
)
|
||||
)
|
||||
connection = mail.get_connection(fail_silently=False)
|
||||
connection.send_messages(mails_to_send)
|
||||
with transaction.atomic():
|
||||
|
@ -280,18 +321,19 @@ def _traitement_post(request, demande):
|
|||
)
|
||||
counter.count += 1
|
||||
counter.save()
|
||||
attrib = PetitCoursAttribution(user=user, matiere=matiere,
|
||||
demande=demande, rank=rank + 1)
|
||||
attrib = PetitCoursAttribution(
|
||||
user=user, matiere=matiere, demande=demande, rank=rank + 1
|
||||
)
|
||||
attrib.save()
|
||||
demande.traitee = True
|
||||
demande.traitee_par = request.user
|
||||
demande.processed = timezone.now()
|
||||
demande.save()
|
||||
return render(request,
|
||||
"gestioncof/traitement_demande_petit_cours_success.html",
|
||||
{"demande": demande,
|
||||
"redo": redo,
|
||||
})
|
||||
return render(
|
||||
request,
|
||||
"gestioncof/traitement_demande_petit_cours_success.html",
|
||||
{"demande": demande, "redo": redo},
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
|
@ -308,22 +350,25 @@ def inscription(request):
|
|||
profile.petits_cours_remarques = request.POST["remarques"]
|
||||
profile.save()
|
||||
with transaction.atomic():
|
||||
abilities = (
|
||||
PetitCoursAbility.objects.filter(user=request.user).all()
|
||||
)
|
||||
abilities = PetitCoursAbility.objects.filter(user=request.user).all()
|
||||
for ability in abilities:
|
||||
PetitCoursAttributionCounter.get_uptodate(
|
||||
ability.user,
|
||||
ability.matiere
|
||||
ability.user, ability.matiere
|
||||
)
|
||||
success = True
|
||||
formset = MatieresFormSet(instance=request.user)
|
||||
else:
|
||||
formset = MatieresFormSet(instance=request.user)
|
||||
return render(request, "inscription-petit-cours.html",
|
||||
{"formset": formset, "success": success,
|
||||
"receive_proposals": profile.petits_cours_accept,
|
||||
"remarques": profile.petits_cours_remarques})
|
||||
return render(
|
||||
request,
|
||||
"inscription-petit-cours.html",
|
||||
{
|
||||
"formset": formset,
|
||||
"success": success,
|
||||
"receive_proposals": profile.petits_cours_accept,
|
||||
"remarques": profile.petits_cours_remarques,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
|
@ -336,8 +381,9 @@ def demande(request):
|
|||
success = True
|
||||
else:
|
||||
form = DemandeForm()
|
||||
return render(request, "demande-petit-cours.html", {"form": form,
|
||||
"success": success})
|
||||
return render(
|
||||
request, "demande-petit-cours.html", {"form": form, "success": success}
|
||||
)
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
|
@ -350,5 +396,6 @@ def demande_raw(request):
|
|||
success = True
|
||||
else:
|
||||
form = DemandeForm()
|
||||
return render(request, "demande-petit-cours-raw.html",
|
||||
{"form": form, "success": success})
|
||||
return render(
|
||||
request, "demande-petit-cours-raw.html", {"form": form, "success": success}
|
||||
)
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
from django.conf import settings
|
||||
from django.contrib.sites.models import Site
|
||||
|
||||
from django_cas_ng.backends import CASBackend
|
||||
|
||||
from gestioncof.models import CofProfile
|
||||
|
||||
|
||||
class COFCASBackend(CASBackend):
|
||||
|
||||
def clean_username(self, username):
|
||||
# Le CAS de l'ENS accepte les logins avec des espaces au début
|
||||
# et à la fin, ainsi qu’avec une casse variable. On normalise pour
|
||||
|
@ -24,9 +22,6 @@ class COFCASBackend(CASBackend):
|
|||
|
||||
|
||||
def context_processor(request):
|
||||
'''Append extra data to the context of the given request'''
|
||||
data = {
|
||||
"user": request.user,
|
||||
"site": Site.objects.get_current(),
|
||||
}
|
||||
"""Append extra data to the context of the given request"""
|
||||
data = {"user": request.user, "site": Site.objects.get_current()}
|
||||
return data
|
||||
|
|
|
@ -2,22 +2,21 @@ from django.contrib import messages
|
|||
from django.contrib.auth.signals import user_logged_in
|
||||
from django.dispatch import receiver
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from django_cas_ng.signals import cas_user_authenticated
|
||||
|
||||
|
||||
@receiver(user_logged_in)
|
||||
def messages_on_out_login(request, user, **kwargs):
|
||||
if user.backend.startswith('django.contrib.auth'):
|
||||
msg = _('Connexion à GestioCOF réussie. Bienvenue {}.').format(
|
||||
user.get_short_name(),
|
||||
if user.backend.startswith("django.contrib.auth"):
|
||||
msg = _("Connexion à GestioCOF réussie. Bienvenue {}.").format(
|
||||
user.get_short_name()
|
||||
)
|
||||
messages.success(request, msg)
|
||||
|
||||
|
||||
@receiver(cas_user_authenticated)
|
||||
def mesagges_on_cas_login(request, user, **kwargs):
|
||||
msg = _('Connexion à GestioCOF par CAS réussie. Bienvenue {}.').format(
|
||||
user.get_short_name(),
|
||||
msg = _("Connexion à GestioCOF par CAS réussie. Bienvenue {}.").format(
|
||||
user.get_short_name()
|
||||
)
|
||||
messages.success(request, msg)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import re
|
||||
|
||||
from django import template
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
import re
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
|
@ -12,6 +12,7 @@ def key(d, key_name):
|
|||
value = d[key_name]
|
||||
except KeyError:
|
||||
from django.conf import settings
|
||||
|
||||
value = settings.TEMPLATE_STRING_IF_INVALID
|
||||
return value
|
||||
|
||||
|
@ -19,16 +20,15 @@ def key(d, key_name):
|
|||
def highlight_text(text, q):
|
||||
q2 = "|".join(re.escape(word) for word in q.split())
|
||||
pattern = re.compile(r"(?P<filter>%s)" % q2, re.IGNORECASE)
|
||||
return mark_safe(re.sub(pattern,
|
||||
r"<span class='highlight'>\g<filter></span>",
|
||||
text))
|
||||
return mark_safe(
|
||||
re.sub(pattern, r"<span class='highlight'>\g<filter></span>", text)
|
||||
)
|
||||
|
||||
|
||||
@register.filter
|
||||
def highlight_user(user, q):
|
||||
if user.first_name and user.last_name:
|
||||
text = "%s %s (<tt>%s</tt>)" % (user.first_name, user.last_name,
|
||||
user.username)
|
||||
text = "%s %s (<tt>%s</tt>)" % (user.first_name, user.last_name, user.username)
|
||||
else:
|
||||
text = user.username
|
||||
return highlight_text(text, q)
|
||||
|
|
|
@ -12,17 +12,17 @@ from gestioncof.models import CofProfile, User
|
|||
|
||||
class SimpleTest(TestCase):
|
||||
def test_delete_user(self):
|
||||
u = User(username='foo', first_name='foo', last_name='bar')
|
||||
u = User(username="foo", first_name="foo", last_name="bar")
|
||||
|
||||
# to each user there's a cofprofile associated
|
||||
u.save()
|
||||
self.assertTrue(CofProfile.objects.filter(user__username='foo').exists())
|
||||
self.assertTrue(CofProfile.objects.filter(user__username="foo").exists())
|
||||
|
||||
# there's no point in having a cofprofile without a user associated.
|
||||
u.delete()
|
||||
self.assertFalse(CofProfile.objects.filter(user__username='foo').exists())
|
||||
self.assertFalse(CofProfile.objects.filter(user__username="foo").exists())
|
||||
|
||||
# there's no point in having a user without a cofprofile associated.
|
||||
u.save()
|
||||
CofProfile.objects.get(user__username='foo').delete()
|
||||
self.assertFalse(User.objects.filter(username='foo').exists())
|
||||
CofProfile.objects.get(user__username="foo").delete()
|
||||
self.assertFalse(User.objects.filter(username="foo").exists())
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
from shared.tests.testcases import ViewTestCaseMixin as BaseViewTestCaseMixin
|
||||
|
||||
from .utils import create_user, create_member, create_staff
|
||||
from .utils import create_member, create_staff, create_user
|
||||
|
||||
|
||||
class ViewTestCaseMixin(BaseViewTestCaseMixin):
|
||||
|
@ -18,7 +18,7 @@ class ViewTestCaseMixin(BaseViewTestCaseMixin):
|
|||
|
||||
def get_users_base(self):
|
||||
return {
|
||||
'user': create_user('user'),
|
||||
'member': create_member('member'),
|
||||
'staff': create_staff('staff'),
|
||||
"user": create_user("user"),
|
||||
"member": create_member("member"),
|
||||
"staff": create_staff("staff"),
|
||||
}
|
||||
|
|
|
@ -7,28 +7,35 @@ def _create_user(username, is_cof=False, is_staff=False, attrs=None):
|
|||
if attrs is None:
|
||||
attrs = {}
|
||||
|
||||
password = attrs.pop('password', username)
|
||||
password = attrs.pop("password", username)
|
||||
|
||||
user_keys = [
|
||||
'first_name', 'last_name', 'email', 'is_staff', 'is_superuser',
|
||||
]
|
||||
user_keys = ["first_name", "last_name", "email", "is_staff", "is_superuser"]
|
||||
user_attrs = {k: v for k, v in attrs.items() if k in user_keys}
|
||||
|
||||
profile_keys = [
|
||||
'is_cof', 'login_clipper', 'phone', 'occupation', 'departement',
|
||||
'type_cotiz', 'mailing_cof', 'mailing_bda', 'mailing_bda_revente',
|
||||
'comments', 'is_buro', 'petit_cours_accept',
|
||||
'petit_cours_remarques',
|
||||
"is_cof",
|
||||
"login_clipper",
|
||||
"phone",
|
||||
"occupation",
|
||||
"departement",
|
||||
"type_cotiz",
|
||||
"mailing_cof",
|
||||
"mailing_bda",
|
||||
"mailing_bda_revente",
|
||||
"comments",
|
||||
"is_buro",
|
||||
"petit_cours_accept",
|
||||
"petit_cours_remarques",
|
||||
]
|
||||
profile_attrs = {k: v for k, v in attrs.items() if k in profile_keys}
|
||||
|
||||
if is_cof:
|
||||
profile_attrs['is_cof'] = True
|
||||
profile_attrs["is_cof"] = True
|
||||
|
||||
if is_staff:
|
||||
# At the moment, admin is accessible by COF staff.
|
||||
user_attrs['is_staff'] = True
|
||||
profile_attrs['is_buro'] = True
|
||||
user_attrs["is_staff"] = True
|
||||
profile_attrs["is_buro"] = True
|
||||
|
||||
user = User(username=username, **user_attrs)
|
||||
user.set_password(password)
|
||||
|
@ -56,6 +63,6 @@ def create_staff(username, attrs=None):
|
|||
def create_root(username, attrs=None):
|
||||
if attrs is None:
|
||||
attrs = {}
|
||||
attrs.setdefault('is_staff', True)
|
||||
attrs.setdefault('is_superuser', True)
|
||||
attrs.setdefault("is_staff", True)
|
||||
attrs.setdefault("is_superuser", True)
|
||||
return _create_user(username, attrs=attrs)
|
||||
|
|
|
@ -1,67 +1,87 @@
|
|||
from django.conf.urls import url
|
||||
from gestioncof.petits_cours_views import DemandeListView, DemandeDetailView
|
||||
from gestioncof import views, petits_cours_views
|
||||
|
||||
from gestioncof import petits_cours_views, views
|
||||
from gestioncof.decorators import buro_required
|
||||
from gestioncof.petits_cours_views import DemandeDetailView, DemandeListView
|
||||
|
||||
export_patterns = [
|
||||
url(r'^members$', views.export_members,
|
||||
name='cof.membres_export'),
|
||||
url(r'^mega/avecremarques$', views.export_mega_remarksonly,
|
||||
name='cof.mega_export_remarks'),
|
||||
url(r'^mega/participants$', views.export_mega_participants,
|
||||
name='cof.mega_export_participants'),
|
||||
url(r'^mega/orgas$', views.export_mega_orgas,
|
||||
name='cof.mega_export_orgas'),
|
||||
url(r"^members$", views.export_members, name="cof.membres_export"),
|
||||
url(
|
||||
r"^mega/avecremarques$",
|
||||
views.export_mega_remarksonly,
|
||||
name="cof.mega_export_remarks",
|
||||
),
|
||||
url(
|
||||
r"^mega/participants$",
|
||||
views.export_mega_participants,
|
||||
name="cof.mega_export_participants",
|
||||
),
|
||||
url(r"^mega/orgas$", views.export_mega_orgas, name="cof.mega_export_orgas"),
|
||||
# url(r'^mega/(?P<type>.+)$', views.export_mega_bytype),
|
||||
url(r'^mega$', views.export_mega,
|
||||
name='cof.mega_export'),
|
||||
url(r"^mega$", views.export_mega, name="cof.mega_export"),
|
||||
]
|
||||
|
||||
petitcours_patterns = [
|
||||
url(r'^inscription$', petits_cours_views.inscription,
|
||||
name='petits-cours-inscription'),
|
||||
url(r'^demande$', petits_cours_views.demande,
|
||||
name='petits-cours-demande'),
|
||||
url(r'^demande-raw$', petits_cours_views.demande_raw,
|
||||
name='petits-cours-demande-raw'),
|
||||
url(r'^demandes$',
|
||||
url(
|
||||
r"^inscription$",
|
||||
petits_cours_views.inscription,
|
||||
name="petits-cours-inscription",
|
||||
),
|
||||
url(r"^demande$", petits_cours_views.demande, name="petits-cours-demande"),
|
||||
url(
|
||||
r"^demande-raw$",
|
||||
petits_cours_views.demande_raw,
|
||||
name="petits-cours-demande-raw",
|
||||
),
|
||||
url(
|
||||
r"^demandes$",
|
||||
buro_required(DemandeListView.as_view()),
|
||||
name='petits-cours-demandes-list'),
|
||||
url(r'^demandes/(?P<pk>\d+)$',
|
||||
name="petits-cours-demandes-list",
|
||||
),
|
||||
url(
|
||||
r"^demandes/(?P<pk>\d+)$",
|
||||
buro_required(DemandeDetailView.as_view()),
|
||||
name='petits-cours-demande-details'),
|
||||
url(r'^demandes/(?P<demande_id>\d+)/traitement$',
|
||||
name="petits-cours-demande-details",
|
||||
),
|
||||
url(
|
||||
r"^demandes/(?P<demande_id>\d+)/traitement$",
|
||||
petits_cours_views.traitement,
|
||||
name='petits-cours-demande-traitement'),
|
||||
url(r'^demandes/(?P<demande_id>\d+)/retraitement$',
|
||||
name="petits-cours-demande-traitement",
|
||||
),
|
||||
url(
|
||||
r"^demandes/(?P<demande_id>\d+)/retraitement$",
|
||||
petits_cours_views.retraitement,
|
||||
name='petits-cours-demande-retraitement'),
|
||||
name="petits-cours-demande-retraitement",
|
||||
),
|
||||
]
|
||||
|
||||
surveys_patterns = [
|
||||
url(r'^(?P<survey_id>\d+)/status$', views.survey_status,
|
||||
name='survey.details.status'),
|
||||
url(r'^(?P<survey_id>\d+)$', views.survey,
|
||||
name='survey.details'),
|
||||
url(
|
||||
r"^(?P<survey_id>\d+)/status$",
|
||||
views.survey_status,
|
||||
name="survey.details.status",
|
||||
),
|
||||
url(r"^(?P<survey_id>\d+)$", views.survey, name="survey.details"),
|
||||
]
|
||||
|
||||
events_patterns = [
|
||||
url(r'^(?P<event_id>\d+)$', views.event,
|
||||
name='event.details'),
|
||||
url(r'^(?P<event_id>\d+)/status$', views.event_status,
|
||||
name='event.details.status'),
|
||||
url(r"^(?P<event_id>\d+)$", views.event, name="event.details"),
|
||||
url(r"^(?P<event_id>\d+)/status$", views.event_status, name="event.details.status"),
|
||||
]
|
||||
|
||||
calendar_patterns = [
|
||||
url(r'^subscription$', views.calendar,
|
||||
name='calendar'),
|
||||
url(r'^(?P<token>[a-z0-9-]+)/calendar.ics$', views.calendar_ics,
|
||||
name='calendar.ics'),
|
||||
url(r"^subscription$", views.calendar, name="calendar"),
|
||||
url(
|
||||
r"^(?P<token>[a-z0-9-]+)/calendar.ics$", views.calendar_ics, name="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'),
|
||||
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",
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,59 +1,74 @@
|
|||
import unicodecsv
|
||||
import uuid
|
||||
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
|
||||
import unicodecsv
|
||||
from custommail.shortcuts import send_custom_mail
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.views import (
|
||||
login as django_login_view, logout as django_logout_view,
|
||||
login as django_login_view,
|
||||
logout as django_logout_view,
|
||||
redirect_to_login,
|
||||
)
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.sites.models import Site
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
from django.views.generic import FormView
|
||||
from django.http import Http404, HttpResponse, HttpResponseForbidden
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.contrib import messages
|
||||
|
||||
from django.views.generic import FormView
|
||||
from django_cas_ng.views import logout as cas_logout_view
|
||||
from icalendar import Calendar, Event as Vevent
|
||||
|
||||
from utils.views.autocomplete import Select2QuerySetView
|
||||
|
||||
from gestioncof.models import Survey, SurveyAnswer, SurveyQuestion, \
|
||||
SurveyQuestionAnswer
|
||||
from gestioncof.models import Event, EventRegistration, EventOption, \
|
||||
EventOptionChoice
|
||||
from gestioncof.models import EventCommentField, EventCommentValue, \
|
||||
CalendarSubscription
|
||||
from gestioncof.models import CofProfile, Club
|
||||
from bda.models import Spectacle, Tirage
|
||||
from gestioncof.decorators import buro_required, cof_required
|
||||
from gestioncof.forms import (
|
||||
UserForm, ProfileForm,
|
||||
EventStatusFilterForm, SurveyForm, SurveyStatusFilterForm,
|
||||
RegistrationUserForm, RegistrationProfileForm, EventForm, CalendarForm,
|
||||
EventFormset, RegistrationPassUserForm, ClubsForm, GestioncofConfigForm
|
||||
CalendarForm,
|
||||
ClubsForm,
|
||||
EventForm,
|
||||
EventFormset,
|
||||
EventStatusFilterForm,
|
||||
GestioncofConfigForm,
|
||||
ProfileForm,
|
||||
RegistrationPassUserForm,
|
||||
RegistrationProfileForm,
|
||||
RegistrationUserForm,
|
||||
SurveyForm,
|
||||
SurveyStatusFilterForm,
|
||||
UserForm,
|
||||
)
|
||||
|
||||
from bda.models import Tirage, Spectacle
|
||||
from gestioncof.models import (
|
||||
CalendarSubscription,
|
||||
Club,
|
||||
CofProfile,
|
||||
Event,
|
||||
EventCommentField,
|
||||
EventCommentValue,
|
||||
EventOption,
|
||||
EventOptionChoice,
|
||||
EventRegistration,
|
||||
Survey,
|
||||
SurveyAnswer,
|
||||
SurveyQuestion,
|
||||
SurveyQuestionAnswer,
|
||||
)
|
||||
from utils.views.autocomplete import Select2QuerySetView
|
||||
|
||||
|
||||
@login_required
|
||||
def home(request):
|
||||
data = {"surveys": Survey.objects.filter(old=False).all(),
|
||||
"events": Event.objects.filter(old=False).all(),
|
||||
"open_surveys":
|
||||
Survey.objects.filter(survey_open=True, old=False).all(),
|
||||
"open_events":
|
||||
Event.objects.filter(registration_open=True, old=False).all(),
|
||||
"active_tirages": Tirage.objects.filter(active=True).all(),
|
||||
"open_tirages":
|
||||
Tirage.objects.filter(active=True,
|
||||
ouverture__lte=timezone.now()).all(),
|
||||
"now": timezone.now()}
|
||||
data = {
|
||||
"surveys": Survey.objects.filter(old=False).all(),
|
||||
"events": Event.objects.filter(old=False).all(),
|
||||
"open_surveys": Survey.objects.filter(survey_open=True, old=False).all(),
|
||||
"open_events": Event.objects.filter(registration_open=True, old=False).all(),
|
||||
"active_tirages": Tirage.objects.filter(active=True).all(),
|
||||
"open_tirages": Tirage.objects.filter(
|
||||
active=True, ouverture__lte=timezone.now()
|
||||
).all(),
|
||||
"now": timezone.now(),
|
||||
}
|
||||
return render(request, "home.html", data)
|
||||
|
||||
|
||||
|
@ -61,8 +76,8 @@ def login(request):
|
|||
if request.user.is_authenticated:
|
||||
return redirect("home")
|
||||
context = {}
|
||||
if request.method == "GET" and 'next' in request.GET:
|
||||
context['next'] = request.GET['next']
|
||||
if request.method == "GET" and "next" in request.GET:
|
||||
context["next"] = request.GET["next"]
|
||||
return render(request, "login_switch.html", context)
|
||||
|
||||
|
||||
|
@ -73,34 +88,33 @@ def login_ext(request):
|
|||
if not user.has_usable_password() or user.password in ("", "!"):
|
||||
profile, created = CofProfile.objects.get_or_create(user=user)
|
||||
if profile.login_clipper:
|
||||
return render(request, "error.html",
|
||||
{"error_type": "use_clipper_login"})
|
||||
return render(
|
||||
request, "error.html", {"error_type": "use_clipper_login"}
|
||||
)
|
||||
else:
|
||||
return render(request, "error.html",
|
||||
{"error_type": "no_password"})
|
||||
return render(request, "error.html", {"error_type": "no_password"})
|
||||
except User.DoesNotExist:
|
||||
pass
|
||||
context = {}
|
||||
if request.method == "GET" and 'next' in request.GET:
|
||||
context['next'] = request.GET['next']
|
||||
if request.method == "POST" and 'next' in request.POST:
|
||||
context['next'] = request.POST['next']
|
||||
return django_login_view(request, template_name='login.html',
|
||||
extra_context=context)
|
||||
if request.method == "GET" and "next" in request.GET:
|
||||
context["next"] = request.GET["next"]
|
||||
if request.method == "POST" and "next" in request.POST:
|
||||
context["next"] = request.POST["next"]
|
||||
return django_login_view(request, template_name="login.html", extra_context=context)
|
||||
|
||||
|
||||
@login_required
|
||||
def logout(request, next_page=None):
|
||||
if next_page is None:
|
||||
next_page = request.GET.get('next', None)
|
||||
next_page = request.GET.get("next", None)
|
||||
|
||||
profile = getattr(request.user, 'profile', None)
|
||||
profile = getattr(request.user, "profile", None)
|
||||
|
||||
if profile and profile.login_clipper:
|
||||
msg = _('Déconnexion de GestioCOF et CAS réussie. À bientôt {}.')
|
||||
msg = _("Déconnexion de GestioCOF et CAS réussie. À bientôt {}.")
|
||||
logout_view = cas_logout_view
|
||||
else:
|
||||
msg = _('Déconnexion de GestioCOF réussie. À bientôt {}.')
|
||||
msg = _("Déconnexion de GestioCOF réussie. À bientôt {}.")
|
||||
logout_view = django_logout_view
|
||||
|
||||
messages.success(request, msg.format(request.user.get_short_name()))
|
||||
|
@ -110,8 +124,7 @@ def logout(request, next_page=None):
|
|||
@login_required
|
||||
def survey(request, survey_id):
|
||||
survey = get_object_or_404(
|
||||
Survey.objects.prefetch_related('questions', 'questions__answers'),
|
||||
id=survey_id,
|
||||
Survey.objects.prefetch_related("questions", "questions__answers"), id=survey_id
|
||||
)
|
||||
if not survey.survey_open or survey.old:
|
||||
raise Http404
|
||||
|
@ -119,10 +132,11 @@ def survey(request, survey_id):
|
|||
deleted = False
|
||||
if request.method == "POST":
|
||||
form = SurveyForm(request.POST, survey=survey)
|
||||
if request.POST.get('delete'):
|
||||
if request.POST.get("delete"):
|
||||
try:
|
||||
current_answer = SurveyAnswer.objects.get(user=request.user,
|
||||
survey=survey)
|
||||
current_answer = SurveyAnswer.objects.get(
|
||||
user=request.user, survey=survey
|
||||
)
|
||||
current_answer.delete()
|
||||
current_answer = None
|
||||
except SurveyAnswer.DoesNotExist:
|
||||
|
@ -134,9 +148,9 @@ def survey(request, survey_id):
|
|||
if form.is_valid():
|
||||
all_answers = []
|
||||
for question_id, answers_ids in form.answers():
|
||||
question = get_object_or_404(SurveyQuestion,
|
||||
id=question_id,
|
||||
survey=survey)
|
||||
question = get_object_or_404(
|
||||
SurveyQuestion, id=question_id, survey=survey
|
||||
)
|
||||
if type(answers_ids) != list:
|
||||
answers_ids = [answers_ids]
|
||||
if not question.multi_answers and len(answers_ids) > 1:
|
||||
|
@ -146,50 +160,48 @@ def survey(request, survey_id):
|
|||
continue
|
||||
answer_id = int(answer_id)
|
||||
answer = SurveyQuestionAnswer.objects.get(
|
||||
id=answer_id,
|
||||
survey_question=question)
|
||||
id=answer_id, survey_question=question
|
||||
)
|
||||
all_answers.append(answer)
|
||||
try:
|
||||
current_answer = SurveyAnswer.objects.get(
|
||||
user=request.user, survey=survey)
|
||||
user=request.user, survey=survey
|
||||
)
|
||||
except SurveyAnswer.DoesNotExist:
|
||||
current_answer = SurveyAnswer(user=request.user,
|
||||
survey=survey)
|
||||
current_answer = SurveyAnswer(user=request.user, survey=survey)
|
||||
current_answer.save()
|
||||
current_answer.answers = all_answers
|
||||
current_answer.save()
|
||||
success = True
|
||||
else:
|
||||
try:
|
||||
current_answer = SurveyAnswer.objects.get(user=request.user,
|
||||
survey=survey)
|
||||
form = SurveyForm(survey=survey,
|
||||
current_answers=current_answer.answers)
|
||||
current_answer = SurveyAnswer.objects.get(user=request.user, survey=survey)
|
||||
form = SurveyForm(survey=survey, current_answers=current_answer.answers)
|
||||
except SurveyAnswer.DoesNotExist:
|
||||
current_answer = None
|
||||
form = SurveyForm(survey=survey)
|
||||
# Messages
|
||||
if success:
|
||||
if deleted:
|
||||
messages.success(request,
|
||||
"Votre réponse a bien été supprimée")
|
||||
messages.success(request, "Votre réponse a bien été supprimée")
|
||||
else:
|
||||
messages.success(request,
|
||||
"Votre réponse a bien été enregistrée ! Vous "
|
||||
"pouvez cependant la modifier jusqu'à la fin "
|
||||
"du sondage.")
|
||||
return render(request, "gestioncof/survey.html", {
|
||||
"survey": survey,
|
||||
"form": form,
|
||||
"current_answer": current_answer
|
||||
})
|
||||
messages.success(
|
||||
request,
|
||||
"Votre réponse a bien été enregistrée ! Vous "
|
||||
"pouvez cependant la modifier jusqu'à la fin "
|
||||
"du sondage.",
|
||||
)
|
||||
return render(
|
||||
request,
|
||||
"gestioncof/survey.html",
|
||||
{"survey": survey, "form": form, "current_answer": current_answer},
|
||||
)
|
||||
|
||||
|
||||
def get_event_form_choices(event, form):
|
||||
all_choices = []
|
||||
for option_id, choices_ids in form.choices():
|
||||
option = get_object_or_404(EventOption, id=option_id,
|
||||
event=event)
|
||||
option = get_object_or_404(EventOption, id=option_id, event=event)
|
||||
if type(choices_ids) != list:
|
||||
choices_ids = [choices_ids]
|
||||
if not option.multi_choices and len(choices_ids) > 1:
|
||||
|
@ -198,22 +210,19 @@ def get_event_form_choices(event, form):
|
|||
if not choice_id:
|
||||
continue
|
||||
choice_id = int(choice_id)
|
||||
choice = EventOptionChoice.objects.get(
|
||||
id=choice_id,
|
||||
event_option=option)
|
||||
choice = EventOptionChoice.objects.get(id=choice_id, event_option=option)
|
||||
all_choices.append(choice)
|
||||
return all_choices
|
||||
|
||||
|
||||
def update_event_form_comments(event, form, registration):
|
||||
for commentfield_id, value in form.comments():
|
||||
field = get_object_or_404(EventCommentField, id=commentfield_id,
|
||||
event=event)
|
||||
field = get_object_or_404(EventCommentField, id=commentfield_id, event=event)
|
||||
if value == field.default:
|
||||
continue
|
||||
(storage, _) = EventCommentValue.objects.get_or_create(
|
||||
commentfield=field,
|
||||
registration=registration)
|
||||
commentfield=field, registration=registration
|
||||
)
|
||||
storage.content = value
|
||||
storage.save()
|
||||
|
||||
|
@ -228,27 +237,29 @@ def event(request, event_id):
|
|||
form = EventForm(request.POST, event=event)
|
||||
if form.is_valid():
|
||||
all_choices = get_event_form_choices(event, form)
|
||||
(current_registration, _) = \
|
||||
EventRegistration.objects.get_or_create(user=request.user,
|
||||
event=event)
|
||||
(current_registration, _) = EventRegistration.objects.get_or_create(
|
||||
user=request.user, event=event
|
||||
)
|
||||
current_registration.options = all_choices
|
||||
current_registration.save()
|
||||
success = True
|
||||
else:
|
||||
try:
|
||||
current_registration = \
|
||||
EventRegistration.objects.get(user=request.user, event=event)
|
||||
form = EventForm(event=event,
|
||||
current_choices=current_registration.options)
|
||||
current_registration = EventRegistration.objects.get(
|
||||
user=request.user, event=event
|
||||
)
|
||||
form = EventForm(event=event, current_choices=current_registration.options)
|
||||
except EventRegistration.DoesNotExist:
|
||||
form = EventForm(event=event)
|
||||
# Messages
|
||||
if success:
|
||||
messages.success(request, "Votre inscription a bien été enregistrée ! "
|
||||
"Vous pouvez cependant la modifier jusqu'à "
|
||||
"la fin des inscriptions.")
|
||||
return render(request, "gestioncof/event.html",
|
||||
{"event": event, "form": form})
|
||||
messages.success(
|
||||
request,
|
||||
"Votre inscription a bien été enregistrée ! "
|
||||
"Vous pouvez cependant la modifier jusqu'à "
|
||||
"la fin des inscriptions.",
|
||||
)
|
||||
return render(request, "gestioncof/event.html", {"event": event, "form": form})
|
||||
|
||||
|
||||
def clean_post_for_status(initial):
|
||||
|
@ -272,19 +283,21 @@ def event_status(request, event_id):
|
|||
if value == "yes":
|
||||
registrations_query = registrations_query.filter(paid=True)
|
||||
elif value == "no":
|
||||
registrations_query = registrations_query.filter(
|
||||
paid=False)
|
||||
registrations_query = registrations_query.filter(paid=False)
|
||||
continue
|
||||
choice = get_object_or_404(EventOptionChoice, id=choice_id,
|
||||
event_option__id=option_id)
|
||||
choice = get_object_or_404(
|
||||
EventOptionChoice, id=choice_id, event_option__id=option_id
|
||||
)
|
||||
if value == "none":
|
||||
continue
|
||||
if value == "yes":
|
||||
registrations_query = registrations_query.filter(
|
||||
options__id__exact=choice.id)
|
||||
options__id__exact=choice.id
|
||||
)
|
||||
elif value == "no":
|
||||
registrations_query = registrations_query.exclude(
|
||||
options__id__exact=choice.id)
|
||||
options__id__exact=choice.id
|
||||
)
|
||||
user_choices = registrations_query.prefetch_related("user").all()
|
||||
options = EventOption.objects.filter(event=event).all()
|
||||
choices_count = {}
|
||||
|
@ -294,10 +307,17 @@ def event_status(request, event_id):
|
|||
for user_choice in user_choices:
|
||||
for choice in user_choice.options.all():
|
||||
choices_count[choice.id] += 1
|
||||
return render(request, "event_status.html",
|
||||
{"event": event, "user_choices": user_choices,
|
||||
"options": options, "choices_count": choices_count,
|
||||
"form": form})
|
||||
return render(
|
||||
request,
|
||||
"event_status.html",
|
||||
{
|
||||
"event": event,
|
||||
"user_choices": user_choices,
|
||||
"options": options,
|
||||
"choices_count": choices_count,
|
||||
"form": form,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@buro_required
|
||||
|
@ -308,16 +328,15 @@ def survey_status(request, survey_id):
|
|||
form = SurveyStatusFilterForm(post_data or None, survey=survey)
|
||||
if form.is_valid():
|
||||
for question_id, answer_id, value in form.filters():
|
||||
answer = get_object_or_404(SurveyQuestionAnswer, id=answer_id,
|
||||
survey_question__id=question_id)
|
||||
answer = get_object_or_404(
|
||||
SurveyQuestionAnswer, id=answer_id, survey_question__id=question_id
|
||||
)
|
||||
if value == "none":
|
||||
continue
|
||||
if value == "yes":
|
||||
answers_query = answers_query.filter(
|
||||
answers__id__exact=answer.id)
|
||||
answers_query = answers_query.filter(answers__id__exact=answer.id)
|
||||
elif value == "no":
|
||||
answers_query = answers_query.exclude(
|
||||
answers__id__exact=answer.id)
|
||||
answers_query = answers_query.exclude(answers__id__exact=answer.id)
|
||||
user_answers = answers_query.prefetch_related("user").all()
|
||||
questions = SurveyQuestion.objects.filter(survey=survey).all()
|
||||
answers_count = {}
|
||||
|
@ -327,10 +346,17 @@ def survey_status(request, survey_id):
|
|||
for user_answer in user_answers:
|
||||
for answer in user_answer.answers.all():
|
||||
answers_count[answer.id] += 1
|
||||
return render(request, "survey_status.html",
|
||||
{"survey": survey, "user_answers": user_answers,
|
||||
"questions": questions, "answers_count": answers_count,
|
||||
"form": form})
|
||||
return render(
|
||||
request,
|
||||
"survey_status.html",
|
||||
{
|
||||
"survey": survey,
|
||||
"user_answers": user_answers,
|
||||
"questions": questions,
|
||||
"answers_count": answers_count,
|
||||
"form": form,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@cof_required
|
||||
|
@ -343,22 +369,18 @@ def profile(request):
|
|||
if user_form.is_valid() and profile_form.is_valid():
|
||||
user_form.save()
|
||||
profile_form.save()
|
||||
messages.success(
|
||||
request,
|
||||
_("Votre profil a été mis à jour avec succès !")
|
||||
)
|
||||
messages.success(request, _("Votre profil a été mis à jour avec succès !"))
|
||||
context = {"user_form": user_form, "profile_form": profile_form}
|
||||
return render(request, "gestioncof/profile.html", context)
|
||||
|
||||
|
||||
def registration_set_ro_fields(user_form, profile_form):
|
||||
user_form.fields['username'].widget.attrs['readonly'] = True
|
||||
profile_form.fields['login_clipper'].widget.attrs['readonly'] = True
|
||||
user_form.fields["username"].widget.attrs["readonly"] = True
|
||||
profile_form.fields["login_clipper"].widget.attrs["readonly"] = True
|
||||
|
||||
|
||||
@buro_required
|
||||
def registration_form2(request, login_clipper=None, username=None,
|
||||
fullname=None):
|
||||
def registration_form2(request, login_clipper=None, username=None, fullname=None):
|
||||
events = Event.objects.filter(old=False).all()
|
||||
member = None
|
||||
if login_clipper:
|
||||
|
@ -369,20 +391,24 @@ def registration_form2(request, login_clipper=None, username=None,
|
|||
except User.DoesNotExist:
|
||||
# new user, but prefill
|
||||
# user
|
||||
user_form = RegistrationUserForm(initial={
|
||||
'username': login_clipper,
|
||||
'email': "%s@clipper.ens.fr" % login_clipper})
|
||||
user_form = RegistrationUserForm(
|
||||
initial={
|
||||
"username": login_clipper,
|
||||
"email": "%s@clipper.ens.fr" % login_clipper,
|
||||
}
|
||||
)
|
||||
if fullname:
|
||||
bits = fullname.split(" ")
|
||||
user_form.fields['first_name'].initial = bits[0]
|
||||
user_form.fields["first_name"].initial = bits[0]
|
||||
if len(bits) > 1:
|
||||
user_form.fields['last_name'].initial = " ".join(bits[1:])
|
||||
user_form.fields["last_name"].initial = " ".join(bits[1:])
|
||||
# profile
|
||||
profile_form = RegistrationProfileForm(initial={
|
||||
'login_clipper': login_clipper})
|
||||
profile_form = RegistrationProfileForm(
|
||||
initial={"login_clipper": login_clipper}
|
||||
)
|
||||
registration_set_ro_fields(user_form, profile_form)
|
||||
# events & clubs
|
||||
event_formset = EventFormset(events=events, prefix='events')
|
||||
event_formset = EventFormset(events=events, prefix="events")
|
||||
clubs_form = ClubsForm()
|
||||
if username:
|
||||
member = get_object_or_404(User, username=username)
|
||||
|
@ -396,26 +422,33 @@ def registration_form2(request, login_clipper=None, username=None,
|
|||
for event in events:
|
||||
try:
|
||||
current_registrations.append(
|
||||
EventRegistration.objects.get(user=member, event=event))
|
||||
EventRegistration.objects.get(user=member, event=event)
|
||||
)
|
||||
except EventRegistration.DoesNotExist:
|
||||
current_registrations.append(None)
|
||||
event_formset = EventFormset(
|
||||
events=events, prefix='events',
|
||||
current_registrations=current_registrations)
|
||||
events=events, prefix="events", current_registrations=current_registrations
|
||||
)
|
||||
# Clubs
|
||||
clubs_form = ClubsForm(initial={'clubs': member.clubs.all()})
|
||||
clubs_form = ClubsForm(initial={"clubs": member.clubs.all()})
|
||||
elif not login_clipper:
|
||||
# new user
|
||||
user_form = RegistrationPassUserForm()
|
||||
profile_form = RegistrationProfileForm()
|
||||
event_formset = EventFormset(events=events, prefix='events')
|
||||
event_formset = EventFormset(events=events, prefix="events")
|
||||
clubs_form = ClubsForm()
|
||||
return render(request, "gestioncof/registration_form.html",
|
||||
{"member": member, "login_clipper": login_clipper,
|
||||
"user_form": user_form,
|
||||
"profile_form": profile_form,
|
||||
"event_formset": event_formset,
|
||||
"clubs_form": clubs_form})
|
||||
return render(
|
||||
request,
|
||||
"gestioncof/registration_form.html",
|
||||
{
|
||||
"member": member,
|
||||
"login_clipper": login_clipper,
|
||||
"user_form": user_form,
|
||||
"profile_form": profile_form,
|
||||
"event_formset": event_formset,
|
||||
"clubs_form": clubs_form,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@buro_required
|
||||
|
@ -429,15 +462,14 @@ def registration(request):
|
|||
# Remplissage des formulaires
|
||||
# -----
|
||||
|
||||
if 'password1' in request_dict or 'password2' in request_dict:
|
||||
if "password1" in request_dict or "password2" in request_dict:
|
||||
user_form = RegistrationPassUserForm(request_dict)
|
||||
else:
|
||||
user_form = RegistrationUserForm(request_dict)
|
||||
profile_form = RegistrationProfileForm(request_dict)
|
||||
clubs_form = ClubsForm(request_dict)
|
||||
events = Event.objects.filter(old=False).all()
|
||||
event_formset = EventFormset(events=events, data=request_dict,
|
||||
prefix='events')
|
||||
event_formset = EventFormset(events=events, data=request_dict, prefix="events")
|
||||
if "user_exists" in request_dict and request_dict["user_exists"]:
|
||||
username = request_dict["username"]
|
||||
try:
|
||||
|
@ -459,38 +491,44 @@ def registration(request):
|
|||
profile, _ = CofProfile.objects.get_or_create(user=member)
|
||||
was_cof = profile.is_cof
|
||||
# Maintenant on remplit le formulaire de profil
|
||||
profile_form = RegistrationProfileForm(request_dict,
|
||||
instance=profile)
|
||||
if (profile_form.is_valid() and event_formset.is_valid()
|
||||
and clubs_form.is_valid()):
|
||||
profile_form = RegistrationProfileForm(request_dict, instance=profile)
|
||||
if (
|
||||
profile_form.is_valid()
|
||||
and event_formset.is_valid()
|
||||
and clubs_form.is_valid()
|
||||
):
|
||||
# Enregistrement du profil
|
||||
profile = profile_form.save()
|
||||
if profile.is_cof and not was_cof:
|
||||
send_custom_mail(
|
||||
"welcome", "cof@ens.fr", [member.email],
|
||||
context={'member': member},
|
||||
"welcome",
|
||||
"cof@ens.fr",
|
||||
[member.email],
|
||||
context={"member": member},
|
||||
)
|
||||
# Enregistrement des inscriptions aux événements
|
||||
for form in event_formset:
|
||||
if 'status' not in form.cleaned_data:
|
||||
form.cleaned_data['status'] = 'no'
|
||||
if form.cleaned_data['status'] == 'no':
|
||||
if "status" not in form.cleaned_data:
|
||||
form.cleaned_data["status"] = "no"
|
||||
if form.cleaned_data["status"] == "no":
|
||||
try:
|
||||
current_registration = EventRegistration.objects \
|
||||
.get(user=member, event=form.event)
|
||||
current_registration = EventRegistration.objects.get(
|
||||
user=member, event=form.event
|
||||
)
|
||||
current_registration.delete()
|
||||
except EventRegistration.DoesNotExist:
|
||||
pass
|
||||
continue
|
||||
all_choices = get_event_form_choices(form.event, form)
|
||||
(current_registration, created_reg) = \
|
||||
EventRegistration.objects.get_or_create(
|
||||
user=member, event=form.event)
|
||||
update_event_form_comments(form.event, form,
|
||||
current_registration)
|
||||
(
|
||||
current_registration,
|
||||
created_reg,
|
||||
) = EventRegistration.objects.get_or_create(
|
||||
user=member, event=form.event
|
||||
)
|
||||
update_event_form_comments(form.event, form, current_registration)
|
||||
current_registration.options = all_choices
|
||||
current_registration.paid = \
|
||||
(form.cleaned_data['status'] == 'paid')
|
||||
current_registration.paid = form.cleaned_data["status"] == "paid"
|
||||
current_registration.save()
|
||||
# if form.event.title == "Mega 15" and created_reg:
|
||||
# field = EventCommentField.objects.get(
|
||||
|
@ -508,7 +546,7 @@ def registration(request):
|
|||
# send_custom_mail(...)
|
||||
# Enregistrement des inscriptions aux clubs
|
||||
member.clubs.clear()
|
||||
for club in clubs_form.cleaned_data['clubs']:
|
||||
for club in clubs_form.cleaned_data["clubs"]:
|
||||
club.membres.add(member)
|
||||
club.save()
|
||||
|
||||
|
@ -516,20 +554,29 @@ def registration(request):
|
|||
# Success
|
||||
# ---
|
||||
|
||||
msg = ("L'inscription de {:s} (<tt>{:s}</tt>) a été "
|
||||
"enregistrée avec succès."
|
||||
.format(member.get_full_name(), member.email))
|
||||
msg = (
|
||||
"L'inscription de {:s} (<tt>{:s}</tt>) a été "
|
||||
"enregistrée avec succès.".format(
|
||||
member.get_full_name(), member.email
|
||||
)
|
||||
)
|
||||
if profile.is_cof:
|
||||
msg += "\nIl est désormais membre du COF n°{:d} !".format(
|
||||
member.profile.id)
|
||||
messages.success(request, msg, extra_tags='safe')
|
||||
return render(request, "gestioncof/registration_post.html",
|
||||
{"user_form": user_form,
|
||||
"profile_form": profile_form,
|
||||
"member": member,
|
||||
"login_clipper": login_clipper,
|
||||
"event_formset": event_formset,
|
||||
"clubs_form": clubs_form})
|
||||
member.profile.id
|
||||
)
|
||||
messages.success(request, msg, extra_tags="safe")
|
||||
return render(
|
||||
request,
|
||||
"gestioncof/registration_post.html",
|
||||
{
|
||||
"user_form": user_form,
|
||||
"profile_form": profile_form,
|
||||
"member": member,
|
||||
"login_clipper": login_clipper,
|
||||
"event_formset": event_formset,
|
||||
"clubs_form": clubs_form,
|
||||
},
|
||||
)
|
||||
else:
|
||||
return render(request, "registration.html")
|
||||
|
||||
|
@ -545,13 +592,14 @@ def membres_club(request, name):
|
|||
# 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>')
|
||||
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})
|
||||
return render(
|
||||
request,
|
||||
"membres_clubs.html",
|
||||
{"club": club, "members_no_respo": members_no_respo},
|
||||
)
|
||||
|
||||
|
||||
@buro_required
|
||||
|
@ -564,31 +612,41 @@ def change_respo(request, club_name, user_id):
|
|||
club.respos.add(user)
|
||||
else:
|
||||
raise Http404
|
||||
return redirect('membres-club', name=club_name)
|
||||
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()}
|
||||
data = {"owned_clubs": clubs.all()}
|
||||
else:
|
||||
data = {'owned_clubs': request.user.clubs_geres.all(),
|
||||
'other_clubs': clubs.exclude(respos=request.user)}
|
||||
return render(request, 'liste_clubs.html', data)
|
||||
data = {
|
||||
"owned_clubs": request.user.clubs_geres.all(),
|
||||
"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')
|
||||
response['Content-Disposition'] = 'attachment; filename=membres_cof.csv'
|
||||
response = HttpResponse(content_type="text/csv")
|
||||
response["Content-Disposition"] = "attachment; filename=membres_cof.csv"
|
||||
|
||||
writer = unicodecsv.writer(response)
|
||||
for profile in CofProfile.objects.filter(is_cof=True).all():
|
||||
user = profile.user
|
||||
bits = [user.id, user.username, user.first_name, user.last_name,
|
||||
user.email, profile.phone, profile.occupation,
|
||||
profile.departement, profile.type_cotiz]
|
||||
bits = [
|
||||
user.id,
|
||||
user.username,
|
||||
user.first_name,
|
||||
user.last_name,
|
||||
user.email,
|
||||
profile.phone,
|
||||
profile.occupation,
|
||||
profile.departement,
|
||||
profile.type_cotiz,
|
||||
]
|
||||
writer.writerow([str(bit) for bit in bits])
|
||||
|
||||
return response
|
||||
|
@ -608,18 +666,24 @@ MEGA_ORGA = "Orga"
|
|||
|
||||
|
||||
def csv_export_mega(filename, qs):
|
||||
response = HttpResponse(content_type='text/csv')
|
||||
response['Content-Disposition'] = 'attachment; filename=' + filename
|
||||
response = HttpResponse(content_type="text/csv")
|
||||
response["Content-Disposition"] = "attachment; filename=" + filename
|
||||
writer = unicodecsv.writer(response)
|
||||
|
||||
for reg in qs.all():
|
||||
user = reg.user
|
||||
profile = user.profile
|
||||
comments = "---".join(
|
||||
[comment.content for comment in reg.comments.all()])
|
||||
bits = [user.username, user.first_name, user.last_name, user.email,
|
||||
profile.phone, user.id,
|
||||
profile.comments if profile.comments else "", comments]
|
||||
comments = "---".join([comment.content for comment in reg.comments.all()])
|
||||
bits = [
|
||||
user.username,
|
||||
user.first_name,
|
||||
user.last_name,
|
||||
user.email,
|
||||
profile.phone,
|
||||
user.id,
|
||||
profile.comments if profile.comments else "",
|
||||
comments,
|
||||
]
|
||||
|
||||
writer.writerow([str(bit) for bit in bits])
|
||||
|
||||
|
@ -628,9 +692,9 @@ def csv_export_mega(filename, qs):
|
|||
|
||||
@buro_required
|
||||
def export_mega_remarksonly(request):
|
||||
filename = 'remarques_mega_{}.csv'.format(MEGA_YEAR)
|
||||
response = HttpResponse(content_type='text/csv')
|
||||
response['Content-Disposition'] = 'attachment; filename=' + filename
|
||||
filename = "remarques_mega_{}.csv".format(MEGA_YEAR)
|
||||
response = HttpResponse(content_type="text/csv")
|
||||
response["Content-Disposition"] = "attachment; filename=" + filename
|
||||
writer = unicodecsv.writer(response)
|
||||
|
||||
event = Event.objects.get(title=MEGA_EVENT_NAME)
|
||||
|
@ -639,8 +703,16 @@ def export_mega_remarksonly(request):
|
|||
reg = val.registration
|
||||
user = reg.user
|
||||
profile = user.profile
|
||||
bits = [user.username, user.first_name, user.last_name, user.email,
|
||||
profile.phone, profile.id, profile.comments, val.content]
|
||||
bits = [
|
||||
user.username,
|
||||
user.first_name,
|
||||
user.last_name,
|
||||
user.email,
|
||||
profile.phone,
|
||||
profile.id,
|
||||
profile.comments,
|
||||
val.content,
|
||||
]
|
||||
writer.writerow([str(bit) for bit in bits])
|
||||
|
||||
return response
|
||||
|
@ -672,7 +744,7 @@ def export_mega_orgas(request):
|
|||
qs = EventRegistration.objects.filter(event=event).filter(
|
||||
options__id=participant_type
|
||||
)
|
||||
return csv_export_mega('orgas_mega_{}.csv'.format(MEGA_YEAR), qs)
|
||||
return csv_export_mega("orgas_mega_{}.csv".format(MEGA_YEAR), qs)
|
||||
|
||||
|
||||
@buro_required
|
||||
|
@ -683,15 +755,15 @@ def export_mega_participants(request):
|
|||
qs = EventRegistration.objects.filter(event=event).filter(
|
||||
options__id=participant_type
|
||||
)
|
||||
return csv_export_mega('conscrits_mega_{}.csv'.format(MEGA_YEAR), qs)
|
||||
return csv_export_mega("conscrits_mega_{}.csv".format(MEGA_YEAR), qs)
|
||||
|
||||
|
||||
@buro_required
|
||||
def export_mega(request):
|
||||
event = Event.objects.filter(title=MEGA_EVENT_NAME)
|
||||
qs = EventRegistration.objects.filter(event=event) \
|
||||
.order_by("user__username")
|
||||
return csv_export_mega('all_mega_{}.csv'.format(MEGA_YEAR), qs)
|
||||
qs = EventRegistration.objects.filter(event=event).order_by("user__username")
|
||||
return csv_export_mega("all_mega_{}.csv".format(MEGA_YEAR), qs)
|
||||
|
||||
|
||||
# ------------------------------
|
||||
# Fin des exports Mega hardcodés
|
||||
|
@ -706,32 +778,28 @@ def utile_cof(request):
|
|||
@buro_required
|
||||
def utile_bda(request):
|
||||
tirages = Tirage.objects.all()
|
||||
return render(request, "utile_bda.html", {'tirages': tirages})
|
||||
return render(request, "utile_bda.html", {"tirages": tirages})
|
||||
|
||||
|
||||
@buro_required
|
||||
def liste_bdadiff(request):
|
||||
titre = "BdA diffusion"
|
||||
personnes = CofProfile.objects.filter(mailing_bda=True, is_cof=True).all()
|
||||
return render(request, "liste_mails.html",
|
||||
{"titre": titre, "personnes": personnes})
|
||||
return render(request, "liste_mails.html", {"titre": titre, "personnes": personnes})
|
||||
|
||||
|
||||
@buro_required
|
||||
def liste_bdarevente(request):
|
||||
titre = "BdA revente"
|
||||
personnes = CofProfile.objects.filter(mailing_bda_revente=True,
|
||||
is_cof=True).all()
|
||||
return render(request, "liste_mails.html", {"titre": titre,
|
||||
"personnes": personnes})
|
||||
personnes = CofProfile.objects.filter(mailing_bda_revente=True, is_cof=True).all()
|
||||
return render(request, "liste_mails.html", {"titre": titre, "personnes": personnes})
|
||||
|
||||
|
||||
@buro_required
|
||||
def liste_diffcof(request):
|
||||
titre = "Diffusion COF"
|
||||
personnes = CofProfile.objects.filter(mailing_cof=True, is_cof=True).all()
|
||||
return render(request, "liste_mails.html", {"titre": titre,
|
||||
"personnes": personnes})
|
||||
return render(request, "liste_mails.html", {"titre": titre, "personnes": personnes})
|
||||
|
||||
|
||||
@cof_required
|
||||
|
@ -740,7 +808,7 @@ def calendar(request):
|
|||
instance = CalendarSubscription.objects.get(user=request.user)
|
||||
except CalendarSubscription.DoesNotExist:
|
||||
instance = None
|
||||
if request.method == 'POST':
|
||||
if request.method == "POST":
|
||||
form = CalendarForm(request.POST, instance=instance)
|
||||
if form.is_valid():
|
||||
subscription = form.save(commit=False)
|
||||
|
@ -749,19 +817,26 @@ def calendar(request):
|
|||
subscription.token = uuid.uuid4()
|
||||
subscription.save()
|
||||
form.save_m2m()
|
||||
messages.success(request,
|
||||
"Calendrier mis à jour avec succès.")
|
||||
return render(request, "gestioncof/calendar_subscription.html",
|
||||
{'form': form,
|
||||
'token': str(subscription.token)})
|
||||
messages.success(request, "Calendrier mis à jour avec succès.")
|
||||
return render(
|
||||
request,
|
||||
"gestioncof/calendar_subscription.html",
|
||||
{"form": form, "token": str(subscription.token)},
|
||||
)
|
||||
else:
|
||||
messages.error(request, "Formulaire incorrect.")
|
||||
return render(request, "gestioncof/calendar_subscription.html",
|
||||
{'form': form})
|
||||
return render(
|
||||
request, "gestioncof/calendar_subscription.html", {"form": form}
|
||||
)
|
||||
else:
|
||||
return render(request, "gestioncof/calendar_subscription.html",
|
||||
{'form': CalendarForm(instance=instance),
|
||||
'token': instance.token if instance else None})
|
||||
return render(
|
||||
request,
|
||||
"gestioncof/calendar_subscription.html",
|
||||
{
|
||||
"form": CalendarForm(instance=instance),
|
||||
"token": instance.token if instance else None,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def calendar_ics(request, token):
|
||||
|
@ -769,33 +844,33 @@ def calendar_ics(request, token):
|
|||
shows = subscription.other_shows.all()
|
||||
if subscription.subscribe_to_my_shows:
|
||||
shows |= Spectacle.objects.filter(
|
||||
attribues__participant__user=subscription.user,
|
||||
tirage__active=True)
|
||||
attribues__participant__user=subscription.user, tirage__active=True
|
||||
)
|
||||
shows = shows.distinct()
|
||||
vcal = Calendar()
|
||||
site = Site.objects.get_current()
|
||||
for show in shows:
|
||||
vevent = Vevent()
|
||||
vevent.add('dtstart', show.date)
|
||||
vevent.add('dtend', show.date + timedelta(seconds=7200))
|
||||
vevent.add('summary', show.title)
|
||||
vevent.add('location', show.location.name)
|
||||
vevent.add('uid', 'show-{:d}-{:d}@{:s}'.format(
|
||||
show.pk, show.tirage_id, site.domain))
|
||||
vevent.add("dtstart", show.date)
|
||||
vevent.add("dtend", show.date + timedelta(seconds=7200))
|
||||
vevent.add("summary", show.title)
|
||||
vevent.add("location", show.location.name)
|
||||
vevent.add(
|
||||
"uid", "show-{:d}-{:d}@{:s}".format(show.pk, show.tirage_id, site.domain)
|
||||
)
|
||||
vcal.add_component(vevent)
|
||||
if subscription.subscribe_to_events:
|
||||
for event in Event.objects.filter(old=False).all():
|
||||
vevent = Vevent()
|
||||
vevent.add('dtstart', event.start_date)
|
||||
vevent.add('dtend', event.end_date)
|
||||
vevent.add('summary', event.title)
|
||||
vevent.add('location', event.location)
|
||||
vevent.add('description', event.description)
|
||||
vevent.add('uid', 'event-{:d}@{:s}'.format(
|
||||
event.pk, site.domain))
|
||||
vevent.add("dtstart", event.start_date)
|
||||
vevent.add("dtend", event.end_date)
|
||||
vevent.add("summary", event.title)
|
||||
vevent.add("location", event.location)
|
||||
vevent.add("description", event.description)
|
||||
vevent.add("uid", "event-{:d}@{:s}".format(event.pk, site.domain))
|
||||
vcal.add_component(vevent)
|
||||
response = HttpResponse(content=vcal.to_ical())
|
||||
response['Content-Type'] = "text/calendar"
|
||||
response["Content-Type"] = "text/calendar"
|
||||
return response
|
||||
|
||||
|
||||
|
@ -823,7 +898,7 @@ class ConfigUpdate(FormView):
|
|||
|
||||
class UserAutocomplete(Select2QuerySetView):
|
||||
model = User
|
||||
search_fields = ('username', 'first_name', 'last_name')
|
||||
search_fields = ("username", "first_name", "last_name")
|
||||
|
||||
|
||||
user_autocomplete = buro_required(UserAutocomplete.as_view())
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from django.forms.widgets import Widget
|
||||
from django.forms.utils import flatatt
|
||||
from django.forms.widgets import Widget
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
|
||||
|
@ -13,8 +13,8 @@ class TriStateCheckbox(Widget):
|
|||
|
||||
def render(self, name, value, attrs=None, choices=()):
|
||||
if value is None:
|
||||
value = 'none'
|
||||
attrs['value'] = value
|
||||
value = "none"
|
||||
attrs["value"] = value
|
||||
final_attrs = self.build_attrs(self.attrs, attrs)
|
||||
output = ["<span class=\"tristate\"%s></span>" % flatatt(final_attrs)]
|
||||
return mark_safe('\n'.join(output))
|
||||
output = ['<span class="tristate"%s></span>' % flatatt(final_attrs)]
|
||||
return mark_safe("\n".join(output))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue