1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2024-11-30 12:23:00 +00:00

Compare commits

..

25 Commits

Author SHA1 Message Date
korenstin
02af4a1bc8 linters 2024-07-11 13:38:22 +02:00
korenstin
e0b2d24fe7 Security against the cycles 2024-07-08 17:44:09 +02:00
korenstin
7f12ee63f2 Open table and shelf life 2024-07-07 21:25:26 +02:00
korenstin
980bdb6fd8 Automatic allergens and expiry_date update 2024-07-06 19:26:21 +02:00
korenstin
fda9df3d6b Adding ingredients to a preparation 2024-07-05 11:57:44 +02:00
korenstin
7051294d76 Migration fixes 2024-07-04 17:11:38 +02:00
korenstin
e9f4795d13 Implementing QRcode creation, modifying Allergen model and creating of few views 2024-07-03 19:20:01 +02:00
korenstin
1aa779f479 linters 2024-07-02 22:13:19 +02:00
korenstin
631a5a59ad Update .gitlab-ci.yml 2024-07-02 22:13:19 +02:00
test
aea6ec5e49 charte info 2024-07-02 22:09:22 +02:00
korenstin
0e83ac32a2 error py37-django22 2024-07-02 22:09:22 +02:00
korenstin
c49a94b87f new_logo 2024-07-02 22:09:22 +02:00
quark
a3073ba5a5 Un peu de nettoyage, rajout de commentaires 2024-05-25 22:34:59 +02:00
quark
9b9fa0bcfe few changes in models, delete default label 2024-05-25 16:47:24 +02:00
quark
b1d0cf92b1 création de forms fonctionnel (form + views + url + html), few changes in models.py 2024-05-25 15:27:26 +02:00
quark
0c3e712f8f création d'un form pour l'ajout d'aliments basiques 2024-05-24 21:49:23 +02:00
quark
708216a67f nom app 2024-05-24 21:47:30 +02:00
quark
c27a8fefe5 First forms 2024-05-23 23:53:33 +02:00
quark
c8afee91d2 Annulation des modifications du Readme, voir https://wiki.crans.org/NoteKfet/NoteKfet2020 pour le cahier des charges 2024-05-21 14:49:07 +02:00
quark
aaa6076e9b Réagencement des tables et de leurs attributs 2024-05-21 14:07:35 +02:00
quark
77233e995e fusion de branche (j'avais fait nimp avec git) 2024-05-21 11:28:51 +02:00
quark
c9980b0bd1 création de l'interface admin temporaire 2024-05-21 11:21:13 +02:00
quark
4e6ec16e94 Rajout de la pseudo-doc 2024-05-17 21:33:30 +02:00
quark
89785ce632 Création de l'apps et de la base de donnée 2024-05-17 20:46:38 +02:00
quark
b636ca49d1 Update README.md 2024-05-17 20:40:52 +02:00
14 changed files with 98 additions and 232 deletions

View File

@ -17,8 +17,7 @@ from django.utils.translation import gettext_lazy as _
from django.views import View from django.views import View
from django.views.decorators.cache import cache_page from django.views.decorators.cache import cache_page
from django.views.generic import DetailView, TemplateView, UpdateView from django.views.generic import DetailView, TemplateView, UpdateView
from django.views.generic.list import ListView from django_tables2.views import SingleTableView
from django_tables2.views import MultiTableMixin
from note.models import Alias, NoteSpecial, NoteUser from note.models import Alias, NoteSpecial, NoteUser
from permission.backends import PermissionBackend from permission.backends import PermissionBackend
from permission.views import ProtectQuerysetMixin, ProtectedCreateView from permission.views import ProtectQuerysetMixin, ProtectedCreateView
@ -58,40 +57,27 @@ class ActivityCreateView(ProtectQuerysetMixin, ProtectedCreateView):
return reverse_lazy('activity:activity_detail', kwargs={"pk": self.object.pk}) return reverse_lazy('activity:activity_detail', kwargs={"pk": self.object.pk})
class ActivityListView(ProtectQuerysetMixin, LoginRequiredMixin, MultiTableMixin, ListView): class ActivityListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
""" """
Displays all Activities, and classify if they are on-going or upcoming ones. Displays all Activities, and classify if they are on-going or upcoming ones.
""" """
model = Activity model = Activity
tables = [ActivityTable, ActivityTable] table_class = ActivityTable
ordering = ('-date_start',)
extra_context = {"title": _("Activities")} extra_context = {"title": _("Activities")}
def get_queryset(self, **kwargs): def get_queryset(self, **kwargs):
return super().get_queryset(**kwargs).distinct() return super().get_queryset(**kwargs).distinct()
def get_tables(self):
tables = super().get_tables()
tables[0].prefix = "all-"
tables[1].prefix = "upcoming-"
return tables
def get_tables_data(self):
# first table = all activities, second table = upcoming
return [
self.get_queryset().order_by("-date_start"),
Activity.objects.filter(date_end__gt=timezone.now())
.filter(PermissionBackend.filter_queryset(self.request, Activity, "view"))
.distinct()
.order_by("date_start")
]
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
tables = context["tables"] upcoming_activities = Activity.objects.filter(date_end__gt=timezone.now())
for name, table in zip(["table", "upcoming"], tables): context['upcoming'] = ActivityTable(
context[name] = table 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() started_activities = self.get_queryset().filter(open=True, valid=True).distinct().all()
context["started_activities"] = started_activities context["started_activities"] = started_activities

View File

@ -138,9 +138,6 @@ class ImageForm(forms.Form):
return cleaned_data return cleaned_data
def is_valid(self):
return super().is_valid() or super().clean().get('image') is None
class ClubForm(forms.ModelForm): class ClubForm(forms.ModelForm):
def clean(self): def clean(self):
@ -154,7 +151,7 @@ class ClubForm(forms.ModelForm):
class Meta: class Meta:
model = Club model = Club
exclude = ("add_registration_form",) fields = '__all__'
widgets = { widgets = {
"membership_fee_paid": AmountInput(), "membership_fee_paid": AmountInput(),
"membership_fee_unpaid": AmountInput(), "membership_fee_unpaid": AmountInput(),

View File

@ -1,18 +0,0 @@
# Generated by Django 2.2.28 on 2024-07-15 09:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('member', '0011_profile_vss_charter_read'),
]
operations = [
migrations.AddField(
model_name='club',
name='add_registration_form',
field=models.BooleanField(default=False, verbose_name='add to registration form'),
),
]

View File

@ -259,11 +259,6 @@ class Club(models.Model):
help_text=_('Maximal date of a membership, after which members must renew it.'), help_text=_('Maximal date of a membership, after which members must renew it.'),
) )
add_registration_form = models.BooleanField(
verbose_name=_("add to registration form"),
default=False,
)
class Meta: class Meta:
verbose_name = _("club") verbose_name = _("club")
verbose_name_plural = _("clubs") verbose_name_plural = _("clubs")

View File

@ -14,9 +14,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
<form method="post" enctype="multipart/form-data" id="formUpload"> <form method="post" enctype="multipart/form-data" id="formUpload">
{% csrf_token %} {% csrf_token %}
{{ form |crispy }} {{ form |crispy }}
{% if user.note.display_image != "pic/default.png" %}
<input type="submit" class="btn btn-primary" value="{% trans "Remove" %}">
{% endif %}
</form> </form>
</div> </div>
<!-- MODAL TO CROP THE IMAGE --> <!-- MODAL TO CROP THE IMAGE -->

View File

@ -326,9 +326,6 @@ class PictureUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin, Det
"""Save image to note""" """Save image to note"""
image = form.cleaned_data['image'] image = form.cleaned_data['image']
if image is None:
image = "pic/default.png"
else:
# Rename as a PNG or GIF # Rename as a PNG or GIF
extension = image.name.split(".")[-1] extension = image.name.split(".")[-1]
if extension == "gif": if extension == "gif":

View File

@ -23,7 +23,7 @@
<p> <p>
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érents dont le solde
est inférieur à 0 €. est inférieur à 0 € depuis plus de 24h.
</p> </p>
<p> <p>

View File

@ -2591,12 +2591,12 @@
"note", "note",
"transaction" "transaction"
], ],
"query": "[\"OR\", {\"source__balance__gte\": 0}, [\"AND\", [\"NOT\", {\"recurrenttransaction__template__category__name\": \"Alcool\"}], {\"source__balance__gte\": {\"F\": [\"SUB\", [\"MUL\", [\"F\", \"amount\"], [\"F\", \"quantity\"]], 2000]}}], {\"valid\": false}]", "query": "[\"OR\", {\"source__balance__gte\": {\"F\": [\"SUB\", [\"MUL\", [\"F\", \"amount\"], [\"F\", \"quantity\"]], 2000]}}, {\"valid\": false}]",
"type": "add", "type": "add",
"mask": 2, "mask": 2,
"field": "", "field": "",
"permanent": false, "permanent": false,
"description": "Créer une transaction quelconque tant que la source reste positive s'il s'agit d'alcool, sinon au-dessus de -20€" "description": "Créer une transaction quelconque tant que la source reste au-dessus de -20 €"
} }
}, },
{ {

View File

@ -5,6 +5,7 @@ from django import forms
from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
# from member.models import Club
from note.models import NoteSpecial, Alias from note.models import NoteSpecial, Alias
from note_kfet.inputs import AmountInput from note_kfet.inputs import AmountInput
@ -114,3 +115,12 @@ class ValidationForm(forms.Form):
required=False, required=False,
initial=True, 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,
# )

View File

@ -1,7 +1,6 @@
# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay # Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from django import forms
from django.conf import settings from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User from django.contrib.auth.models import User
@ -239,8 +238,9 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
fee += bde.membership_fee_paid if user.profile.paid else bde.membership_fee_unpaid fee += bde.membership_fee_paid if user.profile.paid else bde.membership_fee_unpaid
kfet = Club.objects.get(name="Kfet") kfet = Club.objects.get(name="Kfet")
fee += kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid fee += kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid
for club in Club.objects.filter(add_registration_form=True): if Club.objects.filter(name__iexact="BDA").exists():
fee += club.membership_fee_paid if user.profile.paid else club.membership_fee_unpaid bda = Club.objects.get(name__iexact="BDA")
fee += bda.membership_fee_paid if user.profile.paid else bda.membership_fee_unpaid
ctx["total_fee"] = "{:.02f}".format(fee / 100, ) ctx["total_fee"] = "{:.02f}".format(fee / 100, )
# ctx["declare_soge_account"] = SogeCredit.objects.filter(user=user).exists() # ctx["declare_soge_account"] = SogeCredit.objects.filter(user=user).exists()
@ -249,16 +249,6 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
def get_form(self, form_class=None): def get_form(self, form_class=None):
form = super().get_form(form_class) form = super().get_form(form_class)
# add clubs that are in registration form
for club in Club.objects.filter(add_registration_form=True).order_by("name"):
form_join_club = forms.BooleanField(
label=_("Join %(club)s Club") % {'club': club.name},
required=False,
initial=False,
)
form.fields.update({f"join_{club.id}": form_join_club})
user = self.get_object() user = self.get_object()
form.fields["last_name"].initial = user.last_name form.fields["last_name"].initial = user.last_name
form.fields["first_name"].initial = user.first_name form.fields["first_name"].initial = user.first_name
@ -276,6 +266,11 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
form.add_error(None, _("An alias with a similar name already exists.")) form.add_error(None, _("An alias with a similar name already exists."))
return self.form_invalid(form) return self.form_invalid(form)
# Check if BDA exist to propose membership at regisration
bda_exists = False
if Club.objects.filter(name__iexact="BDA").exists():
bda_exists = True
# Get form data # Get form data
# soge = form.cleaned_data["soge"] # soge = form.cleaned_data["soge"]
credit_type = form.cleaned_data["credit_type"] credit_type = form.cleaned_data["credit_type"]
@ -285,9 +280,8 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
bank = form.cleaned_data["bank"] bank = form.cleaned_data["bank"]
join_bde = form.cleaned_data["join_bde"] join_bde = form.cleaned_data["join_bde"]
join_kfet = form.cleaned_data["join_kfet"] join_kfet = form.cleaned_data["join_kfet"]
if bda_exists:
clubs_registration = Club.objects.filter(add_registration_form=True).order_by("name") join_bda = form.cleaned_data["join_bda"]
join_clubs = [(club, form.cleaned_data[f"join_{club.id}"]) for club in clubs_registration]
# if soge: # if soge:
# # If Société Générale pays the inscription, the user automatically joins the two clubs. # # If Société Générale pays the inscription, the user automatically joins the two clubs.
@ -309,12 +303,11 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
kfet_fee = kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid kfet_fee = kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid
# Add extra fee for the full membership # Add extra fee for the full membership
fee += kfet_fee if join_kfet else 0 fee += kfet_fee if join_kfet else 0
clubs_fee = dict() if bda_exists:
for club, join_club in join_clubs: bda = Club.objects.get(name__iexact="BDA")
club_fee = club.membership_fee_paid if user.profile.paid else club.membership_fee_unpaid bda_fee = bda.membership_fee_paid if user.profile.paid else bda.membership_fee_unpaid
# Add extra fee for the club membership # Add extra fee for the bda membership
clubs_fee[club] = club_fee fee += bda_fee if join_bda else 0
fee += club_fee if join_club else 0
# # If the bank pays, then we don't credit now. Treasurers will validate the transaction # # If the bank pays, then we don't credit now. Treasurers will validate the transaction
# # and credit the note later. # # and credit the note later.
@ -394,13 +387,12 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
membership.roles.add(Role.objects.get(name="Adhérent Kfet")) membership.roles.add(Role.objects.get(name="Adhérent Kfet"))
membership.save() membership.save()
for club, join_club in join_clubs: if bda_exists and join_bda:
if join_club:
# Create membership for the user to the BDA starting today # Create membership for the user to the BDA starting today
membership = Membership( membership = Membership(
club=club, club=bda,
user=user, user=user,
fee=clubs_fee[club], fee=bda_fee,
) )
membership.save() membership.save()
membership.refresh_from_db() membership.refresh_from_db()

View File

@ -1,83 +0,0 @@
Application Food
================
L'application ``food`` s'occupe de la traçabilité et permet notamment l'obtention de la liste des allergènes.
Modèles
-------
L'application comporte 5 modèles : Allergen, QRCode, Food, BasicFood, TransformedFood.
Food
~~~~
Ce modèle est un PolymorphicModel et ne sert uniquement à créer BasicFood et TransformedFood.
Le modèle regroupe :
* Nom du produit
* Propriétaire (doit-être un Club)
* Allergènes (ManyToManyField)
* date d'expiration
* a été mangé (booléen)
* est prêt (booléen)
BasicFood
~~~~~~~~~
Les BasicFood correspondent aux produits non modifiés à la Kfet. Ils peuvent correspondre à la fois à des produits achetés en magasin ou à des produits Terre à Terre. Ces produits seront les ingrédients de tous les plats préparés et en conséquent sont les seuls produits à nécessité une saisie manuelle des allergènes.
Le modèle regroupe :
* Type de date (DLC = date limite de consommation, DDM = date de durabilité minimale)
* Date d'arrivée
* Champs de Food
TransformedFood
~~~~~~~~~~~~~~~
Les TransformedFood correspondent aux produits préparés à la Kfet. Ils peuvent être composés de BasicFood et/ou de TransformedFood. La date d'expiration et les allergènes sont automatiquement mis à jour par update (qui doit être exécuté après modification des ingrédients dans les forms par exemple).
Le modèle regroupe :
* Durée de consommation (par défaut 3 jours)
* Ingrédients (ManyToManyField vers Food)
* Date de création
* Champs de Food
Allergen
~~~~~~~~
Le modèle regroupe :
* Nom
QRCode
~~~~~~
Le modèle regroupe :
* nombre (unique, entier positif)
* food (OneToOneField vers Food)
Création de BasicFood
~~~~~~~~~~~~~~~~~~~~~
Un BasicFood a toujours besoin d'un QRCode (depuis l'interface web). Il convient donc de coller le QRCode puis de le scanner et de compléter le formulaire.
Création de TransformedFood
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Pour créer un TransformedFood, il suffit d'aller dans l'onglet ``traçabilité`` et de cliquer sur l'onglet.
Ajouter un ingrédient
~~~~~~~~~~~~~~~~~~~~~
Un ingrédient a forcément un QRCode. Il convient donc de scanner le QRCode de l'ingrédient et de sélectionner le produit auquel il doit être ajouté.
Remarque : Un produit fini doit avoir un QRCode et inversement.
Terminer un plat
~~~~~~~~~~~~~~~~
Il suffit de coller le QRCode sur le plat, de le scanner et de sélectionner le produit.

View File

@ -114,7 +114,7 @@ msgstr "Lieu où l'activité est organisée, par exemple la Kfet."
msgid "type" msgid "type"
msgstr "type" msgstr "type"
#: apps/activity/models.py:89 apps/logs/models.py:22 apps/member/models.py:318 #: 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/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/models.py:171 apps/wei/templates/wei/attribute_bus_1A.html:13
#: apps/wei/templates/wei/survey.html:15 #: apps/wei/templates/wei/survey.html:15
@ -247,7 +247,6 @@ msgid "The validation of the activity is pending."
msgstr "La validation de cette activité est en attente." msgstr "La validation de cette activité est en attente."
#: apps/activity/tables.py:43 apps/treasury/tables.py:107 #: apps/activity/tables.py:43 apps/treasury/tables.py:107
#: apps/member/templates/member/picture_update.html:18
msgid "Remove" msgid "Remove"
msgstr "Supprimer" msgstr "Supprimer"
@ -263,13 +262,13 @@ msgstr "supprimer"
msgid "Type" msgid "Type"
msgstr "Type" msgstr "Type"
#: apps/activity/tables.py:84 apps/member/forms.py:196 #: apps/activity/tables.py:84 apps/member/forms.py:193
#: apps/registration/forms.py:92 apps/treasury/forms.py:131 #: apps/registration/forms.py:92 apps/treasury/forms.py:131
#: apps/wei/forms/registration.py:104 #: apps/wei/forms/registration.py:104
msgid "Last name" msgid "Last name"
msgstr "Nom de famille" msgstr "Nom de famille"
#: apps/activity/tables.py:86 apps/member/forms.py:201 #: apps/activity/tables.py:86 apps/member/forms.py:198
#: apps/note/templates/note/transaction_form.html:138 #: apps/note/templates/note/transaction_form.html:138
#: apps/registration/forms.py:97 apps/treasury/forms.py:133 #: apps/registration/forms.py:97 apps/treasury/forms.py:133
#: apps/wei/forms/registration.py:109 #: apps/wei/forms/registration.py:109
@ -401,37 +400,37 @@ msgstr "Inviter"
msgid "Create new activity" msgid "Create new activity"
msgstr "Créer une nouvelle activité" msgstr "Créer une nouvelle activité"
#: apps/activity/views.py:68 note_kfet/templates/base.html:90 #: apps/activity/views.py:67 note_kfet/templates/base.html:90
msgid "Activities" msgid "Activities"
msgstr "Activités" msgstr "Activités"
#: apps/activity/views.py:108 #: apps/activity/views.py:93
msgid "Activity detail" msgid "Activity detail"
msgstr "Détails de l'activité" msgstr "Détails de l'activité"
#: apps/activity/views.py:128 #: apps/activity/views.py:113
msgid "Update activity" msgid "Update activity"
msgstr "Modifier l'activité" msgstr "Modifier l'activité"
#: apps/activity/views.py:155 #: apps/activity/views.py:140
msgid "Invite guest to the activity \"{}\"" msgid "Invite guest to the activity \"{}\""
msgstr "Invitation pour l'activité « {} »" msgstr "Invitation pour l'activité « {} »"
#: apps/activity/views.py:193 #: apps/activity/views.py:178
msgid "You are not allowed to display the entry interface for this activity." msgid "You are not allowed to display the entry interface for this activity."
msgstr "" msgstr ""
"Vous n'êtes pas autorisé·e à afficher l'interface des entrées pour cette " "Vous n'êtes pas autorisé·e à afficher l'interface des entrées pour cette "
"activité." "activité."
#: apps/activity/views.py:196 #: apps/activity/views.py:181
msgid "This activity does not support activity entries." msgid "This activity does not support activity entries."
msgstr "Cette activité ne requiert pas d'entrées." msgstr "Cette activité ne requiert pas d'entrées."
#: apps/activity/views.py:199 #: apps/activity/views.py:184
msgid "This activity is closed." msgid "This activity is closed."
msgstr "Cette activité est fermée." msgstr "Cette activité est fermée."
#: apps/activity/views.py:295 #: apps/activity/views.py:280
msgid "Entry for activity \"{}\"" msgid "Entry for activity \"{}\""
msgstr "Entrées pour l'activité « {} »" msgstr "Entrées pour l'activité « {} »"
@ -508,11 +507,11 @@ msgstr "cotisation pour adhérer (normalien·ne élève)"
msgid "membership fee (unpaid students)" msgid "membership fee (unpaid students)"
msgstr "cotisation pour adhérer (normalien·ne étudiant·e)" msgstr "cotisation pour adhérer (normalien·ne étudiant·e)"
#: apps/member/admin.py:65 apps/member/models.py:330 #: apps/member/admin.py:65 apps/member/models.py:325
msgid "roles" msgid "roles"
msgstr "rôles" msgstr "rôles"
#: apps/member/admin.py:66 apps/member/models.py:344 #: apps/member/admin.py:66 apps/member/models.py:339
msgid "fee" msgid "fee"
msgstr "cotisation" msgstr "cotisation"
@ -564,29 +563,29 @@ msgid "This image cannot be loaded."
msgstr "Cette image ne peut pas être chargée." msgstr "Cette image ne peut pas être chargée."
#: apps/member/forms.py:148 apps/member/views.py:102 #: apps/member/forms.py:148 apps/member/views.py:102
#: apps/registration/forms.py:34 apps/registration/views.py:276 #: apps/registration/forms.py:34 apps/registration/views.py:266
msgid "An alias with a similar name already exists." msgid "An alias with a similar name already exists."
msgstr "Un alias avec un nom similaire existe déjà." msgstr "Un alias avec un nom similaire existe déjà."
#: apps/member/forms.py:175 #: apps/member/forms.py:172
msgid "Inscription paid by Société Générale" msgid "Inscription paid by Société Générale"
msgstr "Inscription payée par la Société générale" msgstr "Inscription payée par la Société générale"
#: apps/member/forms.py:177 #: apps/member/forms.py:174
msgid "Check this case if the Société Générale paid the inscription." msgid "Check this case if the Société Générale paid the inscription."
msgstr "Cochez cette case si la Société Générale a payé l'inscription." msgstr "Cochez cette case si la Société Générale a payé l'inscription."
#: apps/member/forms.py:182 apps/registration/forms.py:79 #: apps/member/forms.py:179 apps/registration/forms.py:79
#: apps/wei/forms/registration.py:91 #: apps/wei/forms/registration.py:91
msgid "Credit type" msgid "Credit type"
msgstr "Type de rechargement" msgstr "Type de rechargement"
#: apps/member/forms.py:183 apps/registration/forms.py:80 #: apps/member/forms.py:180 apps/registration/forms.py:80
#: apps/wei/forms/registration.py:92 #: apps/wei/forms/registration.py:92
msgid "No credit" msgid "No credit"
msgstr "Pas de rechargement" msgstr "Pas de rechargement"
#: apps/member/forms.py:185 #: apps/member/forms.py:182
msgid "You can credit the note of the user." msgid "You can credit the note of the user."
msgstr "Vous pouvez créditer la note de l'utilisateur·ice avant l'adhésion." msgstr "Vous pouvez créditer la note de l'utilisateur·ice avant l'adhésion."
@ -595,17 +594,17 @@ msgstr "Vous pouvez créditer la note de l'utilisateur·ice avant l'adhésion."
msgid "Credit amount" msgid "Credit amount"
msgstr "Montant à créditer" msgstr "Montant à créditer"
#: apps/member/forms.py:206 apps/note/templates/note/transaction_form.html:144 #: apps/member/forms.py:203 apps/note/templates/note/transaction_form.html:144
#: apps/registration/forms.py:102 apps/treasury/forms.py:135 #: apps/registration/forms.py:102 apps/treasury/forms.py:135
#: apps/wei/forms/registration.py:114 #: apps/wei/forms/registration.py:114
msgid "Bank" msgid "Bank"
msgstr "Banque" msgstr "Banque"
#: apps/member/forms.py:233 #: apps/member/forms.py:230
msgid "User" msgid "User"
msgstr "Utilisateur·ice" msgstr "Utilisateur·ice"
#: apps/member/forms.py:247 #: apps/member/forms.py:244
msgid "Roles" msgid "Roles"
msgstr "Rôles" msgstr "Rôles"
@ -853,50 +852,46 @@ msgstr ""
"Date maximale d'une fin d'adhésion, après laquelle les adhérent·e·s doivent la " "Date maximale d'une fin d'adhésion, après laquelle les adhérent·e·s doivent la "
"renouveler." "renouveler."
#: apps/member/models.py:263 #: apps/member/models.py:263 apps/member/models.py:319
msgid "add to registration form"
msgstr "ajouter au formulaire d'inscription"
#: apps/member/models.py:268 apps/member/models.py:324
#: apps/note/models/notes.py:176 #: apps/note/models/notes.py:176
msgid "club" msgid "club"
msgstr "club" msgstr "club"
#: apps/member/models.py:269 #: apps/member/models.py:264
msgid "clubs" msgid "clubs"
msgstr "clubs" msgstr "clubs"
#: apps/member/models.py:335 #: apps/member/models.py:330
msgid "membership starts on" msgid "membership starts on"
msgstr "l'adhésion commence le" msgstr "l'adhésion commence le"
#: apps/member/models.py:339 #: apps/member/models.py:334
msgid "membership ends on" msgid "membership ends on"
msgstr "l'adhésion finit le" msgstr "l'adhésion finit le"
#: apps/member/models.py:348 apps/note/models/transactions.py:385 #: apps/member/models.py:343 apps/note/models/transactions.py:385
msgid "membership" msgid "membership"
msgstr "adhésion" msgstr "adhésion"
#: apps/member/models.py:349 #: apps/member/models.py:344
msgid "memberships" msgid "memberships"
msgstr "adhésions" msgstr "adhésions"
#: apps/member/models.py:353 #: apps/member/models.py:348
#, python-brace-format #, python-brace-format
msgid "Membership of {user} for the club {club}" msgid "Membership of {user} for the club {club}"
msgstr "Adhésion de {user} pour le club {club}" msgstr "Adhésion de {user} pour le club {club}"
#: apps/member/models.py:372 #: apps/member/models.py:367
#, python-brace-format #, python-brace-format
msgid "The role {role} does not apply to the club {club}." msgid "The role {role} does not apply to the club {club}."
msgstr "Le rôle {role} ne s'applique pas au club {club}." msgstr "Le rôle {role} ne s'applique pas au club {club}."
#: apps/member/models.py:381 apps/member/views.py:712 #: apps/member/models.py:376 apps/member/views.py:712
msgid "User is already a member of the club" msgid "User is already a member of the club"
msgstr "L'utilisateur·ice est déjà membre du club" msgstr "L'utilisateur·ice est déjà membre du club"
#: apps/member/models.py:393 apps/member/views.py:721 #: apps/member/models.py:388 apps/member/views.py:721
msgid "User is not a member of the parent club" msgid "User is not a member of the parent club"
msgstr "L'utilisateur·ice n'est pas membre du club parent" msgstr "L'utilisateur·ice n'est pas membre du club parent"
@ -1158,11 +1153,11 @@ msgstr "Introspection :"
msgid "Show my applications" msgid "Show my applications"
msgstr "Voir mes applications" msgstr "Voir mes applications"
#: apps/member/templates/member/picture_update.html:38 #: apps/member/templates/member/picture_update.html:35
msgid "Nevermind" msgid "Nevermind"
msgstr "Annuler" msgstr "Annuler"
#: apps/member/templates/member/picture_update.html:39 #: apps/member/templates/member/picture_update.html:36
msgid "Crop and upload" msgid "Crop and upload"
msgstr "Recadrer et envoyer" msgstr "Recadrer et envoyer"
@ -2188,23 +2183,18 @@ msgstr "Utilisateur·ice·s en attente d'inscription"
msgid "Registration detail" msgid "Registration detail"
msgstr "Détails de l'inscription" msgstr "Détails de l'inscription"
#: apps/registration/views.py:256 #: apps/registration/views.py:293
#, python-format
msgid "Join %(club)s Club"
msgstr "Adhérer au club %(club)s"
#: apps/registration/views.py:299
msgid "You must join the BDE." msgid "You must join the BDE."
msgstr "Vous devez adhérer au BDE." msgstr "Vous devez adhérer au BDE."
#: apps/registration/views.py:330 #: apps/registration/views.py:323
msgid "" msgid ""
"The entered amount is not enough for the memberships, should be at least {}" "The entered amount is not enough for the memberships, should be at least {}"
msgstr "" msgstr ""
"Le montant crédité est trop faible pour adhérer, il doit être au minimum de " "Le montant crédité est trop faible pour adhérer, il doit être au minimum de "
"{}" "{}"
#: apps/registration/views.py:425 #: apps/registration/views.py:417
msgid "Invalidate pre-registration" msgid "Invalidate pre-registration"
msgstr "Invalider l'inscription" msgstr "Invalider l'inscription"
@ -3630,6 +3620,9 @@ msgstr ""
"d'adhésion. Vous devez également valider votre adresse email en suivant le " "d'adhésion. Vous devez également valider votre adresse email en suivant le "
"lien que vous avez reçu." "lien que vous avez reçu."
#~ msgid "Join BDA Club"
#~ msgstr "Adhérer au club BDA"
#, fuzzy #, fuzzy
#~| msgid "People having you as a friend" #~| msgid "People having you as a friend"
#~ msgid "You already have that person as a friend" #~ msgid "You already have that person as a friend"