diff --git a/apps/activity/__init__.py b/apps/activity/__init__.py
index efee9563..713ba510 100644
--- a/apps/activity/__init__.py
+++ b/apps/activity/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
default_app_config = 'activity.apps.ActivityConfig'
diff --git a/apps/activity/admin.py b/apps/activity/admin.py
index d8fb6106..88496361 100644
--- a/apps/activity/admin.py
+++ b/apps/activity/admin.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib import admin
diff --git a/apps/activity/api/serializers.py b/apps/activity/api/serializers.py
index 5f0da651..e4bc50b8 100644
--- a/apps/activity/api/serializers.py
+++ b/apps/activity/api/serializers.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from rest_framework import serializers
diff --git a/apps/activity/api/urls.py b/apps/activity/api/urls.py
index 6680201f..5906705b 100644
--- a/apps/activity/api/urls.py
+++ b/apps/activity/api/urls.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from .views import ActivityTypeViewSet, ActivityViewSet, EntryViewSet, GuestViewSet
diff --git a/apps/activity/api/views.py b/apps/activity/api/views.py
index ae9347c7..97e6c40d 100644
--- a/apps/activity/api/views.py
+++ b/apps/activity/api/views.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from api.viewsets import ReadProtectedModelViewSet
diff --git a/apps/activity/apps.py b/apps/activity/apps.py
index e1f7ba70..f3ee3936 100644
--- a/apps/activity/apps.py
+++ b/apps/activity/apps.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.apps import AppConfig
diff --git a/apps/activity/forms.py b/apps/activity/forms.py
index 1ca98cef..6e1c35ff 100644
--- a/apps/activity/forms.py
+++ b/apps/activity/forms.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from datetime import timedelta
diff --git a/apps/activity/migrations/0003_auto_20240323_1422.py b/apps/activity/migrations/0003_auto_20240323_1422.py
new file mode 100644
index 00000000..86f92c21
--- /dev/null
+++ b/apps/activity/migrations/0003_auto_20240323_1422.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2.28 on 2024-03-23 13:22
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('activity', '0002_auto_20200904_2341'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='activity',
+ name='description',
+ field=models.TextField(blank=True, default='', verbose_name='description'),
+ ),
+ ]
diff --git a/apps/activity/models.py b/apps/activity/models.py
index f8e5fab9..88cce457 100644
--- a/apps/activity/models.py
+++ b/apps/activity/models.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import os
@@ -66,6 +66,8 @@ class Activity(models.Model):
description = models.TextField(
verbose_name=_('description'),
+ blank=True,
+ default="",
)
location = models.CharField(
@@ -123,6 +125,14 @@ class Activity(models.Model):
verbose_name=_('open'),
)
+ class Meta:
+ verbose_name = _("activity")
+ verbose_name_plural = _("activities")
+ unique_together = ("name", "date_start", "date_end",)
+
+ def __str__(self):
+ return self.name
+
@transaction.atomic
def save(self, *args, **kwargs):
"""
@@ -144,14 +154,6 @@ class Activity(models.Model):
if settings.DATABASES["default"]["ENGINE"] == 'django.db.backends.postgresql' else refresh_activities()
return ret
- def __str__(self):
- return self.name
-
- class Meta:
- verbose_name = _("activity")
- verbose_name_plural = _("activities")
- unique_together = ("name", "date_start", "date_end",)
-
class Entry(models.Model):
"""
@@ -252,14 +254,13 @@ class Guest(models.Model):
verbose_name=_("inviter"),
)
- @property
- def has_entry(self):
- try:
- if self.entry:
- return True
- return False
- except AttributeError:
- return False
+ class Meta:
+ verbose_name = _("guest")
+ verbose_name_plural = _("guests")
+ unique_together = ("activity", "last_name", "first_name", )
+
+ def __str__(self):
+ return self.first_name + " " + self.last_name
@transaction.atomic
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
@@ -290,13 +291,14 @@ class Guest(models.Model):
return super().save(force_insert, force_update, using, update_fields)
- def __str__(self):
- return self.first_name + " " + self.last_name
-
- class Meta:
- verbose_name = _("guest")
- verbose_name_plural = _("guests")
- unique_together = ("activity", "last_name", "first_name", )
+ @property
+ def has_entry(self):
+ try:
+ if self.entry:
+ return True
+ return False
+ except AttributeError:
+ return False
class GuestTransaction(Transaction):
diff --git a/apps/activity/templates/activity/activity_form.html b/apps/activity/templates/activity/activity_form.html
index c472d3cb..757b47b0 100644
--- a/apps/activity/templates/activity/activity_form.html
+++ b/apps/activity/templates/activity/activity_form.html
@@ -17,4 +17,24 @@ SPDX-License-Identifier: GPL-3.0-or-later
-{% endblock %}
\ No newline at end of file
+
+{% endblock %}
diff --git a/apps/activity/tests/test_activities.py b/apps/activity/tests/test_activities.py
index 1fcc7769..379f5d1b 100644
--- a/apps/activity/tests/test_activities.py
+++ b/apps/activity/tests/test_activities.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from datetime import timedelta
diff --git a/apps/activity/urls.py b/apps/activity/urls.py
index 73e4a385..3578c340 100644
--- a/apps/activity/urls.py
+++ b/apps/activity/urls.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.urls import path
diff --git a/apps/activity/views.py b/apps/activity/views.py
index bfd344ef..d55e0534 100644
--- a/apps/activity/views.py
+++ b/apps/activity/views.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from hashlib import md5
@@ -76,6 +76,7 @@ class ActivityListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView
context['upcoming'] = ActivityTable(
data=upcoming_activities.filter(PermissionBackend.filter_queryset(self.request, Activity, "view")),
prefix='upcoming-',
+ order_by='date_start',
)
started_activities = self.get_queryset().filter(open=True, valid=True).distinct().all()
diff --git a/apps/api/__init__.py b/apps/api/__init__.py
index bfa0f07d..2e6addb0 100644
--- a/apps/api/__init__.py
+++ b/apps/api/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
default_app_config = 'api.apps.APIConfig'
diff --git a/apps/api/apps.py b/apps/api/apps.py
index ebce358c..46fa6979 100644
--- a/apps/api/apps.py
+++ b/apps/api/apps.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.apps import AppConfig
diff --git a/apps/api/serializers.py b/apps/api/serializers.py
index 0bae937f..74a95775 100644
--- a/apps/api/serializers.py
+++ b/apps/api/serializers.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/apps/api/tests.py b/apps/api/tests.py
index 36de0658..285acc46 100644
--- a/apps/api/tests.py
+++ b/apps/api/tests.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import json
diff --git a/apps/api/urls.py b/apps/api/urls.py
index 5d8b8b98..7c73093b 100644
--- a/apps/api/urls.py
+++ b/apps/api/urls.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
diff --git a/apps/api/views.py b/apps/api/views.py
index 9718336d..43ef3f78 100644
--- a/apps/api/views.py
+++ b/apps/api/views.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib.auth.models import User
diff --git a/apps/api/viewsets.py b/apps/api/viewsets.py
index faeadee1..35dad92d 100644
--- a/apps/api/viewsets.py
+++ b/apps/api/viewsets.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib.contenttypes.models import ContentType
diff --git a/apps/logs/__init__.py b/apps/logs/__init__.py
index 708d35df..5271d575 100644
--- a/apps/logs/__init__.py
+++ b/apps/logs/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
default_app_config = 'logs.apps.LogsConfig'
diff --git a/apps/logs/api/serializers.py b/apps/logs/api/serializers.py
index f861bd21..cca94155 100644
--- a/apps/logs/api/serializers.py
+++ b/apps/logs/api/serializers.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from rest_framework import serializers
diff --git a/apps/logs/api/urls.py b/apps/logs/api/urls.py
index d0044c9b..9f255dd5 100644
--- a/apps/logs/api/urls.py
+++ b/apps/logs/api/urls.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from .views import ChangelogViewSet
diff --git a/apps/logs/api/views.py b/apps/logs/api/views.py
index eab1f1e4..655a473a 100644
--- a/apps/logs/api/views.py
+++ b/apps/logs/api/views.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django_filters.rest_framework import DjangoFilterBackend
diff --git a/apps/logs/apps.py b/apps/logs/apps.py
index bdf52d5e..366981ec 100644
--- a/apps/logs/apps.py
+++ b/apps/logs/apps.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.apps import AppConfig
diff --git a/apps/logs/models.py b/apps/logs/models.py
index 65a23486..8f2c2eda 100644
--- a/apps/logs/models.py
+++ b/apps/logs/models.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
@@ -76,9 +76,6 @@ class Changelog(models.Model):
verbose_name=_('timestamp'),
)
- def delete(self, using=None, keep_parents=False):
- raise ValidationError(_("Logs cannot be destroyed."))
-
class Meta:
verbose_name = _("changelog")
verbose_name_plural = _("changelogs")
@@ -86,3 +83,6 @@ class Changelog(models.Model):
def __str__(self):
return _("Changelog of type \"{action}\" for model {model} at {timestamp}").format(
action=self.get_action_display(), model=str(self.model), timestamp=str(self.timestamp))
+
+ def delete(self, using=None, keep_parents=False):
+ raise ValidationError(_("Logs cannot be destroyed."))
diff --git a/apps/logs/signals.py b/apps/logs/signals.py
index a3166eed..c331e89e 100644
--- a/apps/logs/signals.py
+++ b/apps/logs/signals.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib.contenttypes.models import ContentType
diff --git a/apps/member/__init__.py b/apps/member/__init__.py
index ae68f6ce..d0ab8586 100644
--- a/apps/member/__init__.py
+++ b/apps/member/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
default_app_config = 'member.apps.MemberConfig'
diff --git a/apps/member/admin.py b/apps/member/admin.py
index b3352c1a..3adc54ed 100644
--- a/apps/member/admin.py
+++ b/apps/member/admin.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib import admin
diff --git a/apps/member/api/serializers.py b/apps/member/api/serializers.py
index ef1c586d..31bb1655 100644
--- a/apps/member/api/serializers.py
+++ b/apps/member/api/serializers.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from rest_framework import serializers
diff --git a/apps/member/api/urls.py b/apps/member/api/urls.py
index c55b0969..6f323186 100644
--- a/apps/member/api/urls.py
+++ b/apps/member/api/urls.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from .views import ProfileViewSet, ClubViewSet, MembershipViewSet
diff --git a/apps/member/api/views.py b/apps/member/api/views.py
index 43127507..ab6146ed 100644
--- a/apps/member/api/views.py
+++ b/apps/member/api/views.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django_filters.rest_framework import DjangoFilterBackend
diff --git a/apps/member/apps.py b/apps/member/apps.py
index 1090c072..840c8783 100644
--- a/apps/member/apps.py
+++ b/apps/member/apps.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.apps import AppConfig
diff --git a/apps/member/auth.py b/apps/member/auth.py
index 888adea1..06e48afa 100644
--- a/apps/member/auth.py
+++ b/apps/member/auth.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from cas_server.auth import DjangoAuthUser # pragma: no cover
diff --git a/apps/member/forms.py b/apps/member/forms.py
index 527816cb..3d892705 100644
--- a/apps/member/forms.py
+++ b/apps/member/forms.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import io
@@ -121,7 +121,7 @@ class ImageForm(forms.Form):
frame = frame.crop((x, y, x + w, y + h))
frame = frame.resize(
(settings.PIC_WIDTH, settings.PIC_RATIO * settings.PIC_WIDTH),
- Image.ANTIALIAS,
+ Image.LANCZOS,
)
frames.append(frame)
diff --git a/apps/member/hashers.py b/apps/member/hashers.py
index 32f8c63e..659aab39 100644
--- a/apps/member/hashers.py
+++ b/apps/member/hashers.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import hashlib
diff --git a/apps/member/models.py b/apps/member/models.py
index 5e0da5bc..a18b18f0 100644
--- a/apps/member/models.py
+++ b/apps/member/models.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import datetime
@@ -28,7 +28,6 @@ class Profile(models.Model):
We do not want to patch the Django Contrib :model:`auth.User`model;
so this model add an user profile with additional information.
"""
-
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
@@ -139,6 +138,17 @@ class Profile(models.Model):
default=False
)
+ class Meta:
+ verbose_name = _('user profile')
+ verbose_name_plural = _('user profile')
+ indexes = [models.Index(fields=['user'])]
+
+ def __str__(self):
+ return str(self.user)
+
+ def get_absolute_url(self):
+ return reverse('member:user_detail', args=(self.user_id,))
+
@property
def ens_year(self):
"""
@@ -163,17 +173,6 @@ class Profile(models.Model):
return SogeCredit.objects.filter(user=self.user, credit_transaction__isnull=False).exists()
return False
- class Meta:
- verbose_name = _('user profile')
- verbose_name_plural = _('user profile')
- indexes = [models.Index(fields=['user'])]
-
- def get_absolute_url(self):
- return reverse('member:user_detail', args=(self.user_id,))
-
- def __str__(self):
- return str(self.user)
-
def send_email_validation_link(self):
subject = "[Note Kfet] " + str(_("Activate your Note Kfet account"))
token = email_validation_token.make_token(self.user)
@@ -205,9 +204,11 @@ class Club(models.Model):
max_length=255,
unique=True,
)
+
email = models.EmailField(
verbose_name=_('email'),
)
+
parent_club = models.ForeignKey(
'self',
null=True,
@@ -258,6 +259,27 @@ class Club(models.Model):
help_text=_('Maximal date of a membership, after which members must renew it.'),
)
+ class Meta:
+ verbose_name = _("club")
+ verbose_name_plural = _("clubs")
+
+ def __str__(self):
+ return self.name
+
+ @transaction.atomic
+ def save(self, force_insert=False, force_update=False, using=None,
+ update_fields=None):
+ if not self.require_memberships:
+ self.membership_fee_paid = 0
+ self.membership_fee_unpaid = 0
+ self.membership_duration = None
+ self.membership_start = None
+ self.membership_end = None
+ super().save(force_insert, force_update, update_fields)
+
+ def get_absolute_url(self):
+ return reverse_lazy('member:club_detail', args=(self.pk,))
+
def update_membership_dates(self):
"""
This function is called each time the club detail view is displayed.
@@ -278,27 +300,6 @@ class Club(models.Model):
self._force_save = True
self.save(force_update=True)
- @transaction.atomic
- def save(self, force_insert=False, force_update=False, using=None,
- update_fields=None):
- if not self.require_memberships:
- self.membership_fee_paid = 0
- self.membership_fee_unpaid = 0
- self.membership_duration = None
- self.membership_start = None
- self.membership_end = None
- super().save(force_insert, force_update, update_fields)
-
- class Meta:
- verbose_name = _("club")
- verbose_name_plural = _("clubs")
-
- def __str__(self):
- return self.name
-
- def get_absolute_url(self):
- return reverse_lazy('member:club_detail', args=(self.pk,))
-
class Membership(models.Model):
"""
@@ -338,6 +339,66 @@ class Membership(models.Model):
verbose_name=_('fee'),
)
+ class Meta:
+ verbose_name = _('membership')
+ verbose_name_plural = _('memberships')
+ indexes = [models.Index(fields=['user'])]
+
+ def __str__(self):
+ return _("Membership of {user} for the club {club}").format(user=self.user.username, club=self.club.name, )
+
+ @transaction.atomic
+ def save(self, *args, **kwargs):
+ """
+ Calculate fee and end date before saving the membership and creating the transaction if needed.
+ """
+ # Ensure that club membership dates are valid
+ old_membership_start = self.club.membership_start
+ self.club.update_membership_dates()
+ if self.club.membership_start != old_membership_start:
+ self.club.save()
+
+ created = not self.pk
+ if not created:
+ 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))
+ else:
+ if Membership.objects.filter(
+ user=self.user,
+ club=self.club,
+ date_start__lte=self.date_start,
+ date_end__gte=self.date_start,
+ ).exists():
+ raise ValidationError(_('User is already a member of the club'))
+
+ if self.club.parent_club is not None:
+ # Check that the user is already a member of the parent club if the membership is created
+ if not Membership.objects.filter(
+ user=self.user,
+ club=self.club.parent_club,
+ date_start__gte=self.club.parent_club.membership_start,
+ ).exists():
+ if hasattr(self, '_force_renew_parent') and self._force_renew_parent:
+ self.renew_parent()
+ else:
+ raise ValidationError(_('User is not a member of the parent club')
+ + ' ' + self.club.parent_club.name)
+
+ self.fee = self.club.membership_fee_paid if self.user.profile.paid else self.club.membership_fee_unpaid
+
+ self.date_end = self.date_start + datetime.timedelta(days=self.club.membership_duration) \
+ if self.club.membership_duration is not None else self.date_start + datetime.timedelta(days=424242)
+ if self.club.membership_end is not None and self.date_end > self.club.membership_end:
+ self.date_end = self.club.membership_end
+
+ super().save(*args, **kwargs)
+
+ self.make_transaction()
+
@property
def valid(self):
"""
@@ -415,58 +476,6 @@ class Membership(models.Model):
parent_membership.roles.set(Role.objects.filter(name="Membre de club").all())
parent_membership.save()
- @transaction.atomic
- def save(self, *args, **kwargs):
- """
- Calculate fee and end date before saving the membership and creating the transaction if needed.
- """
- # Ensure that club membership dates are valid
- old_membership_start = self.club.membership_start
- self.club.update_membership_dates()
- if self.club.membership_start != old_membership_start:
- self.club.save()
-
- created = not self.pk
- if not created:
- 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))
- else:
- if Membership.objects.filter(
- user=self.user,
- club=self.club,
- date_start__lte=self.date_start,
- date_end__gte=self.date_start,
- ).exists():
- raise ValidationError(_('User is already a member of the club'))
-
- if self.club.parent_club is not None:
- # Check that the user is already a member of the parent club if the membership is created
- if not Membership.objects.filter(
- user=self.user,
- club=self.club.parent_club,
- date_start__gte=self.club.parent_club.membership_start,
- ).exists():
- if hasattr(self, '_force_renew_parent') and self._force_renew_parent:
- self.renew_parent()
- else:
- raise ValidationError(_('User is not a member of the parent club')
- + ' ' + self.club.parent_club.name)
-
- self.fee = self.club.membership_fee_paid if self.user.profile.paid else self.club.membership_fee_unpaid
-
- self.date_end = self.date_start + datetime.timedelta(days=self.club.membership_duration) \
- if self.club.membership_duration is not None else self.date_start + datetime.timedelta(days=424242)
- if self.club.membership_end is not None and self.date_end > self.club.membership_end:
- self.date_end = self.club.membership_end
-
- super().save(*args, **kwargs)
-
- self.make_transaction()
-
def make_transaction(self):
"""
Create Membership transaction associated to this membership.
@@ -504,11 +513,3 @@ class Membership(models.Model):
soge_credit.save()
else:
transaction.save(force_insert=True)
-
- def __str__(self):
- return _("Membership of {user} for the club {club}").format(user=self.user.username, club=self.club.name, )
-
- class Meta:
- verbose_name = _('membership')
- verbose_name_plural = _('memberships')
- indexes = [models.Index(fields=['user'])]
diff --git a/apps/member/signals.py b/apps/member/signals.py
index 197c6413..94dd4021 100644
--- a/apps/member/signals.py
+++ b/apps/member/signals.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/apps/member/tables.py b/apps/member/tables.py
index 7f7e54fd..46be76e7 100644
--- a/apps/member/tables.py
+++ b/apps/member/tables.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from datetime import date
diff --git a/apps/member/templatetags/memberinfo.py b/apps/member/templatetags/memberinfo.py
index f528677e..c9b3b60c 100644
--- a/apps/member/templatetags/memberinfo.py
+++ b/apps/member/templatetags/memberinfo.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from datetime import date
diff --git a/apps/member/urls.py b/apps/member/urls.py
index 54b0f91d..51d506ab 100644
--- a/apps/member/urls.py
+++ b/apps/member/urls.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.urls import path
diff --git a/apps/member/views.py b/apps/member/views.py
index 066a7ef3..7c72d3d4 100644
--- a/apps/member/views.py
+++ b/apps/member/views.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from datetime import timedelta, date
diff --git a/apps/note/__init__.py b/apps/note/__init__.py
index d3b96f09..828d8ed2 100644
--- a/apps/note/__init__.py
+++ b/apps/note/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
default_app_config = 'note.apps.NoteConfig'
diff --git a/apps/note/admin.py b/apps/note/admin.py
index 8d081d90..9bd8add1 100644
--- a/apps/note/admin.py
+++ b/apps/note/admin.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib import admin
diff --git a/apps/note/api/serializers.py b/apps/note/api/serializers.py
index a374fc33..980d992d 100644
--- a/apps/note/api/serializers.py
+++ b/apps/note/api/serializers.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
diff --git a/apps/note/api/urls.py b/apps/note/api/urls.py
index d15e8241..0522ebea 100644
--- a/apps/note/api/urls.py
+++ b/apps/note/api/urls.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from .views import NotePolymorphicViewSet, AliasViewSet, ConsumerViewSet, \
diff --git a/apps/note/api/views.py b/apps/note/api/views.py
index 34ffaf2d..39b9b270 100644
--- a/apps/note/api/views.py
+++ b/apps/note/api/views.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import re
diff --git a/apps/note/apps.py b/apps/note/apps.py
index 435fedf8..3d9c8583 100644
--- a/apps/note/apps.py
+++ b/apps/note/apps.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.apps import AppConfig
diff --git a/apps/note/forms.py b/apps/note/forms.py
index 791abb51..209b49d9 100644
--- a/apps/note/forms.py
+++ b/apps/note/forms.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from datetime import datetime
diff --git a/apps/note/models/__init__.py b/apps/note/models/__init__.py
index ab5d4ff1..4beb8112 100644
--- a/apps/note/models/__init__.py
+++ b/apps/note/models/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from .notes import Alias, Note, NoteClub, NoteSpecial, NoteUser, Trust
diff --git a/apps/note/models/notes.py b/apps/note/models/notes.py
index 6db9e5f8..a1697fd9 100644
--- a/apps/note/models/notes.py
+++ b/apps/note/models/notes.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import unicodedata
@@ -293,6 +293,11 @@ class Alias(models.Model):
def __str__(self):
return self.name
+ @transaction.atomic
+ def save(self, *args, **kwargs):
+ self.clean()
+ super().save(*args, **kwargs)
+
@staticmethod
def normalize(string):
"""
@@ -321,11 +326,6 @@ class Alias(models.Model):
pass
self.normalized_name = normalized_name
- @transaction.atomic
- def save(self, *args, **kwargs):
- self.clean()
- super().save(*args, **kwargs)
-
def delete(self, using=None, keep_parents=False):
if self.name == str(self.note):
raise ValidationError(_("You can't delete your main alias."),
diff --git a/apps/note/models/transactions.py b/apps/note/models/transactions.py
index 8ec7bf0a..0fc299b0 100644
--- a/apps/note/models/transactions.py
+++ b/apps/note/models/transactions.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.core.exceptions import ValidationError
@@ -59,6 +59,7 @@ class TransactionTemplate(models.Model):
amount = models.PositiveIntegerField(
verbose_name=_('amount'),
)
+
category = models.ForeignKey(
TemplateCategory,
on_delete=models.PROTECT,
@@ -87,12 +88,12 @@ class TransactionTemplate(models.Model):
verbose_name = _("transaction template")
verbose_name_plural = _("transaction templates")
- def get_absolute_url(self):
- return reverse('note:template_update', args=(self.pk,))
-
def __str__(self):
return self.name
+ def get_absolute_url(self):
+ return reverse('note:template_update', args=(self.pk,))
+
class Transaction(PolymorphicModel):
"""
@@ -101,7 +102,6 @@ class Transaction(PolymorphicModel):
amount is store in centimes of currency, making it a positive integer
value. (from someone to someone else)
"""
-
source = models.ForeignKey(
Note,
on_delete=models.PROTECT,
@@ -166,6 +166,50 @@ class Transaction(PolymorphicModel):
models.Index(fields=['destination']),
]
+ def __str__(self):
+ return self.__class__.__name__ + " from " + str(self.source) + " to " + str(self.destination) + " of "\
+ + pretty_money(self.quantity * self.amount) + ("" if self.valid else " invalid")
+
+ @transaction.atomic
+ def save(self, *args, **kwargs):
+ """
+ When saving, also transfer money between two notes
+ """
+ if self.source.pk == self.destination.pk:
+ # When source == destination, no money is transferred and no transaction is created
+ return
+
+ self.source = Note.objects.select_for_update().get(pk=self.source_id)
+ self.destination = Note.objects.select_for_update().get(pk=self.destination_id)
+
+ # Check that the amounts stay between big integer bounds
+ diff_source, diff_dest = self.validate()
+
+ if not (hasattr(self, '_force_save') and self._force_save) \
+ and (not self.source.is_active or not self.destination.is_active):
+ raise ValidationError(_("The transaction can't be saved since the source note "
+ "or the destination note is not active."))
+
+ # If the aliases are not entered, we assume that the used alias is the name of the note
+ if not self.source_alias:
+ self.source_alias = str(self.source)
+
+ if not self.destination_alias:
+ self.destination_alias = str(self.destination)
+
+ # We save first the transaction, in case of the user has no right to transfer money
+ super().save(*args, **kwargs)
+
+ # Save notes
+ self.source.refresh_from_db()
+ self.source.balance += diff_source
+ self.source._force_save = True
+ self.source.save()
+ self.destination.refresh_from_db()
+ self.destination.balance += diff_dest
+ self.destination._force_save = True
+ self.destination.save()
+
def validate(self):
previous_source_balance = self.source.balance
previous_dest_balance = self.destination.balance
@@ -208,46 +252,6 @@ class Transaction(PolymorphicModel):
return source_balance - previous_source_balance, dest_balance - previous_dest_balance
- @transaction.atomic
- def save(self, *args, **kwargs):
- """
- When saving, also transfer money between two notes
- """
- if self.source.pk == self.destination.pk:
- # When source == destination, no money is transferred and no transaction is created
- return
-
- self.source = Note.objects.select_for_update().get(pk=self.source_id)
- self.destination = Note.objects.select_for_update().get(pk=self.destination_id)
-
- # Check that the amounts stay between big integer bounds
- diff_source, diff_dest = self.validate()
-
- if not (hasattr(self, '_force_save') and self._force_save) \
- and (not self.source.is_active or not self.destination.is_active):
- raise ValidationError(_("The transaction can't be saved since the source note "
- "or the destination note is not active."))
-
- # If the aliases are not entered, we assume that the used alias is the name of the note
- if not self.source_alias:
- self.source_alias = str(self.source)
-
- if not self.destination_alias:
- self.destination_alias = str(self.destination)
-
- # We save first the transaction, in case of the user has no right to transfer money
- super().save(*args, **kwargs)
-
- # Save notes
- self.source.refresh_from_db()
- self.source.balance += diff_source
- self.source._force_save = True
- self.source.save()
- self.destination.refresh_from_db()
- self.destination.balance += diff_dest
- self.destination._force_save = True
- self.destination.save()
-
@property
def total(self):
return self.amount * self.quantity
@@ -256,46 +260,40 @@ class Transaction(PolymorphicModel):
def type(self):
return _('Transfer')
- def __str__(self):
- return self.__class__.__name__ + " from " + str(self.source) + " to " + str(self.destination) + " of "\
- + pretty_money(self.quantity * self.amount) + ("" if self.valid else " invalid")
-
class RecurrentTransaction(Transaction):
"""
Special type of :model:`note.Transaction` associated to a :model:`note.TransactionTemplate`.
"""
-
template = models.ForeignKey(
TransactionTemplate,
on_delete=models.PROTECT,
)
+ class Meta:
+ verbose_name = _("recurrent transaction")
+ verbose_name_plural = _("recurrent transactions")
+
+ @transaction.atomic
+ def save(self, *args, **kwargs):
+ self.clean()
+ return super().save(*args, **kwargs)
+
def clean(self):
if self.template.destination != self.destination and not (hasattr(self, '_force_save') and self._force_save):
raise ValidationError(
_("The destination of this transaction must equal to the destination of the template."))
return super().clean()
- @transaction.atomic
- def save(self, *args, **kwargs):
- self.clean()
- return super().save(*args, **kwargs)
-
@property
def type(self):
return _('Template')
- class Meta:
- verbose_name = _("recurrent transaction")
- verbose_name_plural = _("recurrent transactions")
-
class SpecialTransaction(Transaction):
"""
Special type of :model:`note.Transaction` associated to transactions with special notes
"""
-
last_name = models.CharField(
max_length=255,
verbose_name=_("name"),
@@ -312,6 +310,15 @@ class SpecialTransaction(Transaction):
blank=True,
)
+ class Meta:
+ verbose_name = _("Special transaction")
+ verbose_name_plural = _("Special transactions")
+
+ @transaction.atomic
+ def save(self, *args, **kwargs):
+ self.clean()
+ super().save(*args, **kwargs)
+
@property
def type(self):
return _('Credit') if isinstance(self.source, NoteSpecial) else _("Debit")
@@ -328,11 +335,6 @@ class SpecialTransaction(Transaction):
raise ValidationError(_("A special transaction is only possible between a"
" Note associated to a payment method and a User or a Club"))
- @transaction.atomic
- def save(self, *args, **kwargs):
- self.clean()
- super().save(*args, **kwargs)
-
@staticmethod
def validate_payment_form(form):
"""
@@ -363,17 +365,11 @@ class SpecialTransaction(Transaction):
return not error
- class Meta:
- verbose_name = _("Special transaction")
- verbose_name_plural = _("Special transactions")
-
class MembershipTransaction(Transaction):
"""
Special type of :model:`note.Transaction` associated to a :model:`member.Membership`.
-
"""
-
membership = models.OneToOneField(
'member.Membership',
on_delete=models.PROTECT,
diff --git a/apps/note/signals.py b/apps/note/signals.py
index 1ef51476..6ca702b9 100644
--- a/apps/note/signals.py
+++ b/apps/note/signals.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.utils import timezone
diff --git a/apps/note/static/note/js/consos.js b/apps/note/static/note/js/consos.js
index 9ee543f7..4f096207 100644
--- a/apps/note/static/note/js/consos.js
+++ b/apps/note/static/note/js/consos.js
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+// Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
// SPDX-License-Identifier: GPL-3.0-or-later
// When a transaction is performed, lock the interface to prevent spam clicks.
diff --git a/apps/note/tables.py b/apps/note/tables.py
index 243a8da6..3ca2d1d4 100644
--- a/apps/note/tables.py
+++ b/apps/note/tables.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import html
diff --git a/apps/note/templates/note/mails/negative_balance.txt b/apps/note/templates/note/mails/negative_balance.txt
index 0052995a..8707bde5 100644
--- a/apps/note/templates/note/mails/negative_balance.txt
+++ b/apps/note/templates/note/mails/negative_balance.txt
@@ -9,7 +9,7 @@ Ce mail t'a été envoyé parce que le solde de ta Note Kfet
Ton solde actuel est de {{ note.balance|pretty_money }}.
-Par ailleurs, le BDE ne sert pas d'alcool aux adhérents dont le solde
+Par ailleurs, le BDE ne sert pas d'alcool aux adhérent·e·s dont le solde
est inférieur à 0 € depuis plus de 24h.
Si tu ne comprends pas ton solde, tu peux consulter ton historique
diff --git a/apps/note/templatetags/getenv.py b/apps/note/templatetags/getenv.py
index c00343d4..3d97b6e9 100644
--- a/apps/note/templatetags/getenv.py
+++ b/apps/note/templatetags/getenv.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django import template
diff --git a/apps/note/templatetags/pretty_money.py b/apps/note/templatetags/pretty_money.py
index dcd58188..2bf838df 100644
--- a/apps/note/templatetags/pretty_money.py
+++ b/apps/note/templatetags/pretty_money.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django import template
diff --git a/apps/note/tests/test_transactions.py b/apps/note/tests/test_transactions.py
index 4f5dd6c5..a11a1962 100644
--- a/apps/note/tests/test_transactions.py
+++ b/apps/note/tests/test_transactions.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from api.tests import TestAPI
diff --git a/apps/note/urls.py b/apps/note/urls.py
index 29ee38c6..f3d50845 100644
--- a/apps/note/urls.py
+++ b/apps/note/urls.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.urls import path
diff --git a/apps/note/views.py b/apps/note/views.py
index 0cdfe370..a84e3636 100644
--- a/apps/note/views.py
+++ b/apps/note/views.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import json
diff --git a/apps/permission/__init__.py b/apps/permission/__init__.py
index 201d8131..de866996 100644
--- a/apps/permission/__init__.py
+++ b/apps/permission/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
default_app_config = 'permission.apps.PermissionConfig'
diff --git a/apps/permission/admin.py b/apps/permission/admin.py
index d5ef8b4f..a6fc713c 100644
--- a/apps/permission/admin.py
+++ b/apps/permission/admin.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-lateré
from django.contrib import admin
diff --git a/apps/permission/api/serializers.py b/apps/permission/api/serializers.py
index 4e98364e..c1426a15 100644
--- a/apps/permission/api/serializers.py
+++ b/apps/permission/api/serializers.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from rest_framework import serializers
diff --git a/apps/permission/api/urls.py b/apps/permission/api/urls.py
index 30651936..fece3d7a 100644
--- a/apps/permission/api/urls.py
+++ b/apps/permission/api/urls.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from .views import PermissionViewSet, RoleViewSet
diff --git a/apps/permission/api/views.py b/apps/permission/api/views.py
index 2db14e00..5296e29b 100644
--- a/apps/permission/api/views.py
+++ b/apps/permission/api/views.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from api.viewsets import ReadOnlyProtectedModelViewSet
diff --git a/apps/permission/apps.py b/apps/permission/apps.py
index 58c30082..1531479c 100644
--- a/apps/permission/apps.py
+++ b/apps/permission/apps.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.apps import AppConfig
diff --git a/apps/permission/backends.py b/apps/permission/backends.py
index 4d7ffbf1..f64fd461 100644
--- a/apps/permission/backends.py
+++ b/apps/permission/backends.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from datetime import date
diff --git a/apps/permission/decorators.py b/apps/permission/decorators.py
index 0e79df90..da36b7dc 100644
--- a/apps/permission/decorators.py
+++ b/apps/permission/decorators.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import sys
from functools import lru_cache
diff --git a/apps/permission/fixtures/initial.json b/apps/permission/fixtures/initial.json
index 5df6ba7f..07b16d40 100644
--- a/apps/permission/fixtures/initial.json
+++ b/apps/permission/fixtures/initial.json
@@ -3244,7 +3244,8 @@
"name": "Pr\u00e9sident\u00b7e de club",
"permissions": [
62,
- 142
+ 142,
+ 135
]
}
},
diff --git a/apps/permission/models.py b/apps/permission/models.py
index c05dcc4b..fbb46a90 100644
--- a/apps/permission/models.py
+++ b/apps/permission/models.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import functools
@@ -26,6 +26,15 @@ class InstancedPermission:
self.mask = mask
self.kwargs = kwargs
+ def __repr__(self):
+ if self.field:
+ return _("Can {type} {model}.{field} in {query}").format(type=self.type, model=self.model, field=self.field, query=self.query)
+ else:
+ return _("Can {type} {model} in {query}").format(type=self.type, model=self.model, query=self.query)
+
+ def __str__(self):
+ return self.__repr__()
+
def applies(self, obj, permission_type, field_name=None):
"""
Returns True if the permission applies to
@@ -84,21 +93,11 @@ class InstancedPermission:
# noinspection PyProtectedMember
self.query = Permission._about(self.raw_query, **self.kwargs)
- def __repr__(self):
- if self.field:
- return _("Can {type} {model}.{field} in {query}").format(type=self.type, model=self.model, field=self.field, query=self.query)
- else:
- return _("Can {type} {model} in {query}").format(type=self.type, model=self.model, query=self.query)
-
- def __str__(self):
- return self.__repr__()
-
class PermissionMask(models.Model):
"""
Permissions that are hidden behind a mask
"""
-
rank = models.PositiveSmallIntegerField(
unique=True,
verbose_name=_('rank'),
@@ -110,13 +109,13 @@ class PermissionMask(models.Model):
verbose_name=_('description'),
)
- def __str__(self):
- return self.description
-
class Meta:
verbose_name = _("permission mask")
verbose_name_plural = _("permission masks")
+ def __str__(self):
+ return self.description
+
class Permission(models.Model):
@@ -194,16 +193,19 @@ class Permission(models.Model):
verbose_name = _("permission")
verbose_name_plural = _("permissions")
- def clean(self):
- self.query = json.dumps(json.loads(self.query))
- if self.field and self.type not in {'view', 'change'}:
- raise ValidationError(_("Specifying field applies only to view and change permission types."))
+ def __str__(self):
+ return self.description
@transaction.atomic
def save(self, **kwargs):
self.full_clean()
super().save()
+ def clean(self):
+ self.query = json.dumps(json.loads(self.query))
+ if self.field and self.type not in {'view', 'change'}:
+ raise ValidationError(_("Specifying field applies only to view and change permission types."))
+
@staticmethod
def compute_f(oper, **kwargs):
if isinstance(oper, list):
@@ -317,9 +319,6 @@ class Permission(models.Model):
# query = self._about(query, **kwargs)
return InstancedPermission(self.model, query, self.type, self.field, self.mask, **kwargs)
- def __str__(self):
- return self.description
-
class Role(models.Model):
"""
@@ -344,9 +343,9 @@ class Role(models.Model):
default=None,
)
- def __str__(self):
- return self.name
-
class Meta:
verbose_name = _("role permissions")
verbose_name_plural = _("role permissions")
+
+ def __str__(self):
+ return self.name
diff --git a/apps/permission/permissions.py b/apps/permission/permissions.py
index 1a5f51e5..3840a3cd 100644
--- a/apps/permission/permissions.py
+++ b/apps/permission/permissions.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from rest_framework.permissions import DjangoObjectPermissions
diff --git a/apps/permission/scopes.py b/apps/permission/scopes.py
index 65242804..c3edfd93 100644
--- a/apps/permission/scopes.py
+++ b/apps/permission/scopes.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from oauth2_provider.oauth2_validators import OAuth2Validator
from oauth2_provider.scopes import BaseScopes
diff --git a/apps/permission/signals.py b/apps/permission/signals.py
index 6fb27392..37b7f7c3 100644
--- a/apps/permission/signals.py
+++ b/apps/permission/signals.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.core.exceptions import PermissionDenied
diff --git a/apps/permission/tables.py b/apps/permission/tables.py
index eaec5138..894d4d13 100644
--- a/apps/permission/tables.py
+++ b/apps/permission/tables.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import django_tables2 as tables
diff --git a/apps/permission/templatetags/perms.py b/apps/permission/templatetags/perms.py
index 17f336f4..241b2c73 100644
--- a/apps/permission/templatetags/perms.py
+++ b/apps/permission/templatetags/perms.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib.contenttypes.models import ContentType
diff --git a/apps/permission/tests/test_oauth2.py b/apps/permission/tests/test_oauth2.py
index 4593b35a..b37902b5 100644
--- a/apps/permission/tests/test_oauth2.py
+++ b/apps/permission/tests/test_oauth2.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from datetime import timedelta
diff --git a/apps/permission/tests/test_permission_denied.py b/apps/permission/tests/test_permission_denied.py
index 1aa3e9e9..7d3fef5f 100644
--- a/apps/permission/tests/test_permission_denied.py
+++ b/apps/permission/tests/test_permission_denied.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from datetime import timedelta, date
diff --git a/apps/permission/tests/test_permission_queries.py b/apps/permission/tests/test_permission_queries.py
index 218c5a75..95e303e4 100644
--- a/apps/permission/tests/test_permission_queries.py
+++ b/apps/permission/tests/test_permission_queries.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from datetime import date
diff --git a/apps/permission/tests/test_rights_page.py b/apps/permission/tests/test_rights_page.py
index 83e41cf3..ee777f48 100644
--- a/apps/permission/tests/test_rights_page.py
+++ b/apps/permission/tests/test_rights_page.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib.auth.models import User
diff --git a/apps/permission/urls.py b/apps/permission/urls.py
index 43eec1ef..31e44b77 100644
--- a/apps/permission/urls.py
+++ b/apps/permission/urls.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
diff --git a/apps/permission/views.py b/apps/permission/views.py
index 8f498478..77e5a4d0 100644
--- a/apps/permission/views.py
+++ b/apps/permission/views.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from collections import OrderedDict
from datetime import date
diff --git a/apps/registration/__init__.py b/apps/registration/__init__.py
index 5c37e986..024c5572 100644
--- a/apps/registration/__init__.py
+++ b/apps/registration/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
default_app_config = 'registration.apps.RegistrationConfig'
diff --git a/apps/registration/apps.py b/apps/registration/apps.py
index 9ea23dc2..44067233 100644
--- a/apps/registration/apps.py
+++ b/apps/registration/apps.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.apps import AppConfig
diff --git a/apps/registration/forms.py b/apps/registration/forms.py
index 6761da43..f6c980c9 100644
--- a/apps/registration/forms.py
+++ b/apps/registration/forms.py
@@ -1,11 +1,11 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.utils.translation import gettext_lazy as _
-from member.models import Club
+# from member.models import Club
from note.models import NoteSpecial, Alias
from note_kfet.inputs import AmountInput
@@ -116,11 +116,11 @@ class ValidationForm(forms.Form):
initial=True,
)
- # If the bda exists
- if Club.objects.filter(name__iexact="bda").exists():
- # The user can join the bda club at the inscription
- join_bda = forms.BooleanField(
- label=_("Join BDA Club"),
- required=False,
- initial=True,
- )
+# If the bda exists
+# if Club.objects.filter(name__iexact="bda").exists():
+# The user can join the bda club at the inscription
+# join_bda = forms.BooleanField(
+# label=_("Join BDA Club"),
+# required=False,
+# initial=True,
+# )
diff --git a/apps/registration/tables.py b/apps/registration/tables.py
index 960866a6..151d5d74 100644
--- a/apps/registration/tables.py
+++ b/apps/registration/tables.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import django_tables2 as tables
diff --git a/apps/registration/tests/test_registration.py b/apps/registration/tests/test_registration.py
index 69ab52d5..a37ad12a 100644
--- a/apps/registration/tests/test_registration.py
+++ b/apps/registration/tests/test_registration.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib.auth.models import User
diff --git a/apps/registration/tokens.py b/apps/registration/tokens.py
index ef8ddb02..332c4ee1 100644
--- a/apps/registration/tokens.py
+++ b/apps/registration/tokens.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
# Copied from https://gitlab.crans.org/bombar/codeflix/-/blob/master/codeflix/codeflix/tokens.py
diff --git a/apps/registration/urls.py b/apps/registration/urls.py
index fe7f1a1f..45ca4c60 100644
--- a/apps/registration/urls.py
+++ b/apps/registration/urls.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.urls import path
diff --git a/apps/registration/views.py b/apps/registration/views.py
index eb415bdd..02d6f05e 100644
--- a/apps/registration/views.py
+++ b/apps/registration/views.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
diff --git a/apps/treasury/__init__.py b/apps/treasury/__init__.py
index d14a7f6b..21ef103b 100644
--- a/apps/treasury/__init__.py
+++ b/apps/treasury/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
default_app_config = 'treasury.apps.TreasuryConfig'
diff --git a/apps/treasury/admin.py b/apps/treasury/admin.py
index 5069e535..c435a4ff 100644
--- a/apps/treasury/admin.py
+++ b/apps/treasury/admin.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-lateré
from django.contrib import admin
diff --git a/apps/treasury/api/serializers.py b/apps/treasury/api/serializers.py
index 5442fd06..79c2445d 100644
--- a/apps/treasury/api/serializers.py
+++ b/apps/treasury/api/serializers.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.db import transaction
from rest_framework import serializers
diff --git a/apps/treasury/api/urls.py b/apps/treasury/api/urls.py
index 90c9d332..a4ba7c1e 100644
--- a/apps/treasury/api/urls.py
+++ b/apps/treasury/api/urls.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from .views import InvoiceViewSet, ProductViewSet, RemittanceViewSet, RemittanceTypeViewSet, SogeCreditViewSet
diff --git a/apps/treasury/api/views.py b/apps/treasury/api/views.py
index e6ba9ced..c7bf68e6 100644
--- a/apps/treasury/api/views.py
+++ b/apps/treasury/api/views.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django_filters.rest_framework import DjangoFilterBackend
diff --git a/apps/treasury/apps.py b/apps/treasury/apps.py
index fb0b09db..e25accc0 100644
--- a/apps/treasury/apps.py
+++ b/apps/treasury/apps.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.apps import AppConfig
diff --git a/apps/treasury/forms.py b/apps/treasury/forms.py
index 02441189..c3a3fc49 100644
--- a/apps/treasury/forms.py
+++ b/apps/treasury/forms.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from crispy_forms.helper import FormHelper
diff --git a/apps/treasury/migrations/0007_auto_20240311_1549.py b/apps/treasury/migrations/0007_auto_20240311_1549.py
new file mode 100644
index 00000000..64cc3acc
--- /dev/null
+++ b/apps/treasury/migrations/0007_auto_20240311_1549.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2.28 on 2024-03-11 14:49
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('treasury', '0006_auto_20230414_1651'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='invoice',
+ name='bde',
+ field=models.CharField(choices=[('RavePartlist', 'RavePart[list]'), ('SecretStorlist', 'SecretStor[list]'), ('TotalistSpies', 'Tota[list]Spies'), ('Saperlistpopette', 'Saper[list]popette'), ('Finalist', 'Fina[list]'), ('Listorique', '[List]orique'), ('Satellist', 'Satel[list]'), ('Monopolist', 'Monopo[list]'), ('Kataclist', 'Katac[list]')], default='RavePartlist', max_length=32, verbose_name='BDE'),
+ ),
+ ]
diff --git a/apps/treasury/migrations/0008_auto_20240322_0045.py b/apps/treasury/migrations/0008_auto_20240322_0045.py
new file mode 100644
index 00000000..2dadb693
--- /dev/null
+++ b/apps/treasury/migrations/0008_auto_20240322_0045.py
@@ -0,0 +1,23 @@
+# Generated by Django 2.2.28 on 2024-03-21 23:45
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('treasury', '0007_auto_20240311_1549'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='invoice',
+ name='payment_date',
+ field=models.CharField(default='', max_length=255, verbose_name='Payment date'),
+ ),
+ migrations.AddField(
+ model_name='invoice',
+ name='quotation',
+ field=models.BooleanField(default=False, verbose_name='Quotation'),
+ ),
+ ]
diff --git a/apps/treasury/models.py b/apps/treasury/models.py
index e788e479..69fc6e6b 100644
--- a/apps/treasury/models.py
+++ b/apps/treasury/models.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2023 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from datetime import date
@@ -20,7 +20,6 @@ class Invoice(models.Model):
"""
An invoice model that can generates a true invoice.
"""
-
id = models.PositiveIntegerField(
primary_key=True,
verbose_name=_("Invoice identifier"),
@@ -28,8 +27,9 @@ class Invoice(models.Model):
bde = models.CharField(
max_length=32,
- default='SecretStorlist',
+ default='RavePartlist',
choices=(
+ ('RavePartlist', 'RavePart[list]'),
('SecretStorlist', 'SecretStor[list]'),
('TotalistSpies', 'Tota[list]Spies'),
('Saperlistpopette', 'Saper[list]popette'),
@@ -41,6 +41,10 @@ class Invoice(models.Model):
),
verbose_name=_("BDE"),
)
+ quotation = models.BooleanField(
+ default=False,
+ verbose_name=_("Quotation"),
+ )
object = models.CharField(
max_length=255,
@@ -65,6 +69,12 @@ class Invoice(models.Model):
verbose_name=_("Date"),
)
+ payment_date = models.CharField(
+ default="",
+ max_length=255,
+ verbose_name=_("Payment date"),
+ )
+
acquitted = models.BooleanField(
verbose_name=_("Acquitted"),
default=False,
@@ -81,6 +91,13 @@ class Invoice(models.Model):
verbose_name=_("tex source"),
)
+ class Meta:
+ verbose_name = _("invoice")
+ verbose_name_plural = _("invoices")
+
+ def __str__(self):
+ return _("Invoice #{id}").format(id=self.id)
+
@transaction.atomic
def save(self, *args, **kwargs):
"""
@@ -111,19 +128,11 @@ class Invoice(models.Model):
return super().save(*args, **kwargs)
- class Meta:
- verbose_name = _("invoice")
- verbose_name_plural = _("invoices")
-
- def __str__(self):
- return _("Invoice #{id}").format(id=self.id)
-
class Product(models.Model):
"""
Product that appears on an invoice.
"""
-
invoice = models.ForeignKey(
Invoice,
on_delete=models.CASCADE,
@@ -147,6 +156,13 @@ class Product(models.Model):
verbose_name=_("Unit price"),
)
+ class Meta:
+ verbose_name = _("product")
+ verbose_name_plural = _("products")
+
+ def __str__(self):
+ return f"{self.designation} ({self.invoice})"
+
@property
def amount_euros(self):
return "{:.2f}".format(self.amount / 100)
@@ -159,37 +175,28 @@ class Product(models.Model):
def total_euros(self):
return "{:.2f}".format(self.total / 100)
- class Meta:
- verbose_name = _("product")
- verbose_name_plural = _("products")
-
- def __str__(self):
- return f"{self.designation} ({self.invoice})"
-
class RemittanceType(models.Model):
"""
Store what kind of remittances can be stored.
"""
-
note = models.OneToOneField(
NoteSpecial,
on_delete=models.CASCADE,
)
- def __str__(self):
- return str(self.note)
-
class Meta:
verbose_name = _("remittance type")
verbose_name_plural = _("remittance types")
+ def __str__(self):
+ return str(self.note)
+
class Remittance(models.Model):
"""
Treasurers want to regroup checks or bank transfers in bank remittances.
"""
-
date = models.DateTimeField(
default=timezone.now,
verbose_name=_("Date"),
@@ -215,6 +222,17 @@ class Remittance(models.Model):
verbose_name = _("remittance")
verbose_name_plural = _("remittances")
+ def __str__(self):
+ return _("Remittance #{:d}: {}").format(self.id, self.comment, )
+
+ @transaction.atomic
+ def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
+ # Check if all transactions have the right type.
+ if self.transactions.exists() and self.transactions.filter(~Q(source=self.remittance_type.note)).exists():
+ raise ValidationError("All transactions in a remittance must have the same type")
+
+ return super().save(force_insert, force_update, using, update_fields)
+
@property
def transactions(self):
"""
@@ -237,17 +255,6 @@ class Remittance(models.Model):
"""
return sum(transaction.total for transaction in self.transactions.all())
- @transaction.atomic
- def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
- # Check if all transactions have the right type.
- if self.transactions.exists() and self.transactions.filter(~Q(source=self.remittance_type.note)).exists():
- raise ValidationError("All transactions in a remittance must have the same type")
-
- return super().save(force_insert, force_update, using, update_fields)
-
- def __str__(self):
- return _("Remittance #{:d}: {}").format(self.id, self.comment, )
-
class SpecialTransactionProxy(models.Model):
"""
@@ -255,7 +262,6 @@ class SpecialTransactionProxy(models.Model):
That's why we create a proxy in this app, to link special transactions and remittances.
If it isn't very clean, it does what we want.
"""
-
transaction = models.OneToOneField(
SpecialTransaction,
on_delete=models.CASCADE,
@@ -301,6 +307,43 @@ class SogeCredit(models.Model):
null=True,
)
+ class Meta:
+ verbose_name = _("Credit from the Société générale")
+ verbose_name_plural = _("Credits from the Société générale")
+
+ def __str__(self):
+ return _("Soge credit for {user}").format(user=str(self.user))
+
+ @transaction.atomic
+ def save(self, *args, **kwargs):
+ # This is a pre-registered user that declared that a SoGé account was opened.
+ # No note exists yet.
+ if not NoteUser.objects.filter(user=self.user).exists():
+ return super().save(*args, **kwargs)
+
+ if not self.credit_transaction:
+ credit_transaction = SpecialTransaction(
+ source=NoteSpecial.objects.get(special_type="Virement bancaire"),
+ destination=self.user.note,
+ quantity=1,
+ amount=0,
+ reason="Crédit société générale",
+ last_name=self.user.last_name,
+ first_name=self.user.first_name,
+ bank="Société générale",
+ valid=False,
+ )
+ credit_transaction._force_save = True
+ credit_transaction.save()
+ credit_transaction.refresh_from_db()
+ self.credit_transaction = credit_transaction
+ elif not self.valid:
+ self.credit_transaction.amount = self.amount
+ self.credit_transaction._force_save = True
+ self.credit_transaction.save()
+
+ return super().save(*args, **kwargs)
+
@property
def valid(self):
return self.credit_transaction and self.credit_transaction.valid
@@ -390,36 +433,6 @@ class SogeCredit(models.Model):
tr._force_save = True
tr.save()
- @transaction.atomic
- def save(self, *args, **kwargs):
- # This is a pre-registered user that declared that a SoGé account was opened.
- # No note exists yet.
- if not NoteUser.objects.filter(user=self.user).exists():
- return super().save(*args, **kwargs)
-
- if not self.credit_transaction:
- credit_transaction = SpecialTransaction(
- source=NoteSpecial.objects.get(special_type="Virement bancaire"),
- destination=self.user.note,
- quantity=1,
- amount=0,
- reason="Crédit société générale",
- last_name=self.user.last_name,
- first_name=self.user.first_name,
- bank="Société générale",
- valid=False,
- )
- credit_transaction._force_save = True
- credit_transaction.save()
- credit_transaction.refresh_from_db()
- self.credit_transaction = credit_transaction
- elif not self.valid:
- self.credit_transaction.amount = self.amount
- self.credit_transaction._force_save = True
- self.credit_transaction.save()
-
- return super().save(*args, **kwargs)
-
def delete(self, **kwargs):
"""
Deleting a SogeCredit is equivalent to say that the Société générale didn't pay.
@@ -447,10 +460,3 @@ class SogeCredit(models.Model):
self.credit_transaction._force_save = True
self.credit_transaction.save()
super().delete(**kwargs)
-
- class Meta:
- verbose_name = _("Credit from the Société générale")
- verbose_name_plural = _("Credits from the Société générale")
-
- def __str__(self):
- return _("Soge credit for {user}").format(user=str(self.user))
diff --git a/apps/treasury/signals.py b/apps/treasury/signals.py
index fc87b874..67b516fc 100644
--- a/apps/treasury/signals.py
+++ b/apps/treasury/signals.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from treasury.models import SpecialTransactionProxy, RemittanceType
diff --git a/apps/treasury/static/img/RavePartlist.png b/apps/treasury/static/img/RavePartlist.png
new file mode 100644
index 00000000..7a239468
Binary files /dev/null and b/apps/treasury/static/img/RavePartlist.png differ
diff --git a/apps/treasury/static/img/RavePartlist_bg.jpg b/apps/treasury/static/img/RavePartlist_bg.jpg
new file mode 100644
index 00000000..17438968
Binary files /dev/null and b/apps/treasury/static/img/RavePartlist_bg.jpg differ
diff --git a/apps/treasury/tables.py b/apps/treasury/tables.py
index f309c20f..c5272091 100644
--- a/apps/treasury/tables.py
+++ b/apps/treasury/tables.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import django_tables2 as tables
diff --git a/apps/treasury/templates/treasury/invoice_sample.tex b/apps/treasury/templates/treasury/invoice_sample.tex
index f34b7ad3..29db4cfb 100644
--- a/apps/treasury/templates/treasury/invoice_sample.tex
+++ b/apps/treasury/templates/treasury/invoice_sample.tex
@@ -76,8 +76,11 @@
\def\FactureNum {{"{"}}{{ obj.id }}} % Numéro de facture
\def\FactureAcquittee {% if obj.acquitted %} {oui} {% else %} {non} {% endif %} % Facture acquittée : oui/non
+\def\Devis {% if obj.quotation %} {oui} {% else %} {non} {% endif %}
+ % Devis : oui/non
\def\FactureLieu {{"{"}}{{ obj.place|escape_tex }}} % Lieu de l'édition de la facture
\def\FactureDate {{"{"}}{{ obj.date }}} % Date de l'édition de la facture
+\def\FacturePaymentDate {{"{"}}{{ obj.payment_date|escape_tex }}} % Date de paiement de la facture
\def\FactureObjet {{"{"}}{{ obj.object|escape_tex }} } % Objet du document
% Description de la facture
\def\FactureDescr {{"{"}}{{ obj.description|escape_tex }}}
@@ -118,10 +121,12 @@
% Nom et adresse de la société
\MonNom \\
\MonAdresseRue \\
-\MonAdresseVille
-
+\MonAdresseVille \\
+\ifthenelse{\equal{\Devis}{oui}}{
+Devis n°\FactureNum
+}{
Facture n°\FactureNum
-
+}
{\addtolength{\leftskip}{10.5cm} %in ERT
\ClientNom \\
@@ -139,6 +144,7 @@ Facture n°\FactureNum
\textnormal{\FactureDescr}
+
~\\
\begin{center}
@@ -154,6 +160,11 @@ Facture n°\FactureNum
\ifthenelse{\equal{\FactureAcquittee}{oui}}{
Facture acquittée.
}{
+ Echéance de paiement : \FacturePaymentDate
+
+ Conditions d'escompte : Aucune
+
+ Taux de pénalité en cas de non paiement ou retard de paiement : 0 \%
À régler par chèque ou par virement bancaire :
@@ -176,5 +187,6 @@ Facture n°\FactureNum
TVA non applicable, article 293 B du CGI.
\end{center}
+
\end{document}
{% endlanguage %}
diff --git a/apps/treasury/templatetags/escape_tex.py b/apps/treasury/templatetags/escape_tex.py
index 9ecbb613..656e53ac 100644
--- a/apps/treasury/templatetags/escape_tex.py
+++ b/apps/treasury/templatetags/escape_tex.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django import template
diff --git a/apps/treasury/tests/test_treasury.py b/apps/treasury/tests/test_treasury.py
index bc0eddc3..1bfc8993 100644
--- a/apps/treasury/tests/test_treasury.py
+++ b/apps/treasury/tests/test_treasury.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from api.tests import TestAPI
@@ -69,9 +69,11 @@ class TestInvoices(TestCase):
response = self.client.post(reverse("treasury:invoice_create"), data={
"id": 42,
"object": "Same object",
+ "quotation": True,
"description": "Longer description",
"name": "Me and others",
"address": "Alwways earth",
+ "payment_date": "Maybe someday...",
"acquitted": True,
"products-0-designation": "Designation",
"products-0-quantity": 1,
@@ -97,8 +99,10 @@ class TestInvoices(TestCase):
"object": "Same object",
"description": "Longer description",
"name": "Me and others",
+ "quotation": False,
"address": "Always earth",
"acquitted": True,
+ "payment_date": "Never",
"locked": True,
"products-0-designation": "Designation",
"products-0-quantity": 1,
diff --git a/apps/treasury/urls.py b/apps/treasury/urls.py
index 4fe87924..2759358f 100644
--- a/apps/treasury/urls.py
+++ b/apps/treasury/urls.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.urls import path
diff --git a/apps/treasury/views.py b/apps/treasury/views.py
index fef684cc..be989f99 100644
--- a/apps/treasury/views.py
+++ b/apps/treasury/views.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import os
diff --git a/apps/wei/__init__.py b/apps/wei/__init__.py
index 93dd4163..c4ea977d 100644
--- a/apps/wei/__init__.py
+++ b/apps/wei/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
default_app_config = 'wei.apps.WeiConfig'
diff --git a/apps/wei/admin.py b/apps/wei/admin.py
index 63792b6b..f7c94227 100644
--- a/apps/wei/admin.py
+++ b/apps/wei/admin.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from note_kfet.admin import admin_site
diff --git a/apps/wei/api/serializers.py b/apps/wei/api/serializers.py
index ee028a37..93915ea9 100644
--- a/apps/wei/api/serializers.py
+++ b/apps/wei/api/serializers.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from rest_framework import serializers
diff --git a/apps/wei/api/urls.py b/apps/wei/api/urls.py
index 58dab39c..e5692224 100644
--- a/apps/wei/api/urls.py
+++ b/apps/wei/api/urls.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from .views import WEIClubViewSet, BusViewSet, BusTeamViewSet, WEIRoleViewSet, WEIRegistrationViewSet, \
diff --git a/apps/wei/api/views.py b/apps/wei/api/views.py
index bad8ff68..e16a5374 100644
--- a/apps/wei/api/views.py
+++ b/apps/wei/api/views.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django_filters.rest_framework import DjangoFilterBackend
diff --git a/apps/wei/apps.py b/apps/wei/apps.py
index 6836a50f..2f89420b 100644
--- a/apps/wei/apps.py
+++ b/apps/wei/apps.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.apps import AppConfig
diff --git a/apps/wei/forms/__init__.py b/apps/wei/forms/__init__.py
index 10765752..fce2373a 100644
--- a/apps/wei/forms/__init__.py
+++ b/apps/wei/forms/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from .registration import WEIForm, WEIRegistrationForm, WEIMembership1AForm, WEIMembershipForm, BusForm, BusTeamForm
diff --git a/apps/wei/forms/registration.py b/apps/wei/forms/registration.py
index 408071f4..808d7eda 100644
--- a/apps/wei/forms/registration.py
+++ b/apps/wei/forms/registration.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2023 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django import forms
diff --git a/apps/wei/forms/surveys/__init__.py b/apps/wei/forms/surveys/__init__.py
index 0b1c583f..0e0c37e2 100644
--- a/apps/wei/forms/surveys/__init__.py
+++ b/apps/wei/forms/surveys/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from .base import WEISurvey, WEISurveyInformation, WEISurveyAlgorithm
diff --git a/apps/wei/forms/surveys/base.py b/apps/wei/forms/surveys/base.py
index d8e86b3e..02bf0be8 100644
--- a/apps/wei/forms/surveys/base.py
+++ b/apps/wei/forms/surveys/base.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from typing import Optional, List
diff --git a/apps/wei/forms/surveys/wei2021.py b/apps/wei/forms/surveys/wei2021.py
index e515d447..83f2d8ce 100644
--- a/apps/wei/forms/surveys/wei2021.py
+++ b/apps/wei/forms/surveys/wei2021.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import time
diff --git a/apps/wei/forms/surveys/wei2022.py b/apps/wei/forms/surveys/wei2022.py
index 6a6aecd5..2550bc94 100644
--- a/apps/wei/forms/surveys/wei2022.py
+++ b/apps/wei/forms/surveys/wei2022.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2023 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import time
diff --git a/apps/wei/forms/surveys/wei2023.py b/apps/wei/forms/surveys/wei2023.py
index 70bd814e..0ec017bb 100644
--- a/apps/wei/forms/surveys/wei2023.py
+++ b/apps/wei/forms/surveys/wei2023.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2023 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from functools import lru_cache
diff --git a/apps/wei/management/commands/export_wei_registrations.py b/apps/wei/management/commands/export_wei_registrations.py
index a51f1c64..ca3dc06c 100644
--- a/apps/wei/management/commands/export_wei_registrations.py
+++ b/apps/wei/management/commands/export_wei_registrations.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.core.management import BaseCommand, CommandError
diff --git a/apps/wei/management/commands/import_scores.py b/apps/wei/management/commands/import_scores.py
index f8587cfd..915ce696 100644
--- a/apps/wei/management/commands/import_scores.py
+++ b/apps/wei/management/commands/import_scores.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import argparse
import sys
diff --git a/apps/wei/management/commands/wei_algorithm.py b/apps/wei/management/commands/wei_algorithm.py
index 9e895035..8d070242 100644
--- a/apps/wei/management/commands/wei_algorithm.py
+++ b/apps/wei/management/commands/wei_algorithm.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from argparse import ArgumentParser, FileType
diff --git a/apps/wei/migrations/0008_auto_20240111_1545.py b/apps/wei/migrations/0008_auto_20240111_1545.py
new file mode 100644
index 00000000..838302aa
--- /dev/null
+++ b/apps/wei/migrations/0008_auto_20240111_1545.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2.28 on 2024-01-11 14:45
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('wei', '0007_help_text_emergency_contact'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='weiclub',
+ name='year',
+ field=models.PositiveIntegerField(default=2024, unique=True, verbose_name='year'),
+ ),
+ ]
diff --git a/apps/wei/models.py b/apps/wei/models.py
index 6b05609f..76fd465d 100644
--- a/apps/wei/models.py
+++ b/apps/wei/models.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2023 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import json
@@ -33,6 +33,10 @@ class WEIClub(Club):
verbose_name=_("date end"),
)
+ class Meta:
+ verbose_name = _("WEI")
+ verbose_name_plural = _("WEI")
+
@property
def is_current_wei(self):
"""
@@ -46,10 +50,6 @@ class WEIClub(Club):
"""
return
- class Meta:
- verbose_name = _("WEI")
- verbose_name_plural = _("WEI")
-
class Bus(models.Model):
"""
@@ -84,6 +84,14 @@ class Bus(models.Model):
help_text=_("Information about the survey for new members, encoded in JSON"),
)
+ class Meta:
+ verbose_name = _("Bus")
+ verbose_name_plural = _("Buses")
+ unique_together = ('wei', 'name',)
+
+ def __str__(self):
+ return self.name
+
@property
def information(self):
"""
@@ -106,14 +114,6 @@ class Bus(models.Model):
registrations = [r for r in registrations if 'selected_bus_pk' in r.information]
return sum(1 for r in registrations if r.information['selected_bus_pk'] == self.pk)
- def __str__(self):
- return self.name
-
- class Meta:
- verbose_name = _("Bus")
- verbose_name_plural = _("Buses")
- unique_together = ('wei', 'name',)
-
class BusTeam(models.Model):
"""
@@ -142,20 +142,19 @@ class BusTeam(models.Model):
verbose_name=_("description"),
)
- def __str__(self):
- return self.name + " (" + str(self.bus) + ")"
-
class Meta:
unique_together = ('bus', 'name',)
verbose_name = _("Bus team")
verbose_name_plural = _("Bus teams")
+ def __str__(self):
+ return self.name + " (" + str(self.bus) + ")"
+
class WEIRole(Role):
"""
A Role for the WEI can be bus chief, team chief, free electron, ...
"""
-
class Meta:
verbose_name = _("WEI Role")
verbose_name_plural = _("WEI Roles")
@@ -165,7 +164,6 @@ class WEIRegistration(models.Model):
"""
Store personal data that can be useful for the WEI.
"""
-
user = models.ForeignKey(
User,
on_delete=models.PROTECT,
@@ -258,6 +256,14 @@ class WEIRegistration(models.Model):
"encoded in JSON"),
)
+ class Meta:
+ unique_together = ('user', 'wei',)
+ verbose_name = _("WEI User")
+ verbose_name_plural = _("WEI Users")
+
+ def __str__(self):
+ return str(self.user)
+
@property
def information(self):
"""
@@ -307,14 +313,6 @@ class WEIRegistration(models.Model):
except AttributeError:
return False
- def __str__(self):
- return str(self.user)
-
- class Meta:
- unique_together = ('user', 'wei',)
- verbose_name = _("WEI User")
- verbose_name_plural = _("WEI Users")
-
class WEIMembership(Membership):
bus = models.ForeignKey(
diff --git a/apps/wei/tables.py b/apps/wei/tables.py
index 687f8f07..7cf26b02 100644
--- a/apps/wei/tables.py
+++ b/apps/wei/tables.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from datetime import date
diff --git a/apps/wei/templates/wei/weilist_sample.tex b/apps/wei/templates/wei/weilist_sample.tex
index 820df64d..79527bae 100644
--- a/apps/wei/templates/wei/weilist_sample.tex
+++ b/apps/wei/templates/wei/weilist_sample.tex
@@ -6,7 +6,7 @@
\begin{document}
\begin{center}
-\huge{Liste des inscrits « {{ wei.name }} »}
+\huge{Liste des personnes inscrites au WEI « {{ wei.name }} »}
{% if bus %}
\LARGE{Bus {{ bus.name|safe }}}
diff --git a/apps/wei/tests/test_wei_algorithm_2021.py b/apps/wei/tests/test_wei_algorithm_2021.py
index 53207127..d6782fe8 100644
--- a/apps/wei/tests/test_wei_algorithm_2021.py
+++ b/apps/wei/tests/test_wei_algorithm_2021.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import random
diff --git a/apps/wei/tests/test_wei_algorithm_2022.py b/apps/wei/tests/test_wei_algorithm_2022.py
index 2d358dbe..2ee3da6e 100644
--- a/apps/wei/tests/test_wei_algorithm_2022.py
+++ b/apps/wei/tests/test_wei_algorithm_2022.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2022 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import random
diff --git a/apps/wei/tests/test_wei_algorithm_2023.py b/apps/wei/tests/test_wei_algorithm_2023.py
index ae982d3c..c94cbb0c 100644
--- a/apps/wei/tests/test_wei_algorithm_2023.py
+++ b/apps/wei/tests/test_wei_algorithm_2023.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2023 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import random
diff --git a/apps/wei/tests/test_wei_registration.py b/apps/wei/tests/test_wei_registration.py
index 86dd4cfd..74fdcf0b 100644
--- a/apps/wei/tests/test_wei_registration.py
+++ b/apps/wei/tests/test_wei_registration.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2023 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import subprocess
diff --git a/apps/wei/urls.py b/apps/wei/urls.py
index fb497216..c96fa040 100644
--- a/apps/wei/urls.py
+++ b/apps/wei/urls.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.urls import path
diff --git a/apps/wei/views.py b/apps/wei/views.py
index 4f2b7b65..4771cb5b 100644
--- a/apps/wei/views.py
+++ b/apps/wei/views.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import os
diff --git a/docs/conf.py b/docs/conf.py
index 50e96fdd..cc9df629 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -18,11 +18,11 @@
# -- Project information -----------------------------------------------------
project = 'Note Kfet 2020'
-copyright = '2020-2021, BDE ENS Paris-Saclay'
+copyright = '2020-2024, BDE ENS Paris-Saclay'
author = 'BDE ENS Paris-Saclay'
# The full version, including alpha/beta/rc tags
-release = '1.0.1'
+release = '1.0.2'
# -- General configuration ---------------------------------------------------
diff --git a/docs/scripts.rst b/docs/scripts.rst
index 4e273b6d..53545171 100644
--- a/docs/scripts.rst
+++ b/docs/scripts.rst
@@ -128,6 +128,14 @@ Le script s'appelle ``extract_ml_registrations``.
Il a pour but d'extraire une liste d'adresses mail pour les inclure directement dans les listes
de diffusion utiles.
+.. caution::
+
+ Vous récupérez les adresses mails de personnes qui ont donné leur consentement afin que leur
+ mail ne soit utilié uniquement à des fins BDE.
+
+ Faîtes attention, donc où la sortie est stockée.
+
+
Il prend 2 options :
* ``--type``, qui prend en argument ``members`` (défaut), ``clubs``, ``events``, ``art``,
@@ -137,6 +145,9 @@ Il prend 2 options :
à ``all.bda@lists.crans.org`` et enfin à ``bds@lists.crans.org``.
* ``--lang``, qui prend en argument ``fr`` ou ``en``. N'est utile que pour la ML événements,
qui a pour projet d'être disponible à la fois en anglais et en français.
+* ``--years``, qui prend en argument un nombre ``n`` (``0`` par défaut). N'est utile que
+ pour la ML Adhérents, pour exporter les mails des adhérents au BDE pendant n'importe
+ laquelle des ``n+1`` dernières années.
Le script sort sur la sortie standard la liste des adresses mails à inscrire.
diff --git a/entrypoint.sh b/entrypoint.sh
index ddfcb00a..60a0a912 100755
--- a/entrypoint.sh
+++ b/entrypoint.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
if [ -z ${NOTE_URL+x} ]; then
diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po
index 4fa2bdac..9ce95379 100644
--- a/locale/de/LC_MESSAGES/django.po
+++ b/locale/de/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-10-25 19:12+0200\n"
+"POT-Creation-Date: 2024-03-22 00:33+0100\n"
"PO-Revision-Date: 2020-11-16 20:02+0000\n"
"Last-Translator: bleizi \n"
"Language-Team: German \n"
@@ -18,7 +18,7 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.3.2\n"
-#: apps/activity/apps.py:10 apps/activity/models.py:151
+#: apps/activity/apps.py:10 apps/activity/models.py:127
#: apps/activity/models.py:167
msgid "activity"
msgstr "Veranstaltung"
@@ -27,38 +27,38 @@ msgstr "Veranstaltung"
msgid "The note of this club is inactive."
msgstr ""
-#: apps/activity/forms.py:41 apps/activity/models.py:132
+#: apps/activity/forms.py:41 apps/activity/models.py:140
msgid "The end date must be after the start date."
msgstr "Das Abschlussdatum muss nach das Anfangsdatum sein."
-#: apps/activity/forms.py:82 apps/activity/models.py:270
+#: apps/activity/forms.py:82 apps/activity/models.py:269
msgid "You can't invite someone once the activity is started."
msgstr ""
"Sie dürfen nicht jemandem einladen wenn die Veranstaltung angefangen hat."
-#: apps/activity/forms.py:85 apps/activity/models.py:273
+#: apps/activity/forms.py:85 apps/activity/models.py:272
msgid "This activity is not validated yet."
msgstr "Diese Veranstaltung ist noch nicht bestätigt."
-#: apps/activity/forms.py:95 apps/activity/models.py:281
+#: apps/activity/forms.py:95 apps/activity/models.py:280
msgid "This person has been already invited 5 times this year."
msgstr "Diese Person wurde schon 5 mal dieses Jahr eingeladen."
-#: apps/activity/forms.py:99 apps/activity/models.py:285
+#: apps/activity/forms.py:99 apps/activity/models.py:284
msgid "This person is already invited."
msgstr "Diese Person wurde schon eingeladen."
-#: apps/activity/forms.py:103 apps/activity/models.py:289
+#: apps/activity/forms.py:103 apps/activity/models.py:288
msgid "You can't invite more than 3 people to this activity."
msgstr "Sie dürfen höchstens 3 Leute zu dieser Veranstaltung einladen."
#: apps/activity/models.py:28 apps/activity/models.py:63
-#: apps/member/models.py:204
+#: apps/member/models.py:203
#: apps/member/templates/member/includes/club_info.html:4
#: apps/member/templates/member/includes/profile_info.html:4
#: apps/note/models/notes.py:263 apps/note/models/transactions.py:26
-#: apps/note/models/transactions.py:46 apps/note/models/transactions.py:301
-#: apps/permission/models.py:330
+#: apps/note/models/transactions.py:46 apps/note/models/transactions.py:299
+#: apps/permission/models.py:329
#: apps/registration/templates/registration/future_profile_detail.html:16
#: apps/wei/models.py:67 apps/wei/models.py:131 apps/wei/tables.py:282
#: apps/wei/templates/wei/base.html:26
@@ -94,8 +94,8 @@ msgstr "Vearnstaltungarte"
#: apps/activity/models.py:68
#: apps/activity/templates/activity/includes/activity_info.html:19
-#: apps/note/models/transactions.py:81 apps/permission/models.py:110
-#: apps/permission/models.py:189 apps/wei/models.py:78 apps/wei/models.py:142
+#: apps/note/models/transactions.py:82 apps/permission/models.py:109
+#: apps/permission/models.py:188 apps/wei/models.py:78 apps/wei/models.py:142
msgid "description"
msgstr "Beschreibung"
@@ -109,14 +109,14 @@ msgstr "Wo findet die Veranstaltung statt ? (z.B Kfet)."
#: apps/activity/models.py:83
#: apps/activity/templates/activity/includes/activity_info.html:22
-#: apps/note/models/notes.py:207 apps/note/models/transactions.py:66
-#: apps/permission/models.py:164
+#: apps/note/models/notes.py:207 apps/note/models/transactions.py:67
+#: apps/permission/models.py:163
msgid "type"
msgstr "Type"
-#: apps/activity/models.py:89 apps/logs/models.py:22 apps/member/models.py:312
-#: apps/note/models/notes.py:148 apps/treasury/models.py:287
-#: apps/wei/models.py:173 apps/wei/templates/wei/attribute_bus_1A.html:13
+#: apps/activity/models.py:89 apps/logs/models.py:22 apps/member/models.py:313
+#: apps/note/models/notes.py:148 apps/treasury/models.py:293
+#: apps/wei/models.py:171 apps/wei/templates/wei/attribute_bus_1A.html:13
#: apps/wei/templates/wei/survey.html:15
msgid "user"
msgstr "User"
@@ -162,7 +162,7 @@ msgstr "gültig"
msgid "open"
msgstr "geöffnet"
-#: apps/activity/models.py:152
+#: apps/activity/models.py:128
msgid "activities"
msgstr "Veranstaltungen"
@@ -226,11 +226,11 @@ msgstr "Vorname"
msgid "inviter"
msgstr "Einlader"
-#: apps/activity/models.py:297
+#: apps/activity/models.py:256
msgid "guest"
msgstr "Gast"
-#: apps/activity/models.py:298
+#: apps/activity/models.py:257
msgid "guests"
msgstr "Gäste"
@@ -258,7 +258,7 @@ msgstr "Eingetreten um "
msgid "remove"
msgstr "entfernen"
-#: apps/activity/tables.py:82 apps/note/forms.py:68 apps/treasury/models.py:201
+#: apps/activity/tables.py:82 apps/note/forms.py:68 apps/treasury/models.py:208
msgid "Type"
msgstr "Type"
@@ -294,7 +294,7 @@ msgid "Guest deleted"
msgstr "Gastliste"
#: apps/activity/templates/activity/activity_entry.html:14
-#: apps/note/models/transactions.py:257
+#: apps/note/models/transactions.py:261
#: apps/note/templates/note/transaction_form.html:17
#: apps/note/templates/note/transaction_form.html:152
#: note_kfet/templates/base.html:72
@@ -302,13 +302,13 @@ msgid "Transfer"
msgstr "Überweisen"
#: apps/activity/templates/activity/activity_entry.html:18
-#: apps/note/models/transactions.py:317
+#: apps/note/models/transactions.py:324
#: apps/note/templates/note/transaction_form.html:22
msgid "Credit"
msgstr "Kredit"
#: apps/activity/templates/activity/activity_entry.html:21
-#: apps/note/models/transactions.py:317
+#: apps/note/models/transactions.py:324
#: apps/note/templates/note/transaction_form.html:26
msgid "Debit"
msgstr "Soll"
@@ -447,7 +447,7 @@ msgstr "Logs"
msgid "IP Address"
msgstr "IP Adresse"
-#: apps/logs/models.py:36 apps/permission/models.py:134
+#: apps/logs/models.py:36 apps/permission/models.py:133
msgid "model"
msgstr "Model"
@@ -468,7 +468,7 @@ msgid "create"
msgstr "schaffen"
#: apps/logs/models.py:65 apps/note/tables.py:230 apps/note/tables.py:277
-#: apps/permission/models.py:127 apps/treasury/tables.py:38
+#: apps/permission/models.py:126 apps/treasury/tables.py:38
#: apps/wei/tables.py:74
msgid "delete"
msgstr "entfernen"
@@ -482,37 +482,37 @@ msgid "timestamp"
msgstr "Zeitstempel"
#: apps/logs/models.py:80
-msgid "Logs cannot be destroyed."
-msgstr "Logs können nicht entfernen sein."
-
-#: apps/logs/models.py:83
msgid "changelog"
msgstr "Changelog"
-#: apps/logs/models.py:84
+#: apps/logs/models.py:81
msgid "changelogs"
msgstr "Changelogs"
-#: apps/logs/models.py:87
+#: apps/logs/models.py:84
#, python-brace-format
msgid "Changelog of type \"{action}\" for model {model} at {timestamp}"
msgstr "Changelog \"{action}\" für Model {model} an {timestamp}"
-#: apps/member/admin.py:50 apps/member/models.py:231
+#: apps/logs/models.py:88
+msgid "Logs cannot be destroyed."
+msgstr "Logs können nicht entfernen sein."
+
+#: apps/member/admin.py:50 apps/member/models.py:232
#: apps/member/templates/member/includes/club_info.html:34
msgid "membership fee (paid students)"
msgstr "Mitgliedschaftpreis (bezahlte Studenten)"
-#: apps/member/admin.py:51 apps/member/models.py:236
+#: apps/member/admin.py:51 apps/member/models.py:237
#: apps/member/templates/member/includes/club_info.html:37
msgid "membership fee (unpaid students)"
msgstr "Mitgliedschaftpreis (unbezahlte Studenten)"
-#: apps/member/admin.py:65 apps/member/models.py:324
+#: apps/member/admin.py:65 apps/member/models.py:325
msgid "roles"
msgstr "Rollen"
-#: apps/member/admin.py:66 apps/member/models.py:338
+#: apps/member/admin.py:66 apps/member/models.py:339
msgid "fee"
msgstr "Preis"
@@ -629,132 +629,132 @@ msgstr ""
msgid "hash"
msgstr ""
-#: apps/member/models.py:38
+#: apps/member/models.py:37
#: apps/member/templates/member/includes/profile_info.html:43
#: apps/registration/templates/registration/future_profile_detail.html:40
#: apps/wei/templates/wei/weimembership_form.html:44
msgid "phone number"
msgstr "Telefonnummer"
-#: apps/member/models.py:45
+#: apps/member/models.py:44
#: apps/member/templates/member/includes/profile_info.html:37
#: apps/registration/templates/registration/future_profile_detail.html:34
#: apps/wei/templates/wei/weimembership_form.html:38
msgid "section"
msgstr "Section"
-#: apps/member/models.py:46
+#: apps/member/models.py:45
msgid "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\""
msgstr "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\""
-#: apps/member/models.py:54 apps/wei/templates/wei/attribute_bus_1A.html:25
+#: apps/member/models.py:53 apps/wei/templates/wei/attribute_bus_1A.html:25
#: apps/wei/templates/wei/weimembership_form.html:32
msgid "department"
msgstr "Fachabteilung"
-#: apps/member/models.py:56
+#: apps/member/models.py:55
msgid "Informatics (A0)"
msgstr "Informatik (A0)"
-#: apps/member/models.py:57
+#: apps/member/models.py:56
msgid "Mathematics (A1)"
msgstr "Mathematik (A1)"
-#: apps/member/models.py:58
+#: apps/member/models.py:57
msgid "Physics (A2)"
msgstr "Physik (A2)"
-#: apps/member/models.py:59
+#: apps/member/models.py:58
msgid "Applied physics (A'2)"
msgstr "Angewandte Physik (A'2)"
-#: apps/member/models.py:60
+#: apps/member/models.py:59
msgid "Chemistry (A''2)"
msgstr "Chemie (A''2)"
-#: apps/member/models.py:61
+#: apps/member/models.py:60
msgid "Biology (A3)"
msgstr "Biologie (A3)"
-#: apps/member/models.py:62
+#: apps/member/models.py:61
msgid "SAPHIRE (B1234)"
msgstr "SAPHIRE (B1234)"
-#: apps/member/models.py:63
+#: apps/member/models.py:62
msgid "Mechanics (B1)"
msgstr "Mechanik (B1)"
-#: apps/member/models.py:64
+#: apps/member/models.py:63
msgid "Civil engineering (B2)"
msgstr "Bauingenieur (B2)"
-#: apps/member/models.py:65
+#: apps/member/models.py:64
msgid "Mechanical engineering (B3)"
msgstr "Mechanikingenieur (B3)"
-#: apps/member/models.py:66
+#: apps/member/models.py:65
msgid "EEA (B4)"
msgstr "Electrotechnik (B4)"
-#: apps/member/models.py:67
+#: apps/member/models.py:66
msgid "Design (C)"
msgstr "Design (C)"
-#: apps/member/models.py:68
+#: apps/member/models.py:67
msgid "Economy-management (D2)"
msgstr "Wirtschaftingenieure (D2)"
-#: apps/member/models.py:69
+#: apps/member/models.py:68
msgid "Social sciences (D3)"
msgstr "Sozialwissenschaften (D3)"
-#: apps/member/models.py:70
+#: apps/member/models.py:69
msgid "English (E)"
msgstr "English (E)"
-#: apps/member/models.py:71
+#: apps/member/models.py:70
msgid "External (EXT)"
msgstr "Extern (EXT)"
-#: apps/member/models.py:78
+#: apps/member/models.py:77
msgid "promotion"
msgstr "Promotion"
-#: apps/member/models.py:79
+#: apps/member/models.py:78
msgid "Year of entry to the school (None if not ENS student)"
msgstr "ENS Eintrittjahr (None wenn kein ENS Student)"
-#: apps/member/models.py:83
+#: apps/member/models.py:82
#: apps/member/templates/member/includes/profile_info.html:47
#: apps/registration/templates/registration/future_profile_detail.html:37
#: apps/wei/templates/wei/weimembership_form.html:41
msgid "address"
msgstr "Adresse"
-#: apps/member/models.py:90
+#: apps/member/models.py:89
#: apps/member/templates/member/includes/profile_info.html:50
#: apps/registration/templates/registration/future_profile_detail.html:43
#: apps/wei/templates/wei/weimembership_form.html:47
msgid "paid"
msgstr "bezahlt"
-#: apps/member/models.py:91
+#: apps/member/models.py:90
msgid "Tells if the user receive a salary."
msgstr "User ist bezahlt."
-#: apps/member/models.py:100 apps/treasury/tables.py:143
+#: apps/member/models.py:99 apps/treasury/tables.py:143
msgid "No"
msgstr "Nein"
-#: apps/member/models.py:101
+#: apps/member/models.py:100
msgid "Yes (receive them in french)"
msgstr "Ja (auf Fränzosich)"
-#: apps/member/models.py:102
+#: apps/member/models.py:101
msgid "Yes (receive them in english)"
msgstr "Ja (auf English)"
-#: apps/member/models.py:104
+#: apps/member/models.py:103
msgid ""
"Register on the mailing list to stay informed of the events of the campus (1 "
"mail/week)"
@@ -762,7 +762,7 @@ msgstr ""
"Melden Sie sich auf der Mailingliste an, um über die Ereignisse des Campus "
"informiert zu bleiben (1 Mail / Woche)"
-#: apps/member/models.py:109
+#: apps/member/models.py:108
msgid ""
"Register on the mailing list to stay informed of the sport events of the "
"campus (1 mail/week)"
@@ -770,7 +770,7 @@ msgstr ""
"Melden Sie sich auf der Mailingliste an, um über die Sportereignisse des "
"Campus informiert zu bleiben (1 Mail / Woche)"
-#: apps/member/models.py:114
+#: apps/member/models.py:113
msgid ""
"Register on the mailing list to stay informed of the art events of the "
"campus (1 mail/week)"
@@ -778,31 +778,31 @@ msgstr ""
"Melden Sie sich auf der Mailingliste an, um über die Kunstereignisse des "
"Campus informiert zu bleiben (1 Mail / Woche)"
-#: apps/member/models.py:118
+#: apps/member/models.py:117
msgid "report frequency (in days)"
msgstr "Bericht Frequenz (Tagen)"
-#: apps/member/models.py:123
+#: apps/member/models.py:122
msgid "last report date"
msgstr "letzen Bericht Datum"
-#: apps/member/models.py:128
+#: apps/member/models.py:127
msgid "email confirmed"
msgstr "email bestätigt"
-#: apps/member/models.py:133
+#: apps/member/models.py:132
msgid "registration valid"
msgstr "Anmeldung gültig"
-#: apps/member/models.py:138
+#: apps/member/models.py:137
msgid "VSS charter read"
msgstr "VSS-Charta gelesen"
-#: apps/member/models.py:167 apps/member/models.py:168
+#: apps/member/models.py:142 apps/member/models.py:143
msgid "user profile"
msgstr "Userprofile"
-#: apps/member/models.py:178
+#: apps/member/models.py:177
msgid "Activate your Note Kfet account"
msgstr "Ihre Note Kfet Konto bestätigen"
@@ -815,90 +815,90 @@ msgstr "Ihre Note Kfet Konto bestätigen"
msgid "email"
msgstr "Email"
-#: apps/member/models.py:216
+#: apps/member/models.py:217
msgid "parent club"
msgstr "Urclub"
-#: apps/member/models.py:225
+#: apps/member/models.py:226
msgid "require memberships"
msgstr "erfordern Mitgliedschaft"
-#: apps/member/models.py:226
+#: apps/member/models.py:227
msgid "Uncheck if this club don't require memberships."
msgstr ""
"Deaktivieren Sie diese Option, wenn für diesen Club keine Mitgliedschaft "
"erforderlich ist."
-#: apps/member/models.py:242
+#: apps/member/models.py:243
#: apps/member/templates/member/includes/club_info.html:26
msgid "membership duration"
msgstr "Mitgliedscahftzeit"
-#: apps/member/models.py:243
+#: apps/member/models.py:244
msgid "The longest time (in days) a membership can last (NULL = infinite)."
msgstr "Wie lang am höchsten eine Mitgliedschaft dauern kann."
-#: apps/member/models.py:250
+#: apps/member/models.py:251
#: apps/member/templates/member/includes/club_info.html:16
msgid "membership start"
msgstr "Mitgliedschaftanfangsdatum"
-#: apps/member/models.py:251
+#: apps/member/models.py:252
msgid "Date from which the members can renew their membership."
msgstr "Ab wann kann man sein Mitgliedschaft erneuern."
-#: apps/member/models.py:257
+#: apps/member/models.py:258
#: apps/member/templates/member/includes/club_info.html:21
msgid "membership end"
msgstr "Mitgliedschaftenddatum"
-#: apps/member/models.py:258
+#: apps/member/models.py:259
msgid "Maximal date of a membership, after which members must renew it."
msgstr ""
"Maximales Datum einer Mitgliedschaft, nach dem Mitglieder es erneuern müssen."
-#: apps/member/models.py:293 apps/member/models.py:318
+#: apps/member/models.py:263 apps/member/models.py:319
#: apps/note/models/notes.py:176
msgid "club"
msgstr "Club"
-#: apps/member/models.py:294
+#: apps/member/models.py:264
msgid "clubs"
msgstr "Clubs"
-#: apps/member/models.py:329
+#: apps/member/models.py:330
msgid "membership starts on"
msgstr "Mitgliedschaft fängt an"
-#: apps/member/models.py:333
+#: apps/member/models.py:334
msgid "membership ends on"
msgstr "Mitgliedschaft endet am"
-#: apps/member/models.py:435
-#, python-brace-format
-msgid "The role {role} does not apply to the club {club}."
-msgstr "Die Rolle {role} ist nicht erlaubt für das Club {club}."
+#: apps/member/models.py:343 apps/note/models/transactions.py:385
+msgid "membership"
+msgstr "Mitgliedschaft"
-#: apps/member/models.py:444 apps/member/views.py:712
-msgid "User is already a member of the club"
-msgstr "User ist schon ein Mitglied dieser club"
+#: apps/member/models.py:344
+msgid "memberships"
+msgstr "Mitgliedschaften"
-#: apps/member/models.py:456 apps/member/views.py:721
-msgid "User is not a member of the parent club"
-msgstr "User ist noch nicht Mitglied des Urclubs"
-
-#: apps/member/models.py:509
+#: apps/member/models.py:348
#, python-brace-format
msgid "Membership of {user} for the club {club}"
msgstr "Mitgliedschaft von {user} für das Club {club}"
-#: apps/member/models.py:512 apps/note/models/transactions.py:389
-msgid "membership"
-msgstr "Mitgliedschaft"
+#: apps/member/models.py:367
+#, python-brace-format
+msgid "The role {role} does not apply to the club {club}."
+msgstr "Die Rolle {role} ist nicht erlaubt für das Club {club}."
-#: apps/member/models.py:513
-msgid "memberships"
-msgstr "Mitgliedschaften"
+#: apps/member/models.py:376 apps/member/views.py:712
+msgid "User is already a member of the club"
+msgstr "User ist schon ein Mitglied dieser club"
+
+#: apps/member/models.py:388 apps/member/views.py:721
+msgid "User is not a member of the parent club"
+msgstr "User ist noch nicht Mitglied des Urclubs"
#: apps/member/tables.py:139
msgid "Renew"
@@ -1307,7 +1307,7 @@ msgid "This friendship already exists"
msgstr "Dieser Kredit ist bereits validiert."
#: apps/note/api/serializers.py:198 apps/note/api/serializers.py:204
-#: apps/note/models/transactions.py:228
+#: apps/note/models/transactions.py:190
msgid ""
"The transaction can't be saved since the source note or the destination note "
"is not active."
@@ -1462,18 +1462,18 @@ msgstr "Unerlaublt Alias"
msgid "alias"
msgstr "Alias"
-#: apps/note/models/notes.py:310
+#: apps/note/models/notes.py:315
msgid "Alias is too long."
msgstr "Alias ist zu lang."
-#: apps/note/models/notes.py:313
+#: apps/note/models/notes.py:318
msgid ""
"This alias contains only complex character. Please use a more simple alias."
msgstr ""
"Dieser Alias enthält nur komplexe Zeichen. Bitte verwenden Sie einen "
"einfacheren Alias."
-#: apps/note/models/notes.py:317
+#: apps/note/models/notes.py:322
msgid "An alias with a similar name already exists: {} "
msgstr "Ein Alias mit einem ähnlichen Namen existiert bereits: {} "
@@ -1493,19 +1493,19 @@ msgstr "Transaktionkategorien"
msgid "A template with this name already exist"
msgstr "Eine Vorlage mit diesem Namen ist bereits vorhanden"
-#: apps/note/models/transactions.py:72
+#: apps/note/models/transactions.py:73
msgid "display"
msgstr "Schauen"
-#: apps/note/models/transactions.py:77
+#: apps/note/models/transactions.py:78
msgid "highlighted"
msgstr "hervorgehoben"
-#: apps/note/models/transactions.py:87
+#: apps/note/models/transactions.py:88
msgid "transaction template"
msgstr "Transaktionsvorlage"
-#: apps/note/models/transactions.py:88
+#: apps/note/models/transactions.py:89
msgid "transaction templates"
msgstr "Transaktionsvorlagen"
@@ -1535,7 +1535,7 @@ msgstr "Transaktion"
msgid "transactions"
msgstr "Transaktionen"
-#: apps/note/models/transactions.py:186
+#: apps/note/models/transactions.py:230
#, python-brace-format
msgid ""
"You can't update the {field} on a Transaction. Please invalidate it and "
@@ -1544,7 +1544,7 @@ msgstr ""
"Sie können das {field} einer Transaktion nicht aktualisieren. Bitte machen "
"Sie es ungültig und erstellen Sie eine andere."
-#: apps/note/models/transactions.py:206
+#: apps/note/models/transactions.py:250
msgid ""
"The note balances must be between - 92 233 720 368 547 758.08 € and 92 233 "
"720 368 547 758.07 €."
@@ -1552,34 +1552,42 @@ msgstr ""
"Die Notenguthaben müssen zwischen - 92 233 720 368 547 758,08 € und 92 233 "
"720 368 547 758,07 € liegen."
-#: apps/note/models/transactions.py:277
+#: apps/note/models/transactions.py:274
+msgid "recurrent transaction"
+msgstr "wiederkehrende Transaktion"
+
+#: apps/note/models/transactions.py:275
+msgid "recurrent transactions"
+msgstr "wiederkehrende Transaktionen"
+
+#: apps/note/models/transactions.py:285
msgid ""
"The destination of this transaction must equal to the destination of the "
"template."
msgstr ""
"Der Empfänger dieser Transaktion muss dem Empfänger der Vorlage entsprechen."
-#: apps/note/models/transactions.py:287
+#: apps/note/models/transactions.py:290
msgid "Template"
msgstr "Vorlage"
-#: apps/note/models/transactions.py:290
-msgid "recurrent transaction"
-msgstr "wiederkehrende Transaktion"
-
-#: apps/note/models/transactions.py:291
-msgid "recurrent transactions"
-msgstr "wiederkehrende Transaktionen"
-
-#: apps/note/models/transactions.py:306
+#: apps/note/models/transactions.py:304
msgid "first_name"
msgstr "Vorname"
-#: apps/note/models/transactions.py:311
+#: apps/note/models/transactions.py:309
msgid "bank"
msgstr "Bank"
-#: apps/note/models/transactions.py:328
+#: apps/note/models/transactions.py:314
+msgid "Special transaction"
+msgstr "Sondertransaktion"
+
+#: apps/note/models/transactions.py:315
+msgid "Special transactions"
+msgstr "Sondertranskationen"
+
+#: apps/note/models/transactions.py:335
msgid ""
"A special transaction is only possible between a Note associated to a "
"payment method and a User or a Club"
@@ -1587,25 +1595,17 @@ msgstr ""
"Eine Sondertransaktion ist nur zwischen einer Note, die einer "
"Zahlungsmethode zugeordnet ist, und einem User oder einem Club möglich"
-#: apps/note/models/transactions.py:355 apps/note/models/transactions.py:358
-#: apps/note/models/transactions.py:361 apps/wei/views.py:978
+#: apps/note/models/transactions.py:357 apps/note/models/transactions.py:360
+#: apps/note/models/transactions.py:363 apps/wei/views.py:978
#: apps/wei/views.py:982
msgid "This field is required."
msgstr "Dies ist ein Pflichtfeld."
-#: apps/note/models/transactions.py:367
-msgid "Special transaction"
-msgstr "Sondertransaktion"
-
-#: apps/note/models/transactions.py:368
-msgid "Special transactions"
-msgstr "Sondertranskationen"
-
-#: apps/note/models/transactions.py:384
+#: apps/note/models/transactions.py:380
msgid "membership transaction"
msgstr "Mitgliedschafttransaktion"
-#: apps/note/models/transactions.py:385 apps/treasury/models.py:294
+#: apps/note/models/transactions.py:381 apps/treasury/models.py:300
msgid "membership transactions"
msgstr "Mitgliedschaftttransaktionen"
@@ -1746,7 +1746,7 @@ msgid "Amount"
msgstr "Anzahl"
#: apps/note/templates/note/transaction_form.html:132
-#: apps/treasury/models.py:56
+#: apps/treasury/models.py:60
msgid "Name"
msgstr "Name"
@@ -1838,57 +1838,57 @@ msgstr "Verbräuche"
msgid "You can't see any button."
msgstr "Sie können keine Taste sehen."
-#: apps/note/views.py:208
+#: apps/note/views.py:204
msgid "Search transactions"
msgstr "Transaktion finden"
-#: apps/permission/models.py:89
+#: apps/permission/models.py:31
#, python-brace-format
msgid "Can {type} {model}.{field} in {query}"
msgstr "Kann {type} {model}.{field} in {query}"
-#: apps/permission/models.py:91
+#: apps/permission/models.py:33
#, python-brace-format
msgid "Can {type} {model} in {query}"
msgstr "Kann {type} {model} in {query}"
-#: apps/permission/models.py:104
+#: apps/permission/models.py:103
msgid "rank"
msgstr "Rank"
-#: apps/permission/models.py:117
+#: apps/permission/models.py:113
msgid "permission mask"
msgstr "Berechtigungsmaske"
-#: apps/permission/models.py:118
+#: apps/permission/models.py:114
msgid "permission masks"
msgstr "Berechtigungsmasken"
-#: apps/permission/models.py:124
+#: apps/permission/models.py:123
msgid "add"
msgstr "hinzufügen"
-#: apps/permission/models.py:125
+#: apps/permission/models.py:124
msgid "view"
msgstr "Schauen"
-#: apps/permission/models.py:126
+#: apps/permission/models.py:125
msgid "change"
msgstr "bearbeiten"
-#: apps/permission/models.py:158
+#: apps/permission/models.py:157
msgid "query"
msgstr "Abfrage"
-#: apps/permission/models.py:171
+#: apps/permission/models.py:170
msgid "mask"
msgstr "Maske"
-#: apps/permission/models.py:177
+#: apps/permission/models.py:176
msgid "field"
msgstr "Feld"
-#: apps/permission/models.py:182
+#: apps/permission/models.py:181
msgid ""
"Tells if the permission should be granted even if the membership of the user "
"is expired."
@@ -1896,28 +1896,28 @@ msgstr ""
"Gibt an, ob die Berechtigung auch erteilt werden soll, wenn die "
"Mitgliedschaft des Benutzers abgelaufen ist."
-#: apps/permission/models.py:183
+#: apps/permission/models.py:182
#: apps/permission/templates/permission/all_rights.html:89
msgid "permanent"
msgstr "permanent"
-#: apps/permission/models.py:194
+#: apps/permission/models.py:193
msgid "permission"
msgstr "Berechtigung"
-#: apps/permission/models.py:195 apps/permission/models.py:335
+#: apps/permission/models.py:194 apps/permission/models.py:334
msgid "permissions"
msgstr "Berechtigungen"
-#: apps/permission/models.py:200
+#: apps/permission/models.py:207
msgid "Specifying field applies only to view and change permission types."
msgstr "Angabefeld gilt nur zum Anzeigen und Ändern von Berechtigungstypen."
-#: apps/permission/models.py:340
+#: apps/permission/models.py:339
msgid "for club"
msgstr "Für Club"
-#: apps/permission/models.py:351 apps/permission/models.py:352
+#: apps/permission/models.py:347 apps/permission/models.py:348
msgid "role permissions"
msgstr "Berechtigung Rollen"
@@ -2064,10 +2064,6 @@ msgstr "BDE Mitglieder werden"
msgid "Join Kfet Club"
msgstr "Kfet Mitglieder werden"
-#: apps/registration/forms.py:123
-msgid "Join BDA Club"
-msgstr "BDA Mitglieder werden"
-
#: apps/registration/templates/registration/email_validation_complete.html:15
msgid "Your email have successfully been validated."
msgstr "Ihre E-Mail wurde erfolgreich validiert."
@@ -2230,7 +2226,7 @@ msgstr "Ungültige Vorregistrierung"
msgid "Treasury"
msgstr "Quaestor"
-#: apps/treasury/forms.py:26 apps/treasury/models.py:95
+#: apps/treasury/forms.py:26 apps/treasury/models.py:112
#: apps/treasury/templates/treasury/invoice_form.html:22
msgid "This invoice is locked and can no longer be edited."
msgstr "Diese Rechnung ist gesperrt und kann nicht mehr bearbeitet werden."
@@ -2243,7 +2239,7 @@ msgstr "Überweisung ist bereits geschlossen."
msgid "You can't change the type of the remittance."
msgstr "Sie können die Art der Überweisung nicht ändern."
-#: apps/treasury/forms.py:125 apps/treasury/models.py:269
+#: apps/treasury/forms.py:125 apps/treasury/models.py:275
#: apps/treasury/tables.py:97 apps/treasury/tables.py:105
#: apps/treasury/templates/treasury/invoice_list.html:16
#: apps/treasury/templates/treasury/remittance_list.html:16
@@ -2255,7 +2251,7 @@ msgstr "Überweisung"
msgid "No attached remittance"
msgstr "Keine beigefügte Überweisung"
-#: apps/treasury/models.py:26
+#: apps/treasury/models.py:25
msgid "Invoice identifier"
msgstr "Rechnungskennung"
@@ -2263,112 +2259,138 @@ msgstr "Rechnungskennung"
msgid "BDE"
msgstr "BDE"
-#: apps/treasury/models.py:47
+#: apps/treasury/models.py:46
+#, fuzzy
+#| msgid "location"
+msgid "Quotation"
+msgstr "Ort"
+
+#: apps/treasury/models.py:51
msgid "Object"
msgstr "Objekt"
-#: apps/treasury/models.py:51
+#: apps/treasury/models.py:55
msgid "Description"
msgstr "Beschreibung"
-#: apps/treasury/models.py:60
+#: apps/treasury/models.py:64
msgid "Address"
msgstr "Adresse"
-#: apps/treasury/models.py:65 apps/treasury/models.py:195
+#: apps/treasury/models.py:69 apps/treasury/models.py:202
msgid "Date"
msgstr "Datum"
-#: apps/treasury/models.py:69
+#: apps/treasury/models.py:75
+#, fuzzy
+#| msgid "end date"
+msgid "Payment date"
+msgstr "Abschlussdatum"
+
+#: apps/treasury/models.py:79
msgid "Acquitted"
msgstr "Bezahlt"
-#: apps/treasury/models.py:74
+#: apps/treasury/models.py:84
msgid "Locked"
msgstr "Gesperrt"
-#: apps/treasury/models.py:75
+#: apps/treasury/models.py:85
msgid "An invoice can't be edited when it is locked."
msgstr "Eine Rechnung kann nicht bearbeitet werden, wenn sie gesperrt ist."
-#: apps/treasury/models.py:81
+#: apps/treasury/models.py:91
msgid "tex source"
msgstr "Tex Quelle"
-#: apps/treasury/models.py:115 apps/treasury/models.py:131
+#: apps/treasury/models.py:95 apps/treasury/models.py:140
msgid "invoice"
msgstr "Rechnung"
-#: apps/treasury/models.py:116
+#: apps/treasury/models.py:96
msgid "invoices"
msgstr "Rechnungen"
-#: apps/treasury/models.py:119
+#: apps/treasury/models.py:99
#, python-brace-format
msgid "Invoice #{id}"
msgstr "Rechnung #{id}"
-#: apps/treasury/models.py:136
+#: apps/treasury/models.py:145
msgid "Designation"
msgstr "Bezeichnung"
-#: apps/treasury/models.py:142
+#: apps/treasury/models.py:151
msgid "Quantity"
msgstr "Qualität"
-#: apps/treasury/models.py:147
+#: apps/treasury/models.py:156
msgid "Unit price"
msgstr "Einzelpreis"
-#: apps/treasury/models.py:163
+#: apps/treasury/models.py:160
msgid "product"
msgstr "Produkt"
-#: apps/treasury/models.py:164
+#: apps/treasury/models.py:161
msgid "products"
msgstr "Produkten"
-#: apps/treasury/models.py:184
+#: apps/treasury/models.py:189
msgid "remittance type"
msgstr "Überweisungstyp"
-#: apps/treasury/models.py:185
+#: apps/treasury/models.py:190
msgid "remittance types"
msgstr "Überweisungstypen"
-#: apps/treasury/models.py:206
+#: apps/treasury/models.py:213
msgid "Comment"
msgstr "Kommentar"
-#: apps/treasury/models.py:211
+#: apps/treasury/models.py:218
msgid "Closed"
msgstr "Geschlossen"
-#: apps/treasury/models.py:215
+#: apps/treasury/models.py:222
msgid "remittance"
msgstr "Überweisung"
-#: apps/treasury/models.py:216
+#: apps/treasury/models.py:223
msgid "remittances"
msgstr "Überweisungen"
-#: apps/treasury/models.py:249
+#: apps/treasury/models.py:226
msgid "Remittance #{:d}: {}"
msgstr "Überweisung #{:d}:{}"
-#: apps/treasury/models.py:273
+#: apps/treasury/models.py:279
msgid "special transaction proxy"
msgstr "spezielle Transaktion Proxy"
-#: apps/treasury/models.py:274
+#: apps/treasury/models.py:280
msgid "special transaction proxies"
msgstr "spezielle Transaktion Proxies"
-#: apps/treasury/models.py:300
+#: apps/treasury/models.py:306
msgid "credit transaction"
msgstr "Kredit Transaktion"
-#: apps/treasury/models.py:432
+#: apps/treasury/models.py:311
+#: apps/treasury/templates/treasury/sogecredit_detail.html:10
+msgid "Credit from the Société générale"
+msgstr "Kredit von der Société générale"
+
+#: apps/treasury/models.py:312
+msgid "Credits from the Société générale"
+msgstr "Krediten von der Société générale"
+
+#: apps/treasury/models.py:315
+#, python-brace-format
+msgid "Soge credit for {user}"
+msgstr "Kredit von der Société générale für {user}"
+
+#: apps/treasury/models.py:445
msgid ""
"This user doesn't have enough money to pay the memberships with its note. "
"Please ask her/him to credit the note before invalidating this credit."
@@ -2376,20 +2398,6 @@ msgstr ""
"Dieser Benutzer hat nicht genug Geld, um die Mitgliedschaften mit seiner "
"Note zu bezahlen."
-#: apps/treasury/models.py:452
-#: apps/treasury/templates/treasury/sogecredit_detail.html:10
-msgid "Credit from the Société générale"
-msgstr "Kredit von der Société générale"
-
-#: apps/treasury/models.py:453
-msgid "Credits from the Société générale"
-msgstr "Krediten von der Société générale"
-
-#: apps/treasury/models.py:456
-#, python-brace-format
-msgid "Soge credit for {user}"
-msgstr "Kredit von der Société générale für {user}"
-
#: apps/treasury/tables.py:20
msgid "Invoice #{:d}"
msgstr "Rechnung #{:d}"
@@ -2638,8 +2646,8 @@ msgstr "Kreditliste von Société générale"
msgid "Manage credits from the Société générale"
msgstr "Krediten von der Société générale handeln"
-#: apps/wei/apps.py:10 apps/wei/models.py:50 apps/wei/models.py:51
-#: apps/wei/models.py:62 apps/wei/models.py:180
+#: apps/wei/apps.py:10 apps/wei/models.py:37 apps/wei/models.py:38
+#: apps/wei/models.py:62 apps/wei/models.py:178
#: note_kfet/templates/base.html:102
msgid "WEI"
msgstr "WEI"
@@ -2649,7 +2657,7 @@ msgid "The selected user is not validated. Please validate its account first"
msgstr ""
#: apps/wei/forms/registration.py:59 apps/wei/models.py:126
-#: apps/wei/models.py:326
+#: apps/wei/models.py:324
msgid "bus"
msgstr "Bus"
@@ -2675,7 +2683,7 @@ msgstr ""
"Buschef, freies Elektron)"
#: apps/wei/forms/registration.py:75 apps/wei/forms/registration.py:85
-#: apps/wei/models.py:161
+#: apps/wei/models.py:160
msgid "WEI Roles"
msgstr "WEI Rollen"
@@ -2717,11 +2725,11 @@ msgstr "Umfrage Infos"
msgid "Information about the survey for new members, encoded in JSON"
msgstr "Informationen zur Umfrage für neue Mitglieder, codiert in JSON"
-#: apps/wei/models.py:113
+#: apps/wei/models.py:88
msgid "Bus"
msgstr "Bus"
-#: apps/wei/models.py:114 apps/wei/templates/wei/weiclub_detail.html:51
+#: apps/wei/models.py:89 apps/wei/templates/wei/weiclub_detail.html:51
msgid "Buses"
msgstr "Buses"
@@ -2733,89 +2741,89 @@ msgstr "Farbe"
msgid "The color of the T-Shirt, stored with its number equivalent"
msgstr "Die Farbe des T-Shirts, gespeichert mit der entsprechenden Nummer"
-#: apps/wei/models.py:150
+#: apps/wei/models.py:147
msgid "Bus team"
msgstr "Bus Team"
-#: apps/wei/models.py:151
+#: apps/wei/models.py:148
msgid "Bus teams"
msgstr "Bus Teams"
-#: apps/wei/models.py:160
+#: apps/wei/models.py:159
msgid "WEI Role"
msgstr "WEI Rolle"
-#: apps/wei/models.py:185
+#: apps/wei/models.py:183
msgid "Credit from Société générale"
msgstr "Kredit von der Société générale"
-#: apps/wei/models.py:190
+#: apps/wei/models.py:188
msgid "Caution check given"
msgstr "Caution check given"
-#: apps/wei/models.py:194 apps/wei/templates/wei/weimembership_form.html:64
+#: apps/wei/models.py:192 apps/wei/templates/wei/weimembership_form.html:64
msgid "birth date"
msgstr "Geburtsdatum"
-#: apps/wei/models.py:200 apps/wei/models.py:210
+#: apps/wei/models.py:198 apps/wei/models.py:208
msgid "Male"
msgstr "Männlich"
-#: apps/wei/models.py:201 apps/wei/models.py:211
+#: apps/wei/models.py:199 apps/wei/models.py:209
msgid "Female"
msgstr "Weiblich"
-#: apps/wei/models.py:202
+#: apps/wei/models.py:200
msgid "Non binary"
msgstr "Nicht binär"
-#: apps/wei/models.py:204 apps/wei/templates/wei/attribute_bus_1A.html:22
+#: apps/wei/models.py:202 apps/wei/templates/wei/attribute_bus_1A.html:22
#: apps/wei/templates/wei/weimembership_form.html:55
msgid "gender"
msgstr "Geschlecht"
-#: apps/wei/models.py:212
+#: apps/wei/models.py:210
msgid "Unisex"
msgstr "Unisex"
-#: apps/wei/models.py:215 apps/wei/templates/wei/weimembership_form.html:58
+#: apps/wei/models.py:213 apps/wei/templates/wei/weimembership_form.html:58
msgid "clothing cut"
msgstr "Kleidung Schnitt"
-#: apps/wei/models.py:228 apps/wei/templates/wei/weimembership_form.html:61
+#: apps/wei/models.py:226 apps/wei/templates/wei/weimembership_form.html:61
msgid "clothing size"
msgstr "Kleidergröße"
-#: apps/wei/models.py:234 apps/wei/templates/wei/attribute_bus_1A.html:28
+#: apps/wei/models.py:232 apps/wei/templates/wei/attribute_bus_1A.html:28
#: apps/wei/templates/wei/weimembership_form.html:67
msgid "health issues"
msgstr "Gesundheitsprobleme"
-#: apps/wei/models.py:239 apps/wei/templates/wei/weimembership_form.html:70
+#: apps/wei/models.py:237 apps/wei/templates/wei/weimembership_form.html:70
msgid "emergency contact name"
msgstr "Notfall-Kontakt"
-#: apps/wei/models.py:240
+#: apps/wei/models.py:238
msgid "The emergency contact must not be a WEI participant"
msgstr "Der Notfallkontakt darf kein WEI-Teilnehmer sein"
-#: apps/wei/models.py:245 apps/wei/templates/wei/weimembership_form.html:73
+#: apps/wei/models.py:243 apps/wei/templates/wei/weimembership_form.html:73
msgid "emergency contact phone"
msgstr "Notfallkontakttelefon"
-#: apps/wei/models.py:250 apps/wei/templates/wei/weimembership_form.html:52
+#: apps/wei/models.py:248 apps/wei/templates/wei/weimembership_form.html:52
msgid "first year"
msgstr "Erste Jahr"
-#: apps/wei/models.py:251
+#: apps/wei/models.py:249
msgid "Tells if the user is new in the school."
msgstr "Gibt an, ob der USer neu in der Schule ist."
-#: apps/wei/models.py:256
+#: apps/wei/models.py:254
msgid "registration information"
msgstr "Registrierung Detailen"
-#: apps/wei/models.py:257
+#: apps/wei/models.py:255
msgid ""
"Information about the registration (buses for old members, survey for the "
"new members), encoded in JSON"
@@ -2823,27 +2831,27 @@ msgstr ""
"Informationen zur Registrierung (Busse für alte Mitglieder, Umfrage für neue "
"Mitglieder), verschlüsselt in JSON"
-#: apps/wei/models.py:315
+#: apps/wei/models.py:261
msgid "WEI User"
msgstr "WEI User"
-#: apps/wei/models.py:316
+#: apps/wei/models.py:262
msgid "WEI Users"
msgstr "WEI Users"
-#: apps/wei/models.py:336
+#: apps/wei/models.py:334
msgid "team"
msgstr "Team"
-#: apps/wei/models.py:346
+#: apps/wei/models.py:344
msgid "WEI registration"
msgstr "WEI Registrierung"
-#: apps/wei/models.py:350
+#: apps/wei/models.py:348
msgid "WEI membership"
msgstr "WEI Mitgliedschaft"
-#: apps/wei/models.py:351
+#: apps/wei/models.py:349
msgid "WEI memberships"
msgstr "WEI Mitgliedschaften"
@@ -3667,6 +3675,9 @@ msgstr ""
"müssen Ihre E-Mail-Adresse auch überprüfen, indem Sie dem Link folgen, den "
"Sie erhalten haben."
+#~ msgid "Join BDA Club"
+#~ msgstr "BDA Mitglieder werden"
+
#, fuzzy
#~| msgid "You already opened an account in the Société générale."
#~ msgid ""
diff --git a/locale/es/LC_MESSAGES/django.po b/locale/es/LC_MESSAGES/django.po
index fe8e4950..a5482763 100644
--- a/locale/es/LC_MESSAGES/django.po
+++ b/locale/es/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-10-25 19:12+0200\n"
+"POT-Creation-Date: 2024-03-22 00:33+0100\n"
"PO-Revision-Date: 2022-04-11 23:12+0200\n"
"Last-Translator: bleizi \n"
"Language-Team: \n"
@@ -18,7 +18,7 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 3.0.1\n"
-#: apps/activity/apps.py:10 apps/activity/models.py:151
+#: apps/activity/apps.py:10 apps/activity/models.py:127
#: apps/activity/models.py:167
msgid "activity"
msgstr "actividad"
@@ -27,37 +27,37 @@ msgstr "actividad"
msgid "The note of this club is inactive."
msgstr "La note del club está inactiva."
-#: apps/activity/forms.py:41 apps/activity/models.py:132
+#: apps/activity/forms.py:41 apps/activity/models.py:140
msgid "The end date must be after the start date."
msgstr "La fecha final tiene que ser después de la fecha de inicio."
-#: apps/activity/forms.py:82 apps/activity/models.py:270
+#: apps/activity/forms.py:82 apps/activity/models.py:269
msgid "You can't invite someone once the activity is started."
msgstr "No se puede invitar a alguien una vez que arrancó la actividad."
-#: apps/activity/forms.py:85 apps/activity/models.py:273
+#: apps/activity/forms.py:85 apps/activity/models.py:272
msgid "This activity is not validated yet."
msgstr "Esta actividad no fue validada por ahora."
-#: apps/activity/forms.py:95 apps/activity/models.py:281
+#: apps/activity/forms.py:95 apps/activity/models.py:280
msgid "This person has been already invited 5 times this year."
msgstr "Esta persona ya fue invitada 5 veces este año."
-#: apps/activity/forms.py:99 apps/activity/models.py:285
+#: apps/activity/forms.py:99 apps/activity/models.py:284
msgid "This person is already invited."
msgstr "Esta persona ya está invitada."
-#: apps/activity/forms.py:103 apps/activity/models.py:289
+#: apps/activity/forms.py:103 apps/activity/models.py:288
msgid "You can't invite more than 3 people to this activity."
msgstr "Usted no puede invitar más de 3 persona a esta actividad."
#: apps/activity/models.py:28 apps/activity/models.py:63
-#: apps/member/models.py:204
+#: apps/member/models.py:203
#: apps/member/templates/member/includes/club_info.html:4
#: apps/member/templates/member/includes/profile_info.html:4
#: apps/note/models/notes.py:263 apps/note/models/transactions.py:26
-#: apps/note/models/transactions.py:46 apps/note/models/transactions.py:301
-#: apps/permission/models.py:330
+#: apps/note/models/transactions.py:46 apps/note/models/transactions.py:299
+#: apps/permission/models.py:329
#: apps/registration/templates/registration/future_profile_detail.html:16
#: apps/wei/models.py:67 apps/wei/models.py:131 apps/wei/tables.py:282
#: apps/wei/templates/wei/base.html:26
@@ -93,8 +93,8 @@ msgstr "tipos de actividad"
#: apps/activity/models.py:68
#: apps/activity/templates/activity/includes/activity_info.html:19
-#: apps/note/models/transactions.py:81 apps/permission/models.py:110
-#: apps/permission/models.py:189 apps/wei/models.py:78 apps/wei/models.py:142
+#: apps/note/models/transactions.py:82 apps/permission/models.py:109
+#: apps/permission/models.py:188 apps/wei/models.py:78 apps/wei/models.py:142
msgid "description"
msgstr "descripción"
@@ -108,14 +108,14 @@ msgstr "Lugar donde se organiza la actividad, por ejemplo la Kfet."
#: apps/activity/models.py:83
#: apps/activity/templates/activity/includes/activity_info.html:22
-#: apps/note/models/notes.py:207 apps/note/models/transactions.py:66
-#: apps/permission/models.py:164
+#: apps/note/models/notes.py:207 apps/note/models/transactions.py:67
+#: apps/permission/models.py:163
msgid "type"
msgstr "tipo"
-#: apps/activity/models.py:89 apps/logs/models.py:22 apps/member/models.py:312
-#: apps/note/models/notes.py:148 apps/treasury/models.py:287
-#: apps/wei/models.py:173 apps/wei/templates/wei/attribute_bus_1A.html:13
+#: apps/activity/models.py:89 apps/logs/models.py:22 apps/member/models.py:313
+#: apps/note/models/notes.py:148 apps/treasury/models.py:293
+#: apps/wei/models.py:171 apps/wei/templates/wei/attribute_bus_1A.html:13
#: apps/wei/templates/wei/survey.html:15
msgid "user"
msgstr "usuario"
@@ -161,7 +161,7 @@ msgstr "válido"
msgid "open"
msgstr "abierto"
-#: apps/activity/models.py:152
+#: apps/activity/models.py:128
msgid "activities"
msgstr "actividades"
@@ -225,11 +225,11 @@ msgstr "nombre"
msgid "inviter"
msgstr "huésped"
-#: apps/activity/models.py:297
+#: apps/activity/models.py:256
msgid "guest"
msgstr "invitado"
-#: apps/activity/models.py:298
+#: apps/activity/models.py:257
msgid "guests"
msgstr "invitados"
@@ -257,7 +257,7 @@ msgstr "Entrado el "
msgid "remove"
msgstr "quitar"
-#: apps/activity/tables.py:82 apps/note/forms.py:68 apps/treasury/models.py:201
+#: apps/activity/tables.py:82 apps/note/forms.py:68 apps/treasury/models.py:208
msgid "Type"
msgstr "Tipo"
@@ -291,7 +291,7 @@ msgid "Guest deleted"
msgstr "Invitados suprimidos"
#: apps/activity/templates/activity/activity_entry.html:14
-#: apps/note/models/transactions.py:257
+#: apps/note/models/transactions.py:261
#: apps/note/templates/note/transaction_form.html:17
#: apps/note/templates/note/transaction_form.html:152
#: note_kfet/templates/base.html:72
@@ -299,13 +299,13 @@ msgid "Transfer"
msgstr "Transferencia"
#: apps/activity/templates/activity/activity_entry.html:18
-#: apps/note/models/transactions.py:317
+#: apps/note/models/transactions.py:324
#: apps/note/templates/note/transaction_form.html:22
msgid "Credit"
msgstr "Crédito"
#: apps/activity/templates/activity/activity_entry.html:21
-#: apps/note/models/transactions.py:317
+#: apps/note/models/transactions.py:324
#: apps/note/templates/note/transaction_form.html:26
msgid "Debit"
msgstr "Débito"
@@ -444,7 +444,7 @@ msgstr "Logs"
msgid "IP Address"
msgstr "Dirección IP"
-#: apps/logs/models.py:36 apps/permission/models.py:134
+#: apps/logs/models.py:36 apps/permission/models.py:133
msgid "model"
msgstr "modelo"
@@ -465,7 +465,7 @@ msgid "create"
msgstr "crear"
#: apps/logs/models.py:65 apps/note/tables.py:230 apps/note/tables.py:277
-#: apps/permission/models.py:127 apps/treasury/tables.py:38
+#: apps/permission/models.py:126 apps/treasury/tables.py:38
#: apps/wei/tables.py:74
msgid "delete"
msgstr "suprimir"
@@ -479,37 +479,37 @@ msgid "timestamp"
msgstr "fecha"
#: apps/logs/models.py:80
-msgid "Logs cannot be destroyed."
-msgstr "No se puede suprimir los logs."
-
-#: apps/logs/models.py:83
msgid "changelog"
msgstr "diario de cambio"
-#: apps/logs/models.py:84
+#: apps/logs/models.py:81
msgid "changelogs"
msgstr "diario de cambios"
-#: apps/logs/models.py:87
+#: apps/logs/models.py:84
#, python-brace-format
msgid "Changelog of type \"{action}\" for model {model} at {timestamp}"
msgstr ""
-#: apps/member/admin.py:50 apps/member/models.py:231
+#: apps/logs/models.py:88
+msgid "Logs cannot be destroyed."
+msgstr "No se puede suprimir los logs."
+
+#: apps/member/admin.py:50 apps/member/models.py:232
#: apps/member/templates/member/includes/club_info.html:34
msgid "membership fee (paid students)"
msgstr "pago de afiliación (estudiantes pagados)"
-#: apps/member/admin.py:51 apps/member/models.py:236
+#: apps/member/admin.py:51 apps/member/models.py:237
#: apps/member/templates/member/includes/club_info.html:37
msgid "membership fee (unpaid students)"
msgstr "pago de afiliación (estudiantes no pagados)"
-#: apps/member/admin.py:65 apps/member/models.py:324
+#: apps/member/admin.py:65 apps/member/models.py:325
msgid "roles"
msgstr "papel"
-#: apps/member/admin.py:66 apps/member/models.py:338
+#: apps/member/admin.py:66 apps/member/models.py:339
msgid "fee"
msgstr "pago"
@@ -623,132 +623,132 @@ msgstr "sal"
msgid "hash"
msgstr "hash"
-#: apps/member/models.py:38
+#: apps/member/models.py:37
#: apps/member/templates/member/includes/profile_info.html:43
#: apps/registration/templates/registration/future_profile_detail.html:40
#: apps/wei/templates/wei/weimembership_form.html:44
msgid "phone number"
msgstr "número de teléfono"
-#: apps/member/models.py:45
+#: apps/member/models.py:44
#: apps/member/templates/member/includes/profile_info.html:37
#: apps/registration/templates/registration/future_profile_detail.html:34
#: apps/wei/templates/wei/weimembership_form.html:38
msgid "section"
msgstr "sección"
-#: apps/member/models.py:46
+#: apps/member/models.py:45
msgid "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\""
msgstr "i.e. \"1A0\", \"9A♥\", \"SAPHIRE\""
-#: apps/member/models.py:54 apps/wei/templates/wei/attribute_bus_1A.html:25
+#: apps/member/models.py:53 apps/wei/templates/wei/attribute_bus_1A.html:25
#: apps/wei/templates/wei/weimembership_form.html:32
msgid "department"
msgstr "departamento"
-#: apps/member/models.py:56
+#: apps/member/models.py:55
msgid "Informatics (A0)"
msgstr "Informática (A0)"
-#: apps/member/models.py:57
+#: apps/member/models.py:56
msgid "Mathematics (A1)"
msgstr "Matemáticas (A1)"
-#: apps/member/models.py:58
+#: apps/member/models.py:57
msgid "Physics (A2)"
msgstr "Física (A2)"
-#: apps/member/models.py:59
+#: apps/member/models.py:58
msgid "Applied physics (A'2)"
msgstr "Física aplicada (A'2)"
-#: apps/member/models.py:60
+#: apps/member/models.py:59
msgid "Chemistry (A''2)"
msgstr "Química (A''2)"
-#: apps/member/models.py:61
+#: apps/member/models.py:60
msgid "Biology (A3)"
msgstr "Biología (A3)"
-#: apps/member/models.py:62
+#: apps/member/models.py:61
msgid "SAPHIRE (B1234)"
msgstr "SAPHIRE (B1234)"
-#: apps/member/models.py:63
+#: apps/member/models.py:62
msgid "Mechanics (B1)"
msgstr "Mecánica (B1)"
-#: apps/member/models.py:64
+#: apps/member/models.py:63
msgid "Civil engineering (B2)"
msgstr "Ingeniería civil (B2)"
-#: apps/member/models.py:65
+#: apps/member/models.py:64
msgid "Mechanical engineering (B3)"
msgstr "Ingeniería mecánica (B3)"
-#: apps/member/models.py:66
+#: apps/member/models.py:65
msgid "EEA (B4)"
msgstr "EEA (B4)"
-#: apps/member/models.py:67
+#: apps/member/models.py:66
msgid "Design (C)"
msgstr "Design (C)"
-#: apps/member/models.py:68
+#: apps/member/models.py:67
msgid "Economy-management (D2)"
msgstr "Economía-gestión (D2)"
-#: apps/member/models.py:69
+#: apps/member/models.py:68
msgid "Social sciences (D3)"
msgstr "Ciencias sociales (D3)"
-#: apps/member/models.py:70
+#: apps/member/models.py:69
msgid "English (E)"
msgstr "Inglés (E)"
-#: apps/member/models.py:71
+#: apps/member/models.py:70
msgid "External (EXT)"
msgstr "Extern@ (EXT)"
-#: apps/member/models.py:78
+#: apps/member/models.py:77
msgid "promotion"
msgstr "promoción"
-#: apps/member/models.py:79
+#: apps/member/models.py:78
msgid "Year of entry to the school (None if not ENS student)"
msgstr "Año de ingreso en la escuela (None si no un alumn@ ENS)"
-#: apps/member/models.py:83
+#: apps/member/models.py:82
#: apps/member/templates/member/includes/profile_info.html:47
#: apps/registration/templates/registration/future_profile_detail.html:37
#: apps/wei/templates/wei/weimembership_form.html:41
msgid "address"
msgstr "dirección"
-#: apps/member/models.py:90
+#: apps/member/models.py:89
#: apps/member/templates/member/includes/profile_info.html:50
#: apps/registration/templates/registration/future_profile_detail.html:43
#: apps/wei/templates/wei/weimembership_form.html:47
msgid "paid"
msgstr "pagado"
-#: apps/member/models.py:91
+#: apps/member/models.py:90
msgid "Tells if the user receive a salary."
msgstr "Indica si el usuario percibe un salario."
-#: apps/member/models.py:100 apps/treasury/tables.py:143
+#: apps/member/models.py:99 apps/treasury/tables.py:143
msgid "No"
msgstr "No"
-#: apps/member/models.py:101
+#: apps/member/models.py:100
msgid "Yes (receive them in french)"
msgstr "Si (recibirles en francés)"
-#: apps/member/models.py:102
+#: apps/member/models.py:101
msgid "Yes (receive them in english)"
msgstr "Si (recibirles en inglés)"
-#: apps/member/models.py:104
+#: apps/member/models.py:103
msgid ""
"Register on the mailing list to stay informed of the events of the campus (1 "
"mail/week)"
@@ -756,7 +756,7 @@ msgstr ""
"Registrar el la lista de difusión de correo electrónico para quedarse "
"informado de los eventos del campus (1 correo por semana)"
-#: apps/member/models.py:109
+#: apps/member/models.py:108
msgid ""
"Register on the mailing list to stay informed of the sport events of the "
"campus (1 mail/week)"
@@ -764,7 +764,7 @@ msgstr ""
"Registrar el la lista de difusión de correo electrónico para quedarse "
"informado de los eventos deportivos del campus (1 correo por semana)"
-#: apps/member/models.py:114
+#: apps/member/models.py:113
msgid ""
"Register on the mailing list to stay informed of the art events of the "
"campus (1 mail/week)"
@@ -772,31 +772,31 @@ msgstr ""
"Registrar el la lista de difusión de correo electrónico para quedarse "
"informado de los eventos artísticos del campus (1 correo por semana)"
-#: apps/member/models.py:118
+#: apps/member/models.py:117
msgid "report frequency (in days)"
msgstr "frecuencia de los informes (en días)"
-#: apps/member/models.py:123
+#: apps/member/models.py:122
msgid "last report date"
msgstr "fecha del último informe"
-#: apps/member/models.py:128
+#: apps/member/models.py:127
msgid "email confirmed"
msgstr "correo electrónico confirmado"
-#: apps/member/models.py:133
+#: apps/member/models.py:132
msgid "registration valid"
msgstr "registración valida"
-#: apps/member/models.py:138
+#: apps/member/models.py:137
msgid "VSS charter read"
msgstr "Carta VSS leída"
-#: apps/member/models.py:167 apps/member/models.py:168
+#: apps/member/models.py:142 apps/member/models.py:143
msgid "user profile"
msgstr "perfil usuario"
-#: apps/member/models.py:178
+#: apps/member/models.py:177
msgid "Activate your Note Kfet account"
msgstr "Active su cuenta Note Kfet"
@@ -809,89 +809,89 @@ msgstr "Active su cuenta Note Kfet"
msgid "email"
msgstr "correo electrónico"
-#: apps/member/models.py:216
+#: apps/member/models.py:217
msgid "parent club"
msgstr "club pariente"
-#: apps/member/models.py:225
+#: apps/member/models.py:226
msgid "require memberships"
msgstr "necesita afiliaciones"
-#: apps/member/models.py:226
+#: apps/member/models.py:227
msgid "Uncheck if this club don't require memberships."
msgstr "Desmarcar si este club no usa afiliaciones."
-#: apps/member/models.py:242
+#: apps/member/models.py:243
#: apps/member/templates/member/includes/club_info.html:26
msgid "membership duration"
msgstr "duración de la afiliación"
-#: apps/member/models.py:243
+#: apps/member/models.py:244
msgid "The longest time (in days) a membership can last (NULL = infinite)."
msgstr "La duración máxima (en días) de una afiliación (NULL = infinito)."
-#: apps/member/models.py:250
+#: apps/member/models.py:251
#: apps/member/templates/member/includes/club_info.html:16
msgid "membership start"
msgstr "inicio de la afiliación"
-#: apps/member/models.py:251
+#: apps/member/models.py:252
msgid "Date from which the members can renew their membership."
msgstr "Fecha a partir de la cual los miembros pueden prorrogar su afiliación."
-#: apps/member/models.py:257
+#: apps/member/models.py:258
#: apps/member/templates/member/includes/club_info.html:21
msgid "membership end"
msgstr "fin de la afiliación"
-#: apps/member/models.py:258
+#: apps/member/models.py:259
msgid "Maximal date of a membership, after which members must renew it."
msgstr ""
"Ultima fecha de una afiliación, después de la cual los miembros tienen que "
"prorrogarla."
-#: apps/member/models.py:293 apps/member/models.py:318
+#: apps/member/models.py:263 apps/member/models.py:319
#: apps/note/models/notes.py:176
msgid "club"
msgstr "club"
-#: apps/member/models.py:294
+#: apps/member/models.py:264
msgid "clubs"
msgstr "clubs"
-#: apps/member/models.py:329
+#: apps/member/models.py:330
msgid "membership starts on"
msgstr "afiliación empezá el"
-#: apps/member/models.py:333
+#: apps/member/models.py:334
msgid "membership ends on"
msgstr "afiliación termina el"
-#: apps/member/models.py:435
-#, python-brace-format
-msgid "The role {role} does not apply to the club {club}."
-msgstr "El papel {role} no se encuentra en el club {club}."
+#: apps/member/models.py:343 apps/note/models/transactions.py:385
+msgid "membership"
+msgstr "afiliación"
-#: apps/member/models.py:444 apps/member/views.py:712
-msgid "User is already a member of the club"
-msgstr "Usuario ya esta un miembro del club"
+#: apps/member/models.py:344
+msgid "memberships"
+msgstr "afiliaciones"
-#: apps/member/models.py:456 apps/member/views.py:721
-msgid "User is not a member of the parent club"
-msgstr "Usuario no es un miembro del club pariente"
-
-#: apps/member/models.py:509
+#: apps/member/models.py:348
#, python-brace-format
msgid "Membership of {user} for the club {club}"
msgstr "Afiliación of {user} for the club {club}"
-#: apps/member/models.py:512 apps/note/models/transactions.py:389
-msgid "membership"
-msgstr "afiliación"
+#: apps/member/models.py:367
+#, python-brace-format
+msgid "The role {role} does not apply to the club {club}."
+msgstr "El papel {role} no se encuentra en el club {club}."
-#: apps/member/models.py:513
-msgid "memberships"
-msgstr "afiliaciones"
+#: apps/member/models.py:376 apps/member/views.py:712
+msgid "User is already a member of the club"
+msgstr "Usuario ya esta un miembro del club"
+
+#: apps/member/models.py:388 apps/member/views.py:721
+msgid "User is not a member of the parent club"
+msgstr "Usuario no es un miembro del club pariente"
#: apps/member/tables.py:139
msgid "Renew"
@@ -1293,7 +1293,7 @@ msgid "This friendship already exists"
msgstr "Este crédito ya fue validado."
#: apps/note/api/serializers.py:198 apps/note/api/serializers.py:204
-#: apps/note/models/transactions.py:228
+#: apps/note/models/transactions.py:190
msgid ""
"The transaction can't be saved since the source note or the destination note "
"is not active."
@@ -1449,18 +1449,18 @@ msgstr "Alias inválido"
msgid "alias"
msgstr "alias"
-#: apps/note/models/notes.py:310
+#: apps/note/models/notes.py:315
msgid "Alias is too long."
msgstr "El alias es demasiado largo."
-#: apps/note/models/notes.py:313
+#: apps/note/models/notes.py:318
msgid ""
"This alias contains only complex character. Please use a more simple alias."
msgstr ""
"Este alias solo contiene caracteres complejos. Por favor usa un alias más "
"sencillo."
-#: apps/note/models/notes.py:317
+#: apps/note/models/notes.py:322
msgid "An alias with a similar name already exists: {} "
msgstr "Un alias parecido ya existe : {} "
@@ -1480,19 +1480,19 @@ msgstr "tipos de transacción"
msgid "A template with this name already exist"
msgstr "Un plantilla de transacción con un nombre similar ya existe"
-#: apps/note/models/transactions.py:72
+#: apps/note/models/transactions.py:73
msgid "display"
msgstr "mostrar"
-#: apps/note/models/transactions.py:77
+#: apps/note/models/transactions.py:78
msgid "highlighted"
msgstr "resaltar"
-#: apps/note/models/transactions.py:87
+#: apps/note/models/transactions.py:88
msgid "transaction template"
msgstr "plantilla de transacción"
-#: apps/note/models/transactions.py:88
+#: apps/note/models/transactions.py:89
msgid "transaction templates"
msgstr "plantillas de transacción"
@@ -1522,7 +1522,7 @@ msgstr "transacción"
msgid "transactions"
msgstr "transacciones"
-#: apps/note/models/transactions.py:186
+#: apps/note/models/transactions.py:230
#, python-brace-format
msgid ""
"You can't update the {field} on a Transaction. Please invalidate it and "
@@ -1531,7 +1531,7 @@ msgstr ""
"No se puede cambiar el {field} de una transacción. Por favor invalide esta y "
"cree una nueva."
-#: apps/note/models/transactions.py:206
+#: apps/note/models/transactions.py:250
msgid ""
"The note balances must be between - 92 233 720 368 547 758.08 € and 92 233 "
"720 368 547 758.07 €."
@@ -1539,33 +1539,41 @@ msgstr ""
"El saldo de la note tiene que ser entre - 92 233 720 368 547 758.08 € y 92 "
"233 720 368 547 758.07 €."
-#: apps/note/models/transactions.py:277
+#: apps/note/models/transactions.py:274
+msgid "recurrent transaction"
+msgstr ""
+
+#: apps/note/models/transactions.py:275
+msgid "recurrent transactions"
+msgstr ""
+
+#: apps/note/models/transactions.py:285
msgid ""
"The destination of this transaction must equal to the destination of the "
"template."
msgstr ""
-#: apps/note/models/transactions.py:287
+#: apps/note/models/transactions.py:290
msgid "Template"
msgstr ""
-#: apps/note/models/transactions.py:290
-msgid "recurrent transaction"
-msgstr ""
-
-#: apps/note/models/transactions.py:291
-msgid "recurrent transactions"
-msgstr ""
-
-#: apps/note/models/transactions.py:306
+#: apps/note/models/transactions.py:304
msgid "first_name"
msgstr "nombre"
-#: apps/note/models/transactions.py:311
+#: apps/note/models/transactions.py:309
msgid "bank"
msgstr "banco"
-#: apps/note/models/transactions.py:328
+#: apps/note/models/transactions.py:314
+msgid "Special transaction"
+msgstr "Transacción especial"
+
+#: apps/note/models/transactions.py:315
+msgid "Special transactions"
+msgstr "Transacciones especiales"
+
+#: apps/note/models/transactions.py:335
msgid ""
"A special transaction is only possible between a Note associated to a "
"payment method and a User or a Club"
@@ -1573,25 +1581,17 @@ msgstr ""
"Una transacción especial solo esta disponible entre una note de un modo de "
"pago y un usuario o un club"
-#: apps/note/models/transactions.py:355 apps/note/models/transactions.py:358
-#: apps/note/models/transactions.py:361 apps/wei/views.py:978
+#: apps/note/models/transactions.py:357 apps/note/models/transactions.py:360
+#: apps/note/models/transactions.py:363 apps/wei/views.py:978
#: apps/wei/views.py:982
msgid "This field is required."
msgstr "Este campo es obligatorio."
-#: apps/note/models/transactions.py:367
-msgid "Special transaction"
-msgstr "Transacción especial"
-
-#: apps/note/models/transactions.py:368
-msgid "Special transactions"
-msgstr "Transacciones especiales"
-
-#: apps/note/models/transactions.py:384
+#: apps/note/models/transactions.py:380
msgid "membership transaction"
msgstr "transacción de afiliación"
-#: apps/note/models/transactions.py:385 apps/treasury/models.py:294
+#: apps/note/models/transactions.py:381 apps/treasury/models.py:300
msgid "membership transactions"
msgstr "transacciones de afiliación"
@@ -1730,7 +1730,7 @@ msgid "Amount"
msgstr "Monto"
#: apps/note/templates/note/transaction_form.html:132
-#: apps/treasury/models.py:56
+#: apps/treasury/models.py:60
msgid "Name"
msgstr "Nombre"
@@ -1818,57 +1818,57 @@ msgstr "Consumiciones"
msgid "You can't see any button."
msgstr "Usted no puede ver ningún botón."
-#: apps/note/views.py:208
+#: apps/note/views.py:204
msgid "Search transactions"
msgstr "Buscar transacciones"
-#: apps/permission/models.py:89
+#: apps/permission/models.py:31
#, python-brace-format
msgid "Can {type} {model}.{field} in {query}"
msgstr ""
-#: apps/permission/models.py:91
+#: apps/permission/models.py:33
#, python-brace-format
msgid "Can {type} {model} in {query}"
msgstr ""
-#: apps/permission/models.py:104
+#: apps/permission/models.py:103
msgid "rank"
msgstr "posición"
-#: apps/permission/models.py:117
+#: apps/permission/models.py:113
msgid "permission mask"
msgstr "antifaz de permisos"
-#: apps/permission/models.py:118
+#: apps/permission/models.py:114
msgid "permission masks"
msgstr "antifaces de permisos"
-#: apps/permission/models.py:124
+#: apps/permission/models.py:123
msgid "add"
msgstr "añadir"
-#: apps/permission/models.py:125
+#: apps/permission/models.py:124
msgid "view"
msgstr "ver"
-#: apps/permission/models.py:126
+#: apps/permission/models.py:125
msgid "change"
msgstr "cambiar"
-#: apps/permission/models.py:158
+#: apps/permission/models.py:157
msgid "query"
msgstr "consulta"
-#: apps/permission/models.py:171
+#: apps/permission/models.py:170
msgid "mask"
msgstr "antifaz"
-#: apps/permission/models.py:177
+#: apps/permission/models.py:176
msgid "field"
msgstr "campo"
-#: apps/permission/models.py:182
+#: apps/permission/models.py:181
msgid ""
"Tells if the permission should be granted even if the membership of the user "
"is expired."
@@ -1876,30 +1876,30 @@ msgstr ""
"Indica si el permiso tiene que ser dado aunque la afiliación del usuario "
"terminó."
-#: apps/permission/models.py:183
+#: apps/permission/models.py:182
#: apps/permission/templates/permission/all_rights.html:89
msgid "permanent"
msgstr "permanente"
-#: apps/permission/models.py:194
+#: apps/permission/models.py:193
msgid "permission"
msgstr "permiso"
-#: apps/permission/models.py:195 apps/permission/models.py:335
+#: apps/permission/models.py:194 apps/permission/models.py:334
msgid "permissions"
msgstr "permisos"
-#: apps/permission/models.py:200
+#: apps/permission/models.py:207
msgid "Specifying field applies only to view and change permission types."
msgstr ""
"Especifica el campo interesado, solo funciona para los permisos view y "
"change."
-#: apps/permission/models.py:340
+#: apps/permission/models.py:339
msgid "for club"
msgstr "interesa el club"
-#: apps/permission/models.py:351 apps/permission/models.py:352
+#: apps/permission/models.py:347 apps/permission/models.py:348
msgid "role permissions"
msgstr "permisos por papeles"
@@ -2041,10 +2041,6 @@ msgstr "Afiliarse al club BDE"
msgid "Join Kfet Club"
msgstr "Afiliarse al club Kfet"
-#: apps/registration/forms.py:123
-msgid "Join BDA Club"
-msgstr "Afiliarse al club BDA"
-
#: apps/registration/templates/registration/email_validation_complete.html:15
msgid "Your email have successfully been validated."
msgstr "Su correo electrónico fue validado con éxito."
@@ -2205,7 +2201,7 @@ msgstr "Invalidar la afiliación"
msgid "Treasury"
msgstr "Tesorería"
-#: apps/treasury/forms.py:26 apps/treasury/models.py:95
+#: apps/treasury/forms.py:26 apps/treasury/models.py:112
#: apps/treasury/templates/treasury/invoice_form.html:22
msgid "This invoice is locked and can no longer be edited."
msgstr "Esta factura esta bloqueada y no puede ser modificada."
@@ -2218,7 +2214,7 @@ msgstr "El descuento ya esta cerrado."
msgid "You can't change the type of the remittance."
msgstr "No puede cambiar el tipo de descuento."
-#: apps/treasury/forms.py:125 apps/treasury/models.py:269
+#: apps/treasury/forms.py:125 apps/treasury/models.py:275
#: apps/treasury/tables.py:97 apps/treasury/tables.py:105
#: apps/treasury/templates/treasury/invoice_list.html:16
#: apps/treasury/templates/treasury/remittance_list.html:16
@@ -2230,7 +2226,7 @@ msgstr "Descuento"
msgid "No attached remittance"
msgstr "No hay descuento relacionado"
-#: apps/treasury/models.py:26
+#: apps/treasury/models.py:25
msgid "Invoice identifier"
msgstr "Numero de factura"
@@ -2238,112 +2234,138 @@ msgstr "Numero de factura"
msgid "BDE"
msgstr "BDE"
-#: apps/treasury/models.py:47
+#: apps/treasury/models.py:46
+#, fuzzy
+#| msgid "location"
+msgid "Quotation"
+msgstr "ubicación"
+
+#: apps/treasury/models.py:51
msgid "Object"
msgstr "Asunto"
-#: apps/treasury/models.py:51
+#: apps/treasury/models.py:55
msgid "Description"
msgstr "Descripción"
-#: apps/treasury/models.py:60
+#: apps/treasury/models.py:64
msgid "Address"
msgstr "Dirección"
-#: apps/treasury/models.py:65 apps/treasury/models.py:195
+#: apps/treasury/models.py:69 apps/treasury/models.py:202
msgid "Date"
msgstr "Fecha"
-#: apps/treasury/models.py:69
+#: apps/treasury/models.py:75
+#, fuzzy
+#| msgid "end date"
+msgid "Payment date"
+msgstr "fecha de fin"
+
+#: apps/treasury/models.py:79
msgid "Acquitted"
msgstr "Pagada"
-#: apps/treasury/models.py:74
+#: apps/treasury/models.py:84
msgid "Locked"
msgstr "Bloqueada"
-#: apps/treasury/models.py:75
+#: apps/treasury/models.py:85
msgid "An invoice can't be edited when it is locked."
msgstr "Une factura no puede ser modificada cuando esta bloqueada."
-#: apps/treasury/models.py:81
+#: apps/treasury/models.py:91
msgid "tex source"
msgstr "código fuente TeX"
-#: apps/treasury/models.py:115 apps/treasury/models.py:131
+#: apps/treasury/models.py:95 apps/treasury/models.py:140
msgid "invoice"
msgstr "factura"
-#: apps/treasury/models.py:116
+#: apps/treasury/models.py:96
msgid "invoices"
msgstr "facturas"
-#: apps/treasury/models.py:119
+#: apps/treasury/models.py:99
#, python-brace-format
msgid "Invoice #{id}"
msgstr "Factura n°{id}"
-#: apps/treasury/models.py:136
+#: apps/treasury/models.py:145
msgid "Designation"
msgstr "Designación"
-#: apps/treasury/models.py:142
+#: apps/treasury/models.py:151
msgid "Quantity"
msgstr "Cantidad"
-#: apps/treasury/models.py:147
+#: apps/treasury/models.py:156
msgid "Unit price"
msgstr "Precio unitario"
-#: apps/treasury/models.py:163
+#: apps/treasury/models.py:160
msgid "product"
msgstr "producto"
-#: apps/treasury/models.py:164
+#: apps/treasury/models.py:161
msgid "products"
msgstr "productos"
-#: apps/treasury/models.py:184
+#: apps/treasury/models.py:189
msgid "remittance type"
msgstr "tipo de descuento"
-#: apps/treasury/models.py:185
+#: apps/treasury/models.py:190
msgid "remittance types"
msgstr "tipos de descuentos"
-#: apps/treasury/models.py:206
+#: apps/treasury/models.py:213
msgid "Comment"
msgstr "Comentario"
-#: apps/treasury/models.py:211
+#: apps/treasury/models.py:218
msgid "Closed"
msgstr "Cerrada"
-#: apps/treasury/models.py:215
+#: apps/treasury/models.py:222
msgid "remittance"
msgstr "descuento"
-#: apps/treasury/models.py:216
+#: apps/treasury/models.py:223
msgid "remittances"
msgstr "descuentos"
-#: apps/treasury/models.py:249
+#: apps/treasury/models.py:226
msgid "Remittance #{:d}: {}"
msgstr "Descuento n°{:d} : {}"
-#: apps/treasury/models.py:273
+#: apps/treasury/models.py:279
msgid "special transaction proxy"
msgstr "proxy de transacción especial"
-#: apps/treasury/models.py:274
+#: apps/treasury/models.py:280
msgid "special transaction proxies"
msgstr "proxys de transacciones especiales"
-#: apps/treasury/models.py:300
+#: apps/treasury/models.py:306
msgid "credit transaction"
msgstr "transacción de crédito"
-#: apps/treasury/models.py:432
+#: apps/treasury/models.py:311
+#: apps/treasury/templates/treasury/sogecredit_detail.html:10
+msgid "Credit from the Société générale"
+msgstr "Crédito de la Société Générale"
+
+#: apps/treasury/models.py:312
+msgid "Credits from the Société générale"
+msgstr "Créditos de la Société Générale"
+
+#: apps/treasury/models.py:315
+#, python-brace-format
+msgid "Soge credit for {user}"
+msgstr "Crédito de la Société Générale para {user}"
+
+#: apps/treasury/models.py:445
msgid ""
"This user doesn't have enough money to pay the memberships with its note. "
"Please ask her/him to credit the note before invalidating this credit."
@@ -2352,20 +2374,6 @@ msgstr ""
"afiliaciones. Por favor pídelo acreditar su note antes de invalidar este "
"crédito."
-#: apps/treasury/models.py:452
-#: apps/treasury/templates/treasury/sogecredit_detail.html:10
-msgid "Credit from the Société générale"
-msgstr "Crédito de la Société Générale"
-
-#: apps/treasury/models.py:453
-msgid "Credits from the Société générale"
-msgstr "Créditos de la Société Générale"
-
-#: apps/treasury/models.py:456
-#, python-brace-format
-msgid "Soge credit for {user}"
-msgstr "Crédito de la Société Générale para {user}"
-
#: apps/treasury/tables.py:20
msgid "Invoice #{:d}"
msgstr "Factura n°{:d}"
@@ -2604,8 +2612,8 @@ msgstr "Lista de los créditos de la Société Générale"
msgid "Manage credits from the Société générale"
msgstr "Gestionar los créditos de la Société Générale"
-#: apps/wei/apps.py:10 apps/wei/models.py:50 apps/wei/models.py:51
-#: apps/wei/models.py:62 apps/wei/models.py:180
+#: apps/wei/apps.py:10 apps/wei/models.py:37 apps/wei/models.py:38
+#: apps/wei/models.py:62 apps/wei/models.py:178
#: note_kfet/templates/base.html:102
msgid "WEI"
msgstr "WEI"
@@ -2616,7 +2624,7 @@ msgstr ""
"El usuario seleccionado no ha sido validado. Validar esta cuenta primero"
#: apps/wei/forms/registration.py:59 apps/wei/models.py:126
-#: apps/wei/models.py:326
+#: apps/wei/models.py:324
msgid "bus"
msgstr "bus"
@@ -2642,7 +2650,7 @@ msgstr ""
"electrón libre)"
#: apps/wei/forms/registration.py:75 apps/wei/forms/registration.py:85
-#: apps/wei/models.py:161
+#: apps/wei/models.py:160
msgid "WEI Roles"
msgstr "Papeles en el WEI"
@@ -2684,11 +2692,11 @@ msgstr ""
"Informaciones sobre el cuestionario para los nuevos miembros, registrado en "
"JSON"
-#: apps/wei/models.py:113
+#: apps/wei/models.py:88
msgid "Bus"
msgstr "Bus"
-#: apps/wei/models.py:114 apps/wei/templates/wei/weiclub_detail.html:51
+#: apps/wei/models.py:89 apps/wei/templates/wei/weiclub_detail.html:51
msgid "Buses"
msgstr "Bus"
@@ -2700,89 +2708,89 @@ msgstr "color"
msgid "The color of the T-Shirt, stored with its number equivalent"
msgstr "El color de la camiseta, registrado con su número equivalente"
-#: apps/wei/models.py:150
+#: apps/wei/models.py:147
msgid "Bus team"
msgstr "Equipo de bus"
-#: apps/wei/models.py:151
+#: apps/wei/models.py:148
msgid "Bus teams"
msgstr "Equipos de bus"
-#: apps/wei/models.py:160
+#: apps/wei/models.py:159
msgid "WEI Role"
msgstr "Papeles en el WEI"
-#: apps/wei/models.py:185
+#: apps/wei/models.py:183
msgid "Credit from Société générale"
msgstr "Crédito de la Société Générale"
-#: apps/wei/models.py:190
+#: apps/wei/models.py:188
msgid "Caution check given"
msgstr "Cheque de garantía dado"
-#: apps/wei/models.py:194 apps/wei/templates/wei/weimembership_form.html:64
+#: apps/wei/models.py:192 apps/wei/templates/wei/weimembership_form.html:64
msgid "birth date"
msgstr "fecha de nacimiento"
-#: apps/wei/models.py:200 apps/wei/models.py:210
+#: apps/wei/models.py:198 apps/wei/models.py:208
msgid "Male"
msgstr "Hombre"
-#: apps/wei/models.py:201 apps/wei/models.py:211
+#: apps/wei/models.py:199 apps/wei/models.py:209
msgid "Female"
msgstr "Mujer"
-#: apps/wei/models.py:202
+#: apps/wei/models.py:200
msgid "Non binary"
msgstr "No binari@"
-#: apps/wei/models.py:204 apps/wei/templates/wei/attribute_bus_1A.html:22
+#: apps/wei/models.py:202 apps/wei/templates/wei/attribute_bus_1A.html:22
#: apps/wei/templates/wei/weimembership_form.html:55
msgid "gender"
msgstr "género"
-#: apps/wei/models.py:212
+#: apps/wei/models.py:210
msgid "Unisex"
msgstr "Unisex"
-#: apps/wei/models.py:215 apps/wei/templates/wei/weimembership_form.html:58
+#: apps/wei/models.py:213 apps/wei/templates/wei/weimembership_form.html:58
msgid "clothing cut"
msgstr "forma de ropa"
-#: apps/wei/models.py:228 apps/wei/templates/wei/weimembership_form.html:61
+#: apps/wei/models.py:226 apps/wei/templates/wei/weimembership_form.html:61
msgid "clothing size"
msgstr "medida de ropa"
-#: apps/wei/models.py:234 apps/wei/templates/wei/attribute_bus_1A.html:28
+#: apps/wei/models.py:232 apps/wei/templates/wei/attribute_bus_1A.html:28
#: apps/wei/templates/wei/weimembership_form.html:67
msgid "health issues"
msgstr "problemas de salud"
-#: apps/wei/models.py:239 apps/wei/templates/wei/weimembership_form.html:70
+#: apps/wei/models.py:237 apps/wei/templates/wei/weimembership_form.html:70
msgid "emergency contact name"
msgstr "nombre del contacto de emergencia"
-#: apps/wei/models.py:240
+#: apps/wei/models.py:238
msgid "The emergency contact must not be a WEI participant"
msgstr "El contacto de emergencia no debe ser un participante de WEI"
-#: apps/wei/models.py:245 apps/wei/templates/wei/weimembership_form.html:73
+#: apps/wei/models.py:243 apps/wei/templates/wei/weimembership_form.html:73
msgid "emergency contact phone"
msgstr "teléfono del contacto de emergencia"
-#: apps/wei/models.py:250 apps/wei/templates/wei/weimembership_form.html:52
+#: apps/wei/models.py:248 apps/wei/templates/wei/weimembership_form.html:52
msgid "first year"
msgstr "primer año"
-#: apps/wei/models.py:251
+#: apps/wei/models.py:249
msgid "Tells if the user is new in the school."
msgstr "Indica si el usuario es nuevo en la escuela."
-#: apps/wei/models.py:256
+#: apps/wei/models.py:254
msgid "registration information"
msgstr "informaciones sobre la afiliación"
-#: apps/wei/models.py:257
+#: apps/wei/models.py:255
msgid ""
"Information about the registration (buses for old members, survey for the "
"new members), encoded in JSON"
@@ -2790,27 +2798,27 @@ msgstr ""
"Informaciones sobre la afiliacion (bus para miembros ancianos, cuestionario "
"para los nuevos miembros), registrado en JSON"
-#: apps/wei/models.py:315
+#: apps/wei/models.py:261
msgid "WEI User"
msgstr "Participante WEI"
-#: apps/wei/models.py:316
+#: apps/wei/models.py:262
msgid "WEI Users"
msgstr "Participantes WEI"
-#: apps/wei/models.py:336
+#: apps/wei/models.py:334
msgid "team"
msgstr "equipo"
-#: apps/wei/models.py:346
+#: apps/wei/models.py:344
msgid "WEI registration"
msgstr "Apuntación al WEI"
-#: apps/wei/models.py:350
+#: apps/wei/models.py:348
msgid "WEI membership"
msgstr "Afiliación al WEI"
-#: apps/wei/models.py:351
+#: apps/wei/models.py:349
msgid "WEI memberships"
msgstr "Afiliaciones al WEI"
@@ -3591,6 +3599,9 @@ msgstr ""
"pagar su afiliación. Tambien tiene que validar su correo electronico con el "
"enlace que recibió."
+#~ msgid "Join BDA Club"
+#~ msgstr "Afiliarse al club BDA"
+
#, fuzzy
#~| msgid "People having you as a friend"
#~ msgid "You already have that person as a friend"
diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po
index 36bfd028..46e6aa0a 100644
--- a/locale/fr/LC_MESSAGES/django.po
+++ b/locale/fr/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-10-25 19:12+0200\n"
+"POT-Creation-Date: 2024-03-22 00:33+0100\n"
"PO-Revision-Date: 2022-04-11 22:05+0200\n"
"Last-Translator: bleizi \n"
"Language-Team: French \n"
@@ -18,7 +18,7 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Poedit 3.0\n"
-#: apps/activity/apps.py:10 apps/activity/models.py:151
+#: apps/activity/apps.py:10 apps/activity/models.py:127
#: apps/activity/models.py:167
msgid "activity"
msgstr "activité"
@@ -27,38 +27,38 @@ msgstr "activité"
msgid "The note of this club is inactive."
msgstr "La note du club est inactive."
-#: apps/activity/forms.py:41 apps/activity/models.py:132
+#: apps/activity/forms.py:41 apps/activity/models.py:140
msgid "The end date must be after the start date."
msgstr "La date de fin doit être après celle de début."
-#: apps/activity/forms.py:82 apps/activity/models.py:270
+#: apps/activity/forms.py:82 apps/activity/models.py:269
msgid "You can't invite someone once the activity is started."
msgstr ""
"Vous ne pouvez pas inviter quelqu'un une fois que l'activité a démarré."
-#: apps/activity/forms.py:85 apps/activity/models.py:273
+#: apps/activity/forms.py:85 apps/activity/models.py:272
msgid "This activity is not validated yet."
msgstr "Cette activité n'est pas encore validée."
-#: apps/activity/forms.py:95 apps/activity/models.py:281
+#: apps/activity/forms.py:95 apps/activity/models.py:280
msgid "This person has been already invited 5 times this year."
msgstr "Cette personne a déjà été invitée 5 fois cette année."
-#: apps/activity/forms.py:99 apps/activity/models.py:285
+#: apps/activity/forms.py:99 apps/activity/models.py:284
msgid "This person is already invited."
msgstr "Cette personne est déjà invitée."
-#: apps/activity/forms.py:103 apps/activity/models.py:289
+#: apps/activity/forms.py:103 apps/activity/models.py:288
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:28 apps/activity/models.py:63
-#: apps/member/models.py:204
+#: apps/member/models.py:203
#: apps/member/templates/member/includes/club_info.html:4
#: apps/member/templates/member/includes/profile_info.html:4
#: apps/note/models/notes.py:263 apps/note/models/transactions.py:26
-#: apps/note/models/transactions.py:46 apps/note/models/transactions.py:301
-#: apps/permission/models.py:330
+#: apps/note/models/transactions.py:46 apps/note/models/transactions.py:299
+#: apps/permission/models.py:329
#: apps/registration/templates/registration/future_profile_detail.html:16
#: apps/wei/models.py:67 apps/wei/models.py:131 apps/wei/tables.py:282
#: apps/wei/templates/wei/base.html:26
@@ -82,7 +82,7 @@ msgstr "peut inviter"
#: apps/activity/models.py:44
#: apps/activity/templates/activity/includes/activity_info.html:46
msgid "guest entry fee"
-msgstr "cotisation de l'entrée invité"
+msgstr "cotisation de l'entrée invitée"
#: apps/activity/models.py:49
msgid "activity type"
@@ -94,8 +94,8 @@ msgstr "types d'activité"
#: apps/activity/models.py:68
#: apps/activity/templates/activity/includes/activity_info.html:19
-#: apps/note/models/transactions.py:81 apps/permission/models.py:110
-#: apps/permission/models.py:189 apps/wei/models.py:78 apps/wei/models.py:142
+#: apps/note/models/transactions.py:82 apps/permission/models.py:109
+#: apps/permission/models.py:188 apps/wei/models.py:78 apps/wei/models.py:142
msgid "description"
msgstr "description"
@@ -109,22 +109,22 @@ msgstr "Lieu où l'activité est organisée, par exemple la Kfet."
#: apps/activity/models.py:83
#: apps/activity/templates/activity/includes/activity_info.html:22
-#: apps/note/models/notes.py:207 apps/note/models/transactions.py:66
-#: apps/permission/models.py:164
+#: apps/note/models/notes.py:207 apps/note/models/transactions.py:67
+#: apps/permission/models.py:163
msgid "type"
msgstr "type"
-#: apps/activity/models.py:89 apps/logs/models.py:22 apps/member/models.py:312
-#: apps/note/models/notes.py:148 apps/treasury/models.py:287
-#: apps/wei/models.py:173 apps/wei/templates/wei/attribute_bus_1A.html:13
+#: apps/activity/models.py:89 apps/logs/models.py:22 apps/member/models.py:313
+#: apps/note/models/notes.py:148 apps/treasury/models.py:293
+#: apps/wei/models.py:171 apps/wei/templates/wei/attribute_bus_1A.html:13
#: apps/wei/templates/wei/survey.html:15
msgid "user"
-msgstr "utilisateur"
+msgstr "utilisateur·ice"
#: apps/activity/models.py:96
#: apps/activity/templates/activity/includes/activity_info.html:36
msgid "organizer"
-msgstr "organisateur"
+msgstr "organisateur·ice"
#: apps/activity/models.py:97
msgid "Club that organizes the activity. The entry fees will go to this club."
@@ -162,7 +162,7 @@ msgstr "valide"
msgid "open"
msgstr "ouvrir"
-#: apps/activity/models.py:152
+#: apps/activity/models.py:128
msgid "activities"
msgstr "activités"
@@ -188,7 +188,7 @@ msgstr "entrées"
#: apps/activity/models.py:193
#, python-brace-format
msgid "Entry for {guest}, invited by {note} to the activity {activity}"
-msgstr "Entrée pour {guest}, invité par {note} à l'activité {activity}"
+msgstr "Entrée pour {guest}, invité·e par {note} à l'activité {activity}"
#: apps/activity/models.py:195
#, python-brace-format
@@ -197,7 +197,7 @@ msgstr "Entrée de la note {note} pour l'activité « {activity} »"
#: apps/activity/models.py:202
msgid "Already entered on "
-msgstr "Déjà rentré le "
+msgstr "Déjà rentré·e le "
#: apps/activity/models.py:202 apps/activity/tables.py:56
msgid "{:%Y-%m-%d %H:%M:%S}"
@@ -226,13 +226,13 @@ msgstr "prénom"
msgid "inviter"
msgstr "hôte"
-#: apps/activity/models.py:297
+#: apps/activity/models.py:256
msgid "guest"
-msgstr "invité"
+msgstr "invité·e"
-#: apps/activity/models.py:298
+#: apps/activity/models.py:257
msgid "guests"
-msgstr "invités"
+msgstr "invité·e·s"
#: apps/activity/models.py:310
msgid "Invitation"
@@ -252,13 +252,13 @@ msgstr "Supprimer"
#: apps/activity/tables.py:56
msgid "Entered on "
-msgstr "Entré le "
+msgstr "Entré·e le "
#: apps/activity/tables.py:58
msgid "remove"
msgstr "supprimer"
-#: apps/activity/tables.py:82 apps/note/forms.py:68 apps/treasury/models.py:201
+#: apps/activity/tables.py:82 apps/note/forms.py:68 apps/treasury/models.py:208
msgid "Type"
msgstr "Type"
@@ -285,14 +285,14 @@ msgstr "Solde du compte"
#: apps/activity/templates/activity/activity_detail.html:15
msgid "Guests list"
-msgstr "Liste des invités"
+msgstr "Liste des invité·e·s"
#: apps/activity/templates/activity/activity_detail.html:33
msgid "Guest deleted"
-msgstr "Invité supprimé"
+msgstr "Invité·e supprimé·e"
#: apps/activity/templates/activity/activity_entry.html:14
-#: apps/note/models/transactions.py:257
+#: apps/note/models/transactions.py:261
#: apps/note/templates/note/transaction_form.html:17
#: apps/note/templates/note/transaction_form.html:152
#: note_kfet/templates/base.html:72
@@ -300,13 +300,13 @@ msgid "Transfer"
msgstr "Virement"
#: apps/activity/templates/activity/activity_entry.html:18
-#: apps/note/models/transactions.py:317
+#: apps/note/models/transactions.py:324
#: apps/note/templates/note/transaction_form.html:22
msgid "Credit"
msgstr "Crédit"
#: apps/activity/templates/activity/activity_entry.html:21
-#: apps/note/models/transactions.py:317
+#: apps/note/models/transactions.py:324
#: apps/note/templates/note/transaction_form.html:26
msgid "Debit"
msgstr "Débit"
@@ -324,7 +324,7 @@ msgstr "Retour à la page de l'activité"
#: apps/activity/templates/activity/activity_entry.html:129
msgid "Entry done, but caution: the user is not a Kfet member."
msgstr ""
-"Entrée effectuée, mais attention : la personne n'est pas un adhérent Kfet."
+"Entrée effectuée, mais attention : la personne n'est pas un·e adhérent·e Kfet."
#: apps/activity/templates/activity/activity_entry.html:132
msgid "Entry done!"
@@ -365,7 +365,7 @@ msgstr "Toutes les activités"
#: apps/activity/templates/activity/includes/activity_info.html:32
msgid "creater"
-msgstr "créateur"
+msgstr "créateur·ice"
#: apps/activity/templates/activity/includes/activity_info.html:53
msgid "opened"
@@ -419,7 +419,7 @@ msgstr "Invitation pour l'activité « {} »"
#: apps/activity/views.py:178
msgid "You are not allowed to display the entry interface for this activity."
msgstr ""
-"Vous n'êtes pas autorisé à afficher l'interface des entrées pour cette "
+"Vous n'êtes pas autorisé·e à afficher l'interface des entrées pour cette "
"activité."
#: apps/activity/views.py:181
@@ -446,7 +446,7 @@ msgstr "Logs"
msgid "IP Address"
msgstr "Adresse IP"
-#: apps/logs/models.py:36 apps/permission/models.py:134
+#: apps/logs/models.py:36 apps/permission/models.py:133
msgid "model"
msgstr "modèle"
@@ -467,7 +467,7 @@ msgid "create"
msgstr "créer"
#: apps/logs/models.py:65 apps/note/tables.py:230 apps/note/tables.py:277
-#: apps/permission/models.py:127 apps/treasury/tables.py:38
+#: apps/permission/models.py:126 apps/treasury/tables.py:38
#: apps/wei/tables.py:74
msgid "delete"
msgstr "supprimer"
@@ -481,43 +481,43 @@ msgid "timestamp"
msgstr "date"
#: apps/logs/models.py:80
-msgid "Logs cannot be destroyed."
-msgstr "Les logs ne peuvent pas être détruits."
-
-#: apps/logs/models.py:83
msgid "changelog"
msgstr "journal de modification"
-#: apps/logs/models.py:84
+#: apps/logs/models.py:81
msgid "changelogs"
msgstr "journaux de modifications"
-#: apps/logs/models.py:87
+#: apps/logs/models.py:84
#, python-brace-format
msgid "Changelog of type \"{action}\" for model {model} at {timestamp}"
msgstr "Changelog de type « {action} » pour le modèle {model} à {timestamp}"
-#: apps/member/admin.py:50 apps/member/models.py:231
+#: apps/logs/models.py:88
+msgid "Logs cannot be destroyed."
+msgstr "Les logs ne peuvent pas être détruits."
+
+#: apps/member/admin.py:50 apps/member/models.py:232
#: apps/member/templates/member/includes/club_info.html:34
msgid "membership fee (paid students)"
-msgstr "cotisation pour adhérer (normalien élève)"
+msgstr "cotisation pour adhérer (normalien·ne élève)"
-#: apps/member/admin.py:51 apps/member/models.py:236
+#: apps/member/admin.py:51 apps/member/models.py:237
#: apps/member/templates/member/includes/club_info.html:37
msgid "membership fee (unpaid students)"
-msgstr "cotisation pour adhérer (normalien étudiant)"
+msgstr "cotisation pour adhérer (normalien·ne étudiant·e)"
-#: apps/member/admin.py:65 apps/member/models.py:324
+#: apps/member/admin.py:65 apps/member/models.py:325
msgid "roles"
msgstr "rôles"
-#: apps/member/admin.py:66 apps/member/models.py:338
+#: apps/member/admin.py:66 apps/member/models.py:339
msgid "fee"
msgstr "cotisation"
#: apps/member/apps.py:14 apps/wei/tables.py:226 apps/wei/tables.py:257
msgid "member"
-msgstr "adhérent"
+msgstr "adhérent·e"
#: apps/member/forms.py:24
msgid "Permission mask"
@@ -542,7 +542,7 @@ msgid ""
"href=https://perso.crans.org/club-bde/Charte-anti-VSS.pdf target=_blank> "
"available here in pdf"
msgstr ""
-"Cochez après avoir lu la chartre anti-VSS disponible en pdf ici"
"a>"
@@ -587,7 +587,7 @@ msgstr "Pas de rechargement"
#: apps/member/forms.py:182
msgid "You can credit the note of the user."
-msgstr "Vous pouvez créditer la note de l'utilisateur avant l'adhésion."
+msgstr "Vous pouvez créditer la note de l'utilisateur·ice avant l'adhésion."
#: apps/member/forms.py:186 apps/registration/forms.py:85
#: apps/wei/forms/registration.py:97
@@ -602,7 +602,7 @@ msgstr "Banque"
#: apps/member/forms.py:230
msgid "User"
-msgstr "Utilisateur"
+msgstr "Utilisateur·ice"
#: apps/member/forms.py:244
msgid "Roles"
@@ -624,180 +624,180 @@ msgstr "salage"
msgid "hash"
msgstr "haché"
-#: apps/member/models.py:38
+#: apps/member/models.py:37
#: apps/member/templates/member/includes/profile_info.html:43
#: apps/registration/templates/registration/future_profile_detail.html:40
#: apps/wei/templates/wei/weimembership_form.html:44
msgid "phone number"
msgstr "numéro de téléphone"
-#: apps/member/models.py:45
+#: apps/member/models.py:44
#: apps/member/templates/member/includes/profile_info.html:37
#: apps/registration/templates/registration/future_profile_detail.html:34
#: apps/wei/templates/wei/weimembership_form.html:38
msgid "section"
msgstr "section"
-#: apps/member/models.py:46
+#: apps/member/models.py:45
msgid "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\""
msgstr "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\""
-#: apps/member/models.py:54 apps/wei/templates/wei/attribute_bus_1A.html:25
+#: apps/member/models.py:53 apps/wei/templates/wei/attribute_bus_1A.html:25
#: apps/wei/templates/wei/weimembership_form.html:32
msgid "department"
msgstr "département"
-#: apps/member/models.py:56
+#: apps/member/models.py:55
msgid "Informatics (A0)"
msgstr "Informatique (A0)"
-#: apps/member/models.py:57
+#: apps/member/models.py:56
msgid "Mathematics (A1)"
msgstr "Mathématiques (A1)"
-#: apps/member/models.py:58
+#: apps/member/models.py:57
msgid "Physics (A2)"
msgstr "Physique (A2)"
-#: apps/member/models.py:59
+#: apps/member/models.py:58
msgid "Applied physics (A'2)"
msgstr "Physique appliquée (A'2)"
-#: apps/member/models.py:60
+#: apps/member/models.py:59
msgid "Chemistry (A''2)"
msgstr "Chimie (A''2)"
-#: apps/member/models.py:61
+#: apps/member/models.py:60
msgid "Biology (A3)"
msgstr "Biologie (A3)"
-#: apps/member/models.py:62
+#: apps/member/models.py:61
msgid "SAPHIRE (B1234)"
msgstr "SAPHIRE (B1234)"
-#: apps/member/models.py:63
+#: apps/member/models.py:62
msgid "Mechanics (B1)"
msgstr "Mécanique (B1)"
-#: apps/member/models.py:64
+#: apps/member/models.py:63
msgid "Civil engineering (B2)"
msgstr "Génie civil (B2)"
-#: apps/member/models.py:65
+#: apps/member/models.py:64
msgid "Mechanical engineering (B3)"
msgstr "Génie mécanique (B3)"
-#: apps/member/models.py:66
+#: apps/member/models.py:65
msgid "EEA (B4)"
msgstr "EEA (B4)"
-#: apps/member/models.py:67
+#: apps/member/models.py:66
msgid "Design (C)"
msgstr "Design (C)"
-#: apps/member/models.py:68
+#: apps/member/models.py:67
msgid "Economy-management (D2)"
msgstr "Économie-gestion (D2)"
-#: apps/member/models.py:69
+#: apps/member/models.py:68
msgid "Social sciences (D3)"
msgstr "Sciences sociales (D3)"
-#: apps/member/models.py:70
+#: apps/member/models.py:69
msgid "English (E)"
msgstr "Anglais (E)"
-#: apps/member/models.py:71
+#: apps/member/models.py:70
msgid "External (EXT)"
msgstr "Externe (EXT)"
-#: apps/member/models.py:78
+#: apps/member/models.py:77
msgid "promotion"
msgstr "promotion"
-#: apps/member/models.py:79
+#: apps/member/models.py:78
msgid "Year of entry to the school (None if not ENS student)"
msgstr "Année d'entrée dans l'école (None si non-étudiant·e de l'ENS)"
-#: apps/member/models.py:83
+#: apps/member/models.py:82
#: apps/member/templates/member/includes/profile_info.html:47
#: apps/registration/templates/registration/future_profile_detail.html:37
#: apps/wei/templates/wei/weimembership_form.html:41
msgid "address"
msgstr "adresse"
-#: apps/member/models.py:90
+#: apps/member/models.py:89
#: apps/member/templates/member/includes/profile_info.html:50
#: apps/registration/templates/registration/future_profile_detail.html:43
#: apps/wei/templates/wei/weimembership_form.html:47
msgid "paid"
-msgstr "payé"
+msgstr "payé·e"
-#: apps/member/models.py:91
+#: apps/member/models.py:90
msgid "Tells if the user receive a salary."
-msgstr "Indique si l'utilisateur perçoit un salaire."
+msgstr "Indique si l'utilisateur·ice perçoit un salaire."
-#: apps/member/models.py:100 apps/treasury/tables.py:143
+#: apps/member/models.py:99 apps/treasury/tables.py:143
msgid "No"
msgstr "Non"
-#: apps/member/models.py:101
+#: apps/member/models.py:100
msgid "Yes (receive them in french)"
msgstr "Oui (les recevoir en français)"
-#: apps/member/models.py:102
+#: apps/member/models.py:101
msgid "Yes (receive them in english)"
msgstr "Oui (les recevoir en anglais)"
-#: apps/member/models.py:104
+#: apps/member/models.py:103
msgid ""
"Register on the mailing list to stay informed of the events of the campus (1 "
"mail/week)"
msgstr ""
-"S'inscrire sur la liste de diffusion pour rester informé des événements sur "
+"S'inscrire sur la liste de diffusion pour rester informé·e des événements sur "
"le campus (1 mail par semaine)"
-#: apps/member/models.py:109
+#: apps/member/models.py:108
msgid ""
"Register on the mailing list to stay informed of the sport events of the "
"campus (1 mail/week)"
msgstr ""
-"S'inscrire sur la liste de diffusion pour rester informé des actualités "
+"S'inscrire sur la liste de diffusion pour rester informé·e des actualités "
"sportives sur le campus (1 mail par semaine)"
-#: apps/member/models.py:114
+#: apps/member/models.py:113
msgid ""
"Register on the mailing list to stay informed of the art events of the "
"campus (1 mail/week)"
msgstr ""
-"S'inscrire sur la liste de diffusion pour rester informé des actualités "
+"S'inscrire sur la liste de diffusion pour rester informé·e des actualités "
"artistiques sur le campus (1 mail par semaine)"
-#: apps/member/models.py:118
+#: apps/member/models.py:117
msgid "report frequency (in days)"
msgstr "fréquence des rapports (en jours)"
-#: apps/member/models.py:123
+#: apps/member/models.py:122
msgid "last report date"
msgstr "date de dernier rapport"
-#: apps/member/models.py:128
+#: apps/member/models.py:127
msgid "email confirmed"
msgstr "adresse email confirmée"
-#: apps/member/models.py:133
+#: apps/member/models.py:132
msgid "registration valid"
msgstr "inscription valide"
-#: apps/member/models.py:138
+#: apps/member/models.py:137
msgid "VSS charter read"
msgstr "Charte VSS lue"
-#: apps/member/models.py:167 apps/member/models.py:168
+#: apps/member/models.py:142 apps/member/models.py:143
msgid "user profile"
-msgstr "profil utilisateur"
+msgstr "profil utilisateur·ice"
-#: apps/member/models.py:178
+#: apps/member/models.py:177
msgid "Activate your Note Kfet account"
msgstr "Activez votre compte Note Kfet"
@@ -810,90 +810,90 @@ msgstr "Activez votre compte Note Kfet"
msgid "email"
msgstr "courriel"
-#: apps/member/models.py:216
+#: apps/member/models.py:217
msgid "parent club"
msgstr "club parent"
-#: apps/member/models.py:225
+#: apps/member/models.py:226
msgid "require memberships"
msgstr "nécessite des adhésions"
-#: apps/member/models.py:226
+#: apps/member/models.py:227
msgid "Uncheck if this club don't require memberships."
msgstr "Décochez si ce club n'utilise pas d'adhésions."
-#: apps/member/models.py:242
+#: apps/member/models.py:243
#: apps/member/templates/member/includes/club_info.html:26
msgid "membership duration"
msgstr "durée de l'adhésion"
-#: apps/member/models.py:243
+#: apps/member/models.py:244
msgid "The longest time (in days) a membership can last (NULL = infinite)."
msgstr "La durée maximale (en jours) d'une adhésion (NULL = infinie)."
-#: apps/member/models.py:250
+#: apps/member/models.py:251
#: apps/member/templates/member/includes/club_info.html:16
msgid "membership start"
msgstr "début de l'adhésion"
-#: apps/member/models.py:251
+#: apps/member/models.py:252
msgid "Date from which the members can renew their membership."
msgstr ""
-"Date à partir de laquelle les adhérents peuvent renouveler leur adhésion."
+"Date à partir de laquelle les adhérent·e·s peuvent renouveler leur adhésion."
-#: apps/member/models.py:257
+#: apps/member/models.py:258
#: apps/member/templates/member/includes/club_info.html:21
msgid "membership end"
msgstr "fin de l'adhésion"
-#: apps/member/models.py:258
+#: apps/member/models.py:259
msgid "Maximal date of a membership, after which members must renew it."
msgstr ""
-"Date maximale d'une fin d'adhésion, après laquelle les adhérents doivent la "
+"Date maximale d'une fin d'adhésion, après laquelle les adhérent·e·s doivent la "
"renouveler."
-#: apps/member/models.py:293 apps/member/models.py:318
+#: apps/member/models.py:263 apps/member/models.py:319
#: apps/note/models/notes.py:176
msgid "club"
msgstr "club"
-#: apps/member/models.py:294
+#: apps/member/models.py:264
msgid "clubs"
msgstr "clubs"
-#: apps/member/models.py:329
+#: apps/member/models.py:330
msgid "membership starts on"
msgstr "l'adhésion commence le"
-#: apps/member/models.py:333
+#: apps/member/models.py:334
msgid "membership ends on"
msgstr "l'adhésion finit le"
-#: apps/member/models.py:435
-#, 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:343 apps/note/models/transactions.py:385
+msgid "membership"
+msgstr "adhésion"
-#: apps/member/models.py:444 apps/member/views.py:712
-msgid "User is already a member of the club"
-msgstr "L'utilisateur est déjà membre du club"
+#: apps/member/models.py:344
+msgid "memberships"
+msgstr "adhésions"
-#: apps/member/models.py:456 apps/member/views.py:721
-msgid "User is not a member of the parent club"
-msgstr "L'utilisateur n'est pas membre du club parent"
-
-#: apps/member/models.py:509
+#: apps/member/models.py:348
#, python-brace-format
msgid "Membership of {user} for the club {club}"
msgstr "Adhésion de {user} pour le club {club}"
-#: apps/member/models.py:512 apps/note/models/transactions.py:389
-msgid "membership"
-msgstr "adhésion"
+#: apps/member/models.py:367
+#, 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:513
-msgid "memberships"
-msgstr "adhésions"
+#: apps/member/models.py:376 apps/member/views.py:712
+msgid "User is already a member of the club"
+msgstr "L'utilisateur·ice est déjà membre du club"
+
+#: apps/member/models.py:388 apps/member/views.py:721
+msgid "User is not a member of the parent club"
+msgstr "L'utilisateur·ice n'est pas membre du club parent"
#: apps/member/tables.py:139
msgid "Renew"
@@ -906,7 +906,7 @@ msgid ""
"%(pretty_fee)s will be charged to renew automatically the membership in this/"
"these club·s."
msgstr ""
-"Cet utilisateur n'est pas membre du/des club·s parent·s %(clubs)s. Un "
+"Cet·te utilisateur·ice n'est pas membre du/des club·s parent·s %(clubs)s. Un "
"montant supplémentaire de %(pretty_fee)s sera débité afin de renouveler "
"automatiquement l'adhésion dans ce·s club·s."
@@ -916,7 +916,7 @@ msgid ""
"The user is not a member of the club·s %(clubs)s. Please create the required "
"memberships, otherwise it will fail."
msgstr ""
-"Cet utilisateur n'est pas membre du/des club·s parent·s %(clubs)s. Merci de "
+"Cet·te utilisateur·ice n'est pas membre du/des club·s parent·s %(clubs)s. Merci de "
"d'abord créer l'adhésion requise, sinon cette adhésion va échouer."
#: apps/member/templates/member/add_members.html:29
@@ -934,7 +934,7 @@ msgid ""
"This club has parents %(clubs)s. Please make sure that the user is a member "
"of this or these club·s, otherwise the creation of this membership will fail."
msgstr ""
-"Ce club a pour parents %(clubs)s. Merci de vous assurer que l'utilisateur "
+"Ce club a pour parents %(clubs)s. Merci de vous assurer que l'utilisateur·ice "
"est membre de ce·s club·s, sinon la création de cette adhésion va échouer."
#: apps/member/templates/member/base.html:17
@@ -956,7 +956,7 @@ msgstr "Voir le profil"
#: apps/member/templates/member/base.html:57
msgid "Add member"
-msgstr "Ajouter un membre"
+msgstr "Ajouter un·e membre"
#: apps/member/templates/member/base.html:72
#: apps/member/templates/member/base.html:93
@@ -983,8 +983,8 @@ msgid ""
"If you use the force mode, the user won't be able to unlock the note by "
"itself."
msgstr ""
-"Si vous verrouillez la note de force, l'utilisateur ne pourra plus la "
-"déverrouiller lui-même."
+"Si vous verrouillez la note de force, l'utilisateur·ice ne pourra plus la "
+"déverrouiller soi-même."
#: apps/member/templates/member/base.html:110
#: apps/member/templates/member/base.html:137 apps/treasury/forms.py:91
@@ -1165,7 +1165,7 @@ msgstr "Recadrer et envoyer"
#: apps/registration/templates/registration/future_profile_detail.html:28
#: apps/wei/templates/wei/weimembership_form.html:26
msgid "This user doesn't have confirmed his/her e-mail address."
-msgstr "Cet utilisateur n'a pas encore confirmé son adresse e-mail."
+msgstr "Cet·te utilisateur·ice n'a pas encore confirmé son adresse e-mail."
#: apps/member/templates/member/profile_detail.html:13
#: apps/registration/templates/registration/future_profile_detail.html:29
@@ -1179,7 +1179,7 @@ msgstr "Voir mes adhésions"
#: apps/member/templates/member/profile_trust.html:10
msgid "Add friends"
-msgstr "Ajouter des amis"
+msgstr "Ajouter des ami·e·s"
#: apps/member/templates/member/profile_trust.html:28
msgid ""
@@ -1191,12 +1191,12 @@ msgid ""
msgstr ""
"Ajouter quelqu'un⋅e en ami⋅e lui permet de me prélever de l'argent (tant que "
"ma note reste positive). Ceci sert à simplifier les remboursements entre "
-"ami⋅es via note. En effet, une personne peut effectuer tous les transferts "
+"ami⋅e·s via note. En effet, une personne peut effectuer tous les transferts "
"sans posséder de droits supplémentaires."
#: apps/member/templates/member/profile_trust.html:39
msgid "People having you as a friend"
-msgstr "Personnes vous ayant ajouté"
+msgstr "Personnes vous ayant ajouté·e"
#: apps/member/templates/member/profile_update.html:18
msgid "Save Changes"
@@ -1212,11 +1212,11 @@ msgstr "Cette adresse doit être valide."
#: apps/member/views.py:139
msgid "Profile detail"
-msgstr "Détails de l'utilisateur"
+msgstr "Détails de l'utilisateur·ice"
#: apps/member/views.py:205
msgid "Search user"
-msgstr "Chercher un utilisateur"
+msgstr "Chercher un·e utilisateur·ice"
#: apps/member/views.py:253
msgid "Note friendships"
@@ -1248,14 +1248,14 @@ msgstr "Modifier le club"
#: apps/member/views.py:574
msgid "Add new member to the club"
-msgstr "Ajouter un nouveau membre au club"
+msgstr "Ajouter un·e nouvelle·au membre au club"
#: apps/member/views.py:703 apps/wei/views.py:973
msgid ""
"This user don't have enough money to join this club, and can't have a "
"negative balance."
msgstr ""
-"Cet utilisateur n'a pas assez d'argent pour rejoindre ce club et ne peut pas "
+"Cet·te utilisateur·ice n'a pas assez d'argent pour rejoindre ce club et ne peut pas "
"avoir un solde négatif."
#: apps/member/views.py:725
@@ -1268,7 +1268,7 @@ msgstr "L'adhésion doit commencer avant le {:%d/%m/%Y}."
#: apps/member/views.py:880
msgid "Manage roles of an user in the club"
-msgstr "Gérer les rôles d'un utilisateur dans le club"
+msgstr "Gérer les rôles d'un·e utilisateur·ice dans le club"
#: apps/member/views.py:905
msgid "Members of the club"
@@ -1293,7 +1293,7 @@ msgid "This friendship already exists"
msgstr "Cette amitié existe déjà"
#: apps/note/api/serializers.py:198 apps/note/api/serializers.py:204
-#: apps/note/models/transactions.py:228
+#: apps/note/models/transactions.py:190
msgid ""
"The transaction can't be saved since the source note or the destination note "
"is not active."
@@ -1343,7 +1343,7 @@ msgstr "en centimes, argent crédité pour cette instance"
#: apps/note/models/notes.py:37
msgid "last negative date"
-msgstr "dernier date de négatif"
+msgstr "dernière date de négatif"
#: apps/note/models/notes.py:38
msgid "last time the balance was negative"
@@ -1359,7 +1359,7 @@ msgstr "créée le"
#: apps/note/models/notes.py:58
msgid "active"
-msgstr "actif"
+msgstr "actif·ve"
#: apps/note/models/notes.py:61
msgid ""
@@ -1379,8 +1379,8 @@ msgstr ""
#: apps/note/models/notes.py:70
msgid "The note is blocked by the the BDE and can't be manually reactivated."
msgstr ""
-"La note est bloquée de force par le BDE et ne peut pas être débloquée par le "
-"possesseur de la note."
+"La note est bloquée de force par le BDE et ne peut pas être débloquée par le·a "
+"possesseur·ice de la note."
#: apps/note/models/notes.py:78
msgid "notes"
@@ -1392,11 +1392,11 @@ msgstr "Cet alias est déjà pris."
#: apps/note/models/notes.py:152
msgid "one's note"
-msgstr "note d'un utilisateur"
+msgstr "note d'un·e utilisateur·ice"
#: apps/note/models/notes.py:153
msgid "users note"
-msgstr "notes des utilisateurs"
+msgstr "notes des utilisateur·ice·s"
#: apps/note/models/notes.py:159
#, python-format
@@ -1430,7 +1430,7 @@ msgstr "note"
#: apps/note/models/notes.py:239
msgid "trusted"
-msgstr "ami"
+msgstr "ami·e"
#: apps/note/models/notes.py:243
msgid "frienship"
@@ -1449,18 +1449,18 @@ msgstr "Alias invalide"
msgid "alias"
msgstr "alias"
-#: apps/note/models/notes.py:310
+#: apps/note/models/notes.py:315
msgid "Alias is too long."
msgstr "L'alias est trop long."
-#: apps/note/models/notes.py:313
+#: apps/note/models/notes.py:318
msgid ""
"This alias contains only complex character. Please use a more simple alias."
msgstr ""
"Cet alias ne contient que des caractères complexes. Merci d'utiliser un "
"alias plus simple."
-#: apps/note/models/notes.py:317
+#: apps/note/models/notes.py:322
msgid "An alias with a similar name already exists: {} "
msgstr "Un alias avec un nom similaire existe déjà : {} "
@@ -1480,19 +1480,19 @@ msgstr "catégories de transaction"
msgid "A template with this name already exist"
msgstr "Un modèle de transaction avec un nom similaire existe déjà"
-#: apps/note/models/transactions.py:72
+#: apps/note/models/transactions.py:73
msgid "display"
msgstr "afficher"
-#: apps/note/models/transactions.py:77
+#: apps/note/models/transactions.py:78
msgid "highlighted"
msgstr "mis en avant"
-#: apps/note/models/transactions.py:87
+#: apps/note/models/transactions.py:88
msgid "transaction template"
msgstr "modèle de transaction"
-#: apps/note/models/transactions.py:88
+#: apps/note/models/transactions.py:89
msgid "transaction templates"
msgstr "modèles de transaction"
@@ -1522,7 +1522,7 @@ msgstr "transaction"
msgid "transactions"
msgstr "transactions"
-#: apps/note/models/transactions.py:186
+#: apps/note/models/transactions.py:230
#, python-brace-format
msgid ""
"You can't update the {field} on a Transaction. Please invalidate it and "
@@ -1531,7 +1531,7 @@ msgstr ""
"Vous ne pouvez pas mettre à jour le champ {field} dans une transaction. "
"Merci de l'invalider et d'en créer une autre."
-#: apps/note/models/transactions.py:206
+#: apps/note/models/transactions.py:250
msgid ""
"The note balances must be between - 92 233 720 368 547 758.08 € and 92 233 "
"720 368 547 758.07 €."
@@ -1540,61 +1540,61 @@ msgstr ""
"€ et 92 233 720 368 547 758.07 €. Ne cherchez pas à capitaliser l'argent du "
"BDE."
-#: apps/note/models/transactions.py:277
+#: apps/note/models/transactions.py:274
+msgid "recurrent transaction"
+msgstr "transaction issue de bouton"
+
+#: apps/note/models/transactions.py:275
+msgid "recurrent transactions"
+msgstr "transactions issues de boutons"
+
+#: apps/note/models/transactions.py:285
msgid ""
"The destination of this transaction must equal to the destination of the "
"template."
msgstr ""
-"Le destinataire de cette transaction doit être identique à celui du bouton "
+"Le·a destinataire de cette transaction doit être identique à celui du bouton "
"utilisé."
-#: apps/note/models/transactions.py:287
+#: apps/note/models/transactions.py:290
msgid "Template"
msgstr "Bouton"
-#: apps/note/models/transactions.py:290
-msgid "recurrent transaction"
-msgstr "transaction issue de bouton"
-
-#: apps/note/models/transactions.py:291
-msgid "recurrent transactions"
-msgstr "transactions issues de boutons"
-
-#: apps/note/models/transactions.py:306
+#: apps/note/models/transactions.py:304
msgid "first_name"
msgstr "prénom"
-#: apps/note/models/transactions.py:311
+#: apps/note/models/transactions.py:309
msgid "bank"
msgstr "banque"
-#: apps/note/models/transactions.py:328
+#: apps/note/models/transactions.py:314
+msgid "Special transaction"
+msgstr "Transaction de crédit/retrait"
+
+#: apps/note/models/transactions.py:315
+msgid "Special transactions"
+msgstr "Transactions de crédit/retrait"
+
+#: apps/note/models/transactions.py:335
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"
+"mode de paiement et un·e utilisateur·ice ou un club"
-#: apps/note/models/transactions.py:355 apps/note/models/transactions.py:358
-#: apps/note/models/transactions.py:361 apps/wei/views.py:978
+#: apps/note/models/transactions.py:357 apps/note/models/transactions.py:360
+#: apps/note/models/transactions.py:363 apps/wei/views.py:978
#: apps/wei/views.py:982
msgid "This field is required."
msgstr "Ce champ est requis."
-#: apps/note/models/transactions.py:367
-msgid "Special transaction"
-msgstr "Transaction de crédit/retrait"
-
-#: apps/note/models/transactions.py:368
-msgid "Special transactions"
-msgstr "Transactions de crédit/retrait"
-
-#: apps/note/models/transactions.py:384
+#: apps/note/models/transactions.py:380
msgid "membership transaction"
msgstr "transaction d'adhésion"
-#: apps/note/models/transactions.py:385 apps/treasury/models.py:294
+#: apps/note/models/transactions.py:381 apps/treasury/models.py:300
msgid "membership transactions"
msgstr "transactions d'adhésion"
@@ -1624,7 +1624,7 @@ msgstr "Supprimer"
#: apps/note/tables.py:191
msgid "Trust back"
-msgstr "Ajouter en ami"
+msgstr "Ajouter en ami·e"
#: apps/note/tables.py:211
msgid "Add back"
@@ -1706,11 +1706,11 @@ msgstr "Mail généré par la Note Kfet le"
#: apps/note/templates/note/transaction_form.html:58
#: apps/note/templates/note/transaction_form.html:178
msgid "Select emitters"
-msgstr "Sélection des émetteurs"
+msgstr "Sélection des émetteur·ice·s"
#: apps/note/templates/note/transaction_form.html:73
msgid "I am the emitter"
-msgstr "Je suis l'émetteur"
+msgstr "Je suis l'émetteur·ice"
#: apps/note/templates/note/transaction_form.html:85
#: apps/note/templates/note/transaction_form.html:180
@@ -1729,13 +1729,13 @@ msgid "Amount"
msgstr "Montant"
#: apps/note/templates/note/transaction_form.html:132
-#: apps/treasury/models.py:56
+#: apps/treasury/models.py:60
msgid "Name"
msgstr "Nom"
#: apps/note/templates/note/transaction_form.html:177
msgid "Select emitter"
-msgstr "Sélection de l'émetteur"
+msgstr "Sélection de l'émetteur·ice"
#: apps/note/templates/note/transaction_form.html:179
msgid "Select receiver"
@@ -1817,88 +1817,88 @@ msgstr "Consommations"
msgid "You can't see any button."
msgstr "Vous ne pouvez pas voir le moindre bouton."
-#: apps/note/views.py:208
+#: apps/note/views.py:204
msgid "Search transactions"
msgstr "Rechercher des transactions"
-#: apps/permission/models.py:89
+#: apps/permission/models.py:31
#, python-brace-format
msgid "Can {type} {model}.{field} in {query}"
msgstr "Peut {type} {model}.{field} si {query}"
-#: apps/permission/models.py:91
+#: apps/permission/models.py:33
#, python-brace-format
msgid "Can {type} {model} in {query}"
msgstr "Peut {type} {model} si {query}"
-#: apps/permission/models.py:104
+#: apps/permission/models.py:103
msgid "rank"
msgstr "rang"
-#: apps/permission/models.py:117
+#: apps/permission/models.py:113
msgid "permission mask"
msgstr "masque de permissions"
-#: apps/permission/models.py:118
+#: apps/permission/models.py:114
msgid "permission masks"
msgstr "masques de permissions"
-#: apps/permission/models.py:124
+#: apps/permission/models.py:123
msgid "add"
msgstr "ajouter"
-#: apps/permission/models.py:125
+#: apps/permission/models.py:124
msgid "view"
msgstr "voir"
-#: apps/permission/models.py:126
+#: apps/permission/models.py:125
msgid "change"
msgstr "modifier"
-#: apps/permission/models.py:158
+#: apps/permission/models.py:157
msgid "query"
msgstr "requête"
-#: apps/permission/models.py:171
+#: apps/permission/models.py:170
msgid "mask"
msgstr "masque"
-#: apps/permission/models.py:177
+#: apps/permission/models.py:176
msgid "field"
msgstr "champ"
-#: apps/permission/models.py:182
+#: apps/permission/models.py:181
msgid ""
"Tells if the permission should be granted even if the membership of the user "
"is expired."
msgstr ""
"Indique si la permission doit être attribuée même si l'adhésion de "
-"l'utilisateur est expirée."
+"l'utilisateur·ice est expirée."
-#: apps/permission/models.py:183
+#: apps/permission/models.py:182
#: apps/permission/templates/permission/all_rights.html:89
msgid "permanent"
msgstr "permanent"
-#: apps/permission/models.py:194
+#: apps/permission/models.py:193
msgid "permission"
msgstr "permission"
-#: apps/permission/models.py:195 apps/permission/models.py:335
+#: apps/permission/models.py:194 apps/permission/models.py:334
msgid "permissions"
msgstr "permissions"
-#: apps/permission/models.py:200
+#: apps/permission/models.py:207
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:340
+#: apps/permission/models.py:339
msgid "for club"
msgstr "s'applique au club"
-#: apps/permission/models.py:351 apps/permission/models.py:352
+#: apps/permission/models.py:347 apps/permission/models.py:348
msgid "role permissions"
msgstr "permissions par rôles"
@@ -1931,16 +1931,16 @@ msgstr ""
#: apps/permission/templates/permission/all_rights.html:12
msgid "Users that have surnormal rights"
-msgstr "Liste des utilisateurs ayant des droits surnormaux"
+msgstr "Liste des utilisateur·ice·s ayant des droits surnormaux"
#: apps/permission/templates/permission/all_rights.html:16
msgid "Superusers have all rights on everything, to manage the website."
msgstr ""
-"Les super-utilisateurs ont tous les droits sur tout, afin de gérer le site."
+"Les super-utilisateur·ice·s ont tous les droits sur tout, afin de gérer le site."
#: apps/permission/templates/permission/all_rights.html:21
msgid "Superusers"
-msgstr "Super-utilisateurs"
+msgstr "Super-utilisateur·ice·s"
#: apps/permission/templates/permission/all_rights.html:45
msgid "Roles description"
@@ -2044,10 +2044,6 @@ msgstr "Adhérer au club BDE"
msgid "Join Kfet Club"
msgstr "Adhérer au club Kfet"
-#: apps/registration/forms.py:123
-msgid "Join BDA Club"
-msgstr "Adhérer au club BDA"
-
#: apps/registration/templates/registration/email_validation_complete.html:15
msgid "Your email have successfully been validated."
msgstr "Votre adresse e-mail a bien été validée."
@@ -2099,7 +2095,7 @@ msgstr "Valider le compte"
#: apps/registration/templates/registration/future_profile_detail.html:63
msgid ""
"The user declared that he/she opened a bank account in the Société générale."
-msgstr "L'utilisateur a déclaré avoir ouvert un compte à la société générale."
+msgstr "L'utilisateur·ice a déclaré avoir ouvert un compte à la société générale."
#: apps/registration/templates/registration/future_profile_detail.html:73
#: apps/wei/templates/wei/weimembership_form.html:127
@@ -2109,7 +2105,7 @@ msgstr "Valider l'inscription"
#: apps/registration/templates/registration/future_user_list.html:9
msgid "New user"
-msgstr "Nouvel utilisateur"
+msgstr "Nouvel·le utilisateur·ice"
#: apps/registration/templates/registration/mails/email_validation_email.html:12
#: apps/registration/templates/registration/mails/email_validation_email.txt:3
@@ -2153,7 +2149,7 @@ msgstr "L'équipe de la Note Kfet."
#: apps/registration/views.py:41
msgid "Register new user"
-msgstr "Enregistrer un nouvel utilisateur"
+msgstr "Enregistrer un·e nouvel·le utilisateur·ice"
#: apps/registration/views.py:99
msgid "Email validation"
@@ -2177,11 +2173,11 @@ msgstr "Renvoyer le lien de validation"
#: apps/registration/views.py:182
msgid "Pre-registered users list"
-msgstr "Liste des utilisateurs en attente d'inscription"
+msgstr "Liste des utilisateur·ice·s en attente d'inscription"
#: apps/registration/views.py:206
msgid "Unregistered users"
-msgstr "Utilisateurs en attente d'inscription"
+msgstr "Utilisateur·ice·s en attente d'inscription"
#: apps/registration/views.py:219
msgid "Registration detail"
@@ -2206,7 +2202,7 @@ msgstr "Invalider l'inscription"
msgid "Treasury"
msgstr "Trésorerie"
-#: apps/treasury/forms.py:26 apps/treasury/models.py:95
+#: apps/treasury/forms.py:26 apps/treasury/models.py:112
#: apps/treasury/templates/treasury/invoice_form.html:22
msgid "This invoice is locked and can no longer be edited."
msgstr "Cette facture est verrouillée et ne peut plus être éditée."
@@ -2219,7 +2215,7 @@ msgstr "La remise est déjà fermée."
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:125 apps/treasury/models.py:269
+#: apps/treasury/forms.py:125 apps/treasury/models.py:275
#: apps/treasury/tables.py:97 apps/treasury/tables.py:105
#: apps/treasury/templates/treasury/invoice_list.html:16
#: apps/treasury/templates/treasury/remittance_list.html:16
@@ -2231,7 +2227,7 @@ msgstr "Remise"
msgid "No attached remittance"
msgstr "Pas de remise associée"
-#: apps/treasury/models.py:26
+#: apps/treasury/models.py:25
msgid "Invoice identifier"
msgstr "Numéro de facture"
@@ -2239,132 +2235,140 @@ msgstr "Numéro de facture"
msgid "BDE"
msgstr "BDE"
-#: apps/treasury/models.py:47
+#: apps/treasury/models.py:46
+msgid "Quotation"
+msgstr "Devis"
+
+#: apps/treasury/models.py:51
msgid "Object"
msgstr "Objet"
-#: apps/treasury/models.py:51
+#: apps/treasury/models.py:55
msgid "Description"
msgstr "Description"
-#: apps/treasury/models.py:60
+#: apps/treasury/models.py:64
msgid "Address"
msgstr "Adresse"
-#: apps/treasury/models.py:65 apps/treasury/models.py:195
+#: apps/treasury/models.py:69 apps/treasury/models.py:202
msgid "Date"
msgstr "Date"
-#: apps/treasury/models.py:69
+#: apps/treasury/models.py:75
+msgid "Payment date"
+msgstr "Date de paiement"
+
+#: apps/treasury/models.py:79
msgid "Acquitted"
msgstr "Acquittée"
-#: apps/treasury/models.py:74
+#: apps/treasury/models.py:84
msgid "Locked"
msgstr "Verrouillée"
-#: apps/treasury/models.py:75
+#: apps/treasury/models.py:85
msgid "An invoice can't be edited when it is locked."
msgstr "Une facture ne peut plus être modifiée si elle est verrouillée."
-#: apps/treasury/models.py:81
+#: apps/treasury/models.py:91
msgid "tex source"
msgstr "fichier TeX source"
-#: apps/treasury/models.py:115 apps/treasury/models.py:131
+#: apps/treasury/models.py:95 apps/treasury/models.py:140
msgid "invoice"
msgstr "facture"
-#: apps/treasury/models.py:116
+#: apps/treasury/models.py:96
msgid "invoices"
msgstr "factures"
-#: apps/treasury/models.py:119
+#: apps/treasury/models.py:99
#, python-brace-format
msgid "Invoice #{id}"
msgstr "Facture n°{id}"
-#: apps/treasury/models.py:136
+#: apps/treasury/models.py:145
msgid "Designation"
msgstr "Désignation"
-#: apps/treasury/models.py:142
+#: apps/treasury/models.py:151
msgid "Quantity"
msgstr "Quantité"
-#: apps/treasury/models.py:147
+#: apps/treasury/models.py:156
msgid "Unit price"
msgstr "Prix unitaire"
-#: apps/treasury/models.py:163
+#: apps/treasury/models.py:160
msgid "product"
msgstr "produit"
-#: apps/treasury/models.py:164
+#: apps/treasury/models.py:161
msgid "products"
msgstr "produits"
-#: apps/treasury/models.py:184
+#: apps/treasury/models.py:189
msgid "remittance type"
msgstr "type de remise"
-#: apps/treasury/models.py:185
+#: apps/treasury/models.py:190
msgid "remittance types"
msgstr "types de remises"
-#: apps/treasury/models.py:206
+#: apps/treasury/models.py:213
msgid "Comment"
msgstr "Commentaire"
-#: apps/treasury/models.py:211
+#: apps/treasury/models.py:218
msgid "Closed"
msgstr "Fermée"
-#: apps/treasury/models.py:215
+#: apps/treasury/models.py:222
msgid "remittance"
msgstr "remise"
-#: apps/treasury/models.py:216
+#: apps/treasury/models.py:223
msgid "remittances"
msgstr "remises"
-#: apps/treasury/models.py:249
+#: apps/treasury/models.py:226
msgid "Remittance #{:d}: {}"
msgstr "Remise n°{:d} : {}"
-#: apps/treasury/models.py:273
+#: apps/treasury/models.py:279
msgid "special transaction proxy"
msgstr "proxy de transaction spéciale"
-#: apps/treasury/models.py:274
+#: apps/treasury/models.py:280
msgid "special transaction proxies"
msgstr "proxys de transactions spéciales"
-#: apps/treasury/models.py:300
+#: apps/treasury/models.py:306
msgid "credit transaction"
msgstr "transaction de crédit"
-#: apps/treasury/models.py:432
-msgid ""
-"This user doesn't have enough money to pay the memberships with its note. "
-"Please ask her/him to credit the note before invalidating this credit."
-msgstr ""
-"Cet utilisateur n'a pas assez d'argent pour payer les adhésions avec sa "
-"note. Merci de lui demander de recharger sa note avant d'invalider ce crédit."
-
-#: apps/treasury/models.py:452
+#: apps/treasury/models.py:311
#: apps/treasury/templates/treasury/sogecredit_detail.html:10
msgid "Credit from the Société générale"
msgstr "Crédit de la Société générale"
-#: apps/treasury/models.py:453
+#: apps/treasury/models.py:312
msgid "Credits from the Société générale"
msgstr "Crédits de la Société générale"
-#: apps/treasury/models.py:456
+#: apps/treasury/models.py:315
#, python-brace-format
msgid "Soge credit for {user}"
-msgstr "Crédit de la société générale pour l'utilisateur {user}"
+msgstr "Crédit de la société générale pour l'utilisateur·ice {user}"
+
+#: apps/treasury/models.py:445
+msgid ""
+"This user doesn't have enough money to pay the memberships with its note. "
+"Please ask her/him to credit the note before invalidating this credit."
+msgstr ""
+"Cet·te utilisateur·ice n'a pas assez d'argent pour payer les adhésions avec sa "
+"note. Merci de lui demander de recharger sa note avant d'invalider ce crédit."
#: apps/treasury/tables.py:20
msgid "Invoice #{:d}"
@@ -2515,12 +2519,12 @@ msgid ""
"If this credit is validated, then the user won't be able to ask for a credit "
"from the Société générale."
msgstr ""
-"Si ce crédit est validé, alors l'utilisateur ne pourra plus demander d'être "
-"crédité par la Société générale à l'avenir."
+"Si ce crédit est validé, alors l'utilisateur·ice ne pourra plus demander d'être "
+"crédité·e par la Société générale à l'avenir."
#: apps/treasury/templates/treasury/sogecredit_detail.html:44
msgid "If you think there is an error, please contact the \"respos info\"."
-msgstr "Si vous pensez qu'il y a une erreur, merci de contacter un respo info."
+msgstr "Si vous pensez qu'il y a une erreur, merci de contacter un·e respo info."
#: apps/treasury/templates/treasury/sogecredit_detail.html:50
msgid "This credit is already validated."
@@ -2531,13 +2535,13 @@ msgid ""
"Warning: if you don't validate this credit, the note of the user doesn't "
"have enough money to pay its memberships."
msgstr ""
-"Attention : si vous ne validez pas ce crédit, la note de l'utilisateur n'a "
+"Attention : si vous ne validez pas ce crédit, la note de l'utilisateur·ice n'a "
"pas assez d'argent pour payer les adhésions."
#: apps/treasury/templates/treasury/sogecredit_detail.html:56
msgid "Please ask the user to credit its note before deleting this credit."
msgstr ""
-"Merci de demander à l'utilisateur de recharger sa note avant de supprimer la "
+"Merci de demander à l'utilisateur·ice de recharger sa note avant de supprimer la "
"demande de crédit."
#: apps/treasury/templates/treasury/sogecredit_detail.html:63
@@ -2556,7 +2560,7 @@ msgstr "Filtrer avec uniquement les crédits non valides"
#: apps/treasury/templates/treasury/sogecredit_list.html:50
msgid "There is no matched user that have asked for a Société générale credit."
msgstr ""
-"Il n'y a pas d'utilisateur trouvé ayant demandé un crédit de la Société "
+"Il n'y a pas d'utilisateur·ice trouvé·e ayant demandé un crédit de la Société "
"générale."
#: apps/treasury/templates/treasury/sogecredit_list.html:63
@@ -2578,7 +2582,7 @@ msgstr "Liste des factures"
#: apps/treasury/views.py:105 apps/treasury/views.py:275
#: apps/treasury/views.py:401
msgid "You are not able to see the treasury interface."
-msgstr "Vous n'êtes pas autorisé à voir l'interface de trésorerie."
+msgstr "Vous n'êtes pas autorisé·e à voir l'interface de trésorerie."
#: apps/treasury/views.py:115
msgid "Update an invoice"
@@ -2608,8 +2612,8 @@ msgstr "Liste des crédits de la Société générale"
msgid "Manage credits from the Société générale"
msgstr "Gérer les crédits de la Société générale"
-#: apps/wei/apps.py:10 apps/wei/models.py:50 apps/wei/models.py:51
-#: apps/wei/models.py:62 apps/wei/models.py:180
+#: apps/wei/apps.py:10 apps/wei/models.py:37 apps/wei/models.py:38
+#: apps/wei/models.py:62 apps/wei/models.py:178
#: note_kfet/templates/base.html:102
msgid "WEI"
msgstr "WEI"
@@ -2617,11 +2621,11 @@ msgstr "WEI"
#: apps/wei/forms/registration.py:35
msgid "The selected user is not validated. Please validate its account first"
msgstr ""
-"L'utilisateur sélectionné n'est pas validé. Merci de d'abord valider son "
+"L'utilisateur·ice sélectionné·e n'est pas validé·e. Merci de d'abord valider son "
"compte"
#: apps/wei/forms/registration.py:59 apps/wei/models.py:126
-#: apps/wei/models.py:326
+#: apps/wei/models.py:324
msgid "bus"
msgstr "bus"
@@ -2630,8 +2634,8 @@ msgid ""
"This choice is not definitive. The WEI organizers are free to attribute for "
"you a bus and a team, in particular if you are a free eletron."
msgstr ""
-"Ce choix n'est pas définitif. Les organisateurs du WEI sont libres de vous "
-"attribuer un bus et une équipe, en particulier si vous êtes un électron "
+"Ce choix n'est pas définitif. Les organisateur·ice·s du WEI sont libres de vous "
+"attribuer un bus et une équipe, en particulier si vous êtes un·e électron "
"libre."
#: apps/wei/forms/registration.py:67
@@ -2647,7 +2651,7 @@ msgstr ""
"bus ou électron libre)"
#: apps/wei/forms/registration.py:75 apps/wei/forms/registration.py:85
-#: apps/wei/models.py:161
+#: apps/wei/models.py:160
msgid "WEI Roles"
msgstr "Rôles au WEI"
@@ -2688,11 +2692,11 @@ 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:113
+#: apps/wei/models.py:88
msgid "Bus"
msgstr "Bus"
-#: apps/wei/models.py:114 apps/wei/templates/wei/weiclub_detail.html:51
+#: apps/wei/models.py:89 apps/wei/templates/wei/weiclub_detail.html:51
msgid "Buses"
msgstr "Bus"
@@ -2705,91 +2709,91 @@ 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:150
+#: apps/wei/models.py:147
msgid "Bus team"
msgstr "Équipe de bus"
-#: apps/wei/models.py:151
+#: apps/wei/models.py:148
msgid "Bus teams"
msgstr "Équipes de bus"
-#: apps/wei/models.py:160
+#: apps/wei/models.py:159
msgid "WEI Role"
msgstr "Rôle au WEI"
-#: apps/wei/models.py:185
+#: apps/wei/models.py:183
msgid "Credit from Société générale"
msgstr "Crédit de la Société générale"
-#: apps/wei/models.py:190
+#: apps/wei/models.py:188
msgid "Caution check given"
msgstr "Chèque de caution donné"
-#: apps/wei/models.py:194 apps/wei/templates/wei/weimembership_form.html:64
+#: apps/wei/models.py:192 apps/wei/templates/wei/weimembership_form.html:64
msgid "birth date"
msgstr "date de naissance"
-#: apps/wei/models.py:200 apps/wei/models.py:210
+#: apps/wei/models.py:198 apps/wei/models.py:208
msgid "Male"
msgstr "Homme"
-#: apps/wei/models.py:201 apps/wei/models.py:211
+#: apps/wei/models.py:199 apps/wei/models.py:209
msgid "Female"
msgstr "Femme"
-#: apps/wei/models.py:202
+#: apps/wei/models.py:200
msgid "Non binary"
msgstr "Non-binaire"
-#: apps/wei/models.py:204 apps/wei/templates/wei/attribute_bus_1A.html:22
+#: apps/wei/models.py:202 apps/wei/templates/wei/attribute_bus_1A.html:22
#: apps/wei/templates/wei/weimembership_form.html:55
msgid "gender"
msgstr "genre"
-#: apps/wei/models.py:212
+#: apps/wei/models.py:210
msgid "Unisex"
msgstr "Unisexe"
-#: apps/wei/models.py:215 apps/wei/templates/wei/weimembership_form.html:58
+#: apps/wei/models.py:213 apps/wei/templates/wei/weimembership_form.html:58
msgid "clothing cut"
msgstr "coupe de vêtement"
-#: apps/wei/models.py:228 apps/wei/templates/wei/weimembership_form.html:61
+#: apps/wei/models.py:226 apps/wei/templates/wei/weimembership_form.html:61
msgid "clothing size"
msgstr "taille de vêtement"
-#: apps/wei/models.py:234 apps/wei/templates/wei/attribute_bus_1A.html:28
+#: apps/wei/models.py:232 apps/wei/templates/wei/attribute_bus_1A.html:28
#: apps/wei/templates/wei/weimembership_form.html:67
msgid "health issues"
msgstr "problèmes de santé"
-#: apps/wei/models.py:239 apps/wei/templates/wei/weimembership_form.html:70
+#: apps/wei/models.py:237 apps/wei/templates/wei/weimembership_form.html:70
msgid "emergency contact name"
msgstr "nom du contact en cas d'urgence"
-#: apps/wei/models.py:240
+#: apps/wei/models.py:238
msgid "The emergency contact must not be a WEI participant"
msgstr ""
"Le contact en cas d'urgence ne doit pas être une personne qui participe au "
"WEI"
-#: apps/wei/models.py:245 apps/wei/templates/wei/weimembership_form.html:73
+#: apps/wei/models.py:243 apps/wei/templates/wei/weimembership_form.html:73
msgid "emergency contact phone"
msgstr "téléphone du contact en cas d'urgence"
-#: apps/wei/models.py:250 apps/wei/templates/wei/weimembership_form.html:52
+#: apps/wei/models.py:248 apps/wei/templates/wei/weimembership_form.html:52
msgid "first year"
msgstr "première année"
-#: apps/wei/models.py:251
+#: apps/wei/models.py:249
msgid "Tells if the user is new in the school."
-msgstr "Indique si l'utilisateur est nouveau dans l'école."
+msgstr "Indique si l'utilisateur·ice est nouveau dans l'école."
-#: apps/wei/models.py:256
+#: apps/wei/models.py:254
msgid "registration information"
msgstr "informations sur l'inscription"
-#: apps/wei/models.py:257
+#: apps/wei/models.py:255
msgid ""
"Information about the registration (buses for old members, survey for the "
"new members), encoded in JSON"
@@ -2797,45 +2801,45 @@ msgstr ""
"Informations sur l'inscription (bus pour les 2A+, questionnaire pour les "
"1A), encodées en JSON"
-#: apps/wei/models.py:315
+#: apps/wei/models.py:261
msgid "WEI User"
-msgstr "Participant au WEI"
+msgstr "Participant·e au WEI"
-#: apps/wei/models.py:316
+#: apps/wei/models.py:262
msgid "WEI Users"
-msgstr "Participants au WEI"
+msgstr "Participant·e·s au WEI"
-#: apps/wei/models.py:336
+#: apps/wei/models.py:334
msgid "team"
msgstr "équipe"
-#: apps/wei/models.py:346
+#: apps/wei/models.py:344
msgid "WEI registration"
msgstr "Inscription au WEI"
-#: apps/wei/models.py:350
+#: apps/wei/models.py:348
msgid "WEI membership"
msgstr "Adhésion au WEI"
-#: apps/wei/models.py:351
+#: apps/wei/models.py:349
msgid "WEI memberships"
msgstr "Adhésions au WEI"
#: apps/wei/tables.py:105
msgid "The user does not have enough money."
-msgstr "L'utilisateur n'a pas assez d'argent."
+msgstr "L'utilisateur·ice n'a pas assez d'argent."
#: apps/wei/tables.py:108
msgid ""
"The user is in first year. You may validate the credit, the algorithm will "
"run later."
msgstr ""
-"L'utilisateur est en première année, vous pouvez valider le crédit, "
+"L'utilisateur·ice est en première année, vous pouvez valider le crédit, "
"l'algorithme tournera plus tard."
#: apps/wei/tables.py:111
msgid "The user has enough money, you can validate the registration."
-msgstr "L'utilisateur a assez d'argent, l'inscription est possible."
+msgstr "L'utilisateur·ice a assez d'argent, l'inscription est possible."
#: apps/wei/tables.py:143
msgid "Year"
@@ -2856,19 +2860,19 @@ msgstr "Nombre de membres"
#: apps/wei/tables.py:226 apps/wei/tables.py:257
msgid "members"
-msgstr "adhérents"
+msgstr "adhérent·e·s"
#: apps/wei/tables.py:287
msgid "suggested first year"
-msgstr "1A suggérés"
+msgstr "1A suggéré·e·s"
#: apps/wei/tables.py:293
msgid "validated first year"
-msgstr "1A validés"
+msgstr "1A validé·e·s"
#: apps/wei/tables.py:299
msgid "validated staff"
-msgstr "2A+ validés"
+msgstr "2A+ validé·e·s"
#: apps/wei/tables.py:310
msgid "free seats"
@@ -3048,7 +3052,7 @@ msgstr "L'inscription a déjà été validée et ne peut pas être dévalidée."
#: apps/wei/templates/wei/weimembership_form.html:132
msgid "The user joined the bus"
-msgstr "L'utilisateur a rejoint le bus"
+msgstr "L'utilisateur·ice a rejoint le bus"
#: apps/wei/templates/wei/weimembership_form.html:133
msgid "in the team"
@@ -3093,7 +3097,7 @@ msgstr ""
#: apps/wei/templates/wei/weimembership_form.html:166
msgid "The user didn't give her/his caution check."
-msgstr "L'utilisateur n'a pas donné son chèque de caution."
+msgstr "L'utilisateur·ice n'a pas donné son chèque de caution."
#: apps/wei/templates/wei/weimembership_form.html:174
msgid ""
@@ -3101,7 +3105,7 @@ msgid ""
"membership will be processed automatically, the WEI registration includes "
"the membership fee."
msgstr ""
-"Cet utilisateur n'est pas membre du club Kfet pour l'année à venir. "
+"Cet·te utilisateur·ice n'est pas membre du club Kfet pour l'année à venir. "
"L'adhésion va être faite automatiquement, l'inscription au WEI inclut le "
"coût d'adhésion."
@@ -3195,7 +3199,7 @@ msgid ""
"This user can't be in her/his first year since he/she has already "
"participated to a WEI."
msgstr ""
-"Cet utilisateur ne peut pas être en première année puisqu'il a déjà "
+"Cet·te utilisateur·ice ne peut pas être en première année puisqu'iel a déjà "
"participé à un WEI."
#: apps/wei/views.py:578
@@ -3309,7 +3313,7 @@ msgstr "La note du BDE de l'ENS Paris-Saclay."
#: note_kfet/templates/base.html:78
msgid "Users"
-msgstr "Utilisateurs"
+msgstr "Utilisateur·ice·s"
#: note_kfet/templates/base.html:84
msgid "Clubs"
@@ -3347,7 +3351,7 @@ msgid ""
"You are not a BDE member anymore. Please renew your membership if you want "
"to use the note."
msgstr ""
-"Vous n'êtes plus adhérent BDE. Merci de réadhérer si vous voulez profiter de "
+"Vous n'êtes plus adhérent·e BDE. Merci de réadhérer si vous voulez profiter de "
"la note."
#: note_kfet/templates/base.html:165
@@ -3366,7 +3370,7 @@ msgid ""
"last a few days. Please make sure that you go to the end of the account "
"creation."
msgstr ""
-"Vous avez déclaré que vous avez ouvert un compte bancaire à la société "
+"Vous avez déclaré·e que vous avez ouvert un compte bancaire à la société "
"générale. La banque n'a pas encore validé la création du compte auprès du "
"BDE, l'adhésion et le WEI ne sont donc pas encore payés. Cette procédure de "
"vérification peut durer quelques jours. Merci de vous assurer de bien aller "
@@ -3585,7 +3589,7 @@ msgid ""
"you registered with, and check your spam folder."
msgstr ""
"Si vous ne recevez pas d'email, vérifiez que vous avez bien utilisé "
-"l'adresse associé à votre compte, et regarder également le dossier spam."
+"l'adresse associée à votre compte, et regarder également le dossier spam."
#: note_kfet/templates/registration/password_reset_form.html:13
msgid ""
@@ -3606,16 +3610,19 @@ msgid ""
"Kfet and pay the registration fee. You must also validate your email address "
"by following the link you received."
msgstr ""
-"Si vous vous êtes déjà inscrits, votre inscription a bien été prise en "
+"Si vous vous êtes déjà inscrit·e·s, votre inscription a bien été prise en "
"compte. Le BDE doit d'abord valider votre compte avant que vous puissiez "
"vous connecter. Vous devez vous rendre à la Kfet et payer les frais "
"d'adhésion. Vous devez également valider votre adresse email en suivant le "
"lien que vous avez reçu."
+#~ msgid "Join BDA Club"
+#~ msgstr "Adhérer au club BDA"
+
#, fuzzy
#~| msgid "People having you as a friend"
#~ msgid "You already have that person as a friend"
-#~ msgstr "Personnes vous ayant ajouté"
+#~ msgstr "Personnes vous ayant ajouté·e"
#~ msgid ""
#~ "I declare that I opened or I will open soon a bank account in the Société "
diff --git a/note_kfet/admin.py b/note_kfet/admin.py
index dc209c67..0900c3b0 100644
--- a/note_kfet/admin.py
+++ b/note_kfet/admin.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
diff --git a/note_kfet/inputs.py b/note_kfet/inputs.py
index 6e729c47..0ad0797a 100644
--- a/note_kfet/inputs.py
+++ b/note_kfet/inputs.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from json import dumps as json_dumps
diff --git a/note_kfet/middlewares.py b/note_kfet/middlewares.py
index ed6d6acf..47948adb 100644
--- a/note_kfet/middlewares.py
+++ b/note_kfet/middlewares.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from threading import local
diff --git a/note_kfet/settings/__init__.py b/note_kfet/settings/__init__.py
index 0710212b..22d5fd0c 100644
--- a/note_kfet/settings/__init__.py
+++ b/note_kfet/settings/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.utils.translation import gettext_lazy as _
diff --git a/note_kfet/settings/base.py b/note_kfet/settings/base.py
index f3c23f4d..74fed818 100644
--- a/note_kfet/settings/base.py
+++ b/note_kfet/settings/base.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
# This file implements sane defaults to use in production.
diff --git a/note_kfet/settings/development.py b/note_kfet/settings/development.py
index 7fa4da86..c83f301a 100644
--- a/note_kfet/settings/development.py
+++ b/note_kfet/settings/development.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
########################
diff --git a/note_kfet/settings/secrets_example.py b/note_kfet/settings/secrets_example.py
index 5b69c10f..49a77a95 100644
--- a/note_kfet/settings/secrets_example.py
+++ b/note_kfet/settings/secrets_example.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
OPTIONAL_APPS = [
diff --git a/note_kfet/static/js/base.js b/note_kfet/static/js/base.js
index 4a34a911..af9c7b20 100644
--- a/note_kfet/static/js/base.js
+++ b/note_kfet/static/js/base.js
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+// Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
// SPDX-License-Identifier: GPL-3.0-or-later
/**
diff --git a/note_kfet/templates/base.html b/note_kfet/templates/base.html
index 7cf80017..979d6e2c 100644
--- a/note_kfet/templates/base.html
+++ b/note_kfet/templates/base.html
@@ -194,7 +194,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
class="text-muted">{% trans "Contact us" %} —
{% trans "Technical Support" %} —
- {% trans "FAQ (FR)" %} —
{% csrf_token %}
diff --git a/note_kfet/urls.py b/note_kfet/urls.py
index 7fc37fa7..d222c239 100644
--- a/note_kfet/urls.py
+++ b/note_kfet/urls.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
diff --git a/note_kfet/views.py b/note_kfet/views.py
index b65bf761..faf14a67 100644
--- a/note_kfet/views.py
+++ b/note_kfet/views.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
+# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib.auth.mixins import LoginRequiredMixin
diff --git a/note_kfet/wsgi.py b/note_kfet/wsgi.py
index b89430ec..8b86ba3b 100644
--- a/note_kfet/wsgi.py
+++ b/note_kfet/wsgi.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2016-2019 by BDE
+# Copyright (C) 2016-2024 by BDE
# SPDX-License-Identifier: GPL-3.0-or-later
"""