diff --git a/core/baker_recipes.py b/core/baker_recipes.py
index 7e49e09b..0abd83e0 100644
--- a/core/baker_recipes.py
+++ b/core/baker_recipes.py
@@ -1,7 +1,8 @@
 from datetime import timedelta
 
+from dateutil.relativedelta import relativedelta
 from django.conf import settings
-from django.utils.timezone import now
+from django.utils.timezone import localdate, now
 from model_bakery import seq
 from model_bakery.recipe import Recipe, related
 
@@ -11,13 +12,13 @@ from subscription.models import Subscription
 
 active_subscription = Recipe(
     Subscription,
-    subscription_start=now() - timedelta(days=30),
-    subscription_end=now() + timedelta(days=30),
+    subscription_start=localdate() - timedelta(days=30),
+    subscription_end=localdate() + timedelta(days=30),
 )
 ended_subscription = Recipe(
     Subscription,
-    subscription_start=now() - timedelta(days=60),
-    subscription_end=now() - timedelta(days=30),
+    subscription_start=localdate() - timedelta(days=60),
+    subscription_end=localdate() - timedelta(days=30),
 )
 
 subscriber_user = Recipe(
@@ -36,6 +37,17 @@ old_subscriber_user = Recipe(
 )
 """A user with an ended subscription."""
 
+__inactivity = localdate() - settings.SITH_ACCOUNT_INACTIVITY_DELTA
+very_old_subscriber_user = old_subscriber_user.extend(
+    subscriptions=related(
+        ended_subscription.extend(
+            subscription_start=__inactivity - relativedelta(months=6, days=1),
+            subscription_end=__inactivity - relativedelta(days=1),
+        )
+    )
+)
+"""A user which subscription ended enough time ago to be considered as inactive."""
+
 ae_board_membership = Recipe(
     Membership,
     start_date=now() - timedelta(days=30),
diff --git a/core/migrations/0039_alter_user_managers.py b/core/migrations/0039_alter_user_managers.py
new file mode 100644
index 00000000..3073bbe6
--- /dev/null
+++ b/core/migrations/0039_alter_user_managers.py
@@ -0,0 +1,15 @@
+# Generated by Django 4.2.16 on 2024-10-06 14:52
+
+from django.db import migrations
+
+import core.models
+
+
+class Migration(migrations.Migration):
+    dependencies = [("core", "0038_alter_preferences_receive_weekmail")]
+
+    operations = [
+        migrations.AlterModelManagers(
+            name="user", managers=[("objects", core.models.CustomUserManager())]
+        )
+    ]
diff --git a/core/models.py b/core/models.py
index 646cbca8..36d0902d 100644
--- a/core/models.py
+++ b/core/models.py
@@ -27,15 +27,12 @@ import importlib
 import logging
 import os
 import unicodedata
-from datetime import date, timedelta
+from datetime import timedelta
 from pathlib import Path
-from typing import TYPE_CHECKING, Optional
+from typing import TYPE_CHECKING, Any, Optional, Self
 
 from django.conf import settings
-from django.contrib.auth.models import (
-    AbstractBaseUser,
-    UserManager,
-)
+from django.contrib.auth.models import AbstractBaseUser, UserManager
 from django.contrib.auth.models import (
     AnonymousUser as AuthAnonymousUser,
 )
@@ -51,15 +48,18 @@ from django.core.cache import cache
 from django.core.exceptions import PermissionDenied, ValidationError
 from django.core.mail import send_mail
 from django.db import models, transaction
+from django.db.models import Exists, OuterRef, Q
 from django.urls import reverse
 from django.utils import timezone
 from django.utils.functional import cached_property
 from django.utils.html import escape
+from django.utils.timezone import localdate, now
 from django.utils.translation import gettext_lazy as _
 from phonenumber_field.modelfields import PhoneNumberField
-from pydantic.v1 import NonNegativeInt
 
 if TYPE_CHECKING:
+    from pydantic import NonNegativeInt
+
     from club.models import Club
 
 
@@ -91,15 +91,15 @@ class Group(AuthGroup):
     class Meta:
         ordering = ["name"]
 
-    def get_absolute_url(self):
+    def get_absolute_url(self) -> str:
         return reverse("core:group_list")
 
-    def save(self, *args, **kwargs):
+    def save(self, *args, **kwargs) -> None:
         super().save(*args, **kwargs)
         cache.set(f"sith_group_{self.id}", self)
         cache.set(f"sith_group_{self.name.replace(' ', '_')}", self)
 
-    def delete(self, *args, **kwargs):
+    def delete(self, *args, **kwargs) -> None:
         super().delete(*args, **kwargs)
         cache.delete(f"sith_group_{self.id}")
         cache.delete(f"sith_group_{self.name.replace(' ', '_')}")
@@ -164,9 +164,9 @@ class RealGroup(Group):
         proxy = True
 
 
-def validate_promo(value):
+def validate_promo(value: int) -> None:
     start_year = settings.SITH_SCHOOL_START_YEAR
-    delta = (date.today() + timedelta(days=180)).year - start_year
+    delta = (localdate() + timedelta(days=180)).year - start_year
     if value < 0 or delta < value:
         raise ValidationError(
             _("%(value)s is not a valid promo (between 0 and %(end)s)"),
@@ -174,7 +174,7 @@ def validate_promo(value):
         )
 
 
-def get_group(*, pk: int = None, name: str = None) -> Optional[Group]:
+def get_group(*, pk: int = None, name: str = None) -> Group | None:
     """Search for a group by its primary key or its name.
     Either one of the two must be set.
 
@@ -216,6 +216,31 @@ def get_group(*, pk: int = None, name: str = None) -> Optional[Group]:
     return group
 
 
+class UserQuerySet(models.QuerySet):
+    def filter_inactive(self) -> Self:
+        from counter.models import Refilling, Selling
+        from subscription.models import Subscription
+
+        threshold = now() - settings.SITH_ACCOUNT_INACTIVITY_DELTA
+        subscriptions = Subscription.objects.filter(
+            member_id=OuterRef("pk"), subscription_end__gt=localdate(threshold)
+        )
+        refills = Refilling.objects.filter(
+            customer__user_id=OuterRef("pk"), date__gt=threshold
+        )
+        purchases = Selling.objects.filter(
+            customer__user_id=OuterRef("pk"), date__gt=threshold
+        )
+        return self.exclude(
+            Q(Exists(subscriptions)) | Q(Exists(refills)) | Q(Exists(purchases))
+        )
+
+
+class CustomUserManager(UserManager.from_queryset(UserQuerySet)):
+    # see https://docs.djangoproject.com/fr/stable/topics/migrations/#model-managers
+    pass
+
+
 class User(AbstractBaseUser):
     """Defines the base user class, useable in every app.
 
@@ -373,36 +398,41 @@ class User(AbstractBaseUser):
     )
     godfathers = models.ManyToManyField("User", related_name="godchildren", blank=True)
 
-    objects = UserManager()
+    objects = CustomUserManager()
 
     USERNAME_FIELD = "username"
 
-    def promo_has_logo(self):
-        return Path(
-            settings.BASE_DIR / f"core/static/core/img/promo_{self.promo}.png"
-        ).exists()
-
-    def has_module_perms(self, package_name):
-        return self.is_active
-
-    def has_perm(self, perm, obj=None):
-        return self.is_active and self.is_superuser
-
-    def get_absolute_url(self):
-        return reverse("core:user_profile", kwargs={"user_id": self.pk})
-
     def __str__(self):
         return self.get_display_name()
 
-    def to_dict(self):
-        return self.__dict__
+    def save(self, *args, **kwargs):
+        with transaction.atomic():
+            if self.id:
+                old = User.objects.filter(id=self.id).first()
+                if old and old.username != self.username:
+                    self._change_username(self.username)
+            super().save(*args, **kwargs)
+
+    def get_absolute_url(self) -> str:
+        return reverse("core:user_profile", kwargs={"user_id": self.pk})
+
+    def promo_has_logo(self) -> bool:
+        return Path(
+            settings.BASE_DIR / f"core/static/core/img/promo_{self.promo}.png"
+        ).exists()
+
+    def has_module_perms(self, package_name: str) -> bool:
+        return self.is_active
+
+    def has_perm(self, perm: str, obj: Any = None) -> bool:
+        return self.is_active and self.is_superuser
 
     @cached_property
-    def was_subscribed(self):
+    def was_subscribed(self) -> bool:
         return self.subscriptions.exists()
 
     @cached_property
-    def is_subscribed(self):
+    def is_subscribed(self) -> bool:
         s = self.subscriptions.filter(
             subscription_start__lte=timezone.now(), subscription_end__gte=timezone.now()
         )
@@ -542,17 +572,6 @@ class User(AbstractBaseUser):
         )
         return age
 
-    def save(self, *args, **kwargs):
-        create = False
-        with transaction.atomic():
-            if self.id:
-                old = User.objects.filter(id=self.id).first()
-                if old and old.username != self.username:
-                    self._change_username(self.username)
-            else:
-                create = True
-            super().save(*args, **kwargs)
-
     def make_home(self):
         if self.home is None:
             home_root = SithFile.objects.filter(parent=None, name="users").first()
diff --git a/core/tests/test_user.py b/core/tests/test_user.py
index 9794b9f6..25125d5c 100644
--- a/core/tests/test_user.py
+++ b/core/tests/test_user.py
@@ -1,6 +1,7 @@
 from datetime import timedelta
 
 import pytest
+from django.conf import settings
 from django.core.management import call_command
 from django.test import Client, TestCase
 from django.urls import reverse
@@ -8,8 +9,13 @@ from django.utils.timezone import now
 from model_bakery import baker, seq
 from model_bakery.recipe import Recipe
 
-from core.baker_recipes import subscriber_user
+from core.baker_recipes import (
+    old_subscriber_user,
+    subscriber_user,
+    very_old_subscriber_user,
+)
 from core.models import User
+from counter.models import Counter, Refilling, Selling
 
 
 class TestSearchUsers(TestCase):
@@ -111,3 +117,34 @@ def test_user_account_not_found(client: Client):
         )
     )
     assert res.status_code == 404
+
+
+class TestFilterInactive(TestCase):
+    @classmethod
+    def setUpTestData(cls):
+        time_active = now() - settings.SITH_ACCOUNT_INACTIVITY_DELTA + timedelta(days=1)
+        time_inactive = time_active - timedelta(days=3)
+        counter, seller = baker.make(Counter), baker.make(User)
+        sale_recipe = Recipe(
+            Selling,
+            counter=counter,
+            club=counter.club,
+            seller=seller,
+            is_validated=True,
+        )
+
+        cls.users = [
+            baker.make(User),
+            subscriber_user.make(),
+            old_subscriber_user.make(),
+            *very_old_subscriber_user.make(_quantity=3),
+        ]
+        sale_recipe.make(customer=cls.users[3].customer, date=time_active)
+        baker.make(
+            Refilling, customer=cls.users[4].customer, date=time_active, counter=counter
+        )
+        sale_recipe.make(customer=cls.users[5].customer, date=time_inactive)
+
+    def test_filter_inactive(self):
+        res = User.objects.filter(id__in=[u.id for u in self.users]).filter_inactive()
+        assert list(res) == [self.users[0], self.users[5]]
diff --git a/counter/admin.py b/counter/admin.py
index 966f5b28..42943338 100644
--- a/counter/admin.py
+++ b/counter/admin.py
@@ -49,6 +49,18 @@ class BillingInfoAdmin(admin.ModelAdmin):
     autocomplete_fields = ("customer",)
 
 
+@admin.register(AccountDump)
+class AccountDumpAdmin(admin.ModelAdmin):
+    list_display = (
+        "customer",
+        "warning_mail_sent_at",
+        "warning_mail_error",
+        "dump_operation",
+    )
+    autocomplete_fields = ("customer",)
+    list_filter = ("warning_mail_error",)
+
+
 @admin.register(Counter)
 class CounterAdmin(admin.ModelAdmin):
     list_display = ("name", "club", "type")
diff --git a/counter/management/__init__.py b/counter/management/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/counter/management/commands/__init__.py b/counter/management/commands/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/counter/management/commands/dump_warning_mail.py b/counter/management/commands/dump_warning_mail.py
new file mode 100644
index 00000000..2b8fbfdd
--- /dev/null
+++ b/counter/management/commands/dump_warning_mail.py
@@ -0,0 +1,91 @@
+import logging
+from smtplib import SMTPException
+
+from django.conf import settings
+from django.core.mail import send_mail
+from django.core.management.base import BaseCommand
+from django.db.models import Exists, OuterRef, QuerySet, Subquery
+from django.template.loader import render_to_string
+from django.utils.timezone import localdate, now
+from django.utils.translation import gettext as _
+
+from core.models import User
+from counter.models import AccountDump
+from subscription.models import Subscription
+
+
+class Command(BaseCommand):
+    """Send mail to inactive users, warning them that their account is about to be dumped.
+
+    This command should be automated with a cron task.
+    """
+
+    def __init__(self, *args, **kwargs):
+        self.logger = logging.getLogger("account_dump_mail")
+        self.logger.setLevel(logging.INFO)
+        super().__init__(*args, **kwargs)
+
+    def handle(self, *args, **options):
+        users = list(self._get_users())
+        self.stdout.write(f"{len(users)} users will be warned of their account dump")
+        dumps = []
+        for user in users:
+            is_success = self._send_mail(user)
+            dumps.append(
+                AccountDump(
+                    customer_id=user.id,
+                    warning_mail_sent_at=now(),
+                    warning_mail_error=not is_success,
+                )
+            )
+        AccountDump.objects.bulk_create(dumps)
+        self.stdout.write("Finished !")
+
+    @staticmethod
+    def _get_users() -> QuerySet[User]:
+        ongoing_dump_operation = AccountDump.objects.ongoing().filter(
+            customer__user=OuterRef("pk")
+        )
+        return (
+            User.objects.filter_inactive()
+            .filter(customer__amount__gt=0)
+            .exclude(Exists(ongoing_dump_operation))
+            .annotate(
+                last_subscription_date=Subquery(
+                    Subscription.objects.filter(member=OuterRef("pk"))
+                    .order_by("-subscription_end")
+                    .values("subscription_end")[:1]
+                ),
+            )
+            .select_related("customer")
+        )
+
+    def _send_mail(self, user: User) -> bool:
+        """Send the warning email to the given user.
+
+        Returns:
+            True if the mail was successfully sent, else False
+        """
+        message = render_to_string(
+            "counter/account_dump_warning_mail.jinja",
+            {
+                "balance": user.customer.amount,
+                "last_subscription_date": user.last_subscription_date,
+                "dump_date": localdate() + settings.SITH_ACCOUNT_DUMP_DELTA,
+            },
+        )
+        try:
+            # sending mails one by one is long and ineffective,
+            # but it makes easier to know which emails failed (and how).
+            # Also, there won't be that much mails sent (except on the first run)
+            send_mail(
+                _("Clearing of your AE account"),
+                message,
+                settings.DEFAULT_FROM_EMAIL,
+                [user.email],
+            )
+            self.logger.info(f"Mail successfully sent to {user.email}")
+            return True
+        except SMTPException as e:
+            self.logger.error(f"failed mail to {user.email} :\n{e}")
+            return False
diff --git a/counter/migrations/0024_accountdump_accountdump_unique_ongoing_dump.py b/counter/migrations/0024_accountdump_accountdump_unique_ongoing_dump.py
new file mode 100644
index 00000000..e5b478a7
--- /dev/null
+++ b/counter/migrations/0024_accountdump_accountdump_unique_ongoing_dump.py
@@ -0,0 +1,64 @@
+# Generated by Django 4.2.16 on 2024-10-06 14:33
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+    dependencies = [("counter", "0023_billinginfo_phone_number")]
+
+    operations = [
+        migrations.CreateModel(
+            name="AccountDump",
+            fields=[
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "warning_mail_sent_at",
+                    models.DateTimeField(
+                        help_text="When the mail warning that the account was about to be dumped was sent."
+                    ),
+                ),
+                (
+                    "warning_mail_error",
+                    models.BooleanField(
+                        default=False,
+                        help_text="Set this to True if the warning mail received an error",
+                    ),
+                ),
+                (
+                    "customer",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="dumps",
+                        to="counter.customer",
+                    ),
+                ),
+                (
+                    "dump_operation",
+                    models.OneToOneField(
+                        blank=True,
+                        help_text="The operation that emptied the account.",
+                        null=True,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to="counter.selling",
+                    ),
+                ),
+            ],
+        ),
+        migrations.AddConstraint(
+            model_name="accountdump",
+            constraint=models.UniqueConstraint(
+                condition=models.Q(("dump_operation", None)),
+                fields=("customer",),
+                name="unique_ongoing_dump",
+            ),
+        ),
+    ]
diff --git a/counter/models.py b/counter/models.py
index 2e58760a..e6d5b061 100644
--- a/counter/models.py
+++ b/counter/models.py
@@ -26,7 +26,7 @@ from dict2xml import dict2xml
 from django.conf import settings
 from django.core.validators import MinLengthValidator
 from django.db import models
-from django.db.models import Exists, F, OuterRef, QuerySet, Sum, Value
+from django.db.models import Exists, F, OuterRef, Q, QuerySet, Sum, Value
 from django.db.models.functions import Concat, Length
 from django.forms import ValidationError
 from django.urls import reverse
@@ -211,6 +211,51 @@ class BillingInfo(models.Model):
         return '' + xml
 
 
+class AccountDumpQuerySet(models.QuerySet):
+    def ongoing(self) -> Self:
+        """Filter dump operations that are not completed yet."""
+        return self.filter(dump_operation=None)
+
+
+class AccountDump(models.Model):
+    """The process of dumping an account."""
+
+    customer = models.ForeignKey(
+        Customer, related_name="dumps", on_delete=models.CASCADE
+    )
+    warning_mail_sent_at = models.DateTimeField(
+        help_text=_(
+            "When the mail warning that the account was about to be dumped was sent."
+        )
+    )
+    warning_mail_error = models.BooleanField(
+        default=False,
+        help_text=_("Set this to True if the warning mail received an error"),
+    )
+    dump_operation = models.OneToOneField(
+        "Selling",
+        null=True,
+        blank=True,
+        on_delete=models.CASCADE,
+        help_text=_("The operation that emptied the account."),
+    )
+
+    objects = AccountDumpQuerySet.as_manager()
+
+    class Meta:
+        constraints = [
+            models.UniqueConstraint(
+                fields=["customer"],
+                condition=Q(dump_operation=None),
+                name="unique_ongoing_dump",
+            ),
+        ]
+
+    def __str__(self):
+        status = "ongoing" if self.dump_operation is None else "finished"
+        return f"{self.customer} - {status}"
+
+
 class ProductType(models.Model):
     """A product type.
 
diff --git a/counter/templates/counter/account_dump_warning_mail.jinja b/counter/templates/counter/account_dump_warning_mail.jinja
new file mode 100644
index 00000000..1d7dc8ed
--- /dev/null
+++ b/counter/templates/counter/account_dump_warning_mail.jinja
@@ -0,0 +1,43 @@
+
+  Bonjour,
+
+
+
+  {%- trans date=last_subscription_date|date(DATETIME_FORMAT) -%}
+    You received this email because your last subscription to the
+    Students' association ended on {{ date }}.
+  {%- endtrans -%}
+
+
+
+  {%- trans date=dump_date|date(DATETIME_FORMAT), amount=balance -%}
+    In accordance with the Internal Regulations, the balance of any
+    inactive AE account for more than 2 years automatically goes back
+    to the AE.
+    The money present on your account will therefore be recovered in full
+    on {{ date }}, for a total of {{ amount }} €.
+  {%- endtrans -%}
+
+
+
+  {%- trans -%}However, if your subscription is renewed by this date,
+    your right to keep the money in your AE account will be renewed.{%- endtrans -%}
+
+
+{% if balance >= 10 %}
+  
+    {%- trans -%}You can also request a refund by sending an email to
+      ae@utbm.fr
+      before the aforementioned date.{%- endtrans -%}
+  
+{% endif %}
+
+
+  {% trans %}Sincerely{% endtrans %},
+
+
+
+  L'association des étudiants de l'UTBM 
+  6, Boulevard Anatole France 
+  90000 Belfort
+
diff --git a/counter/tests/test_account_dump.py b/counter/tests/test_account_dump.py
new file mode 100644
index 00000000..49882cfe
--- /dev/null
+++ b/counter/tests/test_account_dump.py
@@ -0,0 +1,65 @@
+from datetime import timedelta
+
+from django.conf import settings
+from django.core import mail
+from django.core.management import call_command
+from django.test import TestCase
+from django.utils.timezone import now
+from model_bakery import baker
+from model_bakery.recipe import Recipe
+
+from core.baker_recipes import subscriber_user, very_old_subscriber_user
+from counter.management.commands.dump_warning_mail import Command
+from counter.models import AccountDump, Customer, Refilling
+
+
+class TestAccountDumpWarningMailCommand(TestCase):
+    @classmethod
+    def setUpTestData(cls):
+        # delete existing customers to avoid side effect
+        Customer.objects.all().delete()
+        refill_recipe = Recipe(Refilling, amount=10)
+        cls.notified_users = very_old_subscriber_user.make(_quantity=3)
+        inactive_date = (
+            now() - settings.SITH_ACCOUNT_INACTIVITY_DELTA - timedelta(days=1)
+        )
+        refill_recipe.make(
+            customer=(u.customer for u in cls.notified_users),
+            date=inactive_date,
+            _quantity=len(cls.notified_users),
+        )
+        cls.not_notified_users = [
+            subscriber_user.make(),
+            very_old_subscriber_user.make(),  # inactive, but account already empty
+            very_old_subscriber_user.make(),  # inactive, but with a recent transaction
+            very_old_subscriber_user.make(),  # inactive, but already warned
+        ]
+        refill_recipe.make(
+            customer=cls.not_notified_users[2].customer, date=now() - timedelta(days=1)
+        )
+        refill_recipe.make(
+            customer=cls.not_notified_users[3].customer, date=inactive_date
+        )
+        baker.make(
+            AccountDump,
+            customer=cls.not_notified_users[3].customer,
+            dump_operation=None,
+        )
+
+    def test_user_selection(self):
+        """Test that the user to warn are well selected."""
+        users = list(Command._get_users())
+        assert len(users) == 3
+        assert set(users) == set(self.notified_users)
+
+    def test_command(self):
+        """The actual command test."""
+        call_command("dump_warning_mail")
+        # 1 already existing + 3 new account dump objects
+        assert AccountDump.objects.count() == 4
+        sent_mails = list(mail.outbox)
+        assert len(sent_mails) == 3
+        target_emails = {u.email for u in self.notified_users}
+        for sent in sent_mails:
+            assert len(sent.to) == 1
+            assert sent.to[0] in target_emails
diff --git a/counter/views.py b/counter/views.py
index 50bf02b0..e5a64bf1 100644
--- a/counter/views.py
+++ b/counter/views.py
@@ -16,6 +16,7 @@ import re
 from datetime import datetime, timedelta
 from datetime import timezone as tz
 from http import HTTPStatus
+from typing import TYPE_CHECKING
 from urllib.parse import parse_qs
 
 from django import forms
@@ -49,7 +50,6 @@ from django.views.generic.edit import (
 )
 
 from accounting.models import CurrencyField
-from core.models import User
 from core.utils import get_semester_code, get_start_of_semester
 from core.views import CanEditMixin, CanViewMixin, TabedViewMixin
 from core.views.forms import LoginForm
@@ -78,6 +78,9 @@ from counter.models import (
 )
 from counter.utils import is_logged_in_counter
 
+if TYPE_CHECKING:
+    from core.models import User
+
 
 class CounterAdminMixin(View):
     """Protect counter admin section."""
diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po
index 02b4bcbe..21c0a35c 100644
--- a/locale/fr/LC_MESSAGES/django.po
+++ b/locale/fr/LC_MESSAGES/django.po
@@ -6,11 +6,11 @@
 msgid ""
 msgstr ""
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2024-10-10 19:37+0200\n"
+"POT-Creation-Date: 2024-10-11 09:58+0200\n"
 "PO-Revision-Date: 2016-07-18\n"
-"Last-Translator: Skia \n"
+"Last-Translator: Maréchal \n"
-"Language: \n"
+"Language: Français\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -18,8 +18,8 @@ msgstr ""
 
 #: accounting/models.py:62 accounting/models.py:103 accounting/models.py:136
 #: accounting/models.py:203 club/models.py:55 com/models.py:274
-#: com/models.py:293 counter/models.py:220 counter/models.py:253
-#: counter/models.py:411 forum/models.py:59 launderette/models.py:29
+#: com/models.py:293 counter/models.py:265 counter/models.py:298
+#: counter/models.py:456 forum/models.py:59 launderette/models.py:29
 #: launderette/models.py:84 launderette/models.py:122
 msgid "name"
 msgstr "nom"
@@ -40,7 +40,7 @@ msgstr "code postal"
 msgid "country"
 msgstr "pays"
 
-#: accounting/models.py:67 core/models.py:365
+#: accounting/models.py:67 core/models.py:390
 msgid "phone"
 msgstr "téléphone"
 
@@ -65,8 +65,8 @@ msgid "account number"
 msgstr "numéro de compte"
 
 #: accounting/models.py:109 accounting/models.py:140 club/models.py:345
-#: com/models.py:74 com/models.py:259 com/models.py:299 counter/models.py:276
-#: counter/models.py:413 trombi/models.py:210
+#: com/models.py:74 com/models.py:259 com/models.py:299 counter/models.py:321
+#: counter/models.py:458 trombi/models.py:210
 msgid "club"
 msgstr "club"
 
@@ -87,12 +87,12 @@ msgstr "Compte club"
 msgid "%(club_account)s on %(bank_account)s"
 msgstr "%(club_account)s sur %(bank_account)s"
 
-#: accounting/models.py:201 club/models.py:351 counter/models.py:899
+#: accounting/models.py:201 club/models.py:351 counter/models.py:944
 #: election/models.py:16 launderette/models.py:179
 msgid "start date"
 msgstr "date de début"
 
-#: accounting/models.py:202 club/models.py:352 counter/models.py:900
+#: accounting/models.py:202 club/models.py:352 counter/models.py:945
 #: election/models.py:17
 msgid "end date"
 msgstr "date de fin"
@@ -106,7 +106,7 @@ msgid "club account"
 msgstr "compte club"
 
 #: accounting/models.py:212 accounting/models.py:272 counter/models.py:57
-#: counter/models.py:609
+#: counter/models.py:654
 msgid "amount"
 msgstr "montant"
 
@@ -126,20 +126,20 @@ msgstr "numéro"
 msgid "journal"
 msgstr "classeur"
 
-#: accounting/models.py:273 core/models.py:940 core/models.py:1460
-#: core/models.py:1505 core/models.py:1534 core/models.py:1558
-#: counter/models.py:619 counter/models.py:723 counter/models.py:935
+#: accounting/models.py:273 core/models.py:959 core/models.py:1479
+#: core/models.py:1524 core/models.py:1553 core/models.py:1577
+#: counter/models.py:664 counter/models.py:768 counter/models.py:980
 #: eboutic/models.py:57 eboutic/models.py:189 forum/models.py:311
 #: forum/models.py:412
 msgid "date"
 msgstr "date"
 
-#: accounting/models.py:274 counter/models.py:222 counter/models.py:936
+#: accounting/models.py:274 counter/models.py:267 counter/models.py:981
 #: pedagogy/models.py:207
 msgid "comment"
 msgstr "commentaire"
 
-#: accounting/models.py:276 counter/models.py:621 counter/models.py:725
+#: accounting/models.py:276 counter/models.py:666 counter/models.py:770
 #: subscription/models.py:56
 msgid "payment method"
 msgstr "méthode de paiement"
@@ -165,8 +165,8 @@ msgid "accounting type"
 msgstr "type comptable"
 
 #: accounting/models.py:311 accounting/models.py:450 accounting/models.py:483
-#: accounting/models.py:515 core/models.py:1533 core/models.py:1559
-#: counter/models.py:689
+#: accounting/models.py:515 core/models.py:1552 core/models.py:1578
+#: counter/models.py:734
 msgid "label"
 msgstr "étiquette"
 
@@ -218,7 +218,7 @@ msgstr "Compte"
 msgid "Company"
 msgstr "Entreprise"
 
-#: accounting/models.py:324 core/models.py:312 sith/settings.py:411
+#: accounting/models.py:324 core/models.py:337 sith/settings.py:420
 msgid "Other"
 msgstr "Autre"
 
@@ -264,7 +264,7 @@ msgstr ""
 "Vous devez fournir soit un type comptable simplifié ou un type comptable "
 "standard"
 
-#: accounting/models.py:442 counter/models.py:263 pedagogy/models.py:41
+#: accounting/models.py:442 counter/models.py:308 pedagogy/models.py:41
 msgid "code"
 msgstr "code"
 
@@ -375,8 +375,8 @@ msgstr "Compte en banque : "
 #: election/templates/election/election_detail.jinja:187
 #: forum/templates/forum/macros.jinja:21
 #: launderette/templates/launderette/launderette_admin.jinja:16
-#: launderette/views.py:217 pedagogy/templates/pedagogy/guide.jinja:95
-#: pedagogy/templates/pedagogy/guide.jinja:110
+#: launderette/views.py:217 pedagogy/templates/pedagogy/guide.jinja:99
+#: pedagogy/templates/pedagogy/guide.jinja:114
 #: pedagogy/templates/pedagogy/uv_detail.jinja:189
 #: sas/templates/sas/album.jinja:32 sas/templates/sas/moderation.jinja:18
 #: sas/templates/sas/picture.jinja:50 trombi/templates/trombi/detail.jinja:35
@@ -427,8 +427,8 @@ msgstr "Nouveau compte club"
 #: election/templates/election/election_detail.jinja:184
 #: forum/templates/forum/macros.jinja:20 forum/templates/forum/macros.jinja:62
 #: launderette/templates/launderette/launderette_list.jinja:16
-#: pedagogy/templates/pedagogy/guide.jinja:94
-#: pedagogy/templates/pedagogy/guide.jinja:109
+#: pedagogy/templates/pedagogy/guide.jinja:98
+#: pedagogy/templates/pedagogy/guide.jinja:113
 #: pedagogy/templates/pedagogy/uv_detail.jinja:188
 #: sas/templates/sas/album.jinja:31 trombi/templates/trombi/detail.jinja:9
 #: trombi/templates/trombi/edit_profile.jinja:34
@@ -517,7 +517,7 @@ msgid "Effective amount"
 msgstr "Montant effectif"
 
 #: accounting/templates/accounting/club_account_details.jinja:36
-#: sith/settings.py:457
+#: sith/settings.py:466
 msgid "Closed"
 msgstr "Fermé"
 
@@ -650,7 +650,7 @@ msgid "Done"
 msgstr "Effectuées"
 
 #: accounting/templates/accounting/journal_details.jinja:41
-#: counter/templates/counter/cash_summary_list.jinja:37 counter/views.py:941
+#: counter/templates/counter/cash_summary_list.jinja:37 counter/views.py:944
 #: pedagogy/templates/pedagogy/moderation.jinja:13
 #: pedagogy/templates/pedagogy/uv_detail.jinja:142
 #: trombi/templates/trombi/comment.jinja:4
@@ -967,15 +967,15 @@ msgstr "Date de fin"
 #: club/forms.py:160 club/templates/club/club_sellings.jinja:49
 #: core/templates/core/user_account_detail.jinja:17
 #: core/templates/core/user_account_detail.jinja:56
-#: counter/templates/counter/cash_summary_list.jinja:33 counter/views.py:138
+#: counter/templates/counter/cash_summary_list.jinja:33 counter/views.py:141
 msgid "Counter"
 msgstr "Comptoir"
 
-#: club/forms.py:167 counter/views.py:685
+#: club/forms.py:167 counter/views.py:688
 msgid "Products"
 msgstr "Produits"
 
-#: club/forms.py:172 counter/views.py:690
+#: club/forms.py:172 counter/views.py:693
 msgid "Archived products"
 msgstr "Produits archivés"
 
@@ -1029,11 +1029,11 @@ msgstr "actif"
 msgid "short description"
 msgstr "description courte"
 
-#: club/models.py:81 core/models.py:367
+#: club/models.py:81 core/models.py:392
 msgid "address"
 msgstr "Adresse"
 
-#: club/models.py:98 core/models.py:278
+#: club/models.py:98 core/models.py:303
 msgid "home"
 msgstr "home"
 
@@ -1045,20 +1045,20 @@ msgstr "Vous ne pouvez pas faire de boucles dans les clubs"
 msgid "A club with that unix_name already exists"
 msgstr "Un club avec ce nom UNIX existe déjà."
 
-#: club/models.py:337 counter/models.py:890 counter/models.py:926
+#: club/models.py:337 counter/models.py:935 counter/models.py:971
 #: eboutic/models.py:53 eboutic/models.py:185 election/models.py:183
 #: launderette/models.py:136 launderette/models.py:198 sas/models.py:274
 #: trombi/models.py:206
 msgid "user"
 msgstr "nom d'utilisateur"
 
-#: club/models.py:354 core/models.py:331 election/models.py:178
+#: club/models.py:354 core/models.py:356 election/models.py:178
 #: election/models.py:212 trombi/models.py:211
 msgid "role"
 msgstr "rôle"
 
-#: club/models.py:359 core/models.py:89 counter/models.py:221
-#: counter/models.py:254 election/models.py:13 election/models.py:115
+#: club/models.py:359 core/models.py:89 counter/models.py:266
+#: counter/models.py:299 election/models.py:13 election/models.py:115
 #: election/models.py:188 forum/models.py:60 forum/models.py:244
 msgid "description"
 msgstr "description"
@@ -1072,7 +1072,7 @@ msgid "Enter a valid address. Only the root of the address is needed."
 msgstr ""
 "Entrez une adresse valide. Seule la racine de l'adresse est nécessaire."
 
-#: club/models.py:429 com/models.py:82 com/models.py:309 core/models.py:941
+#: club/models.py:429 com/models.py:82 com/models.py:309 core/models.py:960
 msgid "is moderated"
 msgstr "est modéré"
 
@@ -1150,7 +1150,7 @@ msgid "There are no members in this club."
 msgstr "Il n'y a pas de membres dans ce club."
 
 #: club/templates/club/club_members.jinja:80
-#: core/templates/core/file_detail.jinja:19 core/views/forms.py:314
+#: core/templates/core/file_detail.jinja:19 core/views/forms.py:312
 #: launderette/views.py:217 trombi/templates/trombi/detail.jinja:19
 msgid "Add"
 msgstr "Ajouter"
@@ -1442,7 +1442,7 @@ msgstr "résumé"
 msgid "content"
 msgstr "contenu"
 
-#: com/models.py:71 core/models.py:1503 launderette/models.py:92
+#: com/models.py:71 core/models.py:1522 launderette/models.py:92
 #: launderette/models.py:130 launderette/models.py:181
 msgid "type"
 msgstr "type"
@@ -1492,7 +1492,7 @@ msgstr "weekmail"
 msgid "rank"
 msgstr "rang"
 
-#: com/models.py:295 core/models.py:906 core/models.py:956
+#: com/models.py:295 core/models.py:925 core/models.py:975
 msgid "file"
 msgstr "fichier"
 
@@ -1589,7 +1589,7 @@ msgstr "Type"
 #: com/templates/com/weekmail.jinja:19 com/templates/com/weekmail.jinja:48
 #: forum/templates/forum/forum.jinja:32 forum/templates/forum/forum.jinja:51
 #: forum/templates/forum/main.jinja:34 forum/views.py:246
-#: pedagogy/templates/pedagogy/guide.jinja:88
+#: pedagogy/templates/pedagogy/guide.jinja:92
 msgid "Title"
 msgstr "Titre"
 
@@ -1988,17 +1988,17 @@ msgstr "Si un groupe est un meta-groupe ou pas"
 msgid "%(value)s is not a valid promo (between 0 and %(end)s)"
 msgstr "%(value)s n'est pas une promo valide (doit être entre 0 et %(end)s)"
 
-#: core/models.py:231
+#: core/models.py:256
 msgid "username"
 msgstr "nom d'utilisateur"
 
-#: core/models.py:235
+#: core/models.py:260
 msgid "Required. 254 characters or fewer. Letters, digits and ./+/-/_ only."
 msgstr ""
 "Requis. Pas plus de 254 caractères. Uniquement des lettres, numéros, et ./"
 "+/-/_"
 
-#: core/models.py:241
+#: core/models.py:266
 msgid ""
 "Enter a valid username. This value may contain only letters, numbers and ./"
 "+/-/_ characters."
@@ -2006,43 +2006,43 @@ msgstr ""
 "Entrez un nom d'utilisateur correct. Uniquement des lettres, numéros, et ./"
 "+/-/_"
 
-#: core/models.py:247
+#: core/models.py:272
 msgid "A user with that username already exists."
 msgstr "Un utilisateur de ce nom existe déjà"
 
-#: core/models.py:249
+#: core/models.py:274
 msgid "first name"
 msgstr "Prénom"
 
-#: core/models.py:250
+#: core/models.py:275
 msgid "last name"
 msgstr "Nom"
 
-#: core/models.py:251
+#: core/models.py:276
 msgid "email address"
 msgstr "adresse email"
 
-#: core/models.py:252
+#: core/models.py:277
 msgid "date of birth"
 msgstr "date de naissance"
 
-#: core/models.py:253
+#: core/models.py:278
 msgid "nick name"
 msgstr "surnom"
 
-#: core/models.py:255
+#: core/models.py:280
 msgid "staff status"
 msgstr "status \"staff\""
 
-#: core/models.py:257
+#: core/models.py:282
 msgid "Designates whether the user can log into this admin site."
 msgstr "Est-ce que l'utilisateur peut se logger à la partie admin du site."
 
-#: core/models.py:260
+#: core/models.py:285
 msgid "active"
 msgstr "actif"
 
-#: core/models.py:263
+#: core/models.py:288
 msgid ""
 "Designates whether this user should be treated as active. Unselect this "
 "instead of deleting accounts."
@@ -2050,163 +2050,163 @@ msgstr ""
 "Est-ce que l'utilisateur doit être traité comme actif. Désélectionnez au "
 "lieu de supprimer les comptes."
 
-#: core/models.py:267
+#: core/models.py:292
 msgid "date joined"
 msgstr "date d'inscription"
 
-#: core/models.py:268
+#: core/models.py:293
 msgid "last update"
 msgstr "dernière mise à jour"
 
-#: core/models.py:270
+#: core/models.py:295
 msgid "superuser"
 msgstr "super-utilisateur"
 
-#: core/models.py:272
+#: core/models.py:297
 msgid "Designates whether this user is a superuser. "
 msgstr "Est-ce que l'utilisateur est super-utilisateur."
 
-#: core/models.py:286
+#: core/models.py:311
 msgid "profile"
 msgstr "profil"
 
-#: core/models.py:294
+#: core/models.py:319
 msgid "avatar"
 msgstr "avatar"
 
-#: core/models.py:302
+#: core/models.py:327
 msgid "scrub"
 msgstr "blouse"
 
-#: core/models.py:308
+#: core/models.py:333
 msgid "sex"
 msgstr "Genre"
 
-#: core/models.py:312
+#: core/models.py:337
 msgid "Man"
 msgstr "Homme"
 
-#: core/models.py:312
+#: core/models.py:337
 msgid "Woman"
 msgstr "Femme"
 
-#: core/models.py:314
+#: core/models.py:339
 msgid "pronouns"
 msgstr "pronoms"
 
-#: core/models.py:316
+#: core/models.py:341
 msgid "tshirt size"
 msgstr "taille de t-shirt"
 
-#: core/models.py:319
+#: core/models.py:344
 msgid "-"
 msgstr "-"
 
-#: core/models.py:320
+#: core/models.py:345
 msgid "XS"
 msgstr "XS"
 
-#: core/models.py:321
+#: core/models.py:346
 msgid "S"
 msgstr "S"
 
-#: core/models.py:322
+#: core/models.py:347
 msgid "M"
 msgstr "M"
 
-#: core/models.py:323
+#: core/models.py:348
 msgid "L"
 msgstr "L"
 
-#: core/models.py:324
+#: core/models.py:349
 msgid "XL"
 msgstr "XL"
 
-#: core/models.py:325
+#: core/models.py:350
 msgid "XXL"
 msgstr "XXL"
 
-#: core/models.py:326
+#: core/models.py:351
 msgid "XXXL"
 msgstr "XXXL"
 
-#: core/models.py:334
+#: core/models.py:359
 msgid "Student"
 msgstr "Étudiant"
 
-#: core/models.py:335
+#: core/models.py:360
 msgid "Administrative agent"
 msgstr "Personnel administratif"
 
-#: core/models.py:336
+#: core/models.py:361
 msgid "Teacher"
 msgstr "Enseignant"
 
-#: core/models.py:337
+#: core/models.py:362
 msgid "Agent"
 msgstr "Personnel"
 
-#: core/models.py:338
+#: core/models.py:363
 msgid "Doctor"
 msgstr "Doctorant"
 
-#: core/models.py:339
+#: core/models.py:364
 msgid "Former student"
 msgstr "Ancien étudiant"
 
-#: core/models.py:340
+#: core/models.py:365
 msgid "Service"
 msgstr "Service"
 
-#: core/models.py:346
+#: core/models.py:371
 msgid "department"
 msgstr "département"
 
-#: core/models.py:353
+#: core/models.py:378
 msgid "dpt option"
 msgstr "Filière"
 
-#: core/models.py:355 pedagogy/models.py:69 pedagogy/models.py:293
+#: core/models.py:380 pedagogy/models.py:69 pedagogy/models.py:293
 msgid "semester"
 msgstr "semestre"
 
-#: core/models.py:356
+#: core/models.py:381
 msgid "quote"
 msgstr "citation"
 
-#: core/models.py:357
+#: core/models.py:382
 msgid "school"
 msgstr "école"
 
-#: core/models.py:359
+#: core/models.py:384
 msgid "promo"
 msgstr "promo"
 
-#: core/models.py:362
+#: core/models.py:387
 msgid "forum signature"
 msgstr "signature du forum"
 
-#: core/models.py:364
+#: core/models.py:389
 msgid "second email address"
 msgstr "adresse email secondaire"
 
-#: core/models.py:366
+#: core/models.py:391
 msgid "parent phone"
 msgstr "téléphone des parents"
 
-#: core/models.py:369
+#: core/models.py:394
 msgid "parent address"
 msgstr "adresse des parents"
 
-#: core/models.py:372
+#: core/models.py:397
 msgid "is subscriber viewable"
 msgstr "profil visible par les cotisants"
 
-#: core/models.py:572
+#: core/models.py:591
 msgid "A user with that username already exists"
 msgstr "Un utilisateur de ce nom d'utilisateur existe déjà"
 
-#: core/models.py:737 core/templates/core/macros.jinja:75
+#: core/models.py:756 core/templates/core/macros.jinja:75
 #: core/templates/core/macros.jinja:77 core/templates/core/macros.jinja:78
 #: core/templates/core/user_detail.jinja:100
 #: core/templates/core/user_detail.jinja:101
@@ -2226,101 +2226,101 @@ msgstr "Un utilisateur de ce nom d'utilisateur existe déjà"
 msgid "Profile"
 msgstr "Profil"
 
-#: core/models.py:856
+#: core/models.py:875
 msgid "Visitor"
 msgstr "Visiteur"
 
-#: core/models.py:863
+#: core/models.py:882
 msgid "receive the Weekmail"
 msgstr "recevoir le Weekmail"
 
-#: core/models.py:864
+#: core/models.py:883
 msgid "show your stats to others"
 msgstr "montrez vos statistiques aux autres"
 
-#: core/models.py:866
+#: core/models.py:885
 msgid "get a notification for every click"
 msgstr "avoir une notification pour chaque click"
 
-#: core/models.py:869
+#: core/models.py:888
 msgid "get a notification for every refilling"
 msgstr "avoir une notification pour chaque rechargement"
 
-#: core/models.py:895 sas/views.py:309
+#: core/models.py:914 sas/views.py:309
 msgid "file name"
 msgstr "nom du fichier"
 
-#: core/models.py:899 core/models.py:1252
+#: core/models.py:918 core/models.py:1271
 msgid "parent"
 msgstr "parent"
 
-#: core/models.py:913
+#: core/models.py:932
 msgid "compressed file"
 msgstr "version allégée"
 
-#: core/models.py:920
+#: core/models.py:939
 msgid "thumbnail"
 msgstr "miniature"
 
-#: core/models.py:928 core/models.py:945
+#: core/models.py:947 core/models.py:964
 msgid "owner"
 msgstr "propriétaire"
 
-#: core/models.py:932 core/models.py:1269 core/views/files.py:223
+#: core/models.py:951 core/models.py:1288 core/views/files.py:223
 msgid "edit group"
 msgstr "groupe d'édition"
 
-#: core/models.py:935 core/models.py:1272 core/views/files.py:226
+#: core/models.py:954 core/models.py:1291 core/views/files.py:226
 msgid "view group"
 msgstr "groupe de vue"
 
-#: core/models.py:937
+#: core/models.py:956
 msgid "is folder"
 msgstr "est un dossier"
 
-#: core/models.py:938
+#: core/models.py:957
 msgid "mime type"
 msgstr "type mime"
 
-#: core/models.py:939
+#: core/models.py:958
 msgid "size"
 msgstr "taille"
 
-#: core/models.py:950
+#: core/models.py:969
 msgid "asked for removal"
 msgstr "retrait demandé"
 
-#: core/models.py:952
+#: core/models.py:971
 msgid "is in the SAS"
 msgstr "est dans le SAS"
 
-#: core/models.py:1021
+#: core/models.py:1040
 msgid "Character '/' not authorized in name"
 msgstr "Le caractère '/' n'est pas autorisé dans les noms de fichier"
 
-#: core/models.py:1023 core/models.py:1027
+#: core/models.py:1042 core/models.py:1046
 msgid "Loop in folder tree"
 msgstr "Boucle dans l'arborescence des dossiers"
 
-#: core/models.py:1030
+#: core/models.py:1049
 msgid "You can not make a file be a children of a non folder file"
 msgstr ""
 "Vous ne pouvez pas mettre un fichier enfant de quelque chose qui n'est pas "
 "un dossier"
 
-#: core/models.py:1041
+#: core/models.py:1060
 msgid "Duplicate file"
 msgstr "Un fichier de ce nom existe déjà"
 
-#: core/models.py:1058
+#: core/models.py:1077
 msgid "You must provide a file"
 msgstr "Vous devez fournir un fichier"
 
-#: core/models.py:1235
+#: core/models.py:1254
 msgid "page unix name"
 msgstr "nom unix de la page"
 
-#: core/models.py:1241
+#: core/models.py:1260
 msgid ""
 "Enter a valid page name. This value may contain only unaccented letters, "
 "numbers and ./+/-/_ characters."
@@ -2328,55 +2328,55 @@ msgstr ""
 "Entrez un nom de page correct. Uniquement des lettres non accentuées, "
 "numéros, et ./+/-/_"
 
-#: core/models.py:1259
+#: core/models.py:1278
 msgid "page name"
 msgstr "nom de la page"
 
-#: core/models.py:1264
+#: core/models.py:1283
 msgid "owner group"
 msgstr "groupe propriétaire"
 
-#: core/models.py:1277
+#: core/models.py:1296
 msgid "lock user"
 msgstr "utilisateur bloquant"
 
-#: core/models.py:1284
+#: core/models.py:1303
 msgid "lock_timeout"
 msgstr "décompte du déblocage"
 
-#: core/models.py:1334
+#: core/models.py:1353
 msgid "Duplicate page"
 msgstr "Une page de ce nom existe déjà"
 
-#: core/models.py:1337
+#: core/models.py:1356
 msgid "Loop in page tree"
 msgstr "Boucle dans l'arborescence des pages"
 
-#: core/models.py:1457
+#: core/models.py:1476
 msgid "revision"
 msgstr "révision"
 
-#: core/models.py:1458
+#: core/models.py:1477
 msgid "page title"
 msgstr "titre de la page"
 
-#: core/models.py:1459
+#: core/models.py:1478
 msgid "page content"
 msgstr "contenu de la page"
 
-#: core/models.py:1500
+#: core/models.py:1519
 msgid "url"
 msgstr "url"
 
-#: core/models.py:1501
+#: core/models.py:1520
 msgid "param"
 msgstr "param"
 
-#: core/models.py:1506
+#: core/models.py:1525
 msgid "viewed"
 msgstr "vue"
 
-#: core/models.py:1564
+#: core/models.py:1583
 msgid "operation type"
 msgstr "type d'opération"
 
@@ -2474,13 +2474,13 @@ msgstr "Forum"
 msgid "Gallery"
 msgstr "Photos"
 
-#: core/templates/core/base.jinja:230 counter/models.py:421
+#: core/templates/core/base.jinja:230 counter/models.py:466
 #: counter/templates/counter/counter_list.jinja:11
 #: eboutic/templates/eboutic/eboutic_main.jinja:4
 #: eboutic/templates/eboutic/eboutic_main.jinja:22
 #: eboutic/templates/eboutic/eboutic_makecommand.jinja:16
 #: eboutic/templates/eboutic/eboutic_payment_result.jinja:4
-#: sith/settings.py:410 sith/settings.py:418
+#: sith/settings.py:419 sith/settings.py:427
 msgid "Eboutic"
 msgstr "Eboutic"
 
@@ -3039,7 +3039,7 @@ msgid "Eboutic invoices"
 msgstr "Facture eboutic"
 
 #: core/templates/core/user_account.jinja:54
-#: core/templates/core/user_tools.jinja:58 counter/views.py:710
+#: core/templates/core/user_tools.jinja:58 counter/views.py:713
 msgid "Etickets"
 msgstr "Etickets"
 
@@ -3375,7 +3375,7 @@ msgid "Subscription stats"
 msgstr "Statistiques de cotisation"
 
 #: core/templates/core/user_tools.jinja:48 counter/forms.py:164
-#: counter/views.py:680
+#: counter/views.py:683
 msgid "Counters"
 msgstr "Comptoirs"
 
@@ -3392,12 +3392,12 @@ msgid "Product types management"
 msgstr "Gestion des types de produit"
 
 #: core/templates/core/user_tools.jinja:56
-#: counter/templates/counter/cash_summary_list.jinja:23 counter/views.py:700
+#: counter/templates/counter/cash_summary_list.jinja:23 counter/views.py:703
 msgid "Cash register summaries"
 msgstr "Relevés de caisse"
 
 #: core/templates/core/user_tools.jinja:57
-#: counter/templates/counter/invoices_call.jinja:4 counter/views.py:705
+#: counter/templates/counter/invoices_call.jinja:4 counter/views.py:708
 msgid "Invoices call"
 msgstr "Appels à facture"
 
@@ -3449,12 +3449,12 @@ msgid "Moderate pictures"
 msgstr "Modérer les photos"
 
 #: core/templates/core/user_tools.jinja:165
-#: pedagogy/templates/pedagogy/guide.jinja:21
+#: pedagogy/templates/pedagogy/guide.jinja:25
 msgid "Create UV"
 msgstr "Créer UV"
 
 #: core/templates/core/user_tools.jinja:166
-#: pedagogy/templates/pedagogy/guide.jinja:24
+#: pedagogy/templates/pedagogy/guide.jinja:28
 #: trombi/templates/trombi/detail.jinja:10
 msgid "Moderate comments"
 msgstr "Modérer les commentaires"
@@ -3495,7 +3495,7 @@ msgstr "Ajouter un nouveau dossier"
 msgid "Error creating folder %(folder_name)s: %(msg)s"
 msgstr "Erreur de création du dossier %(folder_name)s : %(msg)s"
 
-#: core/views/files.py:153 core/views/forms.py:279 core/views/forms.py:286
+#: core/views/files.py:153 core/views/forms.py:277 core/views/forms.py:284
 #: sas/views.py:81
 #, python-format
 msgid "Error uploading file %(file_name)s: %(msg)s"
@@ -3505,23 +3505,23 @@ msgstr "Erreur d'envoi du fichier %(file_name)s : %(msg)s"
 msgid "Apply rights recursively"
 msgstr "Appliquer les droits récursivement"
 
-#: core/views/forms.py:88
+#: core/views/forms.py:86
 msgid "Unsupported NFC card"
 msgstr "Carte NFC non supportée"
 
-#: core/views/forms.py:102 core/views/forms.py:110
+#: core/views/forms.py:100 core/views/forms.py:108
 msgid "Choose file"
 msgstr "Choisir un fichier"
 
-#: core/views/forms.py:126 core/views/forms.py:134
+#: core/views/forms.py:124 core/views/forms.py:132
 msgid "Choose user"
 msgstr "Choisir un utilisateur"
 
-#: core/views/forms.py:166
+#: core/views/forms.py:164
 msgid "Username, email, or account number"
 msgstr "Nom d'utilisateur, email, ou numéro de compte AE"
 
-#: core/views/forms.py:229
+#: core/views/forms.py:227
 msgid ""
 "Profile: you need to be visible on the picture, in order to be recognized (e."
 "g. by the barmen)"
@@ -3529,55 +3529,54 @@ msgstr ""
 "Photo de profil: vous devez être visible sur la photo afin d'être reconnu "
 "(par exemple par les barmen)"
 
-#: core/views/forms.py:234
+#: core/views/forms.py:232
 msgid "Avatar: used on the forum"
 msgstr "Avatar : utilisé sur le forum"
 
-#: core/views/forms.py:238
+#: core/views/forms.py:236
 msgid "Scrub: let other know how your scrub looks like!"
 msgstr "Blouse : montrez aux autres à quoi ressemble votre blouse !"
 
-#: core/views/forms.py:290
+#: core/views/forms.py:288
 msgid "Bad image format, only jpeg, png, webp and gif are accepted"
 msgstr "Mauvais format d'image, seuls les jpeg, png, webp et gif sont acceptés"
 
-#: core/views/forms.py:311
+#: core/views/forms.py:309
 msgid "Godfather / Godmother"
 msgstr "Parrain / Marraine"
 
-#: core/views/forms.py:312
+#: core/views/forms.py:310
 msgid "Godchild"
 msgstr "Fillot / Fillote"
 
-#: core/views/forms.py:317 counter/forms.py:72 trombi/views.py:149
+#: core/views/forms.py:315 counter/forms.py:72 trombi/views.py:149
 msgid "Select user"
 msgstr "Choisir un utilisateur"
 
-#: core/views/forms.py:327
+#: core/views/forms.py:325
 msgid "This user does not exist"
 msgstr "Cet utilisateur n'existe pas"
 
-#: core/views/forms.py:329
+#: core/views/forms.py:327
 msgid "You cannot be related to yourself"
 msgstr "Vous ne pouvez pas être relié à vous-même"
 
-#: core/views/forms.py:341
+#: core/views/forms.py:339
 #, python-format
 msgid "%s is already your godfather"
 msgstr "%s est déjà votre parrain/marraine"
 
-#: core/views/forms.py:347
-#, fuzzy, python-format
-#| msgid "This user has already commented on this UV"
+#: core/views/forms.py:345
+#, python-format
 msgid "%s is already your godchild"
 msgstr "%s est déjà votre fillot/fillote"
 
-#: core/views/forms.py:361 core/views/forms.py:379 election/models.py:22
+#: core/views/forms.py:359 core/views/forms.py:377 election/models.py:22
 #: election/views.py:147
 msgid "edit groups"
 msgstr "groupe d'édition"
 
-#: core/views/forms.py:364 core/views/forms.py:382 election/models.py:29
+#: core/views/forms.py:362 core/views/forms.py:380 election/models.py:29
 #: election/views.py:150
 msgid "view groups"
 msgstr "groupe de vue"
@@ -3608,8 +3607,8 @@ msgstr "Photos"
 msgid "Galaxy"
 msgstr "Galaxie"
 
-#: counter/apps.py:30 counter/models.py:437 counter/models.py:896
-#: counter/models.py:932 launderette/models.py:32
+#: counter/apps.py:30 counter/models.py:482 counter/models.py:941
+#: counter/models.py:977 launderette/models.py:32
 msgid "counter"
 msgstr "comptoir"
 
@@ -3629,6 +3628,10 @@ msgstr "Produit parent"
 msgid "Buying groups"
 msgstr "Groupes d'achat"
 
+#: counter/management/commands/dump_warning_mail.py:82
+msgid "Clearing of your AE account"
+msgstr "Vidange de votre compte AE"
+
 #: counter/migrations/0013_customer_recorded_products.py:25
 msgid "Ecocup regularization"
 msgstr "Régularization des ecocups"
@@ -3649,7 +3652,7 @@ msgstr "client"
 msgid "customers"
 msgstr "clients"
 
-#: counter/models.py:74 counter/views.py:262
+#: counter/models.py:74 counter/views.py:265
 msgid "Not enough money"
 msgstr "Solde insuffisant"
 
@@ -3685,117 +3688,129 @@ msgstr "Pays"
 msgid "Phone number"
 msgstr "Numéro de téléphone"
 
-#: counter/models.py:232 counter/models.py:258
+#: counter/models.py:228
+msgid "When the mail warning that the account was about to be dumped was sent."
+msgstr "Quand le mail d'avertissement de la vidange du compte a été envoyé."
+
+#: counter/models.py:233
+msgid "Set this to True if the warning mail received an error"
+msgstr "Mettre à True si le mail a reçu une erreur"
+
+#: counter/models.py:240
+msgid "The operation that emptied the account."
+msgstr "L'opération qui a vidé le compte."
+
+#: counter/models.py:277 counter/models.py:303
 msgid "product type"
 msgstr "type du produit"
 
-#: counter/models.py:264
+#: counter/models.py:309
 msgid "purchase price"
 msgstr "prix d'achat"
 
-#: counter/models.py:265
+#: counter/models.py:310
 msgid "selling price"
 msgstr "prix de vente"
 
-#: counter/models.py:266
+#: counter/models.py:311
 msgid "special selling price"
 msgstr "prix de vente spécial"
 
-#: counter/models.py:273
+#: counter/models.py:318
 msgid "icon"
 msgstr "icône"
 
-#: counter/models.py:278
+#: counter/models.py:323
 msgid "limit age"
 msgstr "âge limite"
 
-#: counter/models.py:279
+#: counter/models.py:324
 msgid "tray price"
 msgstr "prix plateau"
 
-#: counter/models.py:283
+#: counter/models.py:328
 msgid "parent product"
 msgstr "produit parent"
 
-#: counter/models.py:289
+#: counter/models.py:334
 msgid "buying groups"
 msgstr "groupe d'achat"
 
-#: counter/models.py:291 election/models.py:50
+#: counter/models.py:336 election/models.py:50
 msgid "archived"
 msgstr "archivé"
 
-#: counter/models.py:294 counter/models.py:1032
+#: counter/models.py:339 counter/models.py:1077
 msgid "product"
 msgstr "produit"
 
-#: counter/models.py:416
+#: counter/models.py:461
 msgid "products"
 msgstr "produits"
 
-#: counter/models.py:419
+#: counter/models.py:464
 msgid "counter type"
 msgstr "type de comptoir"
 
-#: counter/models.py:421
+#: counter/models.py:466
 msgid "Bar"
 msgstr "Bar"
 
-#: counter/models.py:421
+#: counter/models.py:466
 msgid "Office"
 msgstr "Bureau"
 
-#: counter/models.py:424
+#: counter/models.py:469
 msgid "sellers"
 msgstr "vendeurs"
 
-#: counter/models.py:432 launderette/models.py:192
+#: counter/models.py:477 launderette/models.py:192
 msgid "token"
 msgstr "jeton"
 
-#: counter/models.py:627
+#: counter/models.py:672
 msgid "bank"
 msgstr "banque"
 
-#: counter/models.py:629 counter/models.py:730
+#: counter/models.py:674 counter/models.py:775
 msgid "is validated"
 msgstr "est validé"
 
-#: counter/models.py:634
+#: counter/models.py:679
 msgid "refilling"
 msgstr "rechargement"
 
-#: counter/models.py:707 eboutic/models.py:245
+#: counter/models.py:752 eboutic/models.py:245
 msgid "unit price"
 msgstr "prix unitaire"
 
-#: counter/models.py:708 counter/models.py:1012 eboutic/models.py:246
+#: counter/models.py:753 counter/models.py:1057 eboutic/models.py:246
 msgid "quantity"
 msgstr "quantité"
 
-#: counter/models.py:727
+#: counter/models.py:772
 msgid "Sith account"
 msgstr "Compte utilisateur"
 
-#: counter/models.py:727 sith/settings.py:403 sith/settings.py:408
-#: sith/settings.py:428
+#: counter/models.py:772 sith/settings.py:412 sith/settings.py:417
+#: sith/settings.py:437
 msgid "Credit card"
 msgstr "Carte bancaire"
 
-#: counter/models.py:735
+#: counter/models.py:780
 msgid "selling"
 msgstr "vente"
 
-#: counter/models.py:839
+#: counter/models.py:884
 msgid "Unknown event"
 msgstr "Événement inconnu"
 
-#: counter/models.py:840
+#: counter/models.py:885
 #, python-format
 msgid "Eticket bought for the event %(event)s"
 msgstr "Eticket acheté pour l'événement %(event)s"
 
-#: counter/models.py:842 counter/models.py:865
+#: counter/models.py:887 counter/models.py:910
 #, python-format
 msgid ""
 "You bought an eticket for the event %(event)s.\n"
@@ -3807,66 +3822,111 @@ msgstr ""
 "Vous pouvez également retrouver tous vos e-tickets sur votre page de compte "
 "%(url)s."
 
-#: counter/models.py:901
+#: counter/models.py:946
 msgid "last activity date"
 msgstr "dernière activité"
 
-#: counter/models.py:904
+#: counter/models.py:949
 msgid "permanency"
 msgstr "permanence"
 
-#: counter/models.py:937
+#: counter/models.py:982
 msgid "emptied"
 msgstr "coffre vidée"
 
-#: counter/models.py:940
+#: counter/models.py:985
 msgid "cash register summary"
 msgstr "relevé de caisse"
 
-#: counter/models.py:1008
+#: counter/models.py:1053
 msgid "cash summary"
 msgstr "relevé"
 
-#: counter/models.py:1011
+#: counter/models.py:1056
 msgid "value"
 msgstr "valeur"
 
-#: counter/models.py:1014
+#: counter/models.py:1059
 msgid "check"
 msgstr "chèque"
 
-#: counter/models.py:1016
+#: counter/models.py:1061
 msgid "True if this is a bank check, else False"
 msgstr "Vrai si c'est un chèque, sinon Faux."
 
-#: counter/models.py:1020
+#: counter/models.py:1065
 msgid "cash register summary item"
 msgstr "élément de relevé de caisse"
 
-#: counter/models.py:1036
+#: counter/models.py:1081
 msgid "banner"
 msgstr "bannière"
 
-#: counter/models.py:1038
+#: counter/models.py:1083
 msgid "event date"
 msgstr "date de l'événement"
 
-#: counter/models.py:1040
+#: counter/models.py:1085
 msgid "event title"
 msgstr "titre de l'événement"
 
-#: counter/models.py:1042
+#: counter/models.py:1087
 msgid "secret"
 msgstr "secret"
 
-#: counter/models.py:1081
+#: counter/models.py:1126
 msgid "uid"
 msgstr "uid"
 
-#: counter/models.py:1086
+#: counter/models.py:1131
 msgid "student cards"
 msgstr "cartes étudiante"
 
+#: counter/templates/counter/account_dump_warning_mail.jinja:6
+#, python-format
+msgid ""
+"You received this email because your last subscription to the\n"
+"    Students' association ended on %(date)s."
+msgstr ""
+"Vous recevez ce mail car votre dernière cotisation à l'assocation des "
+"étudiants de l'UTBM s'est achevée le %(date)s."
+
+#: counter/templates/counter/account_dump_warning_mail.jinja:11
+#, python-format
+msgid ""
+"In accordance with the Internal Regulations, the balance of any\n"
+"    inactive AE account for more than 2 years automatically goes back\n"
+"    to the AE.\n"
+"    The money present on your account will therefore be recovered in full\n"
+"    on %(date)s, for a total of %(amount)s €."
+msgstr ""
+"Conformément au Règlement intérieur, le solde de tout compte AE inactif "
+"depuis plus de 2 ans revient de droit à l'AE. L'argent présent sur votre "
+"compte sera donc récupéré en totalité le %(date)s, pour un total de "
+"%(amount)s €. "
+
+#: counter/templates/counter/account_dump_warning_mail.jinja:19
+msgid ""
+"However, if your subscription is renewed by this date,\n"
+"    your right to keep the money in your AE account will be renewed."
+msgstr ""
+"Cependant, si votre cotisation est renouvelée d'ici cette date, votre droit "
+"à conserver l'argent de votre compte AE sera renouvelé."
+
+#: counter/templates/counter/account_dump_warning_mail.jinja:25
+msgid ""
+"You can also request a refund by sending an email to\n"
+"      ae@utbm.fr\n"
+"      before the aforementioned date."
+msgstr ""
+"Vous pouvez également effectuer une demande de remboursement par mail à "
+"l'adresse ae@utbm.fr avant la date "
+"susmentionnée."
+
+#: counter/templates/counter/account_dump_warning_mail.jinja:32
+msgid "Sincerely"
+msgstr "Cordialement"
+
 #: counter/templates/counter/activity.jinja:5
 #: counter/templates/counter/activity.jinja:13
 #, python-format
@@ -3910,7 +3970,7 @@ msgstr "Liste des relevés de caisse"
 msgid "Theoric sums"
 msgstr "Sommes théoriques"
 
-#: counter/templates/counter/cash_summary_list.jinja:36 counter/views.py:942
+#: counter/templates/counter/cash_summary_list.jinja:36 counter/views.py:945
 msgid "Emptied"
 msgstr "Coffre vidé"
 
@@ -4136,101 +4196,101 @@ msgstr "Temps"
 msgid "Top 100 barman %(counter_name)s (all semesters)"
 msgstr "Top 100 barman %(counter_name)s (tous les semestres)"
 
-#: counter/views.py:148
+#: counter/views.py:151
 msgid "Cash summary"
 msgstr "Relevé de caisse"
 
-#: counter/views.py:157
+#: counter/views.py:160
 msgid "Last operations"
 msgstr "Dernières opérations"
 
-#: counter/views.py:204
+#: counter/views.py:207
 msgid "Bad credentials"
 msgstr "Mauvais identifiants"
 
-#: counter/views.py:206
+#: counter/views.py:209
 msgid "User is not barman"
 msgstr "L'utilisateur n'est pas barman."
 
-#: counter/views.py:211
+#: counter/views.py:214
 msgid "Bad location, someone is already logged in somewhere else"
 msgstr "Mauvais comptoir, quelqu'un est déjà connecté ailleurs"
 
-#: counter/views.py:253
+#: counter/views.py:256
 msgid "Too young for that product"
 msgstr "Trop jeune pour ce produit"
 
-#: counter/views.py:256
+#: counter/views.py:259
 msgid "Not allowed for that product"
 msgstr "Non autorisé pour ce produit"
 
-#: counter/views.py:259
+#: counter/views.py:262
 msgid "No date of birth provided"
 msgstr "Pas de date de naissance renseignée"
 
-#: counter/views.py:548
+#: counter/views.py:551
 msgid "You have not enough money to buy all the basket"
 msgstr "Vous n'avez pas assez d'argent pour acheter le panier"
 
-#: counter/views.py:675
+#: counter/views.py:678
 msgid "Counter administration"
 msgstr "Administration des comptoirs"
 
-#: counter/views.py:695
+#: counter/views.py:698
 msgid "Product types"
 msgstr "Types de produit"
 
-#: counter/views.py:899
+#: counter/views.py:902
 msgid "10 cents"
 msgstr "10 centimes"
 
-#: counter/views.py:900
+#: counter/views.py:903
 msgid "20 cents"
 msgstr "20 centimes"
 
-#: counter/views.py:901
+#: counter/views.py:904
 msgid "50 cents"
 msgstr "50 centimes"
 
-#: counter/views.py:902
+#: counter/views.py:905
 msgid "1 euro"
 msgstr "1 €"
 
-#: counter/views.py:903
+#: counter/views.py:906
 msgid "2 euros"
 msgstr "2 €"
 
-#: counter/views.py:904
+#: counter/views.py:907
 msgid "5 euros"
 msgstr "5 €"
 
-#: counter/views.py:905
+#: counter/views.py:908
 msgid "10 euros"
 msgstr "10 €"
 
-#: counter/views.py:906
+#: counter/views.py:909
 msgid "20 euros"
 msgstr "20 €"
 
-#: counter/views.py:907
+#: counter/views.py:910
 msgid "50 euros"
 msgstr "50 €"
 
-#: counter/views.py:909
+#: counter/views.py:912
 msgid "100 euros"
 msgstr "100 €"
 
-#: counter/views.py:912 counter/views.py:918 counter/views.py:924
-#: counter/views.py:930 counter/views.py:936
+#: counter/views.py:915 counter/views.py:921 counter/views.py:927
+#: counter/views.py:933 counter/views.py:939
 msgid "Check amount"
 msgstr "Montant du chèque"
 
-#: counter/views.py:915 counter/views.py:921 counter/views.py:927
-#: counter/views.py:933 counter/views.py:939
+#: counter/views.py:918 counter/views.py:924 counter/views.py:930
+#: counter/views.py:936 counter/views.py:942
 msgid "Check quantity"
 msgstr "Nombre de chèque"
 
-#: counter/views.py:1459
+#: counter/views.py:1462
 msgid "people(s)"
 msgstr "personne(s)"
 
@@ -4803,12 +4863,12 @@ msgid "Washing and drying"
 msgstr "Lavage et séchage"
 
 #: launderette/templates/launderette/launderette_book.jinja:27
-#: sith/settings.py:639
+#: sith/settings.py:653
 msgid "Washing"
 msgstr "Lavage"
 
 #: launderette/templates/launderette/launderette_book.jinja:31
-#: sith/settings.py:639
+#: sith/settings.py:653
 msgid "Drying"
 msgstr "Séchage"
 
@@ -5008,26 +5068,26 @@ msgstr "raison"
 msgid "UV Guide"
 msgstr "Guide des UVs"
 
-#: pedagogy/templates/pedagogy/guide.jinja:55
+#: pedagogy/templates/pedagogy/guide.jinja:59
 #, python-format
 msgid "%(display_name)s"
 msgstr "%(display_name)s"
 
-#: pedagogy/templates/pedagogy/guide.jinja:69
+#: pedagogy/templates/pedagogy/guide.jinja:73
 #, python-format
 msgid "%(credit_type)s"
 msgstr "%(credit_type)s"
 
-#: pedagogy/templates/pedagogy/guide.jinja:87
+#: pedagogy/templates/pedagogy/guide.jinja:91
 #: pedagogy/templates/pedagogy/moderation.jinja:12
 msgid "UV"
 msgstr "UE"
 
-#: pedagogy/templates/pedagogy/guide.jinja:89
+#: pedagogy/templates/pedagogy/guide.jinja:93
 msgid "Department"
 msgstr "Département"
 
-#: pedagogy/templates/pedagogy/guide.jinja:90
+#: pedagogy/templates/pedagogy/guide.jinja:94
 msgid "Credit type"
 msgstr "Type de crédit"
 
@@ -5266,10 +5326,8 @@ msgid "Ask for removal"
 msgstr "Demander le retrait"
 
 #: sas/templates/sas/picture.jinja:118 sas/templates/sas/picture.jinja:129
-#, fuzzy
-#| msgid "Previous"
 msgid "Previous picture"
-msgstr "Précédent"
+msgstr "Image précédente"
 
 #: sas/templates/sas/picture.jinja:137
 msgid "People"
@@ -5292,380 +5350,380 @@ msgstr "Erreur de création de l'album %(album)s : %(msg)s"
 msgid "Add user"
 msgstr "Ajouter une personne"
 
-#: sith/settings.py:246 sith/settings.py:465
+#: sith/settings.py:255 sith/settings.py:474
 msgid "English"
 msgstr "Anglais"
 
-#: sith/settings.py:246 sith/settings.py:464
+#: sith/settings.py:255 sith/settings.py:473
 msgid "French"
 msgstr "Français"
 
-#: sith/settings.py:384
+#: sith/settings.py:393
 msgid "TC"
 msgstr "TC"
 
-#: sith/settings.py:385
+#: sith/settings.py:394
 msgid "IMSI"
 msgstr "IMSI"
 
-#: sith/settings.py:386
+#: sith/settings.py:395
 msgid "IMAP"
 msgstr "IMAP"
 
-#: sith/settings.py:387
+#: sith/settings.py:396
 msgid "INFO"
 msgstr "INFO"
 
-#: sith/settings.py:388
+#: sith/settings.py:397
 msgid "GI"
 msgstr "GI"
 
-#: sith/settings.py:389 sith/settings.py:475
+#: sith/settings.py:398 sith/settings.py:484
 msgid "E"
 msgstr "E"
 
-#: sith/settings.py:390
+#: sith/settings.py:399
 msgid "EE"
 msgstr "EE"
 
-#: sith/settings.py:391
+#: sith/settings.py:400
 msgid "GESC"
 msgstr "GESC"
 
-#: sith/settings.py:392
+#: sith/settings.py:401
 msgid "GMC"
 msgstr "GMC"
 
-#: sith/settings.py:393
+#: sith/settings.py:402
 msgid "MC"
 msgstr "MC"
 
-#: sith/settings.py:394
+#: sith/settings.py:403
 msgid "EDIM"
 msgstr "EDIM"
 
-#: sith/settings.py:395
+#: sith/settings.py:404
 msgid "Humanities"
 msgstr "Humanités"
 
-#: sith/settings.py:396
+#: sith/settings.py:405
 msgid "N/A"
 msgstr "N/A"
 
-#: sith/settings.py:400 sith/settings.py:407 sith/settings.py:426
+#: sith/settings.py:409 sith/settings.py:416 sith/settings.py:435
 msgid "Check"
 msgstr "Chèque"
 
-#: sith/settings.py:401 sith/settings.py:409 sith/settings.py:427
+#: sith/settings.py:410 sith/settings.py:418 sith/settings.py:436
 msgid "Cash"
 msgstr "Espèces"
 
-#: sith/settings.py:402
+#: sith/settings.py:411
 msgid "Transfert"
 msgstr "Virement"
 
-#: sith/settings.py:415
+#: sith/settings.py:424
 msgid "Belfort"
 msgstr "Belfort"
 
-#: sith/settings.py:416
+#: sith/settings.py:425
 msgid "Sevenans"
 msgstr "Sevenans"
 
-#: sith/settings.py:417
+#: sith/settings.py:426
 msgid "Montbéliard"
 msgstr "Montbéliard"
 
-#: sith/settings.py:445
+#: sith/settings.py:454
 msgid "Free"
 msgstr "Libre"
 
-#: sith/settings.py:446
+#: sith/settings.py:455
 msgid "CS"
 msgstr "CS"
 
-#: sith/settings.py:447
+#: sith/settings.py:456
 msgid "TM"
 msgstr "TM"
 
-#: sith/settings.py:448
+#: sith/settings.py:457
 msgid "OM"
 msgstr "OM"
 
-#: sith/settings.py:449
+#: sith/settings.py:458
 msgid "QC"
 msgstr "QC"
 
-#: sith/settings.py:450
+#: sith/settings.py:459
 msgid "EC"
 msgstr "EC"
 
-#: sith/settings.py:451
+#: sith/settings.py:460
 msgid "RN"
 msgstr "RN"
 
-#: sith/settings.py:452
+#: sith/settings.py:461
 msgid "ST"
 msgstr "ST"
 
-#: sith/settings.py:453
+#: sith/settings.py:462
 msgid "EXT"
 msgstr "EXT"
 
-#: sith/settings.py:458
+#: sith/settings.py:467
 msgid "Autumn"
 msgstr "Automne"
 
-#: sith/settings.py:459
+#: sith/settings.py:468
 msgid "Spring"
 msgstr "Printemps"
 
-#: sith/settings.py:460
+#: sith/settings.py:469
 msgid "Autumn and spring"
 msgstr "Automne et printemps"
 
-#: sith/settings.py:466
+#: sith/settings.py:475
 msgid "German"
 msgstr "Allemand"
 
-#: sith/settings.py:467
+#: sith/settings.py:476
 msgid "Spanish"
 msgstr "Espagnol"
 
-#: sith/settings.py:471
+#: sith/settings.py:480
 msgid "A"
 msgstr "A"
 
-#: sith/settings.py:472
+#: sith/settings.py:481
 msgid "B"
 msgstr "B"
 
-#: sith/settings.py:473
+#: sith/settings.py:482
 msgid "C"
 msgstr "C"
 
-#: sith/settings.py:474
+#: sith/settings.py:483
 msgid "D"
 msgstr "D"
 
-#: sith/settings.py:476
+#: sith/settings.py:485
 msgid "FX"
 msgstr "FX"
 
-#: sith/settings.py:477
+#: sith/settings.py:486
 msgid "F"
 msgstr "F"
 
-#: sith/settings.py:478
+#: sith/settings.py:487
 msgid "Abs"
 msgstr "Abs"
 
-#: sith/settings.py:482
+#: sith/settings.py:491
 msgid "Selling deletion"
 msgstr "Suppression de vente"
 
-#: sith/settings.py:483
+#: sith/settings.py:492
 msgid "Refilling deletion"
 msgstr "Suppression de rechargement"
 
-#: sith/settings.py:520
+#: sith/settings.py:534
 msgid "One semester"
 msgstr "Un semestre, 20 €"
 
-#: sith/settings.py:521
+#: sith/settings.py:535
 msgid "Two semesters"
 msgstr "Deux semestres, 35 €"
 
-#: sith/settings.py:523
+#: sith/settings.py:537
 msgid "Common core cursus"
 msgstr "Cursus tronc commun, 60 €"
 
-#: sith/settings.py:527
+#: sith/settings.py:541
 msgid "Branch cursus"
 msgstr "Cursus branche, 60 €"
 
-#: sith/settings.py:528
+#: sith/settings.py:542
 msgid "Alternating cursus"
 msgstr "Cursus alternant, 30 €"
 
-#: sith/settings.py:529
+#: sith/settings.py:543
 msgid "Honorary member"
 msgstr "Membre honoraire, 0 €"
 
-#: sith/settings.py:530
+#: sith/settings.py:544
 msgid "Assidu member"
 msgstr "Membre d'Assidu, 0 €"
 
-#: sith/settings.py:531
+#: sith/settings.py:545
 msgid "Amicale/DOCEO member"
 msgstr "Membre de l'Amicale/DOCEO, 0 €"
 
-#: sith/settings.py:532
+#: sith/settings.py:546
 msgid "UT network member"
 msgstr "Cotisant du réseau UT, 0 €"
 
-#: sith/settings.py:533
+#: sith/settings.py:547
 msgid "CROUS member"
 msgstr "Membres du CROUS, 0 €"
 
-#: sith/settings.py:534
+#: sith/settings.py:548
 msgid "Sbarro/ESTA member"
 msgstr "Membre de Sbarro ou de l'ESTA, 20 €"
 
-#: sith/settings.py:536
+#: sith/settings.py:550
 msgid "One semester Welcome Week"
 msgstr "Un semestre Welcome Week"
 
-#: sith/settings.py:540
+#: sith/settings.py:554
 msgid "One month for free"
 msgstr "Un mois gratuit"
 
-#: sith/settings.py:541
+#: sith/settings.py:555
 msgid "Two months for free"
 msgstr "Deux mois gratuits"
 
-#: sith/settings.py:542
+#: sith/settings.py:556
 msgid "Eurok's volunteer"
 msgstr "Bénévole Eurockéennes"
 
-#: sith/settings.py:544
+#: sith/settings.py:558
 msgid "Six weeks for free"
 msgstr "6 semaines gratuites"
 
-#: sith/settings.py:548
+#: sith/settings.py:562
 msgid "One day"
 msgstr "Un jour"
 
-#: sith/settings.py:549
+#: sith/settings.py:563
 msgid "GA staff member"
 msgstr "Membre staff GA (2 semaines), 1 €"
 
-#: sith/settings.py:552
+#: sith/settings.py:566
 msgid "One semester (-20%)"
 msgstr "Un semestre (-20%), 12 €"
 
-#: sith/settings.py:557
+#: sith/settings.py:571
 msgid "Two semesters (-20%)"
 msgstr "Deux semestres (-20%), 22 €"
 
-#: sith/settings.py:562
+#: sith/settings.py:576
 msgid "Common core cursus (-20%)"
 msgstr "Cursus tronc commun (-20%), 36 €"
 
-#: sith/settings.py:567
+#: sith/settings.py:581
 msgid "Branch cursus (-20%)"
 msgstr "Cursus branche (-20%), 36 €"
 
-#: sith/settings.py:572
+#: sith/settings.py:586
 msgid "Alternating cursus (-20%)"
 msgstr "Cursus alternant (-20%), 24 €"
 
-#: sith/settings.py:578
+#: sith/settings.py:592
 msgid "One year for free(CA offer)"
 msgstr "Une année offerte (Offre CA)"
 
-#: sith/settings.py:598
+#: sith/settings.py:612
 msgid "President"
 msgstr "Président⸱e"
 
-#: sith/settings.py:599
+#: sith/settings.py:613
 msgid "Vice-President"
 msgstr "Vice-Président⸱e"
 
-#: sith/settings.py:600
+#: sith/settings.py:614
 msgid "Treasurer"
 msgstr "Trésorier⸱e"
 
-#: sith/settings.py:601
+#: sith/settings.py:615
 msgid "Communication supervisor"
 msgstr "Responsable communication"
 
-#: sith/settings.py:602
+#: sith/settings.py:616
 msgid "Secretary"
 msgstr "Secrétaire"
 
-#: sith/settings.py:603
+#: sith/settings.py:617
 msgid "IT supervisor"
 msgstr "Responsable info"
 
-#: sith/settings.py:604
+#: sith/settings.py:618
 msgid "Board member"
 msgstr "Membre du bureau"
 
-#: sith/settings.py:605
+#: sith/settings.py:619
 msgid "Active member"
 msgstr "Membre actif⸱ve"
 
-#: sith/settings.py:606
+#: sith/settings.py:620
 msgid "Curious"
 msgstr "Curieux⸱euse"
 
-#: sith/settings.py:643
+#: sith/settings.py:657
 msgid "A new poster needs to be moderated"
 msgstr "Une nouvelle affiche a besoin d'être modérée"
 
-#: sith/settings.py:644
+#: sith/settings.py:658
 msgid "A new mailing list needs to be moderated"
 msgstr "Une nouvelle mailing list a besoin d'être modérée"
 
-#: sith/settings.py:647
+#: sith/settings.py:661
 msgid "A new pedagogy comment has been signaled for moderation"
 msgstr ""
 "Un nouveau commentaire de la pédagogie a été signalé pour la modération"
 
-#: sith/settings.py:649
+#: sith/settings.py:663
 #, python-format
 msgid "There are %s fresh news to be moderated"
 msgstr "Il y a %s nouvelles toutes fraîches à modérer"
 
-#: sith/settings.py:650
+#: sith/settings.py:664
 msgid "New files to be moderated"
 msgstr "Nouveaux fichiers à modérer"
 
-#: sith/settings.py:651
+#: sith/settings.py:665
 #, python-format
 msgid "There are %s pictures to be moderated in the SAS"
 msgstr "Il y a %s photos à modérer dans le SAS"
 
-#: sith/settings.py:652
+#: sith/settings.py:666
 msgid "You've been identified on some pictures"
 msgstr "Vous avez été identifié sur des photos"
 
-#: sith/settings.py:653
+#: sith/settings.py:667
 #, python-format
 msgid "You just refilled of %s €"
 msgstr "Vous avez rechargé votre compte de %s€"
 
-#: sith/settings.py:654
+#: sith/settings.py:668
 #, python-format
 msgid "You just bought %s"
 msgstr "Vous avez acheté %s"
 
-#: sith/settings.py:655
+#: sith/settings.py:669
 msgid "You have a notification"
 msgstr "Vous avez une notification"
 
-#: sith/settings.py:667
+#: sith/settings.py:681
 msgid "Success!"
 msgstr "Succès !"
 
-#: sith/settings.py:668
+#: sith/settings.py:682
 msgid "Fail!"
 msgstr "Échec !"
 
-#: sith/settings.py:669
+#: sith/settings.py:683
 msgid "You successfully posted an article in the Weekmail"
 msgstr "Article posté avec succès dans le Weekmail"
 
-#: sith/settings.py:670
+#: sith/settings.py:684
 msgid "You successfully edited an article in the Weekmail"
 msgstr "Article édité avec succès dans le Weekmail"
 
-#: sith/settings.py:671
+#: sith/settings.py:685
 msgid "You successfully sent the Weekmail"
 msgstr "Weekmail envoyé avec succès"
 
-#: sith/settings.py:679
+#: sith/settings.py:693
 msgid "AE tee-shirt"
 msgstr "Tee-shirt AE"
 
diff --git a/sith/settings.py b/sith/settings.py
index cd70f49b..9b484559 100644
--- a/sith/settings.py
+++ b/sith/settings.py
@@ -37,9 +37,11 @@ import binascii
 import logging
 import os
 import sys
+from datetime import timedelta
 from pathlib import Path
 
 import sentry_sdk
+from dateutil.relativedelta import relativedelta
 from django.utils.translation import gettext_lazy as _
 from sentry_sdk.integrations.django import DjangoIntegration
 
@@ -228,13 +230,20 @@ LOGGING = {
             "class": "logging.StreamHandler",
             "formatter": "simple",
         },
+        "dump_mail_file": {
+            "level": "DEBUG",
+            "class": "logging.FileHandler",
+            "filename": "account_dump_mail.log",
+            "formatter": "simple",
+        },
     },
     "loggers": {
         "main": {
             "handlers": ["log_to_stdout"],
             "level": "INFO",
             "propagate": True,
-        }
+        },
+        "account_dump_mail": {"handlers": ["dump_mail_file", "log_to_stdout"]},
     },
 }
 
@@ -495,6 +504,11 @@ SITH_ECOCUP_LIMIT = 3
 # Defines pagination for cash summary
 SITH_COUNTER_CASH_SUMMARY_LENGTH = 50
 
+SITH_ACCOUNT_INACTIVITY_DELTA = relativedelta(years=2)
+"""Time before which a user account is considered inactive"""
+SITH_ACCOUNT_DUMP_DELTA = timedelta(days=30)
+"""timedelta between the warning mail and the actual account dump"""
+
 # Defines which product type is the refilling type, and thus increases the account amount
 SITH_COUNTER_PRODUCTTYPE_REFILLING = 3