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

Handle credits from the Société générale

This commit is contained in:
Yohann D'ANELLO 2020-04-22 03:26:45 +02:00
parent f83f6da79a
commit b23814aef0
25 changed files with 954 additions and 500 deletions

View File

@ -28,7 +28,7 @@ class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = '__all__'
exclude = ('user', 'email_confirmed', 'registration_valid', 'soge', )
exclude = ('user', 'email_confirmed', 'registration_valid', )
class ClubForm(forms.ModelForm):

View File

@ -64,11 +64,12 @@ class Profile(models.Model):
default=False,
)
soge = models.BooleanField(
verbose_name=_("Société générale"),
help_text=_("Has the user ever be paid by the Société générale?"),
default=False,
)
@property
def soge(self):
if "treasury" in settings.INSTALLED_APPS:
from treasury.models import SogeCredit
return SogeCredit.objects.filter(user=self.user, credit_transaction=None).exists()
return False
class Meta:
verbose_name = _('user profile')
@ -309,6 +310,19 @@ 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 the soge pays, then the transaction is unvalidated in a first time, then submitted for control
# to treasurers.
transaction.valid = False
from treasury.models import SogeCredit
soge_credit = SogeCredit.objects.get_or_create(user=self.user)[0]
soge_credit.refresh_from_db()
transaction.save(force_insert=True)
transaction.refresh_from_db()
soge_credit.transactions.add(transaction)
soge_credit.save()
else:
transaction.save(force_insert=True)
def __str__(self):

View File

@ -18,7 +18,7 @@ from django.views.generic.edit import FormMixin
from django_tables2.views import SingleTableView
from rest_framework.authtoken.models import Token
from note.forms import ImageForm
from note.models import Alias, NoteUser, NoteSpecial
from note.models import Alias, NoteUser
from note.models.transactions import Transaction, SpecialTransaction
from note.tables import HistoryTable, AliasTable
from permission.backends import PermissionBackend
@ -128,7 +128,8 @@ class UserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
context = super().get_context_data(**kwargs)
user = context['user_object']
history_list = \
Transaction.objects.all().filter(Q(source=user.note) | Q(destination=user.note)).order_by("-id")\
Transaction.objects.all().filter(Q(source=user.note) | Q(destination=user.note))\
.order_by("-created_at", "-id")\
.filter(PermissionBackend.filter_queryset(self.request.user, Transaction, "view"))
history_table = HistoryTable(history_list, prefix='transaction-')
history_table.paginate(per_page=20, page=self.request.GET.get("transaction-page", 1))
@ -314,7 +315,8 @@ class ClubDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
club.update_membership_dates()
club_transactions = Transaction.objects.all().filter(Q(source=club.note) | Q(destination=club.note))\
.filter(PermissionBackend.filter_queryset(self.request.user, Transaction, "view")).order_by('-id')
.filter(PermissionBackend.filter_queryset(self.request.user, Transaction, "view"))\
.order_by('-created_at', '-id')
history_table = HistoryTable(club_transactions, prefix="history-")
history_table.paginate(per_page=20, page=self.request.GET.get('history-page', 1))
context['history_list'] = history_table
@ -365,6 +367,15 @@ class ClubUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
form_class = ClubForm
template_name = "member/club_form.html"
def get_queryset(self, **kwargs):
qs = super().get_queryset(**kwargs)
# Don't update a WEI club through this view
if "wei" in settings.INSTALLED_APPS:
qs = qs.filter(weiclub=None)
return qs
def get_success_url(self):
return reverse_lazy("member:club_detail", kwargs={"pk": self.object.pk})
@ -396,7 +407,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
if "club_pk" in self.kwargs:
# We create a new membership.
club = Club.objects.filter(PermissionBackend.filter_queryset(self.request.user, Club, "view"))\
.get(pk=self.kwargs["club_pk"])
.get(pk=self.kwargs["club_pk"], weiclub=None)
form.fields['credit_amount'].initial = club.membership_fee_paid
form.fields['roles'].initial = Role.objects.filter(name="Membre de club").all()
@ -463,17 +474,11 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
bank = form.cleaned_data["bank"]
soge = form.cleaned_data["soge"] and not user.profile.soge and club.name == "BDE"
# If Société générale pays, then we auto-fill some data
# 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.
if soge:
credit_type = NoteSpecial.objects.get(special_type="Virement bancaire")
bde = club
kfet = Club.objects.get(name="Kfet")
if user.profile.paid:
fee = bde.membership_fee_paid + kfet.membership_fee_paid
else:
fee = bde.membership_fee_unpaid + kfet.membership_fee_unpaid
credit_amount = fee
bank = "Société générale"
credit_type = None
form.instance._soge = True
if credit_type is None:
credit_amount = 0
@ -546,11 +551,9 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
ret = super().form_valid(form)
# If Société générale pays, then we store the information: the bank can't pay twice to a same person.
# 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:
user.profile.soge = True
user.profile.save()
kfet = Club.objects.get(name="Kfet")
kfet_fee = kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid
@ -562,13 +565,16 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
date_end__gte=datetime.today(),
)
membership = Membership.objects.create(
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._soge = True
membership.save()
membership.refresh_from_db()
if old_membership.exists():
membership.roles.set(old_membership.get().roles.all())
else:

View File

@ -8,6 +8,7 @@ from django.utils.translation import gettext_lazy as _
from polymorphic.models import PolymorphicModel
from .notes import Note, NoteClub, NoteSpecial
from ..templatetags.pretty_money import pretty_money
"""
Defines transactions
@ -198,6 +199,14 @@ class Transaction(PolymorphicModel):
self.source.save()
self.destination.save()
def delete(self, **kwargs):
"""
Whenever we want to delete a transaction (caution with this), we ensure the transaction is invalid first.
"""
self.valid = False
self.save(**kwargs)
super().delete(**kwargs)
@property
def total(self):
return self.amount * self.quantity
@ -206,6 +215,10 @@ class Transaction(PolymorphicModel):
def type(self):
return _('Transfer')
def __str__(self):
return self.__class__.__name__ + " from " + str(self.source) + " to " + str(self.destination) + " of "\
+ pretty_money(self.quantity * self.amount) + ("" if self.valid else " invalid")
class RecurrentTransaction(Transaction):
"""

View File

@ -10,7 +10,7 @@ def save_user_note(instance, raw, **_kwargs):
# When provisionning data, do not try to autocreate
return
if (instance.is_superuser or instance.profile.registration_valid) and instance.is_active:
if instance.is_superuser or instance.profile.registration_valid:
# Create note only when the registration is validated
from note.models import NoteUser
NoteUser.objects.get_or_create(user=instance)

View File

@ -30,7 +30,7 @@ class TransactionCreateView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTabl
table_class = HistoryTable
def get_queryset(self, **kwargs):
return super().get_queryset(**kwargs).order_by("-id").all()[:20]
return super().get_queryset(**kwargs).order_by("-created_at", "-id").all()[:20]
def get_context_data(self, **kwargs):
"""
@ -93,7 +93,7 @@ class ConsoView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
table_class = HistoryTable
def get_queryset(self, **kwargs):
return super().get_queryset(**kwargs).order_by("-id").all()[:20]
return super().get_queryset(**kwargs).order_by("-created_at", "-id").all()[:20]
def get_context_data(self, **kwargs):
"""

View File

@ -16,13 +16,12 @@ from django.views.generic.edit import FormMixin
from django_tables2 import SingleTableView
from member.forms import ProfileForm
from member.models import Membership, Club, Role
from note.models import SpecialTransaction, NoteSpecial
from note.models import SpecialTransaction
from note.templatetags.pretty_money import pretty_money
from permission.backends import PermissionBackend
from permission.views import ProtectQuerysetMixin
from wei.models import WEIClub
from .forms import SignUpForm, ValidationForm, WEISignupForm
from .forms import SignUpForm, ValidationForm
from .tables import FutureUserTable
from .tokens import email_validation_token
@ -40,16 +39,6 @@ class UserCreateView(CreateView):
context = super().get_context_data(**kwargs)
context["profile_form"] = self.second_form()
if "wei" in settings.INSTALLED_APPS:
from wei.forms import WEIRegistrationForm
wei_form = WEIRegistrationForm()
del wei_form.fields["user"]
del wei_form.fields["caution_check"]
del wei_form.fields["first_year"]
del wei_form.fields["information_json"]
context["wei_form"] = wei_form
context["wei_registration_form"] = WEISignupForm()
return context
def form_valid(self, form):
@ -62,23 +51,6 @@ class UserCreateView(CreateView):
if not profile_form.is_valid():
return self.form_invalid(form)
wei_form = None
self.wei = False
if "wei" in settings.INSTALLED_APPS:
wei_signup_form = WEISignupForm(self.request.POST)
if wei_signup_form.is_valid() and wei_signup_form.cleaned_data["wei_registration"]:
from wei.forms import WEIRegistrationForm
wei_form = WEIRegistrationForm(self.request.POST)
del wei_form.fields["user"]
del wei_form.fields["caution_check"]
del wei_form.fields["first_year"]
if not wei_form.is_valid():
return self.form_invalid(wei_form)
self.wei = True
# Save the user and the profile
user = form.save(commit=False)
user.is_active = False
@ -92,20 +64,9 @@ class UserCreateView(CreateView):
user.profile.send_email_validation_link()
if self.wei:
wei_registration = wei_form.instance
wei_registration.user = user
wei_registration.wei = WEIClub.objects.order_by('date_start').last()
wei_registration.caution_check = False
wei_registration.first_year = True
wei_registration.save()
return super().form_valid(form)
def get_success_url(self):
if self.wei:
return reverse_lazy('registration:email_validation_sent') # TODO Load WEI survey
else:
return reverse_lazy('registration:email_validation_sent')
@ -304,17 +265,17 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
fee += kfet_fee
if soge:
# Fill payment information if Société Générale pays the inscription
credit_type = NoteSpecial.objects.get(special_type="Virement bancaire")
credit_amount = fee
bank = "Société générale"
# If the bank pays, then we don't credit now. Treasurers will validate the transaction
# and credit the note later.
credit_type = None
print("OK")
if credit_type is None:
credit_amount = 0
if join_Kfet and not join_BDE:
form.add_error('join_Kfet', _("You must join BDE club before joining Kfet club."))
if fee > credit_amount:
if fee > credit_amount and not soge:
# Check if the user credits enough money
form.add_error('credit_type',
_("The entered amount is not enough for the memberships, should be at least {}")
@ -336,10 +297,9 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
ret = super().form_valid(form)
user.is_active = user.profile.email_confirmed or user.is_superuser
user.profile.registration_valid = True
# Store if Société générale paid for next years
user.profile.soge = soge
user.save()
user.profile.save()
user.refresh_from_db()
if credit_type is not None and credit_amount > 0:
# Credit the note
@ -357,21 +317,29 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
if join_BDE:
# Create membership for the user to the BDE starting today
membership = Membership.objects.create(
membership = Membership(
club=bde,
user=user,
fee=bde_fee,
)
if soge:
membership._soge = True
membership.save()
membership.refresh_from_db()
membership.roles.add(Role.objects.get(name="Adhérent BDE"))
membership.save()
if join_Kfet:
# Create membership for the user to the Kfet starting today
membership = Membership.objects.create(
membership = Membership(
club=kfet,
user=user,
fee=kfet_fee,
)
if soge:
membership._soge = True
membership.save()
membership.refresh_from_db()
membership.roles.add(Role.objects.get(name="Adhérent Kfet"))
membership.save()

View File

@ -3,7 +3,7 @@
from django.contrib import admin
from .models import RemittanceType, Remittance
from .models import RemittanceType, Remittance, SogeCredit
@admin.register(RemittanceType)
@ -25,3 +25,6 @@ class RemittanceAdmin(admin.ModelAdmin):
if not obj:
return True
return not obj.closed and super().has_change_permission(request, obj)
admin.site.register(SogeCredit)

View File

@ -4,7 +4,7 @@
from rest_framework import serializers
from note.api.serializers import SpecialTransactionSerializer
from ..models import Invoice, Product, RemittanceType, Remittance
from ..models import Invoice, Product, RemittanceType, Remittance, SogeCredit
class ProductSerializer(serializers.ModelSerializer):
@ -60,3 +60,14 @@ class RemittanceSerializer(serializers.ModelSerializer):
def get_transactions(self, obj):
return serializers.ListSerializer(child=SpecialTransactionSerializer()).to_representation(obj.transactions)
class SogeCreditSerializer(serializers.ModelSerializer):
"""
REST API Serializer for SogeCredit types.
The djangorestframework plugin will analyse the model `SogeCredit` and parse all fields in the API.
"""
class Meta:
model = SogeCredit
fields = '__all__'

View File

@ -1,7 +1,7 @@
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from .views import InvoiceViewSet, ProductViewSet, RemittanceViewSet, RemittanceTypeViewSet
from .views import InvoiceViewSet, ProductViewSet, RemittanceViewSet, RemittanceTypeViewSet, SogeCreditViewSet
def register_treasury_urls(router, path):
@ -12,3 +12,4 @@ def register_treasury_urls(router, path):
router.register(path + '/product', ProductViewSet)
router.register(path + '/remittance_type', RemittanceTypeViewSet)
router.register(path + '/remittance', RemittanceViewSet)
router.register(path + '/soge_credit', SogeCreditViewSet)

View File

@ -5,8 +5,9 @@ from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import SearchFilter
from api.viewsets import ReadProtectedModelViewSet
from .serializers import InvoiceSerializer, ProductSerializer, RemittanceTypeSerializer, RemittanceSerializer
from ..models import Invoice, Product, RemittanceType, Remittance
from .serializers import InvoiceSerializer, ProductSerializer, RemittanceTypeSerializer, RemittanceSerializer,\
SogeCreditSerializer
from ..models import Invoice, Product, RemittanceType, Remittance, SogeCredit
class InvoiceViewSet(ReadProtectedModelViewSet):
@ -39,7 +40,7 @@ class RemittanceTypeViewSet(ReadProtectedModelViewSet):
The djangorestframework plugin will get all `RemittanceType` objects, serialize it to JSON with the given serializer
then render it on /api/treasury/remittance_type/
"""
queryset = RemittanceType.objects.all()
queryset = RemittanceType.objects
serializer_class = RemittanceTypeSerializer
@ -49,5 +50,15 @@ class RemittanceViewSet(ReadProtectedModelViewSet):
The djangorestframework plugin will get all `Remittance` objects, serialize it to JSON with the given serializer,
then render it on /api/treasury/remittance/
"""
queryset = Remittance.objects.all()
queryset = Remittance.objects
serializer_class = RemittanceSerializer
class SogeCreditViewSet(ReadProtectedModelViewSet):
"""
REST API View set.
The djangorestframework plugin will get all `SogeCredit` objects, serialize it to JSON with the given serializer,
then render it on /api/treasury/soge_credit/
"""
queryset = SogeCredit.objects
serializer_class = SogeCreditSerializer

View File

@ -1,11 +1,13 @@
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from datetime import datetime
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.db import models
from django.db.models import Q
from django.utils.translation import gettext_lazy as _
from note.models import NoteSpecial, SpecialTransaction
from note.models import NoteSpecial, SpecialTransaction, MembershipTransaction
class Invoice(models.Model):
@ -207,3 +209,90 @@ class SpecialTransactionProxy(models.Model):
class Meta:
verbose_name = _("special transaction proxy")
verbose_name_plural = _("special transaction proxies")
class SogeCredit(models.Model):
"""
Manage the credits from the Société générale.
"""
user = models.OneToOneField(
User,
on_delete=models.PROTECT,
verbose_name=_("user"),
)
transactions = models.ManyToManyField(
MembershipTransaction,
related_name="+",
verbose_name=_("membership transactions"),
)
credit_transaction = models.OneToOneField(
SpecialTransaction,
on_delete=models.SET_NULL,
verbose_name=_("credit transaction"),
null=True,
)
@property
def valid(self):
return self.credit_transaction is not None
@property
def amount(self):
return sum(transaction.quantity * transaction.amount for transaction in self.transactions.all())
def invalidate(self):
"""
Invalidating a Société générale delete the transaction of the bank if it was already created.
Treasurers must know what they do, With Great Power Comes Great Responsibility...
"""
if self.valid:
self.credit_transaction.valid = False
self.credit_transaction.save()
self.credit_transaction.delete()
self.credit_transaction = None
for transaction in self.transactions.all():
transaction.valid = False
transaction.save()
def validate(self, force=False):
if self.valid and not force:
# The credit is already done
return
# First invalidate all transaction and delete the credit if already did (and force mode)
self.invalidate()
self.credit_transaction = SpecialTransaction.objects.create(
source=NoteSpecial.objects.get(special_type="Virement bancaire"),
destination=self.user.note,
quantity=1,
amount=self.amount,
reason="Crédit société générale",
last_name=self.user.last_name,
first_name=self.user.first_name,
bank="Société générale",
)
self.save()
for transaction in self.transactions.all():
transaction.valid = True
transaction.created_at = datetime.now()
transaction.save()
def delete(self, **kwargs):
"""
Deleting a SogeCredit is equivalent to say that the Société générale didn't pay.
Treasurers must know what they do, this is difficult to undo this operation.
With Great Power Comes Great Responsibility...
"""
self.invalidate()
for transaction in self.transactions.all():
transaction.valid = True
transaction.created_at = datetime.now()
transaction.save()
super().delete(**kwargs)
class Meta:
verbose_name = _("Credit from the Société générale")
verbose_name_plural = _("Credits from the Société générale")

View File

@ -7,7 +7,7 @@ from django_tables2 import A
from note.models import SpecialTransaction
from note.templatetags.pretty_money import pretty_money
from .models import Invoice, Remittance
from .models import Invoice, Remittance, SogeCredit
class InvoiceTable(tables.Table):
@ -101,3 +101,28 @@ class SpecialTransactionTable(tables.Table):
model = SpecialTransaction
template_name = 'django_tables2/bootstrap4.html'
fields = ('id', 'source', 'destination', 'last_name', 'first_name', 'bank', 'amount', 'reason',)
class SogeCreditTable(tables.Table):
user = tables.LinkColumn(
'treasury:manage_soge_credit',
args=[A('pk')],
)
amount = tables.Column(
verbose_name=_("Amount"),
)
valid = tables.Column(
verbose_name=_("Valid"),
)
def render_amount(self, value):
return pretty_money(value)
def render_valid(self, value):
return _("Yes") if value else _("No")
class Meta:
model = SogeCredit
fields = ('user', 'amount', 'valid', )

View File

@ -4,7 +4,8 @@
from django.urls import path
from .views import InvoiceCreateView, InvoiceListView, InvoiceUpdateView, InvoiceRenderView, RemittanceListView,\
RemittanceCreateView, RemittanceUpdateView, LinkTransactionToRemittanceView, UnlinkTransactionToRemittanceView
RemittanceCreateView, RemittanceUpdateView, LinkTransactionToRemittanceView, UnlinkTransactionToRemittanceView,\
SogeCreditListView, SogeCreditManageView
app_name = 'treasury'
urlpatterns = [
@ -21,4 +22,7 @@ urlpatterns = [
path('remittance/link_transaction/<int:pk>/', LinkTransactionToRemittanceView.as_view(), name='link_transaction'),
path('remittance/unlink_transaction/<int:pk>/', UnlinkTransactionToRemittanceView.as_view(),
name='unlink_transaction'),
path('soge-credits/list/', SogeCreditListView.as_view(), name='soge_credits'),
path('soge-credits/manage/<int:pk>/', SogeCreditManageView.as_view(), name='manage_soge_credit'),
]

View File

@ -10,21 +10,23 @@ from crispy_forms.helper import FormHelper
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import ValidationError
from django.db.models import Q
from django.forms import Form
from django.http import HttpResponse
from django.shortcuts import redirect
from django.template.loader import render_to_string
from django.urls import reverse_lazy
from django.views.generic import CreateView, UpdateView
from django.views.generic import CreateView, UpdateView, DetailView
from django.views.generic.base import View, TemplateView
from django.views.generic.edit import BaseFormView
from django_tables2 import SingleTableView
from note.models import SpecialTransaction, NoteSpecial
from note.models import SpecialTransaction, NoteSpecial, Alias
from note_kfet.settings.base import BASE_DIR
from permission.backends import PermissionBackend
from permission.views import ProtectQuerysetMixin
from .forms import InvoiceForm, ProductFormSet, ProductFormSetHelper, RemittanceForm, LinkTransactionToRemittanceForm
from .models import Invoice, Product, Remittance, SpecialTransactionProxy
from .tables import InvoiceTable, RemittanceTable, SpecialTransactionTable
from .models import Invoice, Product, Remittance, SpecialTransactionProxy, SogeCredit
from .tables import InvoiceTable, RemittanceTable, SpecialTransactionTable, SogeCreditTable
class InvoiceCreateView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
@ -307,3 +309,61 @@ class UnlinkTransactionToRemittanceView(LoginRequiredMixin, View):
transaction.save()
return redirect('treasury:remittance_list')
class SogeCreditListView(LoginRequiredMixin, ProtectQuerysetMixin, SingleTableView):
"""
List all Société Générale credits
"""
model = SogeCredit
table_class = SogeCreditTable
def get_queryset(self, **kwargs):
"""
Filter the table with the given parameter.
:param kwargs:
:return:
"""
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 "valid" in self.request.GET:
q = Q(credit_transaction=None)
if not self.request.GET["valid"]:
q = ~q
qs = qs.filter(q)
return qs[:20]
class SogeCreditManageView(LoginRequiredMixin, ProtectQuerysetMixin, BaseFormView, DetailView):
"""
Manage credits from the Société générale.
"""
model = SogeCredit
form_class = Form
def form_valid(self, form):
if "validate" in form.data:
self.get_object().validate(True)
elif "delete" in form.data:
self.get_object().delete()
return super().form_valid(form)
def get_success_url(self):
if "validate" in self.request.POST:
return reverse_lazy('treasury:manage_soge_credit', args=(self.get_object().pk,))
return reverse_lazy('treasury:soge_credits')

View File

@ -3,6 +3,7 @@
import json
from django.conf import settings
from django.contrib.auth.models import User
from django.db import models
from django.utils.translation import gettext_lazy as _
@ -312,3 +313,14 @@ class WEIMembership(Membership):
)
transaction._force_save = True
transaction.save(force_insert=True)
if self.registration.soge_credit and "treasury" in settings.INSTALLED_APPS:
# If the soge pays, then the transaction is unvalidated in a first time, then submitted for control
# to treasurers.
transaction.refresh_from_db()
from treasury.models import SogeCredit
soge_credit = SogeCredit.objects.get_or_create(user=self.user)[0]
soge_credit.refresh_from_db()
transaction.save()
soge_credit.transactions.add(transaction)
soge_credit.save()

View File

@ -73,7 +73,8 @@ class WEIDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
club = context["club"]
club_transactions = Transaction.objects.all().filter(Q(source=club.note) | Q(destination=club.note)) \
.filter(PermissionBackend.filter_queryset(self.request.user, Transaction, "view")).order_by('-id')
.filter(PermissionBackend.filter_queryset(self.request.user, Transaction, "view"))\
.order_by('-created_at', '-id')
history_table = HistoryTable(club_transactions, prefix="history-")
history_table.paginate(per_page=20, page=self.request.GET.get('history-page', 1))
context['history_list'] = history_table
@ -742,9 +743,10 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Crea
return reverse_lazy("wei:wei_detail", kwargs={"pk": self.object.club.pk})
class WEISurveyView(BaseFormView, DetailView):
class WEISurveyView(LoginRequiredMixin, BaseFormView, DetailView):
"""
Display the survey for the WEI for first
Display the survey for the WEI for first year members.
Warning: this page is accessible for anyone that is connected, the view doesn't extend ProtectQuerySetMixin.
"""
model = WEIRegistration
template_name = "wei/survey.html"
@ -800,7 +802,7 @@ class WEISurveyView(BaseFormView, DetailView):
return reverse_lazy('wei:wei_survey', args=(self.get_object().pk,))
class WEISurveyEndView(TemplateView):
class WEISurveyEndView(LoginRequiredMixin, TemplateView):
template_name = "wei/survey_end.html"
def get_context_data(self, **kwargs):
@ -810,7 +812,7 @@ class WEISurveyEndView(TemplateView):
return context
class WEIClosedView(TemplateView):
class WEIClosedView(LoginRequiredMixin, TemplateView):
template_name = "wei/survey_closed.html"
def get_context_data(self, **kwargs):

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-21 17:47+0200\n"
"POT-Creation-Date: 2020-04-22 03:07+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -44,10 +44,10 @@ msgid "You can't invite more than 3 people to this activity."
msgstr ""
#: apps/activity/models.py:23 apps/activity/models.py:48
#: apps/member/models.py:99 apps/member/models.py:203
#: apps/note/models/notes.py:188 apps/note/models/transactions.py:24
#: apps/note/models/transactions.py:44 apps/note/models/transactions.py:237
#: apps/wei/models.py:61 templates/member/club_info.html:13
#: apps/member/models.py:100 apps/member/models.py:204
#: apps/note/models/notes.py:188 apps/note/models/transactions.py:25
#: apps/note/models/transactions.py:45 apps/note/models/transactions.py:250
#: apps/wei/models.py:62 templates/member/club_info.html:13
#: templates/member/profile_info.html:14
#: templates/registration/future_profile_detail.html:16
#: templates/wei/weiclub_info.html:13 templates/wei/weimembership_form.html:18
@ -70,20 +70,21 @@ msgstr ""
msgid "activity types"
msgstr ""
#: apps/activity/models.py:53 apps/note/models/transactions.py:74
#: apps/permission/models.py:103 apps/wei/models.py:67 apps/wei/models.py:123
#: apps/activity/models.py:53 apps/note/models/transactions.py:75
#: apps/permission/models.py:103 apps/wei/models.py:68 apps/wei/models.py:124
#: templates/activity/activity_detail.html:16
msgid "description"
msgstr ""
#: apps/activity/models.py:60 apps/note/models/notes.py:164
#: apps/note/models/transactions.py:64
#: apps/note/models/transactions.py:65
#: templates/activity/activity_detail.html:19
msgid "type"
msgstr ""
#: apps/activity/models.py:66 apps/logs/models.py:21 apps/member/models.py:224
#: apps/note/models/notes.py:117 apps/wei/models.py:154
#: apps/activity/models.py:66 apps/logs/models.py:21 apps/member/models.py:225
#: apps/note/models/notes.py:117 apps/treasury/models.py:220
#: apps/wei/models.py:155 templates/treasury/sogecredit_detail.html:13
#: templates/wei/survey.html:16
msgid "user"
msgstr ""
@ -104,7 +105,7 @@ msgstr ""
msgid "end date"
msgstr ""
#: apps/activity/models.py:93 apps/note/models/transactions.py:139
#: apps/activity/models.py:93 apps/note/models/transactions.py:140
#: templates/activity/activity_detail.html:47
msgid "valid"
msgstr ""
@ -180,7 +181,7 @@ msgstr ""
msgid "remove"
msgstr ""
#: apps/activity/tables.py:75 apps/treasury/models.py:138
#: apps/activity/tables.py:75 apps/treasury/models.py:139
msgid "Type"
msgstr ""
@ -346,117 +347,109 @@ msgstr ""
msgid "registration valid"
msgstr ""
#: apps/member/models.py:68
msgid "Société générale"
msgstr ""
#: apps/member/models.py:69
msgid "Has the user ever be paid by the Société générale?"
msgstr ""
#: apps/member/models.py:74 apps/member/models.py:75
#: apps/member/models.py:75 apps/member/models.py:76
msgid "user profile"
msgstr ""
#: apps/member/models.py:104 templates/member/club_info.html:51
#: apps/member/models.py:105 templates/member/club_info.html:51
#: templates/registration/future_profile_detail.html:22
#: templates/wei/weiclub_info.html:52 templates/wei/weimembership_form.html:24
msgid "email"
msgstr ""
#: apps/member/models.py:111
#: apps/member/models.py:112
msgid "parent club"
msgstr ""
#: apps/member/models.py:120
#: apps/member/models.py:121
msgid "require memberships"
msgstr ""
#: apps/member/models.py:121
#: apps/member/models.py:122
msgid "Uncheck if this club don't require memberships."
msgstr ""
#: apps/member/models.py:126 templates/member/club_info.html:35
#: apps/member/models.py:127 templates/member/club_info.html:35
msgid "membership fee (paid students)"
msgstr ""
#: apps/member/models.py:131 templates/member/club_info.html:38
#: apps/member/models.py:132 templates/member/club_info.html:38
msgid "membership fee (unpaid students)"
msgstr ""
#: apps/member/models.py:137 templates/member/club_info.html:28
#: apps/member/models.py:138 templates/member/club_info.html:28
msgid "membership duration"
msgstr ""
#: apps/member/models.py:138
#: apps/member/models.py:139
msgid "The longest time (in days) a membership can last (NULL = infinite)."
msgstr ""
#: apps/member/models.py:145 templates/member/club_info.html:22
#: apps/member/models.py:146 templates/member/club_info.html:22
msgid "membership start"
msgstr ""
#: apps/member/models.py:146
#: apps/member/models.py:147
msgid "How long after January 1st the members can renew their membership."
msgstr ""
#: apps/member/models.py:153 templates/member/club_info.html:25
#: apps/member/models.py:154 templates/member/club_info.html:25
msgid "membership end"
msgstr ""
#: apps/member/models.py:154
#: apps/member/models.py:155
msgid ""
"How long the membership can last after January 1st of the next year after "
"members can renew their membership."
msgstr ""
#: apps/member/models.py:188 apps/member/models.py:230
#: apps/member/models.py:189 apps/member/models.py:231
#: apps/note/models/notes.py:139
msgid "club"
msgstr ""
#: apps/member/models.py:189
#: apps/member/models.py:190
msgid "clubs"
msgstr ""
#: apps/member/models.py:209 apps/permission/models.py:294
#: apps/member/models.py:210 apps/permission/models.py:294
msgid "role"
msgstr ""
#: apps/member/models.py:210 apps/member/models.py:235
#: apps/member/models.py:211 apps/member/models.py:236
msgid "roles"
msgstr ""
#: apps/member/models.py:240
#: apps/member/models.py:241
msgid "membership starts on"
msgstr ""
#: apps/member/models.py:244
#: apps/member/models.py:245
msgid "membership ends on"
msgstr ""
#: apps/member/models.py:249
#: apps/member/models.py:250
msgid "fee"
msgstr ""
#: apps/member/models.py:267 apps/member/views.py:500 apps/wei/views.py:726
#: apps/member/models.py:268 apps/member/views.py:494 apps/wei/views.py:726
msgid "User is not a member of the parent club"
msgstr ""
#: apps/member/models.py:277 apps/member/views.py:509
#: apps/member/models.py:278 apps/member/views.py:503
msgid "User is already a member of the club"
msgstr ""
#: apps/member/models.py:315
#: apps/member/models.py:329
#, python-brace-format
msgid "Membership of {user} for the club {club}"
msgstr ""
#: apps/member/models.py:318
#: apps/member/models.py:332
msgid "membership"
msgstr ""
#: apps/member/models.py:319
#: apps/member/models.py:333
msgid "memberships"
msgstr ""
@ -482,32 +475,32 @@ msgstr ""
msgid "Search user"
msgstr ""
#: apps/member/views.py:495 apps/wei/views.py:717
#: apps/member/views.py:489 apps/wei/views.py:717
msgid ""
"This user don't have enough money to join this club, and can't have a "
"negative balance."
msgstr ""
#: apps/member/views.py:513
#: apps/member/views.py:507
msgid "The membership must start after {:%m-%d-%Y}."
msgstr ""
#: apps/member/views.py:518
#: apps/member/views.py:512
msgid "The membership must begin before {:%m-%d-%Y}."
msgstr ""
#: apps/member/views.py:528 apps/member/views.py:530 apps/member/views.py:532
#: apps/registration/views.py:327 apps/registration/views.py:329
#: apps/registration/views.py:331
#: apps/member/views.py:522 apps/member/views.py:524 apps/member/views.py:526
#: apps/registration/views.py:288 apps/registration/views.py:290
#: apps/registration/views.py:292
msgid "This field is required."
msgstr ""
#: apps/note/admin.py:120 apps/note/models/transactions.py:99
#: apps/note/admin.py:120 apps/note/models/transactions.py:100
msgid "source"
msgstr ""
#: apps/note/admin.py:128 apps/note/admin.py:170
#: apps/note/models/transactions.py:54 apps/note/models/transactions.py:112
#: apps/note/models/transactions.py:55 apps/note/models/transactions.py:113
msgid "destination"
msgstr ""
@ -549,7 +542,7 @@ msgstr ""
msgid "display image"
msgstr ""
#: apps/note/models/notes.py:53 apps/note/models/transactions.py:122
#: apps/note/models/notes.py:53 apps/note/models/transactions.py:123
msgid "created at"
msgstr ""
@ -620,97 +613,98 @@ msgstr ""
msgid "You can't delete your main alias."
msgstr ""
#: apps/note/models/transactions.py:30
#: apps/note/models/transactions.py:31
msgid "transaction category"
msgstr ""
#: apps/note/models/transactions.py:31
#: apps/note/models/transactions.py:32
msgid "transaction categories"
msgstr ""
#: apps/note/models/transactions.py:47
#: apps/note/models/transactions.py:48
msgid "A template with this name already exist"
msgstr ""
#: apps/note/models/transactions.py:58 apps/note/models/transactions.py:130
#: apps/note/models/transactions.py:59 apps/note/models/transactions.py:131
msgid "amount"
msgstr ""
#: apps/note/models/transactions.py:59
#: apps/note/models/transactions.py:60
msgid "in centimes"
msgstr ""
#: apps/note/models/transactions.py:70
#: apps/note/models/transactions.py:71
msgid "display"
msgstr ""
#: apps/note/models/transactions.py:80
#: apps/note/models/transactions.py:81
msgid "transaction template"
msgstr ""
#: apps/note/models/transactions.py:81
#: apps/note/models/transactions.py:82
msgid "transaction templates"
msgstr ""
#: apps/note/models/transactions.py:105 apps/note/models/transactions.py:118
#: apps/note/models/transactions.py:106 apps/note/models/transactions.py:119
#: apps/note/tables.py:33 apps/note/tables.py:42
msgid "used alias"
msgstr ""
#: apps/note/models/transactions.py:126
#: apps/note/models/transactions.py:127
msgid "quantity"
msgstr ""
#: apps/note/models/transactions.py:134
#: apps/note/models/transactions.py:135
msgid "reason"
msgstr ""
#: apps/note/models/transactions.py:144 apps/note/tables.py:95
#: apps/note/models/transactions.py:145 apps/note/tables.py:95
msgid "invalidity reason"
msgstr ""
#: apps/note/models/transactions.py:152
#: apps/note/models/transactions.py:153
msgid "transaction"
msgstr ""
#: apps/note/models/transactions.py:153
#: apps/note/models/transactions.py:154
#: templates/treasury/sogecredit_detail.html:16
msgid "transactions"
msgstr ""
#: apps/note/models/transactions.py:207
#: apps/note/models/transactions.py:216
#: templates/activity/activity_entry.html:13 templates/base.html:84
#: templates/note/transaction_form.html:19
#: templates/note/transaction_form.html:145
msgid "Transfer"
msgstr ""
#: apps/note/models/transactions.py:227
#: apps/note/models/transactions.py:240
msgid "Template"
msgstr ""
#: apps/note/models/transactions.py:242
#: apps/note/models/transactions.py:255
msgid "first_name"
msgstr ""
#: apps/note/models/transactions.py:247
#: apps/note/models/transactions.py:260
msgid "bank"
msgstr ""
#: apps/note/models/transactions.py:253
#: apps/note/models/transactions.py:266
#: templates/activity/activity_entry.html:17
#: templates/note/transaction_form.html:24
msgid "Credit"
msgstr ""
#: apps/note/models/transactions.py:253 templates/note/transaction_form.html:28
#: apps/note/models/transactions.py:266 templates/note/transaction_form.html:28
msgid "Debit"
msgstr ""
#: apps/note/models/transactions.py:269 apps/note/models/transactions.py:274
#: apps/note/models/transactions.py:282 apps/note/models/transactions.py:287
msgid "membership transaction"
msgstr ""
#: apps/note/models/transactions.py:270
#: apps/note/models/transactions.py:283 apps/treasury/models.py:226
msgid "membership transactions"
msgstr ""
@ -727,6 +721,7 @@ msgid "No reason specified"
msgstr ""
#: apps/note/tables.py:122 apps/note/tables.py:151 apps/wei/tables.py:66
#: templates/treasury/sogecredit_detail.html:45
#: templates/wei/weiregistration_confirm_delete.html:32
msgid "Delete"
msgstr ""
@ -806,31 +801,31 @@ msgstr ""
msgid "Join Kfet Club"
msgstr ""
#: apps/registration/views.py:116
#: apps/registration/views.py:77
msgid "Email validation"
msgstr ""
#: apps/registration/views.py:162
#: apps/registration/views.py:123
msgid "Email validation unsuccessful"
msgstr ""
#: apps/registration/views.py:173
#: apps/registration/views.py:134
msgid "Email validation email sent"
msgstr ""
#: apps/registration/views.py:226
#: apps/registration/views.py:187
msgid "Unregistered users"
msgstr ""
#: apps/registration/views.py:293
#: apps/registration/views.py:254
msgid "You must join the BDE."
msgstr ""
#: apps/registration/views.py:315
#: apps/registration/views.py:276
msgid "You must join BDE club before joining Kfet club."
msgstr ""
#: apps/registration/views.py:320
#: apps/registration/views.py:281
msgid ""
"The entered amount is not enough for the memberships, should be at least {}"
msgstr ""
@ -863,123 +858,137 @@ msgid "You can't change the type of the remittance."
msgstr ""
#: apps/treasury/forms.py:127 apps/treasury/tables.py:47
#: templates/note/transaction_form.html:133
#: apps/treasury/tables.py:113 templates/note/transaction_form.html:133
#: templates/treasury/remittance_form.html:18
msgid "Amount"
msgstr ""
#: apps/treasury/models.py:18
#: apps/treasury/models.py:19
msgid "Invoice identifier"
msgstr ""
#: apps/treasury/models.py:32
#: apps/treasury/models.py:33
msgid "BDE"
msgstr ""
#: apps/treasury/models.py:37
#: apps/treasury/models.py:38
msgid "Object"
msgstr ""
#: apps/treasury/models.py:41
#: apps/treasury/models.py:42
msgid "Description"
msgstr ""
#: apps/treasury/models.py:46 templates/note/transaction_form.html:91
#: apps/treasury/models.py:47 templates/note/transaction_form.html:91
msgid "Name"
msgstr ""
#: apps/treasury/models.py:50
#: apps/treasury/models.py:51
msgid "Address"
msgstr ""
#: apps/treasury/models.py:55
#: apps/treasury/models.py:56
msgid "Place"
msgstr ""
#: apps/treasury/models.py:59
#: apps/treasury/models.py:60
msgid "Acquitted"
msgstr ""
#: apps/treasury/models.py:63
#: apps/treasury/models.py:64
msgid "invoice"
msgstr ""
#: apps/treasury/models.py:64
#: apps/treasury/models.py:65
msgid "invoices"
msgstr ""
#: apps/treasury/models.py:79
#: apps/treasury/models.py:80
msgid "Designation"
msgstr ""
#: apps/treasury/models.py:83
#: apps/treasury/models.py:84
msgid "Quantity"
msgstr ""
#: apps/treasury/models.py:87
#: apps/treasury/models.py:88
msgid "Unit price"
msgstr ""
#: apps/treasury/models.py:103
#: apps/treasury/models.py:104
msgid "product"
msgstr ""
#: apps/treasury/models.py:104
#: apps/treasury/models.py:105
msgid "products"
msgstr ""
#: apps/treasury/models.py:121
#: apps/treasury/models.py:122
msgid "remittance type"
msgstr ""
#: apps/treasury/models.py:122
#: apps/treasury/models.py:123
msgid "remittance types"
msgstr ""
#: apps/treasury/models.py:132
#: apps/treasury/models.py:133
msgid "Date"
msgstr ""
#: apps/treasury/models.py:143
#: apps/treasury/models.py:144
msgid "Comment"
msgstr ""
#: apps/treasury/models.py:148
#: apps/treasury/models.py:149
msgid "Closed"
msgstr ""
#: apps/treasury/models.py:152
#: apps/treasury/models.py:153
msgid "remittance"
msgstr ""
#: apps/treasury/models.py:153
#: apps/treasury/models.py:154
msgid "remittances"
msgstr ""
#: apps/treasury/models.py:185
#: apps/treasury/models.py:186
msgid "Remittance #{:d}: {}"
msgstr ""
#: apps/treasury/models.py:204 apps/treasury/tables.py:76
#: apps/treasury/models.py:205 apps/treasury/tables.py:76
#: apps/treasury/tables.py:84 templates/treasury/invoice_list.html:13
#: templates/treasury/remittance_list.html:13
#: templates/treasury/sogecredit_list.html:13
msgid "Remittance"
msgstr ""
#: apps/treasury/models.py:208
#: apps/treasury/models.py:209
msgid "special transaction proxy"
msgstr ""
#: apps/treasury/models.py:209
#: apps/treasury/models.py:210
msgid "special transaction proxies"
msgstr ""
#: apps/treasury/models.py:232
msgid "credit transaction"
msgstr ""
#: apps/treasury/models.py:294 templates/treasury/sogecredit_detail.html:9
msgid "Credit from the Société générale"
msgstr ""
#: apps/treasury/models.py:295
msgid "Credits from the Société générale"
msgstr ""
#: apps/treasury/tables.py:19
msgid "Invoice #{:d}"
msgstr ""
#: apps/treasury/tables.py:22 templates/treasury/invoice_list.html:10
#: templates/treasury/remittance_list.html:10
#: templates/treasury/sogecredit_list.html:10
msgid "Invoice"
msgstr ""
@ -999,13 +1008,25 @@ msgstr ""
msgid "Remove"
msgstr ""
#: apps/wei/apps.py:10 apps/wei/models.py:44 apps/wei/models.py:45
#: apps/wei/models.py:56 apps/wei/models.py:161 templates/base.html:116
#: apps/treasury/tables.py:117
msgid "Valid"
msgstr ""
#: apps/treasury/tables.py:124
msgid "Yes"
msgstr ""
#: apps/treasury/tables.py:124
msgid "No"
msgstr ""
#: apps/wei/apps.py:10 apps/wei/models.py:45 apps/wei/models.py:46
#: apps/wei/models.py:57 apps/wei/models.py:162 templates/base.html:116
msgid "WEI"
msgstr ""
#: apps/wei/forms/registration.py:47 apps/wei/models.py:108
#: apps/wei/models.py:269
#: apps/wei/forms/registration.py:47 apps/wei/models.py:109
#: apps/wei/models.py:270
msgid "bus"
msgstr ""
@ -1026,7 +1047,7 @@ msgid ""
msgstr ""
#: apps/wei/forms/registration.py:61 apps/wei/forms/registration.py:67
#: apps/wei/models.py:142
#: apps/wei/models.py:143
msgid "WEI Roles"
msgstr ""
@ -1042,155 +1063,156 @@ msgstr ""
msgid "Attribute to each first year member a bus for the WEI"
msgstr ""
#: apps/wei/models.py:19 templates/wei/weiclub_info.html:23
#: apps/wei/models.py:20 templates/wei/weiclub_info.html:23
msgid "year"
msgstr ""
#: apps/wei/models.py:23 templates/wei/weiclub_info.html:17
#: apps/wei/models.py:24 templates/wei/weiclub_info.html:17
msgid "date start"
msgstr ""
#: apps/wei/models.py:27 templates/wei/weiclub_info.html:20
#: apps/wei/models.py:28 templates/wei/weiclub_info.html:20
msgid "date end"
msgstr ""
#: apps/wei/models.py:72
#: apps/wei/models.py:73
msgid "survey information"
msgstr ""
#: apps/wei/models.py:73
#: apps/wei/models.py:74
msgid "Information about the survey for new members, encoded in JSON"
msgstr ""
#: apps/wei/models.py:95
#: apps/wei/models.py:96
msgid "Bus"
msgstr ""
#: apps/wei/models.py:96 templates/wei/weiclub_tables.html:79
#: apps/wei/models.py:97 templates/wei/weiclub_tables.html:79
msgid "Buses"
msgstr ""
#: apps/wei/models.py:116
#: apps/wei/models.py:117
msgid "color"
msgstr ""
#: apps/wei/models.py:117
#: apps/wei/models.py:118
msgid "The color of the T-Shirt, stored with its number equivalent"
msgstr ""
#: apps/wei/models.py:131
#: apps/wei/models.py:132
msgid "Bus team"
msgstr ""
#: apps/wei/models.py:132
#: apps/wei/models.py:133
msgid "Bus teams"
msgstr ""
#: apps/wei/models.py:141
#: apps/wei/models.py:142
msgid "WEI Role"
msgstr ""
#: apps/wei/models.py:166
#: apps/wei/models.py:167
msgid "Credit from Société générale"
msgstr ""
#: apps/wei/models.py:171
#: apps/wei/models.py:172
msgid "Caution check given"
msgstr ""
#: apps/wei/models.py:175 templates/wei/weimembership_form.html:56
#: apps/wei/models.py:176 templates/wei/weimembership_form.html:56
msgid "birth date"
msgstr ""
#: apps/wei/models.py:181
#: apps/wei/models.py:182
msgid "Male"
msgstr ""
#: apps/wei/models.py:182
#: apps/wei/models.py:183
msgid "Female"
msgstr ""
#: apps/wei/models.py:183
#: apps/wei/models.py:184
msgid "Non binary"
msgstr ""
#: apps/wei/models.py:185 templates/wei/weimembership_form.html:53
#: apps/wei/models.py:186 templates/wei/weimembership_form.html:53
msgid "gender"
msgstr ""
#: apps/wei/models.py:191 templates/wei/weimembership_form.html:59
#: apps/wei/models.py:192 templates/wei/weimembership_form.html:59
msgid "health issues"
msgstr ""
#: apps/wei/models.py:196 templates/wei/weimembership_form.html:62
#: apps/wei/models.py:197 templates/wei/weimembership_form.html:62
msgid "emergency contact name"
msgstr ""
#: apps/wei/models.py:201 templates/wei/weimembership_form.html:65
#: apps/wei/models.py:202 templates/wei/weimembership_form.html:65
msgid "emergency contact phone"
msgstr ""
#: apps/wei/models.py:206 templates/wei/weimembership_form.html:68
#: apps/wei/models.py:207 templates/wei/weimembership_form.html:68
msgid ""
"Register on the mailing list to stay informed of the events of the campus (1 "
"mail/week)"
msgstr ""
#: apps/wei/models.py:211 templates/wei/weimembership_form.html:71
#: apps/wei/models.py:212 templates/wei/weimembership_form.html:71
msgid ""
"Register on the mailing list to stay informed of the sport events of the "
"campus (1 mail/week)"
msgstr ""
#: apps/wei/models.py:216 templates/wei/weimembership_form.html:74
#: apps/wei/models.py:217 templates/wei/weimembership_form.html:74
msgid ""
"Register on the mailing list to stay informed of the art events of the "
"campus (1 mail/week)"
msgstr ""
#: apps/wei/models.py:221 templates/wei/weimembership_form.html:50
#: apps/wei/models.py:222 templates/wei/weimembership_form.html:50
msgid "first year"
msgstr ""
#: apps/wei/models.py:222
#: apps/wei/models.py:223
msgid "Tells if the user is new in the school."
msgstr ""
#: apps/wei/models.py:227
#: apps/wei/models.py:228
msgid "registration information"
msgstr ""
#: apps/wei/models.py:228
#: apps/wei/models.py:229
msgid ""
"Information about the registration (buses for old members, survey fot the "
"new members), encoded in JSON"
msgstr ""
#: apps/wei/models.py:259
#: apps/wei/models.py:260
msgid "WEI User"
msgstr ""
#: apps/wei/models.py:260
#: apps/wei/models.py:261
msgid "WEI Users"
msgstr ""
#: apps/wei/models.py:279
#: apps/wei/models.py:280
msgid "team"
msgstr ""
#: apps/wei/models.py:289
#: apps/wei/models.py:290
msgid "WEI registration"
msgstr ""
#: apps/wei/models.py:293
#: apps/wei/models.py:294
msgid "WEI membership"
msgstr ""
#: apps/wei/models.py:294
#: apps/wei/models.py:295
msgid "WEI memberships"
msgstr ""
#: apps/wei/tables.py:53 apps/wei/tables.py:54
#: templates/treasury/sogecredit_detail.html:44
msgid "Validate"
msgstr ""
@ -1233,7 +1255,7 @@ msgstr ""
msgid "This user didn't give her/his caution check."
msgstr ""
#: apps/wei/views.py:789 apps/wei/views.py:809 apps/wei/views.py:819
#: apps/wei/views.py:790 apps/wei/views.py:810 apps/wei/views.py:820
#: templates/wei/survey.html:12 templates/wei/survey_closed.html:12
#: templates/wei/survey_end.html:12
msgid "Survey WEI"
@ -1745,22 +1767,16 @@ msgid "Reset my password"
msgstr ""
#: templates/registration/signup.html:5 templates/registration/signup.html:8
#: templates/registration/signup.html:28
#: templates/registration/signup.html:19
msgid "Sign up"
msgstr ""
#: templates/registration/signup.html:11
msgid ""
"\n"
" If you already signed up, your registration is taken into "
"account. The BDE must validate your account before\n"
" your can log in. You have to go to the Kfet and pay the "
"registration fee. You must also validate your email\n"
" address by following the link you received. If you forgot to "
"register to the WEI, then you can pre-register\n"
" to the WEI after your account get validated, so please go to the "
"Kfet.\n"
" "
"If you already signed up, your registration is taken into account. The BDE "
"must validate your account before your can log in. You have to go to the "
"Kfet and pay the registration fee. You must also validate your email address "
"by following the link you received."
msgstr ""
#: templates/treasury/invoice_form.html:6
@ -1775,7 +1791,13 @@ msgstr ""
msgid "Remove product"
msgstr ""
#: templates/treasury/invoice_list.html:21
#: templates/treasury/invoice_list.html:16
#: templates/treasury/remittance_list.html:16
#: templates/treasury/sogecredit_list.html:16
msgid "Société générale credits"
msgstr ""
#: templates/treasury/invoice_list.html:24
msgid "New invoice"
msgstr ""
@ -1800,38 +1822,80 @@ msgstr ""
msgid "There is no transaction linked with this remittance."
msgstr ""
#: templates/treasury/remittance_list.html:19
#: templates/treasury/remittance_list.html:22
msgid "Opened remittances"
msgstr ""
#: templates/treasury/remittance_list.html:24
#: templates/treasury/remittance_list.html:27
msgid "There is no opened remittance."
msgstr ""
#: templates/treasury/remittance_list.html:28
#: templates/treasury/remittance_list.html:31
msgid "New remittance"
msgstr ""
#: templates/treasury/remittance_list.html:32
#: templates/treasury/remittance_list.html:35
msgid "Transfers without remittances"
msgstr ""
#: templates/treasury/remittance_list.html:37
#: templates/treasury/remittance_list.html:40
msgid "There is no transaction without any linked remittance."
msgstr ""
#: templates/treasury/remittance_list.html:43
#: templates/treasury/remittance_list.html:46
msgid "Transfers with opened remittances"
msgstr ""
#: templates/treasury/remittance_list.html:48
#: templates/treasury/remittance_list.html:51
msgid "There is no transaction with an opened linked remittance."
msgstr ""
#: templates/treasury/remittance_list.html:54
#: templates/treasury/remittance_list.html:57
msgid "Closed remittances"
msgstr ""
#: templates/treasury/sogecredit_detail.html:23
msgid "total amount"
msgstr ""
#: templates/treasury/sogecredit_detail.html:29
msgid ""
"Warning: Validating this credit implies that all membership transactions "
"will be validated."
msgstr ""
#: templates/treasury/sogecredit_detail.html:30
msgid ""
"If you delete this credit, there all membership transactions will be also "
"validated, but no credit will be operated."
msgstr ""
#: templates/treasury/sogecredit_detail.html:31
msgid ""
"If this credit is validated, then the user won't be able to ask for a credit "
"from the Société générale."
msgstr ""
#: templates/treasury/sogecredit_detail.html:32
msgid "If you think there is an error, please contact the \"respos info\"."
msgstr ""
#: templates/treasury/sogecredit_detail.html:38
msgid "This credit is already validated."
msgstr ""
#: templates/treasury/sogecredit_detail.html:49
msgid "Return to credit list"
msgstr ""
#: templates/treasury/sogecredit_list.html:26
msgid "Filter with unvalidated credits only"
msgstr ""
#: templates/treasury/sogecredit_list.html:36
msgid "There is no matched user that have asked for a Société générale credit."
msgstr ""
#: templates/wei/bus_tables.html:16 templates/wei/busteam_tables.html:16
msgid "Add team"
msgstr ""

View File

@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-21 17:47+0200\n"
"POT-Creation-Date: 2020-04-22 03:07+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -40,10 +40,10 @@ msgid "You can't invite more than 3 people to this activity."
msgstr "Vous ne pouvez pas inviter plus de 3 personnes à cette activité."
#: apps/activity/models.py:23 apps/activity/models.py:48
#: apps/member/models.py:99 apps/member/models.py:203
#: apps/note/models/notes.py:188 apps/note/models/transactions.py:24
#: apps/note/models/transactions.py:44 apps/note/models/transactions.py:237
#: apps/wei/models.py:61 templates/member/club_info.html:13
#: apps/member/models.py:100 apps/member/models.py:204
#: apps/note/models/notes.py:188 apps/note/models/transactions.py:25
#: apps/note/models/transactions.py:45 apps/note/models/transactions.py:250
#: apps/wei/models.py:62 templates/member/club_info.html:13
#: templates/member/profile_info.html:14
#: templates/registration/future_profile_detail.html:16
#: templates/wei/weiclub_info.html:13 templates/wei/weimembership_form.html:18
@ -66,20 +66,21 @@ msgstr "type d'activité"
msgid "activity types"
msgstr "types d'activité"
#: apps/activity/models.py:53 apps/note/models/transactions.py:74
#: apps/permission/models.py:103 apps/wei/models.py:67 apps/wei/models.py:123
#: apps/activity/models.py:53 apps/note/models/transactions.py:75
#: apps/permission/models.py:103 apps/wei/models.py:68 apps/wei/models.py:124
#: templates/activity/activity_detail.html:16
msgid "description"
msgstr "description"
#: apps/activity/models.py:60 apps/note/models/notes.py:164
#: apps/note/models/transactions.py:64
#: apps/note/models/transactions.py:65
#: templates/activity/activity_detail.html:19
msgid "type"
msgstr "type"
#: apps/activity/models.py:66 apps/logs/models.py:21 apps/member/models.py:224
#: apps/note/models/notes.py:117 apps/wei/models.py:154
#: apps/activity/models.py:66 apps/logs/models.py:21 apps/member/models.py:225
#: apps/note/models/notes.py:117 apps/treasury/models.py:220
#: apps/wei/models.py:155 templates/treasury/sogecredit_detail.html:13
#: templates/wei/survey.html:16
msgid "user"
msgstr "utilisateur"
@ -100,7 +101,7 @@ msgstr "date de début"
msgid "end date"
msgstr "date de fin"
#: apps/activity/models.py:93 apps/note/models/transactions.py:139
#: apps/activity/models.py:93 apps/note/models/transactions.py:140
#: templates/activity/activity_detail.html:47
msgid "valid"
msgstr "valide"
@ -176,7 +177,7 @@ msgstr "Entré le "
msgid "remove"
msgstr "supprimer"
#: apps/activity/tables.py:75 apps/treasury/models.py:138
#: apps/activity/tables.py:75 apps/treasury/models.py:139
msgid "Type"
msgstr "Type"
@ -342,67 +343,59 @@ msgstr "adresse email confirmée"
msgid "registration valid"
msgstr "inscription valid"
#: apps/member/models.py:68
msgid "Société générale"
msgstr "Société générale"
#: apps/member/models.py:69
msgid "Has the user ever be paid by the Société générale?"
msgstr "Est-ce que l'utilisateur a déjà été payé par la Société Générale ?"
#: apps/member/models.py:74 apps/member/models.py:75
#: apps/member/models.py:75 apps/member/models.py:76
msgid "user profile"
msgstr "profil utilisateur"
#: apps/member/models.py:104 templates/member/club_info.html:51
#: apps/member/models.py:105 templates/member/club_info.html:51
#: 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:111
#: apps/member/models.py:112
msgid "parent club"
msgstr "club parent"
#: apps/member/models.py:120
#: apps/member/models.py:121
msgid "require memberships"
msgstr "nécessite des adhésions"
#: apps/member/models.py:121
#: apps/member/models.py:122
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:126 templates/member/club_info.html:35
#: apps/member/models.py:127 templates/member/club_info.html:35
msgid "membership fee (paid students)"
msgstr "cotisation pour adhérer (normalien élève)"
#: apps/member/models.py:131 templates/member/club_info.html:38
#: apps/member/models.py:132 templates/member/club_info.html:38
msgid "membership fee (unpaid students)"
msgstr "cotisation pour adhérer (normalien étudiant)"
#: apps/member/models.py:137 templates/member/club_info.html:28
#: apps/member/models.py:138 templates/member/club_info.html:28
msgid "membership duration"
msgstr "durée de l'adhésion"
#: apps/member/models.py:138
#: apps/member/models.py:139
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:145 templates/member/club_info.html:22
#: apps/member/models.py:146 templates/member/club_info.html:22
msgid "membership start"
msgstr "début de l'adhésion"
#: apps/member/models.py:146
#: apps/member/models.py:147
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:153 templates/member/club_info.html:25
#: apps/member/models.py:154 templates/member/club_info.html:25
msgid "membership end"
msgstr "fin de l'adhésion"
#: apps/member/models.py:154
#: apps/member/models.py:155
msgid ""
"How long the membership can last after January 1st of the next year after "
"members can renew their membership."
@ -410,53 +403,53 @@ 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:188 apps/member/models.py:230
#: apps/member/models.py:189 apps/member/models.py:231
#: apps/note/models/notes.py:139
msgid "club"
msgstr "club"
#: apps/member/models.py:189
#: apps/member/models.py:190
msgid "clubs"
msgstr "clubs"
#: apps/member/models.py:209 apps/permission/models.py:294
#: apps/member/models.py:210 apps/permission/models.py:294
msgid "role"
msgstr "rôle"
#: apps/member/models.py:210 apps/member/models.py:235
#: apps/member/models.py:211 apps/member/models.py:236
msgid "roles"
msgstr "rôles"
#: apps/member/models.py:240
#: apps/member/models.py:241
msgid "membership starts on"
msgstr "l'adhésion commence le"
#: apps/member/models.py:244
#: apps/member/models.py:245
msgid "membership ends on"
msgstr "l'adhésion finit le"
#: apps/member/models.py:249
#: apps/member/models.py:250
msgid "fee"
msgstr "cotisation"
#: apps/member/models.py:267 apps/member/views.py:500 apps/wei/views.py:726
#: apps/member/models.py:268 apps/member/views.py:494 apps/wei/views.py:726
msgid "User is not a member of the parent club"
msgstr "L'utilisateur n'est pas membre du club parent"
#: apps/member/models.py:277 apps/member/views.py:509
#: apps/member/models.py:278 apps/member/views.py:503
msgid "User is already a member of the club"
msgstr "L'utilisateur est déjà membre du club"
#: apps/member/models.py:315
#: apps/member/models.py:329
#, python-brace-format
msgid "Membership of {user} for the club {club}"
msgstr "Adhésion de {user} pour le club {club}"
#: apps/member/models.py:318
#: apps/member/models.py:332
msgid "membership"
msgstr "adhésion"
#: apps/member/models.py:319
#: apps/member/models.py:333
msgid "memberships"
msgstr "adhésions"
@ -482,7 +475,7 @@ msgstr "Un alias avec un nom similaire existe déjà."
msgid "Search user"
msgstr "Chercher un utilisateur"
#: apps/member/views.py:495 apps/wei/views.py:717
#: apps/member/views.py:489 apps/wei/views.py:717
msgid ""
"This user don't have enough money to join this club, and can't have a "
"negative balance."
@ -490,26 +483,26 @@ 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:513
#: apps/member/views.py:507
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:518
#: apps/member/views.py:512
msgid "The membership must begin before {:%m-%d-%Y}."
msgstr "L'adhésion doit commencer avant le {:%d/%m/%Y}."
#: apps/member/views.py:528 apps/member/views.py:530 apps/member/views.py:532
#: apps/registration/views.py:327 apps/registration/views.py:329
#: apps/registration/views.py:331
#: apps/member/views.py:522 apps/member/views.py:524 apps/member/views.py:526
#: apps/registration/views.py:288 apps/registration/views.py:290
#: apps/registration/views.py:292
msgid "This field is required."
msgstr "Ce champ est requis."
#: apps/note/admin.py:120 apps/note/models/transactions.py:99
#: apps/note/admin.py:120 apps/note/models/transactions.py:100
msgid "source"
msgstr "source"
#: apps/note/admin.py:128 apps/note/admin.py:170
#: apps/note/models/transactions.py:54 apps/note/models/transactions.py:112
#: apps/note/models/transactions.py:55 apps/note/models/transactions.py:113
msgid "destination"
msgstr "destination"
@ -552,7 +545,7 @@ msgstr ""
msgid "display image"
msgstr "image affichée"
#: apps/note/models/notes.py:53 apps/note/models/transactions.py:122
#: apps/note/models/notes.py:53 apps/note/models/transactions.py:123
msgid "created at"
msgstr "créée le"
@ -623,97 +616,98 @@ msgstr "Un alias avec un nom similaire existe déjà : {}"
msgid "You can't delete your main alias."
msgstr "Vous ne pouvez pas supprimer votre alias principal."
#: apps/note/models/transactions.py:30
#: apps/note/models/transactions.py:31
msgid "transaction category"
msgstr "catégorie de transaction"
#: apps/note/models/transactions.py:31
#: apps/note/models/transactions.py:32
msgid "transaction categories"
msgstr "catégories de transaction"
#: apps/note/models/transactions.py:47
#: apps/note/models/transactions.py:48
msgid "A template with this name already exist"
msgstr "Un modèle de transaction avec un nom similaire existe déjà."
#: apps/note/models/transactions.py:58 apps/note/models/transactions.py:130
#: apps/note/models/transactions.py:59 apps/note/models/transactions.py:131
msgid "amount"
msgstr "montant"
#: apps/note/models/transactions.py:59
#: apps/note/models/transactions.py:60
msgid "in centimes"
msgstr "en centimes"
#: apps/note/models/transactions.py:70
#: apps/note/models/transactions.py:71
msgid "display"
msgstr "afficher"
#: apps/note/models/transactions.py:80
#: apps/note/models/transactions.py:81
msgid "transaction template"
msgstr "modèle de transaction"
#: apps/note/models/transactions.py:81
#: apps/note/models/transactions.py:82
msgid "transaction templates"
msgstr "modèles de transaction"
#: apps/note/models/transactions.py:105 apps/note/models/transactions.py:118
#: apps/note/models/transactions.py:106 apps/note/models/transactions.py:119
#: apps/note/tables.py:33 apps/note/tables.py:42
msgid "used alias"
msgstr "alias utilisé"
#: apps/note/models/transactions.py:126
#: apps/note/models/transactions.py:127
msgid "quantity"
msgstr "quantité"
#: apps/note/models/transactions.py:134
#: apps/note/models/transactions.py:135
msgid "reason"
msgstr "raison"
#: apps/note/models/transactions.py:144 apps/note/tables.py:95
#: apps/note/models/transactions.py:145 apps/note/tables.py:95
msgid "invalidity reason"
msgstr "Motif d'invalidité"
#: apps/note/models/transactions.py:152
#: apps/note/models/transactions.py:153
msgid "transaction"
msgstr "transaction"
#: apps/note/models/transactions.py:153
#: apps/note/models/transactions.py:154
#: templates/treasury/sogecredit_detail.html:16
msgid "transactions"
msgstr "transactions"
#: apps/note/models/transactions.py:207
#: apps/note/models/transactions.py:216
#: templates/activity/activity_entry.html:13 templates/base.html:84
#: templates/note/transaction_form.html:19
#: templates/note/transaction_form.html:145
msgid "Transfer"
msgstr "Virement"
#: apps/note/models/transactions.py:227
#: apps/note/models/transactions.py:240
msgid "Template"
msgstr "Bouton"
#: apps/note/models/transactions.py:242
#: apps/note/models/transactions.py:255
msgid "first_name"
msgstr "prénom"
#: apps/note/models/transactions.py:247
#: apps/note/models/transactions.py:260
msgid "bank"
msgstr "banque"
#: apps/note/models/transactions.py:253
#: apps/note/models/transactions.py:266
#: templates/activity/activity_entry.html:17
#: templates/note/transaction_form.html:24
msgid "Credit"
msgstr "Crédit"
#: apps/note/models/transactions.py:253 templates/note/transaction_form.html:28
#: apps/note/models/transactions.py:266 templates/note/transaction_form.html:28
msgid "Debit"
msgstr "Débit"
#: apps/note/models/transactions.py:269 apps/note/models/transactions.py:274
#: apps/note/models/transactions.py:282 apps/note/models/transactions.py:287
msgid "membership transaction"
msgstr "Transaction d'adhésion"
#: apps/note/models/transactions.py:270
#: apps/note/models/transactions.py:283 apps/treasury/models.py:226
msgid "membership transactions"
msgstr "Transactions d'adhésion"
@ -730,6 +724,7 @@ msgid "No reason specified"
msgstr "Pas de motif spécifié"
#: apps/note/tables.py:122 apps/note/tables.py:151 apps/wei/tables.py:66
#: templates/treasury/sogecredit_detail.html:45
#: templates/wei/weiregistration_confirm_delete.html:32
msgid "Delete"
msgstr "Supprimer"
@ -812,31 +807,31 @@ msgstr "Adhérer au club BDE"
msgid "Join Kfet Club"
msgstr "Adhérer au club Kfet"
#: apps/registration/views.py:116
#: apps/registration/views.py:77
msgid "Email validation"
msgstr "Validation de l'adresse mail"
#: apps/registration/views.py:162
#: apps/registration/views.py:123
msgid "Email validation unsuccessful"
msgstr " La validation de l'adresse mail a échoué"
#: apps/registration/views.py:173
#: apps/registration/views.py:134
msgid "Email validation email sent"
msgstr "L'email de vérification de l'adresse email a bien été envoyé."
#: apps/registration/views.py:226
#: apps/registration/views.py:187
msgid "Unregistered users"
msgstr "Utilisateurs en attente d'inscription"
#: apps/registration/views.py:293
#: apps/registration/views.py:254
msgid "You must join the BDE."
msgstr "Vous devez adhérer au BDE."
#: apps/registration/views.py:315
#: apps/registration/views.py:276
msgid "You must join BDE club before joining Kfet club."
msgstr "Vous devez adhérer au club BDE avant d'adhérer au club Kfet."
#: apps/registration/views.py:320
#: apps/registration/views.py:281
msgid ""
"The entered amount is not enough for the memberships, should be at least {}"
msgstr ""
@ -871,123 +866,137 @@ msgid "You can't change the type of the remittance."
msgstr "Vous ne pouvez pas changer le type de la remise."
#: apps/treasury/forms.py:127 apps/treasury/tables.py:47
#: templates/note/transaction_form.html:133
#: apps/treasury/tables.py:113 templates/note/transaction_form.html:133
#: templates/treasury/remittance_form.html:18
msgid "Amount"
msgstr "Montant"
#: apps/treasury/models.py:18
#: apps/treasury/models.py:19
msgid "Invoice identifier"
msgstr "Numéro de facture"
#: apps/treasury/models.py:32
#: apps/treasury/models.py:33
msgid "BDE"
msgstr "BDE"
#: apps/treasury/models.py:37
#: apps/treasury/models.py:38
msgid "Object"
msgstr "Objet"
#: apps/treasury/models.py:41
#: apps/treasury/models.py:42
msgid "Description"
msgstr "Description"
#: apps/treasury/models.py:46 templates/note/transaction_form.html:91
#: apps/treasury/models.py:47 templates/note/transaction_form.html:91
msgid "Name"
msgstr "Nom"
#: apps/treasury/models.py:50
#: apps/treasury/models.py:51
msgid "Address"
msgstr "Adresse"
#: apps/treasury/models.py:55
#: apps/treasury/models.py:56
msgid "Place"
msgstr "Lieu"
#: apps/treasury/models.py:59
#: apps/treasury/models.py:60
msgid "Acquitted"
msgstr "Acquittée"
#: apps/treasury/models.py:63
#: apps/treasury/models.py:64
msgid "invoice"
msgstr "facture"
#: apps/treasury/models.py:64
#: apps/treasury/models.py:65
msgid "invoices"
msgstr "factures"
#: apps/treasury/models.py:79
#: apps/treasury/models.py:80
msgid "Designation"
msgstr "Désignation"
#: apps/treasury/models.py:83
#: apps/treasury/models.py:84
msgid "Quantity"
msgstr "Quantité"
#: apps/treasury/models.py:87
#: apps/treasury/models.py:88
msgid "Unit price"
msgstr "Prix unitaire"
#: apps/treasury/models.py:103
#: apps/treasury/models.py:104
msgid "product"
msgstr "produit"
#: apps/treasury/models.py:104
#: apps/treasury/models.py:105
msgid "products"
msgstr "produits"
#: apps/treasury/models.py:121
#: apps/treasury/models.py:122
msgid "remittance type"
msgstr "type de remise"
#: apps/treasury/models.py:122
#: apps/treasury/models.py:123
msgid "remittance types"
msgstr "types de remises"
#: apps/treasury/models.py:132
#: apps/treasury/models.py:133
msgid "Date"
msgstr "Date"
#: apps/treasury/models.py:143
#: apps/treasury/models.py:144
msgid "Comment"
msgstr "Commentaire"
#: apps/treasury/models.py:148
#: apps/treasury/models.py:149
msgid "Closed"
msgstr "Fermée"
#: apps/treasury/models.py:152
#: apps/treasury/models.py:153
msgid "remittance"
msgstr "remise"
#: apps/treasury/models.py:153
#: apps/treasury/models.py:154
msgid "remittances"
msgstr "remises"
#: apps/treasury/models.py:185
#: apps/treasury/models.py:186
msgid "Remittance #{:d}: {}"
msgstr "Remise n°{:d} : {}"
#: apps/treasury/models.py:204 apps/treasury/tables.py:76
#: apps/treasury/models.py:205 apps/treasury/tables.py:76
#: apps/treasury/tables.py:84 templates/treasury/invoice_list.html:13
#: templates/treasury/remittance_list.html:13
#: templates/treasury/sogecredit_list.html:13
msgid "Remittance"
msgstr "Remise"
#: apps/treasury/models.py:208
#: apps/treasury/models.py:209
msgid "special transaction proxy"
msgstr "Proxy de transaction spéciale"
#: apps/treasury/models.py:209
#: apps/treasury/models.py:210
msgid "special transaction proxies"
msgstr "Proxys de transactions spéciales"
#: apps/treasury/models.py:232
msgid "credit transaction"
msgstr "transaction de crédit"
#: apps/treasury/models.py:294 templates/treasury/sogecredit_detail.html:9
msgid "Credit from the Société générale"
msgstr "Crédit de la Société générale"
#: apps/treasury/models.py:295
msgid "Credits from the Société générale"
msgstr "Crédits de la Société générale"
#: apps/treasury/tables.py:19
msgid "Invoice #{:d}"
msgstr "Facture n°{:d}"
#: apps/treasury/tables.py:22 templates/treasury/invoice_list.html:10
#: templates/treasury/remittance_list.html:10
#: templates/treasury/sogecredit_list.html:10
msgid "Invoice"
msgstr "Facture"
@ -1007,13 +1016,25 @@ msgstr "Ajouter"
msgid "Remove"
msgstr "supprimer"
#: apps/wei/apps.py:10 apps/wei/models.py:44 apps/wei/models.py:45
#: apps/wei/models.py:56 apps/wei/models.py:161 templates/base.html:116
#: apps/treasury/tables.py:117
msgid "Valid"
msgstr "Valide"
#: apps/treasury/tables.py:124
msgid "Yes"
msgstr "Oui"
#: apps/treasury/tables.py:124
msgid "No"
msgstr "Non"
#: apps/wei/apps.py:10 apps/wei/models.py:45 apps/wei/models.py:46
#: apps/wei/models.py:57 apps/wei/models.py:162 templates/base.html:116
msgid "WEI"
msgstr "WEI"
#: apps/wei/forms/registration.py:47 apps/wei/models.py:108
#: apps/wei/models.py:269
#: apps/wei/forms/registration.py:47 apps/wei/models.py:109
#: apps/wei/models.py:270
msgid "bus"
msgstr "Bus"
@ -1039,7 +1060,7 @@ msgstr ""
"bus ou électron libre)"
#: apps/wei/forms/registration.py:61 apps/wei/forms/registration.py:67
#: apps/wei/models.py:142
#: apps/wei/models.py:143
msgid "WEI Roles"
msgstr "Rôles au WEI"
@ -1055,97 +1076,97 @@ msgstr "Cette équipe n'appartient pas à ce bus."
msgid "Attribute to each first year member a bus for the WEI"
msgstr "Attribuer à chaque première année un bus pour le WEI"
#: apps/wei/models.py:19 templates/wei/weiclub_info.html:23
#: apps/wei/models.py:20 templates/wei/weiclub_info.html:23
msgid "year"
msgstr "année"
#: apps/wei/models.py:23 templates/wei/weiclub_info.html:17
#: apps/wei/models.py:24 templates/wei/weiclub_info.html:17
msgid "date start"
msgstr "début"
#: apps/wei/models.py:27 templates/wei/weiclub_info.html:20
#: apps/wei/models.py:28 templates/wei/weiclub_info.html:20
msgid "date end"
msgstr "fin"
#: apps/wei/models.py:72
#: apps/wei/models.py:73
msgid "survey information"
msgstr "informations sur le questionnaire"
#: apps/wei/models.py:73
#: apps/wei/models.py:74
msgid "Information about the survey for new members, encoded in JSON"
msgstr ""
"Informations sur le sondage pour les nouveaux membres, encodées en JSON"
#: apps/wei/models.py:95
#: apps/wei/models.py:96
msgid "Bus"
msgstr "Bus"
#: apps/wei/models.py:96 templates/wei/weiclub_tables.html:79
#: apps/wei/models.py:97 templates/wei/weiclub_tables.html:79
msgid "Buses"
msgstr "Bus"
#: apps/wei/models.py:116
#: apps/wei/models.py:117
msgid "color"
msgstr "couleur"
#: apps/wei/models.py:117
#: apps/wei/models.py:118
msgid "The color of the T-Shirt, stored with its number equivalent"
msgstr ""
"La couleur du T-Shirt, stocké sous la forme de son équivalent numérique"
#: apps/wei/models.py:131
#: apps/wei/models.py:132
msgid "Bus team"
msgstr "Équipe de bus"
#: apps/wei/models.py:132
#: apps/wei/models.py:133
msgid "Bus teams"
msgstr "Équipes de bus"
#: apps/wei/models.py:141
#: apps/wei/models.py:142
msgid "WEI Role"
msgstr "Rôle au WEI"
#: apps/wei/models.py:166
#: apps/wei/models.py:167
msgid "Credit from Société générale"
msgstr "Crédit de la Société générale"
#: apps/wei/models.py:171
#: apps/wei/models.py:172
msgid "Caution check given"
msgstr "Chèque de caution donné"
#: apps/wei/models.py:175 templates/wei/weimembership_form.html:56
#: apps/wei/models.py:176 templates/wei/weimembership_form.html:56
msgid "birth date"
msgstr "date de naissance"
#: apps/wei/models.py:181
#: apps/wei/models.py:182
msgid "Male"
msgstr "Homme"
#: apps/wei/models.py:182
#: apps/wei/models.py:183
msgid "Female"
msgstr "Femme"
#: apps/wei/models.py:183
#: apps/wei/models.py:184
msgid "Non binary"
msgstr "Non-binaire"
#: apps/wei/models.py:185 templates/wei/weimembership_form.html:53
#: apps/wei/models.py:186 templates/wei/weimembership_form.html:53
msgid "gender"
msgstr "genre"
#: apps/wei/models.py:191 templates/wei/weimembership_form.html:59
#: apps/wei/models.py:192 templates/wei/weimembership_form.html:59
msgid "health issues"
msgstr "problèmes de santé"
#: apps/wei/models.py:196 templates/wei/weimembership_form.html:62
#: apps/wei/models.py:197 templates/wei/weimembership_form.html:62
msgid "emergency contact name"
msgstr "Nom du contact en cas d'urgence"
#: apps/wei/models.py:201 templates/wei/weimembership_form.html:65
#: apps/wei/models.py:202 templates/wei/weimembership_form.html:65
msgid "emergency contact phone"
msgstr "Téléphone du contact en cas d'urgence"
#: apps/wei/models.py:206 templates/wei/weimembership_form.html:68
#: apps/wei/models.py:207 templates/wei/weimembership_form.html:68
msgid ""
"Register on the mailing list to stay informed of the events of the campus (1 "
"mail/week)"
@ -1153,7 +1174,7 @@ msgstr ""
"S'inscrire sur la liste de diffusion pour rester informé des événements sur "
"le campus (1 mail par semaine)"
#: apps/wei/models.py:211 templates/wei/weimembership_form.html:71
#: apps/wei/models.py:212 templates/wei/weimembership_form.html:71
msgid ""
"Register on the mailing list to stay informed of the sport events of the "
"campus (1 mail/week)"
@ -1161,7 +1182,7 @@ msgstr ""
"S'inscrire sur la liste de diffusion pour rester informé des actualités "
"sportives sur le campus (1 mail par semaine)"
#: apps/wei/models.py:216 templates/wei/weimembership_form.html:74
#: apps/wei/models.py:217 templates/wei/weimembership_form.html:74
msgid ""
"Register on the mailing list to stay informed of the art events of the "
"campus (1 mail/week)"
@ -1169,19 +1190,19 @@ msgstr ""
"S'inscrire sur la liste de diffusion pour rester informé des actualités "
"artistiques sur le campus (1 mail par semaine)"
#: apps/wei/models.py:221 templates/wei/weimembership_form.html:50
#: apps/wei/models.py:222 templates/wei/weimembership_form.html:50
msgid "first year"
msgstr "première année"
#: apps/wei/models.py:222
#: apps/wei/models.py:223
msgid "Tells if the user is new in the school."
msgstr "Indique si l'utilisateur est nouveau dans l'école."
#: apps/wei/models.py:227
#: apps/wei/models.py:228
msgid "registration information"
msgstr "informations sur l'inscription"
#: apps/wei/models.py:228
#: apps/wei/models.py:229
msgid ""
"Information about the registration (buses for old members, survey fot the "
"new members), encoded in JSON"
@ -1189,31 +1210,32 @@ msgstr ""
"Informations sur l'inscription (bus pour les 2A+, questionnaire pour les "
"1A), encodées en JSON"
#: apps/wei/models.py:259
#: apps/wei/models.py:260
msgid "WEI User"
msgstr "Participant au WEI"
#: apps/wei/models.py:260
#: apps/wei/models.py:261
msgid "WEI Users"
msgstr "Participants au WEI"
#: apps/wei/models.py:279
#: apps/wei/models.py:280
msgid "team"
msgstr "équipe"
#: apps/wei/models.py:289
#: apps/wei/models.py:290
msgid "WEI registration"
msgstr "inscription au WEI"
#: apps/wei/models.py:293
#: apps/wei/models.py:294
msgid "WEI membership"
msgstr "adhésion au WEI"
#: apps/wei/models.py:294
#: apps/wei/models.py:295
msgid "WEI memberships"
msgstr "adhésions au WEI"
#: apps/wei/tables.py:53 apps/wei/tables.py:54
#: templates/treasury/sogecredit_detail.html:44
msgid "Validate"
msgstr "Valider"
@ -1258,7 +1280,7 @@ msgstr "Vous avez déjà ouvert un compte auprès de la société générale."
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:789 apps/wei/views.py:809 apps/wei/views.py:819
#: apps/wei/views.py:790 apps/wei/views.py:810 apps/wei/views.py:820
#: templates/wei/survey.html:12 templates/wei/survey_closed.html:12
#: templates/wei/survey_end.html:12
msgid "Survey WEI"
@ -1784,34 +1806,22 @@ msgid "Reset my password"
msgstr ""
#: templates/registration/signup.html:5 templates/registration/signup.html:8
#: templates/registration/signup.html:28
#: templates/registration/signup.html:19
msgid "Sign up"
msgstr "Inscription"
#: templates/registration/signup.html:11
msgid ""
"\n"
" If you already signed up, your registration is taken into "
"account. The BDE must validate your account before\n"
" your can log in. You have to go to the Kfet and pay the "
"registration fee. You must also validate your email\n"
" address by following the link you received. If you forgot to "
"register to the WEI, then you can pre-register\n"
" to the WEI after your account get validated, so please go to the "
"Kfet.\n"
" "
"If you already signed up, your registration is taken into account. The BDE "
"must validate your account before your can log in. You have to go to the "
"Kfet and pay the registration fee. You must also validate your email address "
"by following the link you received."
msgstr ""
"\n"
" Si vous vous êtes déjà inscrits, votre inscription a bien été "
"prise en compte. Le BDE doit d'abord valider votre compte avant\n"
" que vous puissiez vous connecter. Vous devez vous rendre à la "
"Kfet et payer les frais d'adhésion. Vous devez également valider votre "
"adresse\n"
" email en suivant le lien que vous avez reçu. Si vous aviez "
"oublié de vous inscrire au WEI, vous pourrez vous pré-inscrire à nouveau\n"
" après avoir validé votre compte, merci alors de vous rendre à la "
"Kfet.\n"
" "
"Si vous vous êtes déjà inscrits, votre inscription a bien été prise en "
"compte. Le BDE doit d'abord valider votre compte avantque vous puissiez vous "
"connecter. Vous devez vous rendre à la Kfet et payer les frais d'adhésion. "
"Vous devez également valider votre adresse email en suivant le lien que vous "
"avez reçu."
#: templates/treasury/invoice_form.html:6
msgid "Invoices list"
@ -1825,7 +1835,13 @@ msgstr "Ajouter produit"
msgid "Remove product"
msgstr "Retirer produit"
#: templates/treasury/invoice_list.html:21
#: templates/treasury/invoice_list.html:16
#: templates/treasury/remittance_list.html:16
#: templates/treasury/sogecredit_list.html:16
msgid "Société générale credits"
msgstr "Crédits de la Société générale"
#: templates/treasury/invoice_list.html:24
msgid "New invoice"
msgstr "Nouvelle facture"
@ -1850,38 +1866,89 @@ msgstr "Transactions liées"
msgid "There is no transaction linked with this remittance."
msgstr "Il n'y a pas de transaction liée à cette remise."
#: templates/treasury/remittance_list.html:19
#: templates/treasury/remittance_list.html:22
msgid "Opened remittances"
msgstr "Remises ouvertes"
#: templates/treasury/remittance_list.html:24
#: templates/treasury/remittance_list.html:27
msgid "There is no opened remittance."
msgstr "Il n'y a pas de remise ouverte."
#: templates/treasury/remittance_list.html:28
#: templates/treasury/remittance_list.html:31
msgid "New remittance"
msgstr "Nouvelle remise"
#: templates/treasury/remittance_list.html:32
#: templates/treasury/remittance_list.html:35
msgid "Transfers without remittances"
msgstr "Transactions sans remise associée"
#: templates/treasury/remittance_list.html:37
#: templates/treasury/remittance_list.html:40
msgid "There is no transaction without any linked remittance."
msgstr "Il n'y a pas de transactions sans remise associée."
#: templates/treasury/remittance_list.html:43
#: templates/treasury/remittance_list.html:46
msgid "Transfers with opened remittances"
msgstr "Transactions associées à une remise ouverte"
#: templates/treasury/remittance_list.html:48
#: templates/treasury/remittance_list.html:51
msgid "There is no transaction with an opened linked remittance."
msgstr "Il n'y a pas de transaction associée à une remise ouverte."
#: templates/treasury/remittance_list.html:54
#: templates/treasury/remittance_list.html:57
msgid "Closed remittances"
msgstr "Remises fermées"
#: templates/treasury/sogecredit_detail.html:23
msgid "total amount"
msgstr "montant total"
#: templates/treasury/sogecredit_detail.html:29
msgid ""
"Warning: Validating this credit implies that all membership transactions "
"will be validated."
msgstr ""
"Attention : Valider ce crédit implique que les transactions d'adhésion "
"seront validées."
#: templates/treasury/sogecredit_detail.html:30
msgid ""
"If you delete this credit, there all membership transactions will be also "
"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 "
"crédit créée."
#: templates/treasury/sogecredit_detail.html:31
msgid ""
"If this credit is validated, then the user won't be able to ask for a credit "
"from the Société générale."
msgstr ""
"Si ce crédit est validé, alors l'utilisateur ne pourra plus demander d'être "
"crédité par la Société générale à l'avenir."
#: templates/treasury/sogecredit_detail.html:32
msgid "If you think there is an error, please contact the \"respos info\"."
msgstr "Si vous pensez qu'il y a une erreur, merci de contacter un respo info."
#: templates/treasury/sogecredit_detail.html:38
msgid "This credit is already validated."
msgstr "Ce crédit a déjà été validé."
#: templates/treasury/sogecredit_detail.html:49
msgid "Return to credit list"
msgstr "Retour à la liste des crédits"
#: templates/treasury/sogecredit_list.html:26
msgid "Filter with unvalidated credits only"
msgstr "Filtrer avec uniquement les crédits non valides"
#: templates/treasury/sogecredit_list.html:36
msgid "There is no matched user that have asked for a Société générale credit."
msgstr ""
"Il n'y a pas d'utilisateur trouvé ayant demandé un crédit de la Société "
"générale."
#: templates/wei/bus_tables.html:16 templates/wei/busteam_tables.html:16
msgid "Add team"
msgstr "Ajouter une équipe"

View File

@ -19,14 +19,20 @@
{% endif %}
{% if club.require_memberships %}
{% if club.membership_start %}
<dt class="col-xl-6">{% trans 'membership start'|capfirst %}</dt>
<dd class="col-xl-6">{{ club.membership_start }}</dd>
{% endif %}
{% if club.membership_end %}
<dt class="col-xl-6">{% trans 'membership end'|capfirst %}</dt>
<dd class="col-xl-6">{{ club.membership_end }}</dd>
{% endif %}
{% if club.membership_duration %}
<dt class="col-xl-6">{% trans 'membership duration'|capfirst %}</dt>
<dd class="col-xl-6">{{ club.membership_duration }} {% trans "days" %}</dd>
{% endif %}
{% if club.membership_fee_paid == club.membership_fee_unpaid %}
<dt class="col-xl-6">{% trans 'membership fee'|capfirst %}</dt>
@ -52,6 +58,7 @@
<dd class="col-xl-8"><a href="mailto:{{ club.email }}">{{ club.email }}</a></dd>
</dl>
</div>
{% if not club.weiclub %}
<div class="card-footer text-center">
{% if can_add_members %}
<a class="btn btn-primary btn-sm my-1" href="{% url 'member:club_add_member' club_pk=club.pk %}"> {% trans "Add member" %}</a>
@ -62,5 +69,7 @@
{% url 'member:club_detail' club.pk as club_detail_url %}
{%if request.path_info != club_detail_url %}
<a class="btn btn-primary btn-sm my-1" href="{{ club_detail_url }}">{% trans 'View Profile' %}</a>
{% endif %} </div>
{% endif %}
</div>
{% endif %}
</div>

View File

@ -8,44 +8,15 @@
<h2>{% trans "Sign up" %}</h2>
<div class="alert alert-warning">
{% blocktrans %}
If you already signed up, your registration is taken into account. The BDE must validate your account before
your can log in. You have to go to the Kfet and pay the registration fee. You must also validate your email
address by following the link you received. If you forgot to register to the WEI, then you can pre-register
to the WEI after your account get validated, so please go to the Kfet.
{% endblocktrans %}
{% blocktrans %}If you already signed up, your registration is taken into account. The BDE must validate your account before your can log in. You have to go to the Kfet and pay the registration fee. You must also validate your email address by following the link you received.{% endblocktrans %}
</div>
<form method="post">
{% csrf_token %}
{{ form|crispy }}
{{ profile_form|crispy }}
{{ wei_registration_form|crispy }}
<div id="wei_form_div" class="d-none">
{{ wei_form|crispy }}
</div>
<button class="btn btn-success" type="submit">
{% trans "Sign up" %}
</button>
</form>
{% endblock %}
{% block extrajavascript %}
<script>
$("#id_wei_registration").change(function () {
if ($(this).is(":checked")) {
$("#wei_form_div").removeClass('d-none');
$("#wei_form_div .form-control").removeAttr('disabled');
}
else {
$("#wei_form_div").addClass('d-none');
$("#wei_form_div .form-control").attr('disabled', true);
}
});
if ($("#id_wei_registration").is(":checked")) {
$("#wei_form_div").removeClass('d-none');
$("#wei_form_div .form-control").removeAttr('disabled');
}
</script>
{% endblock %}

View File

@ -12,6 +12,9 @@
<a href="{% url "treasury:remittance_list" %}" class="btn btn-sm btn-outline-primary">
{% trans "Remittance" %}s
</a>
<a href="{% url "treasury:soge_credits" %}" class="btn btn-sm btn-outline-primary">
{% trans "Société générale credits" %}
</a>
</div>
</div>
</div>

View File

@ -12,6 +12,9 @@
<a href="#" class="btn btn-sm btn-outline-primary active">
{% trans "Remittance" %}s
</a>
<a href="{% url "treasury:soge_credits" %}" class="btn btn-sm btn-outline-primary">
{% trans "Société générale credits" %}
</a>
</div>
</div>
</div>

View File

@ -0,0 +1,52 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% load pretty_money %}
{% block content %}
<div class="card bg-light shadow">
<div class="card-header text-center">
<h4>{% trans "Credit from the Société générale" %}</h4>
</div>
<div class="card-body">
<dl class="row">
<dt class="col-xl-6 text-right">{% trans 'user'|capfirst %}</dt>
<dd class="col-xl-6"><a href="{% url 'member:user_detail' pk=object.user.pk %}">{{ object.user }}</a></dd>
<dt class="col-xl-6 text-right">{% trans 'transactions'|capfirst %}</dt>
<dd class="col-xl-6">
{% for transaction in object.transactions.all %}
{{ transaction.membership.club }} ({{ transaction.amount|pretty_money }})<br>
{% endfor %}
</dd>
<dt class="col-xl-6 text-right">{% trans 'total amount'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.amount|pretty_money }}</dd>
</dl>
</div>
<div class="alert alert-warning">
{% trans 'Warning: Validating this credit implies that all membership transactions will be validated.' %}
{% trans 'If you delete this credit, there all membership transactions will be also validated, but no credit will be operated.' %}
{% trans "If this credit is validated, then the user won't be able to ask for a credit from the Société générale." %}
{% trans 'If you think there is an error, please contact the "respos info".' %}
</div>
<div class="card-footer text-center" id="buttons_footer">
{% if object.valid %}
<div class="alert alert-danger">
{% trans "This credit is already validated." %}
</div>
{% else %}
<form method="post">
{% csrf_token %}
<div class="btn-group btn-block">
<button name="validate" class="btn btn-success">{% trans "Validate" %}</button>
<button name="delete" class="btn btn-danger">{% trans "Delete" %}</button>
</div>
</form>
{% endif %}
<a href="{% url 'treasury:soge_credits' %}"><button class="btn btn-primary btn-block">{% trans "Return to credit list" %}</button></a>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,66 @@
{% extends "base.html" %}
{% load render_table from django_tables2 %}
{% load i18n %}
{% block content %}
<div class="row">
<div class="col-xl-12">
<div class="btn-group btn-group-toggle" style="width: 100%; padding: 0 0 2em 0" data-toggle="buttons">
<a href="{% url "treasury:invoice_list" %}" class="btn btn-sm btn-outline-primary">
{% trans "Invoice" %}s
</a>
<a href="{% url "treasury:remittance_list" %}" class="btn btn-sm btn-outline-primary">
{% trans "Remittance" %}s
</a>
<a href="#" class="btn btn-sm btn-outline-primary active">
{% trans "Société générale credits" %}
</a>
</div>
</div>
</div>
<input id="searchbar" type="text" class="form-control" placeholder="Nom/prénom/note ...">
<div class="form-check">
<label for="invalid_only" class="form-check-label">
<input id="invalid_only" name="invalid_only" type="checkbox" class="checkboxinput form-check-input">
{% trans "Filter with unvalidated credits only" %}
</label>
</div>
<hr>
<div id="credits_table">
{% if table.data %}
{% render_table table %}
{% else %}
<div class="alert alert-warning">
{% trans "There is no matched user that have asked for a Société générale credit." %}
</div>
{% endif %}
</div>
{% endblock %}
{% block extrajavascript %}
<script type="text/javascript">
$(document).ready(function() {
let old_pattern = null;
let searchbar_obj = $("#searchbar");
let invalid_only_obj = $("#invalid_only");
function reloadTable() {
let pattern = searchbar_obj.val();
if (pattern === old_pattern || pattern === "")
return;
$("#credits_table").load(location.pathname + "?search=" + pattern.replace(" ", "%20") + (invalid_only_obj.is(':checked') ? "&valid=false" : "") + " #credits_table");
$(".table-row").click(function() {
window.document.location = $(this).data("href");
});
}
searchbar_obj.keyup(reloadTable);
invalid_only_obj.change(reloadTable);
});
</script>
{% endblock %}