Compare commits

..

No commits in common. "8cde94c5f59e49ee084646ac68c304f6d6a8bffc" and "3fea17c5559fd864015a6ed874b69d9799df6262" have entirely different histories.

29 changed files with 510 additions and 434 deletions

View File

@ -6,7 +6,7 @@ from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from .forms import ProfileForm
from .models import Club, Membership, Profile
from .models import Club, Membership, Profile, Role
class ProfileInline(admin.StackedInline):
@ -39,3 +39,4 @@ admin.site.register(User, CustomUserAdmin)
# Add other models
admin.site.register(Club)
admin.site.register(Membership)
admin.site.register(Role)

View File

@ -3,7 +3,7 @@
from rest_framework import serializers
from ..models import Profile, Club, Membership
from ..models import Profile, Club, Role, Membership
class ProfileSerializer(serializers.ModelSerializer):
@ -29,6 +29,17 @@ class ClubSerializer(serializers.ModelSerializer):
fields = '__all__'
class RoleSerializer(serializers.ModelSerializer):
"""
REST API Serializer for Roles.
The djangorestframework plugin will analyse the model `Role` and parse all fields in the API.
"""
class Meta:
model = Role
fields = '__all__'
class MembershipSerializer(serializers.ModelSerializer):
"""
REST API Serializer for Memberships.

View File

@ -1,7 +1,7 @@
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from .views import ProfileViewSet, ClubViewSet, MembershipViewSet
from .views import ProfileViewSet, ClubViewSet, RoleViewSet, MembershipViewSet
def register_members_urls(router, path):
@ -10,4 +10,5 @@ def register_members_urls(router, path):
"""
router.register(path + '/profile', ProfileViewSet)
router.register(path + '/club', ClubViewSet)
router.register(path + '/role', RoleViewSet)
router.register(path + '/membership', MembershipViewSet)

View File

@ -4,8 +4,8 @@
from rest_framework.filters import SearchFilter
from api.viewsets import ReadProtectedModelViewSet
from .serializers import ProfileSerializer, ClubSerializer, MembershipSerializer
from ..models import Profile, Club, Membership
from .serializers import ProfileSerializer, ClubSerializer, RoleSerializer, MembershipSerializer
from ..models import Profile, Club, Role, Membership
class ProfileViewSet(ReadProtectedModelViewSet):
@ -30,6 +30,18 @@ class ClubViewSet(ReadProtectedModelViewSet):
search_fields = ['$name', ]
class RoleViewSet(ReadProtectedModelViewSet):
"""
REST API View set.
The djangorestframework plugin will get all `Role` objects, serialize it to JSON with the given serializer,
then render it on /api/members/role/
"""
queryset = Role.objects.all()
serializer_class = RoleSerializer
filter_backends = [SearchFilter]
search_fields = ['$name', ]
class MembershipViewSet(ReadProtectedModelViewSet):
"""
REST API View set.

View File

@ -7,9 +7,9 @@ from django.contrib.auth.models import User
from django.utils.translation import gettext_lazy as _
from note.models import NoteSpecial
from note_kfet.inputs import Autocomplete, AmountInput, DatePickerInput
from permission.models import PermissionMask, Role
from permission.models import PermissionMask
from .models import Profile, Club, Membership
from .models import Profile, Club, Membership, Role
class CustomAuthenticationForm(AuthenticationForm):

View File

@ -247,6 +247,24 @@ class Club(models.Model):
return reverse_lazy('member:club_detail', args=(self.pk,))
class Role(models.Model):
"""
Role that an :model:`auth.User` can have in a :model:`member.Club`
"""
name = models.CharField(
verbose_name=_('name'),
max_length=255,
unique=True,
)
class Meta:
verbose_name = _('role')
verbose_name_plural = _('roles')
def __str__(self):
return str(self.name)
class Membership(models.Model):
"""
Register the membership of a user to a club, including roles and membership duration.
@ -266,7 +284,7 @@ class Membership(models.Model):
)
roles = models.ManyToManyField(
"permission.Role",
Role,
verbose_name=_("roles"),
)
@ -284,7 +302,6 @@ class Membership(models.Model):
verbose_name=_('fee'),
)
@property
def valid(self):
"""
A membership is valid if today is between the start and the end date.
@ -302,13 +319,6 @@ class Membership(models.Model):
if not Membership.objects.filter(user=self.user, club=self.club.parent_club).exists():
raise ValidationError(_('User is not a member of the parent club') + ' ' + self.club.parent_club.name)
for role in self.roles.all():
club = role.for_club
if club is not None:
if club.pk != self.club_id:
raise ValidationError(_('The role {role} does not apply to the club {club}.')
.format(role=role.name, club=club.name))
created = not self.pk
if created:
if Membership.objects.filter(

View File

@ -22,12 +22,10 @@ from note.models import Alias, NoteUser
from note.models.transactions import Transaction, SpecialTransaction
from note.tables import HistoryTable, AliasTable
from permission.backends import PermissionBackend
from permission.models import Role
from permission.views import ProtectQuerysetMixin
from wei.models import WEIClub
from .forms import ProfileForm, ClubForm, MembershipForm, CustomAuthenticationForm
from .models import Club, Membership
from .models import Club, Membership, Role
from .tables import ClubTable, UserTable, MembershipTable
@ -305,7 +303,7 @@ class ClubListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
"""
Filter the user list with the given pattern.
"""
qs = super().get_queryset().distinct()
qs = super().get_queryset().filter()
if "search" in self.request.GET:
pattern = self.request.GET["search"]
@ -427,8 +425,6 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
club = Club.objects.filter(PermissionBackend.filter_queryset(self.request.user, Club, "view"))\
.get(pk=self.kwargs["club_pk"], weiclub=None)
form.fields['credit_amount'].initial = club.membership_fee_paid
form.fields['roles'].queryset = Role.objects.filter(Q(weirole__isnull=not isinstance(club, WEIClub))
& (Q(for_club__isnull=True) | Q(for_club=club))).all()
form.fields['roles'].initial = Role.objects.filter(name="Membre de club").all()
# If the concerned club is the BDE, then we add the option that Société générale pays the membership.
@ -448,8 +444,6 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
user = old_membership.user
form.fields['user'].initial = user
form.fields['user'].disabled = True
form.fields['roles'].queryset = Role.objects.filter(Q(weirole__isnull=not isinstance(club, WEIClub))
& (Q(for_club__isnull=True) | Q(for_club=club))).all()
form.fields['roles'].initial = old_membership.roles.all()
form.fields['date_start'].initial = old_membership.date_end + timedelta(days=1)
form.fields['credit_amount'].initial = club.membership_fee_paid if user.profile.paid \
@ -640,11 +634,6 @@ class ClubManageRolesView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
del form.fields['last_name']
del form.fields['first_name']
del form.fields['bank']
club = self.object.club
form.fields['roles'].queryset = Role.objects.filter(Q(weirole__isnull=isinstance(club, WEIClub))
& (Q(for_club__isnull=True) | Q(for_club=club))).all()
return form
def get_success_url(self):

View File

@ -3,7 +3,7 @@
from django.contrib import admin
from .models import Permission, PermissionMask, Role
from .models import Permission, PermissionMask, RolePermissions
@admin.register(PermissionMask)
@ -22,9 +22,9 @@ class PermissionAdmin(admin.ModelAdmin):
list_display = ('type', 'model', 'field', 'mask', 'description', )
@admin.register(Role)
class RoleAdmin(admin.ModelAdmin):
@admin.register(RolePermissions)
class RolePermissionsAdmin(admin.ModelAdmin):
"""
Admin customisation for Role
Admin customisation for RolePermissions
"""
list_display = ('name', )
list_display = ('role', )

View File

@ -3,7 +3,7 @@
from rest_framework import serializers
from ..models import Permission, Role
from ..models import Permission, RolePermissions
class PermissionSerializer(serializers.ModelSerializer):
@ -17,12 +17,12 @@ class PermissionSerializer(serializers.ModelSerializer):
fields = '__all__'
class RoleSerializer(serializers.ModelSerializer):
class RolePermissionsSerializer(serializers.ModelSerializer):
"""
REST API Serializer for Role types.
The djangorestframework plugin will analyse the model `Role` and parse all fields in the API.
REST API Serializer for RolePermissions types.
The djangorestframework plugin will analyse the model `RolePermissions` and parse all fields in the API.
"""
class Meta:
model = Role
model = RolePermissions
fields = '__all__'

View File

@ -1,7 +1,7 @@
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from .views import PermissionViewSet, RoleViewSet
from .views import PermissionViewSet, RolePermissionsViewSet
def register_permission_urls(router, path):
@ -9,4 +9,4 @@ def register_permission_urls(router, path):
Configure router for permission REST API.
"""
router.register(path + "/permission", PermissionViewSet)
router.register(path + "/roles", RoleViewSet)
router.register(path + "/roles", RolePermissionsViewSet)

View File

@ -4,8 +4,8 @@
from django_filters.rest_framework import DjangoFilterBackend
from api.viewsets import ReadOnlyProtectedModelViewSet
from .serializers import PermissionSerializer, RoleSerializer
from ..models import Permission, Role
from .serializers import PermissionSerializer, RolePermissionsSerializer
from ..models import Permission, RolePermissions
class PermissionViewSet(ReadOnlyProtectedModelViewSet):
@ -20,13 +20,13 @@ class PermissionViewSet(ReadOnlyProtectedModelViewSet):
filterset_fields = ['model', 'type', ]
class RoleViewSet(ReadOnlyProtectedModelViewSet):
class RolePermissionsViewSet(ReadOnlyProtectedModelViewSet):
"""
REST API View set.
The djangorestframework plugin will get all `RolePermission` objects, serialize it to JSON with the given serializer
then render it on /api/permission/roles/
"""
queryset = Role.objects.all()
serializer_class = RoleSerializer
queryset = RolePermissions.objects.all()
serializer_class = RolePermissionsSerializer
filter_backends = [DjangoFilterBackend]
filterset_fields = ['role', ]

View File

@ -37,17 +37,17 @@ class PermissionBackend(ModelBackend):
return Permission.objects.none()
qs = Permission.objects.annotate(
club=F("role__membership__club"),
membership=F("role__membership"),
club=F("rolepermissions__role__membership__club"),
membership=F("rolepermissions__role__membership"),
).filter(
(
Q(
role__membership__date_start__lte=timezone.now().today(),
role__membership__date_end__gte=timezone.now().today(),
rolepermissions__role__membership__date_start__lte=timezone.now().today(),
rolepermissions__role__membership__date_end__gte=timezone.now().today(),
)
| Q(permanent=True)
)
& Q(role__membership__user=user)
& Q(rolepermissions__role__membership__user=user)
& Q(type=t)
& Q(mask__rank__lte=get_current_session().get("permission_mask", 0))
)

View File

@ -1,4 +1,165 @@
[
{
"model": "member.role",
"pk": 1,
"fields": {
"name": "Adh\u00e9rent BDE"
}
},
{
"model": "member.role",
"pk": 2,
"fields": {
"name": "Adh\u00e9rent Kfet"
}
},
{
"model": "member.role",
"pk": 3,
"fields": {
"name": "Membre de club"
}
},
{
"model": "member.role",
"pk": 4,
"fields": {
"name": "Bureau de club"
}
},
{
"model": "member.role",
"pk": 5,
"fields": {
"name": "Pr\u00e9sident\u00b7e de club"
}
},
{
"model": "member.role",
"pk": 6,
"fields": {
"name": "Tr\u00e9sorier\u00b7\u00e8re de club"
}
},
{
"model": "member.role",
"pk": 7,
"fields": {
"name": "Pr\u00e9sident\u00b7e BDE"
}
},
{
"model": "member.role",
"pk": 8,
"fields": {
"name": "Tr\u00e9sorier\u00b7\u00e8re BDE"
}
},
{
"model": "member.role",
"pk": 9,
"fields": {
"name": "Respo info"
}
},
{
"model": "member.role",
"pk": 10,
"fields": {
"name": "GC Kfet"
}
},
{
"model": "member.role",
"pk": 11,
"fields": {
"name": "Res[pot]"
}
},
{
"model": "member.role",
"pk": 12,
"fields": {
"name": "GC WEI"
}
},
{
"model": "member.role",
"pk": 13,
"fields": {
"name": "Chef de bus"
}
},
{
"model": "member.role",
"pk": 14,
"fields": {
"name": "Chef d'\u00e9quipe"
}
},
{
"model": "member.role",
"pk": 15,
"fields": {
"name": "\u00c9lectron libre"
}
},
{
"model": "member.role",
"pk": 16,
"fields": {
"name": "\u00c9lectron libre (avec perm)"
}
},
{
"model": "member.role",
"pk": 17,
"fields": {
"name": "1A"
}
},
{
"model": "member.role",
"pk": 18,
"fields": {
"name": "Adhérent WEI"
}
},
{
"model": "wei.weirole",
"pk": 12,
"fields": {}
},
{
"model": "wei.weirole",
"pk": 13,
"fields": {}
},
{
"model": "wei.weirole",
"pk": 14,
"fields": {}
},
{
"model": "wei.weirole",
"pk": 15,
"fields": {}
},
{
"model": "wei.weirole",
"pk": 16,
"fields": {}
},
{
"model": "wei.weirole",
"pk": 17,
"fields": {}
},
{
"model": "wei.weirole",
"pk": 18,
"fields": {}
},
{
"model": "permission.permissionmask",
"pk": 1,
@ -2056,11 +2217,10 @@
}
},
{
"model": "permission.role",
"model": "permission.rolepermissions",
"pk": 1,
"fields": {
"for_club": 1,
"name": "Adh\u00e9rent BDE",
"role": 1,
"permissions": [
1,
2,
@ -2081,11 +2241,10 @@
}
},
{
"model": "permission.role",
"model": "permission.rolepermissions",
"pk": 2,
"fields": {
"for_club": 2,
"name": "Adh\u00e9rent Kfet",
"role": 2,
"permissions": [
34,
35,
@ -2108,20 +2267,10 @@
}
},
{
"model": "permission.role",
"pk": 3,
"fields": {
"for_club": null,
"name": "Membre de club",
"permissions": []
}
},
{
"model": "permission.role",
"model": "permission.rolepermissions",
"pk": 4,
"fields": {
"for_club": null,
"name": "Bureau de club",
"role": 4,
"permissions": [
22,
47,
@ -2130,11 +2279,10 @@
}
},
{
"model": "permission.role",
"model": "permission.rolepermissions",
"pk": 5,
"fields": {
"for_club": null,
"name": "Pr\u00e9sident\u00b7e de club",
"role": 5,
"permissions": [
50,
51,
@ -2143,11 +2291,10 @@
}
},
{
"model": "permission.role",
"model": "permission.rolepermissions",
"pk": 6,
"fields": {
"for_club": null,
"name": "Tr\u00e9sorier\u00b7\u00e8re de club",
"role": 6,
"permissions": [
59,
19,
@ -2162,11 +2309,10 @@
}
},
{
"model": "permission.role",
"model": "permission.rolepermissions",
"pk": 7,
"fields": {
"for_club": 1,
"name": "Pr\u00e9sident\u00b7e BDE",
"role": 7,
"permissions": [
24,
25,
@ -2177,11 +2323,10 @@
}
},
{
"model": "permission.role",
"model": "permission.rolepermissions",
"pk": 8,
"fields": {
"for_club": 1,
"name": "Tr\u00e9sorier\u00b7\u00e8re BDE",
"role": 8,
"permissions": [
23,
24,
@ -2214,11 +2359,10 @@
}
},
{
"model": "permission.role",
"model": "permission.rolepermissions",
"pk": 9,
"fields": {
"for_club": 1,
"name": "Respo info",
"role": 9,
"permissions": [
1,
2,
@ -2350,11 +2494,10 @@
}
},
{
"model": "permission.role",
"model": "permission.rolepermissions",
"pk": 10,
"fields": {
"for_club": 2,
"name": "GC Kfet",
"role": 10,
"permissions": [
32,
33,
@ -2378,11 +2521,10 @@
}
},
{
"model": "permission.role",
"model": "permission.rolepermissions",
"pk": 11,
"fields": {
"for_club": 2,
"name": "Res[pot]",
"role": 11,
"permissions": [
37,
38,
@ -2396,11 +2538,10 @@
}
},
{
"model": "permission.role",
"model": "permission.rolepermissions",
"pk": 12,
"fields": {
"for_club": null,
"name": "GC WEI",
"role": 12,
"permissions": [
76,
80,
@ -2430,11 +2571,10 @@
}
},
{
"model": "permission.role",
"model": "permission.rolepermissions",
"pk": 13,
"fields": {
"for_club": null,
"name": "Chef de bus",
"role": 13,
"permissions": [
117,
118,
@ -2446,11 +2586,10 @@
}
},
{
"model": "permission.role",
"model": "permission.rolepermissions",
"pk": 14,
"fields": {
"for_club": null,
"name": "Chef d'\u00e9quipe",
"role": 14,
"permissions": [
116,
123,
@ -2460,38 +2599,10 @@
}
},
{
"model": "permission.role",
"pk": 15,
"fields": {
"for_club": null,
"name": "\u00c9lectron libre",
"permissions": []
}
},
{
"model": "permission.role",
"model": "permission.rolepermissions",
"pk": 16,
"fields": {
"for_club": null,
"name": "\u00c9lectron libre (avec perm)",
"permissions": []
}
},
{
"model": "permission.role",
"pk": 17,
"fields": {
"for_club": null,
"name": "1A",
"permissions": []
}
},
{
"model": "permission.role",
"pk": 18,
"fields": {
"for_club": null,
"name": "Adhérent WEI",
"role": 18,
"permissions": [
97,
99,
@ -2507,40 +2618,5 @@
95
]
}
},
{
"model": "wei.weirole",
"pk": 12,
"fields": {}
},
{
"model": "wei.weirole",
"pk": 13,
"fields": {}
},
{
"model": "wei.weirole",
"pk": 14,
"fields": {}
},
{
"model": "wei.weirole",
"pk": 15,
"fields": {}
},
{
"model": "wei.weirole",
"pk": 16,
"fields": {}
},
{
"model": "wei.weirole",
"pk": 17,
"fields": {}
},
{
"model": "wei.weirole",
"pk": 18,
"fields": {}
}
]

View File

@ -10,6 +10,7 @@ from django.core.exceptions import ValidationError
from django.db import models
from django.db.models import F, Q, Model
from django.utils.translation import gettext_lazy as _
from member.models import Role
class InstancedPermission:
@ -306,30 +307,23 @@ class Permission(models.Model):
return self.description
class Role(models.Model):
class RolePermissions(models.Model):
"""
Permissions associated with a Role
"""
name = models.CharField(
max_length=255,
verbose_name=_("name"),
role = models.OneToOneField(
Role,
on_delete=models.PROTECT,
related_name='permissions',
verbose_name=_('role'),
)
permissions = models.ManyToManyField(
Permission,
verbose_name=_("permissions"),
)
for_club = models.ForeignKey(
"member.Club",
verbose_name=_("for club"),
on_delete=models.PROTECT,
null=True,
default=None,
)
def __str__(self):
return self.name
return str(self.role)
class Meta:
verbose_name = _("role permissions")

View File

@ -5,10 +5,9 @@ from datetime import date
from django.forms import HiddenInput
from django.utils.translation import gettext_lazy as _
from django.views.generic import UpdateView, TemplateView
from member.models import Membership
from member.models import Role, Membership
from .backends import PermissionBackend
from .models import Role
class ProtectQuerysetMixin:

View File

@ -15,11 +15,10 @@ from django.views.generic import CreateView, TemplateView, DetailView
from django.views.generic.edit import FormMixin
from django_tables2 import SingleTableView
from member.forms import ProfileForm
from member.models import Membership, Club
from member.models import Membership, Club, Role
from note.models import SpecialTransaction
from note.templatetags.pretty_money import pretty_money
from permission.backends import PermissionBackend
from permission.models import Role
from permission.views import ProtectQuerysetMixin
from .forms import SignUpForm, ValidationForm
@ -165,7 +164,7 @@ class FutureUserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableVi
:param kwargs:
:return:
"""
qs = super().get_queryset().distinct().filter(profile__registration_valid=False)
qs = super().get_queryset().filter(profile__registration_valid=False)
if "search" in self.request.GET:
pattern = self.request.GET["search"]

@ -1 +1 @@
Subproject commit 85568dd4f5e24770fb2e3321100aeddcc28580a7
Subproject commit 580948fe1da1904ba6418daafb48a0a64824a11b

View File

@ -8,6 +8,7 @@ from crispy_forms.layout import Submit
from django import forms
from django.utils.translation import gettext_lazy as _
from note_kfet.inputs import DatePickerInput, AmountInput
from permission.backends import PermissionBackend
from .models import Invoice, Product, Remittance, SpecialTransactionProxy

View File

@ -96,7 +96,7 @@ class WEIMembershipForm(forms.ModelForm):
class BusForm(forms.ModelForm):
class Meta:
model = Bus
exclude = ('information_json',)
fields = '__all__'
widgets = {
"wei": Autocomplete(
WEIClub,

View File

@ -8,9 +8,8 @@ from django.conf import settings
from django.contrib.auth.models import User
from django.db import models
from django.utils.translation import gettext_lazy as _
from member.models import Club, Membership
from member.models import Role, Club, Membership
from note.models import MembershipTransaction
from permission.models import Role
class WEIClub(Club):
@ -114,7 +113,6 @@ class BusTeam(models.Model):
name = models.CharField(
max_length=255,
verbose_name=_("name"),
)
color = models.PositiveIntegerField( # Use a color picker to get the hexa code

View File

@ -144,10 +144,10 @@ class BusTable(tables.Table):
)
def render_teams(self, value):
return ", ".join(team.name for team in value.order_by('name').all())
return ", ".join(team.name for team in value.all())
def render_count(self, value):
return str(value) + " " + (str(_("members")) if value > 1 else str(_("member")))
return str(value) + " " + (str(_("members")) if value > 0 else str(_("member")))
class Meta:
attrs = {
@ -178,7 +178,7 @@ class BusTeamTable(tables.Table):
)
def render_count(self, value):
return str(value) + " " + (str(_("members")) if value > 1 else str(_("member")))
return str(value) + " " + (str(_("members")) if value > 0 else str(_("member")))
count = tables.Column(
verbose_name=_("Members count"),

View File

@ -177,7 +177,7 @@ class WEIMembershipsView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableVi
return super().dispatch(request, *args, **kwargs)
def get_queryset(self, **kwargs):
qs = super().get_queryset(**kwargs).filter(club=self.club).distinct()
qs = super().get_queryset(**kwargs).filter(club=self.club)
pattern = self.request.GET.get("search", "")
@ -214,7 +214,7 @@ class WEIRegistrationsView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTable
return super().dispatch(request, *args, **kwargs)
def get_queryset(self, **kwargs):
qs = super().get_queryset(**kwargs).filter(wei=self.club, membership=None).distinct()
qs = super().get_queryset(**kwargs).filter(wei=self.club, membership=None)
pattern = self.request.GET.get("search", "")
@ -330,7 +330,7 @@ class BusManageView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
bus = self.object
teams = BusTeam.objects.filter(PermissionBackend.filter_queryset(self.request.user, BusTeam, "view")) \
.filter(bus=bus).annotate(count=Count("memberships")).order_by("name")
.filter(bus=bus).annotate(count=Count("memberships"))
teams_table = BusTeamTable(data=teams, prefix="team-")
context["teams"] = teams_table

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-25 19:55+0200\n"
"POT-Creation-Date: 2020-07-25 16:50+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -44,11 +44,11 @@ msgid "You can't invite more than 3 people to this activity."
msgstr ""
#: apps/activity/models.py:23 apps/activity/models.py:48
#: apps/member/models.py:151 apps/note/models/notes.py:188
#: apps/note/models/transactions.py:25 apps/note/models/transactions.py:45
#: apps/note/models/transactions.py:261 apps/permission/models.py:315
#: apps/wei/models.py:65 apps/wei/models.py:117
#: templates/member/club_info.html:13 templates/member/profile_info.html:14
#: apps/member/models.py:151 apps/member/models.py:255
#: apps/note/models/notes.py:188 apps/note/models/transactions.py:25
#: apps/note/models/transactions.py:45 apps/note/models/transactions.py:261
#: apps/wei/models.py:64 templates/member/club_info.html:13
#: templates/member/profile_info.html:14
#: templates/registration/future_profile_detail.html:16
#: templates/wei/weiclub_info.html:13 templates/wei/weimembership_form.html:18
msgid "name"
@ -71,21 +71,21 @@ msgid "activity types"
msgstr ""
#: apps/activity/models.py:53 apps/note/models/transactions.py:81
#: apps/permission/models.py:102 apps/permission/models.py:181
#: apps/wei/models.py:71 apps/wei/models.py:128
#: apps/permission/models.py:103 apps/permission/models.py:182
#: apps/wei/models.py:70 apps/wei/models.py:126
#: templates/activity/activity_detail.html:16
msgid "description"
msgstr ""
#: apps/activity/models.py:60 apps/note/models/notes.py:164
#: apps/note/models/transactions.py:66 apps/permission/models.py:156
#: apps/note/models/transactions.py:66 apps/permission/models.py:157
#: templates/activity/activity_detail.html:19
msgid "type"
msgstr ""
#: apps/activity/models.py:66 apps/logs/models.py:21 apps/member/models.py:259
#: apps/activity/models.py:66 apps/logs/models.py:21 apps/member/models.py:277
#: apps/note/models/notes.py:117 apps/treasury/models.py:221
#: apps/wei/models.py:159 templates/treasury/sogecredit_detail.html:14
#: apps/wei/models.py:157 templates/treasury/sogecredit_detail.html:14
#: templates/wei/survey.html:16
msgid "user"
msgstr ""
@ -187,12 +187,12 @@ msgid "Type"
msgstr ""
#: apps/activity/tables.py:77 apps/member/forms.py:83
#: apps/registration/forms.py:64 apps/treasury/forms.py:120
#: apps/registration/forms.py:64 apps/treasury/forms.py:121
msgid "Last name"
msgstr ""
#: apps/activity/tables.py:79 apps/member/forms.py:88
#: apps/registration/forms.py:69 apps/treasury/forms.py:122
#: apps/registration/forms.py:69 apps/treasury/forms.py:123
#: templates/note/transaction_form.html:126
msgid "First name"
msgstr ""
@ -225,7 +225,7 @@ msgstr ""
msgid "IP Address"
msgstr ""
#: apps/logs/models.py:35 apps/permission/models.py:126
#: apps/logs/models.py:35 apps/permission/models.py:127
msgid "model"
msgstr ""
@ -304,7 +304,7 @@ msgid "Credit amount"
msgstr ""
#: apps/member/forms.py:93 apps/registration/forms.py:74
#: apps/treasury/forms.py:124 templates/note/transaction_form.html:132
#: apps/treasury/forms.py:125 templates/note/transaction_form.html:132
msgid "Bank"
msgstr ""
@ -480,7 +480,7 @@ msgid ""
"members can renew their membership."
msgstr ""
#: apps/member/models.py:240 apps/member/models.py:265
#: apps/member/models.py:240 apps/member/models.py:283
#: apps/note/models/notes.py:139
msgid "club"
msgstr ""
@ -489,45 +489,44 @@ msgstr ""
msgid "clubs"
msgstr ""
#: apps/member/models.py:270
#: apps/member/models.py:261 apps/permission/models.py:318
msgid "role"
msgstr ""
#: apps/member/models.py:262 apps/member/models.py:288
msgid "roles"
msgstr ""
#: apps/member/models.py:275
#: apps/member/models.py:293
msgid "membership starts on"
msgstr ""
#: apps/member/models.py:279
#: apps/member/models.py:297
msgid "membership ends on"
msgstr ""
#: apps/member/models.py:284
#: apps/member/models.py:302
msgid "fee"
msgstr ""
#: apps/member/models.py:303 apps/member/views.py:527 apps/wei/views.py:768
#: apps/member/models.py:320 apps/member/views.py:521 apps/wei/views.py:768
msgid "User is not a member of the parent club"
msgstr ""
#: apps/member/models.py:309
#, python-brace-format
msgid "The role {role} does not apply to the club {club}."
msgstr ""
#: apps/member/models.py:320 apps/member/views.py:536
#: apps/member/models.py:330 apps/member/views.py:530
msgid "User is already a member of the club"
msgstr ""
#: apps/member/models.py:371
#: apps/member/models.py:381
#, python-brace-format
msgid "Membership of {user} for the club {club}"
msgstr ""
#: apps/member/models.py:374
#: apps/member/models.py:384
msgid "membership"
msgstr ""
#: apps/member/models.py:375
#: apps/member/models.py:385
msgid "memberships"
msgstr ""
@ -535,41 +534,41 @@ msgstr ""
msgid "Renew"
msgstr ""
#: apps/member/views.py:64 apps/registration/forms.py:23
#: apps/member/views.py:62 apps/registration/forms.py:23
msgid "This address must be valid."
msgstr ""
#: apps/member/views.py:67 templates/member/profile_info.html:47
#: apps/member/views.py:65 templates/member/profile_info.html:47
#: templates/registration/future_profile_detail.html:48
#: templates/wei/weimembership_form.html:124
msgid "Update Profile"
msgstr ""
#: apps/member/views.py:77
#: apps/member/views.py:75
msgid "An alias with a similar name already exists."
msgstr ""
#: apps/member/views.py:183
#: apps/member/views.py:181
msgid "Search user"
msgstr ""
#: apps/member/views.py:522 apps/wei/views.py:759
#: apps/member/views.py:516 apps/wei/views.py:759
msgid ""
"This user don't have enough money to join this club, and can't have a "
"negative balance."
msgstr ""
#: apps/member/views.py:540
#: apps/member/views.py:534
msgid "The membership must start after {:%m-%d-%Y}."
msgstr ""
#: apps/member/views.py:545
#: apps/member/views.py:539
msgid "The membership must begin before {:%m-%d-%Y}."
msgstr ""
#: apps/member/views.py:562 apps/member/views.py:564 apps/member/views.py:566
#: apps/registration/views.py:290 apps/registration/views.py:292
#: apps/registration/views.py:294
#: apps/member/views.py:556 apps/member/views.py:558 apps/member/views.py:560
#: apps/registration/views.py:289 apps/registration/views.py:291
#: apps/registration/views.py:293
msgid "This field is required."
msgstr ""
@ -835,67 +834,63 @@ msgstr ""
msgid "Consumptions"
msgstr ""
#: apps/permission/models.py:81
#: apps/permission/models.py:82
#, python-brace-format
msgid "Can {type} {model}.{field} in {query}"
msgstr ""
#: apps/permission/models.py:83
#: apps/permission/models.py:84
#, python-brace-format
msgid "Can {type} {model} in {query}"
msgstr ""
#: apps/permission/models.py:96
#: apps/permission/models.py:97
msgid "rank"
msgstr ""
#: apps/permission/models.py:109
#: apps/permission/models.py:110
msgid "permission mask"
msgstr ""
#: apps/permission/models.py:110
#: apps/permission/models.py:111
msgid "permission masks"
msgstr ""
#: apps/permission/models.py:150
#: apps/permission/models.py:151
msgid "query"
msgstr ""
#: apps/permission/models.py:163
#: apps/permission/models.py:164
msgid "mask"
msgstr ""
#: apps/permission/models.py:169
#: apps/permission/models.py:170
msgid "field"
msgstr ""
#: apps/permission/models.py:174
#: apps/permission/models.py:175
msgid ""
"Tells if the permission should be granted even if the membership of the user "
"is expired."
msgstr ""
#: apps/permission/models.py:175 templates/permission/all_rights.html:26
#: apps/permission/models.py:176 templates/permission/all_rights.html:26
msgid "permanent"
msgstr ""
#: apps/permission/models.py:186
#: apps/permission/models.py:187
msgid "permission"
msgstr ""
#: apps/permission/models.py:187 apps/permission/models.py:320
#: apps/permission/models.py:188 apps/permission/models.py:322
msgid "permissions"
msgstr ""
#: apps/permission/models.py:192
#: apps/permission/models.py:193
msgid "Specifying field applies only to view and change permission types."
msgstr ""
#: apps/permission/models.py:325
msgid "for club"
msgstr ""
#: apps/permission/models.py:335 apps/permission/models.py:336
#: apps/permission/models.py:329 apps/permission/models.py:330
msgid "role permissions"
msgstr ""
@ -920,7 +915,7 @@ msgid ""
"{model_name}."
msgstr ""
#: apps/permission/views.py:48
#: apps/permission/views.py:47
msgid "All rights"
msgstr ""
@ -946,31 +941,31 @@ msgstr ""
msgid "Join Kfet Club"
msgstr ""
#: apps/registration/views.py:79
#: apps/registration/views.py:78
msgid "Email validation"
msgstr ""
#: apps/registration/views.py:125
#: apps/registration/views.py:124
msgid "Email validation unsuccessful"
msgstr ""
#: apps/registration/views.py:136
#: apps/registration/views.py:135
msgid "Email validation email sent"
msgstr ""
#: apps/registration/views.py:189
#: apps/registration/views.py:188
msgid "Unregistered users"
msgstr ""
#: apps/registration/views.py:256
#: apps/registration/views.py:255
msgid "You must join the BDE."
msgstr ""
#: apps/registration/views.py:278
#: apps/registration/views.py:277
msgid "You must join BDE club before joining Kfet club."
msgstr ""
#: apps/registration/views.py:283
#: apps/registration/views.py:282
msgid ""
"The entered amount is not enough for the memberships, should be at least {}"
msgstr ""
@ -979,7 +974,7 @@ msgstr ""
msgid "Treasury"
msgstr ""
#: apps/treasury/forms.py:84 apps/treasury/forms.py:132
#: apps/treasury/forms.py:85 apps/treasury/forms.py:133
#: templates/activity/activity_form.html:9
#: templates/activity/activity_invite.html:8
#: templates/django_filters/rest_framework/form.html:5
@ -991,19 +986,19 @@ msgstr ""
msgid "Submit"
msgstr ""
#: apps/treasury/forms.py:86
#: apps/treasury/forms.py:87
msgid "Close"
msgstr ""
#: apps/treasury/forms.py:95
#: apps/treasury/forms.py:96
msgid "Remittance is already closed."
msgstr ""
#: apps/treasury/forms.py:100
#: apps/treasury/forms.py:101
msgid "You can't change the type of the remittance."
msgstr ""
#: apps/treasury/forms.py:126 apps/treasury/tables.py:47
#: apps/treasury/forms.py:127 apps/treasury/tables.py:47
#: apps/treasury/tables.py:113 templates/note/transaction_form.html:95
#: templates/treasury/remittance_form.html:18
msgid "Amount"
@ -1172,13 +1167,13 @@ msgstr ""
msgid "No"
msgstr ""
#: apps/wei/apps.py:10 apps/wei/models.py:48 apps/wei/models.py:49
#: apps/wei/models.py:60 apps/wei/models.py:166 templates/base.html:130
#: apps/wei/apps.py:10 apps/wei/models.py:47 apps/wei/models.py:48
#: apps/wei/models.py:59 apps/wei/models.py:164 templates/base.html:130
msgid "WEI"
msgstr ""
#: apps/wei/forms/registration.py:47 apps/wei/models.py:112
#: apps/wei/models.py:275
#: apps/wei/forms/registration.py:47 apps/wei/models.py:111
#: apps/wei/models.py:273
msgid "bus"
msgstr ""
@ -1199,7 +1194,7 @@ msgid ""
msgstr ""
#: apps/wei/forms/registration.py:61 apps/wei/forms/registration.py:67
#: apps/wei/models.py:147
#: apps/wei/models.py:145
msgid "WEI Roles"
msgstr ""
@ -1211,151 +1206,151 @@ msgstr ""
msgid "This team doesn't belong to the given bus."
msgstr ""
#: apps/wei/models.py:23 templates/wei/weiclub_info.html:23
#: apps/wei/models.py:22 templates/wei/weiclub_info.html:23
msgid "year"
msgstr ""
#: apps/wei/models.py:27 templates/wei/weiclub_info.html:17
#: apps/wei/models.py:26 templates/wei/weiclub_info.html:17
msgid "date start"
msgstr ""
#: apps/wei/models.py:31 templates/wei/weiclub_info.html:20
#: apps/wei/models.py:30 templates/wei/weiclub_info.html:20
msgid "date end"
msgstr ""
#: apps/wei/models.py:76
#: apps/wei/models.py:75
msgid "survey information"
msgstr ""
#: apps/wei/models.py:77
#: apps/wei/models.py:76
msgid "Information about the survey for new members, encoded in JSON"
msgstr ""
#: apps/wei/models.py:99
#: apps/wei/models.py:98
msgid "Bus"
msgstr ""
#: apps/wei/models.py:100 templates/wei/weiclub_tables.html:79
#: apps/wei/models.py:99 templates/wei/weiclub_tables.html:79
msgid "Buses"
msgstr ""
#: apps/wei/models.py:121
#: apps/wei/models.py:119
msgid "color"
msgstr ""
#: apps/wei/models.py:122
#: apps/wei/models.py:120
msgid "The color of the T-Shirt, stored with its number equivalent"
msgstr ""
#: apps/wei/models.py:136
#: apps/wei/models.py:134
msgid "Bus team"
msgstr ""
#: apps/wei/models.py:137
#: apps/wei/models.py:135
msgid "Bus teams"
msgstr ""
#: apps/wei/models.py:146
#: apps/wei/models.py:144
msgid "WEI Role"
msgstr ""
#: apps/wei/models.py:171
#: apps/wei/models.py:169
msgid "Credit from Société générale"
msgstr ""
#: apps/wei/models.py:176
#: apps/wei/models.py:174
msgid "Caution check given"
msgstr ""
#: apps/wei/models.py:180 templates/wei/weimembership_form.html:62
#: apps/wei/models.py:178 templates/wei/weimembership_form.html:62
msgid "birth date"
msgstr ""
#: apps/wei/models.py:186
#: apps/wei/models.py:184
msgid "Male"
msgstr ""
#: apps/wei/models.py:187
#: apps/wei/models.py:185
msgid "Female"
msgstr ""
#: apps/wei/models.py:188
#: apps/wei/models.py:186
msgid "Non binary"
msgstr ""
#: apps/wei/models.py:190 templates/wei/weimembership_form.html:59
#: apps/wei/models.py:188 templates/wei/weimembership_form.html:59
msgid "gender"
msgstr ""
#: apps/wei/models.py:196 templates/wei/weimembership_form.html:65
#: apps/wei/models.py:194 templates/wei/weimembership_form.html:65
msgid "health issues"
msgstr ""
#: apps/wei/models.py:201 templates/wei/weimembership_form.html:68
#: apps/wei/models.py:199 templates/wei/weimembership_form.html:68
msgid "emergency contact name"
msgstr ""
#: apps/wei/models.py:206 templates/wei/weimembership_form.html:71
#: apps/wei/models.py:204 templates/wei/weimembership_form.html:71
msgid "emergency contact phone"
msgstr ""
#: apps/wei/models.py:211 templates/wei/weimembership_form.html:74
#: apps/wei/models.py:209 templates/wei/weimembership_form.html:74
msgid ""
"Register on the mailing list to stay informed of the events of the campus (1 "
"mail/week)"
msgstr ""
#: apps/wei/models.py:216 templates/wei/weimembership_form.html:77
#: apps/wei/models.py:214 templates/wei/weimembership_form.html:77
msgid ""
"Register on the mailing list to stay informed of the sport events of the "
"campus (1 mail/week)"
msgstr ""
#: apps/wei/models.py:221 templates/wei/weimembership_form.html:80
#: apps/wei/models.py:219 templates/wei/weimembership_form.html:80
msgid ""
"Register on the mailing list to stay informed of the art events of the "
"campus (1 mail/week)"
msgstr ""
#: apps/wei/models.py:226 templates/wei/weimembership_form.html:56
#: apps/wei/models.py:224 templates/wei/weimembership_form.html:56
msgid "first year"
msgstr ""
#: apps/wei/models.py:227
#: apps/wei/models.py:225
msgid "Tells if the user is new in the school."
msgstr ""
#: apps/wei/models.py:232
#: apps/wei/models.py:230
msgid "registration information"
msgstr ""
#: apps/wei/models.py:233
#: apps/wei/models.py:231
msgid ""
"Information about the registration (buses for old members, survey fot the "
"new members), encoded in JSON"
msgstr ""
#: apps/wei/models.py:264
#: apps/wei/models.py:262
msgid "WEI User"
msgstr ""
#: apps/wei/models.py:265
#: apps/wei/models.py:263
msgid "WEI Users"
msgstr ""
#: apps/wei/models.py:285
#: apps/wei/models.py:283
msgid "team"
msgstr ""
#: apps/wei/models.py:295
#: apps/wei/models.py:293
msgid "WEI registration"
msgstr ""
#: apps/wei/models.py:299
#: apps/wei/models.py:297
msgid "WEI membership"
msgstr ""
#: apps/wei/models.py:300
#: apps/wei/models.py:298
msgid "WEI memberships"
msgstr ""
@ -1425,15 +1420,15 @@ msgstr ""
msgid "Survey WEI"
msgstr ""
#: note_kfet/settings/base.py:155
#: note_kfet/settings/base.py:154
msgid "German"
msgstr ""
#: note_kfet/settings/base.py:156
#: note_kfet/settings/base.py:155
msgid "English"
msgstr ""
#: note_kfet/settings/base.py:157
#: note_kfet/settings/base.py:156
msgid "French"
msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-25 19:55+0200\n"
"POT-Creation-Date: 2020-07-25 16:50+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -45,11 +45,11 @@ msgid "You can't invite more than 3 people to this activity."
msgstr "Vous ne pouvez pas inviter plus de 3 personnes à cette activité."
#: apps/activity/models.py:23 apps/activity/models.py:48
#: apps/member/models.py:151 apps/note/models/notes.py:188
#: apps/note/models/transactions.py:25 apps/note/models/transactions.py:45
#: apps/note/models/transactions.py:261 apps/permission/models.py:315
#: apps/wei/models.py:65 apps/wei/models.py:117
#: templates/member/club_info.html:13 templates/member/profile_info.html:14
#: apps/member/models.py:151 apps/member/models.py:255
#: apps/note/models/notes.py:188 apps/note/models/transactions.py:25
#: apps/note/models/transactions.py:45 apps/note/models/transactions.py:261
#: apps/wei/models.py:64 templates/member/club_info.html:13
#: templates/member/profile_info.html:14
#: templates/registration/future_profile_detail.html:16
#: templates/wei/weiclub_info.html:13 templates/wei/weimembership_form.html:18
msgid "name"
@ -72,21 +72,21 @@ msgid "activity types"
msgstr "types d'activité"
#: apps/activity/models.py:53 apps/note/models/transactions.py:81
#: apps/permission/models.py:102 apps/permission/models.py:181
#: apps/wei/models.py:71 apps/wei/models.py:128
#: apps/permission/models.py:103 apps/permission/models.py:182
#: apps/wei/models.py:70 apps/wei/models.py:126
#: templates/activity/activity_detail.html:16
msgid "description"
msgstr "description"
#: apps/activity/models.py:60 apps/note/models/notes.py:164
#: apps/note/models/transactions.py:66 apps/permission/models.py:156
#: apps/note/models/transactions.py:66 apps/permission/models.py:157
#: templates/activity/activity_detail.html:19
msgid "type"
msgstr "type"
#: apps/activity/models.py:66 apps/logs/models.py:21 apps/member/models.py:259
#: apps/activity/models.py:66 apps/logs/models.py:21 apps/member/models.py:277
#: apps/note/models/notes.py:117 apps/treasury/models.py:221
#: apps/wei/models.py:159 templates/treasury/sogecredit_detail.html:14
#: apps/wei/models.py:157 templates/treasury/sogecredit_detail.html:14
#: templates/wei/survey.html:16
msgid "user"
msgstr "utilisateur"
@ -188,12 +188,12 @@ msgid "Type"
msgstr "Type"
#: apps/activity/tables.py:77 apps/member/forms.py:83
#: apps/registration/forms.py:64 apps/treasury/forms.py:120
#: apps/registration/forms.py:64 apps/treasury/forms.py:121
msgid "Last name"
msgstr "Nom de famille"
#: apps/activity/tables.py:79 apps/member/forms.py:88
#: apps/registration/forms.py:69 apps/treasury/forms.py:122
#: apps/registration/forms.py:69 apps/treasury/forms.py:123
#: templates/note/transaction_form.html:126
msgid "First name"
msgstr "Prénom"
@ -226,7 +226,7 @@ msgstr "Logs"
msgid "IP Address"
msgstr "Adresse IP"
#: apps/logs/models.py:35 apps/permission/models.py:126
#: apps/logs/models.py:35 apps/permission/models.py:127
msgid "model"
msgstr "Modèle"
@ -305,7 +305,7 @@ msgid "Credit amount"
msgstr "Montant à créditer"
#: apps/member/forms.py:93 apps/registration/forms.py:74
#: apps/treasury/forms.py:124 templates/note/transaction_form.html:132
#: apps/treasury/forms.py:125 templates/note/transaction_form.html:132
msgid "Bank"
msgstr "Banque"
@ -485,7 +485,7 @@ msgstr ""
"Combien de temps l'adhésion peut durer après le 1er Janvier de l'année "
"suivante avant que les adhérents peuvent renouveler leur adhésion."
#: apps/member/models.py:240 apps/member/models.py:265
#: apps/member/models.py:240 apps/member/models.py:283
#: apps/note/models/notes.py:139
msgid "club"
msgstr "club"
@ -494,45 +494,44 @@ msgstr "club"
msgid "clubs"
msgstr "clubs"
#: apps/member/models.py:270
#: apps/member/models.py:261 apps/permission/models.py:318
msgid "role"
msgstr "rôle"
#: apps/member/models.py:262 apps/member/models.py:288
msgid "roles"
msgstr "rôles"
#: apps/member/models.py:275
#: apps/member/models.py:293
msgid "membership starts on"
msgstr "l'adhésion commence le"
#: apps/member/models.py:279
#: apps/member/models.py:297
msgid "membership ends on"
msgstr "l'adhésion finit le"
#: apps/member/models.py:284
#: apps/member/models.py:302
msgid "fee"
msgstr "cotisation"
#: apps/member/models.py:303 apps/member/views.py:527 apps/wei/views.py:768
#: apps/member/models.py:320 apps/member/views.py:521 apps/wei/views.py:768
msgid "User is not a member of the parent club"
msgstr "L'utilisateur n'est pas membre du club parent"
#: apps/member/models.py:309
#, python-brace-format
msgid "The role {role} does not apply to the club {club}."
msgstr "Le rôle {role} ne s'applique pas au club {club}."
#: apps/member/models.py:320 apps/member/views.py:536
#: apps/member/models.py:330 apps/member/views.py:530
msgid "User is already a member of the club"
msgstr "L'utilisateur est déjà membre du club"
#: apps/member/models.py:371
#: apps/member/models.py:381
#, python-brace-format
msgid "Membership of {user} for the club {club}"
msgstr "Adhésion de {user} pour le club {club}"
#: apps/member/models.py:374
#: apps/member/models.py:384
msgid "membership"
msgstr "adhésion"
#: apps/member/models.py:375
#: apps/member/models.py:385
msgid "memberships"
msgstr "adhésions"
@ -540,25 +539,25 @@ msgstr "adhésions"
msgid "Renew"
msgstr "Renouveler"
#: apps/member/views.py:64 apps/registration/forms.py:23
#: apps/member/views.py:62 apps/registration/forms.py:23
msgid "This address must be valid."
msgstr "Cette adresse doit être valide."
#: apps/member/views.py:67 templates/member/profile_info.html:47
#: apps/member/views.py:65 templates/member/profile_info.html:47
#: templates/registration/future_profile_detail.html:48
#: templates/wei/weimembership_form.html:124
msgid "Update Profile"
msgstr "Modifier le profil"
#: apps/member/views.py:77
#: apps/member/views.py:75
msgid "An alias with a similar name already exists."
msgstr "Un alias avec un nom similaire existe déjà."
#: apps/member/views.py:183
#: apps/member/views.py:181
msgid "Search user"
msgstr "Chercher un utilisateur"
#: apps/member/views.py:522 apps/wei/views.py:759
#: apps/member/views.py:516 apps/wei/views.py:759
msgid ""
"This user don't have enough money to join this club, and can't have a "
"negative balance."
@ -566,17 +565,17 @@ msgstr ""
"Cet utilisateur n'a pas assez d'argent pour rejoindre ce club et ne peut pas "
"avoir un solde négatif."
#: apps/member/views.py:540
#: apps/member/views.py:534
msgid "The membership must start after {:%m-%d-%Y}."
msgstr "L'adhésion doit commencer après le {:%d/%m/%Y}."
#: apps/member/views.py:545
#: apps/member/views.py:539
msgid "The membership must begin before {:%m-%d-%Y}."
msgstr "L'adhésion doit commencer avant le {:%d/%m/%Y}."
#: apps/member/views.py:562 apps/member/views.py:564 apps/member/views.py:566
#: apps/registration/views.py:290 apps/registration/views.py:292
#: apps/registration/views.py:294
#: apps/member/views.py:556 apps/member/views.py:558 apps/member/views.py:560
#: apps/registration/views.py:289 apps/registration/views.py:291
#: apps/registration/views.py:293
msgid "This field is required."
msgstr "Ce champ est requis."
@ -725,7 +724,7 @@ msgstr "afficher"
#: apps/note/models/transactions.py:77
msgid "highlighted"
msgstr "mis en avant"
msgstr ""
#: apps/note/models/transactions.py:87
msgid "transaction template"
@ -766,8 +765,6 @@ msgid ""
"The transaction can't be saved since the source note or the destination note "
"is not active."
msgstr ""
"La transaction ne peut pas être sauvegardée puisque la note source ou la note "
"de destination n'est pas active."
#: apps/note/models/transactions.py:228
#: templates/activity/activity_entry.html:13 templates/base.html:98
@ -803,8 +800,6 @@ msgid ""
"A special transaction is only possible between a Note associated to a "
"payment method and a User or a Club"
msgstr ""
"Une transaction spéciale n'est possible que entre une note associée à "
"un mode de paiement et un utilisateur ou un club."
#: apps/note/models/transactions.py:305 apps/note/models/transactions.py:310
msgid "membership transaction"
@ -847,41 +842,41 @@ msgstr "Transférer de l'argent"
msgid "Consumptions"
msgstr "Consommations"
#: apps/permission/models.py:81
#: apps/permission/models.py:82
#, python-brace-format
msgid "Can {type} {model}.{field} in {query}"
msgstr "Can {type} {model}.{field} in {query}"
#: apps/permission/models.py:83
#: apps/permission/models.py:84
#, python-brace-format
msgid "Can {type} {model} in {query}"
msgstr "Can {type} {model} in {query}"
#: apps/permission/models.py:96
#: apps/permission/models.py:97
msgid "rank"
msgstr "Rang"
#: apps/permission/models.py:109
#: apps/permission/models.py:110
msgid "permission mask"
msgstr "masque de permissions"
#: apps/permission/models.py:110
#: apps/permission/models.py:111
msgid "permission masks"
msgstr "masques de permissions"
#: apps/permission/models.py:150
#: apps/permission/models.py:151
msgid "query"
msgstr "requête"
#: apps/permission/models.py:163
#: apps/permission/models.py:164
msgid "mask"
msgstr "masque"
#: apps/permission/models.py:169
#: apps/permission/models.py:170
msgid "field"
msgstr "champ"
#: apps/permission/models.py:174
#: apps/permission/models.py:175
msgid ""
"Tells if the permission should be granted even if the membership of the user "
"is expired."
@ -889,29 +884,25 @@ msgstr ""
"Indique si la permission doit être attribuée même si l'adhésion de "
"l'utilisateur est expirée."
#: apps/permission/models.py:175 templates/permission/all_rights.html:26
#: apps/permission/models.py:176 templates/permission/all_rights.html:26
msgid "permanent"
msgstr "permanent"
#: apps/permission/models.py:186
#: apps/permission/models.py:187
msgid "permission"
msgstr "permission"
#: apps/permission/models.py:187 apps/permission/models.py:320
#: apps/permission/models.py:188 apps/permission/models.py:322
msgid "permissions"
msgstr "permissions"
#: apps/permission/models.py:192
#: apps/permission/models.py:193
msgid "Specifying field applies only to view and change permission types."
msgstr ""
"Spécifie le champ concerné, ne fonctionne que pour les permissions view et "
"change."
#: apps/permission/models.py:325
msgid "for club"
msgstr "s'applique au club"
#: apps/permission/models.py:335 apps/permission/models.py:336
#: apps/permission/models.py:329 apps/permission/models.py:330
msgid "role permissions"
msgstr "Permissions par rôles"
@ -942,7 +933,7 @@ msgstr ""
"Vous n'avez pas la permission de supprimer cette instance du modèle "
"{app_label}.{model_name}."
#: apps/permission/views.py:48
#: apps/permission/views.py:47
msgid "All rights"
msgstr "Tous les droits"
@ -971,31 +962,31 @@ msgstr "Adhérer au club BDE"
msgid "Join Kfet Club"
msgstr "Adhérer au club Kfet"
#: apps/registration/views.py:79
#: apps/registration/views.py:78
msgid "Email validation"
msgstr "Validation de l'adresse mail"
#: apps/registration/views.py:125
#: apps/registration/views.py:124
msgid "Email validation unsuccessful"
msgstr " La validation de l'adresse mail a échoué"
#: apps/registration/views.py:136
#: apps/registration/views.py:135
msgid "Email validation email sent"
msgstr "L'email de vérification de l'adresse email a bien été envoyé."
#: apps/registration/views.py:189
#: apps/registration/views.py:188
msgid "Unregistered users"
msgstr "Utilisateurs en attente d'inscription"
#: apps/registration/views.py:256
#: apps/registration/views.py:255
msgid "You must join the BDE."
msgstr "Vous devez adhérer au BDE."
#: apps/registration/views.py:278
#: apps/registration/views.py:277
msgid "You must join BDE club before joining Kfet club."
msgstr "Vous devez adhérer au club BDE avant d'adhérer au club Kfet."
#: apps/registration/views.py:283
#: apps/registration/views.py:282
msgid ""
"The entered amount is not enough for the memberships, should be at least {}"
msgstr ""
@ -1006,7 +997,7 @@ msgstr ""
msgid "Treasury"
msgstr "Trésorerie"
#: apps/treasury/forms.py:84 apps/treasury/forms.py:132
#: apps/treasury/forms.py:85 apps/treasury/forms.py:133
#: templates/activity/activity_form.html:9
#: templates/activity/activity_invite.html:8
#: templates/django_filters/rest_framework/form.html:5
@ -1018,19 +1009,19 @@ msgstr "Trésorerie"
msgid "Submit"
msgstr "Envoyer"
#: apps/treasury/forms.py:86
#: apps/treasury/forms.py:87
msgid "Close"
msgstr "Fermer"
#: apps/treasury/forms.py:95
#: apps/treasury/forms.py:96
msgid "Remittance is already closed."
msgstr "La remise est déjà fermée."
#: apps/treasury/forms.py:100
#: apps/treasury/forms.py:101
msgid "You can't change the type of the remittance."
msgstr "Vous ne pouvez pas changer le type de la remise."
#: apps/treasury/forms.py:126 apps/treasury/tables.py:47
#: apps/treasury/forms.py:127 apps/treasury/tables.py:47
#: apps/treasury/tables.py:113 templates/note/transaction_form.html:95
#: templates/treasury/remittance_form.html:18
msgid "Amount"
@ -1201,13 +1192,13 @@ msgstr "Oui"
msgid "No"
msgstr "Non"
#: apps/wei/apps.py:10 apps/wei/models.py:48 apps/wei/models.py:49
#: apps/wei/models.py:60 apps/wei/models.py:166 templates/base.html:130
#: apps/wei/apps.py:10 apps/wei/models.py:47 apps/wei/models.py:48
#: apps/wei/models.py:59 apps/wei/models.py:164 templates/base.html:130
msgid "WEI"
msgstr "WEI"
#: apps/wei/forms/registration.py:47 apps/wei/models.py:112
#: apps/wei/models.py:275
#: apps/wei/forms/registration.py:47 apps/wei/models.py:111
#: apps/wei/models.py:273
msgid "bus"
msgstr "Bus"
@ -1233,7 +1224,7 @@ msgstr ""
"bus ou électron libre)"
#: apps/wei/forms/registration.py:61 apps/wei/forms/registration.py:67
#: apps/wei/models.py:147
#: apps/wei/models.py:145
msgid "WEI Roles"
msgstr "Rôles au WEI"
@ -1245,97 +1236,97 @@ msgstr "Sélectionnez les rôles qui vous intéressent."
msgid "This team doesn't belong to the given bus."
msgstr "Cette équipe n'appartient pas à ce bus."
#: apps/wei/models.py:23 templates/wei/weiclub_info.html:23
#: apps/wei/models.py:22 templates/wei/weiclub_info.html:23
msgid "year"
msgstr "année"
#: apps/wei/models.py:27 templates/wei/weiclub_info.html:17
#: apps/wei/models.py:26 templates/wei/weiclub_info.html:17
msgid "date start"
msgstr "début"
#: apps/wei/models.py:31 templates/wei/weiclub_info.html:20
#: apps/wei/models.py:30 templates/wei/weiclub_info.html:20
msgid "date end"
msgstr "fin"
#: apps/wei/models.py:76
#: apps/wei/models.py:75
msgid "survey information"
msgstr "informations sur le questionnaire"
#: apps/wei/models.py:77
#: apps/wei/models.py:76
msgid "Information about the survey for new members, encoded in JSON"
msgstr ""
"Informations sur le sondage pour les nouveaux membres, encodées en JSON"
#: apps/wei/models.py:99
#: apps/wei/models.py:98
msgid "Bus"
msgstr "Bus"
#: apps/wei/models.py:100 templates/wei/weiclub_tables.html:79
#: apps/wei/models.py:99 templates/wei/weiclub_tables.html:79
msgid "Buses"
msgstr "Bus"
#: apps/wei/models.py:121
#: apps/wei/models.py:119
msgid "color"
msgstr "couleur"
#: apps/wei/models.py:122
#: apps/wei/models.py:120
msgid "The color of the T-Shirt, stored with its number equivalent"
msgstr ""
"La couleur du T-Shirt, stocké sous la forme de son équivalent numérique"
#: apps/wei/models.py:136
#: apps/wei/models.py:134
msgid "Bus team"
msgstr "Équipe de bus"
#: apps/wei/models.py:137
#: apps/wei/models.py:135
msgid "Bus teams"
msgstr "Équipes de bus"
#: apps/wei/models.py:146
#: apps/wei/models.py:144
msgid "WEI Role"
msgstr "Rôle au WEI"
#: apps/wei/models.py:171
#: apps/wei/models.py:169
msgid "Credit from Société générale"
msgstr "Crédit de la Société générale"
#: apps/wei/models.py:176
#: apps/wei/models.py:174
msgid "Caution check given"
msgstr "Chèque de caution donné"
#: apps/wei/models.py:180 templates/wei/weimembership_form.html:62
#: apps/wei/models.py:178 templates/wei/weimembership_form.html:62
msgid "birth date"
msgstr "date de naissance"
#: apps/wei/models.py:186
#: apps/wei/models.py:184
msgid "Male"
msgstr "Homme"
#: apps/wei/models.py:187
#: apps/wei/models.py:185
msgid "Female"
msgstr "Femme"
#: apps/wei/models.py:188
#: apps/wei/models.py:186
msgid "Non binary"
msgstr "Non-binaire"
#: apps/wei/models.py:190 templates/wei/weimembership_form.html:59
#: apps/wei/models.py:188 templates/wei/weimembership_form.html:59
msgid "gender"
msgstr "genre"
#: apps/wei/models.py:196 templates/wei/weimembership_form.html:65
#: apps/wei/models.py:194 templates/wei/weimembership_form.html:65
msgid "health issues"
msgstr "problèmes de santé"
#: apps/wei/models.py:201 templates/wei/weimembership_form.html:68
#: apps/wei/models.py:199 templates/wei/weimembership_form.html:68
msgid "emergency contact name"
msgstr "Nom du contact en cas d'urgence"
#: apps/wei/models.py:206 templates/wei/weimembership_form.html:71
#: apps/wei/models.py:204 templates/wei/weimembership_form.html:71
msgid "emergency contact phone"
msgstr "Téléphone du contact en cas d'urgence"
#: apps/wei/models.py:211 templates/wei/weimembership_form.html:74
#: apps/wei/models.py:209 templates/wei/weimembership_form.html:74
msgid ""
"Register on the mailing list to stay informed of the events of the campus (1 "
"mail/week)"
@ -1343,7 +1334,7 @@ msgstr ""
"S'inscrire sur la liste de diffusion pour rester informé des événements sur "
"le campus (1 mail par semaine)"
#: apps/wei/models.py:216 templates/wei/weimembership_form.html:77
#: apps/wei/models.py:214 templates/wei/weimembership_form.html:77
msgid ""
"Register on the mailing list to stay informed of the sport events of the "
"campus (1 mail/week)"
@ -1351,7 +1342,7 @@ msgstr ""
"S'inscrire sur la liste de diffusion pour rester informé des actualités "
"sportives sur le campus (1 mail par semaine)"
#: apps/wei/models.py:221 templates/wei/weimembership_form.html:80
#: apps/wei/models.py:219 templates/wei/weimembership_form.html:80
msgid ""
"Register on the mailing list to stay informed of the art events of the "
"campus (1 mail/week)"
@ -1359,19 +1350,19 @@ msgstr ""
"S'inscrire sur la liste de diffusion pour rester informé des actualités "
"artistiques sur le campus (1 mail par semaine)"
#: apps/wei/models.py:226 templates/wei/weimembership_form.html:56
#: apps/wei/models.py:224 templates/wei/weimembership_form.html:56
msgid "first year"
msgstr "première année"
#: apps/wei/models.py:227
#: apps/wei/models.py:225
msgid "Tells if the user is new in the school."
msgstr "Indique si l'utilisateur est nouveau dans l'école."
#: apps/wei/models.py:232
#: apps/wei/models.py:230
msgid "registration information"
msgstr "informations sur l'inscription"
#: apps/wei/models.py:233
#: apps/wei/models.py:231
msgid ""
"Information about the registration (buses for old members, survey fot the "
"new members), encoded in JSON"
@ -1379,27 +1370,27 @@ msgstr ""
"Informations sur l'inscription (bus pour les 2A+, questionnaire pour les "
"1A), encodées en JSON"
#: apps/wei/models.py:264
#: apps/wei/models.py:262
msgid "WEI User"
msgstr "Participant au WEI"
#: apps/wei/models.py:265
#: apps/wei/models.py:263
msgid "WEI Users"
msgstr "Participants au WEI"
#: apps/wei/models.py:285
#: apps/wei/models.py:283
msgid "team"
msgstr "équipe"
#: apps/wei/models.py:295
#: apps/wei/models.py:293
msgid "WEI registration"
msgstr "inscription au WEI"
#: apps/wei/models.py:299
#: apps/wei/models.py:297
msgid "WEI membership"
msgstr "adhésion au WEI"
#: apps/wei/models.py:300
#: apps/wei/models.py:298
msgid "WEI memberships"
msgstr "adhésions au WEI"
@ -1471,15 +1462,15 @@ msgstr "Cet utilisateur n'a pas donné son chèque de caution."
msgid "Survey WEI"
msgstr "Questionnaire WEI"
#: note_kfet/settings/base.py:155
#: note_kfet/settings/base.py:154
msgid "German"
msgstr "Allemand"
#: note_kfet/settings/base.py:156
#: note_kfet/settings/base.py:155
msgid "English"
msgstr "Anglais"
#: note_kfet/settings/base.py:157
#: note_kfet/settings/base.py:156
msgid "French"
msgstr "Français"

View File

@ -25,7 +25,7 @@ DATABASES = {
}
# Break it, fix it!
DEBUG = False
DEBUG = True
# Mandatory !
ALLOWED_HOSTS = [os.environ.get('NOTE_URL', 'localhost')]
@ -36,7 +36,7 @@ SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'CHANGE_ME_IN_ENV_SETTINGS')
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_SSL = False
EMAIL_HOST = os.getenv('EMAIL_HOST', 'smtp.example.org')
EMAIL_PORT = os.getenv('EMAIL_PORT', 465)
EMAIL_PORT = os.getenv('EMAIL_PORT', 443)
EMAIL_HOST_USER = os.getenv('EMAIL_USER', 'change_me')
EMAIL_HOST_PASSWORD = os.getenv('EMAIL_PASSWORD', 'change_me')

View File

@ -1 +1 @@
django-cas-server==1.2.0
django-cas-server==1.1.0

View File

@ -15,14 +15,14 @@
{% regroup active_memberships by roles as memberships_per_role %}
{% for role in roles %}
<li class="{% if not role.clubs %}no-club{% endif %}">
{{ role }} {% if role.weirole %}(<em>Pour le WEI</em>){% endif %} {% if role.for_club %}(<em>Pour le club {{ role.for_club }} uniquement</em>){% endif %}
{{ role }} {% if role.weirole %}(<em>Pour le WEI</em>){% endif %}
{% if role.clubs %}
<div class="alert alert-success">
{% trans "Own this role in the clubs" %} {{ role.clubs|join:", " }}
</div>
{% endif %}
<ul>
{% for permission in role.permissions.all %}
{% for permission in role.permissions.permissions.all %}
<li data-toggle="tooltip" title="{% trans "Query:" %} {{ permission.query }}">{{ permission }} ({{ permission.type }} {{ permission.model }}{% if permission.permanent %}, {% trans "permanent" %}{% endif %})</li>
{% empty %}
<em>{% trans "No associated permission" %}</em>

View File

@ -5,7 +5,6 @@
\usepackage[french]{babel}
\usepackage[margin=1.5cm]{geometry}
\usepackage{lmodern}
\usepackage{ltablex}
\usepackage{tabularx}