mirror of
https://gitlab.crans.org/bde/nk20
synced 2024-11-26 18:37:12 +00:00
Merge branch 'beta' into JS_translations
# Conflicts: # apps/note/static/note/js/consos.js # locale/de/LC_MESSAGES/django.po # locale/es/LC_MESSAGES/django.po # locale/fr/LC_MESSAGES/django.po
This commit is contained in:
commit
8434c0062c
@ -16,8 +16,8 @@ py37-django22:
|
||||
apt-get install --no-install-recommends -t buster-backports -y
|
||||
python3-django python3-django-crispy-forms
|
||||
python3-django-extensions python3-django-filters python3-django-polymorphic
|
||||
python3-djangorestframework python3-django-cas-server python3-psycopg2 python3-pil
|
||||
python3-babel python3-lockfile python3-pip python3-phonenumbers
|
||||
python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
|
||||
python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
|
||||
python3-bs4 python3-setuptools tox texlive-xetex
|
||||
script: tox -e py37-django22
|
||||
|
||||
@ -33,8 +33,8 @@ py38-django22:
|
||||
apt-get install --no-install-recommends -y
|
||||
python3-django python3-django-crispy-forms
|
||||
python3-django-extensions python3-django-filters python3-django-polymorphic
|
||||
python3-djangorestframework python3-django-cas-server python3-psycopg2 python3-pil
|
||||
python3-babel python3-lockfile python3-pip python3-phonenumbers
|
||||
python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
|
||||
python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
|
||||
python3-bs4 python3-setuptools tox texlive-xetex
|
||||
script: tox -e py38-django22
|
||||
|
||||
|
@ -8,8 +8,8 @@ RUN apt-get update && \
|
||||
apt-get install --no-install-recommends -t buster-backports -y \
|
||||
python3-django python3-django-crispy-forms \
|
||||
python3-django-extensions python3-django-filters python3-django-polymorphic \
|
||||
python3-djangorestframework python3-django-cas-server python3-psycopg2 python3-pil \
|
||||
python3-babel python3-lockfile python3-pip python3-phonenumbers ipython3 \
|
||||
python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil \
|
||||
python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache ipython3 \
|
||||
python3-bs4 python3-setuptools \
|
||||
uwsgi uwsgi-plugin-python3 \
|
||||
texlive-xetex gettext libjs-bootstrap4 fonts-font-awesome && \
|
||||
|
@ -93,10 +93,10 @@ Sinon vous pouvez suivre les étapes décrites ci-dessous.
|
||||
$ sudo apt install --no-install-recommends -t buster-backports -y \
|
||||
python3-django python3-django-crispy-forms \
|
||||
python3-django-extensions python3-django-filters python3-django-polymorphic \
|
||||
python3-djangorestframework python3-django-cas-server python3-psycopg2 python3-pil \
|
||||
python3-babel python3-lockfile python3-pip python3-phonenumbers ipython3 \
|
||||
python3-bs4 python3-setuptools \
|
||||
uwsgi uwsgi-plugin-python3 \
|
||||
python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil \
|
||||
python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache ipython3 \
|
||||
python3-bs4 python3-setuptools python3-docutils \
|
||||
memcached uwsgi uwsgi-plugin-python3 \
|
||||
texlive-xetex gettext libjs-bootstrap4 fonts-font-awesome \
|
||||
nginx python3-venv git acl
|
||||
```
|
||||
|
@ -23,13 +23,14 @@
|
||||
- python3-babel
|
||||
- python3-bs4
|
||||
- python3-django
|
||||
- python3-django-cas-server
|
||||
- python3-django-crispy-forms
|
||||
- python3-django-extensions
|
||||
- python3-django-filters
|
||||
- python3-django-oauth-toolkit
|
||||
- python3-django-polymorphic
|
||||
- python3-djangorestframework
|
||||
- python3-lockfile
|
||||
- python3-memcache
|
||||
- python3-phonenumbers
|
||||
- python3-pil
|
||||
- python3-pip
|
||||
@ -40,6 +41,9 @@
|
||||
# LaTeX (PDF generation)
|
||||
- texlive-xetex
|
||||
|
||||
# Cache server
|
||||
- memcached
|
||||
|
||||
# WSGI server
|
||||
- uwsgi
|
||||
- uwsgi-plugin-python3
|
||||
|
@ -12,8 +12,10 @@ from django.db.models import F, Q
|
||||
from django.http import HttpResponse
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils import timezone
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views import View
|
||||
from django.views.decorators.cache import cache_page
|
||||
from django.views.generic import DetailView, TemplateView, UpdateView
|
||||
from django_tables2.views import SingleTableView
|
||||
from note.models import Alias, NoteSpecial, NoteUser
|
||||
@ -288,6 +290,8 @@ class ActivityEntryView(LoginRequiredMixin, TemplateView):
|
||||
return context
|
||||
|
||||
|
||||
# Cache for 1 hour
|
||||
@method_decorator(cache_page(60 * 60), name='dispatch')
|
||||
class CalendarView(View):
|
||||
"""
|
||||
Render an ICS calendar with all valid activities.
|
||||
|
@ -150,6 +150,7 @@ class ClubForm(forms.ModelForm):
|
||||
"membership_fee_unpaid": AmountInput(),
|
||||
"parent_club": Autocomplete(
|
||||
Club,
|
||||
resetable=True,
|
||||
attrs={
|
||||
'api_url': '/api/members/club/',
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ def create_bde_and_kfet(apps, schema_editor):
|
||||
"""
|
||||
Club = apps.get_model("member", "club")
|
||||
NoteClub = apps.get_model("note", "noteclub")
|
||||
Alias = apps.get_model("note", "alias")
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
polymorphic_ctype_id = ContentType.objects.get_for_model(NoteClub).id
|
||||
|
||||
@ -45,6 +46,19 @@ def create_bde_and_kfet(apps, schema_editor):
|
||||
polymorphic_ctype_id=polymorphic_ctype_id,
|
||||
)
|
||||
|
||||
Alias.objects.get_or_create(
|
||||
id=5,
|
||||
note_id=5,
|
||||
name="BDE",
|
||||
normalized_name="bde",
|
||||
)
|
||||
Alias.objects.get_or_create(
|
||||
id=6,
|
||||
note_id=6,
|
||||
name="Kfet",
|
||||
normalized_name="kfet",
|
||||
)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
|
@ -0,0 +1,50 @@
|
||||
import sys
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
def give_note_account_permissions(apps, schema_editor):
|
||||
"""
|
||||
Automatically manage the membership of the Note account.
|
||||
"""
|
||||
User = apps.get_model("auth", "user")
|
||||
Membership = apps.get_model("member", "membership")
|
||||
Role = apps.get_model("permission", "role")
|
||||
|
||||
note = User.objects.filter(username="note")
|
||||
if not note.exists():
|
||||
# We are in a test environment, don't log error message
|
||||
if len(sys.argv) > 1 and sys.argv[1] == 'test':
|
||||
return
|
||||
print("Warning: Note account was not found. The note account was not imported.")
|
||||
print("Make sure you have imported the NK15 database. The new import script handles correctly the permissions.")
|
||||
print("This migration will be ignored, you can re-run it if you forgot the note account or ignore it if you "
|
||||
"don't want this account.")
|
||||
return
|
||||
|
||||
note = note.get()
|
||||
|
||||
# Set for the two clubs a large expiration date and the correct role.
|
||||
for m in Membership.objects.filter(user_id=note.id).all():
|
||||
m.date_end = "3142-12-12"
|
||||
m.roles.set(Role.objects.filter(name="PC Kfet").all())
|
||||
m.save()
|
||||
# By default, the note account is only authorized to be logged from localhost.
|
||||
note.password = "ipbased$127.0.0.1"
|
||||
note.is_active = True
|
||||
note.save()
|
||||
# Ensure that the note of the account is disabled
|
||||
note.note.inactivity_reason = 'forced'
|
||||
note.note.is_active = False
|
||||
note.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
('member', '0005_remove_null_tag_on_charfields'),
|
||||
('permission', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(give_note_account_permissions),
|
||||
]
|
@ -43,8 +43,24 @@ class UserTable(tables.Table):
|
||||
|
||||
section = tables.Column(accessor='profile__section')
|
||||
|
||||
# Override the column to let replace the URL
|
||||
email = tables.EmailColumn(linkify=lambda record: "mailto:{}".format(record.email))
|
||||
|
||||
balance = tables.Column(accessor='note__balance', verbose_name=_("Balance"))
|
||||
|
||||
def render_email(self, record, value):
|
||||
# Replace the email by a dash if the user can't see the profile detail
|
||||
# Replace also the URL
|
||||
if not PermissionBackend.check_perm(get_current_authenticated_user(), "member.view_profile", record.profile):
|
||||
value = "—"
|
||||
record.email = value
|
||||
return value
|
||||
|
||||
def render_section(self, record, value):
|
||||
return value \
|
||||
if PermissionBackend.check_perm(get_current_authenticated_user(), "member.view_profile", record.profile) \
|
||||
else "—"
|
||||
|
||||
def render_balance(self, record, value):
|
||||
return pretty_money(value)\
|
||||
if PermissionBackend.check_perm(get_current_authenticated_user(), "note.view_note", record.note) else "—"
|
||||
@ -112,7 +128,7 @@ class MembershipTable(tables.Table):
|
||||
fee=0,
|
||||
)
|
||||
if PermissionBackend.check_perm(get_current_authenticated_user(),
|
||||
"member:add_membership", empty_membership): # If the user has right
|
||||
"member.add_membership", empty_membership): # If the user has right
|
||||
renew_url = reverse_lazy('member:club_renew_membership',
|
||||
kwargs={"pk": record.pk})
|
||||
t = format_html(
|
||||
|
@ -25,25 +25,27 @@
|
||||
</a>
|
||||
</dd>
|
||||
|
||||
<dt class="col-xl-6">{% trans 'section'|capfirst %}</dt>
|
||||
<dd class="col-xl-6">{{ user_object.profile.section }}</dd>
|
||||
{% if "member.view_profile"|has_perm:user_object.profile %}
|
||||
<dt class="col-xl-6">{% trans 'section'|capfirst %}</dt>
|
||||
<dd class="col-xl-6">{{ user_object.profile.section }}</dd>
|
||||
|
||||
<dt class="col-xl-6">{% trans 'email'|capfirst %}</dt>
|
||||
<dd class="col-xl-6"><a href="mailto:{{ user_object.email }}">{{ user_object.email }}</a></dd>
|
||||
<dt class="col-xl-6">{% trans 'email'|capfirst %}</dt>
|
||||
<dd class="col-xl-6"><a href="mailto:{{ user_object.email }}">{{ user_object.email }}</a></dd>
|
||||
|
||||
<dt class="col-xl-6">{% trans 'phone number'|capfirst %}</dt>
|
||||
<dd class="col-xl-6"><a href="tel:{{ user_object.profile.phone_number }}">{{ user_object.profile.phone_number }}</a>
|
||||
</dd>
|
||||
<dt class="col-xl-6">{% trans 'phone number'|capfirst %}</dt>
|
||||
<dd class="col-xl-6"><a href="tel:{{ user_object.profile.phone_number }}">{{ user_object.profile.phone_number }}</a>
|
||||
</dd>
|
||||
|
||||
<dt class="col-xl-6">{% trans 'address'|capfirst %}</dt>
|
||||
<dd class="col-xl-6">{{ user_object.profile.address }}</dd>
|
||||
<dt class="col-xl-6">{% trans 'address'|capfirst %}</dt>
|
||||
<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>
|
||||
{% 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>
|
||||
<dd class="col-xl-6">{{ user_object.profile.paid|yesno }}</dd>
|
||||
<dt class="col-xl-6">{% trans 'paid'|capfirst %}</dt>
|
||||
<dd class="col-xl-6">{{ user_object.profile.paid|yesno }}</dd>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</dl>
|
||||
|
||||
|
@ -5,7 +5,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
{% load i18n perms %}
|
||||
|
||||
{% block content %}
|
||||
{% if "member.change_profile_registration_valid"|has_perm:user %}
|
||||
{% if can_manage_registrations %}
|
||||
<a class="btn btn-block btn-secondary mb-3" href="{% url 'registration:future_user_list' %}">
|
||||
<i class="fa fa-user-plus"></i> {% trans "Registrations" %}
|
||||
</a>
|
||||
|
0
apps/member/templatetags/__init__.py
Normal file
0
apps/member/templatetags/__init__.py
Normal file
22
apps/member/templatetags/memberinfo.py
Normal file
22
apps/member/templatetags/memberinfo.py
Normal file
@ -0,0 +1,22 @@
|
||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from datetime import date
|
||||
|
||||
from django import template
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from ..models import Club, Membership
|
||||
|
||||
|
||||
def is_member(user, club):
|
||||
if isinstance(user, str):
|
||||
club = User.objects.get(username=user)
|
||||
if isinstance(club, str):
|
||||
club = Club.objects.get(name=club)
|
||||
return Membership.objects\
|
||||
.filter(user=user, club=club, date_start__lte=date.today(), date_end__gte=date.today()).exists()
|
||||
|
||||
|
||||
register = template.Library()
|
||||
register.filter("is_member", is_member)
|
@ -41,7 +41,7 @@ class TemplateLoggedInTests(TestCase):
|
||||
password="adminadmin",
|
||||
permission_mask=3,
|
||||
))
|
||||
self.assertRedirects(response, settings.LOGIN_REDIRECT_URL, 302, 200)
|
||||
self.assertRedirects(response, settings.LOGIN_REDIRECT_URL, 302, 302)
|
||||
|
||||
def test_logout(self):
|
||||
response = self.client.get(reverse("logout"))
|
||||
|
@ -205,7 +205,7 @@ class TestMemberships(TestCase):
|
||||
first_name="Toto",
|
||||
bank="Le matelas",
|
||||
))
|
||||
self.assertRedirects(response, club.get_absolute_url(), 302, 200)
|
||||
self.assertRedirects(response, user.profile.get_absolute_url(), 302, 200)
|
||||
|
||||
self.assertTrue(Membership.objects.filter(user=user, club=club).exists())
|
||||
|
||||
@ -244,9 +244,9 @@ class TestMemberships(TestCase):
|
||||
first_name="Toto",
|
||||
bank="Bank",
|
||||
))
|
||||
self.assertRedirects(response, club.get_absolute_url(), 302, 200)
|
||||
self.assertRedirects(response, user.profile.get_absolute_url(), 302, 200)
|
||||
|
||||
response = self.client.get(user.profile.get_absolute_url())
|
||||
response = self.client.get(club.get_absolute_url())
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_auto_join_kfet_when_join_bde_with_soge(self):
|
||||
@ -273,7 +273,7 @@ class TestMemberships(TestCase):
|
||||
first_name="Toto",
|
||||
bank="Société générale",
|
||||
))
|
||||
self.assertRedirects(response, bde.get_absolute_url(), 302, 200)
|
||||
self.assertRedirects(response, user.profile.get_absolute_url(), 302, 200)
|
||||
|
||||
self.assertTrue(Membership.objects.filter(user=user, club=bde).exists())
|
||||
self.assertTrue(Membership.objects.filter(user=user, club=kfet).exists())
|
||||
|
@ -70,10 +70,11 @@ class UserUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
|
||||
form.fields['email'].required = True
|
||||
form.fields['email'].help_text = _("This address must be valid.")
|
||||
|
||||
context['profile_form'] = self.profile_form(instance=context['user_object'].profile,
|
||||
data=self.request.POST if self.request.POST else None)
|
||||
if not self.object.profile.report_frequency:
|
||||
del context['profile_form'].fields["last_report"]
|
||||
if PermissionBackend.check_perm(self.request.user, "member.change_profile", context['user_object'].profile):
|
||||
context['profile_form'] = self.profile_form(instance=context['user_object'].profile,
|
||||
data=self.request.POST if self.request.POST else None)
|
||||
if not self.object.profile.report_frequency:
|
||||
del context['profile_form'].fields["last_report"]
|
||||
|
||||
return context
|
||||
|
||||
@ -157,8 +158,12 @@ class UserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
|
||||
history_table.paginate(per_page=20, page=self.request.GET.get("transaction-page", 1))
|
||||
context['history_list'] = history_table
|
||||
|
||||
club_list = Membership.objects.filter(user=user, date_end__gte=date.today())\
|
||||
.filter(PermissionBackend.filter_queryset(self.request.user, Membership, "view"))
|
||||
club_list = Membership.objects.filter(user=user, date_end__gte=date.today() - timedelta(days=15))\
|
||||
.filter(PermissionBackend.filter_queryset(self.request.user, Membership, "view"))\
|
||||
.order_by("club__name", "-date_start")
|
||||
# Display only the most recent membership
|
||||
club_list = club_list.distinct("club__name")\
|
||||
if settings.DATABASES["default"]["ENGINE"] == 'django.db.backends.postgresql' else club_list
|
||||
membership_table = MembershipTable(data=club_list, prefix='membership-')
|
||||
membership_table.paginate(per_page=10, page=self.request.GET.get("membership-page", 1))
|
||||
context['club_list'] = membership_table
|
||||
@ -166,6 +171,8 @@ class UserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
|
||||
# Check permissions to see if the authenticated user can lock/unlock the note
|
||||
with transaction.atomic():
|
||||
modified_note = NoteUser.objects.get(pk=user.note.pk)
|
||||
# Don't log these tests
|
||||
modified_note._no_signal = True
|
||||
modified_note.is_active = True
|
||||
modified_note.inactivity_reason = 'manual'
|
||||
context["can_lock_note"] = user.note.is_active and PermissionBackend\
|
||||
@ -178,6 +185,7 @@ class UserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
|
||||
context["can_force_lock"] = user.note.is_active and PermissionBackend\
|
||||
.check_perm(self.request.user, "note.change_note_is_active", modified_note)
|
||||
old_note._force_save = True
|
||||
old_note._no_signal = True
|
||||
old_note.save()
|
||||
modified_note.refresh_from_db()
|
||||
modified_note.is_active = True
|
||||
@ -227,6 +235,13 @@ class UserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
|
||||
|
||||
return qs
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
pre_registered_users = User.objects.filter(PermissionBackend.filter_queryset(self.request.user, User, "view"))\
|
||||
.filter(profile__registration_valid=False)
|
||||
context["can_manage_registrations"] = pre_registered_users.exists()
|
||||
return context
|
||||
|
||||
|
||||
class ProfileAliasView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
|
||||
"""
|
||||
@ -240,8 +255,8 @@ class ProfileAliasView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
note = context['object'].note
|
||||
context["aliases"] = AliasTable(note.alias_set.filter(PermissionBackend
|
||||
.filter_queryset(self.request.user, Alias, "view")).all())
|
||||
context["aliases"] = AliasTable(
|
||||
note.alias_set.filter(PermissionBackend.filter_queryset(self.request.user, Alias, "view")).distinct().all())
|
||||
context["can_create"] = PermissionBackend.check_perm(self.request.user, "note.add_alias", Alias(
|
||||
note=context["object"].note,
|
||||
name="",
|
||||
@ -392,7 +407,8 @@ class ClubDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
|
||||
if PermissionBackend.check_perm(self.request.user, "member.change_club_membership_start", club):
|
||||
club.update_membership_dates()
|
||||
# managers list
|
||||
managers = Membership.objects.filter(club=self.object, roles__name="Bureau de club")\
|
||||
managers = Membership.objects.filter(club=self.object, roles__name="Bureau de club",
|
||||
date_start__lte=date.today(), date_end__gte=date.today())\
|
||||
.order_by('user__last_name').all()
|
||||
context["managers"] = ClubManagerTable(data=managers, prefix="managers-")
|
||||
# transaction history
|
||||
@ -405,8 +421,12 @@ class ClubDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
|
||||
# member list
|
||||
club_member = Membership.objects.filter(
|
||||
club=club,
|
||||
date_end__gte=date.today(),
|
||||
).filter(PermissionBackend.filter_queryset(self.request.user, Membership, "view"))
|
||||
date_end__gte=date.today() - timedelta(days=15),
|
||||
).filter(PermissionBackend.filter_queryset(self.request.user, Membership, "view"))\
|
||||
.order_by("user__username", "-date_start")
|
||||
# Display only the most recent membership
|
||||
club_member = club_member.distinct("user__username")\
|
||||
if settings.DATABASES["default"]["ENGINE"] == 'django.db.backends.postgresql' else club_member
|
||||
|
||||
membership_table = MembershipTable(data=club_member, prefix="membership-")
|
||||
membership_table.paginate(per_page=5, page=self.request.GET.get('membership-page', 1))
|
||||
@ -438,8 +458,8 @@ class ClubAliasView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
note = context['object'].note
|
||||
context["aliases"] = AliasTable(note.alias_set.filter(PermissionBackend
|
||||
.filter_queryset(self.request.user, Alias, "view")).all())
|
||||
context["aliases"] = AliasTable(note.alias_set.filter(
|
||||
PermissionBackend.filter_queryset(self.request.user, Alias, "view")).distinct().all())
|
||||
context["can_create"] = PermissionBackend.check_perm(self.request.user, "note.add_alias", Alias(
|
||||
note=context["object"].note,
|
||||
name="",
|
||||
@ -638,8 +658,8 @@ class ClubAddMemberView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||
if club.name != "Kfet" and club.parent_club and not Membership.objects.filter(
|
||||
user=form.instance.user,
|
||||
club=club.parent_club,
|
||||
date_start__lte=club.parent_club.membership_start,
|
||||
date_end__gte=club.parent_club.membership_end,
|
||||
date_start__gte=club.parent_club.membership_start,
|
||||
date_end__lte=club.parent_club.membership_end,
|
||||
).exists():
|
||||
form.add_error('user', _('User is not a member of the parent club') + ' ' + club.parent_club.name)
|
||||
error = True
|
||||
@ -658,11 +678,13 @@ class ClubAddMemberView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||
if not last_name or not first_name or (not bank and credit_type.special_type == "Chèque"):
|
||||
if not last_name:
|
||||
form.add_error('last_name', _("This field is required."))
|
||||
error = True
|
||||
if not first_name:
|
||||
form.add_error('first_name', _("This field is required."))
|
||||
error = True
|
||||
if not bank and credit_type.special_type == "Chèque":
|
||||
form.add_error('bank', _("This field is required."))
|
||||
return self.form_invalid(form)
|
||||
error = True
|
||||
|
||||
return not error
|
||||
|
||||
@ -676,6 +698,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||
club = Club.objects.filter(PermissionBackend.filter_queryset(self.request.user, Club, "view")) \
|
||||
.get(pk=self.kwargs["club_pk"])
|
||||
user = form.instance.user
|
||||
old_membership = None
|
||||
else: # get from url for renewal
|
||||
old_membership = self.get_queryset().get(pk=self.kwargs["pk"])
|
||||
club = old_membership.club
|
||||
@ -750,6 +773,9 @@ class ClubAddMemberView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||
member_role = Role.objects.filter(Q(name="Adhérent BDE") | Q(name="Membre de club")).all() \
|
||||
if club.name == "BDE" else Role.objects.filter(Q(name="Adhérent Kfet") | Q(name="Membre de club")).all() \
|
||||
if club.name == "Kfet"else Role.objects.filter(name="Membre de club").all()
|
||||
# Set the same roles as before
|
||||
if old_membership:
|
||||
member_role = member_role.union(old_membership.roles.all())
|
||||
form.instance.roles.set(member_role)
|
||||
form.instance._force_save = True
|
||||
form.instance.save()
|
||||
@ -787,7 +813,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||
return ret
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse_lazy('member:club_detail', kwargs={'pk': self.object.club.id})
|
||||
return reverse_lazy('member:user_detail', kwargs={'pk': self.object.user.id})
|
||||
|
||||
|
||||
class ClubManageRolesView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
from django.apps import AppConfig
|
||||
from django.conf import settings
|
||||
from django.db.models.signals import post_save, pre_delete
|
||||
from django.db.models.signals import pre_delete, pre_save, post_save
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from . import signals
|
||||
@ -17,6 +17,15 @@ class NoteConfig(AppConfig):
|
||||
"""
|
||||
Define app internal signals to interact with other apps
|
||||
"""
|
||||
pre_save.connect(
|
||||
signals.pre_save_note,
|
||||
sender="note.noteuser",
|
||||
)
|
||||
pre_save.connect(
|
||||
signals.pre_save_note,
|
||||
sender="note.noteclub",
|
||||
)
|
||||
|
||||
post_save.connect(
|
||||
signals.save_user_note,
|
||||
sender=settings.AUTH_USER_MODEL,
|
||||
|
@ -159,20 +159,6 @@ class NoteUser(Note):
|
||||
def pretty(self):
|
||||
return _("%(user)s's note") % {'user': str(self.user)}
|
||||
|
||||
@transaction.atomic
|
||||
def save(self, *args, **kwargs):
|
||||
if self.pk and self.balance < 0:
|
||||
old_note = NoteUser.objects.get(pk=self.pk)
|
||||
super().save(*args, **kwargs)
|
||||
if old_note.balance >= 0:
|
||||
# Passage en négatif
|
||||
self.last_negative = timezone.now()
|
||||
self._force_save = True
|
||||
self.save(*args, **kwargs)
|
||||
self.send_mail_negative_balance()
|
||||
else:
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def send_mail_negative_balance(self):
|
||||
plain_text = render_to_string("note/mails/negative_balance.txt", dict(note=self))
|
||||
html = render_to_string("note/mails/negative_balance.html", dict(note=self))
|
||||
@ -201,20 +187,6 @@ class NoteClub(Note):
|
||||
def pretty(self):
|
||||
return _("Note of %(club)s club") % {'club': str(self.club)}
|
||||
|
||||
@transaction.atomic
|
||||
def save(self, *args, **kwargs):
|
||||
if self.pk and self.balance < 0:
|
||||
old_note = NoteClub.objects.get(pk=self.pk)
|
||||
super().save(*args, **kwargs)
|
||||
if old_note.balance >= 0:
|
||||
# Passage en négatif
|
||||
self.last_negative = timezone.now()
|
||||
self._force_save = True
|
||||
self.save(*args, **kwargs)
|
||||
self.send_mail_negative_balance()
|
||||
else:
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def send_mail_negative_balance(self):
|
||||
plain_text = render_to_string("note/mails/negative_balance.txt", dict(note=self))
|
||||
html = render_to_string("note/mails/negative_balance.html", dict(note=self))
|
||||
|
@ -217,6 +217,9 @@ class Transaction(PolymorphicModel):
|
||||
# When source == destination, no money is transferred and no transaction is created
|
||||
return
|
||||
|
||||
self.source = Note.objects.select_for_update().get(pk=self.source_id)
|
||||
self.destination = Note.objects.select_for_update().get(pk=self.destination_id)
|
||||
|
||||
# Check that the amounts stay between big integer bounds
|
||||
diff_source, diff_dest = self.validate()
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
def save_user_note(instance, raw, **_kwargs):
|
||||
"""
|
||||
@ -25,6 +27,16 @@ def save_club_note(instance, raw, **_kwargs):
|
||||
instance.note.save()
|
||||
|
||||
|
||||
def pre_save_note(instance, raw, **_kwargs):
|
||||
if not raw and instance.pk and not hasattr(instance, "_no_signal") and instance.balance < 0:
|
||||
from note.models import Note
|
||||
old_note = Note.objects.get(pk=instance.pk)
|
||||
if old_note.balance >= 0:
|
||||
# Passage en négatif
|
||||
instance.last_negative = timezone.now()
|
||||
instance.send_mail_negative_balance()
|
||||
|
||||
|
||||
def delete_transaction(instance, **_kwargs):
|
||||
"""
|
||||
Whenever we want to delete a transaction (caution with this), we ensure the transaction is invalid first.
|
||||
|
@ -67,7 +67,11 @@ $(document).ready(function () {
|
||||
|
||||
last.quantity = 1
|
||||
|
||||
if (!last.note.user) {
|
||||
if (last.note.club) {
|
||||
$('#last_name').val(last.note.name)
|
||||
$('#first_name').val(last.note.name)
|
||||
}
|
||||
else if (!last.note.user) {
|
||||
$.getJSON('/api/note/note/' + last.note.id + '/?format=json', function (note) {
|
||||
last.note.user = note.user
|
||||
$.getJSON('/api/user/' + last.note.user + '/', function (user) {
|
||||
@ -246,7 +250,7 @@ $('#btn_transfer').click(function () {
|
||||
error = true
|
||||
}
|
||||
|
||||
if (!reason_field.val()) {
|
||||
if (!reason_field.val() && $('#type_transfer').is(':checked')) {
|
||||
reason_field.addClass('is-invalid')
|
||||
$('#reason-required').html('<strong>' + gettext('This field is required.') + '</strong>')
|
||||
error = true
|
||||
@ -377,7 +381,7 @@ $('#btn_transfer').click(function () {
|
||||
alias = sources_notes_display[0].name
|
||||
source_id = user_note.id
|
||||
dest_id = special_note
|
||||
reason = 'Retrait ' + $('#credit_type option:selected').text().toLowerCase()
|
||||
reason = 'Retrait ' + $('#debit_type option:selected').text().toLowerCase()
|
||||
if (given_reason.length > 0) { reason += ' (' + given_reason + ')' }
|
||||
}
|
||||
$.post('/api/note/transaction/transaction/',
|
||||
|
@ -159,7 +159,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
{% endblock %}
|
||||
|
||||
{% block extrajavascript %}
|
||||
<script type="text/javascript" src="{% static "note/js/consos.js" 'javascript-catalog' %}"></script>
|
||||
<script type="text/javascript" src="{% static "note/js/consos.js" %}"></script>
|
||||
<script type="text/javascript">
|
||||
{% for button in highlighted %}
|
||||
{% if button.display %}
|
||||
|
@ -115,7 +115,7 @@
|
||||
"type": "view",
|
||||
"mask": 1,
|
||||
"field": "",
|
||||
"permanent": true,
|
||||
"permanent": false,
|
||||
"description": "Voir les aliases des notes des clubs et des adhérents du club Kfet"
|
||||
}
|
||||
},
|
||||
@ -799,12 +799,12 @@
|
||||
"member",
|
||||
"membership"
|
||||
],
|
||||
"query": "{\"club\": [\"club\"]}",
|
||||
"query": "{}",
|
||||
"type": "change",
|
||||
"mask": 3,
|
||||
"field": "roles",
|
||||
"permanent": false,
|
||||
"description": "Modifier les rôles d'un adhérent d'un club"
|
||||
"description": "Modifier les rôles d'une adhésion"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -2081,7 +2081,7 @@
|
||||
],
|
||||
"query": "{}",
|
||||
"type": "change",
|
||||
"mask": 1,
|
||||
"mask": 2,
|
||||
"field": "invalidity_reason",
|
||||
"permanent": false,
|
||||
"description": "Modifier la raison d'invalidité d'une transaction"
|
||||
@ -2791,6 +2791,86 @@
|
||||
"description": "Voir tous les alias, y compris ceux des non adhérents"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "permission.permission",
|
||||
"pk": 179,
|
||||
"fields": {
|
||||
"model": [
|
||||
"note",
|
||||
"alias"
|
||||
],
|
||||
"query": "{\"note__noteuser__user\": [\"user\"]}",
|
||||
"type": "view",
|
||||
"mask": 1,
|
||||
"field": "",
|
||||
"permanent": true,
|
||||
"description": "Voir ses propres alias, pour toujours"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "permission.permission",
|
||||
"pk": 180,
|
||||
"fields": {
|
||||
"model": [
|
||||
"auth",
|
||||
"user"
|
||||
],
|
||||
"query": "{\"profile__registration_valid\": false}",
|
||||
"type": "view",
|
||||
"mask": 2,
|
||||
"field": "",
|
||||
"permanent": false,
|
||||
"description": "Voir n'importe quel utilisateur non encore inscrit"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "permission.permission",
|
||||
"pk": 181,
|
||||
"fields": {
|
||||
"model": [
|
||||
"member",
|
||||
"profile"
|
||||
],
|
||||
"query": "{\"registration_valid\": false}",
|
||||
"type": "view",
|
||||
"mask": 2,
|
||||
"field": "",
|
||||
"permanent": false,
|
||||
"description": "Voir n'importe quel profil non encore inscrit"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "permission.permission",
|
||||
"pk": 182,
|
||||
"fields": {
|
||||
"model": [
|
||||
"auth",
|
||||
"user"
|
||||
],
|
||||
"query": "{\"memberships__club__name\": \"BDE\", \"memberships__roles__name\": \"Adhérent BDE\", \"memberships__date_start__lte\": [\"today\"], \"memberships__date_end__gte\": [\"today\"]}",
|
||||
"type": "view",
|
||||
"mask": 2,
|
||||
"field": "",
|
||||
"permanent": false,
|
||||
"description": "Voir n'importe quel utilisateur qui est adhérent BDE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "permission.permission",
|
||||
"pk": 183,
|
||||
"fields": {
|
||||
"model": [
|
||||
"note",
|
||||
"note"
|
||||
],
|
||||
"query": "{}",
|
||||
"type": "change",
|
||||
"mask": 1,
|
||||
"field": "display_image",
|
||||
"permanent": false,
|
||||
"description": "Changer l'image de n'importe quelle note"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "permission.role",
|
||||
"pk": 1,
|
||||
@ -2861,7 +2941,8 @@
|
||||
157,
|
||||
158,
|
||||
159,
|
||||
160
|
||||
160,
|
||||
179
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -2922,14 +3003,14 @@
|
||||
62,
|
||||
127,
|
||||
133,
|
||||
135,
|
||||
136,
|
||||
141,
|
||||
142,
|
||||
150,
|
||||
166,
|
||||
167,
|
||||
168
|
||||
168,
|
||||
182
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -2965,6 +3046,7 @@
|
||||
31,
|
||||
32,
|
||||
33,
|
||||
51,
|
||||
53,
|
||||
54,
|
||||
55,
|
||||
@ -2988,6 +3070,7 @@
|
||||
137,
|
||||
138,
|
||||
139,
|
||||
140,
|
||||
143,
|
||||
146,
|
||||
147,
|
||||
@ -3003,7 +3086,8 @@
|
||||
175,
|
||||
176,
|
||||
177,
|
||||
178
|
||||
178,
|
||||
183
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -3186,7 +3270,12 @@
|
||||
175,
|
||||
176,
|
||||
177,
|
||||
178
|
||||
178,
|
||||
179,
|
||||
180,
|
||||
181,
|
||||
182,
|
||||
183
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -3220,7 +3309,12 @@
|
||||
170,
|
||||
171,
|
||||
176,
|
||||
177
|
||||
177,
|
||||
178,
|
||||
179,
|
||||
180,
|
||||
181,
|
||||
182
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -3383,7 +3477,6 @@
|
||||
135,
|
||||
136,
|
||||
137,
|
||||
138,
|
||||
139,
|
||||
140,
|
||||
143,
|
||||
@ -3396,6 +3489,41 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "permission.role",
|
||||
"pk": 20,
|
||||
"fields": {
|
||||
"for_club": 2,
|
||||
"name": "PC Kfet",
|
||||
"permissions": [
|
||||
6,
|
||||
22,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
30,
|
||||
49,
|
||||
50,
|
||||
55,
|
||||
56,
|
||||
57,
|
||||
58,
|
||||
137,
|
||||
143,
|
||||
147,
|
||||
150,
|
||||
166,
|
||||
167,
|
||||
168,
|
||||
176,
|
||||
177,
|
||||
180,
|
||||
181,
|
||||
182
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "wei.weirole",
|
||||
"pk": 12,
|
||||
|
@ -43,7 +43,9 @@ class InstancedPermission:
|
||||
obj = copy(obj)
|
||||
obj.pk = 0
|
||||
with transaction.atomic():
|
||||
sid = transaction.savepoint()
|
||||
for o in self.model.model_class().objects.filter(pk=0).all():
|
||||
o._no_signal = True
|
||||
o._force_delete = True
|
||||
Model.delete(o)
|
||||
# An object with pk 0 wouldn't deleted. That's not normal, we alert admins.
|
||||
@ -61,9 +63,7 @@ class InstancedPermission:
|
||||
obj._no_signal = True
|
||||
Model.save(obj, force_insert=True)
|
||||
ret = self.model.model_class().objects.filter(self.query & Q(pk=0)).exists()
|
||||
# Delete testing object
|
||||
obj._force_delete = True
|
||||
Model.delete(obj)
|
||||
transaction.savepoint_rollback(sid)
|
||||
|
||||
return ret
|
||||
|
||||
|
@ -51,8 +51,10 @@ class ProtectQuerysetMixin:
|
||||
# No worry if the user change the hidden fields: a 403 error will be performed if the user tries to make
|
||||
# a custom request.
|
||||
# We could also delete the field, but some views might be affected.
|
||||
meta = form.instance._meta
|
||||
for key in form.base_fields:
|
||||
if not PermissionBackend.check_perm(self.request.user, "wei.change_weiregistration_" + key, self.object):
|
||||
if not PermissionBackend.check_perm(self.request.user,
|
||||
f"{meta.app_label}.change_{meta.model_name}_" + key, self.object):
|
||||
form.fields[key].widget = HiddenInput()
|
||||
|
||||
return form
|
||||
|
@ -44,6 +44,15 @@ class SignUpForm(UserCreationForm):
|
||||
fields = ('first_name', 'last_name', 'username', 'email', )
|
||||
|
||||
|
||||
class DeclareSogeAccountOpenedForm(forms.Form):
|
||||
soge_account = forms.BooleanField(
|
||||
label=_("I declare that I opened a bank account in the Société générale with the BDE partnership."),
|
||||
help_text=_("Warning: this engages you to open your bank account. If you finally decides to don't open your "
|
||||
"account, you will have to pay the BDE membership."),
|
||||
required=False,
|
||||
)
|
||||
|
||||
|
||||
class WEISignupForm(forms.Form):
|
||||
wei_registration = forms.BooleanField(
|
||||
label=_("Register to the WEI"),
|
||||
|
@ -4,6 +4,8 @@
|
||||
import django_tables2 as tables
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from treasury.models import SogeCredit
|
||||
|
||||
|
||||
class FutureUserTable(tables.Table):
|
||||
"""
|
||||
@ -21,6 +23,7 @@ class FutureUserTable(tables.Table):
|
||||
fields = ('last_name', 'first_name', 'username', 'email', )
|
||||
model = User
|
||||
row_attrs = {
|
||||
'class': 'table-row',
|
||||
'class': lambda record: 'table-row'
|
||||
+ (' bg-warning' if SogeCredit.objects.filter(user=record).exists() else ''),
|
||||
'data-href': lambda record: record.pk
|
||||
}
|
||||
|
@ -56,6 +56,13 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
<div class="card-header text-center" >
|
||||
<h4> {% trans "Validate account" %}</h4>
|
||||
</div>
|
||||
|
||||
{% if declare_soge_account %}
|
||||
<div class="alert alert-info">
|
||||
{% trans "The user declared that he/she opened a bank account in the Société générale." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="card-body" id="profile_infos">
|
||||
{% csrf_token %}
|
||||
{{ form|crispy }}
|
||||
@ -104,7 +111,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
soge_field.change(fillFields);
|
||||
|
||||
{% if object.profile.soge %}
|
||||
{% if declare_soge_account %}
|
||||
soge_field.attr('checked', true);
|
||||
fillFields();
|
||||
{% endif %}
|
||||
|
@ -24,7 +24,7 @@ from permission.models import Role
|
||||
from permission.views import ProtectQuerysetMixin
|
||||
from treasury.models import SogeCredit
|
||||
|
||||
from .forms import SignUpForm, ValidationForm
|
||||
from .forms import SignUpForm, ValidationForm, DeclareSogeAccountOpenedForm
|
||||
from .tables import FutureUserTable
|
||||
from .tokens import email_validation_token
|
||||
|
||||
@ -42,6 +42,7 @@ class UserCreateView(CreateView):
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["profile_form"] = self.second_form(self.request.POST if self.request.POST else None)
|
||||
context["soge_form"] = DeclareSogeAccountOpenedForm(self.request.POST if self.request.POST else None)
|
||||
del context["profile_form"].fields["section"]
|
||||
del context["profile_form"].fields["report_frequency"]
|
||||
del context["profile_form"].fields["last_report"]
|
||||
@ -72,6 +73,13 @@ class UserCreateView(CreateView):
|
||||
|
||||
user.profile.send_email_validation_link()
|
||||
|
||||
soge_form = DeclareSogeAccountOpenedForm(self.request.POST)
|
||||
if "soge_account" in soge_form.data and soge_form.data["soge_account"]:
|
||||
# If the user declares that a bank account got opened, prepare the soge credit to warn treasurers
|
||||
soge_credit = SogeCredit(user=user)
|
||||
soge_credit._force_save = True
|
||||
soge_credit.save()
|
||||
|
||||
return super().form_valid(form)
|
||||
|
||||
def get_success_url(self):
|
||||
@ -182,7 +190,7 @@ class FutureUserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableVi
|
||||
| Q(username__iregex="^" + pattern)
|
||||
)
|
||||
|
||||
return qs[:20]
|
||||
return qs
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
@ -227,6 +235,8 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
|
||||
fee += 8000
|
||||
ctx["total_fee"] = "{:.02f}".format(fee / 100, )
|
||||
|
||||
ctx["declare_soge_account"] = SogeCredit.objects.filter(user=user).exists()
|
||||
|
||||
return ctx
|
||||
|
||||
def get_form(self, form_class=None):
|
||||
@ -307,6 +317,13 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
|
||||
user.profile.save()
|
||||
user.refresh_from_db()
|
||||
|
||||
if not soge and SogeCredit.objects.filter(user=user).exists():
|
||||
# If the user declared that a bank account was opened but in the validation form the SoGé case was
|
||||
# unchecked, delete the associated credit
|
||||
soge_credit = SogeCredit.objects.get(user=user)
|
||||
soge_credit._force_delete = True
|
||||
soge_credit.delete()
|
||||
|
||||
if credit_type is not None and credit_amount > 0:
|
||||
# Credit the note
|
||||
SpecialTransaction.objects.create(
|
||||
@ -373,6 +390,8 @@ class FutureUserInvalidateView(ProtectQuerysetMixin, LoginRequiredMixin, View):
|
||||
user = User.objects.filter(profile__registration_valid=False)\
|
||||
.filter(PermissionBackend.filter_queryset(request.user, User, "change", "is_valid"))\
|
||||
.get(pk=self.kwargs["pk"])
|
||||
# Delete associated soge credits before
|
||||
SogeCredit.objects.filter(user=user).delete()
|
||||
|
||||
user.delete()
|
||||
|
||||
|
@ -28,6 +28,8 @@ class TreasuryConfig(AppConfig):
|
||||
source__in=NoteSpecial.objects.filter(~Q(remittancetype=None)),
|
||||
specialtransactionproxy=None,
|
||||
):
|
||||
SpecialTransactionProxy.objects.create(transaction=transaction, remittance=None)
|
||||
proxy = SpecialTransactionProxy(transaction=transaction, remittance=None)
|
||||
proxy._force_save = True
|
||||
proxy.save()
|
||||
|
||||
post_migrate.connect(setup_specialtransactions_proxies, sender=SpecialTransactionProxy)
|
||||
|
@ -10,7 +10,7 @@ from django.db.models import Q
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from note.models import NoteSpecial, SpecialTransaction, MembershipTransaction
|
||||
from note.models import NoteSpecial, SpecialTransaction, MembershipTransaction, NoteUser
|
||||
|
||||
|
||||
class Invoice(models.Model):
|
||||
@ -335,6 +335,11 @@ class SogeCredit(models.Model):
|
||||
|
||||
@transaction.atomic
|
||||
def save(self, *args, **kwargs):
|
||||
# This is a pre-registered user that declared that a SoGé account was opened.
|
||||
# No note exists yet.
|
||||
if not NoteUser.objects.filter(user=self.user).exists():
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
if not self.credit_transaction:
|
||||
credit_transaction = SpecialTransaction(
|
||||
source=NoteSpecial.objects.get(special_type="Virement bancaire"),
|
||||
|
@ -10,9 +10,8 @@ def save_special_transaction(instance, created, **kwargs):
|
||||
"""
|
||||
|
||||
if not hasattr(instance, "_no_signal"):
|
||||
if instance.is_credit():
|
||||
if created and RemittanceType.objects.filter(note=instance.source).exists():
|
||||
SpecialTransactionProxy.objects.create(transaction=instance, remittance=None).save()
|
||||
else:
|
||||
if created and RemittanceType.objects.filter(note=instance.destination).exists():
|
||||
SpecialTransactionProxy.objects.create(transaction=instance, remittance=None).save()
|
||||
if created and RemittanceType.objects.filter(
|
||||
note=instance.source if instance.is_credit() else instance.destination).exists():
|
||||
proxy = SpecialTransactionProxy(transaction=instance, remittance=None)
|
||||
proxy._force_save = True
|
||||
proxy.save()
|
||||
|
@ -147,4 +147,4 @@ class SogeCreditTable(tables.Table):
|
||||
|
||||
class Meta:
|
||||
model = SogeCredit
|
||||
fields = ('user', 'amount', 'valid', )
|
||||
fields = ('user', 'user__last_name', 'user__first_name', 'amount', 'valid', )
|
||||
|
@ -11,8 +11,14 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
</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 'last name'|capfirst %}</dt>
|
||||
<dd class="col-xl-6">{{ object.user.last_name }}</dd>
|
||||
|
||||
<dt class="col-xl-6 text-right">{% trans 'first name'|capfirst %}</dt>
|
||||
<dd class="col-xl-6">{{ object.user.first_name }}</dd>
|
||||
|
||||
<dt class="col-xl-6 text-right">{% trans 'username'|capfirst %}</dt>
|
||||
<dd class="col-xl-6"><a href="{% url 'member:user_detail' pk=object.user.pk %}">{{ object.user.username }}</a></dd>
|
||||
|
||||
{% if "note.view_note_balance"|has_perm:object.user.note %}
|
||||
<dt class="col-xl-6 text-right">{% trans 'balance'|capfirst %}</dt>
|
||||
|
@ -60,7 +60,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
let pattern = searchbar_obj.val();
|
||||
|
||||
$("#credits_table").load(location.pathname + "?search=" + pattern.replace(" ", "%20") + (
|
||||
invalid_only_obj.is(':checked') ? "&valid=false" : "") + " #credits_table");
|
||||
invalid_only_obj.is(':checked') ? "" : "&valid=1") + " #credits_table");
|
||||
|
||||
$(".table-row").click(function () {
|
||||
window.document.location = $(this).data("href");
|
||||
|
@ -431,7 +431,7 @@ class SogeCreditListView(LoginRequiredMixin, ProtectQuerysetMixin, SingleTableVi
|
||||
if "valid" not in self.request.GET or not self.request.GET["valid"]:
|
||||
qs = qs.filter(credit_transaction__valid=False)
|
||||
|
||||
return qs[:20]
|
||||
return qs
|
||||
|
||||
|
||||
class SogeCreditManageView(LoginRequiredMixin, ProtectQuerysetMixin, BaseFormView, DetailView):
|
||||
|
@ -52,9 +52,9 @@ msgstr "Sie dürfen höchstens 3 Leute zu dieser Veranstaltung einladen."
|
||||
#: apps/member/models.py:199
|
||||
#: apps/member/templates/member/includes/club_info.html:4
|
||||
#: apps/member/templates/member/includes/profile_info.html:4
|
||||
#: apps/note/models/notes.py:260 apps/note/models/transactions.py:26
|
||||
#: apps/note/models/transactions.py:46 apps/note/models/transactions.py:297
|
||||
#: apps/permission/models.py:330
|
||||
#: apps/note/models/notes.py:232 apps/note/models/transactions.py:26
|
||||
#: apps/note/models/transactions.py:46 apps/note/models/transactions.py:300
|
||||
#: apps/permission/models.py:333
|
||||
#: apps/registration/templates/registration/future_profile_detail.html:16
|
||||
#: apps/wei/models.py:66 apps/wei/models.py:118
|
||||
#: apps/wei/templates/wei/base.html:26
|
||||
@ -90,8 +90,8 @@ msgstr "Vearnstaltungarte"
|
||||
|
||||
#: apps/activity/models.py:68
|
||||
#: apps/activity/templates/activity/includes/activity_info.html:19
|
||||
#: apps/note/models/transactions.py:81 apps/permission/models.py:110
|
||||
#: apps/permission/models.py:189 apps/wei/models.py:72 apps/wei/models.py:129
|
||||
#: apps/note/models/transactions.py:81 apps/permission/models.py:113
|
||||
#: apps/permission/models.py:192 apps/wei/models.py:72 apps/wei/models.py:129
|
||||
msgid "description"
|
||||
msgstr "Beschreibung"
|
||||
|
||||
@ -105,8 +105,8 @@ msgstr "Wo findet die Veranstaltung statt ? (z.B Kfet)"
|
||||
|
||||
#: apps/activity/models.py:83
|
||||
#: apps/activity/templates/activity/includes/activity_info.html:22
|
||||
#: apps/note/models/notes.py:236 apps/note/models/transactions.py:66
|
||||
#: apps/permission/models.py:164
|
||||
#: apps/note/models/notes.py:208 apps/note/models/transactions.py:66
|
||||
#: apps/permission/models.py:167
|
||||
msgid "type"
|
||||
msgstr "Type"
|
||||
|
||||
@ -254,15 +254,15 @@ msgstr "entfernen"
|
||||
msgid "Type"
|
||||
msgstr "Type"
|
||||
|
||||
#: apps/activity/tables.py:82 apps/member/forms.py:185
|
||||
#: apps/registration/forms.py:81 apps/treasury/forms.py:130
|
||||
#: apps/activity/tables.py:82 apps/member/forms.py:186
|
||||
#: apps/registration/forms.py:90 apps/treasury/forms.py:130
|
||||
#: apps/wei/forms/registration.py:96
|
||||
msgid "Last name"
|
||||
msgstr "Nachname"
|
||||
|
||||
#: apps/activity/tables.py:84 apps/member/forms.py:190
|
||||
#: apps/activity/tables.py:84 apps/member/forms.py:191
|
||||
#: apps/note/templates/note/transaction_form.html:134
|
||||
#: apps/registration/forms.py:86 apps/treasury/forms.py:132
|
||||
#: apps/registration/forms.py:95 apps/treasury/forms.py:132
|
||||
#: apps/wei/forms/registration.py:101
|
||||
msgid "First name"
|
||||
msgstr "Vorname"
|
||||
@ -286,7 +286,7 @@ msgid "Guest deleted"
|
||||
msgstr "Gastliste"
|
||||
|
||||
#: apps/activity/templates/activity/activity_entry.html:14
|
||||
#: apps/note/models/transactions.py:253
|
||||
#: apps/note/models/transactions.py:256
|
||||
#: apps/note/templates/note/transaction_form.html:16
|
||||
#: apps/note/templates/note/transaction_form.html:148
|
||||
#: note_kfet/templates/base.html:73
|
||||
@ -294,13 +294,13 @@ msgid "Transfer"
|
||||
msgstr "Überweisen"
|
||||
|
||||
#: apps/activity/templates/activity/activity_entry.html:18
|
||||
#: apps/note/models/transactions.py:313
|
||||
#: apps/note/models/transactions.py:316
|
||||
#: apps/note/templates/note/transaction_form.html:21
|
||||
msgid "Credit"
|
||||
msgstr "Kredit"
|
||||
|
||||
#: apps/activity/templates/activity/activity_entry.html:21
|
||||
#: apps/note/models/transactions.py:313
|
||||
#: apps/note/models/transactions.py:316
|
||||
#: apps/note/templates/note/transaction_form.html:25
|
||||
msgid "Debit"
|
||||
msgstr "Soll"
|
||||
@ -391,39 +391,39 @@ msgstr "bearbeiten"
|
||||
msgid "Invite"
|
||||
msgstr "Einladen"
|
||||
|
||||
#: apps/activity/views.py:34
|
||||
#: apps/activity/views.py:36
|
||||
msgid "Create new activity"
|
||||
msgstr "Neue Veranstaltung schaffen"
|
||||
|
||||
#: apps/activity/views.py:65 note_kfet/templates/base.html:91
|
||||
#: apps/activity/views.py:67 note_kfet/templates/base.html:91
|
||||
msgid "Activities"
|
||||
msgstr "Veranstaltungen"
|
||||
|
||||
#: apps/activity/views.py:93
|
||||
#: apps/activity/views.py:95
|
||||
msgid "Activity detail"
|
||||
msgstr "Veranstaltunginfo"
|
||||
|
||||
#: apps/activity/views.py:113
|
||||
#: apps/activity/views.py:115
|
||||
msgid "Update activity"
|
||||
msgstr "Veranstaltung bearbeiten"
|
||||
|
||||
#: apps/activity/views.py:140
|
||||
#: apps/activity/views.py:142
|
||||
msgid "Invite guest to the activity \"{}\""
|
||||
msgstr "Gast zur Veranstaltung \"{}\" einladen"
|
||||
|
||||
#: apps/activity/views.py:175
|
||||
#: apps/activity/views.py:177
|
||||
msgid "You are not allowed to display the entry interface for this activity."
|
||||
msgstr "Sie haben nicht das Recht diese Seite zu benuzten."
|
||||
|
||||
#: apps/activity/views.py:178
|
||||
#: apps/activity/views.py:180
|
||||
msgid "This activity does not support activity entries."
|
||||
msgstr "Diese Veranstaltung braucht nicht Eintritt."
|
||||
|
||||
#: apps/activity/views.py:181
|
||||
#: apps/activity/views.py:183
|
||||
msgid "This activity is closed."
|
||||
msgstr "Diese Veranstaltung ist geschlossen."
|
||||
|
||||
#: apps/activity/views.py:277
|
||||
#: apps/activity/views.py:279
|
||||
msgid "Entry for activity \"{}\""
|
||||
msgstr "Eintritt zur Veranstaltung \"{}\""
|
||||
|
||||
@ -439,7 +439,7 @@ msgstr "Logs"
|
||||
msgid "IP Address"
|
||||
msgstr "IP Adresse"
|
||||
|
||||
#: apps/logs/models.py:36 apps/permission/models.py:134
|
||||
#: apps/logs/models.py:36 apps/permission/models.py:137
|
||||
msgid "model"
|
||||
msgstr "Model"
|
||||
|
||||
@ -460,7 +460,7 @@ msgid "create"
|
||||
msgstr "schaffen"
|
||||
|
||||
#: apps/logs/models.py:65 apps/note/tables.py:165 apps/note/tables.py:201
|
||||
#: apps/permission/models.py:127 apps/treasury/tables.py:38
|
||||
#: apps/permission/models.py:130 apps/treasury/tables.py:38
|
||||
#: apps/wei/tables.py:75
|
||||
msgid "delete"
|
||||
msgstr "entfernen"
|
||||
@ -541,48 +541,48 @@ msgid "This image cannot be loaded."
|
||||
msgstr "Dieses Bild kann nicht geladen werden."
|
||||
|
||||
#: apps/member/forms.py:141 apps/member/views.py:100
|
||||
#: apps/registration/forms.py:33 apps/registration/views.py:244
|
||||
#: apps/registration/forms.py:33 apps/registration/views.py:254
|
||||
msgid "An alias with a similar name already exists."
|
||||
msgstr "Ein ähnliches Alias ist schon benutzt."
|
||||
|
||||
#: apps/member/forms.py:164 apps/registration/forms.py:61
|
||||
#: apps/member/forms.py:165 apps/registration/forms.py:70
|
||||
msgid "Inscription paid by Société Générale"
|
||||
msgstr "Mitgliedschaft von der Société Générale bezahlt"
|
||||
|
||||
#: apps/member/forms.py:166 apps/registration/forms.py:63
|
||||
#: apps/member/forms.py:167 apps/registration/forms.py:72
|
||||
msgid "Check this case if the Société Générale paid the inscription."
|
||||
msgstr "Die Société Générale die Mitgliedschaft bezahlt."
|
||||
|
||||
#: apps/member/forms.py:171 apps/registration/forms.py:68
|
||||
#: apps/member/forms.py:172 apps/registration/forms.py:77
|
||||
#: apps/wei/forms/registration.py:83
|
||||
msgid "Credit type"
|
||||
msgstr "Kredittype"
|
||||
|
||||
#: apps/member/forms.py:172 apps/registration/forms.py:69
|
||||
#: apps/member/forms.py:173 apps/registration/forms.py:78
|
||||
#: apps/wei/forms/registration.py:84
|
||||
msgid "No credit"
|
||||
msgstr "Kein Kredit"
|
||||
|
||||
#: apps/member/forms.py:174
|
||||
#: apps/member/forms.py:175
|
||||
msgid "You can credit the note of the user."
|
||||
msgstr "Sie dûrfen diese Note kreditieren."
|
||||
|
||||
#: apps/member/forms.py:178 apps/registration/forms.py:74
|
||||
#: apps/member/forms.py:179 apps/registration/forms.py:83
|
||||
#: apps/wei/forms/registration.py:89
|
||||
msgid "Credit amount"
|
||||
msgstr "Kreditanzahl"
|
||||
|
||||
#: apps/member/forms.py:195 apps/note/templates/note/transaction_form.html:140
|
||||
#: apps/registration/forms.py:91 apps/treasury/forms.py:134
|
||||
#: apps/member/forms.py:196 apps/note/templates/note/transaction_form.html:140
|
||||
#: apps/registration/forms.py:100 apps/treasury/forms.py:134
|
||||
#: apps/wei/forms/registration.py:106
|
||||
msgid "Bank"
|
||||
msgstr "Bank"
|
||||
|
||||
#: apps/member/forms.py:222
|
||||
#: apps/member/forms.py:223
|
||||
msgid "User"
|
||||
msgstr "User"
|
||||
|
||||
#: apps/member/forms.py:236
|
||||
#: apps/member/forms.py:237
|
||||
msgid "Roles"
|
||||
msgstr "Rollen"
|
||||
|
||||
@ -810,7 +810,7 @@ msgstr ""
|
||||
"Maximales Datum einer Mitgliedschaft, nach dem Mitglieder es erneuern müssen."
|
||||
|
||||
#: apps/member/models.py:286 apps/member/models.py:311
|
||||
#: apps/note/models/notes.py:191
|
||||
#: apps/note/models/notes.py:177
|
||||
msgid "club"
|
||||
msgstr "Club"
|
||||
|
||||
@ -831,11 +831,11 @@ msgstr "Mitgliedschaft endet am"
|
||||
msgid "The role {role} does not apply to the club {club}."
|
||||
msgstr "Die Rolle {role} ist nicht erlaubt für das Club {club}."
|
||||
|
||||
#: apps/member/models.py:430 apps/member/views.py:634
|
||||
#: apps/member/models.py:430 apps/member/views.py:646
|
||||
msgid "User is already a member of the club"
|
||||
msgstr "User ist schon ein Mitglied dieser club"
|
||||
|
||||
#: apps/member/models.py:442 apps/member/views.py:644
|
||||
#: apps/member/models.py:442 apps/member/views.py:656
|
||||
msgid "User is not a member of the parent club"
|
||||
msgstr "User ist noch nicht Mitglied des Urclubs"
|
||||
|
||||
@ -844,7 +844,7 @@ msgstr "User ist noch nicht Mitglied des Urclubs"
|
||||
msgid "Membership of {user} for the club {club}"
|
||||
msgstr "Mitgliedschaft von {user} für das Club {club}"
|
||||
|
||||
#: apps/member/models.py:498 apps/note/models/transactions.py:355
|
||||
#: apps/member/models.py:498 apps/note/models/transactions.py:358
|
||||
msgid "membership"
|
||||
msgstr "Mitgliedschaft"
|
||||
|
||||
@ -963,8 +963,8 @@ msgstr ""
|
||||
"erlaubt."
|
||||
|
||||
#: apps/member/templates/member/club_alias.html:10
|
||||
#: apps/member/templates/member/profile_alias.html:10 apps/member/views.py:238
|
||||
#: apps/member/views.py:436
|
||||
#: apps/member/templates/member/profile_alias.html:10 apps/member/views.py:245
|
||||
#: apps/member/views.py:448
|
||||
msgid "Note aliases"
|
||||
msgstr "Note Aliases"
|
||||
|
||||
@ -1028,7 +1028,7 @@ msgstr "Kontostand"
|
||||
|
||||
#: apps/member/templates/member/includes/club_info.html:47
|
||||
#: apps/member/templates/member/includes/profile_info.html:20
|
||||
#: apps/note/models/notes.py:283 apps/wei/templates/wei/base.html:66
|
||||
#: apps/note/models/notes.py:255 apps/wei/templates/wei/base.html:66
|
||||
msgid "aliases"
|
||||
msgstr "Aliases"
|
||||
|
||||
@ -1107,39 +1107,39 @@ msgstr "Diese Adresse muss gültig sein."
|
||||
msgid "Profile detail"
|
||||
msgstr "Profile detail"
|
||||
|
||||
#: apps/member/views.py:197
|
||||
#: apps/member/views.py:204
|
||||
msgid "Search user"
|
||||
msgstr "User finden"
|
||||
|
||||
#: apps/member/views.py:258
|
||||
#: apps/member/views.py:265
|
||||
msgid "Update note picture"
|
||||
msgstr "Notebild ändern"
|
||||
|
||||
#: apps/member/views.py:304
|
||||
#: apps/member/views.py:311
|
||||
msgid "Manage auth token"
|
||||
msgstr "Auth token bearbeiten"
|
||||
|
||||
#: apps/member/views.py:331
|
||||
#: apps/member/views.py:338
|
||||
msgid "Create new club"
|
||||
msgstr "Neue Club"
|
||||
|
||||
#: apps/member/views.py:350
|
||||
#: apps/member/views.py:357
|
||||
msgid "Search club"
|
||||
msgstr "Club finden"
|
||||
|
||||
#: apps/member/views.py:383
|
||||
#: apps/member/views.py:390
|
||||
msgid "Club detail"
|
||||
msgstr "Club Details"
|
||||
|
||||
#: apps/member/views.py:459
|
||||
#: apps/member/views.py:471
|
||||
msgid "Update club"
|
||||
msgstr "Club bearbeiten"
|
||||
|
||||
#: apps/member/views.py:493
|
||||
#: apps/member/views.py:505
|
||||
msgid "Add new member to the club"
|
||||
msgstr "Neue Mitglieder"
|
||||
|
||||
#: apps/member/views.py:625 apps/wei/views.py:928
|
||||
#: apps/member/views.py:637 apps/wei/views.py:928
|
||||
msgid ""
|
||||
"This user don't have enough money to join this club, and can't have a "
|
||||
"negative balance."
|
||||
@ -1147,25 +1147,25 @@ msgstr ""
|
||||
"Diese User hat nicht genug Geld um Mitglied zu werden, und darf nich im Rot "
|
||||
"sein."
|
||||
|
||||
#: apps/member/views.py:648
|
||||
#: apps/member/views.py:660
|
||||
msgid "The membership must start after {:%m-%d-%Y}."
|
||||
msgstr "Die Mitgliedschaft muss nach {:%m-%d-Y} anfängen."
|
||||
|
||||
#: apps/member/views.py:653
|
||||
#: apps/member/views.py:665
|
||||
msgid "The membership must begin before {:%m-%d-%Y}."
|
||||
msgstr "Die Mitgliedschaft muss vor {:%m-%d-Y} anfängen."
|
||||
|
||||
#: apps/member/views.py:660 apps/member/views.py:662 apps/member/views.py:664
|
||||
#: apps/registration/views.py:294 apps/registration/views.py:296
|
||||
#: apps/registration/views.py:298 apps/wei/views.py:933 apps/wei/views.py:937
|
||||
#: apps/member/views.py:672 apps/member/views.py:674 apps/member/views.py:676
|
||||
#: apps/registration/views.py:304 apps/registration/views.py:306
|
||||
#: apps/registration/views.py:308 apps/wei/views.py:933 apps/wei/views.py:937
|
||||
msgid "This field is required."
|
||||
msgstr "Dies ist ein Pflichtfeld."
|
||||
|
||||
#: apps/member/views.py:800
|
||||
#: apps/member/views.py:816
|
||||
msgid "Manage roles of an user in the club"
|
||||
msgstr "Rollen in diesen Club bearbeiten"
|
||||
|
||||
#: apps/member/views.py:825
|
||||
#: apps/member/views.py:841
|
||||
msgid "Members of the club"
|
||||
msgstr "Mitlglieder dieses Club"
|
||||
|
||||
@ -1184,7 +1184,7 @@ msgid "amount"
|
||||
msgstr "Anzahl"
|
||||
|
||||
#: apps/note/api/serializers.py:183 apps/note/api/serializers.py:189
|
||||
#: apps/note/models/transactions.py:224
|
||||
#: apps/note/models/transactions.py:227
|
||||
msgid ""
|
||||
"The transaction can't be saved since the source note or the destination note "
|
||||
"is not active."
|
||||
@ -1293,51 +1293,51 @@ msgstr "User Note"
|
||||
msgid "%(user)s's note"
|
||||
msgstr "%(user)s's note"
|
||||
|
||||
#: apps/note/models/notes.py:195
|
||||
#: apps/note/models/notes.py:181
|
||||
msgid "club note"
|
||||
msgstr "Club Note"
|
||||
|
||||
#: apps/note/models/notes.py:196
|
||||
#: apps/note/models/notes.py:182
|
||||
msgid "clubs notes"
|
||||
msgstr "Club Notes"
|
||||
|
||||
#: apps/note/models/notes.py:202
|
||||
#: apps/note/models/notes.py:188
|
||||
#, python-format
|
||||
msgid "Note of %(club)s club"
|
||||
msgstr "%(club)s Note"
|
||||
|
||||
#: apps/note/models/notes.py:242
|
||||
#: apps/note/models/notes.py:214
|
||||
msgid "special note"
|
||||
msgstr "Sondernote"
|
||||
|
||||
#: apps/note/models/notes.py:243
|
||||
#: apps/note/models/notes.py:215
|
||||
msgid "special notes"
|
||||
msgstr "Sondernoten"
|
||||
|
||||
#: apps/note/models/notes.py:266
|
||||
#: apps/note/models/notes.py:238
|
||||
msgid "Invalid alias"
|
||||
msgstr "Unerlaublt Alias"
|
||||
|
||||
#: apps/note/models/notes.py:282
|
||||
#: apps/note/models/notes.py:254
|
||||
msgid "alias"
|
||||
msgstr "Alias"
|
||||
|
||||
#: apps/note/models/notes.py:306
|
||||
#: apps/note/models/notes.py:278
|
||||
msgid "Alias is too long."
|
||||
msgstr "Alias ist zu lang."
|
||||
|
||||
#: apps/note/models/notes.py:309
|
||||
#: apps/note/models/notes.py:281
|
||||
msgid ""
|
||||
"This alias contains only complex character. Please use a more simple alias."
|
||||
msgstr ""
|
||||
"Dieser Alias enthält nur komplexe Zeichen. Bitte verwenden Sie einen "
|
||||
"einfacheren Alias."
|
||||
|
||||
#: apps/note/models/notes.py:313
|
||||
#: apps/note/models/notes.py:285
|
||||
msgid "An alias with a similar name already exists: {} "
|
||||
msgstr "Ein Alias mit einem ähnlichen Namen existiert bereits: {} "
|
||||
|
||||
#: apps/note/models/notes.py:327
|
||||
#: apps/note/models/notes.py:299
|
||||
msgid "You can't delete your main alias."
|
||||
msgstr "Sie können Ihren Hauptalias nicht löschen."
|
||||
|
||||
@ -1412,34 +1412,34 @@ msgstr ""
|
||||
"Die Notenguthaben müssen zwischen - 92 233 720 368 547 758,08 € und 92 233 "
|
||||
"720 368 547 758,07 € liegen."
|
||||
|
||||
#: apps/note/models/transactions.py:273
|
||||
#: apps/note/models/transactions.py:276
|
||||
msgid ""
|
||||
"The destination of this transaction must equal to the destination of the "
|
||||
"template."
|
||||
msgstr ""
|
||||
"Der Empfänger dieser Transaktion muss dem Empfänger der Vorlage entsprechen."
|
||||
|
||||
#: apps/note/models/transactions.py:283
|
||||
#: apps/note/models/transactions.py:286
|
||||
msgid "Template"
|
||||
msgstr "Vorlage"
|
||||
|
||||
#: apps/note/models/transactions.py:286
|
||||
#: apps/note/models/transactions.py:289
|
||||
msgid "recurrent transaction"
|
||||
msgstr "wiederkehrende Transaktion"
|
||||
|
||||
#: apps/note/models/transactions.py:287
|
||||
#: apps/note/models/transactions.py:290
|
||||
msgid "recurrent transactions"
|
||||
msgstr "wiederkehrende Transaktionen"
|
||||
|
||||
#: apps/note/models/transactions.py:302
|
||||
#: apps/note/models/transactions.py:305
|
||||
msgid "first_name"
|
||||
msgstr "Vorname"
|
||||
|
||||
#: apps/note/models/transactions.py:307
|
||||
#: apps/note/models/transactions.py:310
|
||||
msgid "bank"
|
||||
msgstr "Bank"
|
||||
|
||||
#: apps/note/models/transactions.py:324
|
||||
#: apps/note/models/transactions.py:327
|
||||
msgid ""
|
||||
"A special transaction is only possible between a Note associated to a "
|
||||
"payment method and a User or a Club"
|
||||
@ -1447,19 +1447,19 @@ msgstr ""
|
||||
"Eine Sondertransaktion ist nur zwischen einer Note, die einer "
|
||||
"Zahlungsmethode zugeordnet ist, und einem User oder einem Club möglich"
|
||||
|
||||
#: apps/note/models/transactions.py:333
|
||||
#: apps/note/models/transactions.py:336
|
||||
msgid "Special transaction"
|
||||
msgstr "Sondertransaktion"
|
||||
|
||||
#: apps/note/models/transactions.py:334
|
||||
#: apps/note/models/transactions.py:337
|
||||
msgid "Special transactions"
|
||||
msgstr "Sondertranskationen"
|
||||
|
||||
#: apps/note/models/transactions.py:350
|
||||
#: apps/note/models/transactions.py:353
|
||||
msgid "membership transaction"
|
||||
msgstr "Mitgliedschafttransaktion"
|
||||
|
||||
#: apps/note/models/transactions.py:351 apps/treasury/models.py:284
|
||||
#: apps/note/models/transactions.py:354 apps/treasury/models.py:284
|
||||
msgid "membership transactions"
|
||||
msgstr "Mitgliedschaftttransaktionen"
|
||||
|
||||
@ -1649,53 +1649,53 @@ msgstr "Sie können keine Taste sehen."
|
||||
msgid "Search transactions"
|
||||
msgstr "Transaktion finden"
|
||||
|
||||
#: apps/permission/models.py:89
|
||||
#: apps/permission/models.py:92
|
||||
#, python-brace-format
|
||||
msgid "Can {type} {model}.{field} in {query}"
|
||||
msgstr "Kann {type} {model}.{field} in {query}"
|
||||
|
||||
#: apps/permission/models.py:91
|
||||
#: apps/permission/models.py:94
|
||||
#, python-brace-format
|
||||
msgid "Can {type} {model} in {query}"
|
||||
msgstr "Kann {type} {model} in {query}"
|
||||
|
||||
#: apps/permission/models.py:104
|
||||
#: apps/permission/models.py:107
|
||||
msgid "rank"
|
||||
msgstr "Rank"
|
||||
|
||||
#: apps/permission/models.py:117
|
||||
#: apps/permission/models.py:120
|
||||
msgid "permission mask"
|
||||
msgstr "Berechtigungsmaske"
|
||||
|
||||
#: apps/permission/models.py:118
|
||||
#: apps/permission/models.py:121
|
||||
msgid "permission masks"
|
||||
msgstr "Berechtigungsmasken"
|
||||
|
||||
#: apps/permission/models.py:124
|
||||
#: apps/permission/models.py:127
|
||||
msgid "add"
|
||||
msgstr "hinzufügen"
|
||||
|
||||
#: apps/permission/models.py:125
|
||||
#: apps/permission/models.py:128
|
||||
msgid "view"
|
||||
msgstr "Schauen"
|
||||
|
||||
#: apps/permission/models.py:126
|
||||
#: apps/permission/models.py:129
|
||||
msgid "change"
|
||||
msgstr "bearbeiten"
|
||||
|
||||
#: apps/permission/models.py:158
|
||||
#: apps/permission/models.py:161
|
||||
msgid "query"
|
||||
msgstr "Abfrage"
|
||||
|
||||
#: apps/permission/models.py:171
|
||||
#: apps/permission/models.py:174
|
||||
msgid "mask"
|
||||
msgstr "Maske"
|
||||
|
||||
#: apps/permission/models.py:177
|
||||
#: apps/permission/models.py:180
|
||||
msgid "field"
|
||||
msgstr "Feld"
|
||||
|
||||
#: apps/permission/models.py:182
|
||||
#: apps/permission/models.py:185
|
||||
msgid ""
|
||||
"Tells if the permission should be granted even if the membership of the user "
|
||||
"is expired."
|
||||
@ -1703,28 +1703,28 @@ msgstr ""
|
||||
"Gibt an, ob die Berechtigung auch erteilt werden soll, wenn die "
|
||||
"Mitgliedschaft des Benutzers abgelaufen ist."
|
||||
|
||||
#: apps/permission/models.py:183
|
||||
#: apps/permission/models.py:186
|
||||
#: apps/permission/templates/permission/all_rights.html:89
|
||||
msgid "permanent"
|
||||
msgstr "permanent"
|
||||
|
||||
#: apps/permission/models.py:194
|
||||
#: apps/permission/models.py:197
|
||||
msgid "permission"
|
||||
msgstr "Berechtigung"
|
||||
|
||||
#: apps/permission/models.py:195 apps/permission/models.py:335
|
||||
#: apps/permission/models.py:198 apps/permission/models.py:338
|
||||
msgid "permissions"
|
||||
msgstr "Berechtigungen"
|
||||
|
||||
#: apps/permission/models.py:200
|
||||
#: apps/permission/models.py:203
|
||||
msgid "Specifying field applies only to view and change permission types."
|
||||
msgstr "Angabefeld gilt nur zum Anzeigen und Ändern von Berechtigungstypen."
|
||||
|
||||
#: apps/permission/models.py:340
|
||||
#: apps/permission/models.py:343
|
||||
msgid "for club"
|
||||
msgstr "Für Club"
|
||||
|
||||
#: apps/permission/models.py:350 apps/permission/models.py:351
|
||||
#: apps/permission/models.py:353 apps/permission/models.py:354
|
||||
msgid "role permissions"
|
||||
msgstr "Berechtigung Rollen"
|
||||
|
||||
@ -1832,10 +1832,24 @@ msgid "This email address is already used."
|
||||
msgstr "Diese email adresse ist schon benutzt."
|
||||
|
||||
#: apps/registration/forms.py:49
|
||||
#, fuzzy
|
||||
#| msgid "You already opened an account in the Société générale."
|
||||
msgid ""
|
||||
"I declare that I opened a bank account in the Société générale with the BDE "
|
||||
"partnership."
|
||||
msgstr "Sie haben bereits ein Konto in der Société générale eröffnet."
|
||||
|
||||
#: apps/registration/forms.py:50
|
||||
msgid ""
|
||||
"Warning: this engages you to open your bank account. If you finally decides "
|
||||
"to don't open your account, you will have to pay the BDE membership."
|
||||
msgstr ""
|
||||
|
||||
#: apps/registration/forms.py:58
|
||||
msgid "Register to the WEI"
|
||||
msgstr "Zu WEI anmelden"
|
||||
|
||||
#: apps/registration/forms.py:51
|
||||
#: apps/registration/forms.py:60
|
||||
msgid ""
|
||||
"Check this case if you want to register to the WEI. If you hesitate, you "
|
||||
"will be able to register later, after validating your account in the Kfet."
|
||||
@ -1844,11 +1858,11 @@ msgstr ""
|
||||
"falls Zweifel, können Sie sich später nach Bestätigung Ihres Kontos im Kfet "
|
||||
"registrieren."
|
||||
|
||||
#: apps/registration/forms.py:96
|
||||
#: apps/registration/forms.py:105
|
||||
msgid "Join BDE Club"
|
||||
msgstr "BDE Mitglieder werden"
|
||||
|
||||
#: apps/registration/forms.py:103
|
||||
#: apps/registration/forms.py:112
|
||||
msgid "Join Kfet Club"
|
||||
msgstr "Kfet Mitglieder werden"
|
||||
|
||||
@ -1900,7 +1914,14 @@ msgstr "Registrierung löschen"
|
||||
msgid "Validate account"
|
||||
msgstr "Konto validieren"
|
||||
|
||||
#: apps/registration/templates/registration/future_profile_detail.html:64
|
||||
#: apps/registration/templates/registration/future_profile_detail.html:62
|
||||
#, fuzzy
|
||||
#| msgid "You already opened an account in the Société générale."
|
||||
msgid ""
|
||||
"The user declared that he/she opened a bank account in the Société générale."
|
||||
msgstr "Sie haben bereits ein Konto in der Société générale eröffnet."
|
||||
|
||||
#: apps/registration/templates/registration/future_profile_detail.html:71
|
||||
#: apps/wei/templates/wei/weimembership_form.html:127
|
||||
#: apps/wei/templates/wei/weimembership_form.html:186
|
||||
msgid "Validate registration"
|
||||
@ -1956,50 +1977,50 @@ msgstr "Die NoteKfet Team."
|
||||
msgid "Register new user"
|
||||
msgstr "Neuen User registrieren"
|
||||
|
||||
#: apps/registration/views.py:85
|
||||
#: apps/registration/views.py:93
|
||||
msgid "Email validation"
|
||||
msgstr "Email validierung"
|
||||
|
||||
#: apps/registration/views.py:87
|
||||
#: apps/registration/views.py:95
|
||||
msgid "Validate email"
|
||||
msgstr "Email validieren"
|
||||
|
||||
#: apps/registration/views.py:129
|
||||
#: apps/registration/views.py:137
|
||||
msgid "Email validation unsuccessful"
|
||||
msgstr "Email validierung unerfolgreich"
|
||||
|
||||
#: apps/registration/views.py:140
|
||||
#: apps/registration/views.py:148
|
||||
msgid "Email validation email sent"
|
||||
msgstr "Validierungsemail wurde gesendet"
|
||||
|
||||
#: apps/registration/views.py:148
|
||||
#: apps/registration/views.py:156
|
||||
msgid "Resend email validation link"
|
||||
msgstr "E-Mail-Validierungslink erneut senden"
|
||||
|
||||
#: apps/registration/views.py:166
|
||||
#: apps/registration/views.py:174
|
||||
msgid "Pre-registered users list"
|
||||
msgstr "Vorregistrierte Userliste"
|
||||
|
||||
#: apps/registration/views.py:190
|
||||
#: apps/registration/views.py:198
|
||||
msgid "Unregistered users"
|
||||
msgstr "Unregistrierte Users"
|
||||
|
||||
#: apps/registration/views.py:203
|
||||
#: apps/registration/views.py:211
|
||||
msgid "Registration detail"
|
||||
msgstr "Registrierung Detailen"
|
||||
|
||||
#: apps/registration/views.py:263
|
||||
#: apps/registration/views.py:273
|
||||
msgid "You must join the BDE."
|
||||
msgstr "Sie müssen die BDE beitreten."
|
||||
|
||||
#: apps/registration/views.py:287
|
||||
#: apps/registration/views.py:297
|
||||
msgid ""
|
||||
"The entered amount is not enough for the memberships, should be at least {}"
|
||||
msgstr ""
|
||||
"Der eingegebene Betrag reicht für die Mitgliedschaft nicht aus, sollte "
|
||||
"mindestens {} betragen"
|
||||
|
||||
#: apps/registration/views.py:367
|
||||
#: apps/registration/views.py:384
|
||||
msgid "Invalidate pre-registration"
|
||||
msgstr "Ungültige Vorregistrierung"
|
||||
|
||||
@ -2145,7 +2166,7 @@ msgstr "spezielle Transaktion Proxies"
|
||||
msgid "credit transaction"
|
||||
msgstr "Kredit Transaktion"
|
||||
|
||||
#: apps/treasury/models.py:369
|
||||
#: apps/treasury/models.py:374
|
||||
msgid ""
|
||||
"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."
|
||||
@ -2153,16 +2174,16 @@ msgstr ""
|
||||
"Dieser Benutzer hat nicht genug Geld, um die Mitgliedschaften mit seiner "
|
||||
"Note zu bezahlen."
|
||||
|
||||
#: apps/treasury/models.py:384
|
||||
#: apps/treasury/models.py:389
|
||||
#: apps/treasury/templates/treasury/sogecredit_detail.html:10
|
||||
msgid "Credit from the Société générale"
|
||||
msgstr "Kredit von der Société générale"
|
||||
|
||||
#: apps/treasury/models.py:385
|
||||
#: apps/treasury/models.py:390
|
||||
msgid "Credits from the Société générale"
|
||||
msgstr "Krediten von der Société générale"
|
||||
|
||||
#: apps/treasury/models.py:388
|
||||
#: apps/treasury/models.py:393
|
||||
#, python-brace-format
|
||||
msgid "Soge credit for {user}"
|
||||
msgstr "Kredit von der Société générale für {user}"
|
||||
@ -2941,19 +2962,19 @@ msgstr "Überprüfen Sie die WEI-Registrierung"
|
||||
msgid "This user didn't give her/his caution check."
|
||||
msgstr "Dieser User hat seine / ihre Vorsicht nicht überprüft."
|
||||
|
||||
#: note_kfet/settings/base.py:155
|
||||
#: note_kfet/settings/base.py:157
|
||||
msgid "German"
|
||||
msgstr "Deutsch"
|
||||
|
||||
#: note_kfet/settings/base.py:156
|
||||
#: note_kfet/settings/base.py:158
|
||||
msgid "English"
|
||||
msgstr "English"
|
||||
|
||||
#: note_kfet/settings/base.py:157
|
||||
#: note_kfet/settings/base.py:159
|
||||
msgid "Spanish"
|
||||
msgstr "Spanisch"
|
||||
|
||||
#: note_kfet/settings/base.py:158
|
||||
#: note_kfet/settings/base.py:160
|
||||
msgid "French"
|
||||
msgstr "Französich"
|
||||
|
||||
@ -3040,7 +3061,7 @@ msgstr "Abmelden"
|
||||
#: note_kfet/templates/base.html:139
|
||||
#: note_kfet/templates/registration/signup.html:6
|
||||
#: note_kfet/templates/registration/signup.html:11
|
||||
#: note_kfet/templates/registration/signup.html:27
|
||||
#: note_kfet/templates/registration/signup.html:28
|
||||
msgid "Sign up"
|
||||
msgstr "Registrieren"
|
||||
|
||||
@ -3052,7 +3073,17 @@ msgstr "Registrieren"
|
||||
msgid "Log in"
|
||||
msgstr "Anmelden"
|
||||
|
||||
#: note_kfet/templates/base.html:158
|
||||
#: note_kfet/templates/base.html:156
|
||||
msgid ""
|
||||
"You are not a BDE member anymore. Please renew your membership if you want "
|
||||
"to use the note."
|
||||
msgstr ""
|
||||
|
||||
#: note_kfet/templates/base.html:160
|
||||
msgid "You are not a Kfet member, so you can't use your note account."
|
||||
msgstr ""
|
||||
|
||||
#: note_kfet/templates/base.html:166
|
||||
msgid ""
|
||||
"Your e-mail address is not validated. Please check your mail inbox and click "
|
||||
"on the validation link."
|
||||
@ -3060,7 +3091,16 @@ msgstr ""
|
||||
"Ihre E-Mail-Adresse ist nicht validiert. Bitte überprüfen Sie Ihren "
|
||||
"Posteingang und klicken Sie auf den Validierungslink."
|
||||
|
||||
#: note_kfet/templates/base.html:175
|
||||
#: note_kfet/templates/base.html:171
|
||||
msgid ""
|
||||
"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 "
|
||||
"registration bonus of 80 € is not credited and the membership is not paid "
|
||||
"yet. This verification procedure may last a few days. Please make sure that "
|
||||
"you go to the end of the account creation."
|
||||
msgstr ""
|
||||
|
||||
#: note_kfet/templates/base.html:194
|
||||
msgid "Contact us"
|
||||
msgstr "Kontakt"
|
||||
|
||||
@ -3072,21 +3112,6 @@ msgstr "Suche nach Attributen wie Name…"
|
||||
msgid "There is no results."
|
||||
msgstr "Es gibt keine Ergebnisse."
|
||||
|
||||
#: note_kfet/templates/cas_server/base.html:7
|
||||
msgid "Central Authentication Service"
|
||||
msgstr "Central Authentication Service"
|
||||
|
||||
#: note_kfet/templates/cas_server/base.html:43
|
||||
#, python-format
|
||||
msgid ""
|
||||
"A new version of the application is available. This instance runs "
|
||||
"%(VERSION)s and the last version is %(LAST_VERSION)s. Please consider "
|
||||
"upgrading."
|
||||
msgstr ""
|
||||
"Eine neue Version der Anwendung ist verfügbar. Diese Instanz führt "
|
||||
"%(VERSION) s aus und die letzte Version ist %(LAST_VERSION) s. Bitte erwägen "
|
||||
"Sie ein Upgrade."
|
||||
|
||||
#: note_kfet/templates/registration/logged_out.html:13
|
||||
msgid "Thanks for spending some quality time with the Web site today."
|
||||
msgstr ""
|
||||
@ -3200,5 +3225,18 @@ msgstr ""
|
||||
"müssen Ihre E-Mail-Adresse auch überprüfen, indem Sie dem Link folgen, den "
|
||||
"Sie erhalten haben."
|
||||
|
||||
#~ msgid "Central Authentication Service"
|
||||
#~ msgstr "Central Authentication Service"
|
||||
|
||||
#, python-format
|
||||
#~ msgid ""
|
||||
#~ "A new version of the application is available. This instance runs "
|
||||
#~ "%(VERSION)s and the last version is %(LAST_VERSION)s. Please consider "
|
||||
#~ "upgrading."
|
||||
#~ msgstr ""
|
||||
#~ "Eine neue Version der Anwendung ist verfügbar. Diese Instanz führt "
|
||||
#~ "%(VERSION) s aus und die letzte Version ist %(LAST_VERSION) s. Bitte "
|
||||
#~ "erwägen Sie ein Upgrade."
|
||||
|
||||
#~ msgid "Check this case is the Société Générale paid the inscription."
|
||||
#~ msgstr "Die Société Générale die Mitgliedschaft bezahlt."
|
||||
|
@ -51,9 +51,9 @@ msgstr "Usted no puede invitar más de 3 persona a esta actividad."
|
||||
#: apps/member/models.py:199
|
||||
#: apps/member/templates/member/includes/club_info.html:4
|
||||
#: apps/member/templates/member/includes/profile_info.html:4
|
||||
#: apps/note/models/notes.py:260 apps/note/models/transactions.py:26
|
||||
#: apps/note/models/transactions.py:46 apps/note/models/transactions.py:297
|
||||
#: apps/permission/models.py:330
|
||||
#: apps/note/models/notes.py:232 apps/note/models/transactions.py:26
|
||||
#: apps/note/models/transactions.py:46 apps/note/models/transactions.py:300
|
||||
#: apps/permission/models.py:333
|
||||
#: apps/registration/templates/registration/future_profile_detail.html:16
|
||||
#: apps/wei/models.py:66 apps/wei/models.py:118
|
||||
#: apps/wei/templates/wei/base.html:26
|
||||
@ -89,8 +89,8 @@ msgstr "tipos de actividad"
|
||||
|
||||
#: apps/activity/models.py:68
|
||||
#: apps/activity/templates/activity/includes/activity_info.html:19
|
||||
#: apps/note/models/transactions.py:81 apps/permission/models.py:110
|
||||
#: apps/permission/models.py:189 apps/wei/models.py:72 apps/wei/models.py:129
|
||||
#: apps/note/models/transactions.py:81 apps/permission/models.py:113
|
||||
#: apps/permission/models.py:192 apps/wei/models.py:72 apps/wei/models.py:129
|
||||
msgid "description"
|
||||
msgstr "descripción"
|
||||
|
||||
@ -104,8 +104,8 @@ msgstr "Lugar donde se organiza la actividad, por ejemplo la Kfet."
|
||||
|
||||
#: apps/activity/models.py:83
|
||||
#: apps/activity/templates/activity/includes/activity_info.html:22
|
||||
#: apps/note/models/notes.py:236 apps/note/models/transactions.py:66
|
||||
#: apps/permission/models.py:164
|
||||
#: apps/note/models/notes.py:208 apps/note/models/transactions.py:66
|
||||
#: apps/permission/models.py:167
|
||||
msgid "type"
|
||||
msgstr "tipo"
|
||||
|
||||
@ -253,15 +253,15 @@ msgstr "quitar"
|
||||
msgid "Type"
|
||||
msgstr "Tipo"
|
||||
|
||||
#: apps/activity/tables.py:82 apps/member/forms.py:185
|
||||
#: apps/registration/forms.py:81 apps/treasury/forms.py:130
|
||||
#: apps/activity/tables.py:82 apps/member/forms.py:186
|
||||
#: apps/registration/forms.py:90 apps/treasury/forms.py:130
|
||||
#: apps/wei/forms/registration.py:96
|
||||
msgid "Last name"
|
||||
msgstr "Apellido"
|
||||
|
||||
#: apps/activity/tables.py:84 apps/member/forms.py:190
|
||||
#: apps/activity/tables.py:84 apps/member/forms.py:191
|
||||
#: apps/note/templates/note/transaction_form.html:134
|
||||
#: apps/registration/forms.py:86 apps/treasury/forms.py:132
|
||||
#: apps/registration/forms.py:95 apps/treasury/forms.py:132
|
||||
#: apps/wei/forms/registration.py:101
|
||||
msgid "First name"
|
||||
msgstr "Nombre"
|
||||
@ -285,7 +285,7 @@ msgid "Guest deleted"
|
||||
msgstr "Lista de los invitados"
|
||||
|
||||
#: apps/activity/templates/activity/activity_entry.html:14
|
||||
#: apps/note/models/transactions.py:253
|
||||
#: apps/note/models/transactions.py:256
|
||||
#: apps/note/templates/note/transaction_form.html:16
|
||||
#: apps/note/templates/note/transaction_form.html:148
|
||||
#: note_kfet/templates/base.html:73
|
||||
@ -293,13 +293,13 @@ msgid "Transfer"
|
||||
msgstr "Transferencia"
|
||||
|
||||
#: apps/activity/templates/activity/activity_entry.html:18
|
||||
#: apps/note/models/transactions.py:313
|
||||
#: apps/note/models/transactions.py:316
|
||||
#: apps/note/templates/note/transaction_form.html:21
|
||||
msgid "Credit"
|
||||
msgstr "Crédito"
|
||||
|
||||
#: apps/activity/templates/activity/activity_entry.html:21
|
||||
#: apps/note/models/transactions.py:313
|
||||
#: apps/note/models/transactions.py:316
|
||||
#: apps/note/templates/note/transaction_form.html:25
|
||||
msgid "Debit"
|
||||
msgstr "Débito"
|
||||
@ -390,41 +390,41 @@ msgstr "modificar"
|
||||
msgid "Invite"
|
||||
msgstr "Invitar"
|
||||
|
||||
#: apps/activity/views.py:34
|
||||
#: apps/activity/views.py:36
|
||||
msgid "Create new activity"
|
||||
msgstr "Crear una nueva actividad"
|
||||
|
||||
#: apps/activity/views.py:65 note_kfet/templates/base.html:91
|
||||
#: apps/activity/views.py:67 note_kfet/templates/base.html:91
|
||||
msgid "Activities"
|
||||
msgstr "Actividades"
|
||||
|
||||
#: apps/activity/views.py:93
|
||||
#: apps/activity/views.py:95
|
||||
msgid "Activity detail"
|
||||
msgstr "Detalles de la actividad"
|
||||
|
||||
#: apps/activity/views.py:113
|
||||
#: apps/activity/views.py:115
|
||||
msgid "Update activity"
|
||||
msgstr "Modificar la actividad"
|
||||
|
||||
#: apps/activity/views.py:140
|
||||
#: apps/activity/views.py:142
|
||||
msgid "Invite guest to the activity \"{}\""
|
||||
msgstr "Invitar alguien para la actividad \"{}\""
|
||||
|
||||
#: apps/activity/views.py:175
|
||||
#: apps/activity/views.py:177
|
||||
msgid "You are not allowed to display the entry interface for this activity."
|
||||
msgstr ""
|
||||
"Usted no tiene derecho a mostrar la interfaz de las entradas para esta "
|
||||
"actividad."
|
||||
|
||||
#: apps/activity/views.py:178
|
||||
#: apps/activity/views.py:180
|
||||
msgid "This activity does not support activity entries."
|
||||
msgstr "Esta actividad no necesita entradas."
|
||||
|
||||
#: apps/activity/views.py:181
|
||||
#: apps/activity/views.py:183
|
||||
msgid "This activity is closed."
|
||||
msgstr "Esta actividad esta cerrada."
|
||||
|
||||
#: apps/activity/views.py:277
|
||||
#: apps/activity/views.py:279
|
||||
msgid "Entry for activity \"{}\""
|
||||
msgstr "Entradas para la actividad \"{}\""
|
||||
|
||||
@ -440,7 +440,7 @@ msgstr "Logs"
|
||||
msgid "IP Address"
|
||||
msgstr "Dirección IP"
|
||||
|
||||
#: apps/logs/models.py:36 apps/permission/models.py:134
|
||||
#: apps/logs/models.py:36 apps/permission/models.py:137
|
||||
msgid "model"
|
||||
msgstr "modelo"
|
||||
|
||||
@ -461,7 +461,7 @@ msgid "create"
|
||||
msgstr "crear"
|
||||
|
||||
#: apps/logs/models.py:65 apps/note/tables.py:165 apps/note/tables.py:201
|
||||
#: apps/permission/models.py:127 apps/treasury/tables.py:38
|
||||
#: apps/permission/models.py:130 apps/treasury/tables.py:38
|
||||
#: apps/wei/tables.py:75
|
||||
msgid "delete"
|
||||
msgstr "suprimir"
|
||||
@ -542,48 +542,48 @@ msgid "This image cannot be loaded."
|
||||
msgstr "Esta imagen no puede ser cargada."
|
||||
|
||||
#: apps/member/forms.py:141 apps/member/views.py:100
|
||||
#: apps/registration/forms.py:33 apps/registration/views.py:244
|
||||
#: apps/registration/forms.py:33 apps/registration/views.py:254
|
||||
msgid "An alias with a similar name already exists."
|
||||
msgstr "Un alias similar ya existe."
|
||||
|
||||
#: apps/member/forms.py:164 apps/registration/forms.py:61
|
||||
#: apps/member/forms.py:165 apps/registration/forms.py:70
|
||||
msgid "Inscription paid by Société Générale"
|
||||
msgstr "Registración pagadas por Société Générale"
|
||||
|
||||
#: apps/member/forms.py:166 apps/registration/forms.py:63
|
||||
#: apps/member/forms.py:167 apps/registration/forms.py:72
|
||||
msgid "Check this case if the Société Générale paid the inscription."
|
||||
msgstr "Marcar esta casilla si Société Générale pagó la registración."
|
||||
|
||||
#: apps/member/forms.py:171 apps/registration/forms.py:68
|
||||
#: apps/member/forms.py:172 apps/registration/forms.py:77
|
||||
#: apps/wei/forms/registration.py:83
|
||||
msgid "Credit type"
|
||||
msgstr "Tipo de crédito"
|
||||
|
||||
#: apps/member/forms.py:172 apps/registration/forms.py:69
|
||||
#: apps/member/forms.py:173 apps/registration/forms.py:78
|
||||
#: apps/wei/forms/registration.py:84
|
||||
msgid "No credit"
|
||||
msgstr "No crédito"
|
||||
|
||||
#: apps/member/forms.py:174
|
||||
#: apps/member/forms.py:175
|
||||
msgid "You can credit the note of the user."
|
||||
msgstr "Usted puede acreditar la note del usuario."
|
||||
|
||||
#: apps/member/forms.py:178 apps/registration/forms.py:74
|
||||
#: apps/member/forms.py:179 apps/registration/forms.py:83
|
||||
#: apps/wei/forms/registration.py:89
|
||||
msgid "Credit amount"
|
||||
msgstr "Valor del crédito"
|
||||
|
||||
#: apps/member/forms.py:195 apps/note/templates/note/transaction_form.html:140
|
||||
#: apps/registration/forms.py:91 apps/treasury/forms.py:134
|
||||
#: apps/member/forms.py:196 apps/note/templates/note/transaction_form.html:140
|
||||
#: apps/registration/forms.py:100 apps/treasury/forms.py:134
|
||||
#: apps/wei/forms/registration.py:106
|
||||
msgid "Bank"
|
||||
msgstr "Banco"
|
||||
|
||||
#: apps/member/forms.py:222
|
||||
#: apps/member/forms.py:223
|
||||
msgid "User"
|
||||
msgstr "Usuario"
|
||||
|
||||
#: apps/member/forms.py:236
|
||||
#: apps/member/forms.py:237
|
||||
msgid "Roles"
|
||||
msgstr "Papeles"
|
||||
|
||||
@ -810,7 +810,7 @@ msgstr ""
|
||||
"prorrogarla."
|
||||
|
||||
#: apps/member/models.py:286 apps/member/models.py:311
|
||||
#: apps/note/models/notes.py:191
|
||||
#: apps/note/models/notes.py:177
|
||||
msgid "club"
|
||||
msgstr "club"
|
||||
|
||||
@ -831,11 +831,11 @@ msgstr "afiliación termina el"
|
||||
msgid "The role {role} does not apply to the club {club}."
|
||||
msgstr "El papel {role} no se encuentra en el club {club}."
|
||||
|
||||
#: apps/member/models.py:430 apps/member/views.py:634
|
||||
#: apps/member/models.py:430 apps/member/views.py:646
|
||||
msgid "User is already a member of the club"
|
||||
msgstr "Usuario ya esta un miembro del club"
|
||||
|
||||
#: apps/member/models.py:442 apps/member/views.py:644
|
||||
#: apps/member/models.py:442 apps/member/views.py:656
|
||||
msgid "User is not a member of the parent club"
|
||||
msgstr "Usuario no es un miembro del club pariente"
|
||||
|
||||
@ -844,7 +844,7 @@ msgstr "Usuario no es un miembro del club pariente"
|
||||
msgid "Membership of {user} for the club {club}"
|
||||
msgstr "Afiliación of {user} for the club {club}"
|
||||
|
||||
#: apps/member/models.py:498 apps/note/models/transactions.py:355
|
||||
#: apps/member/models.py:498 apps/note/models/transactions.py:358
|
||||
msgid "membership"
|
||||
msgstr "afiliación"
|
||||
|
||||
@ -960,8 +960,8 @@ msgstr ""
|
||||
"nuevo posibles."
|
||||
|
||||
#: apps/member/templates/member/club_alias.html:10
|
||||
#: apps/member/templates/member/profile_alias.html:10 apps/member/views.py:238
|
||||
#: apps/member/views.py:436
|
||||
#: apps/member/templates/member/profile_alias.html:10 apps/member/views.py:245
|
||||
#: apps/member/views.py:448
|
||||
msgid "Note aliases"
|
||||
msgstr "Alias de la note"
|
||||
|
||||
@ -1025,7 +1025,7 @@ msgstr "saldo de la cuenta"
|
||||
|
||||
#: apps/member/templates/member/includes/club_info.html:47
|
||||
#: apps/member/templates/member/includes/profile_info.html:20
|
||||
#: apps/note/models/notes.py:283 apps/wei/templates/wei/base.html:66
|
||||
#: apps/note/models/notes.py:255 apps/wei/templates/wei/base.html:66
|
||||
msgid "aliases"
|
||||
msgstr "alias"
|
||||
|
||||
@ -1104,39 +1104,39 @@ msgstr "Este correo tiene que ser valido."
|
||||
msgid "Profile detail"
|
||||
msgstr "Detalles del usuario"
|
||||
|
||||
#: apps/member/views.py:197
|
||||
#: apps/member/views.py:204
|
||||
msgid "Search user"
|
||||
msgstr "Buscar un usuario"
|
||||
|
||||
#: apps/member/views.py:258
|
||||
#: apps/member/views.py:265
|
||||
msgid "Update note picture"
|
||||
msgstr "Modificar la imagen de la note"
|
||||
|
||||
#: apps/member/views.py:304
|
||||
#: apps/member/views.py:311
|
||||
msgid "Manage auth token"
|
||||
msgstr "Gestionar los token de autentificación"
|
||||
|
||||
#: apps/member/views.py:331
|
||||
#: apps/member/views.py:338
|
||||
msgid "Create new club"
|
||||
msgstr "Crear un nuevo club"
|
||||
|
||||
#: apps/member/views.py:350
|
||||
#: apps/member/views.py:357
|
||||
msgid "Search club"
|
||||
msgstr "Buscar un club"
|
||||
|
||||
#: apps/member/views.py:383
|
||||
#: apps/member/views.py:390
|
||||
msgid "Club detail"
|
||||
msgstr "Detalles del club"
|
||||
|
||||
#: apps/member/views.py:459
|
||||
#: apps/member/views.py:471
|
||||
msgid "Update club"
|
||||
msgstr "Modificar el club"
|
||||
|
||||
#: apps/member/views.py:493
|
||||
#: apps/member/views.py:505
|
||||
msgid "Add new member to the club"
|
||||
msgstr "Añadir un nuevo miembro al club"
|
||||
|
||||
#: apps/member/views.py:625 apps/wei/views.py:928
|
||||
#: apps/member/views.py:637 apps/wei/views.py:928
|
||||
msgid ""
|
||||
"This user don't have enough money to join this club, and can't have a "
|
||||
"negative balance."
|
||||
@ -1144,25 +1144,25 @@ msgstr ""
|
||||
"Este usuario no tiene suficiente dinero para unirse a este club, y no puede "
|
||||
"tener un saldo negativo."
|
||||
|
||||
#: apps/member/views.py:648
|
||||
#: apps/member/views.py:660
|
||||
msgid "The membership must start after {:%m-%d-%Y}."
|
||||
msgstr "La afiliación tiene que empezar después del {:%d-%m-%Y}."
|
||||
|
||||
#: apps/member/views.py:653
|
||||
#: apps/member/views.py:665
|
||||
msgid "The membership must begin before {:%m-%d-%Y}."
|
||||
msgstr "La afiliación tiene que empezar antes del {:%d-%m-%Y}."
|
||||
|
||||
#: apps/member/views.py:660 apps/member/views.py:662 apps/member/views.py:664
|
||||
#: apps/registration/views.py:294 apps/registration/views.py:296
|
||||
#: apps/registration/views.py:298 apps/wei/views.py:933 apps/wei/views.py:937
|
||||
#: apps/member/views.py:672 apps/member/views.py:674 apps/member/views.py:676
|
||||
#: apps/registration/views.py:304 apps/registration/views.py:306
|
||||
#: apps/registration/views.py:308 apps/wei/views.py:933 apps/wei/views.py:937
|
||||
msgid "This field is required."
|
||||
msgstr "Este campo es obligatorio."
|
||||
|
||||
#: apps/member/views.py:800
|
||||
#: apps/member/views.py:816
|
||||
msgid "Manage roles of an user in the club"
|
||||
msgstr "Gestionar los papeles de un usuario en el club"
|
||||
|
||||
#: apps/member/views.py:825
|
||||
#: apps/member/views.py:841
|
||||
msgid "Members of the club"
|
||||
msgstr "Miembros del club"
|
||||
|
||||
@ -1181,7 +1181,7 @@ msgid "amount"
|
||||
msgstr "monto"
|
||||
|
||||
#: apps/note/api/serializers.py:183 apps/note/api/serializers.py:189
|
||||
#: apps/note/models/transactions.py:224
|
||||
#: apps/note/models/transactions.py:227
|
||||
msgid ""
|
||||
"The transaction can't be saved since the source note or the destination note "
|
||||
"is not active."
|
||||
@ -1291,51 +1291,51 @@ msgstr "notes de los usuarios"
|
||||
msgid "%(user)s's note"
|
||||
msgstr "Note de %(user)s"
|
||||
|
||||
#: apps/note/models/notes.py:195
|
||||
#: apps/note/models/notes.py:181
|
||||
msgid "club note"
|
||||
msgstr "note de un club"
|
||||
|
||||
#: apps/note/models/notes.py:196
|
||||
#: apps/note/models/notes.py:182
|
||||
msgid "clubs notes"
|
||||
msgstr "notes de los clubs"
|
||||
|
||||
#: apps/note/models/notes.py:202
|
||||
#: apps/note/models/notes.py:188
|
||||
#, python-format
|
||||
msgid "Note of %(club)s club"
|
||||
msgstr "Note del club %(club)s"
|
||||
|
||||
#: apps/note/models/notes.py:242
|
||||
#: apps/note/models/notes.py:214
|
||||
msgid "special note"
|
||||
msgstr "note especial"
|
||||
|
||||
#: apps/note/models/notes.py:243
|
||||
#: apps/note/models/notes.py:215
|
||||
msgid "special notes"
|
||||
msgstr "notes especiales"
|
||||
|
||||
#: apps/note/models/notes.py:266
|
||||
#: apps/note/models/notes.py:238
|
||||
msgid "Invalid alias"
|
||||
msgstr "Alias inválido"
|
||||
|
||||
#: apps/note/models/notes.py:282
|
||||
#: apps/note/models/notes.py:254
|
||||
msgid "alias"
|
||||
msgstr "alias"
|
||||
|
||||
#: apps/note/models/notes.py:306
|
||||
#: apps/note/models/notes.py:278
|
||||
msgid "Alias is too long."
|
||||
msgstr "El alias es demasiado largo."
|
||||
|
||||
#: apps/note/models/notes.py:309
|
||||
#: apps/note/models/notes.py:281
|
||||
msgid ""
|
||||
"This alias contains only complex character. Please use a more simple alias."
|
||||
msgstr ""
|
||||
"Este alias solo contiene caracteres complejos. Por favor usa un alias más "
|
||||
"sencillo."
|
||||
|
||||
#: apps/note/models/notes.py:313
|
||||
#: apps/note/models/notes.py:285
|
||||
msgid "An alias with a similar name already exists: {} "
|
||||
msgstr "Un alias parecido ya existe : {} "
|
||||
|
||||
#: apps/note/models/notes.py:327
|
||||
#: apps/note/models/notes.py:299
|
||||
msgid "You can't delete your main alias."
|
||||
msgstr "No puede suprimir su alias principal."
|
||||
|
||||
@ -1410,33 +1410,33 @@ msgstr ""
|
||||
"El saldo de la note tiene que ser entre - 92 233 720 368 547 758.08 € y 92 "
|
||||
"233 720 368 547 758.07 €."
|
||||
|
||||
#: apps/note/models/transactions.py:273
|
||||
#: apps/note/models/transactions.py:276
|
||||
msgid ""
|
||||
"The destination of this transaction must equal to the destination of the "
|
||||
"template."
|
||||
msgstr ""
|
||||
|
||||
#: apps/note/models/transactions.py:283
|
||||
#: apps/note/models/transactions.py:286
|
||||
msgid "Template"
|
||||
msgstr ""
|
||||
|
||||
#: apps/note/models/transactions.py:286
|
||||
#: apps/note/models/transactions.py:289
|
||||
msgid "recurrent transaction"
|
||||
msgstr ""
|
||||
|
||||
#: apps/note/models/transactions.py:287
|
||||
#: apps/note/models/transactions.py:290
|
||||
msgid "recurrent transactions"
|
||||
msgstr ""
|
||||
|
||||
#: apps/note/models/transactions.py:302
|
||||
#: apps/note/models/transactions.py:305
|
||||
msgid "first_name"
|
||||
msgstr "nombre"
|
||||
|
||||
#: apps/note/models/transactions.py:307
|
||||
#: apps/note/models/transactions.py:310
|
||||
msgid "bank"
|
||||
msgstr "banco"
|
||||
|
||||
#: apps/note/models/transactions.py:324
|
||||
#: apps/note/models/transactions.py:327
|
||||
msgid ""
|
||||
"A special transaction is only possible between a Note associated to a "
|
||||
"payment method and a User or a Club"
|
||||
@ -1444,19 +1444,19 @@ msgstr ""
|
||||
"Una transacción especial solo esta disponible entre una note de un modo de "
|
||||
"pago y un usuario o un club"
|
||||
|
||||
#: apps/note/models/transactions.py:333
|
||||
#: apps/note/models/transactions.py:336
|
||||
msgid "Special transaction"
|
||||
msgstr "Transacción especial"
|
||||
|
||||
#: apps/note/models/transactions.py:334
|
||||
#: apps/note/models/transactions.py:337
|
||||
msgid "Special transactions"
|
||||
msgstr "Transacciones especiales"
|
||||
|
||||
#: apps/note/models/transactions.py:350
|
||||
#: apps/note/models/transactions.py:353
|
||||
msgid "membership transaction"
|
||||
msgstr "transacción de afiliación"
|
||||
|
||||
#: apps/note/models/transactions.py:351 apps/treasury/models.py:284
|
||||
#: apps/note/models/transactions.py:354 apps/treasury/models.py:284
|
||||
msgid "membership transactions"
|
||||
msgstr "transacciones de afiliación"
|
||||
|
||||
@ -1646,53 +1646,53 @@ msgstr "Usted no puede ver ningún botón."
|
||||
msgid "Search transactions"
|
||||
msgstr "Buscar transacciones"
|
||||
|
||||
#: apps/permission/models.py:89
|
||||
#: apps/permission/models.py:92
|
||||
#, python-brace-format
|
||||
msgid "Can {type} {model}.{field} in {query}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/permission/models.py:91
|
||||
#: apps/permission/models.py:94
|
||||
#, python-brace-format
|
||||
msgid "Can {type} {model} in {query}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/permission/models.py:104
|
||||
#: apps/permission/models.py:107
|
||||
msgid "rank"
|
||||
msgstr "posición"
|
||||
|
||||
#: apps/permission/models.py:117
|
||||
#: apps/permission/models.py:120
|
||||
msgid "permission mask"
|
||||
msgstr "antifaz de permisos"
|
||||
|
||||
#: apps/permission/models.py:118
|
||||
#: apps/permission/models.py:121
|
||||
msgid "permission masks"
|
||||
msgstr "antifaces de permisos"
|
||||
|
||||
#: apps/permission/models.py:124
|
||||
#: apps/permission/models.py:127
|
||||
msgid "add"
|
||||
msgstr "añadir"
|
||||
|
||||
#: apps/permission/models.py:125
|
||||
#: apps/permission/models.py:128
|
||||
msgid "view"
|
||||
msgstr "ver"
|
||||
|
||||
#: apps/permission/models.py:126
|
||||
#: apps/permission/models.py:129
|
||||
msgid "change"
|
||||
msgstr "cambiar"
|
||||
|
||||
#: apps/permission/models.py:158
|
||||
#: apps/permission/models.py:161
|
||||
msgid "query"
|
||||
msgstr "consulta"
|
||||
|
||||
#: apps/permission/models.py:171
|
||||
#: apps/permission/models.py:174
|
||||
msgid "mask"
|
||||
msgstr "antifaz"
|
||||
|
||||
#: apps/permission/models.py:177
|
||||
#: apps/permission/models.py:180
|
||||
msgid "field"
|
||||
msgstr "campo"
|
||||
|
||||
#: apps/permission/models.py:182
|
||||
#: apps/permission/models.py:185
|
||||
msgid ""
|
||||
"Tells if the permission should be granted even if the membership of the user "
|
||||
"is expired."
|
||||
@ -1700,30 +1700,30 @@ msgstr ""
|
||||
"Indica si el permiso tiene que ser dado aunque la afiliación del usuario "
|
||||
"terminó."
|
||||
|
||||
#: apps/permission/models.py:183
|
||||
#: apps/permission/models.py:186
|
||||
#: apps/permission/templates/permission/all_rights.html:89
|
||||
msgid "permanent"
|
||||
msgstr "permanente"
|
||||
|
||||
#: apps/permission/models.py:194
|
||||
#: apps/permission/models.py:197
|
||||
msgid "permission"
|
||||
msgstr "permiso"
|
||||
|
||||
#: apps/permission/models.py:195 apps/permission/models.py:335
|
||||
#: apps/permission/models.py:198 apps/permission/models.py:338
|
||||
msgid "permissions"
|
||||
msgstr "permisos"
|
||||
|
||||
#: apps/permission/models.py:200
|
||||
#: apps/permission/models.py:203
|
||||
msgid "Specifying field applies only to view and change permission types."
|
||||
msgstr ""
|
||||
"Especifica el campo interesado, solo funciona para los permisos view y "
|
||||
"change."
|
||||
|
||||
#: apps/permission/models.py:340
|
||||
#: apps/permission/models.py:343
|
||||
msgid "for club"
|
||||
msgstr "interesa el club"
|
||||
|
||||
#: apps/permission/models.py:350 apps/permission/models.py:351
|
||||
#: apps/permission/models.py:353 apps/permission/models.py:354
|
||||
msgid "role permissions"
|
||||
msgstr "permisos por papeles"
|
||||
|
||||
@ -1827,10 +1827,24 @@ msgid "This email address is already used."
|
||||
msgstr "Este correo electrónico ya esta utilizado."
|
||||
|
||||
#: apps/registration/forms.py:49
|
||||
#, fuzzy
|
||||
#| msgid "You already opened an account in the Société générale."
|
||||
msgid ""
|
||||
"I declare that I opened a bank account in the Société générale with the BDE "
|
||||
"partnership."
|
||||
msgstr "Usted ya abrió una cuenta a la Société Générale."
|
||||
|
||||
#: apps/registration/forms.py:50
|
||||
msgid ""
|
||||
"Warning: this engages you to open your bank account. If you finally decides "
|
||||
"to don't open your account, you will have to pay the BDE membership."
|
||||
msgstr ""
|
||||
|
||||
#: apps/registration/forms.py:58
|
||||
msgid "Register to the WEI"
|
||||
msgstr "Registrarse en el WEI"
|
||||
|
||||
#: apps/registration/forms.py:51
|
||||
#: apps/registration/forms.py:60
|
||||
msgid ""
|
||||
"Check this case if you want to register to the WEI. If you hesitate, you "
|
||||
"will be able to register later, after validating your account in the Kfet."
|
||||
@ -1838,11 +1852,11 @@ msgstr ""
|
||||
"Marcar esta casilla si usted quiere registrarse en el WEI. Si duda, podrá "
|
||||
"registrarse más tarde, después de validar su cuenta Note Kfet."
|
||||
|
||||
#: apps/registration/forms.py:96
|
||||
#: apps/registration/forms.py:105
|
||||
msgid "Join BDE Club"
|
||||
msgstr "Afiliarse al club BDE"
|
||||
|
||||
#: apps/registration/forms.py:103
|
||||
#: apps/registration/forms.py:112
|
||||
msgid "Join Kfet Club"
|
||||
msgstr "Afiliarse al club Kfet"
|
||||
|
||||
@ -1894,7 +1908,14 @@ msgstr "Suprimir afiliación"
|
||||
msgid "Validate account"
|
||||
msgstr "Validar la cuenta"
|
||||
|
||||
#: apps/registration/templates/registration/future_profile_detail.html:64
|
||||
#: apps/registration/templates/registration/future_profile_detail.html:62
|
||||
#, fuzzy
|
||||
#| msgid "You already opened an account in the Société générale."
|
||||
msgid ""
|
||||
"The user declared that he/she opened a bank account in the Société générale."
|
||||
msgstr "Usted ya abrió una cuenta a la Société Générale."
|
||||
|
||||
#: apps/registration/templates/registration/future_profile_detail.html:71
|
||||
#: apps/wei/templates/wei/weimembership_form.html:127
|
||||
#: apps/wei/templates/wei/weimembership_form.html:186
|
||||
msgid "Validate registration"
|
||||
@ -1950,50 +1971,50 @@ msgstr "El equipo Note Kfet."
|
||||
msgid "Register new user"
|
||||
msgstr "Registrar un nuevo usuario"
|
||||
|
||||
#: apps/registration/views.py:85
|
||||
#: apps/registration/views.py:93
|
||||
msgid "Email validation"
|
||||
msgstr "Validación del correo electrónico"
|
||||
|
||||
#: apps/registration/views.py:87
|
||||
#: apps/registration/views.py:95
|
||||
msgid "Validate email"
|
||||
msgstr "Validar el correo electrónico"
|
||||
|
||||
#: apps/registration/views.py:129
|
||||
#: apps/registration/views.py:137
|
||||
msgid "Email validation unsuccessful"
|
||||
msgstr "La validación del correo electrónico fracasó"
|
||||
|
||||
#: apps/registration/views.py:140
|
||||
#: apps/registration/views.py:148
|
||||
msgid "Email validation email sent"
|
||||
msgstr "Correo de validación enviado"
|
||||
|
||||
#: apps/registration/views.py:148
|
||||
#: apps/registration/views.py:156
|
||||
msgid "Resend email validation link"
|
||||
msgstr "Reenviar el enlace de validación"
|
||||
|
||||
#: apps/registration/views.py:166
|
||||
#: apps/registration/views.py:174
|
||||
msgid "Pre-registered users list"
|
||||
msgstr "Lista de los usuarios con afiliación pendiente"
|
||||
|
||||
#: apps/registration/views.py:190
|
||||
#: apps/registration/views.py:198
|
||||
msgid "Unregistered users"
|
||||
msgstr "Usuarios con afiliación pendiente"
|
||||
|
||||
#: apps/registration/views.py:203
|
||||
#: apps/registration/views.py:211
|
||||
msgid "Registration detail"
|
||||
msgstr "Detalles de la afiliación"
|
||||
|
||||
#: apps/registration/views.py:263
|
||||
#: apps/registration/views.py:273
|
||||
msgid "You must join the BDE."
|
||||
msgstr "Usted tiene que afiliarse al BDE."
|
||||
|
||||
#: apps/registration/views.py:287
|
||||
#: apps/registration/views.py:297
|
||||
msgid ""
|
||||
"The entered amount is not enough for the memberships, should be at least {}"
|
||||
msgstr ""
|
||||
"El monto dado no es suficiente para las afiliaciones, tiene que ser al menos "
|
||||
"{}"
|
||||
|
||||
#: apps/registration/views.py:367
|
||||
#: apps/registration/views.py:384
|
||||
msgid "Invalidate pre-registration"
|
||||
msgstr "Invalidar la afiliación"
|
||||
|
||||
@ -2139,7 +2160,7 @@ msgstr "proxys de transacciones especiales"
|
||||
msgid "credit transaction"
|
||||
msgstr "transacción de crédito"
|
||||
|
||||
#: apps/treasury/models.py:369
|
||||
#: apps/treasury/models.py:374
|
||||
msgid ""
|
||||
"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."
|
||||
@ -2148,16 +2169,16 @@ msgstr ""
|
||||
"afiliaciones. Por favor pídelo acreditar su note antes de invalidar este "
|
||||
"crédito."
|
||||
|
||||
#: apps/treasury/models.py:384
|
||||
#: apps/treasury/models.py:389
|
||||
#: apps/treasury/templates/treasury/sogecredit_detail.html:10
|
||||
msgid "Credit from the Société générale"
|
||||
msgstr "Crédito de la Société Générale"
|
||||
|
||||
#: apps/treasury/models.py:385
|
||||
#: apps/treasury/models.py:390
|
||||
msgid "Credits from the Société générale"
|
||||
msgstr "Créditos de la Société Générale"
|
||||
|
||||
#: apps/treasury/models.py:388
|
||||
#: apps/treasury/models.py:393
|
||||
#, python-brace-format
|
||||
msgid "Soge credit for {user}"
|
||||
msgstr "Crédito de la Société Générale para {user}"
|
||||
@ -2925,19 +2946,19 @@ msgstr "Validar la inscripción WEI"
|
||||
msgid "This user didn't give her/his caution check."
|
||||
msgstr "Este usuario no dio su cheque de garantía."
|
||||
|
||||
#: note_kfet/settings/base.py:155
|
||||
#: note_kfet/settings/base.py:157
|
||||
msgid "German"
|
||||
msgstr "Alemán"
|
||||
|
||||
#: note_kfet/settings/base.py:156
|
||||
#: note_kfet/settings/base.py:158
|
||||
msgid "English"
|
||||
msgstr "Ingles"
|
||||
|
||||
#: note_kfet/settings/base.py:157
|
||||
#: note_kfet/settings/base.py:159
|
||||
msgid "Spanish"
|
||||
msgstr "Español"
|
||||
|
||||
#: note_kfet/settings/base.py:158
|
||||
#: note_kfet/settings/base.py:160
|
||||
msgid "French"
|
||||
msgstr "Francés"
|
||||
|
||||
@ -3022,7 +3043,7 @@ msgstr "Desconectarse"
|
||||
#: note_kfet/templates/base.html:139
|
||||
#: note_kfet/templates/registration/signup.html:6
|
||||
#: note_kfet/templates/registration/signup.html:11
|
||||
#: note_kfet/templates/registration/signup.html:27
|
||||
#: note_kfet/templates/registration/signup.html:28
|
||||
msgid "Sign up"
|
||||
msgstr "Registrar"
|
||||
|
||||
@ -3034,7 +3055,17 @@ msgstr "Registrar"
|
||||
msgid "Log in"
|
||||
msgstr "Conectarse"
|
||||
|
||||
#: note_kfet/templates/base.html:158
|
||||
#: note_kfet/templates/base.html:156
|
||||
msgid ""
|
||||
"You are not a BDE member anymore. Please renew your membership if you want "
|
||||
"to use the note."
|
||||
msgstr ""
|
||||
|
||||
#: note_kfet/templates/base.html:160
|
||||
msgid "You are not a Kfet member, so you can't use your note account."
|
||||
msgstr ""
|
||||
|
||||
#: note_kfet/templates/base.html:166
|
||||
msgid ""
|
||||
"Your e-mail address is not validated. Please check your mail inbox and click "
|
||||
"on the validation link."
|
||||
@ -3042,7 +3073,16 @@ msgstr ""
|
||||
"Su correo electrónico no fue validado. Por favor mire en sus correos y haga "
|
||||
"clic en el enlace de validación."
|
||||
|
||||
#: note_kfet/templates/base.html:175
|
||||
#: note_kfet/templates/base.html:171
|
||||
msgid ""
|
||||
"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 "
|
||||
"registration bonus of 80 € is not credited and the membership is not paid "
|
||||
"yet. This verification procedure may last a few days. Please make sure that "
|
||||
"you go to the end of the account creation."
|
||||
msgstr ""
|
||||
|
||||
#: note_kfet/templates/base.html:194
|
||||
msgid "Contact us"
|
||||
msgstr "Contactarnos"
|
||||
|
||||
@ -3054,20 +3094,6 @@ msgstr "Buscar con atributo, como el nombre…"
|
||||
msgid "There is no results."
|
||||
msgstr "No hay resultado."
|
||||
|
||||
#: note_kfet/templates/cas_server/base.html:7
|
||||
msgid "Central Authentication Service"
|
||||
msgstr "Servicio Central de Autentificación"
|
||||
|
||||
#: note_kfet/templates/cas_server/base.html:43
|
||||
#, python-format
|
||||
msgid ""
|
||||
"A new version of the application is available. This instance runs "
|
||||
"%(VERSION)s and the last version is %(LAST_VERSION)s. Please consider "
|
||||
"upgrading."
|
||||
msgstr ""
|
||||
"Una nueva versión es disponible. Se está usando %(VERSION)s y la ultima "
|
||||
"versión está %(LAST_VERSION)s. Piensa en actualizar."
|
||||
|
||||
#: note_kfet/templates/registration/logged_out.html:13
|
||||
msgid "Thanks for spending some quality time with the Web site today."
|
||||
msgstr "Gracias por usar la Note Kfet."
|
||||
@ -3176,6 +3202,18 @@ msgstr ""
|
||||
"pagar su afiliación. Tambien tiene que validar su correo electronico con el "
|
||||
"enlace que recibió."
|
||||
|
||||
#~ msgid "Central Authentication Service"
|
||||
#~ msgstr "Servicio Central de Autentificación"
|
||||
|
||||
#, python-format
|
||||
#~ msgid ""
|
||||
#~ "A new version of the application is available. This instance runs "
|
||||
#~ "%(VERSION)s and the last version is %(LAST_VERSION)s. Please consider "
|
||||
#~ "upgrading."
|
||||
#~ msgstr ""
|
||||
#~ "Una nueva versión es disponible. Se está usando %(VERSION)s y la ultima "
|
||||
#~ "versión está %(LAST_VERSION)s. Piensa en actualizar."
|
||||
|
||||
#~ msgid "Check this case is the Société Générale paid the inscription."
|
||||
#~ msgstr "Marcar esta casilla si Société Générale pagó la registración."
|
||||
|
||||
|
@ -52,9 +52,9 @@ msgstr "Vous ne pouvez pas inviter plus de 3 personnes à cette activité."
|
||||
#: apps/member/models.py:199
|
||||
#: apps/member/templates/member/includes/club_info.html:4
|
||||
#: apps/member/templates/member/includes/profile_info.html:4
|
||||
#: apps/note/models/notes.py:260 apps/note/models/transactions.py:26
|
||||
#: apps/note/models/transactions.py:46 apps/note/models/transactions.py:297
|
||||
#: apps/permission/models.py:330
|
||||
#: apps/note/models/notes.py:232 apps/note/models/transactions.py:26
|
||||
#: apps/note/models/transactions.py:46 apps/note/models/transactions.py:300
|
||||
#: apps/permission/models.py:333
|
||||
#: apps/registration/templates/registration/future_profile_detail.html:16
|
||||
#: apps/wei/models.py:66 apps/wei/models.py:118
|
||||
#: apps/wei/templates/wei/base.html:26
|
||||
@ -90,8 +90,8 @@ msgstr "types d'activité"
|
||||
|
||||
#: apps/activity/models.py:68
|
||||
#: apps/activity/templates/activity/includes/activity_info.html:19
|
||||
#: apps/note/models/transactions.py:81 apps/permission/models.py:110
|
||||
#: apps/permission/models.py:189 apps/wei/models.py:72 apps/wei/models.py:129
|
||||
#: apps/note/models/transactions.py:81 apps/permission/models.py:113
|
||||
#: apps/permission/models.py:192 apps/wei/models.py:72 apps/wei/models.py:129
|
||||
msgid "description"
|
||||
msgstr "description"
|
||||
|
||||
@ -105,8 +105,8 @@ msgstr "Lieu où l'activité est organisée, par exemple la Kfet."
|
||||
|
||||
#: apps/activity/models.py:83
|
||||
#: apps/activity/templates/activity/includes/activity_info.html:22
|
||||
#: apps/note/models/notes.py:236 apps/note/models/transactions.py:66
|
||||
#: apps/permission/models.py:164
|
||||
#: apps/note/models/notes.py:208 apps/note/models/transactions.py:66
|
||||
#: apps/permission/models.py:167
|
||||
msgid "type"
|
||||
msgstr "type"
|
||||
|
||||
@ -254,15 +254,15 @@ msgstr "supprimer"
|
||||
msgid "Type"
|
||||
msgstr "Type"
|
||||
|
||||
#: apps/activity/tables.py:82 apps/member/forms.py:185
|
||||
#: apps/registration/forms.py:81 apps/treasury/forms.py:130
|
||||
#: apps/activity/tables.py:82 apps/member/forms.py:186
|
||||
#: apps/registration/forms.py:90 apps/treasury/forms.py:130
|
||||
#: apps/wei/forms/registration.py:96
|
||||
msgid "Last name"
|
||||
msgstr "Nom de famille"
|
||||
|
||||
#: apps/activity/tables.py:84 apps/member/forms.py:190
|
||||
#: apps/activity/tables.py:84 apps/member/forms.py:191
|
||||
#: apps/note/templates/note/transaction_form.html:134
|
||||
#: apps/registration/forms.py:86 apps/treasury/forms.py:132
|
||||
#: apps/registration/forms.py:95 apps/treasury/forms.py:132
|
||||
#: apps/wei/forms/registration.py:101
|
||||
msgid "First name"
|
||||
msgstr "Prénom"
|
||||
@ -284,7 +284,7 @@ msgid "Guest deleted"
|
||||
msgstr "Invité supprimé"
|
||||
|
||||
#: apps/activity/templates/activity/activity_entry.html:14
|
||||
#: apps/note/models/transactions.py:253
|
||||
#: apps/note/models/transactions.py:256
|
||||
#: apps/note/templates/note/transaction_form.html:16
|
||||
#: apps/note/templates/note/transaction_form.html:148
|
||||
#: note_kfet/templates/base.html:73
|
||||
@ -292,13 +292,13 @@ msgid "Transfer"
|
||||
msgstr "Virement"
|
||||
|
||||
#: apps/activity/templates/activity/activity_entry.html:18
|
||||
#: apps/note/models/transactions.py:313
|
||||
#: apps/note/models/transactions.py:316
|
||||
#: apps/note/templates/note/transaction_form.html:21
|
||||
msgid "Credit"
|
||||
msgstr "Crédit"
|
||||
|
||||
#: apps/activity/templates/activity/activity_entry.html:21
|
||||
#: apps/note/models/transactions.py:313
|
||||
#: apps/note/models/transactions.py:316
|
||||
#: apps/note/templates/note/transaction_form.html:25
|
||||
msgid "Debit"
|
||||
msgstr "Débit"
|
||||
@ -388,41 +388,41 @@ msgstr "modifier"
|
||||
msgid "Invite"
|
||||
msgstr "Inviter"
|
||||
|
||||
#: apps/activity/views.py:34
|
||||
#: apps/activity/views.py:36
|
||||
msgid "Create new activity"
|
||||
msgstr "Créer une nouvelle activité"
|
||||
|
||||
#: apps/activity/views.py:65 note_kfet/templates/base.html:91
|
||||
#: apps/activity/views.py:67 note_kfet/templates/base.html:91
|
||||
msgid "Activities"
|
||||
msgstr "Activités"
|
||||
|
||||
#: apps/activity/views.py:93
|
||||
#: apps/activity/views.py:95
|
||||
msgid "Activity detail"
|
||||
msgstr "Détails de l'activité"
|
||||
|
||||
#: apps/activity/views.py:113
|
||||
#: apps/activity/views.py:115
|
||||
msgid "Update activity"
|
||||
msgstr "Modifier l'activité"
|
||||
|
||||
#: apps/activity/views.py:140
|
||||
#: apps/activity/views.py:142
|
||||
msgid "Invite guest to the activity \"{}\""
|
||||
msgstr "Invitation pour l'activité « {} »"
|
||||
|
||||
#: apps/activity/views.py:175
|
||||
#: apps/activity/views.py:177
|
||||
msgid "You are not allowed to display the entry interface for this activity."
|
||||
msgstr ""
|
||||
"Vous n'êtes pas autorisé à afficher l'interface des entrées pour cette "
|
||||
"activité."
|
||||
|
||||
#: apps/activity/views.py:178
|
||||
#: apps/activity/views.py:180
|
||||
msgid "This activity does not support activity entries."
|
||||
msgstr "Cette activité ne requiert pas d'entrées."
|
||||
|
||||
#: apps/activity/views.py:181
|
||||
#: apps/activity/views.py:183
|
||||
msgid "This activity is closed."
|
||||
msgstr "Cette activité est fermée."
|
||||
|
||||
#: apps/activity/views.py:277
|
||||
#: apps/activity/views.py:279
|
||||
msgid "Entry for activity \"{}\""
|
||||
msgstr "Entrées pour l'activité « {} »"
|
||||
|
||||
@ -438,7 +438,7 @@ msgstr "Logs"
|
||||
msgid "IP Address"
|
||||
msgstr "Adresse IP"
|
||||
|
||||
#: apps/logs/models.py:36 apps/permission/models.py:134
|
||||
#: apps/logs/models.py:36 apps/permission/models.py:137
|
||||
msgid "model"
|
||||
msgstr "modèle"
|
||||
|
||||
@ -459,7 +459,7 @@ msgid "create"
|
||||
msgstr "créer"
|
||||
|
||||
#: apps/logs/models.py:65 apps/note/tables.py:165 apps/note/tables.py:201
|
||||
#: apps/permission/models.py:127 apps/treasury/tables.py:38
|
||||
#: apps/permission/models.py:130 apps/treasury/tables.py:38
|
||||
#: apps/wei/tables.py:75
|
||||
msgid "delete"
|
||||
msgstr "supprimer"
|
||||
@ -540,48 +540,48 @@ msgid "This image cannot be loaded."
|
||||
msgstr "Cette image ne peut pas être chargée."
|
||||
|
||||
#: apps/member/forms.py:141 apps/member/views.py:100
|
||||
#: apps/registration/forms.py:33 apps/registration/views.py:244
|
||||
#: apps/registration/forms.py:33 apps/registration/views.py:254
|
||||
msgid "An alias with a similar name already exists."
|
||||
msgstr "Un alias avec un nom similaire existe déjà."
|
||||
|
||||
#: apps/member/forms.py:164 apps/registration/forms.py:61
|
||||
#: apps/member/forms.py:165 apps/registration/forms.py:70
|
||||
msgid "Inscription paid by Société Générale"
|
||||
msgstr "Inscription payée par la Société générale"
|
||||
|
||||
#: apps/member/forms.py:166 apps/registration/forms.py:63
|
||||
#: apps/member/forms.py:167 apps/registration/forms.py:72
|
||||
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."
|
||||
|
||||
#: apps/member/forms.py:171 apps/registration/forms.py:68
|
||||
#: apps/member/forms.py:172 apps/registration/forms.py:77
|
||||
#: apps/wei/forms/registration.py:83
|
||||
msgid "Credit type"
|
||||
msgstr "Type de rechargement"
|
||||
|
||||
#: apps/member/forms.py:172 apps/registration/forms.py:69
|
||||
#: apps/member/forms.py:173 apps/registration/forms.py:78
|
||||
#: apps/wei/forms/registration.py:84
|
||||
msgid "No credit"
|
||||
msgstr "Pas de rechargement"
|
||||
|
||||
#: apps/member/forms.py:174
|
||||
#: apps/member/forms.py:175
|
||||
msgid "You can credit the note of the user."
|
||||
msgstr "Vous pouvez créditer la note de l'utilisateur avant l'adhésion."
|
||||
|
||||
#: apps/member/forms.py:178 apps/registration/forms.py:74
|
||||
#: apps/member/forms.py:179 apps/registration/forms.py:83
|
||||
#: apps/wei/forms/registration.py:89
|
||||
msgid "Credit amount"
|
||||
msgstr "Montant à créditer"
|
||||
|
||||
#: apps/member/forms.py:195 apps/note/templates/note/transaction_form.html:140
|
||||
#: apps/registration/forms.py:91 apps/treasury/forms.py:134
|
||||
#: apps/member/forms.py:196 apps/note/templates/note/transaction_form.html:140
|
||||
#: apps/registration/forms.py:100 apps/treasury/forms.py:134
|
||||
#: apps/wei/forms/registration.py:106
|
||||
msgid "Bank"
|
||||
msgstr "Banque"
|
||||
|
||||
#: apps/member/forms.py:222
|
||||
#: apps/member/forms.py:223
|
||||
msgid "User"
|
||||
msgstr "Utilisateur"
|
||||
|
||||
#: apps/member/forms.py:236
|
||||
#: apps/member/forms.py:237
|
||||
msgid "Roles"
|
||||
msgstr "Rôles"
|
||||
|
||||
@ -809,7 +809,7 @@ msgstr ""
|
||||
"renouveler."
|
||||
|
||||
#: apps/member/models.py:286 apps/member/models.py:311
|
||||
#: apps/note/models/notes.py:191
|
||||
#: apps/note/models/notes.py:177
|
||||
msgid "club"
|
||||
msgstr "club"
|
||||
|
||||
@ -830,11 +830,11 @@ msgstr "l'adhésion finit le"
|
||||
msgid "The role {role} does not apply to the club {club}."
|
||||
msgstr "Le rôle {role} ne s'applique pas au club {club}."
|
||||
|
||||
#: apps/member/models.py:430 apps/member/views.py:634
|
||||
#: apps/member/models.py:430 apps/member/views.py:646
|
||||
msgid "User is already a member of the club"
|
||||
msgstr "L'utilisateur est déjà membre du club"
|
||||
|
||||
#: apps/member/models.py:442 apps/member/views.py:644
|
||||
#: apps/member/models.py:442 apps/member/views.py:656
|
||||
msgid "User is not a member of the parent club"
|
||||
msgstr "L'utilisateur n'est pas membre du club parent"
|
||||
|
||||
@ -843,7 +843,7 @@ msgstr "L'utilisateur n'est pas membre du club parent"
|
||||
msgid "Membership of {user} for the club {club}"
|
||||
msgstr "Adhésion de {user} pour le club {club}"
|
||||
|
||||
#: apps/member/models.py:498 apps/note/models/transactions.py:355
|
||||
#: apps/member/models.py:498 apps/note/models/transactions.py:358
|
||||
msgid "membership"
|
||||
msgstr "adhésion"
|
||||
|
||||
@ -959,8 +959,8 @@ msgstr ""
|
||||
"à nouveau possible."
|
||||
|
||||
#: apps/member/templates/member/club_alias.html:10
|
||||
#: apps/member/templates/member/profile_alias.html:10 apps/member/views.py:238
|
||||
#: apps/member/views.py:436
|
||||
#: apps/member/templates/member/profile_alias.html:10 apps/member/views.py:245
|
||||
#: apps/member/views.py:448
|
||||
msgid "Note aliases"
|
||||
msgstr "Alias de la note"
|
||||
|
||||
@ -1024,7 +1024,7 @@ msgstr "solde du compte"
|
||||
|
||||
#: apps/member/templates/member/includes/club_info.html:47
|
||||
#: apps/member/templates/member/includes/profile_info.html:20
|
||||
#: apps/note/models/notes.py:283 apps/wei/templates/wei/base.html:66
|
||||
#: apps/note/models/notes.py:255 apps/wei/templates/wei/base.html:66
|
||||
msgid "aliases"
|
||||
msgstr "alias"
|
||||
|
||||
@ -1103,39 +1103,39 @@ msgstr "Cette adresse doit être valide."
|
||||
msgid "Profile detail"
|
||||
msgstr "Détails de l'utilisateur"
|
||||
|
||||
#: apps/member/views.py:197
|
||||
#: apps/member/views.py:204
|
||||
msgid "Search user"
|
||||
msgstr "Chercher un utilisateur"
|
||||
|
||||
#: apps/member/views.py:258
|
||||
#: apps/member/views.py:265
|
||||
msgid "Update note picture"
|
||||
msgstr "Modifier la photo de la note"
|
||||
|
||||
#: apps/member/views.py:304
|
||||
#: apps/member/views.py:311
|
||||
msgid "Manage auth token"
|
||||
msgstr "Gérer les jetons d'authentification"
|
||||
|
||||
#: apps/member/views.py:331
|
||||
#: apps/member/views.py:338
|
||||
msgid "Create new club"
|
||||
msgstr "Créer un nouveau club"
|
||||
|
||||
#: apps/member/views.py:350
|
||||
#: apps/member/views.py:357
|
||||
msgid "Search club"
|
||||
msgstr "Chercher un club"
|
||||
|
||||
#: apps/member/views.py:383
|
||||
#: apps/member/views.py:390
|
||||
msgid "Club detail"
|
||||
msgstr "Détails du club"
|
||||
|
||||
#: apps/member/views.py:459
|
||||
#: apps/member/views.py:471
|
||||
msgid "Update club"
|
||||
msgstr "Modifier le club"
|
||||
|
||||
#: apps/member/views.py:493
|
||||
#: apps/member/views.py:505
|
||||
msgid "Add new member to the club"
|
||||
msgstr "Ajouter un nouveau membre au club"
|
||||
|
||||
#: apps/member/views.py:625 apps/wei/views.py:928
|
||||
#: apps/member/views.py:637 apps/wei/views.py:928
|
||||
msgid ""
|
||||
"This user don't have enough money to join this club, and can't have a "
|
||||
"negative balance."
|
||||
@ -1143,25 +1143,25 @@ msgstr ""
|
||||
"Cet utilisateur n'a pas assez d'argent pour rejoindre ce club et ne peut pas "
|
||||
"avoir un solde négatif."
|
||||
|
||||
#: apps/member/views.py:648
|
||||
#: apps/member/views.py:660
|
||||
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:653
|
||||
#: apps/member/views.py:665
|
||||
msgid "The membership must begin before {:%m-%d-%Y}."
|
||||
msgstr "L'adhésion doit commencer avant le {:%d/%m/%Y}."
|
||||
|
||||
#: apps/member/views.py:660 apps/member/views.py:662 apps/member/views.py:664
|
||||
#: apps/registration/views.py:294 apps/registration/views.py:296
|
||||
#: apps/registration/views.py:298 apps/wei/views.py:933 apps/wei/views.py:937
|
||||
#: apps/member/views.py:672 apps/member/views.py:674 apps/member/views.py:676
|
||||
#: apps/registration/views.py:304 apps/registration/views.py:306
|
||||
#: apps/registration/views.py:308 apps/wei/views.py:933 apps/wei/views.py:937
|
||||
msgid "This field is required."
|
||||
msgstr "Ce champ est requis."
|
||||
|
||||
#: apps/member/views.py:800
|
||||
#: apps/member/views.py:816
|
||||
msgid "Manage roles of an user in the club"
|
||||
msgstr "Gérer les rôles d'un utilisateur dans le club"
|
||||
|
||||
#: apps/member/views.py:825
|
||||
#: apps/member/views.py:841
|
||||
msgid "Members of the club"
|
||||
msgstr "Membres du club"
|
||||
|
||||
@ -1180,7 +1180,7 @@ msgid "amount"
|
||||
msgstr "montant"
|
||||
|
||||
#: apps/note/api/serializers.py:183 apps/note/api/serializers.py:189
|
||||
#: apps/note/models/transactions.py:224
|
||||
#: apps/note/models/transactions.py:227
|
||||
msgid ""
|
||||
"The transaction can't be saved since the source note or the destination note "
|
||||
"is not active."
|
||||
@ -1290,51 +1290,51 @@ msgstr "notes des utilisateurs"
|
||||
msgid "%(user)s's note"
|
||||
msgstr "Note de %(user)s"
|
||||
|
||||
#: apps/note/models/notes.py:195
|
||||
#: apps/note/models/notes.py:181
|
||||
msgid "club note"
|
||||
msgstr "note d'un club"
|
||||
|
||||
#: apps/note/models/notes.py:196
|
||||
#: apps/note/models/notes.py:182
|
||||
msgid "clubs notes"
|
||||
msgstr "notes des clubs"
|
||||
|
||||
#: apps/note/models/notes.py:202
|
||||
#: apps/note/models/notes.py:188
|
||||
#, python-format
|
||||
msgid "Note of %(club)s club"
|
||||
msgstr "Note du club %(club)s"
|
||||
|
||||
#: apps/note/models/notes.py:242
|
||||
#: apps/note/models/notes.py:214
|
||||
msgid "special note"
|
||||
msgstr "note spéciale"
|
||||
|
||||
#: apps/note/models/notes.py:243
|
||||
#: apps/note/models/notes.py:215
|
||||
msgid "special notes"
|
||||
msgstr "notes spéciales"
|
||||
|
||||
#: apps/note/models/notes.py:266
|
||||
#: apps/note/models/notes.py:238
|
||||
msgid "Invalid alias"
|
||||
msgstr "Alias invalide"
|
||||
|
||||
#: apps/note/models/notes.py:282
|
||||
#: apps/note/models/notes.py:254
|
||||
msgid "alias"
|
||||
msgstr "alias"
|
||||
|
||||
#: apps/note/models/notes.py:306
|
||||
#: apps/note/models/notes.py:278
|
||||
msgid "Alias is too long."
|
||||
msgstr "L'alias est trop long."
|
||||
|
||||
#: apps/note/models/notes.py:309
|
||||
#: apps/note/models/notes.py:281
|
||||
msgid ""
|
||||
"This alias contains only complex character. Please use a more simple alias."
|
||||
msgstr ""
|
||||
"Cet alias ne contient que des caractères complexes. Merci d'utiliser un "
|
||||
"alias plus simple."
|
||||
|
||||
#: apps/note/models/notes.py:313
|
||||
#: apps/note/models/notes.py:285
|
||||
msgid "An alias with a similar name already exists: {} "
|
||||
msgstr "Un alias avec un nom similaire existe déjà : {} "
|
||||
|
||||
#: apps/note/models/notes.py:327
|
||||
#: apps/note/models/notes.py:299
|
||||
msgid "You can't delete your main alias."
|
||||
msgstr "Vous ne pouvez pas supprimer votre alias principal."
|
||||
|
||||
@ -1410,7 +1410,7 @@ msgstr ""
|
||||
"€ et 92 233 720 368 547 758.07 €. Ne cherchez pas à capitaliser l'argent du "
|
||||
"BDE."
|
||||
|
||||
#: apps/note/models/transactions.py:273
|
||||
#: apps/note/models/transactions.py:276
|
||||
msgid ""
|
||||
"The destination of this transaction must equal to the destination of the "
|
||||
"template."
|
||||
@ -1418,27 +1418,27 @@ msgstr ""
|
||||
"Le destinataire de cette transaction doit être identique à celui du bouton "
|
||||
"utilisé."
|
||||
|
||||
#: apps/note/models/transactions.py:283
|
||||
#: apps/note/models/transactions.py:286
|
||||
msgid "Template"
|
||||
msgstr "Bouton"
|
||||
|
||||
#: apps/note/models/transactions.py:286
|
||||
#: apps/note/models/transactions.py:289
|
||||
msgid "recurrent transaction"
|
||||
msgstr "transaction issue de bouton"
|
||||
|
||||
#: apps/note/models/transactions.py:287
|
||||
#: apps/note/models/transactions.py:290
|
||||
msgid "recurrent transactions"
|
||||
msgstr "transactions issues de boutons"
|
||||
|
||||
#: apps/note/models/transactions.py:302
|
||||
#: apps/note/models/transactions.py:305
|
||||
msgid "first_name"
|
||||
msgstr "prénom"
|
||||
|
||||
#: apps/note/models/transactions.py:307
|
||||
#: apps/note/models/transactions.py:310
|
||||
msgid "bank"
|
||||
msgstr "banque"
|
||||
|
||||
#: apps/note/models/transactions.py:324
|
||||
#: apps/note/models/transactions.py:327
|
||||
msgid ""
|
||||
"A special transaction is only possible between a Note associated to a "
|
||||
"payment method and a User or a Club"
|
||||
@ -1446,19 +1446,19 @@ msgstr ""
|
||||
"Une transaction spéciale n'est possible que entre une note associée à un "
|
||||
"mode de paiement et un utilisateur ou un club"
|
||||
|
||||
#: apps/note/models/transactions.py:333
|
||||
#: apps/note/models/transactions.py:336
|
||||
msgid "Special transaction"
|
||||
msgstr "Transaction de crédit/retrait"
|
||||
|
||||
#: apps/note/models/transactions.py:334
|
||||
#: apps/note/models/transactions.py:337
|
||||
msgid "Special transactions"
|
||||
msgstr "Transactions de crédit/retrait"
|
||||
|
||||
#: apps/note/models/transactions.py:350
|
||||
#: apps/note/models/transactions.py:353
|
||||
msgid "membership transaction"
|
||||
msgstr "transaction d'adhésion"
|
||||
|
||||
#: apps/note/models/transactions.py:351 apps/treasury/models.py:284
|
||||
#: apps/note/models/transactions.py:354 apps/treasury/models.py:284
|
||||
msgid "membership transactions"
|
||||
msgstr "transactions d'adhésion"
|
||||
|
||||
@ -1648,53 +1648,53 @@ msgstr "Vous ne pouvez pas voir le moindre bouton."
|
||||
msgid "Search transactions"
|
||||
msgstr "Rechercher des transactions"
|
||||
|
||||
#: apps/permission/models.py:89
|
||||
#: apps/permission/models.py:92
|
||||
#, python-brace-format
|
||||
msgid "Can {type} {model}.{field} in {query}"
|
||||
msgstr "Can {type} {model}.{field} in {query}"
|
||||
|
||||
#: apps/permission/models.py:91
|
||||
#: apps/permission/models.py:94
|
||||
#, python-brace-format
|
||||
msgid "Can {type} {model} in {query}"
|
||||
msgstr "Can {type} {model} in {query}"
|
||||
|
||||
#: apps/permission/models.py:104
|
||||
#: apps/permission/models.py:107
|
||||
msgid "rank"
|
||||
msgstr "rang"
|
||||
|
||||
#: apps/permission/models.py:117
|
||||
#: apps/permission/models.py:120
|
||||
msgid "permission mask"
|
||||
msgstr "masque de permissions"
|
||||
|
||||
#: apps/permission/models.py:118
|
||||
#: apps/permission/models.py:121
|
||||
msgid "permission masks"
|
||||
msgstr "masques de permissions"
|
||||
|
||||
#: apps/permission/models.py:124
|
||||
#: apps/permission/models.py:127
|
||||
msgid "add"
|
||||
msgstr "ajouter"
|
||||
|
||||
#: apps/permission/models.py:125
|
||||
#: apps/permission/models.py:128
|
||||
msgid "view"
|
||||
msgstr "voir"
|
||||
|
||||
#: apps/permission/models.py:126
|
||||
#: apps/permission/models.py:129
|
||||
msgid "change"
|
||||
msgstr "modifier"
|
||||
|
||||
#: apps/permission/models.py:158
|
||||
#: apps/permission/models.py:161
|
||||
msgid "query"
|
||||
msgstr "requête"
|
||||
|
||||
#: apps/permission/models.py:171
|
||||
#: apps/permission/models.py:174
|
||||
msgid "mask"
|
||||
msgstr "masque"
|
||||
|
||||
#: apps/permission/models.py:177
|
||||
#: apps/permission/models.py:180
|
||||
msgid "field"
|
||||
msgstr "champ"
|
||||
|
||||
#: apps/permission/models.py:182
|
||||
#: apps/permission/models.py:185
|
||||
msgid ""
|
||||
"Tells if the permission should be granted even if the membership of the user "
|
||||
"is expired."
|
||||
@ -1702,30 +1702,30 @@ msgstr ""
|
||||
"Indique si la permission doit être attribuée même si l'adhésion de "
|
||||
"l'utilisateur est expirée."
|
||||
|
||||
#: apps/permission/models.py:183
|
||||
#: apps/permission/models.py:186
|
||||
#: apps/permission/templates/permission/all_rights.html:89
|
||||
msgid "permanent"
|
||||
msgstr "permanent"
|
||||
|
||||
#: apps/permission/models.py:194
|
||||
#: apps/permission/models.py:197
|
||||
msgid "permission"
|
||||
msgstr "permission"
|
||||
|
||||
#: apps/permission/models.py:195 apps/permission/models.py:335
|
||||
#: apps/permission/models.py:198 apps/permission/models.py:338
|
||||
msgid "permissions"
|
||||
msgstr "permissions"
|
||||
|
||||
#: apps/permission/models.py:200
|
||||
#: apps/permission/models.py:203
|
||||
msgid "Specifying field applies only to view and change permission types."
|
||||
msgstr ""
|
||||
"Spécifie le champ concerné, ne fonctionne que pour les permissions view et "
|
||||
"change."
|
||||
|
||||
#: apps/permission/models.py:340
|
||||
#: apps/permission/models.py:343
|
||||
msgid "for club"
|
||||
msgstr "s'applique au club"
|
||||
|
||||
#: apps/permission/models.py:350 apps/permission/models.py:351
|
||||
#: apps/permission/models.py:353 apps/permission/models.py:354
|
||||
msgid "role permissions"
|
||||
msgstr "permissions par rôles"
|
||||
|
||||
@ -1832,10 +1832,26 @@ msgid "This email address is already used."
|
||||
msgstr "Cet email est déjà pris."
|
||||
|
||||
#: apps/registration/forms.py:49
|
||||
msgid ""
|
||||
"I declare that I opened a bank account in the Société générale with the BDE "
|
||||
"partnership."
|
||||
msgstr ""
|
||||
"Je déclare avoir ouvert un compte à la société générale avec le partenariat "
|
||||
"du BDE."
|
||||
|
||||
#: apps/registration/forms.py:50
|
||||
msgid ""
|
||||
"Warning: this engages you to open your bank account. If you finally decides "
|
||||
"to don't open your account, you will have to pay the BDE membership."
|
||||
msgstr ""
|
||||
"Attention : cocher cette case vous engage à ouvrir votre compte. Si vous "
|
||||
"décidez de ne pas le faire, vous devrez payer l'adhésion au BDE."
|
||||
|
||||
#: apps/registration/forms.py:58
|
||||
msgid "Register to the WEI"
|
||||
msgstr "S'inscrire au WEI"
|
||||
|
||||
#: apps/registration/forms.py:51
|
||||
#: apps/registration/forms.py:60
|
||||
msgid ""
|
||||
"Check this case if you want to register to the WEI. If you hesitate, you "
|
||||
"will be able to register later, after validating your account in the Kfet."
|
||||
@ -1844,11 +1860,11 @@ msgstr ""
|
||||
"pourrez toujours vous inscrire plus tard, après avoir validé votre compte à "
|
||||
"la Kfet."
|
||||
|
||||
#: apps/registration/forms.py:96
|
||||
#: apps/registration/forms.py:105
|
||||
msgid "Join BDE Club"
|
||||
msgstr "Adhérer au club BDE"
|
||||
|
||||
#: apps/registration/forms.py:103
|
||||
#: apps/registration/forms.py:112
|
||||
msgid "Join Kfet Club"
|
||||
msgstr "Adhérer au club Kfet"
|
||||
|
||||
@ -1900,7 +1916,12 @@ msgstr "Supprimer l'inscription"
|
||||
msgid "Validate account"
|
||||
msgstr "Valider le compte"
|
||||
|
||||
#: apps/registration/templates/registration/future_profile_detail.html:64
|
||||
#: apps/registration/templates/registration/future_profile_detail.html:62
|
||||
msgid ""
|
||||
"The user declared that he/she opened a bank account in the Société générale."
|
||||
msgstr "L'utilisateur a déclaré avoir ouvert un compte à la société générale."
|
||||
|
||||
#: apps/registration/templates/registration/future_profile_detail.html:71
|
||||
#: apps/wei/templates/wei/weimembership_form.html:127
|
||||
#: apps/wei/templates/wei/weimembership_form.html:186
|
||||
msgid "Validate registration"
|
||||
@ -1954,50 +1975,50 @@ msgstr "L'équipe de la Note Kfet."
|
||||
msgid "Register new user"
|
||||
msgstr "Enregistrer un nouvel utilisateur"
|
||||
|
||||
#: apps/registration/views.py:85
|
||||
#: apps/registration/views.py:93
|
||||
msgid "Email validation"
|
||||
msgstr "Validation de l'adresse mail"
|
||||
|
||||
#: apps/registration/views.py:87
|
||||
#: apps/registration/views.py:95
|
||||
msgid "Validate email"
|
||||
msgstr "Valider l'adresse e-mail"
|
||||
|
||||
#: apps/registration/views.py:129
|
||||
#: apps/registration/views.py:137
|
||||
msgid "Email validation unsuccessful"
|
||||
msgstr "La validation de l'adresse mail a échoué"
|
||||
|
||||
#: apps/registration/views.py:140
|
||||
#: apps/registration/views.py:148
|
||||
msgid "Email validation email sent"
|
||||
msgstr "L'email de vérification de l'adresse email a bien été envoyé"
|
||||
|
||||
#: apps/registration/views.py:148
|
||||
#: apps/registration/views.py:156
|
||||
msgid "Resend email validation link"
|
||||
msgstr "Renvoyer le lien de validation"
|
||||
|
||||
#: apps/registration/views.py:166
|
||||
#: apps/registration/views.py:174
|
||||
msgid "Pre-registered users list"
|
||||
msgstr "Liste des utilisateurs en attente d'inscription"
|
||||
|
||||
#: apps/registration/views.py:190
|
||||
#: apps/registration/views.py:198
|
||||
msgid "Unregistered users"
|
||||
msgstr "Utilisateurs en attente d'inscription"
|
||||
|
||||
#: apps/registration/views.py:203
|
||||
#: apps/registration/views.py:211
|
||||
msgid "Registration detail"
|
||||
msgstr "Détails de l'inscription"
|
||||
|
||||
#: apps/registration/views.py:263
|
||||
#: apps/registration/views.py:273
|
||||
msgid "You must join the BDE."
|
||||
msgstr "Vous devez adhérer au BDE."
|
||||
|
||||
#: apps/registration/views.py:287
|
||||
#: apps/registration/views.py:297
|
||||
msgid ""
|
||||
"The entered amount is not enough for the memberships, should be at least {}"
|
||||
msgstr ""
|
||||
"Le montant crédité est trop faible pour adhérer, il doit être au minimum de "
|
||||
"{}"
|
||||
|
||||
#: apps/registration/views.py:367
|
||||
#: apps/registration/views.py:384
|
||||
msgid "Invalidate pre-registration"
|
||||
msgstr "Invalider l'inscription"
|
||||
|
||||
@ -2143,7 +2164,7 @@ msgstr "proxys de transactions spéciales"
|
||||
msgid "credit transaction"
|
||||
msgstr "transaction de crédit"
|
||||
|
||||
#: apps/treasury/models.py:369
|
||||
#: apps/treasury/models.py:374
|
||||
msgid ""
|
||||
"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."
|
||||
@ -2151,16 +2172,16 @@ msgstr ""
|
||||
"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."
|
||||
|
||||
#: apps/treasury/models.py:384
|
||||
#: apps/treasury/models.py:389
|
||||
#: apps/treasury/templates/treasury/sogecredit_detail.html:10
|
||||
msgid "Credit from the Société générale"
|
||||
msgstr "Crédit de la Société générale"
|
||||
|
||||
#: apps/treasury/models.py:385
|
||||
#: apps/treasury/models.py:390
|
||||
msgid "Credits from the Société générale"
|
||||
msgstr "Crédits de la Société générale"
|
||||
|
||||
#: apps/treasury/models.py:388
|
||||
#: apps/treasury/models.py:393
|
||||
#, python-brace-format
|
||||
msgid "Soge credit for {user}"
|
||||
msgstr "Crédit de la société générale pour l'utilisateur {user}"
|
||||
@ -2936,19 +2957,19 @@ msgstr "Valider l'inscription WEI"
|
||||
msgid "This user didn't give her/his caution check."
|
||||
msgstr "Cet utilisateur n'a pas donné son chèque de caution."
|
||||
|
||||
#: note_kfet/settings/base.py:155
|
||||
#: note_kfet/settings/base.py:157
|
||||
msgid "German"
|
||||
msgstr "Allemand"
|
||||
|
||||
#: note_kfet/settings/base.py:156
|
||||
#: note_kfet/settings/base.py:158
|
||||
msgid "English"
|
||||
msgstr "Anglais"
|
||||
|
||||
#: note_kfet/settings/base.py:157
|
||||
#: note_kfet/settings/base.py:159
|
||||
msgid "Spanish"
|
||||
msgstr "Espagnol"
|
||||
|
||||
#: note_kfet/settings/base.py:158
|
||||
#: note_kfet/settings/base.py:160
|
||||
msgid "French"
|
||||
msgstr "Français"
|
||||
|
||||
@ -3036,7 +3057,7 @@ msgstr "Se déconnecter"
|
||||
#: note_kfet/templates/base.html:139
|
||||
#: note_kfet/templates/registration/signup.html:6
|
||||
#: note_kfet/templates/registration/signup.html:11
|
||||
#: note_kfet/templates/registration/signup.html:27
|
||||
#: note_kfet/templates/registration/signup.html:28
|
||||
msgid "Sign up"
|
||||
msgstr "Inscription"
|
||||
|
||||
@ -3048,7 +3069,21 @@ msgstr "Inscription"
|
||||
msgid "Log in"
|
||||
msgstr "Se connecter"
|
||||
|
||||
#: note_kfet/templates/base.html:158
|
||||
#: note_kfet/templates/base.html:156
|
||||
msgid ""
|
||||
"You are not a BDE member anymore. Please renew your membership if you want "
|
||||
"to use the note."
|
||||
msgstr ""
|
||||
"Vous n'êtes plus adhérent BDE. Merci de réadhérer si vous voulez profiter de "
|
||||
"la note."
|
||||
|
||||
#: note_kfet/templates/base.html:160
|
||||
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:166
|
||||
msgid ""
|
||||
"Your e-mail address is not validated. Please check your mail inbox and click "
|
||||
"on the validation link."
|
||||
@ -3056,7 +3091,22 @@ msgstr ""
|
||||
"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."
|
||||
|
||||
#: note_kfet/templates/base.html:175
|
||||
#: note_kfet/templates/base.html:171
|
||||
msgid ""
|
||||
"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 "
|
||||
"registration bonus of 80 € is not credited and the membership is not paid "
|
||||
"yet. This verification procedure may last a few days. Please make sure that "
|
||||
"you go to the end of the account creation."
|
||||
msgstr ""
|
||||
"Vous avez déclaré que vous avez ouvert un compte bancaire à la société "
|
||||
"générale. La banque n'a pas encore validé la création du compte auprès du "
|
||||
"BDE, le bonus d'inscription de 80 € n'a donc pas encore été créditée et "
|
||||
"l'adhésion n'est pas encore payée. Cette procédure de vérification peut "
|
||||
"durer quelques jours. Merci de vous assurer de bien aller au bout de vos "
|
||||
"démarches."
|
||||
|
||||
#: note_kfet/templates/base.html:194
|
||||
msgid "Contact us"
|
||||
msgstr "Nous contacter"
|
||||
|
||||
@ -3068,21 +3118,6 @@ msgstr "Chercher par un attribut tel que le nom …"
|
||||
msgid "There is no results."
|
||||
msgstr "Il n'y a pas de résultat."
|
||||
|
||||
#: note_kfet/templates/cas_server/base.html:7
|
||||
msgid "Central Authentication Service"
|
||||
msgstr "Service Central d'Authentification"
|
||||
|
||||
#: note_kfet/templates/cas_server/base.html:43
|
||||
#, python-format
|
||||
msgid ""
|
||||
"A new version of the application is available. This instance runs "
|
||||
"%(VERSION)s and the last version is %(LAST_VERSION)s. Please consider "
|
||||
"upgrading."
|
||||
msgstr ""
|
||||
"Une nouvelle version de l'application est disponible. Cette instance utilise "
|
||||
"la version %(VERSION)s et la dernière version est %(LAST_VERSION)s. Merci de "
|
||||
"vous mettre à jour."
|
||||
|
||||
#: note_kfet/templates/registration/logged_out.html:13
|
||||
msgid "Thanks for spending some quality time with the Web site today."
|
||||
msgstr "Merci d'avoir utilisé la Note Kfet."
|
||||
@ -3195,5 +3230,18 @@ msgstr ""
|
||||
"d'adhésion. Vous devez également valider votre adresse email en suivant le "
|
||||
"lien que vous avez reçu."
|
||||
|
||||
#~ msgid "Central Authentication Service"
|
||||
#~ msgstr "Service Central d'Authentification"
|
||||
|
||||
#, python-format
|
||||
#~ msgid ""
|
||||
#~ "A new version of the application is available. This instance runs "
|
||||
#~ "%(VERSION)s and the last version is %(LAST_VERSION)s. Please consider "
|
||||
#~ "upgrading."
|
||||
#~ msgstr ""
|
||||
#~ "Une nouvelle version de l'application est disponible. Cette instance "
|
||||
#~ "utilise la version %(VERSION)s et la dernière version est "
|
||||
#~ "%(LAST_VERSION)s. Merci de vous mettre à jour."
|
||||
|
||||
#~ msgid "Check this case is the Société Générale paid the inscription."
|
||||
#~ msgstr "Cochez cette case si la Société Générale a payé l'inscription."
|
||||
|
@ -20,3 +20,5 @@
|
||||
55 6 * * * root cd /var/www/note_kfet && env/bin/python manage.py send_reports
|
||||
# Mettre à jour les boutons mis en avant
|
||||
00 9 * * * root cd /var/www/note_kfet && env/bin/python manage.py refresh_highlighted_buttons
|
||||
# Vider les tokens Oauth2
|
||||
00 6 * * * root cd /var/www/note_kfet && env/bin/python manage.py cleartokens
|
||||
|
@ -26,6 +26,14 @@ admin_site = StrongAdminSite()
|
||||
admin_site.register(Site, SiteAdmin)
|
||||
|
||||
# Add external apps model
|
||||
if "oauth2_provider" in settings.INSTALLED_APPS:
|
||||
from oauth2_provider.admin import Application, ApplicationAdmin, Grant, \
|
||||
GrantAdmin, AccessToken, AccessTokenAdmin, RefreshToken, RefreshTokenAdmin
|
||||
admin_site.register(Application, ApplicationAdmin)
|
||||
admin_site.register(Grant, GrantAdmin)
|
||||
admin_site.register(AccessToken, AccessTokenAdmin)
|
||||
admin_site.register(RefreshToken, RefreshTokenAdmin)
|
||||
|
||||
if "django_htcpcp_tea" in settings.INSTALLED_APPS:
|
||||
from django_htcpcp_tea.admin import *
|
||||
from django_htcpcp_tea.models import *
|
||||
@ -44,9 +52,3 @@ if "rest_framework" in settings.INSTALLED_APPS:
|
||||
from rest_framework.authtoken.admin import *
|
||||
from rest_framework.authtoken.models import *
|
||||
admin_site.register(Token, TokenAdmin)
|
||||
|
||||
if "cas_server" in settings.INSTALLED_APPS:
|
||||
from cas_server.admin import *
|
||||
from cas_server.models import *
|
||||
admin_site.register(ServicePattern, ServicePatternAdmin)
|
||||
admin_site.register(FederatedIendityProvider, FederatedIendityProviderAdmin)
|
||||
|
@ -1,11 +0,0 @@
|
||||
[
|
||||
{
|
||||
"model": "cas_server.servicepattern",
|
||||
"pk": 1,
|
||||
"fields": {
|
||||
"pos": 1,
|
||||
"pattern": ".*",
|
||||
"name": "REPLACEME"
|
||||
}
|
||||
}
|
||||
]
|
@ -2,12 +2,12 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import login
|
||||
from django.contrib.auth.models import AnonymousUser, User
|
||||
from django.contrib.sessions.backends.db import SessionStore
|
||||
|
||||
from threading import local
|
||||
|
||||
from django.contrib.sessions.backends.db import SessionStore
|
||||
|
||||
USER_ATTR_NAME = getattr(settings, 'LOCAL_USER_ATTR_NAME', '_current_user')
|
||||
SESSION_ATTR_NAME = getattr(settings, 'LOCAL_SESSION_ATTR_NAME', '_current_session')
|
||||
IP_ATTR_NAME = getattr(settings, 'LOCAL_IP_ATTR_NAME', '_current_ip')
|
||||
@ -78,6 +78,41 @@ class SessionMiddleware(object):
|
||||
return response
|
||||
|
||||
|
||||
class LoginByIPMiddleware(object):
|
||||
"""
|
||||
Allow some users to be authenticated based on their IP address.
|
||||
For example, the "note" account should not be used elsewhere than the Kfet computer,
|
||||
and should not have any password.
|
||||
The password that is stored in database should be on the form "ipbased$my.public.ip.address".
|
||||
"""
|
||||
|
||||
def __init__(self, get_response):
|
||||
self.get_response = get_response
|
||||
|
||||
def __call__(self, request):
|
||||
"""
|
||||
If the user is not authenticated, get the used IP address
|
||||
and check if an user is authorized to be automatically logged with this address.
|
||||
If it is the case, the logging is performed with the full rights.
|
||||
"""
|
||||
if not request.user.is_authenticated:
|
||||
if 'HTTP_X_REAL_IP' in request.META:
|
||||
ip = request.META.get('HTTP_X_REAL_IP')
|
||||
elif 'HTTP_X_FORWARDED_FOR' in request.META:
|
||||
ip = request.META.get('HTTP_X_FORWARDED_FOR').split(', ')[0]
|
||||
else:
|
||||
ip = request.META.get('REMOTE_ADDR')
|
||||
|
||||
qs = User.objects.filter(password=f"ipbased${ip}")
|
||||
if qs.exists():
|
||||
login(request, qs.get())
|
||||
session = request.session
|
||||
session["permission_mask"] = 42
|
||||
session.save()
|
||||
|
||||
return self.get_response(request)
|
||||
|
||||
|
||||
class TurbolinksMiddleware(object):
|
||||
"""
|
||||
Send the `Turbolinks-Location` header in response to a visit that was redirected,
|
||||
|
@ -49,16 +49,6 @@ try:
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
if "cas_server" in INSTALLED_APPS:
|
||||
# CAS Settings
|
||||
CAS_AUTO_CREATE_USER = False
|
||||
CAS_LOGO_URL = "/static/img/Saperlistpopette.png"
|
||||
CAS_FAVICON_URL = "/static/favicon/favicon-32x32.png"
|
||||
CAS_SHOW_POWERED = False
|
||||
|
||||
if "logs" in INSTALLED_APPS:
|
||||
MIDDLEWARE += ('note_kfet.middlewares.SessionMiddleware',)
|
||||
|
||||
if DEBUG:
|
||||
PASSWORD_HASHERS += ['member.hashers.DebugSuperuserBackdoor']
|
||||
if "debug_toolbar" in INSTALLED_APPS:
|
||||
|
@ -35,8 +35,10 @@ INSTALLED_APPS = [
|
||||
'mailer',
|
||||
'phonenumber_field',
|
||||
'polymorphic',
|
||||
'oauth2_provider',
|
||||
|
||||
# Django contrib
|
||||
# Django Admin will autodiscover our apps for our custom admin site.
|
||||
'django.contrib.admin',
|
||||
'django.contrib.admindocs',
|
||||
'django.contrib.auth',
|
||||
@ -77,6 +79,8 @@ MIDDLEWARE = [
|
||||
'django.middleware.locale.LocaleMiddleware',
|
||||
'django.contrib.sites.middleware.CurrentSiteMiddleware',
|
||||
'django_htcpcp_tea.middleware.HTCPCPTeaMiddleware',
|
||||
'note_kfet.middlewares.SessionMiddleware',
|
||||
'note_kfet.middlewares.LoginByIPMiddleware',
|
||||
'note_kfet.middlewares.TurbolinksMiddleware',
|
||||
]
|
||||
|
||||
@ -214,6 +218,16 @@ EMAIL_HOST_PASSWORD = os.getenv('EMAIL_PASSWORD', None)
|
||||
SERVER_EMAIL = os.getenv("NOTE_MAIL", "notekfet@example.com")
|
||||
DEFAULT_FROM_EMAIL = "NoteKfet2020 <" + SERVER_EMAIL + ">"
|
||||
|
||||
# Cache
|
||||
# https://docs.djangoproject.com/en/2.2/topics/cache/#setting-up-the-cache
|
||||
cache_address = os.getenv("CACHE_ADDRESS", "127.0.0.1:11211")
|
||||
CACHES = {
|
||||
'default': {
|
||||
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
|
||||
'LOCATION': cache_address,
|
||||
}
|
||||
}
|
||||
|
||||
# Django REST Framework
|
||||
REST_FRAMEWORK = {
|
||||
'DEFAULT_PERMISSION_CLASSES': [
|
||||
@ -233,7 +247,7 @@ REST_FRAMEWORK = {
|
||||
FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'
|
||||
|
||||
# After login redirect user to transfer page
|
||||
LOGIN_REDIRECT_URL = '/note/transfer/'
|
||||
LOGIN_REDIRECT_URL = '/'
|
||||
|
||||
# An user session will expired after 3 hours
|
||||
SESSION_COOKIE_AGE = 60 * 60 * 3
|
||||
|
@ -24,6 +24,14 @@ if os.getenv("DJANGO_DEV_STORE_METHOD", "sqlite") != "postgresql":
|
||||
}
|
||||
}
|
||||
|
||||
# Dummy cache for development
|
||||
# https://docs.djangoproject.com/en/2.2/topics/cache/#setting-up-the-cache
|
||||
CACHES = {
|
||||
'default': {
|
||||
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
|
||||
}
|
||||
}
|
||||
|
||||
# Break it, fix it!
|
||||
DEBUG = True
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
# CAS
|
||||
OPTIONAL_APPS = [
|
||||
# 'cas_server',
|
||||
# 'debug_toolbar'
|
||||
]
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% load static i18n pretty_money static getenv perms %}
|
||||
{% load static i18n pretty_money static getenv perms memberinfo %}
|
||||
{% comment %}
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
{% endcomment %}
|
||||
@ -67,7 +67,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}"><i class="fa fa-coffee"></i> {% trans 'Consumptions' %}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if "note.transaction"|not_empty_model_list %}
|
||||
{% if user.is_authenticated and user|is_member:"Kfet" %}
|
||||
<li class="nav-item">
|
||||
{% url 'note:transfer' as url %}
|
||||
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}"><i class="fa fa-exchange"></i> {% trans 'Transfer' %} </a>
|
||||
@ -153,12 +153,36 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
</div>
|
||||
</nav>
|
||||
<div class="{% block containertype %}container{% endblock %} my-3">
|
||||
{% if request.user.is_authenticated and not request.user.profile.email_confirmed %}
|
||||
<div class="alert alert-warning">
|
||||
{% trans "Your e-mail address is not validated. Please check your mail inbox and click on the validation link." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div id="messages"></div>
|
||||
<div id="messages">
|
||||
{% if user.is_authenticated %}
|
||||
{% if not user|is_member:"BDE" %}
|
||||
<div class="alert alert-danger">
|
||||
{% trans "You are not a BDE member anymore. Please renew your membership if you want to use the note." %}
|
||||
</div>
|
||||
{% elif not user|is_member:"Kfet" %}
|
||||
<div class="alert alert-warning">
|
||||
{% trans "You are not a Kfet member, so you can't use your note account." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if not user.profile.email_confirmed %}
|
||||
<div class="alert alert-warning">
|
||||
{% trans "Your e-mail address is not validated. Please check your mail inbox and click on the validation link." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if user.sogecredit and not user.sogecredit.valid %}
|
||||
<div class="alert alert-info">
|
||||
{% blocktrans trimmed %}
|
||||
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 registration bonus of 80 € is not credited and the membership is not paid yet.
|
||||
This verification procedure may last a few days.
|
||||
Please make sure that you go to the end of the account creation.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{# TODO Add banners #}
|
||||
</div>
|
||||
{% block content %}
|
||||
<p>Default content...</p>
|
||||
{% endblock %}
|
||||
|
@ -1,99 +0,0 @@
|
||||
{% load i18n %}{% load static %}{% get_current_language as LANGUAGE_CODE %}<!DOCTYPE html>
|
||||
<html{% if LANGUAGE_CODE %} lang="{{LANGUAGE_CODE}}"{% endif %}>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge" /><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{% block title %}{% trans "Central Authentication Service" %}{% endblock %}</title>
|
||||
<link href="{{settings.CAS_COMPONENT_URLS.bootstrap3_css}}" rel="stylesheet">
|
||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="{{settings.CAS_COMPONENT_URLS.html5shiv}}"></script>
|
||||
<script src="{{settings.CAS_COMPONENT_URLS.respond}}"></script>
|
||||
<![endif]-->
|
||||
{% if settings.CAS_FAVICON_URL %}<link rel="shortcut icon" href="{{settings.CAS_FAVICON_URL}}" />{% endif %}
|
||||
<link href="{% static "cas_server/styles.css" %}" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrap">
|
||||
<div class="container">
|
||||
{% if auto_submit %}<noscript>{% endif %}
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||
<h1 id="app-name">
|
||||
{% if settings.CAS_LOGO_URL %}<img src="{{settings.CAS_LOGO_URL}}" alt="cas-logo" />{% endif %}
|
||||
Authentification Note Kfet 2020</h1>
|
||||
</div>
|
||||
</div>
|
||||
{% if auto_submit %}</noscript>{% endif %}
|
||||
<div class="row">
|
||||
<div class="col-lg-3 col-md-3 col-sm-2 col-xs-12"></div>
|
||||
<div class="col-lg-6 col-md-6 col-sm-8 col-xs-12">
|
||||
{% if auto_submit %}<noscript>{% endif %}
|
||||
{% for msg in CAS_INFO_RENDER %}
|
||||
<div class="alert alert-{{msg.type}}{% if msg.discardable %} alert-dismissable{% endif %}">
|
||||
{% if msg.discardable %}<button type="button" class="close" data-dismiss="alert" aria-hidden="true" id="info-{{msg.name}}">×</button>{% endif %}
|
||||
<p>{{msg.message}}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if settings.CAS_NEW_VERSION_HTML_WARNING and upgrade_available %}
|
||||
<div class="alert alert-info alert-dismissable">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true" id="alert-version">×</button>
|
||||
<p>{% blocktrans %}A new version of the application is available. This instance runs {{VERSION}} and the last version is {{LAST_VERSION}}. Please consider upgrading.{% endblocktrans %}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% block ante_messages %}{% endblock %}
|
||||
{% for message in messages %}
|
||||
<div {% spaceless %}
|
||||
{% if message.level == message_levels.DEBUG %}
|
||||
class="alert alert-warning"
|
||||
{% elif message.level == message_levels.INFO %}
|
||||
class="alert alert-info"
|
||||
{% elif message.level == message_levels.SUCCESS %}
|
||||
class="alert alert-success"
|
||||
{% elif message.level == message_levels.WARNING %}
|
||||
class="alert alert-warning"
|
||||
{% else %}
|
||||
class="alert alert-danger"
|
||||
{% endif %}
|
||||
{% endspaceless %}>
|
||||
<p>{{message}}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if auto_submit %}</noscript>{% endif %}
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
<div class="col-lg-3 col-md-3 col-sm-2 col-xs-0"></div>
|
||||
</div>
|
||||
</div> <!-- /container -->
|
||||
</div>
|
||||
<div style="clear: both;"></div>
|
||||
{% if settings.CAS_SHOW_POWERED %}
|
||||
<div id="footer">
|
||||
<p><a class="text-muted" href="https://pypi.org/project/django-cas-server/">django-cas-server powered</a></p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<script src="{{settings.CAS_COMPONENT_URLS.jquery}}"></script>
|
||||
<script src="{{settings.CAS_COMPONENT_URLS.bootstrap3_js}}"></script>
|
||||
<script src="{% static "cas_server/functions.js" %}"></script>
|
||||
<script type="text/javascript">
|
||||
{% if settings.CAS_NEW_VERSION_HTML_WARNING and upgrade_available %}
|
||||
discard_and_remember("#alert-version", "cas-alert-version", "{{LAST_VERSION}}");
|
||||
{% endif %}
|
||||
{% for msg in CAS_INFO_RENDER %}
|
||||
{% if msg.discardable %}
|
||||
discard_and_remember("#info-{{msg.name}}", "cas-info-{{msg.name}}", "{{msg.hash}}");
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% block javascript_inline %}{% endblock %}
|
||||
</script>
|
||||
{% block javascript %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
<!--
|
||||
Powered by django-cas-server version {{VERSION}}
|
||||
|
||||
Pypi: https://pypi.org/project/django-cas-server/
|
||||
github: https://github.com/nitmir/django-cas-server
|
||||
-->
|
@ -23,6 +23,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
{% csrf_token %}
|
||||
{{ form|crispy }}
|
||||
{{ profile_form|crispy }}
|
||||
{{ soge_form|crispy }}
|
||||
<button class="btn btn-success" type="submit">
|
||||
{% trans "Sign up" %}
|
||||
</button>
|
||||
|
@ -5,15 +5,14 @@ from django.conf import settings
|
||||
from django.conf.urls.static import static
|
||||
from django.urls import path, include
|
||||
from django.views.defaults import bad_request, permission_denied, page_not_found, server_error
|
||||
from django.views.generic import RedirectView
|
||||
|
||||
from member.views import CustomLoginView
|
||||
|
||||
from .admin import admin_site
|
||||
from .views import IndexView
|
||||
|
||||
urlpatterns = [
|
||||
# Dev so redirect to something random
|
||||
path('', RedirectView.as_view(pattern_name='note:transfer'), name='index'),
|
||||
path('', IndexView.as_view(), name='index'),
|
||||
|
||||
# Include project routers
|
||||
path('note/', include('note.urls')),
|
||||
@ -40,12 +39,11 @@ urlpatterns = [
|
||||
if settings.DEBUG:
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
||||
|
||||
if "cas_server" in settings.INSTALLED_APPS:
|
||||
urlpatterns += [
|
||||
# Include CAS Server routers
|
||||
path('cas/', include('cas_server.urls', namespace="cas_server")),
|
||||
]
|
||||
if "oauth2_provider" in settings.INSTALLED_APPS:
|
||||
# OAuth2 provider
|
||||
urlpatterns.append(
|
||||
path('o/', include('oauth2_provider.urls', namespace='oauth2_provider'))
|
||||
)
|
||||
|
||||
if "debug_toolbar" in settings.INSTALLED_APPS:
|
||||
import debug_toolbar
|
||||
|
30
note_kfet/views.py
Normal file
30
note_kfet/views.py
Normal file
@ -0,0 +1,30 @@
|
||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.urls import reverse
|
||||
from django.views.generic import RedirectView
|
||||
from note.models import Alias
|
||||
from permission.backends import PermissionBackend
|
||||
|
||||
|
||||
class IndexView(LoginRequiredMixin, RedirectView):
|
||||
def get_redirect_url(self, *args, **kwargs):
|
||||
"""
|
||||
Calculate the index page according to the roles.
|
||||
A normal user will have access to the transfer page.
|
||||
A non-Kfet member will have access to its user detail page.
|
||||
The user "note" will display the consumption interface.
|
||||
"""
|
||||
user = self.request.user
|
||||
|
||||
# The account note will have the consumption page as default page
|
||||
if not PermissionBackend.check_perm(user, "auth.view_user", user):
|
||||
return reverse("note:consos")
|
||||
|
||||
# People that can see the alias BDE are Kfet members
|
||||
if PermissionBackend.check_perm(user, "alias.view_alias", Alias.objects.get(name="BDE")):
|
||||
return reverse("note:transfer")
|
||||
|
||||
# Non-Kfet members will don't see the transfer page, but their profile page
|
||||
return reverse("member:user_detail", args=(user.pk,))
|
@ -1,17 +1,18 @@
|
||||
beautifulsoup4~=4.7.1
|
||||
Django~=2.2.15
|
||||
django-bootstrap-datepicker-plus~=3.0.5
|
||||
django-cas-server>=1.2.0
|
||||
django-colorfield~=0.3.2
|
||||
django-crispy-forms~=1.7.2
|
||||
django-extensions~=2.1.4
|
||||
django-filter~=2.1.0
|
||||
django-htcpcp-tea~=0.3.1
|
||||
django-mailer~=2.0.1
|
||||
django-oauth-toolkit~=1.3.3
|
||||
django-phonenumber-field~=5.0.0
|
||||
django-polymorphic~=2.0.3
|
||||
djangorestframework~=3.9.0
|
||||
django-rest-polymorphic~=0.1.9
|
||||
django-tables2~=2.3.1
|
||||
python-memcached~=1.59
|
||||
phonenumbers~=8.9.10
|
||||
Pillow>=5.4.1
|
||||
|
Loading…
Reference in New Issue
Block a user