mirror of https://gitlab.crans.org/bde/nk20
Merge branch 'beta' into 'master'
Corrections de bugs See merge request bde/nk20!177
This commit is contained in:
commit
5828a20383
|
@ -2,10 +2,12 @@
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.hashers import PBKDF2PasswordHasher
|
from django.contrib.auth.hashers import PBKDF2PasswordHasher, mask_hash
|
||||||
from django.utils.crypto import constant_time_compare
|
from django.utils.crypto import constant_time_compare
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
from note_kfet.middlewares import get_current_request
|
from note_kfet.middlewares import get_current_request
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,6 +49,18 @@ class CustomNK15Hasher(PBKDF2PasswordHasher):
|
||||||
return constant_time_compare(hashlib.sha256((salt + password).encode("utf-8")).hexdigest(), db_hashed_pass)
|
return constant_time_compare(hashlib.sha256((salt + password).encode("utf-8")).hexdigest(), db_hashed_pass)
|
||||||
return super().verify(password, encoded)
|
return super().verify(password, encoded)
|
||||||
|
|
||||||
|
def safe_summary(self, encoded):
|
||||||
|
# Displayed information in Django Admin.
|
||||||
|
if '|' in encoded:
|
||||||
|
salt, db_hashed_pass = encoded.split('$')[2].split('|')
|
||||||
|
return OrderedDict([
|
||||||
|
(_('algorithm'), 'custom_nk15'),
|
||||||
|
(_('iterations'), '1'),
|
||||||
|
(_('salt'), mask_hash(salt)),
|
||||||
|
(_('hash'), mask_hash(db_hashed_pass)),
|
||||||
|
])
|
||||||
|
return super().safe_summary(encoded)
|
||||||
|
|
||||||
|
|
||||||
class DebugSuperuserBackdoor(PBKDF2PasswordHasher):
|
class DebugSuperuserBackdoor(PBKDF2PasswordHasher):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -57,7 +57,7 @@ class Profile(models.Model):
|
||||||
('A1', _("Mathematics (A1)")),
|
('A1', _("Mathematics (A1)")),
|
||||||
('A2', _("Physics (A2)")),
|
('A2', _("Physics (A2)")),
|
||||||
("A'2", _("Applied physics (A'2)")),
|
("A'2", _("Applied physics (A'2)")),
|
||||||
('A''2', _("Chemistry (A''2)")),
|
("A''2", _("Chemistry (A''2)")),
|
||||||
('A3', _("Biology (A3)")),
|
('A3', _("Biology (A3)")),
|
||||||
('B1234', _("SAPHIRE (B1234)")),
|
('B1234', _("SAPHIRE (B1234)")),
|
||||||
('B1', _("Mechanics (B1)")),
|
('B1', _("Mechanics (B1)")),
|
||||||
|
|
|
@ -39,13 +39,13 @@
|
||||||
<dt class="col-xl-6">{% trans 'address'|capfirst %}</dt>
|
<dt class="col-xl-6">{% trans 'address'|capfirst %}</dt>
|
||||||
<dd class="col-xl-6">{{ user_object.profile.address }}</dd>
|
<dd class="col-xl-6">{{ user_object.profile.address }}</dd>
|
||||||
|
|
||||||
{% if user_object.note and "note.view_note"|has_perm:user_object.note %}
|
|
||||||
<dt class="col-xl-6">{% trans 'balance'|capfirst %}</dt>
|
|
||||||
<dd class="col-xl-6">{{ user_object.note.balance | pretty_money }}</dd>
|
|
||||||
|
|
||||||
<dt class="col-xl-6">{% trans 'paid'|capfirst %}</dt>
|
<dt class="col-xl-6">{% trans 'paid'|capfirst %}</dt>
|
||||||
<dd class="col-xl-6">{{ user_object.profile.paid|yesno }}</dd>
|
<dd class="col-xl-6">{{ user_object.profile.paid|yesno }}</dd>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if user_object.note and "note.view_note"|has_perm:user_object.note %}
|
||||||
|
<dt class="col-xl-6">{% trans 'balance'|capfirst %}</dt>
|
||||||
|
<dd class="col-xl-6">{{ user_object.note.balance | pretty_money }}</dd>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
|
# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
import re
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
@ -133,23 +134,31 @@ class ConsumerViewSet(ReadOnlyProtectedModelViewSet):
|
||||||
if settings.DATABASES[queryset.db]["ENGINE"] == 'django.db.backends.postgresql' else queryset
|
if settings.DATABASES[queryset.db]["ENGINE"] == 'django.db.backends.postgresql' else queryset
|
||||||
|
|
||||||
alias = self.request.query_params.get("alias", None)
|
alias = self.request.query_params.get("alias", None)
|
||||||
|
# Check if this is a valid regex. If not, we won't check regex
|
||||||
|
try:
|
||||||
|
re.compile(alias)
|
||||||
|
valid_regex = True
|
||||||
|
except (re.error, TypeError):
|
||||||
|
valid_regex = False
|
||||||
|
suffix = '__iregex' if valid_regex else '__istartswith'
|
||||||
|
alias_prefix = '^' if valid_regex else ''
|
||||||
queryset = queryset.prefetch_related('note')
|
queryset = queryset.prefetch_related('note')
|
||||||
|
|
||||||
if alias:
|
if alias:
|
||||||
# We match first an alias if it is matched without normalization,
|
# We match first an alias if it is matched without normalization,
|
||||||
# then if the normalized pattern matches a normalized alias.
|
# then if the normalized pattern matches a normalized alias.
|
||||||
queryset = queryset.filter(
|
queryset = queryset.filter(
|
||||||
name__iregex="^" + alias
|
**{f'name{suffix}': alias_prefix + alias}
|
||||||
).union(
|
).union(
|
||||||
queryset.filter(
|
queryset.filter(
|
||||||
Q(normalized_name__iregex="^" + Alias.normalize(alias))
|
Q(**{f'normalized_name{suffix}': alias_prefix + Alias.normalize(alias)})
|
||||||
& ~Q(name__iregex="^" + alias)
|
& ~Q(**{f'name{suffix}': alias_prefix + alias})
|
||||||
),
|
),
|
||||||
all=True).union(
|
all=True).union(
|
||||||
queryset.filter(
|
queryset.filter(
|
||||||
Q(normalized_name__iregex="^" + alias.lower())
|
Q(**{f'normalized_name{suffix}': alias_prefix + alias.lower()})
|
||||||
& ~Q(normalized_name__iregex="^" + Alias.normalize(alias))
|
& ~Q(**{f'normalized_name{suffix}': alias_prefix + Alias.normalize(alias)})
|
||||||
& ~Q(name__iregex="^" + alias)
|
& ~Q(**{f'name{suffix}': alias_prefix + alias})
|
||||||
),
|
),
|
||||||
all=True)
|
all=True)
|
||||||
|
|
||||||
|
|
|
@ -159,6 +159,10 @@ class PermissionBackend(ModelBackend):
|
||||||
primary key, the result is not memoized. Moreover, the right could change
|
primary key, the result is not memoized. Moreover, the right could change
|
||||||
(e.g. for a transaction, the balance of the user could change)
|
(e.g. for a transaction, the balance of the user could change)
|
||||||
"""
|
"""
|
||||||
|
# Requested by a shell
|
||||||
|
if request is None:
|
||||||
|
return False
|
||||||
|
|
||||||
user_obj = request.user
|
user_obj = request.user
|
||||||
sess = request.session
|
sess = request.session
|
||||||
|
|
||||||
|
|
|
@ -627,7 +627,7 @@
|
||||||
"type": "view",
|
"type": "view",
|
||||||
"mask": 1,
|
"mask": 1,
|
||||||
"field": "",
|
"field": "",
|
||||||
"permanent": false,
|
"permanent": true,
|
||||||
"description": "Voir les personnes qu'on a invitées"
|
"description": "Voir les personnes qu'on a invitées"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2883,6 +2883,7 @@
|
||||||
3,
|
3,
|
||||||
4,
|
4,
|
||||||
5,
|
5,
|
||||||
|
6,
|
||||||
7,
|
7,
|
||||||
8,
|
8,
|
||||||
9,
|
9,
|
||||||
|
@ -2890,6 +2891,10 @@
|
||||||
11,
|
11,
|
||||||
12,
|
12,
|
||||||
13,
|
13,
|
||||||
|
14,
|
||||||
|
15,
|
||||||
|
16,
|
||||||
|
17,
|
||||||
22,
|
22,
|
||||||
48,
|
48,
|
||||||
52,
|
52,
|
||||||
|
@ -2907,11 +2912,6 @@
|
||||||
"for_club": 2,
|
"for_club": 2,
|
||||||
"name": "Adh\u00e9rent Kfet",
|
"name": "Adh\u00e9rent Kfet",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
6,
|
|
||||||
14,
|
|
||||||
15,
|
|
||||||
16,
|
|
||||||
17,
|
|
||||||
22,
|
22,
|
||||||
34,
|
34,
|
||||||
36,
|
36,
|
||||||
|
@ -3304,6 +3304,7 @@
|
||||||
30,
|
30,
|
||||||
31,
|
31,
|
||||||
70,
|
70,
|
||||||
|
72,
|
||||||
143,
|
143,
|
||||||
166,
|
166,
|
||||||
167,
|
167,
|
||||||
|
@ -3511,6 +3512,8 @@
|
||||||
56,
|
56,
|
||||||
57,
|
57,
|
||||||
58,
|
58,
|
||||||
|
70,
|
||||||
|
72,
|
||||||
135,
|
135,
|
||||||
137,
|
137,
|
||||||
143,
|
143,
|
||||||
|
|
|
@ -61,6 +61,12 @@ def pre_save_object(sender, instance, **kwargs):
|
||||||
# If the field wasn't modified, no need to check the permissions
|
# If the field wasn't modified, no need to check the permissions
|
||||||
if old_value == new_value:
|
if old_value == new_value:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if app_label == 'auth' and model_name == 'user' and field.name == 'password' and request.user.is_anonymous:
|
||||||
|
# We must ignore password changes from anonymous users since it can be done by people that forgot
|
||||||
|
# their password. We trust password change form.
|
||||||
|
continue
|
||||||
|
|
||||||
if not PermissionBackend.check_perm(request, app_label + ".change_" + model_name + "_" + field_name,
|
if not PermissionBackend.check_perm(request, app_label + ".change_" + model_name + "_" + field_name,
|
||||||
instance):
|
instance):
|
||||||
raise PermissionDenied(
|
raise PermissionDenied(
|
||||||
|
|
|
@ -85,6 +85,9 @@ class UserCreateView(CreateView):
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
|
# Direct access to validation menu if we have the right to validate it
|
||||||
|
if PermissionBackend.check_perm(self.request, 'auth.view_user', self.object):
|
||||||
|
return reverse_lazy('registration:future_user_detail', args=(self.object.pk,))
|
||||||
return reverse_lazy('registration:email_validation_sent')
|
return reverse_lazy('registration:email_validation_sent')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
|
# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
from django.db import transaction
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from note.api.serializers import SpecialTransactionSerializer
|
from note.api.serializers import SpecialTransactionSerializer
|
||||||
|
|
||||||
|
@ -68,6 +68,14 @@ class SogeCreditSerializer(serializers.ModelSerializer):
|
||||||
The djangorestframework plugin will analyse the model `SogeCredit` and parse all fields in the API.
|
The djangorestframework plugin will analyse the model `SogeCredit` and parse all fields in the API.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@transaction.atomic
|
||||||
|
def save(self, **kwargs):
|
||||||
|
# Update soge transactions after creating a credit
|
||||||
|
instance = super().save(**kwargs)
|
||||||
|
instance.update_transactions()
|
||||||
|
instance.save()
|
||||||
|
return instance
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SogeCredit
|
model = SogeCredit
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
|
@ -4,11 +4,12 @@
|
||||||
from crispy_forms.helper import FormHelper
|
from crispy_forms.helper import FormHelper
|
||||||
from crispy_forms.layout import Submit
|
from crispy_forms.layout import Submit
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.contrib.auth.models import User
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from note_kfet.inputs import AmountInput
|
from note_kfet.inputs import AmountInput, Autocomplete
|
||||||
|
|
||||||
from .models import Invoice, Product, Remittance, SpecialTransactionProxy
|
from .models import Invoice, Product, Remittance, SpecialTransactionProxy, SogeCredit
|
||||||
|
|
||||||
|
|
||||||
class InvoiceForm(forms.ModelForm):
|
class InvoiceForm(forms.ModelForm):
|
||||||
|
@ -161,3 +162,19 @@ class LinkTransactionToRemittanceForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SpecialTransactionProxy
|
model = SpecialTransactionProxy
|
||||||
fields = ('remittance', )
|
fields = ('remittance', )
|
||||||
|
|
||||||
|
|
||||||
|
class SogeCreditForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = SogeCredit
|
||||||
|
fields = ('user', )
|
||||||
|
widgets = {
|
||||||
|
"user": Autocomplete(
|
||||||
|
User,
|
||||||
|
attrs={
|
||||||
|
'api_url': '/api/user/',
|
||||||
|
'name_field': 'username',
|
||||||
|
'placeholder': 'Nom ...',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.core.validators import MinValueValidator
|
from django.core.validators import MinValueValidator
|
||||||
|
@ -11,6 +12,7 @@ from django.db.models import Q
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from member.models import Club, Membership
|
||||||
from note.models import NoteSpecial, SpecialTransaction, MembershipTransaction, NoteUser
|
from note.models import NoteSpecial, SpecialTransaction, MembershipTransaction, NoteUser
|
||||||
|
|
||||||
|
|
||||||
|
@ -286,6 +288,7 @@ class SogeCredit(models.Model):
|
||||||
transactions = models.ManyToManyField(
|
transactions = models.ManyToManyField(
|
||||||
MembershipTransaction,
|
MembershipTransaction,
|
||||||
related_name="+",
|
related_name="+",
|
||||||
|
blank=True,
|
||||||
verbose_name=_("membership transactions"),
|
verbose_name=_("membership transactions"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -305,6 +308,42 @@ class SogeCredit(models.Model):
|
||||||
return self.credit_transaction.total if self.valid \
|
return self.credit_transaction.total if self.valid \
|
||||||
else sum(transaction.total for transaction in self.transactions.all())
|
else sum(transaction.total for transaction in self.transactions.all())
|
||||||
|
|
||||||
|
def update_transactions(self):
|
||||||
|
"""
|
||||||
|
The Sogé credit may be created after the user already paid its memberships.
|
||||||
|
We query transactions and update the credit, if it is unvalid.
|
||||||
|
"""
|
||||||
|
if self.valid or not self.pk:
|
||||||
|
return
|
||||||
|
|
||||||
|
bde = Club.objects.get(name="BDE")
|
||||||
|
kfet = Club.objects.get(name="Kfet")
|
||||||
|
bde_qs = Membership.objects.filter(user=self.user, club=bde, date_start__gte=bde.membership_start)
|
||||||
|
kfet_qs = Membership.objects.filter(user=self.user, club=kfet, date_start__gte=kfet.membership_start)
|
||||||
|
|
||||||
|
if bde_qs.exists():
|
||||||
|
m = bde_qs.get()
|
||||||
|
if m.transaction not in self.transactions.all():
|
||||||
|
self.transactions.add(m.transaction)
|
||||||
|
|
||||||
|
if kfet_qs.exists():
|
||||||
|
m = kfet_qs.get()
|
||||||
|
if m.transaction not in self.transactions.all():
|
||||||
|
self.transactions.add(m.transaction)
|
||||||
|
|
||||||
|
if 'wei' in settings.INSTALLED_APPS:
|
||||||
|
from wei.models import WEIClub
|
||||||
|
wei = WEIClub.objects.order_by('-year').first()
|
||||||
|
wei_qs = Membership.objects.filter(user=self.user, club=wei, date_start__gte=wei.membership_start)
|
||||||
|
if wei_qs.exists():
|
||||||
|
m = wei_qs.get()
|
||||||
|
if m.transaction not in self.transactions.all():
|
||||||
|
self.transactions.add(m.transaction)
|
||||||
|
|
||||||
|
for tr in self.transactions.all():
|
||||||
|
tr.valid = False
|
||||||
|
tr.save()
|
||||||
|
|
||||||
def invalidate(self):
|
def invalidate(self):
|
||||||
"""
|
"""
|
||||||
Invalidating a Société générale delete the transaction of the bank if it was already created.
|
Invalidating a Société générale delete the transaction of the bank if it was already created.
|
||||||
|
@ -365,7 +404,8 @@ class SogeCredit(models.Model):
|
||||||
self.credit_transaction.amount = self.amount
|
self.credit_transaction.amount = self.amount
|
||||||
self.credit_transaction._force_save = True
|
self.credit_transaction._force_save = True
|
||||||
self.credit_transaction.save()
|
self.credit_transaction.save()
|
||||||
super().save(*args, **kwargs)
|
|
||||||
|
return super().save(*args, **kwargs)
|
||||||
|
|
||||||
def delete(self, **kwargs):
|
def delete(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load render_table from django_tables2 %}
|
{% load render_table from django_tables2 %}
|
||||||
|
{% load crispy_forms_filters %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -27,7 +28,12 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{{ title }}
|
{{ title }}
|
||||||
</h3>
|
</h3>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
<div class="input-group">
|
||||||
<input id="searchbar" type="text" class="form-control" placeholder="Nom/prénom/note ...">
|
<input id="searchbar" type="text" class="form-control" placeholder="Nom/prénom/note ...">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button id="add_sogecredit" class="btn btn-success" data-toggle="modal" data-target="#add-sogecredit-modal">{% trans "Add" %}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<label for="invalid_only" class="form-check-label">
|
<label for="invalid_only" class="form-check-label">
|
||||||
<input id="invalid_only" name="invalid_only" type="checkbox" class="checkboxinput form-check-input" checked>
|
<input id="invalid_only" name="invalid_only" type="checkbox" class="checkboxinput form-check-input" checked>
|
||||||
|
@ -47,11 +53,32 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{# Popup to add new Soge credits manually if needed #}
|
||||||
|
<div class="modal fade" id="add-sogecredit-modal" tabindex="-1" role="dialog" aria-labelledby="addSogeCredit"
|
||||||
|
aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="lockNote">{% trans "Add credit from the Société générale" %}</h5>
|
||||||
|
<button type="button" class="close btn-modal" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
{{ form|crispy }}
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary btn-modal" data-dismiss="modal">{% trans "Close" %}</button>
|
||||||
|
<button type="button" class="btn btn-success btn-modal" data-dismiss="modal" onclick="addSogeCredit()">{% trans "Add" %}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extrajavascript %}
|
{% block extrajavascript %}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(function () {
|
|
||||||
let old_pattern = null;
|
let old_pattern = null;
|
||||||
let searchbar_obj = $("#searchbar");
|
let searchbar_obj = $("#searchbar");
|
||||||
let invalid_only_obj = $("#invalid_only");
|
let invalid_only_obj = $("#invalid_only");
|
||||||
|
@ -69,6 +96,22 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
searchbar_obj.keyup(reloadTable);
|
searchbar_obj.keyup(reloadTable);
|
||||||
invalid_only_obj.change(reloadTable);
|
invalid_only_obj.change(reloadTable);
|
||||||
});
|
|
||||||
|
function addSogeCredit() {
|
||||||
|
let user_pk = $('#id_user_pk').val()
|
||||||
|
if (!user_pk)
|
||||||
|
return
|
||||||
|
|
||||||
|
$.post('/api/treasury/soge_credit/?format=json', {
|
||||||
|
csrfmiddlewaretoken: CSRF_TOKEN,
|
||||||
|
user: user_pk,
|
||||||
|
}).done(function() {
|
||||||
|
addMsg("{% trans "Credit successfully registered" %}", 'success', 10000)
|
||||||
|
reloadTable()
|
||||||
|
}).fail(function (xhr) {
|
||||||
|
errMsg(xhr.responseJSON, 30000)
|
||||||
|
reloadTable()
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -25,7 +25,8 @@ from note_kfet.settings.base import BASE_DIR
|
||||||
from permission.backends import PermissionBackend
|
from permission.backends import PermissionBackend
|
||||||
from permission.views import ProtectQuerysetMixin, ProtectedCreateView
|
from permission.views import ProtectQuerysetMixin, ProtectedCreateView
|
||||||
|
|
||||||
from .forms import InvoiceForm, ProductFormSet, ProductFormSetHelper, RemittanceForm, LinkTransactionToRemittanceForm
|
from .forms import InvoiceForm, ProductFormSet, ProductFormSetHelper, RemittanceForm, \
|
||||||
|
LinkTransactionToRemittanceForm, SogeCreditForm
|
||||||
from .models import Invoice, Product, Remittance, SpecialTransactionProxy, SogeCredit
|
from .models import Invoice, Product, Remittance, SpecialTransactionProxy, SogeCredit
|
||||||
from .tables import InvoiceTable, RemittanceTable, SpecialTransactionTable, SogeCreditTable
|
from .tables import InvoiceTable, RemittanceTable, SpecialTransactionTable, SogeCreditTable
|
||||||
|
|
||||||
|
@ -433,6 +434,11 @@ class SogeCreditListView(LoginRequiredMixin, ProtectQuerysetMixin, SingleTableVi
|
||||||
|
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['form'] = SogeCreditForm(self.request.POST or None)
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
class SogeCreditManageView(LoginRequiredMixin, ProtectQuerysetMixin, BaseFormView, DetailView):
|
class SogeCreditManageView(LoginRequiredMixin, ProtectQuerysetMixin, BaseFormView, DetailView):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -6,7 +6,7 @@ from django.contrib.auth.models import User
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.forms import CheckboxSelectMultiple
|
from django.forms import CheckboxSelectMultiple
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from note.models import NoteSpecial
|
from note.models import NoteSpecial, NoteUser
|
||||||
from note_kfet.inputs import AmountInput, DatePickerInput, Autocomplete, ColorWidget
|
from note_kfet.inputs import AmountInput, DatePickerInput, Autocomplete, ColorWidget
|
||||||
|
|
||||||
from ..models import WEIClub, WEIRegistration, Bus, BusTeam, WEIMembership, WEIRole
|
from ..models import WEIClub, WEIRegistration, Bus, BusTeam, WEIMembership, WEIRole
|
||||||
|
@ -27,6 +27,15 @@ class WEIForm(forms.ModelForm):
|
||||||
|
|
||||||
|
|
||||||
class WEIRegistrationForm(forms.ModelForm):
|
class WEIRegistrationForm(forms.ModelForm):
|
||||||
|
def clean(self):
|
||||||
|
cleaned_data = super().clean()
|
||||||
|
|
||||||
|
if 'user' in cleaned_data:
|
||||||
|
if not NoteUser.objects.filter(user=cleaned_data['user']).exists():
|
||||||
|
self.add_error('user', _("The selected user is not validated. Please validate its account first"))
|
||||||
|
|
||||||
|
return cleaned_data
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = WEIRegistration
|
model = WEIRegistration
|
||||||
exclude = ('wei', )
|
exclude = ('wei', )
|
||||||
|
|
|
@ -170,6 +170,7 @@ class WEISurveyAlgorithm2021(WEISurveyAlgorithm):
|
||||||
We modify it to allow buses to have multiple "weddings".
|
We modify it to allow buses to have multiple "weddings".
|
||||||
"""
|
"""
|
||||||
surveys = list(self.get_survey_class()(r) for r in self.get_registrations()) # All surveys
|
surveys = list(self.get_survey_class()(r) for r in self.get_registrations()) # All surveys
|
||||||
|
surveys = [s for s in surveys if s.is_complete()]
|
||||||
free_surveys = [s for s in surveys if not s.information.valid] # Remaining surveys
|
free_surveys = [s for s in surveys if not s.information.valid] # Remaining surveys
|
||||||
while free_surveys: # Some students are not affected
|
while free_surveys: # Some students are not affected
|
||||||
survey = free_surveys[0]
|
survey = free_surveys[0]
|
||||||
|
|
|
@ -28,7 +28,8 @@ class Command(BaseCommand):
|
||||||
|
|
||||||
output = options['output']
|
output = options['output']
|
||||||
registrations = algorithm.get_registrations()
|
registrations = algorithm.get_registrations()
|
||||||
per_bus = {bus: [r for r in registrations if r.information['selected_bus_pk'] == bus.pk]
|
per_bus = {bus: [r for r in registrations if 'selected_bus_pk' in r.information
|
||||||
|
and r.information['selected_bus_pk'] == bus.pk]
|
||||||
for bus in algorithm.get_buses()}
|
for bus in algorithm.get_buses()}
|
||||||
for bus, members in per_bus.items():
|
for bus, members in per_bus.items():
|
||||||
output.write(bus.name + "\n")
|
output.write(bus.name + "\n")
|
||||||
|
|
|
@ -364,8 +364,19 @@ class WEIMembership(Membership):
|
||||||
# to treasurers.
|
# to treasurers.
|
||||||
transaction.refresh_from_db()
|
transaction.refresh_from_db()
|
||||||
from treasury.models import SogeCredit
|
from treasury.models import SogeCredit
|
||||||
soge_credit = SogeCredit.objects.get_or_create(user=self.user)[0]
|
soge_credit, created = SogeCredit.objects.get_or_create(user=self.user)
|
||||||
soge_credit.refresh_from_db()
|
soge_credit.refresh_from_db()
|
||||||
transaction.save()
|
transaction.save()
|
||||||
soge_credit.transactions.add(transaction)
|
soge_credit.transactions.add(transaction)
|
||||||
soge_credit.save()
|
soge_credit.save()
|
||||||
|
|
||||||
|
soge_credit.update_transactions()
|
||||||
|
soge_credit.save()
|
||||||
|
|
||||||
|
if soge_credit.valid and \
|
||||||
|
soge_credit.credit_transaction.total != sum(tr.total for tr in soge_credit.transactions.all()):
|
||||||
|
# The credit is already validated, but we add a new transaction (eg. for the WEI).
|
||||||
|
# Then we invalidate the transaction, update the credit transaction amount
|
||||||
|
# and re-validate the credit.
|
||||||
|
soge_credit.validate(True)
|
||||||
|
soge_credit.save()
|
||||||
|
|
|
@ -99,9 +99,12 @@ class WEIRegistrationTable(tables.Table):
|
||||||
|
|
||||||
url = reverse_lazy('wei:validate_registration', args=(record.pk,))
|
url = reverse_lazy('wei:validate_registration', args=(record.pk,))
|
||||||
text = _('Validate')
|
text = _('Validate')
|
||||||
if record.fee > record.user.note.balance:
|
if record.fee > record.user.note.balance and not record.soge_credit:
|
||||||
btn_class = 'btn-secondary'
|
btn_class = 'btn-secondary'
|
||||||
tooltip = _("The user does not have enough money.")
|
tooltip = _("The user does not have enough money.")
|
||||||
|
elif record.first_year and 'selected_bus_pk' not in record.information:
|
||||||
|
btn_class = 'btn-info'
|
||||||
|
tooltip = _("The user is in first year, and the repartition algorithm didn't run.")
|
||||||
else:
|
else:
|
||||||
btn_class = 'btn-success'
|
btn_class = 'btn-success'
|
||||||
tooltip = _("The user has enough money, you can validate the registration.")
|
tooltip = _("The user has enough money, you can validate the registration.")
|
||||||
|
|
|
@ -12,7 +12,7 @@ from django.test import TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from member.models import Membership, Club
|
from member.models import Membership, Club
|
||||||
from note.models import NoteClub, SpecialTransaction
|
from note.models import NoteClub, SpecialTransaction, NoteUser
|
||||||
from treasury.models import SogeCredit
|
from treasury.models import SogeCredit
|
||||||
|
|
||||||
from ..api.views import BusViewSet, BusTeamViewSet, WEIClubViewSet, WEIMembershipViewSet, WEIRegistrationViewSet, \
|
from ..api.views import BusViewSet, BusTeamViewSet, WEIClubViewSet, WEIMembershipViewSet, WEIRegistrationViewSet, \
|
||||||
|
@ -302,6 +302,7 @@ class TestWEIRegistration(TestCase):
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
user = User.objects.create(username="toto", email="toto@example.com")
|
user = User.objects.create(username="toto", email="toto@example.com")
|
||||||
|
NoteUser.objects.create(user=user)
|
||||||
|
|
||||||
# Try with an invalid form
|
# Try with an invalid form
|
||||||
response = self.client.post(reverse("wei:wei_register_2A", kwargs=dict(wei_pk=self.wei.pk)), dict(
|
response = self.client.post(reverse("wei:wei_register_2A", kwargs=dict(wei_pk=self.wei.pk)), dict(
|
||||||
|
@ -368,7 +369,7 @@ class TestWEIRegistration(TestCase):
|
||||||
last_name="toto",
|
last_name="toto",
|
||||||
bank="Société générale",
|
bank="Société générale",
|
||||||
))
|
))
|
||||||
response = self.client.get(reverse("wei:wei_register_2A_myself", kwargs=dict(wei_pk=self.wei.pk)))
|
response = self.client.get(reverse("wei:wei_register_2A", kwargs=dict(wei_pk=self.wei.pk)))
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
# Check that if the WEI is started, we can't register anyone
|
# Check that if the WEI is started, we can't register anyone
|
||||||
|
@ -384,10 +385,8 @@ class TestWEIRegistration(TestCase):
|
||||||
response = self.client.get(reverse("wei:wei_register_1A", kwargs=dict(wei_pk=self.wei.pk)))
|
response = self.client.get(reverse("wei:wei_register_1A", kwargs=dict(wei_pk=self.wei.pk)))
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
response = self.client.get(reverse("wei:wei_register_1A_myself", kwargs=dict(wei_pk=self.wei.pk)))
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
|
||||||
user = User.objects.create(username="toto", email="toto@example.com")
|
user = User.objects.create(username="toto", email="toto@example.com")
|
||||||
|
NoteUser.objects.create(user=user)
|
||||||
response = self.client.post(reverse("wei:wei_register_1A", kwargs=dict(wei_pk=self.wei.pk)), dict(
|
response = self.client.post(reverse("wei:wei_register_1A", kwargs=dict(wei_pk=self.wei.pk)), dict(
|
||||||
user=user.id,
|
user=user.id,
|
||||||
soge_credit=True,
|
soge_credit=True,
|
||||||
|
@ -467,6 +466,24 @@ class TestWEIRegistration(TestCase):
|
||||||
response = self.client.get(reverse("wei:wei_survey", kwargs=dict(pk=registration.pk)))
|
response = self.client.get(reverse("wei:wei_survey", kwargs=dict(pk=registration.pk)))
|
||||||
self.assertRedirects(response, reverse("wei:wei_closed", kwargs=dict(pk=self.wei.pk)), 302, 200)
|
self.assertRedirects(response, reverse("wei:wei_closed", kwargs=dict(pk=self.wei.pk)), 302, 200)
|
||||||
|
|
||||||
|
def test_register_myself(self):
|
||||||
|
"""
|
||||||
|
Try to register myself to the WEI, and check redirections.
|
||||||
|
"""
|
||||||
|
response = self.client.get(reverse('wei:wei_register_1A_myself', args=(self.wei.pk,)))
|
||||||
|
self.assertRedirects(response, reverse('wei:wei_update_registration', args=(self.registration.pk,)))
|
||||||
|
|
||||||
|
response = self.client.get(reverse('wei:wei_register_2A_myself', args=(self.wei.pk,)))
|
||||||
|
self.assertRedirects(response, reverse('wei:wei_update_registration', args=(self.registration.pk,)))
|
||||||
|
|
||||||
|
self.registration.delete()
|
||||||
|
|
||||||
|
response = self.client.get(reverse('wei:wei_register_1A_myself', args=(self.wei.pk,)))
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
response = self.client.get(reverse('wei:wei_register_2A_myself', args=(self.wei.pk,)))
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
def test_wei_survey_ended(self):
|
def test_wei_survey_ended(self):
|
||||||
"""
|
"""
|
||||||
Test display the end page of a survey.
|
Test display the end page of a survey.
|
||||||
|
|
|
@ -132,7 +132,7 @@ class WEIDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
|
||||||
wei=club
|
wei=club
|
||||||
)
|
)
|
||||||
pre_registrations_table = WEIRegistrationTable(data=pre_registrations, prefix="pre-registration-")
|
pre_registrations_table = WEIRegistrationTable(data=pre_registrations, prefix="pre-registration-")
|
||||||
pre_registrations_table.paginate(per_page=20, page=self.request.GET.get('membership-page', 1))
|
pre_registrations_table.paginate(per_page=20, page=self.request.GET.get('pre-registration-page', 1))
|
||||||
context['pre_registrations'] = pre_registrations_table
|
context['pre_registrations'] = pre_registrations_table
|
||||||
|
|
||||||
my_registration = WEIRegistration.objects.filter(wei=club, user=self.request.user)
|
my_registration = WEIRegistration.objects.filter(wei=club, user=self.request.user)
|
||||||
|
@ -510,6 +510,10 @@ class WEIRegister1AView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||||
# We can't register someone once the WEI is started and before the membership start date
|
# We can't register someone once the WEI is started and before the membership start date
|
||||||
if today >= wei.date_start or today < wei.membership_start:
|
if today >= wei.date_start or today < wei.membership_start:
|
||||||
return redirect(reverse_lazy('wei:wei_closed', args=(wei.pk,)))
|
return redirect(reverse_lazy('wei:wei_closed', args=(wei.pk,)))
|
||||||
|
# Don't register twice
|
||||||
|
if 'myself' in self.request.path and WEIRegistration.objects.filter(wei=wei, user=self.request.user).exists():
|
||||||
|
obj = WEIRegistration.objects.get(wei=wei, user=self.request.user)
|
||||||
|
return redirect(reverse_lazy('wei:wei_update_registration', args=(obj.pk,)))
|
||||||
return super().dispatch(request, *args, **kwargs)
|
return super().dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
|
@ -585,6 +589,10 @@ class WEIRegister2AView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||||
# We can't register someone once the WEI is started and before the membership start date
|
# We can't register someone once the WEI is started and before the membership start date
|
||||||
if today >= wei.date_start or today < wei.membership_start:
|
if today >= wei.date_start or today < wei.membership_start:
|
||||||
return redirect(reverse_lazy('wei:wei_closed', args=(wei.pk,)))
|
return redirect(reverse_lazy('wei:wei_closed', args=(wei.pk,)))
|
||||||
|
# Don't register twice
|
||||||
|
if 'myself' in self.request.path and WEIRegistration.objects.filter(wei=wei, user=self.request.user).exists():
|
||||||
|
obj = WEIRegistration.objects.get(wei=wei, user=self.request.user)
|
||||||
|
return redirect(reverse_lazy('wei:wei_update_registration', args=(obj.pk,)))
|
||||||
return super().dispatch(request, *args, **kwargs)
|
return super().dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
|
@ -683,12 +691,14 @@ class WEIUpdateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Update
|
||||||
context["membership_form"] = membership_form
|
context["membership_form"] = membership_form
|
||||||
elif not self.object.first_year and PermissionBackend.check_perm(
|
elif not self.object.first_year and PermissionBackend.check_perm(
|
||||||
self.request, "wei.change_weiregistration_information_json", self.object):
|
self.request, "wei.change_weiregistration_information_json", self.object):
|
||||||
|
information = self.object.information
|
||||||
|
d = dict(
|
||||||
|
bus=Bus.objects.filter(pk__in=information["preferred_bus_pk"]).all(),
|
||||||
|
team=BusTeam.objects.filter(pk__in=information["preferred_team_pk"]).all(),
|
||||||
|
roles=WEIRole.objects.filter(pk__in=information["preferred_roles_pk"]).all(),
|
||||||
|
) if 'preferred_bus_pk' in information else dict()
|
||||||
choose_bus_form = WEIChooseBusForm(
|
choose_bus_form = WEIChooseBusForm(
|
||||||
self.request.POST if self.request.POST else dict(
|
self.request.POST if self.request.POST else d
|
||||||
bus=Bus.objects.filter(pk__in=self.object.information["preferred_bus_pk"]).all(),
|
|
||||||
team=BusTeam.objects.filter(pk__in=self.object.information["preferred_team_pk"]).all(),
|
|
||||||
roles=WEIRole.objects.filter(pk__in=self.object.information["preferred_roles_pk"]).all(),
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
choose_bus_form.fields["bus"].queryset = Bus.objects.filter(wei=context["club"])
|
choose_bus_form.fields["bus"].queryset = Bus.objects.filter(wei=context["club"])
|
||||||
choose_bus_form.fields["team"].queryset = BusTeam.objects.filter(bus__wei=context["club"])
|
choose_bus_form.fields["team"].queryset = BusTeam.objects.filter(bus__wei=context["club"])
|
||||||
|
@ -704,7 +714,8 @@ class WEIUpdateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Update
|
||||||
def get_form(self, form_class=None):
|
def get_form(self, form_class=None):
|
||||||
form = super().get_form(form_class)
|
form = super().get_form(form_class)
|
||||||
form.fields["user"].disabled = True
|
form.fields["user"].disabled = True
|
||||||
if not self.object.first_year:
|
# The auto-json-format may cause issues with the default field remove
|
||||||
|
if not PermissionBackend.check_perm(self.request, 'wei.change_weiregistration_information_json', self.object):
|
||||||
del form.fields["information_json"]
|
del form.fields["information_json"]
|
||||||
return form
|
return form
|
||||||
|
|
||||||
|
@ -964,12 +975,11 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||||
membership.roles.set(WEIRole.objects.filter(name="1A").all())
|
membership.roles.set(WEIRole.objects.filter(name="1A").all())
|
||||||
membership.save()
|
membership.save()
|
||||||
|
|
||||||
ret = super().form_valid(form)
|
membership.save()
|
||||||
|
|
||||||
membership.refresh_from_db()
|
membership.refresh_from_db()
|
||||||
membership.roles.add(WEIRole.objects.get(name="Adhérent WEI"))
|
membership.roles.add(WEIRole.objects.get(name="Adhérent WEI"))
|
||||||
|
|
||||||
return ret
|
return super().form_valid(form)
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
self.object.refresh_from_db()
|
self.object.refresh_from_db()
|
||||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-06-15 21:17+0200\n"
|
"POT-Creation-Date: 2021-09-08 18:46+0200\n"
|
||||||
"PO-Revision-Date: 2020-11-16 20:02+0000\n"
|
"PO-Revision-Date: 2020-11-16 20:02+0000\n"
|
||||||
"Last-Translator: Yohann D'ANELLO <ynerant@crans.org>\n"
|
"Last-Translator: Yohann D'ANELLO <ynerant@crans.org>\n"
|
||||||
"Language-Team: French <http://translate.ynerant.fr/projects/nk20/nk20/fr/>\n"
|
"Language-Team: French <http://translate.ynerant.fr/projects/nk20/nk20/fr/>\n"
|
||||||
|
@ -111,7 +111,7 @@ msgid "type"
|
||||||
msgstr "type"
|
msgstr "type"
|
||||||
|
|
||||||
#: apps/activity/models.py:89 apps/logs/models.py:22 apps/member/models.py:305
|
#: apps/activity/models.py:89 apps/logs/models.py:22 apps/member/models.py:305
|
||||||
#: apps/note/models/notes.py:148 apps/treasury/models.py:283
|
#: apps/note/models/notes.py:148 apps/treasury/models.py:286
|
||||||
#: apps/wei/models.py:165 apps/wei/templates/wei/survey.html:15
|
#: apps/wei/models.py:165 apps/wei/templates/wei/survey.html:15
|
||||||
msgid "user"
|
msgid "user"
|
||||||
msgstr "utilisateur"
|
msgstr "utilisateur"
|
||||||
|
@ -251,20 +251,20 @@ msgstr "Entré le "
|
||||||
msgid "remove"
|
msgid "remove"
|
||||||
msgstr "supprimer"
|
msgstr "supprimer"
|
||||||
|
|
||||||
#: apps/activity/tables.py:80 apps/note/forms.py:68 apps/treasury/models.py:197
|
#: apps/activity/tables.py:80 apps/note/forms.py:68 apps/treasury/models.py:200
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr "Type"
|
msgstr "Type"
|
||||||
|
|
||||||
#: apps/activity/tables.py:82 apps/member/forms.py:186
|
#: apps/activity/tables.py:82 apps/member/forms.py:186
|
||||||
#: apps/registration/forms.py:90 apps/treasury/forms.py:130
|
#: apps/registration/forms.py:90 apps/treasury/forms.py:131
|
||||||
#: apps/wei/forms/registration.py:96
|
#: apps/wei/forms/registration.py:105
|
||||||
msgid "Last name"
|
msgid "Last name"
|
||||||
msgstr "Nom de famille"
|
msgstr "Nom de famille"
|
||||||
|
|
||||||
#: apps/activity/tables.py:84 apps/member/forms.py:191
|
#: apps/activity/tables.py:84 apps/member/forms.py:191
|
||||||
#: apps/note/templates/note/transaction_form.html:134
|
#: apps/note/templates/note/transaction_form.html:134
|
||||||
#: apps/registration/forms.py:95 apps/treasury/forms.py:132
|
#: apps/registration/forms.py:95 apps/treasury/forms.py:133
|
||||||
#: apps/wei/forms/registration.py:101
|
#: apps/wei/forms/registration.py:110
|
||||||
msgid "First name"
|
msgid "First name"
|
||||||
msgstr "Prénom"
|
msgstr "Prénom"
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ msgstr "Entrée effectuée !"
|
||||||
#: apps/member/templates/member/add_members.html:46
|
#: apps/member/templates/member/add_members.html:46
|
||||||
#: apps/member/templates/member/club_form.html:16
|
#: apps/member/templates/member/club_form.html:16
|
||||||
#: apps/note/templates/note/transactiontemplate_form.html:18
|
#: apps/note/templates/note/transactiontemplate_form.html:18
|
||||||
#: apps/treasury/forms.py:88 apps/treasury/forms.py:142
|
#: apps/treasury/forms.py:89 apps/treasury/forms.py:143
|
||||||
#: apps/treasury/templates/treasury/invoice_form.html:74
|
#: apps/treasury/templates/treasury/invoice_form.html:74
|
||||||
#: apps/wei/templates/wei/bus_form.html:17
|
#: apps/wei/templates/wei/bus_form.html:17
|
||||||
#: apps/wei/templates/wei/busteam_form.html:17
|
#: apps/wei/templates/wei/busteam_form.html:17
|
||||||
|
@ -508,7 +508,7 @@ msgstr "rôles"
|
||||||
msgid "fee"
|
msgid "fee"
|
||||||
msgstr "cotisation"
|
msgstr "cotisation"
|
||||||
|
|
||||||
#: apps/member/apps.py:14 apps/wei/tables.py:193 apps/wei/tables.py:224
|
#: apps/member/apps.py:14 apps/wei/tables.py:196 apps/wei/tables.py:227
|
||||||
msgid "member"
|
msgid "member"
|
||||||
msgstr "adhérent"
|
msgstr "adhérent"
|
||||||
|
|
||||||
|
@ -540,8 +540,8 @@ msgstr "Taille maximale : 2 Mo"
|
||||||
msgid "This image cannot be loaded."
|
msgid "This image cannot be loaded."
|
||||||
msgstr "Cette image ne peut pas être chargée."
|
msgstr "Cette image ne peut pas être chargée."
|
||||||
|
|
||||||
#: apps/member/forms.py:141 apps/member/views.py:100
|
#: apps/member/forms.py:141 apps/member/views.py:102
|
||||||
#: apps/registration/forms.py:33 apps/registration/views.py:254
|
#: apps/registration/forms.py:33 apps/registration/views.py:262
|
||||||
msgid "An alias with a similar name already exists."
|
msgid "An alias with a similar name already exists."
|
||||||
msgstr "Un alias avec un nom similaire existe déjà."
|
msgstr "Un alias avec un nom similaire existe déjà."
|
||||||
|
|
||||||
|
@ -554,12 +554,12 @@ msgid "Check this case if the Société Générale paid the inscription."
|
||||||
msgstr "Cochez cette case si la Société Générale a payé l'inscription."
|
msgstr "Cochez cette case si la Société Générale a payé l'inscription."
|
||||||
|
|
||||||
#: apps/member/forms.py:172 apps/registration/forms.py:77
|
#: apps/member/forms.py:172 apps/registration/forms.py:77
|
||||||
#: apps/wei/forms/registration.py:83
|
#: apps/wei/forms/registration.py:92
|
||||||
msgid "Credit type"
|
msgid "Credit type"
|
||||||
msgstr "Type de rechargement"
|
msgstr "Type de rechargement"
|
||||||
|
|
||||||
#: apps/member/forms.py:173 apps/registration/forms.py:78
|
#: apps/member/forms.py:173 apps/registration/forms.py:78
|
||||||
#: apps/wei/forms/registration.py:84
|
#: apps/wei/forms/registration.py:93
|
||||||
msgid "No credit"
|
msgid "No credit"
|
||||||
msgstr "Pas de rechargement"
|
msgstr "Pas de rechargement"
|
||||||
|
|
||||||
|
@ -568,13 +568,13 @@ msgid "You can credit the note of the user."
|
||||||
msgstr "Vous pouvez créditer la note de l'utilisateur avant l'adhésion."
|
msgstr "Vous pouvez créditer la note de l'utilisateur avant l'adhésion."
|
||||||
|
|
||||||
#: apps/member/forms.py:179 apps/registration/forms.py:83
|
#: apps/member/forms.py:179 apps/registration/forms.py:83
|
||||||
#: apps/wei/forms/registration.py:89
|
#: apps/wei/forms/registration.py:98
|
||||||
msgid "Credit amount"
|
msgid "Credit amount"
|
||||||
msgstr "Montant à créditer"
|
msgstr "Montant à créditer"
|
||||||
|
|
||||||
#: apps/member/forms.py:196 apps/note/templates/note/transaction_form.html:140
|
#: apps/member/forms.py:196 apps/note/templates/note/transaction_form.html:140
|
||||||
#: apps/registration/forms.py:100 apps/treasury/forms.py:134
|
#: apps/registration/forms.py:100 apps/treasury/forms.py:135
|
||||||
#: apps/wei/forms/registration.py:106
|
#: apps/wei/forms/registration.py:115
|
||||||
msgid "Bank"
|
msgid "Bank"
|
||||||
msgstr "Banque"
|
msgstr "Banque"
|
||||||
|
|
||||||
|
@ -586,6 +586,22 @@ msgstr "Utilisateur"
|
||||||
msgid "Roles"
|
msgid "Roles"
|
||||||
msgstr "Rôles"
|
msgstr "Rôles"
|
||||||
|
|
||||||
|
#: apps/member/hashers.py:57
|
||||||
|
msgid "algorithm"
|
||||||
|
msgstr "algorithme"
|
||||||
|
|
||||||
|
#: apps/member/hashers.py:58
|
||||||
|
msgid "iterations"
|
||||||
|
msgstr "itérations"
|
||||||
|
|
||||||
|
#: apps/member/hashers.py:59
|
||||||
|
msgid "salt"
|
||||||
|
msgstr "salage"
|
||||||
|
|
||||||
|
#: apps/member/hashers.py:60
|
||||||
|
msgid "hash"
|
||||||
|
msgstr "haché"
|
||||||
|
|
||||||
#: apps/member/models.py:38
|
#: apps/member/models.py:38
|
||||||
#: apps/member/templates/member/includes/profile_info.html:35
|
#: apps/member/templates/member/includes/profile_info.html:35
|
||||||
#: apps/registration/templates/registration/future_profile_detail.html:40
|
#: apps/registration/templates/registration/future_profile_detail.html:40
|
||||||
|
@ -688,7 +704,7 @@ msgid "address"
|
||||||
msgstr "adresse"
|
msgstr "adresse"
|
||||||
|
|
||||||
#: apps/member/models.py:90
|
#: apps/member/models.py:90
|
||||||
#: apps/member/templates/member/includes/profile_info.html:46
|
#: apps/member/templates/member/includes/profile_info.html:42
|
||||||
#: apps/registration/templates/registration/future_profile_detail.html:43
|
#: apps/registration/templates/registration/future_profile_detail.html:43
|
||||||
#: apps/wei/templates/wei/weimembership_form.html:47
|
#: apps/wei/templates/wei/weimembership_form.html:47
|
||||||
msgid "paid"
|
msgid "paid"
|
||||||
|
@ -835,7 +851,7 @@ msgstr "Le rôle {role} ne s'applique pas au club {club}."
|
||||||
msgid "User is already a member of the club"
|
msgid "User is already a member of the club"
|
||||||
msgstr "L'utilisateur est déjà membre du club"
|
msgstr "L'utilisateur est déjà membre du club"
|
||||||
|
|
||||||
#: apps/member/models.py:443 apps/member/views.py:661
|
#: apps/member/models.py:443 apps/member/views.py:660
|
||||||
msgid "User is not a member of the parent club"
|
msgid "User is not a member of the parent club"
|
||||||
msgstr "L'utilisateur n'est pas membre du club parent"
|
msgstr "L'utilisateur n'est pas membre du club parent"
|
||||||
|
|
||||||
|
@ -944,7 +960,8 @@ msgstr ""
|
||||||
"déverrouiller lui-même."
|
"déverrouiller lui-même."
|
||||||
|
|
||||||
#: apps/member/templates/member/base.html:110
|
#: apps/member/templates/member/base.html:110
|
||||||
#: apps/member/templates/member/base.html:137 apps/treasury/forms.py:90
|
#: apps/member/templates/member/base.html:137 apps/treasury/forms.py:91
|
||||||
|
#: apps/treasury/templates/treasury/sogecredit_list.html:72
|
||||||
msgid "Close"
|
msgid "Close"
|
||||||
msgstr "Fermer"
|
msgstr "Fermer"
|
||||||
|
|
||||||
|
@ -968,6 +985,8 @@ msgstr "Alias de la note"
|
||||||
#: apps/member/templates/member/club_alias.html:20
|
#: apps/member/templates/member/club_alias.html:20
|
||||||
#: apps/member/templates/member/profile_alias.html:19
|
#: apps/member/templates/member/profile_alias.html:19
|
||||||
#: apps/treasury/tables.py:99
|
#: apps/treasury/tables.py:99
|
||||||
|
#: apps/treasury/templates/treasury/sogecredit_list.html:34
|
||||||
|
#: apps/treasury/templates/treasury/sogecredit_list.html:73
|
||||||
msgid "Add"
|
msgid "Add"
|
||||||
msgstr "Ajouter"
|
msgstr "Ajouter"
|
||||||
|
|
||||||
|
@ -1017,7 +1036,7 @@ msgid "membership fee"
|
||||||
msgstr "cotisation pour adhérer"
|
msgstr "cotisation pour adhérer"
|
||||||
|
|
||||||
#: apps/member/templates/member/includes/club_info.html:43
|
#: apps/member/templates/member/includes/club_info.html:43
|
||||||
#: apps/member/templates/member/includes/profile_info.html:43
|
#: apps/member/templates/member/includes/profile_info.html:47
|
||||||
#: apps/treasury/templates/treasury/sogecredit_detail.html:24
|
#: apps/treasury/templates/treasury/sogecredit_detail.html:24
|
||||||
#: apps/wei/templates/wei/base.html:60
|
#: apps/wei/templates/wei/base.html:60
|
||||||
msgid "balance"
|
msgid "balance"
|
||||||
|
@ -1133,7 +1152,7 @@ msgstr "Inscriptions"
|
||||||
msgid "This address must be valid."
|
msgid "This address must be valid."
|
||||||
msgstr "Cette adresse doit être valide."
|
msgstr "Cette adresse doit être valide."
|
||||||
|
|
||||||
#: apps/member/views.py:138
|
#: apps/member/views.py:139
|
||||||
msgid "Profile detail"
|
msgid "Profile detail"
|
||||||
msgstr "Détails de l'utilisateur"
|
msgstr "Détails de l'utilisateur"
|
||||||
|
|
||||||
|
@ -1169,7 +1188,7 @@ msgstr "Modifier le club"
|
||||||
msgid "Add new member to the club"
|
msgid "Add new member to the club"
|
||||||
msgstr "Ajouter un nouveau membre au club"
|
msgstr "Ajouter un nouveau membre au club"
|
||||||
|
|
||||||
#: apps/member/views.py:642 apps/wei/views.py:917
|
#: apps/member/views.py:642 apps/wei/views.py:932
|
||||||
msgid ""
|
msgid ""
|
||||||
"This user don't have enough money to join this club, and can't have a "
|
"This user don't have enough money to join this club, and can't have a "
|
||||||
"negative balance."
|
"negative balance."
|
||||||
|
@ -1177,19 +1196,19 @@ msgstr ""
|
||||||
"Cet utilisateur n'a pas assez d'argent pour rejoindre ce club et ne peut pas "
|
"Cet utilisateur n'a pas assez d'argent pour rejoindre ce club et ne peut pas "
|
||||||
"avoir un solde négatif."
|
"avoir un solde négatif."
|
||||||
|
|
||||||
#: apps/member/views.py:665
|
#: apps/member/views.py:664
|
||||||
msgid "The membership must start after {:%m-%d-%Y}."
|
msgid "The membership must start after {:%m-%d-%Y}."
|
||||||
msgstr "L'adhésion doit commencer après le {:%d/%m/%Y}."
|
msgstr "L'adhésion doit commencer après le {:%d/%m/%Y}."
|
||||||
|
|
||||||
#: apps/member/views.py:670
|
#: apps/member/views.py:669
|
||||||
msgid "The membership must begin before {:%m-%d-%Y}."
|
msgid "The membership must begin before {:%m-%d-%Y}."
|
||||||
msgstr "L'adhésion doit commencer avant le {:%d/%m/%Y}."
|
msgstr "L'adhésion doit commencer avant le {:%d/%m/%Y}."
|
||||||
|
|
||||||
#: apps/member/views.py:816
|
#: apps/member/views.py:815
|
||||||
msgid "Manage roles of an user in the club"
|
msgid "Manage roles of an user in the club"
|
||||||
msgstr "Gérer les rôles d'un utilisateur dans le club"
|
msgstr "Gérer les rôles d'un utilisateur dans le club"
|
||||||
|
|
||||||
#: apps/member/views.py:841
|
#: apps/member/views.py:840
|
||||||
msgid "Members of the club"
|
msgid "Members of the club"
|
||||||
msgstr "Membres du club"
|
msgstr "Membres du club"
|
||||||
|
|
||||||
|
@ -1475,8 +1494,8 @@ msgstr ""
|
||||||
"mode de paiement et un utilisateur ou un club"
|
"mode de paiement et un utilisateur ou un club"
|
||||||
|
|
||||||
#: apps/note/models/transactions.py:355 apps/note/models/transactions.py:358
|
#: apps/note/models/transactions.py:355 apps/note/models/transactions.py:358
|
||||||
#: apps/note/models/transactions.py:361 apps/wei/views.py:922
|
#: apps/note/models/transactions.py:361 apps/wei/views.py:937
|
||||||
#: apps/wei/views.py:926
|
#: apps/wei/views.py:941
|
||||||
msgid "This field is required."
|
msgid "This field is required."
|
||||||
msgstr "Ce champ est requis."
|
msgstr "Ce champ est requis."
|
||||||
|
|
||||||
|
@ -1492,7 +1511,7 @@ msgstr "Transactions de crédit/retrait"
|
||||||
msgid "membership transaction"
|
msgid "membership transaction"
|
||||||
msgstr "transaction d'adhésion"
|
msgstr "transaction d'adhésion"
|
||||||
|
|
||||||
#: apps/note/models/transactions.py:385 apps/treasury/models.py:289
|
#: apps/note/models/transactions.py:385 apps/treasury/models.py:293
|
||||||
msgid "membership transactions"
|
msgid "membership transactions"
|
||||||
msgstr "transactions d'adhésion"
|
msgstr "transactions d'adhésion"
|
||||||
|
|
||||||
|
@ -1511,7 +1530,7 @@ msgstr "Pas de motif spécifié"
|
||||||
#: apps/note/tables.py:169 apps/note/tables.py:203 apps/treasury/tables.py:39
|
#: apps/note/tables.py:169 apps/note/tables.py:203 apps/treasury/tables.py:39
|
||||||
#: apps/treasury/templates/treasury/invoice_confirm_delete.html:30
|
#: apps/treasury/templates/treasury/invoice_confirm_delete.html:30
|
||||||
#: apps/treasury/templates/treasury/sogecredit_detail.html:65
|
#: apps/treasury/templates/treasury/sogecredit_detail.html:65
|
||||||
#: apps/wei/tables.py:74 apps/wei/tables.py:114
|
#: apps/wei/tables.py:74 apps/wei/tables.py:117
|
||||||
#: apps/wei/templates/wei/weiregistration_confirm_delete.html:31
|
#: apps/wei/templates/wei/weiregistration_confirm_delete.html:31
|
||||||
#: note_kfet/templates/oauth2_provider/application_confirm_delete.html:18
|
#: note_kfet/templates/oauth2_provider/application_confirm_delete.html:18
|
||||||
#: note_kfet/templates/oauth2_provider/application_detail.html:39
|
#: note_kfet/templates/oauth2_provider/application_detail.html:39
|
||||||
|
@ -1599,14 +1618,14 @@ msgid "Action"
|
||||||
msgstr "Action"
|
msgstr "Action"
|
||||||
|
|
||||||
#: apps/note/templates/note/transaction_form.html:112
|
#: apps/note/templates/note/transaction_form.html:112
|
||||||
#: apps/treasury/forms.py:136 apps/treasury/tables.py:67
|
#: apps/treasury/forms.py:137 apps/treasury/tables.py:67
|
||||||
#: apps/treasury/tables.py:132
|
#: apps/treasury/tables.py:132
|
||||||
#: apps/treasury/templates/treasury/remittance_form.html:23
|
#: apps/treasury/templates/treasury/remittance_form.html:23
|
||||||
msgid "Amount"
|
msgid "Amount"
|
||||||
msgstr "Montant"
|
msgstr "Montant"
|
||||||
|
|
||||||
#: apps/note/templates/note/transaction_form.html:128
|
#: apps/note/templates/note/transaction_form.html:128
|
||||||
#: apps/treasury/models.py:52
|
#: apps/treasury/models.py:55
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Nom"
|
msgstr "Nom"
|
||||||
|
|
||||||
|
@ -1767,7 +1786,7 @@ msgstr "s'applique au club"
|
||||||
msgid "role permissions"
|
msgid "role permissions"
|
||||||
msgstr "permissions par rôles"
|
msgstr "permissions par rôles"
|
||||||
|
|
||||||
#: apps/permission/signals.py:67
|
#: apps/permission/signals.py:73
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"You don't have the permission to change the field {field} on this instance "
|
"You don't have the permission to change the field {field} on this instance "
|
||||||
|
@ -1776,7 +1795,7 @@ msgstr ""
|
||||||
"Vous n'avez pas la permission de modifier le champ {field} sur l'instance du "
|
"Vous n'avez pas la permission de modifier le champ {field} sur l'instance du "
|
||||||
"modèle {app_label}.{model_name}."
|
"modèle {app_label}.{model_name}."
|
||||||
|
|
||||||
#: apps/permission/signals.py:77 apps/permission/views.py:105
|
#: apps/permission/signals.py:83 apps/permission/views.py:105
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"You don't have the permission to add an instance of model {app_label}."
|
"You don't have the permission to add an instance of model {app_label}."
|
||||||
|
@ -1785,7 +1804,7 @@ msgstr ""
|
||||||
"Vous n'avez pas la permission d'ajouter une instance du modèle {app_label}."
|
"Vous n'avez pas la permission d'ajouter une instance du modèle {app_label}."
|
||||||
"{model_name}."
|
"{model_name}."
|
||||||
|
|
||||||
#: apps/permission/signals.py:106
|
#: apps/permission/signals.py:112
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"You don't have the permission to delete this instance of model {app_label}."
|
"You don't have the permission to delete this instance of model {app_label}."
|
||||||
|
@ -2032,50 +2051,50 @@ msgstr "L'équipe de la Note Kfet."
|
||||||
msgid "Register new user"
|
msgid "Register new user"
|
||||||
msgstr "Enregistrer un nouvel utilisateur"
|
msgstr "Enregistrer un nouvel utilisateur"
|
||||||
|
|
||||||
#: apps/registration/views.py:95
|
#: apps/registration/views.py:98
|
||||||
msgid "Email validation"
|
msgid "Email validation"
|
||||||
msgstr "Validation de l'adresse mail"
|
msgstr "Validation de l'adresse mail"
|
||||||
|
|
||||||
#: apps/registration/views.py:97
|
#: apps/registration/views.py:100
|
||||||
msgid "Validate email"
|
msgid "Validate email"
|
||||||
msgstr "Valider l'adresse e-mail"
|
msgstr "Valider l'adresse e-mail"
|
||||||
|
|
||||||
#: apps/registration/views.py:141
|
#: apps/registration/views.py:144
|
||||||
msgid "Email validation unsuccessful"
|
msgid "Email validation unsuccessful"
|
||||||
msgstr "La validation de l'adresse mail a échoué"
|
msgstr "La validation de l'adresse mail a échoué"
|
||||||
|
|
||||||
#: apps/registration/views.py:152
|
#: apps/registration/views.py:155
|
||||||
msgid "Email validation email sent"
|
msgid "Email validation email sent"
|
||||||
msgstr "L'email de vérification de l'adresse email a bien été envoyé"
|
msgstr "L'email de vérification de l'adresse email a bien été envoyé"
|
||||||
|
|
||||||
#: apps/registration/views.py:160
|
#: apps/registration/views.py:163
|
||||||
msgid "Resend email validation link"
|
msgid "Resend email validation link"
|
||||||
msgstr "Renvoyer le lien de validation"
|
msgstr "Renvoyer le lien de validation"
|
||||||
|
|
||||||
#: apps/registration/views.py:178
|
#: apps/registration/views.py:181
|
||||||
msgid "Pre-registered users list"
|
msgid "Pre-registered users list"
|
||||||
msgstr "Liste des utilisateurs en attente d'inscription"
|
msgstr "Liste des utilisateurs en attente d'inscription"
|
||||||
|
|
||||||
#: apps/registration/views.py:202
|
#: apps/registration/views.py:205
|
||||||
msgid "Unregistered users"
|
msgid "Unregistered users"
|
||||||
msgstr "Utilisateurs en attente d'inscription"
|
msgstr "Utilisateurs en attente d'inscription"
|
||||||
|
|
||||||
#: apps/registration/views.py:215
|
#: apps/registration/views.py:218
|
||||||
msgid "Registration detail"
|
msgid "Registration detail"
|
||||||
msgstr "Détails de l'inscription"
|
msgstr "Détails de l'inscription"
|
||||||
|
|
||||||
#: apps/registration/views.py:278
|
#: apps/registration/views.py:282
|
||||||
msgid "You must join the BDE."
|
msgid "You must join the BDE."
|
||||||
msgstr "Vous devez adhérer au BDE."
|
msgstr "Vous devez adhérer au BDE."
|
||||||
|
|
||||||
#: apps/registration/views.py:302
|
#: apps/registration/views.py:306
|
||||||
msgid ""
|
msgid ""
|
||||||
"The entered amount is not enough for the memberships, should be at least {}"
|
"The entered amount is not enough for the memberships, should be at least {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Le montant crédité est trop faible pour adhérer, il doit être au minimum de "
|
"Le montant crédité est trop faible pour adhérer, il doit être au minimum de "
|
||||||
"{}"
|
"{}"
|
||||||
|
|
||||||
#: apps/registration/views.py:383
|
#: apps/registration/views.py:387
|
||||||
msgid "Invalidate pre-registration"
|
msgid "Invalidate pre-registration"
|
||||||
msgstr "Invalider l'inscription"
|
msgstr "Invalider l'inscription"
|
||||||
|
|
||||||
|
@ -2083,145 +2102,145 @@ msgstr "Invalider l'inscription"
|
||||||
msgid "Treasury"
|
msgid "Treasury"
|
||||||
msgstr "Trésorerie"
|
msgstr "Trésorerie"
|
||||||
|
|
||||||
#: apps/treasury/forms.py:25 apps/treasury/models.py:91
|
#: apps/treasury/forms.py:26 apps/treasury/models.py:94
|
||||||
#: apps/treasury/templates/treasury/invoice_form.html:22
|
#: apps/treasury/templates/treasury/invoice_form.html:22
|
||||||
msgid "This invoice is locked and can no longer be edited."
|
msgid "This invoice is locked and can no longer be edited."
|
||||||
msgstr "Cette facture est verrouillée et ne peut plus être éditée."
|
msgstr "Cette facture est verrouillée et ne peut plus être éditée."
|
||||||
|
|
||||||
#: apps/treasury/forms.py:99
|
#: apps/treasury/forms.py:100
|
||||||
msgid "Remittance is already closed."
|
msgid "Remittance is already closed."
|
||||||
msgstr "La remise est déjà fermée."
|
msgstr "La remise est déjà fermée."
|
||||||
|
|
||||||
#: apps/treasury/forms.py:104
|
#: apps/treasury/forms.py:105
|
||||||
msgid "You can't change the type of the remittance."
|
msgid "You can't change the type of the remittance."
|
||||||
msgstr "Vous ne pouvez pas changer le type de la remise."
|
msgstr "Vous ne pouvez pas changer le type de la remise."
|
||||||
|
|
||||||
#: apps/treasury/forms.py:124 apps/treasury/models.py:265
|
#: apps/treasury/forms.py:125 apps/treasury/models.py:268
|
||||||
#: apps/treasury/tables.py:97 apps/treasury/tables.py:105
|
#: apps/treasury/tables.py:97 apps/treasury/tables.py:105
|
||||||
#: apps/treasury/templates/treasury/invoice_list.html:16
|
#: apps/treasury/templates/treasury/invoice_list.html:16
|
||||||
#: apps/treasury/templates/treasury/remittance_list.html:16
|
#: apps/treasury/templates/treasury/remittance_list.html:16
|
||||||
#: apps/treasury/templates/treasury/sogecredit_list.html:16
|
#: apps/treasury/templates/treasury/sogecredit_list.html:17
|
||||||
msgid "Remittance"
|
msgid "Remittance"
|
||||||
msgstr "Remise"
|
msgstr "Remise"
|
||||||
|
|
||||||
#: apps/treasury/forms.py:125
|
#: apps/treasury/forms.py:126
|
||||||
msgid "No attached remittance"
|
msgid "No attached remittance"
|
||||||
msgstr "Pas de remise associée"
|
msgstr "Pas de remise associée"
|
||||||
|
|
||||||
#: apps/treasury/models.py:24
|
#: apps/treasury/models.py:27
|
||||||
msgid "Invoice identifier"
|
msgid "Invoice identifier"
|
||||||
msgstr "Numéro de facture"
|
msgstr "Numéro de facture"
|
||||||
|
|
||||||
#: apps/treasury/models.py:38
|
#: apps/treasury/models.py:41
|
||||||
msgid "BDE"
|
msgid "BDE"
|
||||||
msgstr "BDE"
|
msgstr "BDE"
|
||||||
|
|
||||||
#: apps/treasury/models.py:43
|
#: apps/treasury/models.py:46
|
||||||
msgid "Object"
|
msgid "Object"
|
||||||
msgstr "Objet"
|
msgstr "Objet"
|
||||||
|
|
||||||
#: apps/treasury/models.py:47
|
#: apps/treasury/models.py:50
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr "Description"
|
msgstr "Description"
|
||||||
|
|
||||||
#: apps/treasury/models.py:56
|
#: apps/treasury/models.py:59
|
||||||
msgid "Address"
|
msgid "Address"
|
||||||
msgstr "Adresse"
|
msgstr "Adresse"
|
||||||
|
|
||||||
#: apps/treasury/models.py:61 apps/treasury/models.py:191
|
#: apps/treasury/models.py:64 apps/treasury/models.py:194
|
||||||
msgid "Date"
|
msgid "Date"
|
||||||
msgstr "Date"
|
msgstr "Date"
|
||||||
|
|
||||||
#: apps/treasury/models.py:65
|
#: apps/treasury/models.py:68
|
||||||
msgid "Acquitted"
|
msgid "Acquitted"
|
||||||
msgstr "Acquittée"
|
msgstr "Acquittée"
|
||||||
|
|
||||||
#: apps/treasury/models.py:70
|
#: apps/treasury/models.py:73
|
||||||
msgid "Locked"
|
msgid "Locked"
|
||||||
msgstr "Verrouillée"
|
msgstr "Verrouillée"
|
||||||
|
|
||||||
#: apps/treasury/models.py:71
|
#: apps/treasury/models.py:74
|
||||||
msgid "An invoice can't be edited when it is locked."
|
msgid "An invoice can't be edited when it is locked."
|
||||||
msgstr "Une facture ne peut plus être modifiée si elle est verrouillée."
|
msgstr "Une facture ne peut plus être modifiée si elle est verrouillée."
|
||||||
|
|
||||||
#: apps/treasury/models.py:77
|
#: apps/treasury/models.py:80
|
||||||
msgid "tex source"
|
msgid "tex source"
|
||||||
msgstr "fichier TeX source"
|
msgstr "fichier TeX source"
|
||||||
|
|
||||||
#: apps/treasury/models.py:111 apps/treasury/models.py:127
|
#: apps/treasury/models.py:114 apps/treasury/models.py:130
|
||||||
msgid "invoice"
|
msgid "invoice"
|
||||||
msgstr "facture"
|
msgstr "facture"
|
||||||
|
|
||||||
#: apps/treasury/models.py:112
|
#: apps/treasury/models.py:115
|
||||||
msgid "invoices"
|
msgid "invoices"
|
||||||
msgstr "factures"
|
msgstr "factures"
|
||||||
|
|
||||||
#: apps/treasury/models.py:115
|
#: apps/treasury/models.py:118
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Invoice #{id}"
|
msgid "Invoice #{id}"
|
||||||
msgstr "Facture n°{id}"
|
msgstr "Facture n°{id}"
|
||||||
|
|
||||||
#: apps/treasury/models.py:132
|
#: apps/treasury/models.py:135
|
||||||
msgid "Designation"
|
msgid "Designation"
|
||||||
msgstr "Désignation"
|
msgstr "Désignation"
|
||||||
|
|
||||||
#: apps/treasury/models.py:138
|
#: apps/treasury/models.py:141
|
||||||
msgid "Quantity"
|
msgid "Quantity"
|
||||||
msgstr "Quantité"
|
msgstr "Quantité"
|
||||||
|
|
||||||
#: apps/treasury/models.py:143
|
#: apps/treasury/models.py:146
|
||||||
msgid "Unit price"
|
msgid "Unit price"
|
||||||
msgstr "Prix unitaire"
|
msgstr "Prix unitaire"
|
||||||
|
|
||||||
#: apps/treasury/models.py:159
|
#: apps/treasury/models.py:162
|
||||||
msgid "product"
|
msgid "product"
|
||||||
msgstr "produit"
|
msgstr "produit"
|
||||||
|
|
||||||
#: apps/treasury/models.py:160
|
#: apps/treasury/models.py:163
|
||||||
msgid "products"
|
msgid "products"
|
||||||
msgstr "produits"
|
msgstr "produits"
|
||||||
|
|
||||||
#: apps/treasury/models.py:180
|
#: apps/treasury/models.py:183
|
||||||
msgid "remittance type"
|
msgid "remittance type"
|
||||||
msgstr "type de remise"
|
msgstr "type de remise"
|
||||||
|
|
||||||
#: apps/treasury/models.py:181
|
#: apps/treasury/models.py:184
|
||||||
msgid "remittance types"
|
msgid "remittance types"
|
||||||
msgstr "types de remises"
|
msgstr "types de remises"
|
||||||
|
|
||||||
#: apps/treasury/models.py:202
|
#: apps/treasury/models.py:205
|
||||||
msgid "Comment"
|
msgid "Comment"
|
||||||
msgstr "Commentaire"
|
msgstr "Commentaire"
|
||||||
|
|
||||||
#: apps/treasury/models.py:207
|
#: apps/treasury/models.py:210
|
||||||
msgid "Closed"
|
msgid "Closed"
|
||||||
msgstr "Fermée"
|
msgstr "Fermée"
|
||||||
|
|
||||||
#: apps/treasury/models.py:211
|
#: apps/treasury/models.py:214
|
||||||
msgid "remittance"
|
msgid "remittance"
|
||||||
msgstr "remise"
|
msgstr "remise"
|
||||||
|
|
||||||
#: apps/treasury/models.py:212
|
#: apps/treasury/models.py:215
|
||||||
msgid "remittances"
|
msgid "remittances"
|
||||||
msgstr "remises"
|
msgstr "remises"
|
||||||
|
|
||||||
#: apps/treasury/models.py:245
|
#: apps/treasury/models.py:248
|
||||||
msgid "Remittance #{:d}: {}"
|
msgid "Remittance #{:d}: {}"
|
||||||
msgstr "Remise n°{:d} : {}"
|
msgstr "Remise n°{:d} : {}"
|
||||||
|
|
||||||
#: apps/treasury/models.py:269
|
#: apps/treasury/models.py:272
|
||||||
msgid "special transaction proxy"
|
msgid "special transaction proxy"
|
||||||
msgstr "proxy de transaction spéciale"
|
msgstr "proxy de transaction spéciale"
|
||||||
|
|
||||||
#: apps/treasury/models.py:270
|
#: apps/treasury/models.py:273
|
||||||
msgid "special transaction proxies"
|
msgid "special transaction proxies"
|
||||||
msgstr "proxys de transactions spéciales"
|
msgstr "proxys de transactions spéciales"
|
||||||
|
|
||||||
#: apps/treasury/models.py:295
|
#: apps/treasury/models.py:299
|
||||||
msgid "credit transaction"
|
msgid "credit transaction"
|
||||||
msgstr "transaction de crédit"
|
msgstr "transaction de crédit"
|
||||||
|
|
||||||
#: apps/treasury/models.py:379
|
#: apps/treasury/models.py:418
|
||||||
msgid ""
|
msgid ""
|
||||||
"This user doesn't have enough money to pay the memberships with its note. "
|
"This user doesn't have enough money to pay the memberships with its note. "
|
||||||
"Please ask her/him to credit the note before invalidating this credit."
|
"Please ask her/him to credit the note before invalidating this credit."
|
||||||
|
@ -2229,16 +2248,16 @@ msgstr ""
|
||||||
"Cet utilisateur n'a pas assez d'argent pour payer les adhésions avec sa "
|
"Cet utilisateur n'a pas assez d'argent pour payer les adhésions avec sa "
|
||||||
"note. Merci de lui demander de recharger sa note avant d'invalider ce crédit."
|
"note. Merci de lui demander de recharger sa note avant d'invalider ce crédit."
|
||||||
|
|
||||||
#: apps/treasury/models.py:399
|
#: apps/treasury/models.py:438
|
||||||
#: apps/treasury/templates/treasury/sogecredit_detail.html:10
|
#: apps/treasury/templates/treasury/sogecredit_detail.html:10
|
||||||
msgid "Credit from the Société générale"
|
msgid "Credit from the Société générale"
|
||||||
msgstr "Crédit de la Société générale"
|
msgstr "Crédit de la Société générale"
|
||||||
|
|
||||||
#: apps/treasury/models.py:400
|
#: apps/treasury/models.py:439
|
||||||
msgid "Credits from the Société générale"
|
msgid "Credits from the Société générale"
|
||||||
msgstr "Crédits de la Société générale"
|
msgstr "Crédits de la Société générale"
|
||||||
|
|
||||||
#: apps/treasury/models.py:403
|
#: apps/treasury/models.py:442
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Soge credit for {user}"
|
msgid "Soge credit for {user}"
|
||||||
msgstr "Crédit de la société générale pour l'utilisateur {user}"
|
msgstr "Crédit de la société générale pour l'utilisateur {user}"
|
||||||
|
@ -2250,7 +2269,7 @@ msgstr "Facture n°{:d}"
|
||||||
#: apps/treasury/tables.py:25
|
#: apps/treasury/tables.py:25
|
||||||
#: apps/treasury/templates/treasury/invoice_list.html:13
|
#: apps/treasury/templates/treasury/invoice_list.html:13
|
||||||
#: apps/treasury/templates/treasury/remittance_list.html:13
|
#: apps/treasury/templates/treasury/remittance_list.html:13
|
||||||
#: apps/treasury/templates/treasury/sogecredit_list.html:13
|
#: apps/treasury/templates/treasury/sogecredit_list.html:14
|
||||||
msgid "Invoice"
|
msgid "Invoice"
|
||||||
msgstr "Facture"
|
msgstr "Facture"
|
||||||
|
|
||||||
|
@ -2267,12 +2286,12 @@ msgid "Yes"
|
||||||
msgstr "Oui"
|
msgstr "Oui"
|
||||||
|
|
||||||
#: apps/treasury/templates/treasury/invoice_confirm_delete.html:10
|
#: apps/treasury/templates/treasury/invoice_confirm_delete.html:10
|
||||||
#: apps/treasury/views.py:179
|
#: apps/treasury/views.py:180
|
||||||
msgid "Delete invoice"
|
msgid "Delete invoice"
|
||||||
msgstr "Supprimer la facture"
|
msgstr "Supprimer la facture"
|
||||||
|
|
||||||
#: apps/treasury/templates/treasury/invoice_confirm_delete.html:15
|
#: apps/treasury/templates/treasury/invoice_confirm_delete.html:15
|
||||||
#: apps/treasury/views.py:183
|
#: apps/treasury/views.py:184
|
||||||
msgid "This invoice is locked and can't be deleted."
|
msgid "This invoice is locked and can't be deleted."
|
||||||
msgstr "Cette facture est verrouillée et ne peut pas être supprimée."
|
msgstr "Cette facture est verrouillée et ne peut pas être supprimée."
|
||||||
|
|
||||||
|
@ -2306,7 +2325,7 @@ msgstr "Retirer produit"
|
||||||
|
|
||||||
#: apps/treasury/templates/treasury/invoice_list.html:19
|
#: apps/treasury/templates/treasury/invoice_list.html:19
|
||||||
#: apps/treasury/templates/treasury/remittance_list.html:19
|
#: apps/treasury/templates/treasury/remittance_list.html:19
|
||||||
#: apps/treasury/templates/treasury/sogecredit_list.html:19
|
#: apps/treasury/templates/treasury/sogecredit_list.html:20
|
||||||
msgid "Société générale credits"
|
msgid "Société générale credits"
|
||||||
msgstr "Crédits de la Société générale"
|
msgstr "Crédits de la Société générale"
|
||||||
|
|
||||||
|
@ -2426,54 +2445,62 @@ msgstr "Valider"
|
||||||
msgid "Return to credit list"
|
msgid "Return to credit list"
|
||||||
msgstr "Retour à la liste des crédits"
|
msgstr "Retour à la liste des crédits"
|
||||||
|
|
||||||
#: apps/treasury/templates/treasury/sogecredit_list.html:34
|
#: apps/treasury/templates/treasury/sogecredit_list.html:40
|
||||||
msgid "Filter with unvalidated credits only"
|
msgid "Filter with unvalidated credits only"
|
||||||
msgstr "Filtrer avec uniquement les crédits non valides"
|
msgstr "Filtrer avec uniquement les crédits non valides"
|
||||||
|
|
||||||
#: apps/treasury/templates/treasury/sogecredit_list.html:44
|
#: apps/treasury/templates/treasury/sogecredit_list.html:50
|
||||||
msgid "There is no matched user that have asked for a Société générale credit."
|
msgid "There is no matched user that have asked for a Société générale credit."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Il n'y a pas d'utilisateur trouvé ayant demandé un crédit de la Société "
|
"Il n'y a pas d'utilisateur trouvé ayant demandé un crédit de la Société "
|
||||||
"générale."
|
"générale."
|
||||||
|
|
||||||
#: apps/treasury/views.py:39
|
#: apps/treasury/templates/treasury/sogecredit_list.html:63
|
||||||
|
msgid "Add credit from the Société générale"
|
||||||
|
msgstr "Ajouter un crédit de la Société générale"
|
||||||
|
|
||||||
|
#: apps/treasury/templates/treasury/sogecredit_list.html:109
|
||||||
|
msgid "Credit successfully registered"
|
||||||
|
msgstr "Le crédit a bien été enregistré"
|
||||||
|
|
||||||
|
#: apps/treasury/views.py:40
|
||||||
msgid "Create new invoice"
|
msgid "Create new invoice"
|
||||||
msgstr "Créer une nouvelle facture"
|
msgstr "Créer une nouvelle facture"
|
||||||
|
|
||||||
#: apps/treasury/views.py:96
|
#: apps/treasury/views.py:97
|
||||||
msgid "Invoices list"
|
msgid "Invoices list"
|
||||||
msgstr "Liste des factures"
|
msgstr "Liste des factures"
|
||||||
|
|
||||||
#: apps/treasury/views.py:111 apps/treasury/views.py:285
|
#: apps/treasury/views.py:112 apps/treasury/views.py:286
|
||||||
#: apps/treasury/views.py:411
|
#: apps/treasury/views.py:412
|
||||||
msgid "You are not able to see the treasury interface."
|
msgid "You are not able to see the treasury interface."
|
||||||
msgstr "Vous n'êtes pas autorisé à voir l'interface de trésorerie."
|
msgstr "Vous n'êtes pas autorisé à voir l'interface de trésorerie."
|
||||||
|
|
||||||
#: apps/treasury/views.py:121
|
#: apps/treasury/views.py:122
|
||||||
msgid "Update an invoice"
|
msgid "Update an invoice"
|
||||||
msgstr "Modifier la facture"
|
msgstr "Modifier la facture"
|
||||||
|
|
||||||
#: apps/treasury/views.py:246
|
#: apps/treasury/views.py:247
|
||||||
msgid "Create a new remittance"
|
msgid "Create a new remittance"
|
||||||
msgstr "Créer une nouvelle remise"
|
msgstr "Créer une nouvelle remise"
|
||||||
|
|
||||||
#: apps/treasury/views.py:273
|
#: apps/treasury/views.py:274
|
||||||
msgid "Remittances list"
|
msgid "Remittances list"
|
||||||
msgstr "Liste des remises"
|
msgstr "Liste des remises"
|
||||||
|
|
||||||
#: apps/treasury/views.py:336
|
#: apps/treasury/views.py:337
|
||||||
msgid "Update a remittance"
|
msgid "Update a remittance"
|
||||||
msgstr "Modifier la remise"
|
msgstr "Modifier la remise"
|
||||||
|
|
||||||
#: apps/treasury/views.py:359
|
#: apps/treasury/views.py:360
|
||||||
msgid "Attach a transaction to a remittance"
|
msgid "Attach a transaction to a remittance"
|
||||||
msgstr "Joindre une transaction à une remise"
|
msgstr "Joindre une transaction à une remise"
|
||||||
|
|
||||||
#: apps/treasury/views.py:403
|
#: apps/treasury/views.py:404
|
||||||
msgid "List of credits from the Société générale"
|
msgid "List of credits from the Société générale"
|
||||||
msgstr "Liste des crédits de la Société générale"
|
msgstr "Liste des crédits de la Société générale"
|
||||||
|
|
||||||
#: apps/treasury/views.py:443
|
#: apps/treasury/views.py:449
|
||||||
msgid "Manage credits from the Société générale"
|
msgid "Manage credits from the Société générale"
|
||||||
msgstr "Gérer les crédits de la Société générale"
|
msgstr "Gérer les crédits de la Société générale"
|
||||||
|
|
||||||
|
@ -2483,12 +2510,18 @@ msgstr "Gérer les crédits de la Société générale"
|
||||||
msgid "WEI"
|
msgid "WEI"
|
||||||
msgstr "WEI"
|
msgstr "WEI"
|
||||||
|
|
||||||
#: apps/wei/forms/registration.py:51 apps/wei/models.py:118
|
#: apps/wei/forms/registration.py:35
|
||||||
|
msgid "The selected user is not validated. Please validate its account first"
|
||||||
|
msgstr ""
|
||||||
|
"L'utilisateur sélectionné n'est pas validé. Merci de d'abord valider son "
|
||||||
|
"compte."
|
||||||
|
|
||||||
|
#: apps/wei/forms/registration.py:60 apps/wei/models.py:118
|
||||||
#: apps/wei/models.py:315
|
#: apps/wei/models.py:315
|
||||||
msgid "bus"
|
msgid "bus"
|
||||||
msgstr "bus"
|
msgstr "bus"
|
||||||
|
|
||||||
#: apps/wei/forms/registration.py:52
|
#: apps/wei/forms/registration.py:61
|
||||||
msgid ""
|
msgid ""
|
||||||
"This choice is not definitive. The WEI organizers are free to attribute for "
|
"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."
|
"you a bus and a team, in particular if you are a free eletron."
|
||||||
|
@ -2497,11 +2530,11 @@ msgstr ""
|
||||||
"attribuer un bus et une équipe, en particulier si vous êtes un électron "
|
"attribuer un bus et une équipe, en particulier si vous êtes un électron "
|
||||||
"libre."
|
"libre."
|
||||||
|
|
||||||
#: apps/wei/forms/registration.py:59
|
#: apps/wei/forms/registration.py:68
|
||||||
msgid "Team"
|
msgid "Team"
|
||||||
msgstr "Équipe"
|
msgstr "Équipe"
|
||||||
|
|
||||||
#: apps/wei/forms/registration.py:61
|
#: apps/wei/forms/registration.py:70
|
||||||
msgid ""
|
msgid ""
|
||||||
"Leave this field empty if you won't be in a team (staff, bus chief, free "
|
"Leave this field empty if you won't be in a team (staff, bus chief, free "
|
||||||
"electron)"
|
"electron)"
|
||||||
|
@ -2509,16 +2542,16 @@ msgstr ""
|
||||||
"Laissez ce champ vide si vous ne serez pas dans une équipe (staff, chef de "
|
"Laissez ce champ vide si vous ne serez pas dans une équipe (staff, chef de "
|
||||||
"bus ou électron libre)"
|
"bus ou électron libre)"
|
||||||
|
|
||||||
#: apps/wei/forms/registration.py:67 apps/wei/forms/registration.py:77
|
#: apps/wei/forms/registration.py:76 apps/wei/forms/registration.py:86
|
||||||
#: apps/wei/models.py:153
|
#: apps/wei/models.py:153
|
||||||
msgid "WEI Roles"
|
msgid "WEI Roles"
|
||||||
msgstr "Rôles au WEI"
|
msgstr "Rôles au WEI"
|
||||||
|
|
||||||
#: apps/wei/forms/registration.py:68
|
#: apps/wei/forms/registration.py:77
|
||||||
msgid "Select the roles that you are interested in."
|
msgid "Select the roles that you are interested in."
|
||||||
msgstr "Sélectionnez les rôles qui vous intéressent."
|
msgstr "Sélectionnez les rôles qui vous intéressent."
|
||||||
|
|
||||||
#: apps/wei/forms/registration.py:113
|
#: apps/wei/forms/registration.py:122
|
||||||
msgid "This team doesn't belong to the given bus."
|
msgid "This team doesn't belong to the given bus."
|
||||||
msgstr "Cette équipe n'appartient pas à ce bus."
|
msgstr "Cette équipe n'appartient pas à ce bus."
|
||||||
|
|
||||||
|
@ -2677,23 +2710,29 @@ msgid "The user does not have enough money."
|
||||||
msgstr "L'utilisateur n'a pas assez d'argent."
|
msgstr "L'utilisateur n'a pas assez d'argent."
|
||||||
|
|
||||||
#: apps/wei/tables.py:107
|
#: apps/wei/tables.py:107
|
||||||
|
msgid "The user is in first year, and the repartition algorithm didn't run."
|
||||||
|
msgstr ""
|
||||||
|
"L'utilisateur est en première année, et l'algorithme de répartition n'a pas "
|
||||||
|
"tourné."
|
||||||
|
|
||||||
|
#: apps/wei/tables.py:110
|
||||||
msgid "The user has enough money, you can validate the registration."
|
msgid "The user has enough money, you can validate the registration."
|
||||||
msgstr "L'utilisateur a assez d'argent, l'inscription est possible."
|
msgstr "L'utilisateur a assez d'argent, l'inscription est possible."
|
||||||
|
|
||||||
#: apps/wei/tables.py:139
|
#: apps/wei/tables.py:142
|
||||||
msgid "Year"
|
msgid "Year"
|
||||||
msgstr "Année"
|
msgstr "Année"
|
||||||
|
|
||||||
#: apps/wei/tables.py:177 apps/wei/templates/wei/bus_detail.html:32
|
#: apps/wei/tables.py:180 apps/wei/templates/wei/bus_detail.html:32
|
||||||
#: apps/wei/templates/wei/busteam_detail.html:50
|
#: apps/wei/templates/wei/busteam_detail.html:50
|
||||||
msgid "Teams"
|
msgid "Teams"
|
||||||
msgstr "Équipes"
|
msgstr "Équipes"
|
||||||
|
|
||||||
#: apps/wei/tables.py:186 apps/wei/tables.py:227
|
#: apps/wei/tables.py:189 apps/wei/tables.py:230
|
||||||
msgid "Members count"
|
msgid "Members count"
|
||||||
msgstr "Nombre de membres"
|
msgstr "Nombre de membres"
|
||||||
|
|
||||||
#: apps/wei/tables.py:193 apps/wei/tables.py:224
|
#: apps/wei/tables.py:196 apps/wei/tables.py:227
|
||||||
msgid "members"
|
msgid "members"
|
||||||
msgstr "adhérents"
|
msgstr "adhérents"
|
||||||
|
|
||||||
|
@ -2713,11 +2752,11 @@ msgstr "Prix du WEI (étudiants)"
|
||||||
msgid "WEI list"
|
msgid "WEI list"
|
||||||
msgstr "Liste des WEI"
|
msgstr "Liste des WEI"
|
||||||
|
|
||||||
#: apps/wei/templates/wei/base.html:81 apps/wei/views.py:510
|
#: apps/wei/templates/wei/base.html:81 apps/wei/views.py:517
|
||||||
msgid "Register 1A"
|
msgid "Register 1A"
|
||||||
msgstr "Inscrire un 1A"
|
msgstr "Inscrire un 1A"
|
||||||
|
|
||||||
#: apps/wei/templates/wei/base.html:85 apps/wei/views.py:578
|
#: apps/wei/templates/wei/base.html:85 apps/wei/views.py:592
|
||||||
msgid "Register 2A+"
|
msgid "Register 2A+"
|
||||||
msgstr "Inscrire un 2A+"
|
msgstr "Inscrire un 2A+"
|
||||||
|
|
||||||
|
@ -2746,8 +2785,8 @@ msgstr "Télécharger au format PDF"
|
||||||
|
|
||||||
#: apps/wei/templates/wei/survey.html:11
|
#: apps/wei/templates/wei/survey.html:11
|
||||||
#: apps/wei/templates/wei/survey_closed.html:11
|
#: apps/wei/templates/wei/survey_closed.html:11
|
||||||
#: apps/wei/templates/wei/survey_end.html:11 apps/wei/views.py:973
|
#: apps/wei/templates/wei/survey_end.html:11 apps/wei/views.py:988
|
||||||
#: apps/wei/views.py:1028 apps/wei/views.py:1038
|
#: apps/wei/views.py:1043 apps/wei/views.py:1053
|
||||||
msgid "Survey WEI"
|
msgid "Survey WEI"
|
||||||
msgstr "Questionnaire WEI"
|
msgstr "Questionnaire WEI"
|
||||||
|
|
||||||
|
@ -2985,11 +3024,11 @@ msgstr "Gérer l'équipe WEI"
|
||||||
msgid "Register first year student to the WEI"
|
msgid "Register first year student to the WEI"
|
||||||
msgstr "Inscrire un 1A au WEI"
|
msgstr "Inscrire un 1A au WEI"
|
||||||
|
|
||||||
#: apps/wei/views.py:532 apps/wei/views.py:613
|
#: apps/wei/views.py:539 apps/wei/views.py:627
|
||||||
msgid "This user is already registered to this WEI."
|
msgid "This user is already registered to this WEI."
|
||||||
msgstr "Cette personne est déjà inscrite au WEI."
|
msgstr "Cette personne est déjà inscrite au WEI."
|
||||||
|
|
||||||
#: apps/wei/views.py:537
|
#: apps/wei/views.py:544
|
||||||
msgid ""
|
msgid ""
|
||||||
"This user can't be in her/his first year since he/she has already "
|
"This user can't be in her/his first year since he/she has already "
|
||||||
"participated to a WEI."
|
"participated to a WEI."
|
||||||
|
@ -2997,27 +3036,27 @@ msgstr ""
|
||||||
"Cet utilisateur ne peut pas être en première année puisqu'il a déjà "
|
"Cet utilisateur ne peut pas être en première année puisqu'il a déjà "
|
||||||
"participé à un WEI."
|
"participé à un WEI."
|
||||||
|
|
||||||
#: apps/wei/views.py:554
|
#: apps/wei/views.py:561
|
||||||
msgid "Register old student to the WEI"
|
msgid "Register old student to the WEI"
|
||||||
msgstr "Inscrire un 2A+ au WEI"
|
msgstr "Inscrire un 2A+ au WEI"
|
||||||
|
|
||||||
#: apps/wei/views.py:597 apps/wei/views.py:686
|
#: apps/wei/views.py:611 apps/wei/views.py:700
|
||||||
msgid "You already opened an account in the Société générale."
|
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."
|
msgstr "Vous avez déjà ouvert un compte auprès de la société générale."
|
||||||
|
|
||||||
#: apps/wei/views.py:643
|
#: apps/wei/views.py:657
|
||||||
msgid "Update WEI Registration"
|
msgid "Update WEI Registration"
|
||||||
msgstr "Modifier l'inscription WEI"
|
msgstr "Modifier l'inscription WEI"
|
||||||
|
|
||||||
#: apps/wei/views.py:746
|
#: apps/wei/views.py:761
|
||||||
msgid "Delete WEI registration"
|
msgid "Delete WEI registration"
|
||||||
msgstr "Supprimer l'inscription WEI"
|
msgstr "Supprimer l'inscription WEI"
|
||||||
|
|
||||||
#: apps/wei/views.py:757
|
#: apps/wei/views.py:772
|
||||||
msgid "You don't have the right to delete this WEI registration."
|
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."
|
msgstr "Vous n'avez pas la permission de supprimer cette inscription au WEI."
|
||||||
|
|
||||||
#: apps/wei/views.py:776
|
#: apps/wei/views.py:791
|
||||||
msgid "Validate WEI registration"
|
msgid "Validate WEI registration"
|
||||||
msgstr "Valider l'inscription WEI"
|
msgstr "Valider l'inscription WEI"
|
||||||
|
|
||||||
|
@ -3141,13 +3180,7 @@ msgstr ""
|
||||||
"Vous n'êtes plus adhérent BDE. Merci de réadhérer si vous voulez profiter de "
|
"Vous n'êtes plus adhérent BDE. Merci de réadhérer si vous voulez profiter de "
|
||||||
"la note."
|
"la note."
|
||||||
|
|
||||||
#: note_kfet/templates/base.html:164
|
#: note_kfet/templates/base.html:166
|
||||||
msgid "You are not a Kfet member, so you can't use your note account."
|
|
||||||
msgstr ""
|
|
||||||
"Vous n'êtes pas adhérent Kfet, vous ne pouvez par conséquent pas utiliser "
|
|
||||||
"votre compte note."
|
|
||||||
|
|
||||||
#: note_kfet/templates/base.html:170
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Your e-mail address is not validated. Please check your mail inbox and click "
|
"Your e-mail address is not validated. Please check your mail inbox and click "
|
||||||
"on the validation link."
|
"on the validation link."
|
||||||
|
@ -3155,7 +3188,7 @@ msgstr ""
|
||||||
"Votre adresse e-mail n'est pas validée. Merci de vérifier votre boîte mail "
|
"Votre adresse e-mail n'est pas validée. Merci de vérifier votre boîte mail "
|
||||||
"et de cliquer sur le lien de validation."
|
"et de cliquer sur le lien de validation."
|
||||||
|
|
||||||
#: note_kfet/templates/base.html:176
|
#: note_kfet/templates/base.html:172
|
||||||
msgid ""
|
msgid ""
|
||||||
"You declared that you opened a bank account in the Société générale. The "
|
"You declared that you opened a bank account in the Société générale. The "
|
||||||
"bank did not validate the creation of the account to the BDE, so the "
|
"bank did not validate the creation of the account to the BDE, so the "
|
||||||
|
@ -3170,7 +3203,7 @@ msgstr ""
|
||||||
"durer quelques jours. Merci de vous assurer de bien aller au bout de vos "
|
"durer quelques jours. Merci de vous assurer de bien aller au bout de vos "
|
||||||
"démarches."
|
"démarches."
|
||||||
|
|
||||||
#: note_kfet/templates/base.html:199
|
#: note_kfet/templates/base.html:195
|
||||||
msgid "Contact us"
|
msgid "Contact us"
|
||||||
msgstr "Nous contacter"
|
msgstr "Nous contacter"
|
||||||
|
|
||||||
|
@ -3218,9 +3251,10 @@ msgid ""
|
||||||
"link templates and convert permissions to scope numbers with the permissions "
|
"link templates and convert permissions to scope numbers with the permissions "
|
||||||
"that you want to grant for your application."
|
"that you want to grant for your application."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Vous pouvez aller <a href=\"%(scopes_url)s\">ici</a> pour générer des modèles "
|
"Vous pouvez aller <a href=\"%(scopes_url)s\">ici</a> pour générer des "
|
||||||
"de liens d'autorisation et convertir des permissions en identifiants de "
|
"modèles de liens d'autorisation et convertir des permissions en identifiants "
|
||||||
"scopes avec les permissions que vous souhaitez attribuer à votre application."
|
"de scopes avec les permissions que vous souhaitez attribuer à votre "
|
||||||
|
"application."
|
||||||
|
|
||||||
#: note_kfet/templates/oauth2_provider/application_detail.html:37
|
#: note_kfet/templates/oauth2_provider/application_detail.html:37
|
||||||
#: note_kfet/templates/oauth2_provider/application_form.html:23
|
#: note_kfet/templates/oauth2_provider/application_form.html:23
|
||||||
|
@ -3400,3 +3434,8 @@ msgstr ""
|
||||||
"vous connecter. Vous devez vous rendre à la Kfet et payer les frais "
|
"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 "
|
"d'adhésion. Vous devez également valider votre adresse email en suivant le "
|
||||||
"lien que vous avez reçu."
|
"lien que vous avez reçu."
|
||||||
|
|
||||||
|
#~ msgid "You are not a Kfet member, so you can't use your note account."
|
||||||
|
#~ msgstr ""
|
||||||
|
#~ "Vous n'êtes pas adhérent Kfet, vous ne pouvez par conséquent pas utiliser "
|
||||||
|
#~ "votre compte note."
|
||||||
|
|
|
@ -75,7 +75,7 @@ class LoginByIPMiddleware(object):
|
||||||
else:
|
else:
|
||||||
ip = request.META.get('REMOTE_ADDR')
|
ip = request.META.get('REMOTE_ADDR')
|
||||||
|
|
||||||
qs = User.objects.filter(password=f"ipbased${ip}")
|
qs = User.objects.filter(password__iregex=f"ipbased\\$.*\\^{ip}\\$.*")
|
||||||
if qs.exists():
|
if qs.exists():
|
||||||
login(request, qs.get())
|
login(request, qs.get())
|
||||||
session = request.session
|
session = request.session
|
||||||
|
|
Loading…
Reference in New Issue