From a096dc44271dcd46769c197bd1419a08a189d89c Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Tue, 4 Aug 2020 20:04:41 +0200 Subject: [PATCH] :sparkles: Adhere to parent clubs automatically, adhere to Kfet automatically when registering to the WEI --- apps/member/models.py | 90 +++++-- apps/member/views.py | 135 +++++++---- apps/treasury/views.py | 19 +- apps/wei/forms/registration.py | 31 +++ apps/wei/tables.py | 33 ++- apps/wei/views.py | 130 ++++++++-- locale/fr/LC_MESSAGES/django.po | 301 ++++++++++++++---------- templates/base.html | 12 +- templates/member/add_members.html | 27 ++- templates/member/club_detail.html | 2 - templates/member/profile_detail.html | 6 +- templates/member/profile_info.html | 28 +-- templates/member/profile_tables.html | 6 +- templates/wei/weiclub_detail.html | 12 +- templates/wei/weimembership_form.html | 12 +- templates/wei/weiregistration_list.html | 10 + 16 files changed, 588 insertions(+), 266 deletions(-) diff --git a/apps/member/models.py b/apps/member/models.py index 5d6544af..7bde2680 100644 --- a/apps/member/models.py +++ b/apps/member/models.py @@ -10,6 +10,7 @@ from django.core.exceptions import ValidationError from django.db import models from django.template import loader from django.urls import reverse, reverse_lazy +from django.utils import timezone from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_encode from django.utils.translation import gettext_lazy as _ @@ -301,13 +302,34 @@ class Membership(models.Model): else: return self.date_start.toordinal() <= datetime.datetime.now().toordinal() + def renew(self): + if Membership.objects.filter( + user=self.user, + club=self.club, + date_start__gte=self.club.membership_start, + ).exists(): + # Membership is already renewed + return + new_membership = Membership( + user=self.user, + club=self.club, + date_start=max(self.date_end + datetime.timedelta(days=1), self.club.membership_start), + ) + from django.forms import model_to_dict + if hasattr(self, '_force_renew_parent') and self._force_renew_parent: + new_membership._force_renew_parent = True + if hasattr(self, '_soge') and self._soge: + new_membership._soge = True + if hasattr(self, '_force_save') and self._force_save: + new_membership._force_save = True + new_membership.save() + new_membership.roles.set(self.roles.all()) + new_membership.save() + def save(self, *args, **kwargs): """ Calculate fee and end date before saving the membership and creating the transaction if needed. """ - if self.club.parent_club is not None: - if not Membership.objects.filter(user=self.user, club=self.club.parent_club).exists(): - raise ValidationError(_('User is not a member of the parent club') + ' ' + self.club.parent_club.name) if self.pk: for role in self.roles.all(): @@ -327,17 +349,54 @@ class Membership(models.Model): ).exists(): raise ValidationError(_('User is already a member of the club')) - if self.user.profile.paid: - self.fee = self.club.membership_fee_paid - else: - self.fee = self.club.membership_fee_unpaid + if self.club.parent_club is not None: + if not Membership.objects.filter( + user=self.user, + club=self.club.parent_club, + date_start__gte=self.club.parent_club.membership_start, + ).exists(): + if hasattr(self, '_force_renew_parent') and self._force_renew_parent: + parent_membership = Membership.objects.filter( + user=self.user, + club=self.club.parent_club, + ).order_by("-date_start") + if parent_membership.exists(): + # Renew the previous membership of the parent club + parent_membership = parent_membership.first() + parent_membership._force_renew_parent = True + if hasattr(self, '_soge'): + parent_membership._soge = True + if hasattr(self, '_force_save'): + parent_membership._force_save = True + parent_membership.renew() + else: + # Create a new membership in the parent club + parent_membership = Membership( + user=self.user, + club=self.club.parent_club, + date_start=self.date_start, + ) + parent_membership._force_renew_parent = True + if hasattr(self, '_soge'): + parent_membership._soge = True + if hasattr(self, '_force_save'): + parent_membership._force_save = True + parent_membership.save() + else: + raise ValidationError(_('User is not a member of the parent club') + + ' ' + self.club.parent_club.name) - if self.club.membership_duration is not None: - self.date_end = self.date_start + datetime.timedelta(days=self.club.membership_duration) - else: - self.date_end = self.date_start + datetime.timedelta(days=424242) - if self.club.membership_end is not None and self.date_end > self.club.membership_end: - self.date_end = self.club.membership_end + if self.user.profile.paid: + self.fee = self.club.membership_fee_paid + else: + self.fee = self.club.membership_fee_unpaid + + if self.club.membership_duration is not None: + self.date_end = self.date_start + datetime.timedelta(days=self.club.membership_duration) + else: + self.date_end = self.date_start + datetime.timedelta(days=424242) + if self.club.membership_end is not None and self.date_end > self.club.membership_end: + self.date_end = self.club.membership_end super().save(*args, **kwargs) @@ -360,8 +419,9 @@ class Membership(models.Model): reason="Adhésion " + self.club.name, ) transaction._force_save = True - print(hasattr(self, '_soge')) - if hasattr(self, '_soge') and "treasury" in settings.INSTALLED_APPS: + if hasattr(self, '_soge') and "treasury" in settings.INSTALLED_APPS\ + and (self.club.name == "BDE" or self.club.name == "Kfet" or + ("wei" in settings.INSTALLED_APPS and hasattr(self.club, "weiclub") and self.club.weiclub)): # If the soge pays, then the transaction is unvalidated in a first time, then submitted for control # to treasurers. transaction.valid = False diff --git a/apps/member/views.py b/apps/member/views.py index edcb0feb..cc1264a1 100644 --- a/apps/member/views.py +++ b/apps/member/views.py @@ -442,6 +442,16 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView): .get(pk=self.kwargs["club_pk"], weiclub=None) form.fields['credit_amount'].initial = club.membership_fee_paid + c = club + clubs_renewal = [] + additional_fee_renewal = 0 + while c.parent_club is not None: + c = c.parent_club + clubs_renewal.append(c) + additional_fee_renewal += c.membership_fee_paid if user.profile.paid else c.membership_fee_unpaid + context["clubs_renewal"] = clubs_renewal + context["additional_fee_renewal"] = additional_fee_renewal + # If the concerned club is the BDE, then we add the option that Société générale pays the membership. if club.name != "BDE": del form.fields['soge'] @@ -454,26 +464,54 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView): context["total_fee"] = "{:.02f}".format(fee / 100, ) else: # This is a renewal. Fields can be pre-completed. + context["renewal"] = True + old_membership = self.get_queryset().get(pk=self.kwargs["pk"]) club = old_membership.club user = old_membership.user + + c = club + clubs_renewal = [] + additional_fee_renewal = 0 + while c.parent_club is not None: + c = c.parent_club + if not Membership.objects.filter( + club=c, + user=user, + date_start__gte=c.membership_start, + ).exists(): + clubs_renewal.append(c) + additional_fee_renewal += c.membership_fee_paid if user.profile.paid else c.membership_fee_unpaid + context["clubs_renewal"] = clubs_renewal + context["additional_fee_renewal"] = additional_fee_renewal + form.fields['user'].initial = user form.fields['user'].disabled = True form.fields['date_start'].initial = old_membership.date_end + timedelta(days=1) - form.fields['credit_amount'].initial = club.membership_fee_paid if user.profile.paid \ - else club.membership_fee_unpaid + form.fields['credit_amount'].initial = (club.membership_fee_paid if user.profile.paid + else club.membership_fee_unpaid) + additional_fee_renewal form.fields['last_name'].initial = user.last_name form.fields['first_name'].initial = user.first_name # If this is a renewal of a BDE membership, Société générale can pays, if it is not yet done - if club.name != "BDE" or user.profile.soge: + if (club.name != "BDE" and club.name != "Kfet") or user.profile.soge: del form.fields['soge'] else: fee = 0 bde = Club.objects.get(name="BDE") - fee += bde.membership_fee_paid if user.profile.paid else bde.membership_fee_unpaid + if not Membership.objects.filter( + club=bde, + user=user, + date_start__gte=bde.membership_start, + ).exists(): + fee += bde.membership_fee_paid if user.profile.paid else bde.membership_fee_unpaid kfet = Club.objects.get(name="Kfet") - fee += kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid + if not Membership.objects.filter( + club=kfet, + user=user, + date_start__gte=bde.membership_start, + ).exists(): + fee += kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid context["total_fee"] = "{:.02f}".format(fee / 100, ) context['club'] = club @@ -502,7 +540,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView): last_name = form.cleaned_data["last_name"] first_name = form.cleaned_data["first_name"] bank = form.cleaned_data["bank"] - soge = form.cleaned_data["soge"] and not user.profile.soge and club.name == "BDE" + soge = form.cleaned_data["soge"] and not user.profile.soge and (club.name == "BDE" or club.name == "Kfet") # If Société générale pays, then we store that information but the payment must be controlled by treasurers # later. The membership transaction will be invalidated. @@ -513,10 +551,17 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView): if credit_type is None: credit_amount = 0 - if user.profile.paid: - fee = club.membership_fee_paid - else: - fee = club.membership_fee_unpaid + fee = 0 + c = club + while c is not None: + if not Membership.objects.filter( + club=c, + user=user, + date_start__gte=c.membership_start, + ).exists(): + fee += c.membership_fee_paid if user.profile.paid else c.membership_fee_unpaid + c = c.parent_club + if user.note.balance + credit_amount < fee and not Membership.objects.filter( club__name="Kfet", user=user, @@ -524,22 +569,11 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView): date_end__gte=datetime.now().date(), ).exists(): # Users without a valid Kfet membership can't have a negative balance. - # Club 2 = Kfet (hard-code :'( ) # TODO Send a notification to the user (with a mail?) to tell her/him to credit her/his note form.add_error('user', _("This user don't have enough money to join this club, and can't have a negative balance.")) return super().form_invalid(form) - if club.parent_club is not None: - if not Membership.objects.filter( - user=form.instance.user, - club=club.parent_club, - date_start__lte=form.instance.date_start, - date_end__gte=form.instance.date_start, - ).exists(): - form.add_error('user', _('User is not a member of the parent club') + ' ' + club.parent_club.name) - return super().form_invalid(form) - if Membership.objects.filter( user=form.instance.user, club=club, @@ -561,7 +595,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView): # Now, all is fine, the membership can be created. - if club.name == "BDE": + if club.name == "BDE" or club.name == "Kfet": # When we renew the BDE membership, we update the profile section. # We could automate that and remove the section field from the Profile model, # but with this way users can customize their section as they want. @@ -593,6 +627,8 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView): transaction._force_save = True transaction.save() + form.instance._force_renew_parent = True + ret = super().form_valid(form) member_role = Role.objects.filter(name="Membre de club").all() @@ -603,33 +639,40 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView): # If Société générale pays, then we assume that this is the BDE membership, and we auto-renew the # Kfet membership. if soge: + # If not already done, create BDE and Kfet memberships + bde = Club.objects.get(name="BDE") kfet = Club.objects.get(name="Kfet") - kfet_fee = kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid - # Get current membership, to get the end date - old_membership = Membership.objects.filter( - club__name="Kfet", - user=user, - date_start__lte=datetime.today(), - date_end__gte=datetime.today(), - ) + soge_clubs = [bde, kfet] + for club in soge_clubs: + fee = club.membership_fee_paid if user.profile.paid else club.membership_fee_unpaid - membership = Membership( - club=kfet, - user=user, - fee=kfet_fee, - date_start=old_membership.get().date_end + timedelta(days=1) - if old_membership.exists() else form.instance.date_start, - ) - membership._force_save = True - membership._soge = True - membership.save() - membership.refresh_from_db() - if old_membership.exists(): - membership.roles.set(old_membership.get().roles.all()) - else: - membership.roles.add(Role.objects.get(name="Adhérent Kfet")) - membership.save() + # Get current membership, to get the end date + old_membership = Membership.objects.filter( + club=club, + user=user, + ).order_by("-date_start") + + if old_membership.filter(date_start__gte=club.membership_start).exists(): + # Membership is already renewed + continue + + membership = Membership( + club=club, + user=user, + fee=fee, + date_start=max(old_membership.first().date_end + timedelta(days=1), club.membership_start) + if old_membership.exists() else form.instance.date_start, + ) + membership._force_save = True + membership._soge = True + membership.save() + membership.refresh_from_db() + if old_membership.exists(): + membership.roles.set(old_membership.get().roles.all()) + else: + membership.roles.add(Role.objects.get(name="Adhérent Kfet")) + membership.save() return ret diff --git a/apps/treasury/views.py b/apps/treasury/views.py index 22215254..088345b8 100644 --- a/apps/treasury/views.py +++ b/apps/treasury/views.py @@ -353,18 +353,13 @@ class SogeCreditListView(LoginRequiredMixin, ProtectQuerysetMixin, SingleTableVi qs = super().get_queryset() if "search" in self.request.GET: pattern = self.request.GET["search"] - - if not pattern: - return qs.none() - - qs = qs.filter( - Q(user__first_name__iregex=pattern) - | Q(user__last_name__iregex=pattern) - | Q(user__note__alias__name__iregex="^" + pattern) - | Q(user__note__alias__normalized_name__iregex="^" + Alias.normalize(pattern)) - ) - else: - qs = qs.none() + if pattern: + qs = qs.filter( + Q(user__first_name__iregex=pattern) + | Q(user__last_name__iregex=pattern) + | Q(user__note__alias__name__iregex="^" + pattern) + | Q(user__note__alias__normalized_name__iregex="^" + Alias.normalize(pattern)) + ) if "valid" in self.request.GET: q = Q(credit_transaction=None) diff --git a/apps/wei/forms/registration.py b/apps/wei/forms/registration.py index 738db4e2..98215f4b 100644 --- a/apps/wei/forms/registration.py +++ b/apps/wei/forms/registration.py @@ -6,6 +6,8 @@ from django.contrib.auth.models import User from django.db.models import Q from django.forms import CheckboxSelectMultiple from django.utils.translation import gettext_lazy as _ + +from note.models import NoteSpecial from note_kfet.inputs import AmountInput, DatePickerInput, Autocomplete, ColorWidget from ..models import WEIClub, WEIRegistration, Bus, BusTeam, WEIMembership, WEIRole @@ -75,6 +77,35 @@ class WEIMembershipForm(forms.ModelForm): widget=CheckboxSelectMultiple(), ) + credit_type = forms.ModelChoiceField( + queryset=NoteSpecial.objects.all(), + label=_("Credit type"), + empty_label=_("No credit"), + required=False, + ) + + credit_amount = forms.IntegerField( + label=_("Credit amount"), + widget=AmountInput(), + initial=0, + required=False, + ) + + last_name = forms.CharField( + label=_("Last name"), + required=False, + ) + + first_name = forms.CharField( + label=_("First name"), + required=False, + ) + + bank = forms.CharField( + label=_("Bank"), + required=False, + ) + def clean(self): cleaned_data = super().clean() if cleaned_data["team"] is not None and cleaned_data["team"].bus != cleaned_data["bus"]: diff --git a/apps/wei/tables.py b/apps/wei/tables.py index 41c35a47..0fae6848 100644 --- a/apps/wei/tables.py +++ b/apps/wei/tables.py @@ -3,9 +3,13 @@ import django_tables2 as tables from django.urls import reverse_lazy +from django.utils import timezone +from django.utils.html import format_html from django.utils.translation import gettext_lazy as _ from django_tables2 import A +from note_kfet.middlewares import get_current_authenticated_user +from permission.backends import PermissionBackend from .models import WEIClub, WEIRegistration, Bus, BusTeam, WEIMembership @@ -53,8 +57,12 @@ class WEIRegistrationTable(tables.Table): verbose_name=_("Validate"), text=_("Validate"), attrs={ + 'th': { + 'id': 'validate-membership-header' + }, 'a': { - 'class': 'btn btn-success' + 'class': 'btn btn-success', + 'data-type': 'validate-membership' } } ) @@ -65,12 +73,33 @@ class WEIRegistrationTable(tables.Table): verbose_name=_("delete"), text=_("Delete"), attrs={ + 'th': { + 'id': 'delete-membership-header' + }, 'a': { - 'class': 'btn btn-danger' + 'class': 'btn btn-danger', + 'data-type': 'delete-membership' } }, ) + def render_validate(self, record): + if PermissionBackend.check_perm(get_current_authenticated_user(), "wei.add_weimembership", WEIMembership( + club=record.wei, + user=record.user, + date_start=timezone.now().date(), + date_end=timezone.now().date(), + fee=0, + registration=record, + )): + return _("Validate") + return format_html("") + + def render_delete(self, record): + if PermissionBackend.check_perm(get_current_authenticated_user(), "wei.delete_weimembership", record): + return _("Delete") + return format_html("") + class Meta: attrs = { 'class': 'table table-condensed table-striped table-hover' diff --git a/apps/wei/views.py b/apps/wei/views.py index 7731f08b..fe2a47a5 100644 --- a/apps/wei/views.py +++ b/apps/wei/views.py @@ -24,10 +24,11 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic.edit import BaseFormView, DeleteView from django_tables2 import SingleTableView from member.models import Membership, Club -from note.models import Transaction, NoteClub, Alias +from note.models import Transaction, NoteClub, Alias, SpecialTransaction, NoteSpecial from note.tables import HistoryTable from note_kfet.settings import BASE_DIR from permission.backends import PermissionBackend +from permission.models import Role from permission.views import ProtectQuerysetMixin from .forms.registration import WEIChooseBusForm @@ -666,6 +667,15 @@ class WEIUpdateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Update survey = CurrentSurvey(self.object) if not survey.is_complete(): return reverse_lazy("wei:wei_survey", kwargs={"pk": self.object.pk}) + if PermissionBackend.check_perm(self.request.user, "wei.add_weimembership", WEIMembership( + club=self.object.wei, + user=self.object.user, + date_start=timezone.now().date(), + date_end=timezone.now().date(), + fee=0, + registration=self.object, + )): + return reverse_lazy("wei:validate_registration", kwargs={"pk": self.object.pk}) return reverse_lazy("wei:wei_detail", kwargs={"pk": self.object.wei.pk}) @@ -723,19 +733,55 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Crea if survey.information.valid: context["suggested_bus"] = survey.information.get_selected_bus() context["club"] = registration.wei - context["fee"] = registration.wei.membership_fee_paid if registration.user.profile.paid \ - else registration.wei.membership_fee_unpaid + + kfet = registration.wei.parent_club + bde = kfet.parent_club + context["kfet_member"] = Membership.objects.filter( - club__name="Kfet", + club__name=kfet.name, user=registration.user, - date_start__gte=registration.wei.parent_club.membership_start, + date_start__gte=kfet.membership_start, ).exists() + context["bde_member"] = Membership.objects.filter( + club__name=bde.name, + user=registration.user, + date_start__gte=bde.membership_start, + ).exists() + + fee = registration.wei.membership_fee_paid if registration.user.profile.paid \ + else registration.wei.membership_fee_unpaid + if not context["kfet_member"]: + fee += kfet.membership_fee_paid if registration.user.profile.paid \ + else kfet.membership_fee_unpaid + if not context["bde_member"]: + fee += bde.membership_fee_paid if registration.user.profile.paid \ + else bde.membership_fee_unpaid + + context["fee"] = fee + + form = context["form"] + if registration.soge_credit: + form.fields["credit_amount"].initial = fee + else: + form.fields["credit_amount"].initial = max(0, fee - registration.user.note.balance) return context def get_form(self, form_class=None): form = super().get_form(form_class) registration = WEIRegistration.objects.get(pk=self.kwargs["pk"]) + form.fields["last_name"].initial = registration.user.last_name + form.fields["first_name"].initial = registration.user.first_name + + if registration.soge_credit: + form.fields["credit_type"].disabled = True + form.fields["credit_type"].initial = NoteSpecial.objects.get(special_type="Virement bancaire") + form.fields["credit_amount"].disabled = True + form.fields["last_name"].disabled = True + form.fields["first_name"].disabled = True + form.fields["bank"].disabled = True + form.fields["bank"].initial = "Société générale" + form.fields["bus"].widget.attrs["api_url"] = "/api/wei/bus/?wei=" + str(registration.wei.pk) if registration.first_year: # Use the results of the survey to fill initial data @@ -750,7 +796,7 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Crea if "preferred_bus_pk" in information and len(information["preferred_bus_pk"]) == 1: form["bus"].initial = Bus.objects.get(pk=information["preferred_bus_pk"][0]) if "preferred_team_pk" in information and len(information["preferred_team_pk"]) == 1: - form["team"].initial = Bus.objects.get(pk=information["preferred_team_pk"][0]) + form["team"].initial = BusTeam.objects.get(pk=information["preferred_team_pk"][0]) if "preferred_roles_pk" in information: form["roles"].initial = WEIRole.objects.filter( Q(pk__in=information["preferred_roles_pk"]) | Q(name="Adhérent WEI") @@ -770,38 +816,80 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Crea membership.club = club membership.date_start = min(date.today(), club.date_start) membership.registration = registration + # Force the membership of the clubs BDE and Kfet + membership._force_renew_parent = True if user.profile.paid: fee = club.membership_fee_paid else: fee = club.membership_fee_unpaid - if not registration.soge_credit and user.note.balance < fee: - # Users must have money before registering to the WEI. - # TODO Send a notification to the user (with a mail?) to tell her/him to credit her/his note - form.add_error('bus', - _("This user don't have enough money to join this club, and can't have a negative balance.")) - return super().form_invalid(form) + kfet = club.parent_club + bde = kfet.parent_club + + kfet_member = Membership.objects.filter( + club__name=kfet.name, + user=registration.user, + date_start__gte=kfet.membership_start, + ).exists() + bde_member = Membership.objects.filter( + club__name=bde.name, + user=registration.user, + date_start__gte=bde.membership_start, + ).exists() + + if not kfet_member: + fee += kfet.membership_fee_paid if registration.user.profile.paid else kfet.membership_fee_unpaid + if not bde_member: + fee += bde.membership_fee_paid if registration.user.profile.paid else bde.membership_fee_unpaid + + credit_type = form.cleaned_data["credit_type"] + credit_amount = form.cleaned_data["credit_amount"] + last_name = form.cleaned_data["last_name"] + first_name = form.cleaned_data["first_name"] + bank = form.cleaned_data["bank"] + + if credit_type is None or registration.soge_credit: + credit_amount = 0 if not registration.caution_check and not registration.first_year: form.add_error('bus', _("This user didn't give her/his caution check.")) return super().form_invalid(form) - if club.parent_club is not None: # parent_club is never None: this is Kfet. - # We want that the user is member of the Kfet club *of this year*: the Kfet membership is included - # in the WEI registration. - if not Membership.objects.filter( - user=form.instance.user, - club=club.parent_club, # Kfet - date_start__gte=club.parent_club.membership_start, - ).exists(): - form.add_error('bus', _('User is not a member of the parent club') + ' ' + club.parent_club.name) + if not registration.soge_credit and user.note.balance < fee + credit_amount: + # Users must have money before registering to the WEI. + form.add_error('bus', + _("This user don't have enough money to join this club, and can't have a negative balance.")) + return super().form_invalid(form) + + if credit_amount: + if not last_name: + form.add_error('last_name', _("This field is required.")) return super().form_invalid(form) + if not first_name: + form.add_error('first_name', _("This field is required.")) + return super().form_invalid(form) + + # Credit note before adding the membership + SpecialTransaction.objects.create( + source=credit_type, + destination=registration.user.note, + amount=credit_amount, + reason="Crédit " + str(credit_type) + " (WEI)", + last_name=last_name, + first_name=first_name, + bank=bank, + ) + # Now, all is fine, the membership can be created. + if registration.soge_credit: + form.instance._soge = True + if registration.first_year: membership = form.instance + # If the user is not a member of the club Kfet, then the membership is created. membership.save() membership.refresh_from_db() membership.roles.set(WEIRole.objects.filter(name="1A").all()) diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index fa49f7cc..6875a00d 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-03 23:53+0200\n" +"POT-Creation-Date: 2020-08-04 20:03+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -45,7 +45,7 @@ msgid "You can't invite more than 3 people to this activity." msgstr "Vous ne pouvez pas inviter plus de 3 personnes à cette activité." #: apps/activity/models.py:24 apps/activity/models.py:49 -#: apps/member/models.py:158 apps/note/models/notes.py:212 +#: apps/member/models.py:159 apps/note/models/notes.py:212 #: apps/note/models/transactions.py:25 apps/note/models/transactions.py:45 #: apps/note/models/transactions.py:268 apps/permission/models.py:339 #: apps/wei/models.py:65 apps/wei/models.py:117 @@ -84,7 +84,7 @@ msgstr "description" msgid "type" msgstr "type" -#: apps/activity/models.py:67 apps/logs/models.py:22 apps/member/models.py:266 +#: apps/activity/models.py:67 apps/logs/models.py:22 apps/member/models.py:267 #: apps/note/models/notes.py:126 apps/treasury/models.py:222 #: apps/wei/models.py:159 templates/treasury/sogecredit_detail.html:14 #: templates/wei/survey.html:16 @@ -189,12 +189,13 @@ msgstr "Type" #: apps/activity/tables.py:77 apps/member/forms.py:103 #: apps/registration/forms.py:70 apps/treasury/forms.py:120 +#: apps/wei/forms/registration.py:95 msgid "Last name" msgstr "Nom de famille" #: apps/activity/tables.py:79 apps/member/forms.py:108 #: apps/registration/forms.py:75 apps/treasury/forms.py:122 -#: templates/note/transaction_form.html:129 +#: apps/wei/forms/registration.py:100 templates/note/transaction_form.html:129 msgid "First name" msgstr "Prénom" @@ -268,7 +269,7 @@ msgid "edit" msgstr "Modifier" #: apps/logs/models.py:63 apps/note/tables.py:137 apps/note/tables.py:165 -#: apps/permission/models.py:137 apps/wei/tables.py:65 +#: apps/permission/models.py:137 apps/wei/tables.py:73 msgid "delete" msgstr "Supprimer" @@ -292,25 +293,25 @@ msgstr "journal de modification" msgid "changelogs" msgstr "journaux de modifications" -#: apps/member/admin.py:52 apps/member/models.py:185 +#: apps/member/admin.py:52 apps/member/models.py:186 #: templates/member/club_info.html:41 msgid "membership fee (paid students)" msgstr "cotisation pour adhérer (normalien élève)" -#: apps/member/admin.py:53 apps/member/models.py:190 +#: apps/member/admin.py:53 apps/member/models.py:191 #: templates/member/club_info.html:44 msgid "membership fee (unpaid students)" msgstr "cotisation pour adhérer (normalien étudiant)" -#: apps/member/admin.py:67 apps/member/models.py:277 +#: apps/member/admin.py:67 apps/member/models.py:278 msgid "roles" msgstr "rôles" -#: apps/member/admin.py:68 apps/member/models.py:291 +#: apps/member/admin.py:68 apps/member/models.py:292 msgid "fee" msgstr "cotisation" -#: apps/member/apps.py:14 apps/wei/tables.py:150 apps/wei/tables.py:181 +#: apps/member/apps.py:14 apps/wei/tables.py:179 apps/wei/tables.py:210 msgid "member" msgstr "adhérent" @@ -328,10 +329,12 @@ msgid "Check this case is the Société Générale paid the inscription." msgstr "Cochez cette case si la Société Générale a payé l'inscription." #: apps/member/forms.py:89 apps/registration/forms.py:57 +#: apps/wei/forms/registration.py:82 msgid "Credit type" msgstr "Type de rechargement" #: apps/member/forms.py:90 apps/registration/forms.py:58 +#: apps/wei/forms/registration.py:83 msgid "No credit" msgstr "Pas de rechargement" @@ -340,11 +343,13 @@ msgid "You can credit the note of the user." msgstr "Vous pouvez créditer la note de l'utisateur avant l'adhésion." #: apps/member/forms.py:96 apps/registration/forms.py:63 +#: apps/wei/forms/registration.py:88 msgid "Credit amount" msgstr "Montant à créditer" #: apps/member/forms.py:113 apps/registration/forms.py:80 -#: apps/treasury/forms.py:124 templates/note/transaction_form.html:135 +#: apps/treasury/forms.py:124 apps/wei/forms/registration.py:105 +#: templates/note/transaction_form.html:135 msgid "Bank" msgstr "Banque" @@ -356,171 +361,171 @@ msgstr "Utilisateur" msgid "Roles" msgstr "Rôles" -#: apps/member/models.py:34 +#: apps/member/models.py:35 #: templates/registration/future_profile_detail.html:40 #: templates/wei/weimembership_form.html:48 msgid "phone number" msgstr "numéro de téléphone" -#: apps/member/models.py:41 templates/member/profile_info.html:29 +#: apps/member/models.py:42 templates/member/profile_info.html:29 #: templates/registration/future_profile_detail.html:34 #: templates/wei/weimembership_form.html:42 msgid "section" msgstr "section" -#: apps/member/models.py:42 +#: apps/member/models.py:43 msgid "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\"" msgstr "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\"" -#: apps/member/models.py:50 templates/wei/weimembership_form.html:36 +#: apps/member/models.py:51 templates/wei/weimembership_form.html:36 msgid "department" msgstr "département" -#: apps/member/models.py:52 +#: apps/member/models.py:53 msgid "Informatics (A0)" msgstr "Informatique (A0)" -#: apps/member/models.py:53 +#: apps/member/models.py:54 msgid "Mathematics (A1)" msgstr "Mathématiques (A1)" -#: apps/member/models.py:54 +#: apps/member/models.py:55 msgid "Physics (A2)" msgstr "Physique (A2)" -#: apps/member/models.py:55 +#: apps/member/models.py:56 msgid "Applied physics (A'2)" msgstr "Physique appliquée (A'2)" -#: apps/member/models.py:56 +#: apps/member/models.py:57 msgid "Chemistry (A''2)" msgstr "Chimie (A''2)" -#: apps/member/models.py:57 +#: apps/member/models.py:58 msgid "Biology (A3)" msgstr "Biologie (A3)" -#: apps/member/models.py:58 +#: apps/member/models.py:59 msgid "SAPHIRE (B1234)" msgstr "SAPHIRE (B1234)" -#: apps/member/models.py:59 +#: apps/member/models.py:60 msgid "Mechanics (B1)" msgstr "Mécanique (B1)" -#: apps/member/models.py:60 +#: apps/member/models.py:61 msgid "Civil engineering (B2)" msgstr "Génie civil (B2)" -#: apps/member/models.py:61 +#: apps/member/models.py:62 msgid "Mechanical engineering (B3)" msgstr "Génie mécanique (B3)" -#: apps/member/models.py:62 +#: apps/member/models.py:63 msgid "EEA (B4)" msgstr "EEA (B4)" -#: apps/member/models.py:63 +#: apps/member/models.py:64 msgid "Design (C)" msgstr "Design (C)" -#: apps/member/models.py:64 +#: apps/member/models.py:65 msgid "Economy-management (D2)" msgstr "Économie-gestion (D2)" -#: apps/member/models.py:65 +#: apps/member/models.py:66 msgid "Social sciences (D3)" msgstr "Sciences sociales (D3)" -#: apps/member/models.py:66 +#: apps/member/models.py:67 msgid "English (E)" msgstr "Anglais (E)" -#: apps/member/models.py:67 +#: apps/member/models.py:68 msgid "External (EXT)" msgstr "Externe (EXT)" -#: apps/member/models.py:74 +#: apps/member/models.py:75 msgid "promotion" msgstr "promotion" -#: apps/member/models.py:75 +#: apps/member/models.py:76 msgid "Year of entry to the school (None if not ENS student)" msgstr "Année d'entrée dans l'école (None si non-étudiant·e de l'ENS)" -#: apps/member/models.py:79 templates/member/profile_info.html:32 +#: apps/member/models.py:80 templates/member/profile_info.html:32 #: templates/registration/future_profile_detail.html:37 #: templates/wei/weimembership_form.html:45 msgid "address" msgstr "adresse" -#: apps/member/models.py:86 +#: apps/member/models.py:87 #: templates/registration/future_profile_detail.html:43 #: templates/wei/weimembership_form.html:51 msgid "paid" msgstr "payé" -#: apps/member/models.py:87 +#: apps/member/models.py:88 msgid "Tells if the user receive a salary." msgstr "Indique si l'utilisateur perçoit un salaire." -#: apps/member/models.py:92 +#: apps/member/models.py:93 msgid "email confirmed" msgstr "adresse email confirmée" -#: apps/member/models.py:97 +#: apps/member/models.py:98 msgid "registration valid" msgstr "inscription valid" -#: apps/member/models.py:126 apps/member/models.py:127 +#: apps/member/models.py:127 apps/member/models.py:128 msgid "user profile" msgstr "profil utilisateur" -#: apps/member/models.py:134 +#: apps/member/models.py:135 msgid "Activate your Note Kfet account" msgstr "Activez votre compte Note Kfet" -#: apps/member/models.py:163 templates/member/club_info.html:57 +#: apps/member/models.py:164 templates/member/club_info.html:57 #: templates/registration/future_profile_detail.html:22 #: templates/wei/weiclub_info.html:52 templates/wei/weimembership_form.html:24 msgid "email" msgstr "courriel" -#: apps/member/models.py:170 +#: apps/member/models.py:171 msgid "parent club" msgstr "club parent" -#: apps/member/models.py:179 +#: apps/member/models.py:180 msgid "require memberships" msgstr "nécessite des adhésions" -#: apps/member/models.py:180 +#: apps/member/models.py:181 msgid "Uncheck if this club don't require memberships." msgstr "Décochez si ce club n'utilise pas d'adhésions." -#: apps/member/models.py:196 templates/member/club_info.html:33 +#: apps/member/models.py:197 templates/member/club_info.html:33 msgid "membership duration" msgstr "durée de l'adhésion" -#: apps/member/models.py:197 +#: apps/member/models.py:198 msgid "The longest time (in days) a membership can last (NULL = infinite)." msgstr "La durée maximale (en jours) d'une adhésion (NULL = infinie)." -#: apps/member/models.py:204 templates/member/club_info.html:23 +#: apps/member/models.py:205 templates/member/club_info.html:23 msgid "membership start" msgstr "début de l'adhésion" -#: apps/member/models.py:205 +#: apps/member/models.py:206 msgid "How long after January 1st the members can renew their membership." msgstr "" "Combien de temps après le 1er Janvier les adhérents peuvent renouveler leur " "adhésion." -#: apps/member/models.py:212 templates/member/club_info.html:28 +#: apps/member/models.py:213 templates/member/club_info.html:28 msgid "membership end" msgstr "fin de l'adhésion" -#: apps/member/models.py:213 +#: apps/member/models.py:214 msgid "" "How long the membership can last after January 1st of the next year after " "members can renew their membership." @@ -528,46 +533,46 @@ msgstr "" "Combien de temps l'adhésion peut durer après le 1er Janvier de l'année " "suivante avant que les adhérents peuvent renouveler leur adhésion." -#: apps/member/models.py:247 apps/member/models.py:272 +#: apps/member/models.py:248 apps/member/models.py:273 #: apps/note/models/notes.py:163 msgid "club" msgstr "club" -#: apps/member/models.py:248 +#: apps/member/models.py:249 msgid "clubs" msgstr "clubs" -#: apps/member/models.py:282 +#: apps/member/models.py:283 msgid "membership starts on" msgstr "l'adhésion commence le" -#: apps/member/models.py:286 +#: apps/member/models.py:287 msgid "membership ends on" msgstr "l'adhésion finit le" -#: apps/member/models.py:310 apps/member/views.py:540 apps/wei/views.py:798 -msgid "User is not a member of the parent club" -msgstr "L'utilisateur n'est pas membre du club parent" - -#: apps/member/models.py:317 +#: apps/member/models.py:339 #, python-brace-format msgid "The role {role} does not apply to the club {club}." msgstr "Le rôle {role} ne s'applique pas au club {club}." -#: apps/member/models.py:328 apps/member/views.py:549 +#: apps/member/models.py:350 apps/member/views.py:583 msgid "User is already a member of the club" msgstr "L'utilisateur est déjà membre du club" -#: apps/member/models.py:379 +#: apps/member/models.py:386 +msgid "User is not a member of the parent club" +msgstr "L'utilisateur n'est pas membre du club parent" + +#: apps/member/models.py:439 #, python-brace-format msgid "Membership of {user} for the club {club}" msgstr "Adhésion de {user} pour le club {club}" -#: apps/member/models.py:382 +#: apps/member/models.py:442 msgid "membership" msgstr "adhésion" -#: apps/member/models.py:383 +#: apps/member/models.py:443 msgid "memberships" msgstr "adhésions" @@ -625,7 +630,7 @@ msgstr "Modifier le club" msgid "Add new member to the club" msgstr "Ajouter un nouveau membre au club" -#: apps/member/views.py:530 apps/wei/views.py:783 +#: apps/member/views.py:574 apps/wei/views.py:862 msgid "" "This user don't have enough money to join this club, and can't have a " "negative balance." @@ -633,25 +638,25 @@ msgstr "" "Cet utilisateur n'a pas assez d'argent pour rejoindre ce club et ne peut pas " "avoir un solde négatif." -#: apps/member/views.py:553 +#: apps/member/views.py:587 msgid "The membership must start after {:%m-%d-%Y}." msgstr "L'adhésion doit commencer après le {:%d/%m/%Y}." -#: apps/member/views.py:558 +#: apps/member/views.py:592 msgid "The membership must begin before {:%m-%d-%Y}." msgstr "L'adhésion doit commencer avant le {:%d/%m/%Y}." -#: apps/member/views.py:575 apps/member/views.py:577 apps/member/views.py:579 +#: apps/member/views.py:609 apps/member/views.py:611 apps/member/views.py:613 #: apps/registration/views.py:290 apps/registration/views.py:292 -#: apps/registration/views.py:294 +#: apps/registration/views.py:294 apps/wei/views.py:867 apps/wei/views.py:871 msgid "This field is required." msgstr "Ce champ est requis." -#: apps/member/views.py:647 +#: apps/member/views.py:690 msgid "Manage roles of an user in the club" msgstr "Gérer les rôles d'un utilisateur dans le club" -#: apps/member/views.py:672 +#: apps/member/views.py:715 msgid "Members of the club" msgstr "Membres du club" @@ -950,13 +955,13 @@ msgstr "Cliquez pour valider" msgid "No reason specified" msgstr "Pas de motif spécifié" -#: apps/note/tables.py:139 apps/note/tables.py:167 apps/wei/tables.py:66 -#: templates/treasury/sogecredit_detail.html:59 +#: apps/note/tables.py:139 apps/note/tables.py:167 apps/wei/tables.py:74 +#: apps/wei/tables.py:100 templates/treasury/sogecredit_detail.html:59 #: templates/wei/weiregistration_confirm_delete.html:32 msgid "Delete" msgstr "Supprimer" -#: apps/note/tables.py:162 apps/wei/tables.py:42 apps/wei/tables.py:43 +#: apps/note/tables.py:162 apps/wei/tables.py:46 apps/wei/tables.py:47 #: templates/member/club_info.html:67 templates/note/conso_form.html:128 #: templates/wei/bus_tables.html:15 templates/wei/busteam_tables.html:15 #: templates/wei/busteam_tables.html:33 templates/wei/weiclub_info.html:68 @@ -1190,7 +1195,7 @@ msgstr "Trésorerie" #: templates/activity/activity_form.html:9 #: templates/activity/activity_invite.html:8 #: templates/django_filters/rest_framework/form.html:5 -#: templates/member/add_members.html:14 templates/member/club_form.html:9 +#: templates/member/add_members.html:31 templates/member/club_form.html:9 #: templates/note/transactiontemplate_form.html:15 #: templates/treasury/invoice_form.html:46 templates/wei/bus_form.html:13 #: templates/wei/busteam_form.html:13 templates/wei/weiclub_form.html:15 @@ -1410,7 +1415,7 @@ msgstr "Joindre une transaction à une remise" msgid "List of credits from the Société générale" msgstr "Liste des crédits de la Société générale" -#: apps/treasury/views.py:384 +#: apps/treasury/views.py:379 msgid "Manage credits from the Société générale" msgstr "Gérer les crédits de la Société générale" @@ -1419,12 +1424,12 @@ msgstr "Gérer les crédits de la Société générale" msgid "WEI" msgstr "WEI" -#: apps/wei/forms/registration.py:48 apps/wei/models.py:112 +#: apps/wei/forms/registration.py:50 apps/wei/models.py:112 #: apps/wei/models.py:297 msgid "bus" msgstr "Bus" -#: apps/wei/forms/registration.py:49 +#: apps/wei/forms/registration.py:51 msgid "" "This choice is not definitive. The WEI organizers are free to attribute for " "you a bus and a team, in particular if you are a free eletron." @@ -1433,11 +1438,11 @@ msgstr "" "attribuer un bus et une équipe, en particulier si vous êtes un électron " "libre." -#: apps/wei/forms/registration.py:56 +#: apps/wei/forms/registration.py:58 msgid "Team" msgstr "Équipe" -#: apps/wei/forms/registration.py:58 +#: apps/wei/forms/registration.py:60 msgid "" "Leave this field empty if you won't be in a team (staff, bus chief, free " "electron)" @@ -1445,16 +1450,16 @@ msgstr "" "Laissez ce champ vide si vous ne serez pas dans une équipe (staff, chef de " "bus ou électron libre)" -#: apps/wei/forms/registration.py:64 apps/wei/forms/registration.py:74 +#: apps/wei/forms/registration.py:66 apps/wei/forms/registration.py:76 #: apps/wei/models.py:147 msgid "WEI Roles" msgstr "Rôles au WEI" -#: apps/wei/forms/registration.py:65 +#: apps/wei/forms/registration.py:67 msgid "Select the roles that you are interested in." msgstr "Sélectionnez les rôles qui vous intéressent." -#: apps/wei/forms/registration.py:81 +#: apps/wei/forms/registration.py:112 msgid "This team doesn't belong to the given bus." msgstr "Cette équipe n'appartient pas à ce bus." @@ -1624,97 +1629,97 @@ msgstr "adhésion au WEI" msgid "WEI memberships" msgstr "adhésions au WEI" -#: apps/wei/tables.py:53 apps/wei/tables.py:54 +#: apps/wei/tables.py:57 apps/wei/tables.py:58 apps/wei/tables.py:95 #: templates/treasury/sogecredit_detail.html:57 msgid "Validate" msgstr "Valider" -#: apps/wei/tables.py:96 +#: apps/wei/tables.py:125 msgid "Year" msgstr "Année" -#: apps/wei/tables.py:134 templates/wei/bus_tables.html:26 +#: apps/wei/tables.py:163 templates/wei/bus_tables.html:26 #: templates/wei/busteam_tables.html:43 msgid "Teams" msgstr "Équipes" -#: apps/wei/tables.py:143 apps/wei/tables.py:184 +#: apps/wei/tables.py:172 apps/wei/tables.py:213 msgid "Members count" msgstr "Nombre de membres" -#: apps/wei/tables.py:150 apps/wei/tables.py:181 +#: apps/wei/tables.py:179 apps/wei/tables.py:210 msgid "members" msgstr "adhérents" -#: apps/wei/views.py:56 +#: apps/wei/views.py:57 msgid "Search WEI" msgstr "Chercher un WEI" -#: apps/wei/views.py:74 templates/wei/weiclub_list.html:10 +#: apps/wei/views.py:75 templates/wei/weiclub_list.html:10 msgid "Create WEI" msgstr "Créer un WEI" -#: apps/wei/views.py:94 +#: apps/wei/views.py:95 msgid "WEI Detail" msgstr "Détails du WEI" -#: apps/wei/views.py:189 +#: apps/wei/views.py:190 msgid "View members of the WEI" msgstr "Voir les membres du WEI" -#: apps/wei/views.py:217 +#: apps/wei/views.py:218 msgid "Find WEI Membership" msgstr "Trouver une adhésion au WEI" -#: apps/wei/views.py:227 +#: apps/wei/views.py:228 msgid "View registrations to the WEI" msgstr "Voir les inscriptions au WEI" -#: apps/wei/views.py:251 +#: apps/wei/views.py:252 msgid "Find WEI Registration" msgstr "Trouver une inscription au WEI" -#: apps/wei/views.py:262 +#: apps/wei/views.py:263 msgid "Update the WEI" msgstr "Modifier le WEI" -#: apps/wei/views.py:283 +#: apps/wei/views.py:284 msgid "Create new bus" msgstr "Ajouter un nouveau bus" -#: apps/wei/views.py:314 +#: apps/wei/views.py:315 msgid "Update bus" msgstr "Modifier le bus" -#: apps/wei/views.py:344 +#: apps/wei/views.py:345 msgid "Manage bus" msgstr "Gérer le bus" -#: apps/wei/views.py:371 +#: apps/wei/views.py:372 msgid "Create new team" msgstr "Créer une nouvelle équipe" -#: apps/wei/views.py:403 +#: apps/wei/views.py:404 msgid "Update team" msgstr "Modifier l'équipe" -#: apps/wei/views.py:434 +#: apps/wei/views.py:435 msgid "Manage WEI team" msgstr "Gérer l'équipe WEI" -#: apps/wei/views.py:456 +#: apps/wei/views.py:457 msgid "Register first year student to the WEI" msgstr "Inscrire un 1A au WEI" -#: apps/wei/views.py:468 templates/wei/weiclub_info.html:62 +#: apps/wei/views.py:469 templates/wei/weiclub_info.html:62 msgid "Register 1A" msgstr "Inscrire un 1A" -#: apps/wei/views.py:489 apps/wei/views.py:560 +#: apps/wei/views.py:490 apps/wei/views.py:561 msgid "This user is already registered to this WEI." msgstr "Cette personne est déjà inscrite au WEI." -#: apps/wei/views.py:494 +#: apps/wei/views.py:495 msgid "" "This user can't be in her/his first year since he/she has already participed " "to a WEI." @@ -1722,39 +1727,39 @@ msgstr "" "Cet utilisateur ne peut pas être en première année puisqu'iel a déjà " "participé à un WEI." -#: apps/wei/views.py:511 +#: apps/wei/views.py:512 msgid "Register old student to the WEI" msgstr "Inscrire un 2A+ au WEI" -#: apps/wei/views.py:523 templates/wei/weiclub_info.html:65 +#: apps/wei/views.py:524 templates/wei/weiclub_info.html:65 msgid "Register 2A+" msgstr "Inscrire un 2A+" -#: apps/wei/views.py:542 apps/wei/views.py:627 +#: apps/wei/views.py:543 apps/wei/views.py:628 msgid "You already opened an account in the Société générale." msgstr "Vous avez déjà ouvert un compte auprès de la société générale." -#: apps/wei/views.py:590 +#: apps/wei/views.py:591 msgid "Update WEI Registration" msgstr "Modifier l'inscription WEI" -#: apps/wei/views.py:677 +#: apps/wei/views.py:687 msgid "Delete WEI registration" msgstr "Supprimer l'inscription WEI" -#: apps/wei/views.py:688 +#: apps/wei/views.py:698 msgid "You don't have the right to delete this WEI registration." msgstr "Vous n'avez pas la permission de supprimer cette inscription au WEI." -#: apps/wei/views.py:707 +#: apps/wei/views.py:717 msgid "Validate WEI registration" msgstr "Valider l'inscription WEI" -#: apps/wei/views.py:787 +#: apps/wei/views.py:856 msgid "This user didn't give her/his caution check." msgstr "Cet utilisateur n'a pas donné son chèque de caution." -#: apps/wei/views.py:830 apps/wei/views.py:883 apps/wei/views.py:893 +#: apps/wei/views.py:918 apps/wei/views.py:971 apps/wei/views.py:981 #: templates/wei/survey.html:12 templates/wei/survey_closed.html:12 #: templates/wei/survey_end.html:12 msgid "Survey WEI" @@ -1807,7 +1812,7 @@ msgstr "Page inexistante" msgid "" "The requested path %(request_path)s was not found on the server." msgstr "" -"The chemin demandé %(request_path)s n'a pas été trouvé sur le " +"Le chemin demandé %(request_path)s n'a pas été trouvé sur le " "serveur." #: templates/500.html:6 @@ -1926,13 +1931,33 @@ msgstr "" msgid "Field filters" msgstr "" +#: templates/member/add_members.html:15 +#, python-format +msgid "" +"The user is not a member of the club·s %(clubs)s. An additional fee of " +"%(pretty_fee)s will be charged to renew automatically the membership in this/" +"these club·s." +msgstr "" +"Cet utilisateur n'est pas membre du/des club·s parent·s %(clubs)s. Un " +"montant supplémentaire de%(pretty_fee)s sera débitée afin de renouveler " +"automatiquement l'adhésion dans ce·s club·s." + +#: templates/member/add_members.html:20 +#, python-format +msgid "" +"This club has parents %(clubs)s. An additional fee of %(pretty_fee)s will be " +"charged to adhere automatically to this/these club·s." +msgstr "" +"Ce club a pour parent·s %(clubs)s. Un coût supplémentaire de %(pretty_fee)s " +"peut être ajouté pour adhérer automatiquement à ce·s club·s." + #: templates/member/alias_update.html:5 msgid "Add alias" msgstr "Ajouter un alias" #: templates/member/autocomplete_model.html:11 msgid "Reset" -msgstr "" +msgstr "Réinitialiser" #: templates/member/club_info.html:17 msgid "Club Parent" @@ -2478,7 +2503,7 @@ msgid "" "validated, but no credit will be operated." msgstr "" "Si vous supprimez cette demande de crédit, alors toutes les transactions " -"d'adhésion seront aussi validées, but il n'y aura pas de transaction de " +"d'adhésion seront aussi validées, mais il n'y aura pas de transaction de " "crédit créée." #: templates/treasury/sogecredit_detail.html:37 @@ -2678,6 +2703,7 @@ msgstr "" "aura validé la création du compte, ou bien changer de moyen de paiement." #: templates/wei/weimembership_form.html:162 +#, python-format msgid "" "The note don't have enough money (%(balance)s, %(pretty_fee)s required). The " "registration may fail." @@ -2686,25 +2712,29 @@ msgstr "" "L'inscription va échouer." #: templates/wei/weimembership_form.html:169 -msgid "The note has enough money, the registration is possible." +#, fuzzy, python-format +#| msgid "The note has enough money, the registration is possible." +msgid "" +"The note has enough money (%(pretty_fee)s required), the registration is " +"possible." msgstr "La note a assez d'argent, l'inscription est possible." -#: templates/wei/weimembership_form.html:176 +#: templates/wei/weimembership_form.html:178 msgid "The user didn't give her/his caution check." msgstr "L'utilisateur n'a pas donné son chèque de caution." -#: templates/wei/weimembership_form.html:184 +#: templates/wei/weimembership_form.html:186 +#, fuzzy +#| msgid "" +#| "You must also go to the Kfet to pay your membership. The WEI registration " +#| "includes the BDE membership." msgid "" -"This user is not a member of the Kfet club for the comming year. Please " -"adhere here if he/she is in her/his first " -"year or here if he/she was an old member " -"before you validate the registration of the WEI." +"This user is not a member of the Kfet club for the coming year. The " +"membership will be processed automatically, the WEI registration includes " +"the membership fee." msgstr "" -"Cet utilisateur n'est pas membre du club Kfet pour l'année à venir. Merci de le faire adhérer\n" -"ici s'iel est en première année\n" -"ou ici s'iel est un ancien membre avant de " -"valider\n" -"l'inscription au WEI." +"Vous devrez également vous rendre à la Kfet pour payer votre adhésion. " +"L'inscription au WEI inclut l'adhésion au BDE." #: templates/wei/weimembership_list.html:24 msgid "View unvalidated registrations..." @@ -2730,3 +2760,16 @@ msgstr "Il n'y a pas de pré-inscription en attente avec cette entrée." #: templates/wei/weiregistration_list.html:24 msgid "View validated memberships..." msgstr "Voir les adhésions validées ..." + +#~ msgid "" +#~ "This user is not a member of the Kfet club for the comming year. Please " +#~ "adhere here if he/she is in her/his " +#~ "first year or here if he/she was an old " +#~ "member before you validate the registration of the WEI." +#~ msgstr "" +#~ "Cet utilisateur n'est pas membre du club Kfet pour l'année à venir. Merci " +#~ "de le faire adhérer\n" +#~ "ici s'iel est en première année\n" +#~ "ou ici s'iel est un ancien membre avant " +#~ "de valider\n" +#~ "l'inscription au WEI." diff --git a/templates/base.html b/templates/base.html index 9b1f463e..8b45d914 100644 --- a/templates/base.html +++ b/templates/base.html @@ -124,27 +124,27 @@ SPDX-License-Identifier: GPL-3.0-or-later {% trans 'WEI' %} {% endif %} - {% if user.is_authenticated %} + {% if request.user.is_authenticated %} {% endif %} - {% if user.is_staff and ""|has_perm:user %} + {% if request.user.is_staff and ""|has_perm:user %} {% endif %}