1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2025-07-20 16:09:12 +02:00

Compare commits

..

2 Commits

Author SHA1 Message Date
fff5674702 Merge branch 'svg_icons' into 'main'
Draft: Replace Font Awesome with inline SVG icons

See merge request bde/nk20!188
2024-06-05 01:10:24 +02:00
466cbd9878 Replace Font Awesome with inline SVG icons
Font Awesome 4 adds 106kB of dependencies on each page and require to
query multiple assets. It also sometimes causes icons to appear after
page loading. Font Awesome 4 is deprecated and replaced by version 5
which is not packaged in every GNU/Linux distributions.

This commit replaces icons with inline SVG which does not require
external assets, does not require an additionnal dependency and is
widely supported by modern browsers. It makes the page loading faster
and enables us to no longer require fonts-font-awesome Debian package.
2021-10-06 17:15:33 +02:00
37 changed files with 291 additions and 593 deletions

View File

@ -12,7 +12,7 @@ RUN apt-get update && \
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 && \
texlive-xetex gettext libjs-bootstrap4 && \
rm -rf /var/lib/apt/lists/*
# Instal PyPI requirements

View File

@ -23,7 +23,7 @@ Bien que cela permette de créer une instance sur toutes les distributions,
$ sudo apt update
$ sudo apt install --no-install-recommends -y \
ipython3 python3-setuptools python3-venv python3-dev \
texlive-xetex gettext libjs-bootstrap4 fonts-font-awesome git
texlive-xetex gettext libjs-bootstrap4 git
```
2. **Clonage du dépot** là où vous voulez :
@ -115,7 +115,7 @@ Sinon vous pouvez suivre les étapes décrites ci-dessous.
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 \
texlive-xetex gettext libjs-bootstrap4 \
nginx python3-venv git acl
```

View File

@ -18,7 +18,6 @@
- ipython3
# Front-end dependencies
- fonts-font-awesome
- libjs-bootstrap4
# Python dependencies

View File

@ -34,7 +34,9 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% endif %}
<div class="card-footer">
<a class="btn btn-sm btn-success" href="{% url 'activity:activity_create' %}" data-turbolinks="false">
<i class="fa fa-calendar-plus-o" aria-hidden="true"></i>
<svg class="bi bi-calendar-plus" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M4 .5a.5.5 0 0 0-1 0V1H2a2 2 0 0 0-2 2v1h16V3a2 2 0 0 0-2-2h-1V.5a.5.5 0 0 0-1 0V1H4V.5zM16 14V5H0v9a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2zM8.5 8.5V10H10a.5.5 0 0 1 0 1H8.5v1.5a.5.5 0 0 1-1 0V11H6a.5.5 0 0 1 0-1h1.5V8.5a.5.5 0 0 1 1 0z"/>
</svg>
{% trans 'New activity' %}
</a>
</div>

View File

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

View File

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

View File

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

View File

@ -1,18 +0,0 @@
# Generated by Django 2.2.28 on 2024-08-07 12:09
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('member', '0012_club_add_registration_form'),
]
operations = [
migrations.AlterField(
model_name='profile',
name='promotion',
field=models.PositiveSmallIntegerField(default=2024, help_text='Year of entry to the school (None if not ENS student)', null=True, verbose_name='promotion'),
),
]

View File

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

View File

@ -45,7 +45,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
<div class="card-footer">
{% if user_object %}
<a class="btn btn-sm btn-secondary" href="{% url 'member:user_update_profile' user_object.pk %}">
<i class="fa fa-edit"></i> {% trans 'Update Profile' %}
<svg class="bi bi-edit" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M12.854.146a.5.5 0 0 0-.707 0L10.5 1.793 14.207 5.5l1.647-1.646a.5.5 0 0 0 0-.708l-3-3zm.646 6.061L9.793 2.5 3.293 9H3.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.207l6.5-6.5zm-7.468 7.468A.5.5 0 0 1 6 13.5V13h-.5a.5.5 0 0 1-.5-.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.5-.5V10h-.5a.499.499 0 0 1-.175-.032l-.179.178a.5.5 0 0 0-.11.168l-2 5a.5.5 0 0 0 .65.65l5-2a.5.5 0 0 0 .168-.11l.178-.178z"/>
</svg>
{% trans 'Update Profile' %}
</a>
{% url 'member:user_detail' user_object.pk as user_profile_url %}
{% if request.path_info != user_profile_url %}
@ -59,7 +62,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% if ".change_"|has_perm:club %}
<a class="btn btn-sm btn-secondary" href="{% url 'member:club_update' pk=club.pk %}"
data-turbolinks="false">
<i class="fa fa-edit"></i> {% trans 'Update Profile' %}
<svg class="bi bi-edit" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M12.854.146a.5.5 0 0 0-.707 0L10.5 1.793 14.207 5.5l1.647-1.646a.5.5 0 0 0 0-.708l-3-3zm.646 6.061L9.793 2.5 3.293 9H3.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.207l6.5-6.5zm-7.468 7.468A.5.5 0 0 1 6 13.5V13h-.5a.5.5 0 0 1-.5-.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.5-.5V10h-.5a.499.499 0 0 1-.175-.032l-.179.178a.5.5 0 0 0-.11.168l-2 5a.5.5 0 0 0 .65.65l5-2a.5.5 0 0 0 .168-.11l.178-.178z"/>
</svg>
{% trans 'Update Profile' %}
</a>
{% endif %}
{% url 'member:club_detail' club.pk as club_detail_url %}

View File

@ -10,7 +10,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
<div class="card">
<div class="card-header position-relative" id="clubListHeading">
<a class="font-weight-bold">
<i class="fa fa-users"></i> {% trans "Club managers" %}
<svg class="bi bi-users" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H3zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
</svg>
{% trans "Club managers" %}
</a>
</div>
{% render_table managers %}
@ -23,7 +26,12 @@ SPDX-License-Identifier: GPL-3.0-or-later
<div class="card">
<div class="card-header position-relative" id="clubListHeading">
<a class="stretched-link font-weight-bold" href="{% url 'member:club_members' pk=club.pk %}">
<i class="fa fa-users"></i> {% trans "Club members" %}
<svg class="bi bi-users" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M7 14s-1 0-1-1 1-4 5-4 5 3 5 4-1 1-1 1H7zm4-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
<path fill-rule="evenodd" d="M5.216 14A2.238 2.238 0 0 1 5 13c0-1.355.68-2.75 1.936-3.72A6.325 6.325 0 0 0 5 9c-4 0-5 3-5 4s1 1 1 1h4.216z"/>
<path d="M4.5 8a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z"/>
</svg>
{% trans "Club members" %}
</a>
</div>
{% render_table member_list %}
@ -37,7 +45,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
<div class="card-header position-relative" id="historyListHeading">
<a class="stretched-link font-weight-bold" {% if "note.view_note"|has_perm:club.note %}
href="{% url 'note:transactions' pk=club.note.pk %}" {% endif %}>
<i class="fa fa-euro"></i> {% trans "Transaction history" %}
<svg class="bi bi-euro" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M4 9.42h1.063C5.4 12.323 7.317 14 10.34 14c.622 0 1.167-.068 1.659-.185v-1.3c-.484.119-1.045.17-1.659.17-2.1 0-3.455-1.198-3.775-3.264h4.017v-.928H6.497v-.936c0-.11 0-.219.008-.329h4.078v-.927H6.618c.388-1.898 1.719-2.985 3.723-2.985.614 0 1.175.05 1.659.177V2.194A6.617 6.617 0 0 0 10.341 2c-2.928 0-4.82 1.569-5.244 4.3H4v.928h1.01v1.265H4v.928z"/>
</svg>
{% trans "Transaction history" %}
</a>
</div>
<div id="history_list">

View File

@ -47,7 +47,9 @@
<dt class="col-xl-6">{% trans 'aliases'|capfirst %}</dt>
<dd class="col-xl-6">
<a class="badge badge-secondary" href="{% url 'member:club_alias' club.pk %}">
<i class="fa fa-edit"></i>
<svg class="bi bi-edit" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M12.854.146a.5.5 0 0 0-.707 0L10.5 1.793 14.207 5.5l1.647-1.646a.5.5 0 0 0 0-.708l-3-3zm.646 6.061L9.793 2.5 3.293 9H3.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.207l6.5-6.5zm-7.468 7.468A.5.5 0 0 1 6 13.5V13h-.5a.5.5 0 0 1-.5-.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.5-.5V10h-.5a.499.499 0 0 1-.175-.032l-.179.178a.5.5 0 0 0-.11.168l-2 5a.5.5 0 0 0 .65.65l5-2a.5.5 0 0 0 .168-.11l.178-.178z"/>
</svg>
{% trans 'Manage aliases' %} ({{ club.note.alias.all|length }})
</a>
</dd>

View File

@ -11,7 +11,9 @@
<dt class="col-xl-6">{% trans 'password'|capfirst %}</dt>
<dd class="col-xl-6">
<a class="badge badge-secondary" href="{% url 'password_change' %}">
<i class="fa fa-lock"></i>
<svg class="bi bi-lock" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M8 1a2 2 0 0 1 2 2v4H6V3a2 2 0 0 1 2-2zm3 6V3a3 3 0 0 0-6 0v4a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2z"/>
</svg>
{% trans 'Change password' %}
</a>
</dd>
@ -20,7 +22,9 @@
<dt class="col-xl-6">{% trans 'aliases'|capfirst %}</dt>
<dd class="col-xl-6">
<a class="badge badge-secondary" href="{% url 'member:user_alias' user_object.pk %}">
<i class="fa fa-edit"></i>
<svg class="bi bi-edit" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M12.854.146a.5.5 0 0 0-.707 0L10.5 1.793 14.207 5.5l1.647-1.646a.5.5 0 0 0 0-.708l-3-3zm.646 6.061L9.793 2.5 3.293 9H3.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.207l6.5-6.5zm-7.468 7.468A.5.5 0 0 1 6 13.5V13h-.5a.5.5 0 0 1-.5-.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.5-.5V10h-.5a.499.499 0 0 1-.175-.032l-.179.178a.5.5 0 0 0-.11.168l-2 5a.5.5 0 0 0 .65.65l5-2a.5.5 0 0 0 .168-.11l.178-.178z"/>
</svg>
{% trans 'Manage aliases' %} ({{ user_object.note.alias.all|length }})
</a>
</dd>
@ -60,7 +64,10 @@
{% if user_object.pk == user.pk %}
<div class="text-center">
<a class="small badge badge-secondary" href="{% url 'member:auth_token' %}">
<i class="fa fa-cogs"></i>{% trans 'API token' %}
<svg class="bi bi-cogs" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M9.405 1.05c-.413-1.4-2.397-1.4-2.81 0l-.1.34a1.464 1.464 0 0 1-2.105.872l-.31-.17c-1.283-.698-2.686.705-1.987 1.987l.169.311c.446.82.023 1.841-.872 2.105l-.34.1c-1.4.413-1.4 2.397 0 2.81l.34.1a1.464 1.464 0 0 1 .872 2.105l-.17.31c-.698 1.283.705 2.686 1.987 1.987l.311-.169a1.464 1.464 0 0 1 2.105.872l.1.34c.413 1.4 2.397 1.4 2.81 0l.1-.34a1.464 1.464 0 0 1 2.105-.872l.31.17c1.283.698 2.686-.705 1.987-1.987l-.169-.311a1.464 1.464 0 0 1 .872-2.105l.34-.1c1.4-.413 1.4-2.397 0-2.81l-.34-.1a1.464 1.464 0 0 1-.872-2.105l.17-.31c.698-1.283-.705-2.686-1.987-1.987l-.311.169a1.464 1.464 0 0 1-2.105-.872l-.1-.34zM8 10.93a2.929 2.929 0 1 1 0-5.86 2.929 2.929 0 0 1 0 5.858z"/>
</svg>
{% trans 'API token' %}
</a>
</div>
{% endif %}

View File

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

View File

@ -18,7 +18,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
<div class="card bg-light mb-3">
<div class="card-header position-relative" id="clubListHeading">
<a class="font-weight-bold">
<i class="fa fa-users"></i> {% trans "View my memberships" %}
<svg class="bi bi-users" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H3zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
</svg>
{% trans "View my memberships" %}
</a>
</div>
{% render_table club_list %}
@ -29,7 +32,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
<a class="stretched-link font-weight-bold text-decoration-none"
{% if "note.view_note"|has_perm:user_object.note %}
href="{% url 'note:transactions' pk=user_object.note.pk %}" {% endif %}>
<i class="fa fa-euro"></i> {% trans "Transaction history" %}
<svg class="bi bi-euro" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M4 9.42h1.063C5.4 12.323 7.317 14 10.34 14c.622 0 1.167-.068 1.659-.185v-1.3c-.484.119-1.045.17-1.659.17-2.1 0-3.455-1.198-3.775-3.264h4.017v-.928H6.497v-.936c0-.11 0-.219.008-.329h4.078v-.927H6.618c.388-1.898 1.719-2.985 3.723-2.985.614 0 1.175.05 1.659.177V2.194A6.617 6.617 0 0 0 10.341 2c-2.928 0-4.82 1.569-5.244 4.3H4v.928h1.01v1.265H4v.928z"/>
</svg>
{% trans "Transaction history" %}
</a>
</div>
<div id="history_list">

View File

@ -7,7 +7,11 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% block content %}
{% 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" %}
<svg class="bi bi-user-plus" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M1 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H1zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
<path fill-rule="evenodd" d="M13.5 5a.5.5 0 0 1 .5.5V7h1.5a.5.5 0 0 1 0 1H14v1.5a.5.5 0 0 1-1 0V8h-1.5a.5.5 0 0 1 0-1H13V5.5a.5.5 0 0 1 .5-.5z"/>
</svg>
{% trans "Registrations" %}
</a>
{% endif %}

View File

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

View File

@ -148,7 +148,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
{# Mode switch #}
<div class="card-footer border-primary">
<a class="btn btn-sm btn-secondary float-left" href="{% url 'note:template_list' %}">
<i class="fa fa-edit"></i> {% trans "Edit" %}
<svg class="bi bi-edit" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M12.854.146a.5.5 0 0 0-.707 0L10.5 1.793 14.207 5.5l1.647-1.646a.5.5 0 0 0 0-.708l-3-3zm.646 6.061L9.793 2.5 3.293 9H3.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.207l6.5-6.5zm-7.468 7.468A.5.5 0 0 1 6 13.5V13h-.5a.5.5 0 0 1-.5-.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.5-.5V10h-.5a.499.499 0 0 1-.175-.032l-.179.178a.5.5 0 0 0-.11.168l-2 5a.5.5 0 0 0 .65.65l5-2a.5.5 0 0 0 .168-.11l.178-.178z"/>
</svg>
{% trans "Edit" %}
</a>
<div class="btn-group btn-group-toggle float-right" data-toggle="buttons">
<label for="single_conso" class="btn btn-sm btn-outline-primary active">

View File

@ -23,7 +23,7 @@
<p>
Par ailleurs, le BDE ne sert pas d'alcool aux adhérents dont le solde
est inférieur à 0 €.
est inférieur à 0 € depuis plus de 24h.
</p>
<p>

View File

@ -1,65 +0,0 @@
{% load pretty_money %}
{% load i18n %}
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>[Note Kfet] Récapitulatif de trésorerie</title>
</head>
<body>
<h1>
Récapitulatif de trésorerie au {{ summary.date|date:"d/m/Y" }} à {{ summary.date|date:"H:i:s" }} :
</h1>
<h2>
Tous les utilisateur⋅rices :
</h2>
<ul>
<li>Positifs : {{ summary.total_positive_user }} soit {{ summary.balance_positive_user / 100 }} €</li>
<li>Neutres : {{ summary.total_zero_user }}</li>
<li>Négatifs : {{ summary.total_negative_user }} soit {{ summary.balance_negative_user / 100 }} €</li>
</ul>
<h2>
Les {{ summary.total_positive_user_bde + summary.total_zero_user_bde + summary.total_negative_user_bde }} adhérent⋅es BDE :
</h2>
<ul>
<li>Positifs : {{ summary.total_positive_user_bde }} soit {{ summary.balance_positive_user_bde / 100 }} €</li>
<li>Neutres : {{ summary.total_zero_user_bde }}</li>
<li>Négatifs : {{ summary.total_negative_user_bde }} soit {{ summary.balance_negative_user_bde / 100 }} €</li>
</ul>
<h2>
Clubs :
</h2>
<ul>
<li>Positifs : {{ summary.total_positive_club }} soit {{ summary.balance_positive_club / 100 }} €</li>
<li>Neutres : {{ summary.total_zero_club }}</li>
<li>Négatifs : {{ summary.total_negative_club }} soit {{ summary.balance_negative_club / 100 }} €</li>
</ul>
<h2>
Clubs hors BDE / Kfet et club dont le nom fini par "- BDE" :
</h2>
<ul>
<li>Positifs : {{ summary.total_positive_club_nbde }} soit {{ summary.balance_positive_club_nbde / 100 }} €</li>
<li>Neutres : {{ summary.total_zero_club_nbde }}</li>
<li>Négatifs : {{ summary.total_negative_club_nbde }} soit {{ summary.balance_negative_club_nbde / 100 }} €</li>
</ul>
<h2>
Progression :
</h2>
<ul>
<li>Ceci correspond à une différence de {{ balance_difference_user / 100 }} € pour les utilisateur⋅rices</li>
<li>Ceci correspond à une différence de {{ balance_difference_club / 100 }} € pour les clubs</li>
</ul>
--
<p>
Le BDE<br>
{% trans "Mail generated by the Note Kfet on the" %} {% now "j F Y à H:i:s" %}
</p>
</body>
</html>

View File

@ -1,33 +0,0 @@
{% load pretty_money %}
{% load i18n %}
Récapitulatif de trésorerie au {{ summary.date|date:"d/m/Y" }} à {{ summary.date|date:"H:i:s" }} :
Tous les utilisateur⋅rices :
- Positifs : {{ summary.total_positive_user }} soit {{ summary.balance_positive_user / 100 }} €
- Neutres : {{ summary.total_zero_user }}
- Négatifs : {{ summary.total_negative_user }} soit {{ summary.balance_negative_user / 100 }} €
Les {{ summary.total_positive_user_bde + summary.total_zero_user_bde + summary.total_negative_user_bde }} adhérent⋅es BDE :
- Positifs : {{ summary.total_positive_user_bde }} soit {{ summary.balance_positive_user_bde / 100 }} €
- Neutres : {{ summary.total_zero_user_bde }}
- Négatifs : {{ summary.total_negative_user_bde }} soit {{ summary.balance_negative_user_bde /100 }} €
Clubs :
- Positifs : {{ summary.total_positive_club }} soit {{ summary.balance_positive_club / 100 }} €
- Neutres : {{ summary.total_zero_club }}
- Négatifs : {{ summary.total_negative_club }} soit {{ summary.balance_negative_club / 100 }} €
Clubs hors BDE / Kfet et club dont le nom fini par "- BDE" :
- Positifs : {{ summary.total_positive_club_nbde }} soit {{ summary.balance_positive_club_nbde / 100 }} €
- Neutres : {{ summary.total_zero_club_nbde }}
- Négatifs : {{ summary.total_negative_club_nbde }} soit {{ summary.balance_negative_club_nbde / 100 }} €
Progression :
- Ceci correspond à une différence de {{ balance_difference_user / 100 }} € pour les utilisateur⋅rices
- Ceci correspond à une différence de {{ balance_difference_club / 100 }} € pour les clubs
--
Le BDE
{% trans "Mail generated by the Note Kfet on the" %} {% now "j F Y à H:i:s" %}

View File

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

View File

@ -5,6 +5,7 @@ from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.utils.translation import gettext_lazy as _
# from member.models import Club
from note.models import NoteSpecial, Alias
from note_kfet.inputs import AmountInput
@ -114,3 +115,12 @@ class ValidationForm(forms.Form):
required=False,
initial=True,
)
# If the bda exists
# if Club.objects.filter(name__iexact="bda").exists():
# The user can join the bda club at the inscription
# join_bda = forms.BooleanField(
# label=_("Join BDA Club"),
# required=False,
# initial=True,
# )

View File

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

View File

@ -5,13 +5,13 @@ from django.contrib import admin
from note_kfet.admin import admin_site
from .forms import ProductForm
from .models import Invoice, NoteSummary, Product, RemittanceType, Remittance, SogeCredit
from .models import RemittanceType, Remittance, SogeCredit, Invoice, Product
@admin.register(RemittanceType, site=admin_site)
class RemittanceTypeAdmin(admin.ModelAdmin):
"""
Admin customisation for RemittanceType
Admin customisation for RemiitanceType
"""
list_display = ('note', )
@ -55,19 +55,3 @@ class InvoiceAdmin(admin.ModelAdmin):
"""
list_display = ('object', 'id', 'bde', 'name', 'date', 'acquitted',)
inlines = (ProductInline,)
@admin.register(NoteSummary, site=admin_site)
class NoteSummaryAdmin(admin.ModelAdmin):
"""
Admin customisation for NoteSummary
"""
list_display = (
'date', 'total_positive_user', 'balance_positive_user', 'total_positive_user_bde',
'balance_positive_user_bde', 'total_zero_user', 'total_zero_user_bde', 'total_negative_user',
'balance_negative_user', 'total_negative_user_bde', 'balance_negative_user_bde',
'total_vnegative_user', 'balance_vnegative_user', 'total_vnegative_user_bde',
'balance_vnegative_user_bde', 'total_positive_club', 'balance_positive_club',
'total_positive_club_nbde', 'balance_positive_club_nbde', 'total_zero_club', 'total_zero_club_nbde',
'total_negative_club', 'balance_negative_club', 'total_negative_club_nbde', 'balance_negative_club_nbde',
)

View File

@ -1,49 +0,0 @@
# Generated by Django 2.2.28 on 2024-08-07 12:09
import datetime
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('treasury', '0008_auto_20240322_0045'),
]
operations = [
migrations.CreateModel(
name='NoteSummary',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date', models.DateField(default=datetime.date.today, verbose_name='Date')),
('total_positive_user', models.PositiveIntegerField(verbose_name='Total positive user')),
('balance_positive_user', models.PositiveIntegerField(verbose_name='Balance positive user')),
('total_positive_user_bde', models.PositiveIntegerField(verbose_name='Total positive user BDE')),
('balance_positive_user_bde', models.PositiveIntegerField(verbose_name='Balance positive user BDE')),
('total_zero_user', models.PositiveIntegerField(verbose_name='Total zero user')),
('total_zero_user_bde', models.PositiveIntegerField(verbose_name='Total zero user BDE')),
('total_negative_user', models.PositiveIntegerField(verbose_name='Total negative user')),
('balance_negative_user', models.PositiveIntegerField(verbose_name='Balance negative user')),
('total_negative_user_bde', models.PositiveIntegerField(verbose_name='Total negative user BDE')),
('balance_negative_user_bde', models.PositiveIntegerField(verbose_name='Balance negative user BDE')),
('total_vnegative_user', models.PositiveIntegerField(verbose_name='Total very negative user')),
('balance_vnegative_user', models.PositiveIntegerField(verbose_name='Balance very negative user')),
('total_vnegative_user_bde', models.PositiveIntegerField(verbose_name='Total very negative user BDE')),
('balance_vnegative_user_bde', models.PositiveIntegerField(verbose_name='Balance very negative user BDE')),
('total_positive_club', models.PositiveIntegerField(verbose_name='Total positive club')),
('balance_positive_club', models.PositiveIntegerField(verbose_name='Balance positive club')),
('total_positive_club_nbde', models.PositiveIntegerField(verbose_name='Total positive club nbde')),
('balance_positive_club_nbde', models.PositiveIntegerField(verbose_name='Balance positive club nbde')),
('total_zero_club', models.PositiveIntegerField(verbose_name='Total zero club')),
('total_zero_club_nbde', models.PositiveIntegerField(verbose_name='Total zero club nbde')),
('total_negative_club', models.PositiveIntegerField(verbose_name='Total negative club')),
('balance_negative_club', models.PositiveIntegerField(verbose_name='Balance negative club')),
('total_negative_club_nbde', models.PositiveIntegerField(verbose_name='Total negative club nbde')),
('balance_negative_club_nbde', models.PositiveIntegerField(verbose_name='Balance negative club nbde')),
],
options={
'verbose_name': 'Summary',
'verbose_name_plural': 'Summaries',
},
),
]

View File

@ -460,117 +460,3 @@ class SogeCredit(models.Model):
self.credit_transaction._force_save = True
self.credit_transaction.save()
super().delete(**kwargs)
class NoteSummary(models.Model):
"""
Summary of every notes
"""
date = models.DateField(
default=date.today,
verbose_name=_("Date"),
)
total_positive_user = models.PositiveIntegerField(
verbose_name=_("Total positive user"),
)
balance_positive_user = models.PositiveIntegerField(
verbose_name=_("Balance positive user"),
)
total_positive_user_bde = models.PositiveIntegerField(
verbose_name=_("Total positive user BDE"),
)
balance_positive_user_bde = models.PositiveIntegerField(
verbose_name=_("Balance positive user BDE"),
)
total_zero_user = models.PositiveIntegerField(
verbose_name=_("Total zero user"),
)
total_zero_user_bde = models.PositiveIntegerField(
verbose_name=_("Total zero user BDE"),
)
total_negative_user = models.PositiveIntegerField(
verbose_name=_("Total negative user"),
)
balance_negative_user = models.PositiveIntegerField(
verbose_name=_("Balance negative user"),
)
total_negative_user_bde = models.PositiveIntegerField(
verbose_name=_("Total negative user BDE"),
)
balance_negative_user_bde = models.PositiveIntegerField(
verbose_name=_("Balance negative user BDE"),
)
total_vnegative_user = models.PositiveIntegerField(
verbose_name=_("Total very negative user"),
)
balance_vnegative_user = models.PositiveIntegerField(
verbose_name=_("Balance very negative user"),
)
total_vnegative_user_bde = models.PositiveIntegerField(
verbose_name=_("Total very negative user BDE"),
)
balance_vnegative_user_bde = models.PositiveIntegerField(
verbose_name=_("Balance very negative user BDE"),
)
total_positive_club = models.PositiveIntegerField(
verbose_name=_("Total positive club"),
)
balance_positive_club = models.PositiveIntegerField(
verbose_name=_("Balance positive club"),
)
total_positive_club_nbde = models.PositiveIntegerField(
verbose_name=_("Total positive club nbde"),
)
balance_positive_club_nbde = models.PositiveIntegerField(
verbose_name=_("Balance positive club nbde"),
)
total_zero_club = models.PositiveIntegerField(
verbose_name=_("Total zero club"),
)
total_zero_club_nbde = models.PositiveIntegerField(
verbose_name=_("Total zero club nbde"),
)
total_negative_club = models.PositiveIntegerField(
verbose_name=_("Total negative club"),
)
balance_negative_club = models.PositiveIntegerField(
verbose_name=_("Balance negative club"),
)
total_negative_club_nbde = models.PositiveIntegerField(
verbose_name=_("Total negative club nbde"),
)
balance_negative_club_nbde = models.PositiveIntegerField(
verbose_name=_("Balance negative club nbde"),
)
class Meta:
verbose_name = _("Summary")
verbose_name_plural = _("Summaries")
def __str__(self):
return "Note summary of {date}".format(date=self.date)

View File

@ -29,7 +29,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
<div class="card">
<div class="card-header position-relative" id="clubListHeading">
<a class="font-weight-bold">
<i class="fa fa-bus"></i> {% trans "Teams" %}
<svg class="bi bi-signpost" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M7.293.707A1 1 0 0 0 7 1.414V4H2a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h5v6h2v-6h3.532a1 1 0 0 0 .768-.36l1.933-2.32a.5.5 0 0 0 0-.64L13.3 4.36a1 1 0 0 0-.768-.36H9V1.414A1 1 0 0 0 7.293.707z"/>
</svg>
{% trans "Teams" %}
</a>
</div>
{% render_table teams %}
@ -42,7 +45,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
<div class="card">
<div class="card-header position-relative" id="clubListHeading">
<a class="font-weight-bold">
<i class="fa fa-bus"></i> {% trans "Members" %}
<svg class="bi bi-signpost" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M7.293.707A1 1 0 0 0 7 1.414V4H2a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h5v6h2v-6h3.532a1 1 0 0 0 .768-.36l1.933-2.32a.5.5 0 0 0 0-.64L13.3 4.36a1 1 0 0 0-.768-.36H9V1.414A1 1 0 0 0 7.293.707z"/>
</svg>
{% trans "Members" %}
</a>
</div>
{% render_table memberships %}
@ -51,7 +57,13 @@ SPDX-License-Identifier: GPL-3.0-or-later
<hr>
<a href="{% url 'wei:wei_memberships_bus_pdf' wei_pk=club.pk bus_pk=object.pk %}" data-turbolinks="false">
<button class="btn btn-block btn-danger"><i class="fa fa-file-pdf-o"></i> {% trans "View as PDF" %}</button>
<button class="btn btn-block btn-danger">
<svg class="bi bi-file-pdf" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M5.523 12.424c.14-.082.293-.162.459-.238a7.878 7.878 0 0 1-.45.606c-.28.337-.498.516-.635.572a.266.266 0 0 1-.035.012.282.282 0 0 1-.026-.044c-.056-.11-.054-.216.04-.36.106-.165.319-.354.647-.548zm2.455-1.647c-.119.025-.237.05-.356.078a21.148 21.148 0 0 0 .5-1.05 12.045 12.045 0 0 0 .51.858c-.217.032-.436.07-.654.114zm2.525.939a3.881 3.881 0 0 1-.435-.41c.228.005.434.022.612.054.317.057.466.147.518.209a.095.095 0 0 1 .026.064.436.436 0 0 1-.06.2.307.307 0 0 1-.094.124.107.107 0 0 1-.069.015c-.09-.003-.258-.066-.498-.256zM8.278 6.97c-.04.244-.108.524-.2.829a4.86 4.86 0 0 1-.089-.346c-.076-.353-.087-.63-.046-.822.038-.177.11-.248.196-.283a.517.517 0 0 1 .145-.04c.013.03.028.092.032.198.005.122-.007.277-.038.465z"/>
<path fill-rule="evenodd" d="M4 0h5.293A1 1 0 0 1 10 .293L13.707 4a1 1 0 0 1 .293.707V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2zm5.5 1.5v2a1 1 0 0 0 1 1h2l-3-3zM4.165 13.668c.09.18.23.343.438.419.207.075.412.04.58-.03.318-.13.635-.436.926-.786.333-.401.683-.927 1.021-1.51a11.651 11.651 0 0 1 1.997-.406c.3.383.61.713.91.95.28.22.603.403.934.417a.856.856 0 0 0 .51-.138c.155-.101.27-.247.354-.416.09-.181.145-.37.138-.563a.844.844 0 0 0-.2-.518c-.226-.27-.596-.4-.96-.465a5.76 5.76 0 0 0-1.335-.05 10.954 10.954 0 0 1-.98-1.686c.25-.66.437-1.284.52-1.794.036-.218.055-.426.048-.614a1.238 1.238 0 0 0-.127-.538.7.7 0 0 0-.477-.365c-.202-.043-.41 0-.601.077-.377.15-.576.47-.651.823-.073.34-.04.736.046 1.136.088.406.238.848.43 1.295a19.697 19.697 0 0 1-1.062 2.227 7.662 7.662 0 0 0-1.482.645c-.37.22-.699.48-.897.787-.21.326-.275.714-.08 1.103z"/>
</svg>
{% trans "View as PDF" %}
</button>
</a>
{% endif %}
{% endblock %}

View File

@ -47,7 +47,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
<div class="card">
<div class="card-header position-relative" id="clubListHeading">
<a class="font-weight-bold">
<i class="fa fa-bus"></i> {% trans "Teams" %}
<svg class="bi bi-signpost" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M7.293.707A1 1 0 0 0 7 1.414V4H2a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h5v6h2v-6h3.532a1 1 0 0 0 .768-.36l1.933-2.32a.5.5 0 0 0 0-.64L13.3 4.36a1 1 0 0 0-.768-.36H9V1.414A1 1 0 0 0 7.293.707z"/>
</svg>
{% trans "Teams" %}
</a>
</div>
{% render_table memberships %}
@ -57,7 +60,13 @@ SPDX-License-Identifier: GPL-3.0-or-later
<a href="{% url 'wei:wei_memberships_team_pdf' wei_pk=club.pk bus_pk=object.bus.pk team_pk=object.pk %}"
data-turbolinks="false">
<button class="btn btn-block btn-danger"><i class="fa fa-file-pdf-o"></i> {% trans "View as PDF" %}</button>
<button class="btn btn-block btn-danger">
<svg class="bi bi-file-pdf" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M5.523 12.424c.14-.082.293-.162.459-.238a7.878 7.878 0 0 1-.45.606c-.28.337-.498.516-.635.572a.266.266 0 0 1-.035.012.282.282 0 0 1-.026-.044c-.056-.11-.054-.216.04-.36.106-.165.319-.354.647-.548zm2.455-1.647c-.119.025-.237.05-.356.078a21.148 21.148 0 0 0 .5-1.05 12.045 12.045 0 0 0 .51.858c-.217.032-.436.07-.654.114zm2.525.939a3.881 3.881 0 0 1-.435-.41c.228.005.434.022.612.054.317.057.466.147.518.209a.095.095 0 0 1 .026.064.436.436 0 0 1-.06.2.307.307 0 0 1-.094.124.107.107 0 0 1-.069.015c-.09-.003-.258-.066-.498-.256zM8.278 6.97c-.04.244-.108.524-.2.829a4.86 4.86 0 0 1-.089-.346c-.076-.353-.087-.63-.046-.822.038-.177.11-.248.196-.283a.517.517 0 0 1 .145-.04c.013.03.028.092.032.198.005.122-.007.277-.038.465z"/>
<path fill-rule="evenodd" d="M4 0h5.293A1 1 0 0 1 10 .293L13.707 4a1 1 0 0 1 .293.707V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2zm5.5 1.5v2a1 1 0 0 0 1 1h2l-3-3zM4.165 13.668c.09.18.23.343.438.419.207.075.412.04.58-.03.318-.13.635-.436.926-.786.333-.401.683-.927 1.021-1.51a11.651 11.651 0 0 1 1.997-.406c.3.383.61.713.91.95.28.22.603.403.934.417a.856.856 0 0 0 .51-.138c.155-.101.27-.247.354-.416.09-.181.145-.37.138-.563a.844.844 0 0 0-.2-.518c-.226-.27-.596-.4-.96-.465a5.76 5.76 0 0 0-1.335-.05 10.954 10.954 0 0 1-.98-1.686c.25-.66.437-1.284.52-1.794.036-.218.055-.426.048-.614a1.238 1.238 0 0 0-.127-.538.7.7 0 0 0-.477-.365c-.202-.043-.41 0-.601.077-.377.15-.576.47-.651.823-.073.34-.04.736.046 1.136.088.406.238.848.43 1.295a19.697 19.697 0 0 1-1.062 2.227 7.662 7.662 0 0 0-1.482.645c-.37.22-.699.48-.897.787-.21.326-.275.714-.08 1.103z"/>
</svg>
{% trans "View as PDF" %}
</button>
</a>
{% endif %}
{% endblock %}

View File

@ -48,7 +48,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
<div class="card bg-white mb-3">
<div class="card-header position-relative" id="clubListHeading">
<span class="font-weight-bold">
<i class="fa fa-bus"></i> {% trans "Buses" %}
<svg class="bi bi-signpost" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M7.293.707A1 1 0 0 0 7 1.414V4H2a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h5v6h2v-6h3.532a1 1 0 0 0 .768-.36l1.933-2.32a.5.5 0 0 0 0-.64L13.3 4.36a1 1 0 0 0-.768-.36H9V1.414A1 1 0 0 0 7.293.707z"/>
</svg>
{% trans "Buses" %}
</span>
</div>
{% render_table buses %}
@ -60,7 +63,12 @@ SPDX-License-Identifier: GPL-3.0-or-later
<div class="card-header position-relative" id="clubListHeading">
<a class="stretched-link font-weight-bold text-decoration-none"
href="{% url "wei:wei_memberships" pk=club.pk %}">
<i class="fa fa-users"></i> {% trans "Members of the WEI" %}
<svg class="bi bi-users" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M7 14s-1 0-1-1 1-4 5-4 5 3 5 4-1 1-1 1H7zm4-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
<path fill-rule="evenodd" d="M5.216 14A2.238 2.238 0 0 1 5 13c0-1.355.68-2.75 1.936-3.72A6.325 6.325 0 0 0 5 9c-4 0-5 3-5 4s1 1 1 1h4.216z"/>
<path d="M4.5 8a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z"/>
</svg>
{% trans "Members of the WEI" %}
</a>
</div>
{% render_table member_list %}
@ -72,7 +80,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
<div class="card-header position-relative" id="historyListHeading">
<a class="stretched-link font-weight-bold text-decoration-none" {% if "note.view_note"|has_perm:club.note %}
href="{% url 'note:transactions' pk=club.note.pk %}" {% endif %}>
<i class="fa fa-euro"></i> {% trans "Transaction history" %}
<svg class="bi bi-euro" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M4 9.42h1.063C5.4 12.323 7.317 14 10.34 14c.622 0 1.167-.068 1.659-.185v-1.3c-.484.119-1.045.17-1.659.17-2.1 0-3.455-1.198-3.775-3.264h4.017v-.928H6.497v-.936c0-.11 0-.219.008-.329h4.078v-.927H6.618c.388-1.898 1.719-2.985 3.723-2.985.614 0 1.175.05 1.659.177V2.194A6.617 6.617 0 0 0 10.341 2c-2.928 0-4.82 1.569-5.244 4.3H4v.928h1.01v1.265H4v.928z"/>
</svg>
{% trans "Transaction history" %}
</a>
</div>
<div id="history_list">
@ -86,7 +97,11 @@ SPDX-License-Identifier: GPL-3.0-or-later
<div class="card-header position-relative" id="historyListHeading">
<a class="stretched-link font-weight-bold text-decoration-none"
href="{% url 'wei:wei_registrations' pk=club.pk %}">
<i class="fa fa-user-plus"></i> {% trans "Unvalidated registrations" %}
<svg class="bi bi-user-plus" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M1 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H1zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
<path fill-rule="evenodd" d="M13.5 5a.5.5 0 0 1 .5.5V7h1.5a.5.5 0 0 1 0 1H14v1.5a.5.5 0 0 1-1 0V8h-1.5a.5.5 0 0 1 0-1H13V5.5a.5.5 0 0 1 .5-.5z"/>
</svg>
{% trans "Unvalidated registrations" %}
</a>
</div>
<div id="history_list">

View File

@ -28,7 +28,13 @@ SPDX-License-Identifier: GPL-3.0-or-later
</a>
<hr>
<a href="{% url 'wei:wei_memberships_pdf' wei_pk=club.pk %}" data-turbolinks="false">
<button class="btn btn-block btn-danger"><i class="fa fa-file-pdf-o"></i> {% trans "View as PDF" %}</button>
<button class="btn btn-block btn-danger">
<svg class="bi bi-file-pdf" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M5.523 12.424c.14-.082.293-.162.459-.238a7.878 7.878 0 0 1-.45.606c-.28.337-.498.516-.635.572a.266.266 0 0 1-.035.012.282.282 0 0 1-.026-.044c-.056-.11-.054-.216.04-.36.106-.165.319-.354.647-.548zm2.455-1.647c-.119.025-.237.05-.356.078a21.148 21.148 0 0 0 .5-1.05 12.045 12.045 0 0 0 .51.858c-.217.032-.436.07-.654.114zm2.525.939a3.881 3.881 0 0 1-.435-.41c.228.005.434.022.612.054.317.057.466.147.518.209a.095.095 0 0 1 .026.064.436.436 0 0 1-.06.2.307.307 0 0 1-.094.124.107.107 0 0 1-.069.015c-.09-.003-.258-.066-.498-.256zM8.278 6.97c-.04.244-.108.524-.2.829a4.86 4.86 0 0 1-.089-.346c-.076-.353-.087-.63-.046-.822.038-.177.11-.248.196-.283a.517.517 0 0 1 .145-.04c.013.03.028.092.032.198.005.122-.007.277-.038.465z"/>
<path fill-rule="evenodd" d="M4 0h5.293A1 1 0 0 1 10 .293L13.707 4a1 1 0 0 1 .293.707V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2zm5.5 1.5v2a1 1 0 0 0 1 1h2l-3-3zM4.165 13.668c.09.18.23.343.438.419.207.075.412.04.58-.03.318-.13.635-.436.926-.786.333-.401.683-.927 1.021-1.51a11.651 11.651 0 0 1 1.997-.406c.3.383.61.713.91.95.28.22.603.403.934.417a.856.856 0 0 0 .51-.138c.155-.101.27-.247.354-.416.09-.181.145-.37.138-.563a.844.844 0 0 0-.2-.518c-.226-.27-.596-.4-.96-.465a5.76 5.76 0 0 0-1.335-.05 10.954 10.954 0 0 1-.98-1.686c.25-.66.437-1.284.52-1.794.036-.218.055-.426.048-.614a1.238 1.238 0 0 0-.127-.538.7.7 0 0 0-.477-.365c-.202-.043-.41 0-.601.077-.377.15-.576.47-.651.823-.073.34-.04.736.046 1.136.088.406.238.848.43 1.295a19.697 19.697 0 0 1-1.062 2.227 7.662 7.662 0 0 0-1.482.645c-.37.22-.699.48-.897.787-.21.326-.275.714-.08 1.103z"/>
</svg>
{% trans "View as PDF" %}
</button>
</a>
</div>
</div>

View File

@ -23,7 +23,7 @@ Sur un Ubuntu/Debian :
$ sudo apt update
$ sudo apt install --no-install-recommends -y \
python3-setuptools python3-venv python3-dev \
texlive-xetex gettext libjs-bootstrap4 fonts-font-awesome git
texlive-xetex gettext libjs-bootstrap4 git
Pour Arch Linux :

View File

@ -62,7 +62,7 @@ plus propre. On peut donc installer tout ce dont on a besoin, depuis buster-back
$ sudo apt update
$ sudo apt install -t buster-backports --no-install-recommends \
gettext git ipython3 \ # Dépendances basiques
fonts-font-awesome libjs-bootstrap4 \ # Pour l'affichage web
libjs-bootstrap4 \ # Pour l'affichage web
python3-bs4 python3-django python3-django-crispy-forms python3-django-extensions \
python3-django-filters python3-django-oauth-toolkit python3-django-polymorphic \
python3-djangorestframework python3-memcache python3-phonenumbers \

View File

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

View File

@ -19,8 +19,6 @@ MAILTO=notekfet2020@lists.crans.org
00 5 * * 2 root cd /var/www/note_kfet && env/bin/python manage.py send_mail_to_negative_balances --spam --negative-amount 1 -v 0
# Envoyer le rapport mensuel aux trésoriers et respos info
00 8 * * 5 root cd /var/www/note_kfet && env/bin/python manage.py send_mail_to_negative_balances --report --add-years 1 -v 0
# Envoyer le recap de tresorerie
00 8 * * 5 root cd /var/www/note_kfet && env/bin/python manage.py send_summary_notes_report --negative-amount 2000
# Envoyer les rapports aux gens
55 6 * * * root cd /var/www/note_kfet && env/bin/python manage.py send_reports -v 0
# Mettre à jour les boutons mis en avant

View File

@ -24,9 +24,8 @@ SPDX-License-Identifier: GPL-3.0-or-later
<meta name="msapplication-config" content="{% static "favicon/browserconfig.xml" %}">
<meta name="theme-color" content="#ffffff">
{# Bootstrap, Font Awesome and custom CSS #}
{# Load CSS #}
<link rel="stylesheet" href="{% static "bootstrap4/css/bootstrap.min.css" %}">
<link rel="stylesheet" href="{% static "font-awesome/css/font-awesome.min.css" %}">
<link rel="stylesheet" href="{% static "css/custom.css" %}">
{# JQuery, Bootstrap and Turbolinks JavaScript #}
@ -63,54 +62,101 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% if "note.transactiontemplate"|not_empty_model_list %}
<li class="nav-item">
{% url 'note:consos' as url %}
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}"><i class="fa fa-coffee"></i> {% trans 'Consumptions' %}</a>
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}">
<svg class="bi bi-mug" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M1 2a1 1 0 0 1 1-1h11a1 1 0 0 1 1 1v1h.5A1.5 1.5 0 0 1 16 4.5v7a1.5 1.5 0 0 1-1.5 1.5h-.55a2.5 2.5 0 0 1-2.45 2h-8A2.5 2.5 0 0 1 1 12.5V2zm13 10h.5a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.5-.5H14v8z"/>
</svg>
{% trans 'Consumptions' %}
</a>
</li>
{% endif %}
{% 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>
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}">
<svg class="bi bi-exchange" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1 11.5a.5.5 0 0 0 .5.5h11.793l-3.147 3.146a.5.5 0 0 0 .708.708l4-4a.5.5 0 0 0 0-.708l-4-4a.5.5 0 0 0-.708.708L13.293 11H1.5a.5.5 0 0 0-.5.5zm14-7a.5.5 0 0 1-.5.5H2.707l3.147 3.146a.5.5 0 1 1-.708.708l-4-4a.5.5 0 0 1 0-.708l4-4a.5.5 0 1 1 .708.708L2.707 4H14.5a.5.5 0 0 1 .5.5z"/>
</svg>
{% trans 'Transfer' %}
</a>
</li>
{% endif %}
{% if "auth.user"|model_list_length >= 2 %}
<li class="nav-item">
{% url 'member:user_list' as url %}
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}"><i class="fa fa-user"></i> {% trans 'Users' %}</a>
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}">
<svg class="bi bi-user" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H3zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
</svg>
{% trans 'Users' %}
</a>
</li>
{% endif %}
{% if "member.club"|not_empty_model_list %}
<li class="nav-item">
{% url 'member:club_list' as url %}
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}"><i class="fa fa-users"></i> {% trans 'Clubs' %}</a>
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}">
<svg class="bi bi-users" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M7 14s-1 0-1-1 1-4 5-4 5 3 5 4-1 1-1 1H7zm4-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
<path fill-rule="evenodd" d="M5.216 14A2.238 2.238 0 0 1 5 13c0-1.355.68-2.75 1.936-3.72A6.325 6.325 0 0 0 5 9c-4 0-5 3-5 4s1 1 1 1h4.216z"/>
<path d="M4.5 8a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z"/>
</svg>
{% trans 'Clubs' %}
</a>
</li>
{% endif %}
{% if "activity.activity"|not_empty_model_list %}
<li class="nav-item">
{% url 'activity:activity_list' as url %}
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}"><i class="fa fa-calendar"></i> {% trans 'Activities' %}</a>
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}">
<svg class="bi bi-calendar" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V5h16V4H0V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5z"/>
</svg>
{% trans 'Activities' %}
</a>
</li>
{% endif %}
{% if "treasury.invoice"|not_empty_model_list %}
<li class="nav-item">
{% url 'treasury:invoice_list' as url %}
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}"><i class="fa fa-credit-card"></i> {% trans 'Treasury' %}</a>
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}">
<svg class="bi bi-credit-card" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v1H0V4zm0 3v5a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7H0zm3 2h1a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1z"/>
</svg>
{% trans 'Treasury' %}
</a>
</li>
{% endif %}
{% if "wei.weiclub"|not_empty_model_list %}
<li class="nav-item">
{% url 'wei:current_wei_detail' as url %}
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}"><i class="fa fa-bus"></i> {% trans 'WEI' %}</a>
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}">
<svg class="bi bi-signpost" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M7.293.707A1 1 0 0 0 7 1.414V4H2a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h5v6h2v-6h3.532a1 1 0 0 0 .768-.36l1.933-2.32a.5.5 0 0 0 0-.64L13.3 4.36a1 1 0 0 0-.768-.36H9V1.414A1 1 0 0 0 7.293.707z"/>
</svg>
{% trans 'WEI' %}
</a>
</li>
{% endif %}
{% if request.user.is_authenticated %}
<li class="nav-item">
{% url 'permission:rights' as url %}
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}"><i class="fa fa-balance-scale"></i> {% trans 'Rights' %}</a>
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}">
<svg class="bi bi-shield" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 0c-.69 0-1.843.265-2.928.56-1.11.3-2.229.655-2.887.87a1.54 1.54 0 0 0-1.044 1.262c-.596 4.477.787 7.795 2.465 9.99a11.777 11.777 0 0 0 2.517 2.453c.386.273.744.482 1.048.625.28.132.581.24.829.24s.548-.108.829-.24a7.159 7.159 0 0 0 1.048-.625 11.775 11.775 0 0 0 2.517-2.453c1.678-2.195 3.061-5.513 2.465-9.99a1.541 1.541 0 0 0-1.044-1.263 62.467 62.467 0 0 0-2.887-.87C9.843.266 8.69 0 8 0zm0 5a1.5 1.5 0 0 1 .5 2.915l.385 1.99a.5.5 0 0 1-.491.595h-.788a.5.5 0 0 1-.49-.595l.384-1.99A1.5 1.5 0 0 1 8 5z"/>
</svg>
{% trans 'Rights' %}
</a>
</li>
{% endif %}
{% if request.user.is_staff and ""|has_perm:user %}
<li class="nav-item">
<a data-turbolinks="false" class="nav-link" href="{% url 'admin:index' %}"><i class="fa fa-cogs"></i> {% trans 'Admin' %}</a>
<a data-turbolinks="false" class="nav-link" href="{% url 'admin:index' %}">
<svg class="bi bi-cog" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M9.405 1.05c-.413-1.4-2.397-1.4-2.81 0l-.1.34a1.464 1.464 0 0 1-2.105.872l-.31-.17c-1.283-.698-2.686.705-1.987 1.987l.169.311c.446.82.023 1.841-.872 2.105l-.34.1c-1.4.413-1.4 2.397 0 2.81l.34.1a1.464 1.464 0 0 1 .872 2.105l-.17.31c-.698 1.283.705 2.686 1.987 1.987l.311-.169a1.464 1.464 0 0 1 2.105.872l.1.34c.413 1.4 2.397 1.4 2.81 0l.1-.34a1.464 1.464 0 0 1 2.105-.872l.31.17c1.283.698 2.686-.705 1.987-1.987l-.169-.311a1.464 1.464 0 0 1 .872-2.105l.34-.1c1.4-.413 1.4-2.397 0-2.81l-.34-.1a1.464 1.464 0 0 1-.872-2.105l.17-.31c.698-1.283-.705-2.686-1.987-1.987l-.311.169a1.464 1.464 0 0 1-2.105-.872l-.1-.34zM8 10.93a2.929 2.929 0 1 1 0-5.86 2.929 2.929 0 0 1 0 5.858z"/>
</svg>
{% trans 'Admin' %}
</a>
</li>
{% endif %}
</ul>
@ -118,16 +164,25 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% if request.user.is_authenticated %}
<li class="dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-user"></i>
<svg class="bi bi-user" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H3zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
</svg>
<span id="user_balance">{{ request.user.username }} ({{ request.user.note.balance | pretty_money }})</span>
</a>
<div class="dropdown-menu dropdown-menu-right"
aria-labelledby="navbarDropdownMenuLink">
<a class="dropdown-item" href="{% url 'member:user_detail' pk=request.user.pk %}">
<i class="fa fa-user"></i> {% trans "My account" %}
<svg class="bi bi-user" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H3zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
</svg>
{% trans "My account" %}
</a>
<a class="dropdown-item" href="{% url 'logout' %}">
<i class="fa fa-sign-out"></i> {% trans "Log out" %}
<svg class="bi bi-signout" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M10 12.5a.5.5 0 0 1-.5.5h-8a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v2a.5.5 0 0 0 1 0v-2A1.5 1.5 0 0 0 9.5 2h-8A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h8a1.5 1.5 0 0 0 1.5-1.5v-2a.5.5 0 0 0-1 0v2z"/>
<path fill-rule="evenodd" d="M15.854 8.354a.5.5 0 0 0 0-.708l-3-3a.5.5 0 0 0-.708.708L14.293 7.5H5.5a.5.5 0 0 0 0 1h8.793l-2.147 2.146a.5.5 0 0 0 .708.708l3-3z"/>
</svg>
{% trans "Log out" %}
</a>
</div>
</li>
@ -135,14 +190,22 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% if request.path != "/registration/signup/" %}
<li class="nav-item">
<a class="nav-link" href="{% url 'registration:signup' %}">
<i class="fa fa-user-plus"></i> {% trans "Sign up" %}
<svg class="bi bi-user-plus" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M1 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H1zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
<path fill-rule="evenodd" d="M13.5 5a.5.5 0 0 1 .5.5V7h1.5a.5.5 0 0 1 0 1H14v1.5a.5.5 0 0 1-1 0V8h-1.5a.5.5 0 0 1 0-1H13V5.5a.5.5 0 0 1 .5-.5z"/>
</svg>
{% trans "Sign up" %}
</a>
</li>
{% endif %}
{% if request.path != "/accounts/login/" %}
<li class="nav-item">
<a class="nav-link" href="{% url 'login' %}">
<i class="fa fa-sign-in"></i> {% trans "Log in" %}
<svg class="bi bi-login" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M6 3.5a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v9a.5.5 0 0 1-.5.5h-8a.5.5 0 0 1-.5-.5v-2a.5.5 0 0 0-1 0v2A1.5 1.5 0 0 0 6.5 14h8a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 14.5 2h-8A1.5 1.5 0 0 0 5 3.5v2a.5.5 0 0 0 1 0v-2z"/>
<path fill-rule="evenodd" d="M11.854 8.354a.5.5 0 0 0 0-.708l-3-3a.5.5 0 1 0-.708.708L10.293 7.5H1.5a.5.5 0 0 0 0 1h8.793l-2.147 2.146a.5.5 0 0 0 .708.708l3-3z"/>
</svg>
{% trans "Log in" %}
</a>
</li>
{% endif %}