mirror of
https://gitlab.crans.org/bde/nk20
synced 2025-06-23 10:56:35 +02:00
Compare commits
37 Commits
fef0de75f2
...
summary_no
Author | SHA1 | Date | |
---|---|---|---|
5a0fe7a6f0 | |||
eda8460014 | |||
15c71ad31a | |||
b8f81048a5 | |||
af819f45a1 | |||
076d065ffa | |||
2da77d9c17 | |||
01584d6330 | |||
4c0a5922c4 | |||
f90b28fc7c | |||
925e0f26f5 | |||
c912383f86 | |||
32830e43fd | |||
11c6a6fa7a | |||
201d6b114a | |||
19e77df299 | |||
5fd6ec5668 | |||
10a01c5bc2 | |||
989905ea64 | |||
0218d43a17 | |||
5d30b0e819 | |||
ec759dd3c0 | |||
2eb965291d | |||
7f182ee2ee | |||
3132aa4c38 | |||
c7eb774859 | |||
32f8d285b3 | |||
050256ea13 | |||
7afd15b1cc | |||
258361f116 | |||
5de930bf40 | |||
f7ebe0e99b | |||
73de6e2176 | |||
40c239e9da | |||
2aaab2b454 | |||
fc088dec86 | |||
ffac940511 |
@ -8,19 +8,19 @@ variables:
|
|||||||
GIT_SUBMODULE_STRATEGY: recursive
|
GIT_SUBMODULE_STRATEGY: recursive
|
||||||
|
|
||||||
# Debian Buster
|
# Debian Buster
|
||||||
py37-django22:
|
# py37-django22:
|
||||||
stage: test
|
# stage: test
|
||||||
image: debian:buster-backports
|
# image: debian:buster-backports
|
||||||
before_script:
|
# before_script:
|
||||||
- >
|
# - >
|
||||||
apt-get update &&
|
# apt-get update &&
|
||||||
apt-get install --no-install-recommends -t buster-backports -y
|
# apt-get install --no-install-recommends -t buster-backports -y
|
||||||
python3-django python3-django-crispy-forms
|
# python3-django python3-django-crispy-forms
|
||||||
python3-django-extensions python3-django-filters python3-django-polymorphic
|
# python3-django-extensions python3-django-filters python3-django-polymorphic
|
||||||
python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
|
# python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
|
||||||
python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
|
# python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
|
||||||
python3-bs4 python3-setuptools tox texlive-xetex
|
# python3-bs4 python3-setuptools tox texlive-xetex
|
||||||
script: tox -e py37-django22
|
# script: tox -e py37-django22
|
||||||
|
|
||||||
# Ubuntu 20.04
|
# Ubuntu 20.04
|
||||||
py38-django22:
|
py38-django22:
|
||||||
@ -56,7 +56,7 @@ py39-django22:
|
|||||||
|
|
||||||
linters:
|
linters:
|
||||||
stage: quality-assurance
|
stage: quality-assurance
|
||||||
image: debian:buster-backports
|
image: debian:bullseye
|
||||||
before_script:
|
before_script:
|
||||||
- apt-get update && apt-get install -y tox
|
- apt-get update && apt-get install -y tox
|
||||||
script: tox -e linters
|
script: tox -e linters
|
||||||
|
@ -17,6 +17,9 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extrajavascript %}
|
||||||
<script>
|
<script>
|
||||||
var date_end = document.getElementById("id_date_end");
|
var date_end = document.getElementById("id_date_end");
|
||||||
var date_start = document.getElementById("id_date_start");
|
var date_start = document.getElementById("id_date_start");
|
||||||
|
@ -17,7 +17,8 @@ from django.utils.translation import gettext_lazy as _
|
|||||||
from django.views import View
|
from django.views import View
|
||||||
from django.views.decorators.cache import cache_page
|
from django.views.decorators.cache import cache_page
|
||||||
from django.views.generic import DetailView, TemplateView, UpdateView
|
from django.views.generic import DetailView, TemplateView, UpdateView
|
||||||
from django_tables2.views import SingleTableView
|
from django.views.generic.list import ListView
|
||||||
|
from django_tables2.views import MultiTableMixin
|
||||||
from note.models import Alias, NoteSpecial, NoteUser
|
from note.models import Alias, NoteSpecial, NoteUser
|
||||||
from permission.backends import PermissionBackend
|
from permission.backends import PermissionBackend
|
||||||
from permission.views import ProtectQuerysetMixin, ProtectedCreateView
|
from permission.views import ProtectQuerysetMixin, ProtectedCreateView
|
||||||
@ -57,27 +58,40 @@ class ActivityCreateView(ProtectQuerysetMixin, ProtectedCreateView):
|
|||||||
return reverse_lazy('activity:activity_detail', kwargs={"pk": self.object.pk})
|
return reverse_lazy('activity:activity_detail', kwargs={"pk": self.object.pk})
|
||||||
|
|
||||||
|
|
||||||
class ActivityListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
|
class ActivityListView(ProtectQuerysetMixin, LoginRequiredMixin, MultiTableMixin, ListView):
|
||||||
"""
|
"""
|
||||||
Displays all Activities, and classify if they are on-going or upcoming ones.
|
Displays all Activities, and classify if they are on-going or upcoming ones.
|
||||||
"""
|
"""
|
||||||
model = Activity
|
model = Activity
|
||||||
table_class = ActivityTable
|
tables = [ActivityTable, ActivityTable]
|
||||||
ordering = ('-date_start',)
|
|
||||||
extra_context = {"title": _("Activities")}
|
extra_context = {"title": _("Activities")}
|
||||||
|
|
||||||
def get_queryset(self, **kwargs):
|
def get_queryset(self, **kwargs):
|
||||||
return super().get_queryset(**kwargs).distinct()
|
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):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
|
|
||||||
upcoming_activities = Activity.objects.filter(date_end__gt=timezone.now())
|
tables = context["tables"]
|
||||||
context['upcoming'] = ActivityTable(
|
for name, table in zip(["table", "upcoming"], tables):
|
||||||
data=upcoming_activities.filter(PermissionBackend.filter_queryset(self.request, Activity, "view")),
|
context[name] = table
|
||||||
prefix='upcoming-',
|
|
||||||
order_by='date_start',
|
|
||||||
)
|
|
||||||
|
|
||||||
started_activities = self.get_queryset().filter(open=True, valid=True).distinct().all()
|
started_activities = self.get_queryset().filter(open=True, valid=True).distinct().all()
|
||||||
context["started_activities"] = started_activities
|
context["started_activities"] = started_activities
|
||||||
|
@ -138,6 +138,9 @@ class ImageForm(forms.Form):
|
|||||||
|
|
||||||
return cleaned_data
|
return cleaned_data
|
||||||
|
|
||||||
|
def is_valid(self):
|
||||||
|
return super().is_valid() or super().clean().get('image') is None
|
||||||
|
|
||||||
|
|
||||||
class ClubForm(forms.ModelForm):
|
class ClubForm(forms.ModelForm):
|
||||||
def clean(self):
|
def clean(self):
|
||||||
@ -151,7 +154,7 @@ class ClubForm(forms.ModelForm):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Club
|
model = Club
|
||||||
fields = '__all__'
|
exclude = ("add_registration_form",)
|
||||||
widgets = {
|
widgets = {
|
||||||
"membership_fee_paid": AmountInput(),
|
"membership_fee_paid": AmountInput(),
|
||||||
"membership_fee_unpaid": AmountInput(),
|
"membership_fee_unpaid": AmountInput(),
|
||||||
|
18
apps/member/migrations/0012_club_add_registration_form.py
Normal file
18
apps/member/migrations/0012_club_add_registration_form.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# 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'),
|
||||||
|
),
|
||||||
|
]
|
18
apps/member/migrations/0013_auto_20240807_1409.py
Normal file
18
apps/member/migrations/0013_auto_20240807_1409.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# 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'),
|
||||||
|
),
|
||||||
|
]
|
@ -259,6 +259,11 @@ class Club(models.Model):
|
|||||||
help_text=_('Maximal date of a membership, after which members must renew it.'),
|
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:
|
class Meta:
|
||||||
verbose_name = _("club")
|
verbose_name = _("club")
|
||||||
verbose_name_plural = _("clubs")
|
verbose_name_plural = _("clubs")
|
||||||
|
@ -14,6 +14,9 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
|||||||
<form method="post" enctype="multipart/form-data" id="formUpload">
|
<form method="post" enctype="multipart/form-data" id="formUpload">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form |crispy }}
|
{{ form |crispy }}
|
||||||
|
{% if user.note.display_image != "pic/default.png" %}
|
||||||
|
<input type="submit" class="btn btn-primary" value="{% trans "Remove" %}">
|
||||||
|
{% endif %}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<!-- MODAL TO CROP THE IMAGE -->
|
<!-- MODAL TO CROP THE IMAGE -->
|
||||||
|
@ -326,6 +326,9 @@ class PictureUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin, Det
|
|||||||
"""Save image to note"""
|
"""Save image to note"""
|
||||||
image = form.cleaned_data['image']
|
image = form.cleaned_data['image']
|
||||||
|
|
||||||
|
if image is None:
|
||||||
|
image = "pic/default.png"
|
||||||
|
else:
|
||||||
# Rename as a PNG or GIF
|
# Rename as a PNG or GIF
|
||||||
extension = image.name.split(".")[-1]
|
extension = image.name.split(".")[-1]
|
||||||
if extension == "gif":
|
if extension == "gif":
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
Par ailleurs, le BDE ne sert pas d'alcool aux adhérents dont le solde
|
Par ailleurs, le BDE ne sert pas d'alcool aux adhérents dont le solde
|
||||||
est inférieur à 0 € depuis plus de 24h.
|
est inférieur à 0 €.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
65
apps/note/templates/note/mails/summary_notes_report.html
Normal file
65
apps/note/templates/note/mails/summary_notes_report.html
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
{% 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>
|
33
apps/note/templates/note/mails/summary_notes_report.txt
Normal file
33
apps/note/templates/note/mails/summary_notes_report.txt
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{% 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" %}
|
@ -2591,12 +2591,12 @@
|
|||||||
"note",
|
"note",
|
||||||
"transaction"
|
"transaction"
|
||||||
],
|
],
|
||||||
"query": "[\"OR\", {\"source__balance__gte\": {\"F\": [\"SUB\", [\"MUL\", [\"F\", \"amount\"], [\"F\", \"quantity\"]], 2000]}}, {\"valid\": false}]",
|
"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}]",
|
||||||
"type": "add",
|
"type": "add",
|
||||||
"mask": 2,
|
"mask": 2,
|
||||||
"field": "",
|
"field": "",
|
||||||
"permanent": false,
|
"permanent": false,
|
||||||
"description": "Créer une transaction quelconque tant que la source reste au-dessus de -20 €"
|
"description": "Créer une transaction quelconque tant que la source reste positive s'il s'agit d'alcool, sinon au-dessus de -20€"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,6 @@ from django import forms
|
|||||||
from django.contrib.auth.forms import UserCreationForm
|
from django.contrib.auth.forms import UserCreationForm
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from member.models import Club
|
|
||||||
from note.models import NoteSpecial, Alias
|
from note.models import NoteSpecial, Alias
|
||||||
from note_kfet.inputs import AmountInput
|
from note_kfet.inputs import AmountInput
|
||||||
|
|
||||||
@ -115,12 +114,3 @@ class ValidationForm(forms.Form):
|
|||||||
required=False,
|
required=False,
|
||||||
initial=True,
|
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,
|
|
||||||
)
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
|
# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
from django import forms
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
@ -238,9 +239,8 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
|
|||||||
fee += bde.membership_fee_paid if user.profile.paid else bde.membership_fee_unpaid
|
fee += bde.membership_fee_paid if user.profile.paid else bde.membership_fee_unpaid
|
||||||
kfet = Club.objects.get(name="Kfet")
|
kfet = Club.objects.get(name="Kfet")
|
||||||
fee += kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid
|
fee += kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid
|
||||||
if Club.objects.filter(name__iexact="BDA").exists():
|
for club in Club.objects.filter(add_registration_form=True):
|
||||||
bda = Club.objects.get(name__iexact="BDA")
|
fee += club.membership_fee_paid if user.profile.paid else club.membership_fee_unpaid
|
||||||
fee += bda.membership_fee_paid if user.profile.paid else bda.membership_fee_unpaid
|
|
||||||
ctx["total_fee"] = "{:.02f}".format(fee / 100, )
|
ctx["total_fee"] = "{:.02f}".format(fee / 100, )
|
||||||
|
|
||||||
# ctx["declare_soge_account"] = SogeCredit.objects.filter(user=user).exists()
|
# ctx["declare_soge_account"] = SogeCredit.objects.filter(user=user).exists()
|
||||||
@ -249,6 +249,16 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
|
|||||||
|
|
||||||
def get_form(self, form_class=None):
|
def get_form(self, form_class=None):
|
||||||
form = super().get_form(form_class)
|
form = super().get_form(form_class)
|
||||||
|
|
||||||
|
# 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()
|
user = self.get_object()
|
||||||
form.fields["last_name"].initial = user.last_name
|
form.fields["last_name"].initial = user.last_name
|
||||||
form.fields["first_name"].initial = user.first_name
|
form.fields["first_name"].initial = user.first_name
|
||||||
@ -266,11 +276,6 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
|
|||||||
form.add_error(None, _("An alias with a similar name already exists."))
|
form.add_error(None, _("An alias with a similar name already exists."))
|
||||||
return self.form_invalid(form)
|
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
|
# Get form data
|
||||||
# soge = form.cleaned_data["soge"]
|
# soge = form.cleaned_data["soge"]
|
||||||
credit_type = form.cleaned_data["credit_type"]
|
credit_type = form.cleaned_data["credit_type"]
|
||||||
@ -280,8 +285,9 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
|
|||||||
bank = form.cleaned_data["bank"]
|
bank = form.cleaned_data["bank"]
|
||||||
join_bde = form.cleaned_data["join_bde"]
|
join_bde = form.cleaned_data["join_bde"]
|
||||||
join_kfet = form.cleaned_data["join_kfet"]
|
join_kfet = form.cleaned_data["join_kfet"]
|
||||||
if bda_exists:
|
|
||||||
join_bda = form.cleaned_data["join_bda"]
|
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 soge:
|
# if soge:
|
||||||
# # If Société Générale pays the inscription, the user automatically joins the two clubs.
|
# # If Société Générale pays the inscription, the user automatically joins the two clubs.
|
||||||
@ -303,11 +309,12 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
|
|||||||
kfet_fee = kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid
|
kfet_fee = kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid
|
||||||
# Add extra fee for the full membership
|
# Add extra fee for the full membership
|
||||||
fee += kfet_fee if join_kfet else 0
|
fee += kfet_fee if join_kfet else 0
|
||||||
if bda_exists:
|
clubs_fee = dict()
|
||||||
bda = Club.objects.get(name__iexact="BDA")
|
for club, join_club in join_clubs:
|
||||||
bda_fee = bda.membership_fee_paid if user.profile.paid else bda.membership_fee_unpaid
|
club_fee = club.membership_fee_paid if user.profile.paid else club.membership_fee_unpaid
|
||||||
# Add extra fee for the bda membership
|
# Add extra fee for the club membership
|
||||||
fee += bda_fee if join_bda else 0
|
clubs_fee[club] = club_fee
|
||||||
|
fee += club_fee if join_club else 0
|
||||||
|
|
||||||
# # If the bank pays, then we don't credit now. Treasurers will validate the transaction
|
# # If the bank pays, then we don't credit now. Treasurers will validate the transaction
|
||||||
# # and credit the note later.
|
# # and credit the note later.
|
||||||
@ -387,12 +394,13 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
|
|||||||
membership.roles.add(Role.objects.get(name="Adhérent Kfet"))
|
membership.roles.add(Role.objects.get(name="Adhérent Kfet"))
|
||||||
membership.save()
|
membership.save()
|
||||||
|
|
||||||
if bda_exists and join_bda:
|
for club, join_club in join_clubs:
|
||||||
|
if join_club:
|
||||||
# Create membership for the user to the BDA starting today
|
# Create membership for the user to the BDA starting today
|
||||||
membership = Membership(
|
membership = Membership(
|
||||||
club=bda,
|
club=club,
|
||||||
user=user,
|
user=user,
|
||||||
fee=bda_fee,
|
fee=clubs_fee[club],
|
||||||
)
|
)
|
||||||
membership.save()
|
membership.save()
|
||||||
membership.refresh_from_db()
|
membership.refresh_from_db()
|
||||||
|
Submodule apps/scripts updated: f580f9b9e9...f76acb3248
@ -5,13 +5,13 @@ from django.contrib import admin
|
|||||||
from note_kfet.admin import admin_site
|
from note_kfet.admin import admin_site
|
||||||
|
|
||||||
from .forms import ProductForm
|
from .forms import ProductForm
|
||||||
from .models import RemittanceType, Remittance, SogeCredit, Invoice, Product
|
from .models import Invoice, NoteSummary, Product, RemittanceType, Remittance, SogeCredit
|
||||||
|
|
||||||
|
|
||||||
@admin.register(RemittanceType, site=admin_site)
|
@admin.register(RemittanceType, site=admin_site)
|
||||||
class RemittanceTypeAdmin(admin.ModelAdmin):
|
class RemittanceTypeAdmin(admin.ModelAdmin):
|
||||||
"""
|
"""
|
||||||
Admin customisation for RemiitanceType
|
Admin customisation for RemittanceType
|
||||||
"""
|
"""
|
||||||
list_display = ('note', )
|
list_display = ('note', )
|
||||||
|
|
||||||
@ -55,3 +55,19 @@ class InvoiceAdmin(admin.ModelAdmin):
|
|||||||
"""
|
"""
|
||||||
list_display = ('object', 'id', 'bde', 'name', 'date', 'acquitted',)
|
list_display = ('object', 'id', 'bde', 'name', 'date', 'acquitted',)
|
||||||
inlines = (ProductInline,)
|
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',
|
||||||
|
)
|
||||||
|
23
apps/treasury/migrations/0008_auto_20240322_0045.py
Normal file
23
apps/treasury/migrations/0008_auto_20240322_0045.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 2.2.28 on 2024-03-21 23:45
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('treasury', '0007_auto_20240311_1549'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='invoice',
|
||||||
|
name='payment_date',
|
||||||
|
field=models.CharField(default='', max_length=255, verbose_name='Payment date'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='invoice',
|
||||||
|
name='quotation',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='Quotation'),
|
||||||
|
),
|
||||||
|
]
|
49
apps/treasury/migrations/0009_notesummary.py
Normal file
49
apps/treasury/migrations/0009_notesummary.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# 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',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
@ -41,6 +41,10 @@ class Invoice(models.Model):
|
|||||||
),
|
),
|
||||||
verbose_name=_("BDE"),
|
verbose_name=_("BDE"),
|
||||||
)
|
)
|
||||||
|
quotation = models.BooleanField(
|
||||||
|
default=False,
|
||||||
|
verbose_name=_("Quotation"),
|
||||||
|
)
|
||||||
|
|
||||||
object = models.CharField(
|
object = models.CharField(
|
||||||
max_length=255,
|
max_length=255,
|
||||||
@ -65,6 +69,12 @@ class Invoice(models.Model):
|
|||||||
verbose_name=_("Date"),
|
verbose_name=_("Date"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
payment_date = models.CharField(
|
||||||
|
default="",
|
||||||
|
max_length=255,
|
||||||
|
verbose_name=_("Payment date"),
|
||||||
|
)
|
||||||
|
|
||||||
acquitted = models.BooleanField(
|
acquitted = models.BooleanField(
|
||||||
verbose_name=_("Acquitted"),
|
verbose_name=_("Acquitted"),
|
||||||
default=False,
|
default=False,
|
||||||
@ -450,3 +460,117 @@ class SogeCredit(models.Model):
|
|||||||
self.credit_transaction._force_save = True
|
self.credit_transaction._force_save = True
|
||||||
self.credit_transaction.save()
|
self.credit_transaction.save()
|
||||||
super().delete(**kwargs)
|
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)
|
||||||
|
@ -76,8 +76,11 @@
|
|||||||
|
|
||||||
\def\FactureNum {{"{"}}{{ obj.id }}} % Numéro de facture
|
\def\FactureNum {{"{"}}{{ obj.id }}} % Numéro de facture
|
||||||
\def\FactureAcquittee {% if obj.acquitted %} {oui} {% else %} {non} {% endif %} % Facture acquittée : oui/non
|
\def\FactureAcquittee {% if obj.acquitted %} {oui} {% else %} {non} {% endif %} % Facture acquittée : oui/non
|
||||||
|
\def\Devis {% if obj.quotation %} {oui} {% else %} {non} {% endif %}
|
||||||
|
% Devis : oui/non
|
||||||
\def\FactureLieu {{"{"}}{{ obj.place|escape_tex }}} % Lieu de l'édition de la facture
|
\def\FactureLieu {{"{"}}{{ obj.place|escape_tex }}} % Lieu de l'édition de la facture
|
||||||
\def\FactureDate {{"{"}}{{ obj.date }}} % Date de l'édition de la facture
|
\def\FactureDate {{"{"}}{{ obj.date }}} % Date de l'édition de la facture
|
||||||
|
\def\FacturePaymentDate {{"{"}}{{ obj.payment_date|escape_tex }}} % Date de paiement de la facture
|
||||||
\def\FactureObjet {{"{"}}{{ obj.object|escape_tex }} } % Objet du document
|
\def\FactureObjet {{"{"}}{{ obj.object|escape_tex }} } % Objet du document
|
||||||
% Description de la facture
|
% Description de la facture
|
||||||
\def\FactureDescr {{"{"}}{{ obj.description|escape_tex }}}
|
\def\FactureDescr {{"{"}}{{ obj.description|escape_tex }}}
|
||||||
@ -118,10 +121,12 @@
|
|||||||
% Nom et adresse de la société
|
% Nom et adresse de la société
|
||||||
\MonNom \\
|
\MonNom \\
|
||||||
\MonAdresseRue \\
|
\MonAdresseRue \\
|
||||||
\MonAdresseVille
|
\MonAdresseVille \\
|
||||||
|
\ifthenelse{\equal{\Devis}{oui}}{
|
||||||
|
Devis n°\FactureNum
|
||||||
|
}{
|
||||||
Facture n°\FactureNum
|
Facture n°\FactureNum
|
||||||
|
}
|
||||||
|
|
||||||
{\addtolength{\leftskip}{10.5cm} %in ERT
|
{\addtolength{\leftskip}{10.5cm} %in ERT
|
||||||
\ClientNom \\
|
\ClientNom \\
|
||||||
@ -139,6 +144,7 @@ Facture n°\FactureNum
|
|||||||
|
|
||||||
\textnormal{\FactureDescr}
|
\textnormal{\FactureDescr}
|
||||||
|
|
||||||
|
|
||||||
~\\
|
~\\
|
||||||
|
|
||||||
\begin{center}
|
\begin{center}
|
||||||
@ -154,6 +160,11 @@ Facture n°\FactureNum
|
|||||||
\ifthenelse{\equal{\FactureAcquittee}{oui}}{
|
\ifthenelse{\equal{\FactureAcquittee}{oui}}{
|
||||||
Facture acquittée.
|
Facture acquittée.
|
||||||
}{
|
}{
|
||||||
|
Echéance de paiement : \FacturePaymentDate
|
||||||
|
|
||||||
|
Conditions d'escompte : Aucune
|
||||||
|
|
||||||
|
Taux de pénalité en cas de non paiement ou retard de paiement : 0 \%
|
||||||
|
|
||||||
À régler par chèque ou par virement bancaire :
|
À régler par chèque ou par virement bancaire :
|
||||||
|
|
||||||
@ -176,5 +187,6 @@ Facture n°\FactureNum
|
|||||||
TVA non applicable, article 293 B du CGI.
|
TVA non applicable, article 293 B du CGI.
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
|
|
||||||
\end{document}
|
\end{document}
|
||||||
{% endlanguage %}
|
{% endlanguage %}
|
||||||
|
@ -69,9 +69,11 @@ class TestInvoices(TestCase):
|
|||||||
response = self.client.post(reverse("treasury:invoice_create"), data={
|
response = self.client.post(reverse("treasury:invoice_create"), data={
|
||||||
"id": 42,
|
"id": 42,
|
||||||
"object": "Same object",
|
"object": "Same object",
|
||||||
|
"quotation": True,
|
||||||
"description": "Longer description",
|
"description": "Longer description",
|
||||||
"name": "Me and others",
|
"name": "Me and others",
|
||||||
"address": "Alwways earth",
|
"address": "Alwways earth",
|
||||||
|
"payment_date": "Maybe someday...",
|
||||||
"acquitted": True,
|
"acquitted": True,
|
||||||
"products-0-designation": "Designation",
|
"products-0-designation": "Designation",
|
||||||
"products-0-quantity": 1,
|
"products-0-quantity": 1,
|
||||||
@ -97,8 +99,10 @@ class TestInvoices(TestCase):
|
|||||||
"object": "Same object",
|
"object": "Same object",
|
||||||
"description": "Longer description",
|
"description": "Longer description",
|
||||||
"name": "Me and others",
|
"name": "Me and others",
|
||||||
|
"quotation": False,
|
||||||
"address": "Always earth",
|
"address": "Always earth",
|
||||||
"acquitted": True,
|
"acquitted": True,
|
||||||
|
"payment_date": "Never",
|
||||||
"locked": True,
|
"locked": True,
|
||||||
"products-0-designation": "Designation",
|
"products-0-designation": "Designation",
|
||||||
"products-0-quantity": 1,
|
"products-0-quantity": 1,
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,8 @@ 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
|
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
|
# 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
|
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
|
# Envoyer les rapports aux gens
|
||||||
55 6 * * * root cd /var/www/note_kfet && env/bin/python manage.py send_reports -v 0
|
55 6 * * * root cd /var/www/note_kfet && env/bin/python manage.py send_reports -v 0
|
||||||
# Mettre à jour les boutons mis en avant
|
# Mettre à jour les boutons mis en avant
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"pk": 1,
|
"pk": 1,
|
||||||
"fields": {
|
"fields": {
|
||||||
"domain": "note.crans.org",
|
"domain": "note.crans.org",
|
||||||
"name": "La Note Kfet \ud83c\udf7b"
|
"name": "La Note Kfet 🍪"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -194,6 +194,8 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
|||||||
class="text-muted">{% trans "Contact us" %}</a> —
|
class="text-muted">{% trans "Contact us" %}</a> —
|
||||||
<a href="mailto:{{ "SUPPORT_EMAIL" | getenv }}"
|
<a href="mailto:{{ "SUPPORT_EMAIL" | getenv }}"
|
||||||
class="text-muted">{% trans "Technical Support" %}</a> —
|
class="text-muted">{% trans "Technical Support" %}</a> —
|
||||||
|
<a href="https://perso.crans.org/club-bde/charte_informatique.pdf"
|
||||||
|
class="text-muted">{% trans "Charte Info (FR)" %}</a> —
|
||||||
<a href="https://note.crans.org/doc/faq/"
|
<a href="https://note.crans.org/doc/faq/"
|
||||||
class="text-muted">{% trans "FAQ (FR)" %}</a> —
|
class="text-muted">{% trans "FAQ (FR)" %}</a> —
|
||||||
</span>
|
</span>
|
||||||
|
Reference in New Issue
Block a user