mirror of
https://gitlab.crans.org/bde/nk20
synced 2025-06-21 09:58:23 +02:00
Compare commits
1 Commits
export_mem
...
a79010f59b
Author | SHA1 | Date | |
---|---|---|---|
a79010f59b |
@ -294,10 +294,3 @@ searchbar.addEventListener("keyup", function (e) {
|
||||
if (firstMatch && e.key === "Enter")
|
||||
firstMatch.click()
|
||||
});
|
||||
|
||||
function createshiny() {
|
||||
const list_btn = document.querySelectorAll('.btn-outline-dark')
|
||||
const shiny_class = list_btn[Math.floor(Math.random() * list_btn.length)].classList
|
||||
shiny_class.replace('btn-outline-dark', 'btn-outline-dark-shiny')
|
||||
}
|
||||
createshiny()
|
||||
|
@ -324,7 +324,7 @@
|
||||
"mask": 2,
|
||||
"field": "",
|
||||
"permanent": false,
|
||||
"description": "Créer une transaction de ou vers la note d'un club tant que la source reste au dessus de -20 €"
|
||||
"description": "Créer une transaction de ou vers la note d'un club"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -3815,7 +3815,7 @@
|
||||
"mask": 2,
|
||||
"field": "",
|
||||
"permanent": false,
|
||||
"description": "Créer une transaction vers la note d'un club tant que la source reste au dessus de -20 €"
|
||||
"description": "Créer une transaction vers la note d'un club"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -4237,22 +4237,6 @@
|
||||
{
|
||||
"model": "permission.permission",
|
||||
"pk": 269,
|
||||
"fields": {
|
||||
"model": [
|
||||
"note",
|
||||
"transaction"
|
||||
],
|
||||
"query": "[\"OR\", {\"source_alias\": \"Carte bancaire\"}, {\"source_alias\": \"Espèces\"}, {\"source_alias\": \"Chèque\"}, {\"source_alias\": \"Virement bancaire\"}]",
|
||||
"type": "add",
|
||||
"mask": 2,
|
||||
"field": "",
|
||||
"permanent": false,
|
||||
"description": "Créer une transaction de rechargement"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "permission.permission",
|
||||
"pk": 270,
|
||||
"fields": {
|
||||
"model": [
|
||||
"note",
|
||||
|
@ -38,7 +38,7 @@ class Command(BaseCommand):
|
||||
required=False,
|
||||
help="""User will have their(s) wrapped generated,
|
||||
all = all users
|
||||
adh = all users who have a valid cd memberships to BDE during the BDE considered
|
||||
adh = all users who have a valid memberships to BDE during the BDE considered
|
||||
supersuser = all superusers
|
||||
custom user1,user2,... = a list of username,
|
||||
custom_id id1,id2,... = a list of user id""",
|
||||
@ -70,7 +70,15 @@ class Command(BaseCommand):
|
||||
dest='create',
|
||||
)
|
||||
|
||||
def handle(self, *args, **options): # NOQA
|
||||
def handle(self, *args, **options):
|
||||
# useful string for output
|
||||
red = '\033[31;1m'
|
||||
yellow = '\033[33;1m'
|
||||
green = '\033[32;1m'
|
||||
abort = red + 'ABORT'
|
||||
warning = yellow + 'WARNING'
|
||||
success = green + 'SUCCESS'
|
||||
|
||||
# Traitement des paramètres
|
||||
verb = options['verbosity']
|
||||
bde = []
|
||||
@ -81,11 +89,11 @@ class Command(BaseCommand):
|
||||
if options['bde_id']:
|
||||
if bde:
|
||||
if verb >= 1:
|
||||
self.stdout.write(self.style.WARNING(
|
||||
"WARNING\nYou already defined bde with their name !"))
|
||||
print(warning)
|
||||
print(yellow + 'You already defined bde with their name !')
|
||||
if verb >= 0:
|
||||
self.stdout.write(self.style.ERROR("ABORT"))
|
||||
exit(1)
|
||||
print(abort)
|
||||
return
|
||||
bde_id = options['bde_id'].split(',')
|
||||
bde = [Bde.objects.get(pk=i) for i in bde_id]
|
||||
|
||||
@ -105,11 +113,11 @@ class Command(BaseCommand):
|
||||
user = ['custom_id', [User.objects.get(pk=u) for u in user_id]]
|
||||
else:
|
||||
if verb >= 1:
|
||||
self.sdtout.write(self.style.WARNING(
|
||||
"WARNING\nYou user option is not recognized"))
|
||||
print(warning)
|
||||
print(yellow + 'You user option is not recognized')
|
||||
if verb >= 0:
|
||||
self.stdout.write(self.style.ERROR("ABORT"))
|
||||
exit(1)
|
||||
print(abort)
|
||||
return
|
||||
|
||||
club = []
|
||||
if options['club']:
|
||||
@ -125,11 +133,11 @@ class Command(BaseCommand):
|
||||
club = ['custom_id', [Club.objects.get(pk=c) for c in club_id]]
|
||||
else:
|
||||
if verb >= 1:
|
||||
self.stdout.write(self.style.WARNING(
|
||||
"WARNING\nYou club option is not recognized"))
|
||||
print(warning)
|
||||
print(yellow + 'You club option is not recognized')
|
||||
if verb >= 0:
|
||||
self.stdout.write(self.style.ERROR("ABORT"))
|
||||
exit(1)
|
||||
print(abort)
|
||||
return
|
||||
|
||||
change = options['change']
|
||||
create = options['create']
|
||||
@ -137,75 +145,72 @@ class Command(BaseCommand):
|
||||
# check if parameters are sufficient for generate wrapped with the desired option
|
||||
if not bde:
|
||||
if verb >= 1:
|
||||
self.stdout.write(self.style.WARNING(
|
||||
"WARNING\nYou have not selectionned a BDE !"))
|
||||
print(warning)
|
||||
print(yellow + 'You have not selectionned a BDE !')
|
||||
if verb >= 0:
|
||||
self.stdout.write(self.style.ERROR("ABORT"))
|
||||
exit(1)
|
||||
print(abort)
|
||||
return
|
||||
if not (user or club):
|
||||
if verb >= 1:
|
||||
self.stdout.write(self.style.WARNING(
|
||||
"WARNING\nNo club or user selected !"))
|
||||
print(warning)
|
||||
print(yellow + 'No club or user selected !')
|
||||
if verb >= 0:
|
||||
self.stdout.write(self.style.ERROR("ABORT"))
|
||||
exit(1)
|
||||
print(abort)
|
||||
return
|
||||
|
||||
if verb >= 3:
|
||||
self.stdout.write("Options:")
|
||||
print('\033[1mOptions:\033[m')
|
||||
bde_str = ''
|
||||
for b in bde:
|
||||
bde_str += str(b) + '\n'
|
||||
self.stdout.write("BDE: " + bde_str)
|
||||
bde_str += str(b)
|
||||
print('BDE: ' + bde_str)
|
||||
if user:
|
||||
self.stdout.write('User: ' + user[0])
|
||||
print('User: ' + user[0])
|
||||
if club:
|
||||
self.stdout.write('Club: ' + club[0])
|
||||
self.stdout.write('change: ' + str(change))
|
||||
self.stdout.write('create: ' + str(create) + '\n')
|
||||
print('Club: ' + club[0])
|
||||
print('change: ' + str(change))
|
||||
print('create: ' + str(create))
|
||||
print('')
|
||||
if not (change or create):
|
||||
if verb >= 1:
|
||||
self.stdout.write(self.style.WARNING(
|
||||
"WARNING\nchange and create is set to false, none wrapped will be created"))
|
||||
print(warning)
|
||||
print(yellow + 'change and create is set to false, none wrapped will be created')
|
||||
if verb >= 0:
|
||||
self.stdout.write(self.style.ERROR("ABORT"))
|
||||
exit(1)
|
||||
print(abort)
|
||||
return
|
||||
if verb >= 1 and change:
|
||||
self.stdout.write(self.style.WARNING(
|
||||
"WARNING\nchange is set to true, some wrapped may be replaced !"))
|
||||
print(warning)
|
||||
print(yellow + 'change is set to true, some wrapped may be replaced !')
|
||||
if verb >= 1 and not create:
|
||||
self.stdout.write(self.style.WARNING(
|
||||
"WARNING\ncreate is set to false, wrapped will not be created !"))
|
||||
print(warning)
|
||||
print(yellow + 'create is set to false, wrapped will not be created !')
|
||||
if verb >= 3 or change or not create:
|
||||
a = str(input('\033[mContinue ? (y/n) ')).lower()
|
||||
if a in ['n', 'no', 'non', '0']:
|
||||
if verb >= 0:
|
||||
self.stdout.write(self.style.ERROR("ABORT"))
|
||||
exit(1)
|
||||
print(abort)
|
||||
return
|
||||
|
||||
note = self.convert_to_note(change, create, bde=bde, user=user, club=club, verb=verb)
|
||||
if verb >= 1:
|
||||
self.stdout.write(self.style.SUCCESS(
|
||||
"User and/or Club given has successfully convert in their note"))
|
||||
|
||||
print("\033[32mUser and/or Club given has successfully convert in their note\033[m")
|
||||
global_data = self.global_data(bde, verb=verb)
|
||||
if verb >= 1:
|
||||
self.stdout.write(self.style.SUCCESS(
|
||||
"Global data has been successfully generated"))
|
||||
print("\033[32mGlobal data has been successfully generated\033[m")
|
||||
|
||||
unique_data = self.unique_data(bde, note, global_data=global_data, verb=verb)
|
||||
if verb >= 1:
|
||||
self.stdout.write(self.style.SUCCESS(
|
||||
"Unique data has been successfully generated"))
|
||||
print("\033[32mUnique data has been successfully generated\033[m")
|
||||
|
||||
self.make_wrapped(unique_data, note, bde, change, create, verb=verb)
|
||||
if verb >= 1:
|
||||
self.stdout.write(self.style.SUCCESS(
|
||||
"The wrapped has been generated !"))
|
||||
print(green + "The wrapped has been generated !")
|
||||
if verb >= 0:
|
||||
self.stdout.write(self.style.SUCCESS("SUCCESS"))
|
||||
exit(0)
|
||||
print(success)
|
||||
|
||||
def convert_to_note(self, change, create, bde=None, user=None, club=None, verb=1): # NOQA
|
||||
return
|
||||
|
||||
def convert_to_note(self, change, create, bde=None, user=None, club=None, verb=1):
|
||||
notes = []
|
||||
for b in bde:
|
||||
note_for_bde = Note.objects.filter(pk__lte=-1)
|
||||
@ -248,17 +253,17 @@ class Command(BaseCommand):
|
||||
note_for_bde = self.filter_note(b, note_for_bde, change, create, verb=verb)
|
||||
notes.append(note_for_bde)
|
||||
if verb >= 2:
|
||||
self.stdout.write(f"{len(note_for_bde)} note selectionned for bde {b.name}")
|
||||
print("\033[m{nb} note selectionned for bde {bde}".format(nb=len(note_for_bde), bde=b.name))
|
||||
return notes
|
||||
|
||||
def global_data(self, bde, verb=1): # NOQA
|
||||
def global_data(self, bde, verb=1):
|
||||
data = {}
|
||||
for b in bde:
|
||||
if b.name == 'Rave Part[list]':
|
||||
if verb >= 2:
|
||||
self.stdout.write("Begin to make global data")
|
||||
print("Begin to make global data")
|
||||
if verb >= 3:
|
||||
self.stdout.write("nb_transaction")
|
||||
print('nb_transaction')
|
||||
# nb total de transactions
|
||||
data['nb_transaction'] = Transaction.objects.filter(
|
||||
created_at__gte=b.date_start,
|
||||
@ -266,7 +271,7 @@ class Command(BaseCommand):
|
||||
valid=True).count()
|
||||
|
||||
if verb >= 3:
|
||||
self.stdout.write("nb_vieux_con")
|
||||
print('nb_vieux_con')
|
||||
# nb total de vielleux con·ne·s derrière le bar
|
||||
button_id = [2884, 2585]
|
||||
transactions = Transaction.objects.filter(
|
||||
@ -281,7 +286,7 @@ class Command(BaseCommand):
|
||||
data['nb_vieux_con'] = q
|
||||
|
||||
if verb >= 3:
|
||||
self.stdout.write("nb_soiree")
|
||||
print('nb_soiree')
|
||||
# nb total de soirée
|
||||
a_type_id = [1, 2, 4, 5, 7, 10]
|
||||
data['nb_soiree'] = Activity.objects.filter(
|
||||
@ -291,7 +296,7 @@ class Command(BaseCommand):
|
||||
activity_type__pk__in=a_type_id).count()
|
||||
|
||||
if verb >= 3:
|
||||
self.stdout.write('pots, nb_entree_pot')
|
||||
print('pots, nb_entree_pot')
|
||||
# nb d'entrée totale aux pots
|
||||
pot_id = [1, 4, 10]
|
||||
pots = Activity.objects.filter(
|
||||
@ -305,7 +310,7 @@ class Command(BaseCommand):
|
||||
data['nb_entree_pot'] += Entry.objects.filter(activity=pot).count()
|
||||
|
||||
if verb >= 3:
|
||||
self.stdout.write('top3_buttons')
|
||||
print('top3_buttons')
|
||||
# top 3 des boutons les plus cliqués
|
||||
transactions = Transaction.objects.filter(
|
||||
created_at__gte=b.date_start,
|
||||
@ -324,7 +329,7 @@ class Command(BaseCommand):
|
||||
data['top3_buttons'] = list(sorted(d.items(), key=lambda item: item[1], reverse=True))[:3]
|
||||
|
||||
if verb >= 3:
|
||||
self.stdout.write('class_conso_all')
|
||||
print('class_conso_all')
|
||||
# le classement des plus gros consommateurs (BDE + club)
|
||||
transactions = Transaction.objects.filter(
|
||||
created_at__gte=b.date_start,
|
||||
@ -343,7 +348,7 @@ class Command(BaseCommand):
|
||||
data['class_conso_all'] = dict(sorted(d.items(), key=lambda item: item[1], reverse=True))
|
||||
|
||||
if verb >= 3:
|
||||
self.stdout.write('class_conso_bde')
|
||||
print('class_conso_bde')
|
||||
# le classement des plus gros consommateurs BDE
|
||||
transactions = Transaction.objects.filter(
|
||||
created_at__gte=b.date_start,
|
||||
@ -363,10 +368,11 @@ class Command(BaseCommand):
|
||||
|
||||
else:
|
||||
# make your wrapped or reuse previous wrapped
|
||||
raise NotImplementedError(f"The BDE: {b.name} has not personalized wrapped, make it !")
|
||||
raise NotImplementedError("The BDE: {bde_name} has not personalized wrapped, make it !"
|
||||
.format(bde_name=b.name))
|
||||
return data
|
||||
|
||||
def unique_data(self, bde, note, global_data=None, verb=1): # NOQA
|
||||
def unique_data(self, bde, note, global_data=None, verb=1):
|
||||
data = []
|
||||
for i in range(len(bde)):
|
||||
data_bde = []
|
||||
@ -374,7 +380,8 @@ class Command(BaseCommand):
|
||||
if verb >= 3:
|
||||
total = len(note[i])
|
||||
current = 0
|
||||
self.stdout.write(f"Make {total} data for wrapped sponsored by {bde[i].name}")
|
||||
print('Make {nb} data for wrapped sponsored by {bde}'
|
||||
.format(nb=total, bde=bde[i].name))
|
||||
for n in note[i]:
|
||||
d = {}
|
||||
if 'user' in n.__dir__():
|
||||
@ -535,11 +542,12 @@ class Command(BaseCommand):
|
||||
data_bde.append(json.dumps(d))
|
||||
if verb >= 3:
|
||||
current += 1
|
||||
self.stdout.write("\033[2K" + f"({current}/{total})" + "\033[1A")
|
||||
print('\033[2K' + '({c}/{t})'.format(c=current, t=total) + '\033[1A')
|
||||
|
||||
else:
|
||||
# make your wrapped or reuse previous wrapped
|
||||
raise NotImplementedError(f"The BDE: {bde[i].name} has not personalized wrapped, make it !")
|
||||
raise NotImplementedError("The BDE: {bde_name} has not personalized wrapped, make it !"
|
||||
.format(bde_name=bde[i].name))
|
||||
data.append(data_bde)
|
||||
return data
|
||||
|
||||
@ -549,7 +557,7 @@ class Command(BaseCommand):
|
||||
total = 0
|
||||
for n in note:
|
||||
total += len(n)
|
||||
self.stdout.write(f"Make {total} wrapped")
|
||||
print('\033[mMake {nb} wrapped'.format(nb=total))
|
||||
for i in range(len(bde)):
|
||||
for j in range(len(note[i])):
|
||||
if create and not Wrapped.objects.filter(bde=bde[i], note=note[i][j]):
|
||||
@ -564,7 +572,7 @@ class Command(BaseCommand):
|
||||
w.save()
|
||||
if verb >= 3:
|
||||
current += 1
|
||||
self.stdout.write("\033[2K" + f"({current}/{total})" + "\033[1A")
|
||||
print('\033[2K' + '({c}/{t})'.format(c=current, t=total) + '\033[1A')
|
||||
return
|
||||
|
||||
def filter_note(self, bde, note, change, create, verb=1):
|
||||
|
@ -23,9 +23,9 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
let d1 = document.getElementById("consumer");
|
||||
let d2 = document.getElementById("creditor");
|
||||
if (con) { d1.textContent = {{ big_consumer | safe }}[0] + " " + gettext("with") + " " + {{ big_consumer | safe}}[1] + "€";}
|
||||
else { d1.textContent = gettext("{% trans "Infortunately, you doesn't have consumer this year" %}");};
|
||||
else { d1.textContent = gettext("Infortunately, you doesn't have consumer this year");};
|
||||
if (cre) { d2.textContent = {{ big_creancier | safe}}[0] + " " + gettext("with") + " " + {{ big_creancier | safe}}[1] + "€";}
|
||||
else { d2.textContent = gettext("{% trans "Congratulations you are a real rat !" %}"); };
|
||||
else { d2.textContent = gettext("Congratulations you are a real rat !"); };
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
@ -6,24 +6,17 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<div id="wrapped_tables">
|
||||
{% if tables|length > 0 %}
|
||||
<div class="card bg-light mb-3">
|
||||
<h3 class="card-header text-center">
|
||||
{% trans "My wrapped" %}
|
||||
</h3>
|
||||
{% render_table tables.1 %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if tables|length > 0 %}
|
||||
<div class="card bg-light mb-3">
|
||||
<h3 class="card-header text-center">
|
||||
{% trans "Public wrapped" %}
|
||||
</h3>
|
||||
{% render_table tables.0 %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-10">
|
||||
<div class="card card-border shadow">
|
||||
<div class="card-header text-center">
|
||||
<h5> {{ title }}</h5>
|
||||
</div>
|
||||
<div class="card-body px-0 py-0" id="wrapped_table">
|
||||
{% render_table table %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@ -32,7 +25,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
let club_not_public = {{ club_not_public }};
|
||||
if (club_not_public) { (addMsg("{% trans "Do not forget to ask permission to people who are in your wrapped before to make them public" %}", 'warning'));}
|
||||
function refreshTable() {
|
||||
$("#wrapped_tables").load(location.pathname + " #wrapped_tables");
|
||||
$("#wrapped_table").load(location.pathname + " #wrapped_table");
|
||||
}
|
||||
|
||||
function copylink(id) {
|
||||
|
@ -1,91 +0,0 @@
|
||||
# Copyright (C) 2018-2025 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
from api.tests import TestAPI
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
|
||||
from ..api.views import WrappedViewSet, BdeViewSet
|
||||
from ..models import Bde, Wrapped
|
||||
|
||||
|
||||
class TestWrapped(TestCase):
|
||||
"""
|
||||
Test activities
|
||||
"""
|
||||
fixtures = ('initial',)
|
||||
|
||||
def setUp(self):
|
||||
self.user = User.objects.create_superuser(
|
||||
username="admintoto",
|
||||
password="tototototo",
|
||||
email="toto@example.com"
|
||||
)
|
||||
self.client.force_login(self.user)
|
||||
|
||||
sess = self.client.session
|
||||
sess["permission_mask"] = 42
|
||||
sess.save()
|
||||
|
||||
self.bde = Bde.objects.create(
|
||||
name="The best BDE",
|
||||
date_start=timezone.now() - timedelta(days=365),
|
||||
date_end=timezone.now(),
|
||||
)
|
||||
|
||||
self.wrapped = Wrapped.objects.create(
|
||||
generated=True,
|
||||
public=False,
|
||||
bde=self.bde,
|
||||
note=self.user.note,
|
||||
data_json="{}",
|
||||
)
|
||||
|
||||
def test_wrapped_list(self):
|
||||
"""
|
||||
Display the list of all wrapped
|
||||
"""
|
||||
response = self.client.get(reverse("wrapped:wrapped_list"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_wrapped_detail(self):
|
||||
"""
|
||||
Display the detail of an wrapped
|
||||
"""
|
||||
response = self.client.get(reverse("wrapped:wrapped_detail", args=(self.wrapped.pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
||||
class TestWrappedAPI(TestAPI):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.bde = Bde.objects.create(
|
||||
name="The best BDE",
|
||||
date_start=timezone.now() - timedelta(days=365),
|
||||
date_end=timezone.now(),
|
||||
)
|
||||
|
||||
self.wrapped = Wrapped.objects.create(
|
||||
generated=True,
|
||||
public=False,
|
||||
bde=self.bde,
|
||||
note=self.user.note,
|
||||
data_json="{}",
|
||||
)
|
||||
|
||||
def test_bde_api(self):
|
||||
"""
|
||||
Load Bde API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(BdeViewSet, "/api/wrapped/bde/")
|
||||
|
||||
def test_wrapped_api(self):
|
||||
"""
|
||||
Load Wrapped API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(WrappedViewSet, "/api/wrapped/wrapped/")
|
@ -6,8 +6,7 @@ import json
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import DetailView
|
||||
from django.views.generic.list import ListView
|
||||
from django_tables2.views import MultiTableMixin
|
||||
from django_tables2.views import SingleTableView
|
||||
from permission.backends import PermissionBackend
|
||||
from permission.views import ProtectQuerysetMixin
|
||||
|
||||
@ -15,29 +14,21 @@ from .models import Wrapped
|
||||
from .tables import WrappedTable
|
||||
|
||||
|
||||
class WrappedListView(ProtectQuerysetMixin, LoginRequiredMixin, MultiTableMixin, ListView):
|
||||
class WrappedListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
|
||||
"""
|
||||
Display all Wrapped, and classify by year
|
||||
"""
|
||||
model = Wrapped
|
||||
tables = [
|
||||
lambda data: WrappedTable(data, prefix="public-"),
|
||||
lambda data: WrappedTable(data, prefix="personnal-"),
|
||||
]
|
||||
table_class = WrappedTable
|
||||
template_name = 'wrapped/wrapped_list.html'
|
||||
extra_context = {'title': _("List of wrapped")}
|
||||
|
||||
def get_queryset(self, **kwargs):
|
||||
return super().get_queryset(**kwargs).distinct()
|
||||
|
||||
def get_tables_data(self):
|
||||
return [
|
||||
Wrapped.objects.filter(public=True),
|
||||
Wrapped.objects
|
||||
.filter(PermissionBackend.filter_queryset(self.request, Wrapped, "change", field='public'))
|
||||
.distinct()
|
||||
.order_by("-bde__date_start")
|
||||
]
|
||||
def get_table_data(self):
|
||||
return Wrapped.objects.filter(PermissionBackend.filter_queryset(
|
||||
self.request, Wrapped, "change", field='public')).distinct().order_by("-bde__date_start")
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
118
docs/_static/img/graphs/wrapped.svg
vendored
118
docs/_static/img/graphs/wrapped.svg
vendored
@ -1,118 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.43.0 (0)
|
||||
-->
|
||||
<!-- Title: model_graph Pages: 1 -->
|
||||
<svg width="319pt" height="245pt"
|
||||
viewBox="0.00 0.00 319.00 245.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 241)">
|
||||
<title>model_graph</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-241 315,-241 315,4 -4,4"/>
|
||||
<!-- wrapped_models_Bde -->
|
||||
<g id="node1" class="node">
|
||||
<title>wrapped_models_Bde</title>
|
||||
<polygon fill="white" stroke="transparent" points="8,-4 8,-79 158,-79 158,-4 8,-4"/>
|
||||
<polygon fill="#1b563f" stroke="transparent" points="9,-56.5 9,-77.5 157,-77.5 157,-56.5 9,-56.5"/>
|
||||
<text text-anchor="start" x="52" y="-65.5" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="62" y="-65.5" font-family="Roboto" font-weight="bold" font-size="10.00" fill="white">    Bde    </text>
|
||||
<text text-anchor="start" x="11" y="-49.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="21" y="-49.1" font-family="Roboto" font-weight="bold" font-size="8.00">id</text>
|
||||
<text text-anchor="start" x="31" y="-49.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="77" y="-49.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="87" y="-49.1" font-family="Roboto" font-weight="bold" font-size="8.00">AutoField</text>
|
||||
<text text-anchor="start" x="131" y="-49.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="11" y="-36.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="21" y="-36.1" font-family="Roboto" font-size="8.00">date_end</text>
|
||||
<text text-anchor="start" x="60" y="-36.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="77" y="-36.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="87" y="-36.1" font-family="Roboto" font-size="8.00">DateTimeField</text>
|
||||
<text text-anchor="start" x="145" y="-36.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="11" y="-23.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="21" y="-23.1" font-family="Roboto" font-size="8.00">date_start</text>
|
||||
<text text-anchor="start" x="63" y="-23.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="77" y="-23.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="87" y="-23.1" font-family="Roboto" font-size="8.00">DateTimeField</text>
|
||||
<text text-anchor="start" x="145" y="-23.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="11" y="-10.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="21" y="-10.1" font-family="Roboto" font-size="8.00">name</text>
|
||||
<text text-anchor="start" x="45" y="-10.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="77" y="-10.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="87" y="-10.1" font-family="Roboto" font-size="8.00">CharField</text>
|
||||
<text text-anchor="start" x="125" y="-10.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<polygon fill="none" stroke="black" points="8,-4 8,-79 158,-79 158,-4 8,-4"/>
|
||||
</g>
|
||||
<!-- wrapped_models_Wrapped -->
|
||||
<g id="node2" class="node">
|
||||
<title>wrapped_models_Wrapped</title>
|
||||
<polygon fill="white" stroke="transparent" points="67,-132 67,-233 231,-233 231,-132 67,-132"/>
|
||||
<polygon fill="#1b563f" stroke="transparent" points="68,-210.5 68,-231.5 230,-231.5 230,-210.5 68,-210.5"/>
|
||||
<text text-anchor="start" x="103" y="-219.5" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="113" y="-219.5" font-family="Roboto" font-weight="bold" font-size="10.00" fill="white">    Wrapped    </text>
|
||||
<text text-anchor="start" x="70" y="-203.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="80" y="-203.1" font-family="Roboto" font-weight="bold" font-size="8.00">id</text>
|
||||
<text text-anchor="start" x="90" y="-203.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="137" y="-203.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="147" y="-203.1" font-family="Roboto" font-weight="bold" font-size="8.00">AutoField</text>
|
||||
<text text-anchor="start" x="191" y="-203.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="70" y="-190.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="80" y="-190.1" font-family="Roboto" font-weight="bold" font-size="8.00">bde</text>
|
||||
<text text-anchor="start" x="98" y="-190.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="137" y="-190.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="147" y="-190.1" font-family="Roboto" font-weight="bold" font-size="8.00">ForeignKey (id)</text>
|
||||
<text text-anchor="start" x="218" y="-190.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="70" y="-177.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="80" y="-177.1" font-family="Roboto" font-weight="bold" font-size="8.00">note</text>
|
||||
<text text-anchor="start" x="101" y="-177.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="137" y="-177.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="147" y="-177.1" font-family="Roboto" font-weight="bold" font-size="8.00">ForeignKey (id)</text>
|
||||
<text text-anchor="start" x="218" y="-177.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="70" y="-164.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="80" y="-164.1" font-family="Roboto" font-size="8.00">data_json</text>
|
||||
<text text-anchor="start" x="120" y="-164.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="137" y="-164.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="147" y="-164.1" font-family="Roboto" font-size="8.00">TextField</text>
|
||||
<text text-anchor="start" x="182" y="-164.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="70" y="-151.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="80" y="-151.1" font-family="Roboto" font-size="8.00">generated</text>
|
||||
<text text-anchor="start" x="123" y="-151.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="137" y="-151.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="147" y="-151.1" font-family="Roboto" font-size="8.00">BooleanField</text>
|
||||
<text text-anchor="start" x="200" y="-151.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="70" y="-138.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="80" y="-138.1" font-family="Roboto" font-size="8.00">public</text>
|
||||
<text text-anchor="start" x="105" y="-138.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="137" y="-138.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<text text-anchor="start" x="147" y="-138.1" font-family="Roboto" font-size="8.00">BooleanField</text>
|
||||
<text text-anchor="start" x="200" y="-138.1" font-family="Roboto" font-size="8.00">    </text>
|
||||
<polygon fill="none" stroke="black" points="67,-132 67,-233 231,-233 231,-132 67,-132"/>
|
||||
</g>
|
||||
<!-- wrapped_models_Wrapped->wrapped_models_Bde -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>wrapped_models_Wrapped->wrapped_models_Bde</title>
|
||||
<path fill="none" stroke="black" d="M119.99,-120.4C114,-107.79 107.84,-94.82 102.31,-83.16"/>
|
||||
<ellipse fill="black" stroke="black" cx="121.77" cy="-124.15" rx="4" ry="4"/>
|
||||
<text text-anchor="middle" x="132" y="-103.6" font-family="Roboto" font-size="8.00"> bde (+)</text>
|
||||
</g>
|
||||
<!-- note_models_notes_Note -->
|
||||
<g id="node3" class="node">
|
||||
<title>note_models_notes_Note</title>
|
||||
<polygon fill="white" stroke="transparent" points="192,-31 192,-52 240,-52 240,-31 192,-31"/>
|
||||
<polygon fill="#1b563f" stroke="transparent" points="192,-30.5 192,-51.5 240,-51.5 240,-30.5 192,-30.5"/>
|
||||
<text text-anchor="start" x="196.5" y="-38.9" font-family="Roboto" font-size="8.00">  </text>
|
||||
<text text-anchor="start" x="201.5" y="-38.9" font-family="Roboto" font-size="12.00" fill="white">Note</text>
|
||||
<text text-anchor="start" x="230.5" y="-38.9" font-family="Roboto" font-size="8.00">  </text>
|
||||
</g>
|
||||
<!-- wrapped_models_Wrapped->note_models_notes_Note -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>wrapped_models_Wrapped->note_models_notes_Note</title>
|
||||
<path fill="none" stroke="black" d="M178.48,-120.33C189.12,-98.27 200.3,-75.07 207.66,-59.8"/>
|
||||
<ellipse fill="black" stroke="black" cx="176.64" cy="-124.16" rx="4" ry="4"/>
|
||||
<text text-anchor="middle" x="204.5" y="-103.6" font-family="Roboto" font-size="8.00"> note (+)</text>
|
||||
</g>
|
||||
<!-- \n\n\n -->
|
||||
<g id="node4" class="node">
|
||||
<title>\n\n\n</title>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 9.7 KiB |
@ -14,7 +14,6 @@ Applications de la Note Kfet 2020
|
||||
logs
|
||||
treasury
|
||||
wei
|
||||
wrapped
|
||||
|
||||
La Note Kfet 2020 est un projet Django, décomposé en applications.
|
||||
Certaines applications sont développées uniquement pour ce projet, et sont indispensables,
|
||||
@ -70,6 +69,4 @@ Applications facultatives
|
||||
Interface de gestion pour les trésorièr⋅es, émission de factures, remises de chèque, statistiques...
|
||||
* `WEI <wei>`_ :
|
||||
Interface de gestion du WEI.
|
||||
* `Wrapped <wrapped>`_ :
|
||||
Récapitulatif personnalisé annuel de statitiques globales et personnelles.
|
||||
|
||||
|
@ -1,108 +0,0 @@
|
||||
Wrapped
|
||||
=======
|
||||
|
||||
Cette application montre les statistiques annuelles des utilisateur·ice·s et/ou des clubs.
|
||||
|
||||
Modèles
|
||||
-------
|
||||
|
||||
Bde
|
||||
~~~
|
||||
|
||||
Le modèle ``Bde`` contient des informations relatifs à un BDE :
|
||||
|
||||
* ``name`` : ``CharField``, nom du BDE.
|
||||
* ``date_start`` : ``DateField``, date de prise de fonction du bureau BDE considéré.
|
||||
* ``date_end`` : ``DateField``, date de démission du bureau BDE considéré.
|
||||
|
||||
Wrapped
|
||||
~~~~~~~
|
||||
|
||||
Contient les informations sur un wrapped :
|
||||
|
||||
* ``generated`` : ``BooleanField``, indique si le wrapped a été généré ou non.
|
||||
* ``public`` : ``BooleanField``, indique si le wrapped est visible de tous les utilisateur·ice·s ou non.
|
||||
* ``bde`` : ``ForeignKey(Bde)``, BDE auquel le wrapped correspond.
|
||||
* ``note`` : ``ForeignKey(Note)``, note à laquelle le wrapped correspond.
|
||||
* ``data_json`` : ``TextField``, diverses statistique concernant les notes durant le mandat BDE
|
||||
considéré ou sur la NoteKfet dans sa globalité.
|
||||
|
||||
Graphe des modèles
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. image:: ../_static/img/graphs/wrapped.svg
|
||||
:width: 960
|
||||
:alt: Graphe des modèles de l'application Wrapped
|
||||
|
||||
Fonctionnement
|
||||
--------------
|
||||
|
||||
Création d'un BDE
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Seul un⋅e respo info peut créer un BDE. Pour cela, se rendre dans l'onglet « Admin »., puis « BDE » et
|
||||
enfin « + Ajouter BDE ». Iel doit renseigner, les dates de début et de fin du bureau BDE ainsi que le
|
||||
nom de la liste.
|
||||
|
||||
Génération des wrappeds
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Seul un·e respo info peut générer des wrappeds. Pour une utilisation annuelle classique, iel exécute la
|
||||
commande :
|
||||
|
||||
``./manage.py generate_wrapped -b "bde_name" -u adh -c active``
|
||||
|
||||
Pour une utilisation plus technique de cette commande se référer à sa documentation
|
||||
|
||||
``./manage.py help generate_wrapped``
|
||||
|
||||
Le script prend une dizaine de minutes pour générer tous les wrappeds.
|
||||
|
||||
Créer ses propres wrappeds
|
||||
--------------------------
|
||||
|
||||
Cette section est plus technique et s'addresse plutôt à des respos infos en cours de mandat qui voudrai
|
||||
faire les wrappeds de leur propre BDE.
|
||||
|
||||
Contenu
|
||||
~~~~~~~
|
||||
|
||||
Il est fortement conseillé de bien réfléchir à ce que l'on souhaite mettre sur un wrapped, plusieurs
|
||||
critères sont à prendre compte :
|
||||
|
||||
* compréhension, est-ce que la donnée fait sens auprès des utilisateur·ice·s.
|
||||
* pertinence, est-ce que la donnée fonctionne pour un grand nombre d'utilisateur.
|
||||
* faisabilité, est-ce que le temps de calcul est suffisament rapide.
|
||||
* complexité, est-ce que c'est trop compliqué à coder.
|
||||
|
||||
Script
|
||||
~~~~~~
|
||||
|
||||
Le script *generate_wrapped* fonctionne de la manière suivante :
|
||||
|
||||
* ``convert_to_note`` : en fonction des arguments d'entrée, il récupére toutes les notes dont le·s
|
||||
wrapped·s va/vont être généré·s
|
||||
ou regénéré·s.
|
||||
* ``global_data`` : le script génére ensuite des statistiques globales qui concernent pas qu'une seule
|
||||
note (nombre de soirée, classement, etc).
|
||||
* ``unique_data`` : le script génére les statitiques uniques à chaque note, et rajoute des données
|
||||
globales si nécessaire, pour chaque note on souhaite avoir un json avec toutes les données qui
|
||||
seront dans le wrapped.
|
||||
* ``make_wrapped`` : enfin, le cas échéant, pour chaque bde, et pour chaque note, le wrapped est crée
|
||||
ou modifié, et enregistré, s'il est crée il est par défault non public.
|
||||
|
||||
Seules les fonctions ``global_data`` et ``unique_data`` sont à modifier, pour implementer un nouveau
|
||||
BDE.
|
||||
|
||||
Template
|
||||
~~~~~~~~
|
||||
|
||||
Il y a au moins deux templates a écrire pour chaque bde :
|
||||
|
||||
* ``templates/wrapped/{bde_id}/wrapped_view_club.html``: le template pour les wrappeds des clubs
|
||||
* ``templates/wrapped/{bde_id}/wrapped_view_user.html``: le template pour les wrappeds des
|
||||
utilisateur·ice·s
|
||||
|
||||
Il est conseillé de suivre la même arborescence pour les fichiers statics (fonts personnalisées,
|
||||
images, css, etc). De même, il est conseillé de créé un fichier
|
||||
``templates/wrapped/{bde_id}/wrapped_base.html`` et d'étendre cette template.
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-03-13 21:08+0100\n"
|
||||
"POT-Creation-Date: 2025-02-25 13:47+0100\n"
|
||||
"PO-Revision-Date: 2022-04-11 22:05+0200\n"
|
||||
"Last-Translator: bleizi <bleizi@crans.org>\n"
|
||||
"Language-Team: French <http://translate.ynerant.fr/projects/nk20/nk20/fr/>\n"
|
||||
@ -865,7 +865,7 @@ msgstr "Taille maximale : 2 Mo"
|
||||
msgid "This image cannot be loaded."
|
||||
msgstr "Cette image ne peut pas être chargée."
|
||||
|
||||
#: apps/member/forms.py:154 apps/member/views.py:117
|
||||
#: apps/member/forms.py:154 apps/member/views.py:103
|
||||
#: apps/registration/forms.py:33 apps/registration/views.py:282
|
||||
msgid "An alias with a similar name already exists."
|
||||
msgstr "Un alias avec un nom similaire existe déjà."
|
||||
@ -1194,11 +1194,11 @@ msgstr "Adhésion de {user} pour le club {club}"
|
||||
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:388 apps/member/views.py:759
|
||||
#: apps/member/models.py:388 apps/member/views.py:745
|
||||
msgid "User is already a member of the club"
|
||||
msgstr "L'utilisateur·rice est déjà membre du club"
|
||||
|
||||
#: apps/member/models.py:400 apps/member/views.py:768
|
||||
#: apps/member/models.py:400 apps/member/views.py:754
|
||||
msgid "User is not a member of the parent club"
|
||||
msgstr "L'utilisateur·rice n'est pas membre du club parent"
|
||||
|
||||
@ -1251,7 +1251,7 @@ msgid "Account #"
|
||||
msgstr "Compte n°"
|
||||
|
||||
#: apps/member/templates/member/base.html:48
|
||||
#: apps/member/templates/member/base.html:62 apps/member/views.py:61
|
||||
#: apps/member/templates/member/base.html:62 apps/member/views.py:60
|
||||
#: apps/registration/templates/registration/future_profile_detail.html:48
|
||||
#: apps/wei/templates/wei/weimembership_form.html:117
|
||||
msgid "Update Profile"
|
||||
@ -1312,8 +1312,8 @@ msgstr ""
|
||||
"seront à nouveau possible."
|
||||
|
||||
#: apps/member/templates/member/club_alias.html:10
|
||||
#: apps/member/templates/member/profile_alias.html:10 apps/member/views.py:318
|
||||
#: apps/member/views.py:559
|
||||
#: apps/member/templates/member/profile_alias.html:10 apps/member/views.py:304
|
||||
#: apps/member/views.py:545
|
||||
msgid "Note aliases"
|
||||
msgstr "Alias de la note"
|
||||
|
||||
@ -1505,51 +1505,51 @@ msgstr "Sauvegarder les changements"
|
||||
msgid "Registrations"
|
||||
msgstr "Inscriptions"
|
||||
|
||||
#: apps/member/views.py:74 apps/registration/forms.py:23
|
||||
#: apps/member/views.py:73 apps/registration/forms.py:23
|
||||
msgid "This address must be valid."
|
||||
msgstr "Cette adresse doit être valide."
|
||||
|
||||
#: apps/member/views.py:154
|
||||
#: apps/member/views.py:140
|
||||
msgid "Profile detail"
|
||||
msgstr "Détails de l'utilisateur⋅rice"
|
||||
|
||||
#: apps/member/views.py:220
|
||||
#: apps/member/views.py:206
|
||||
msgid "Search user"
|
||||
msgstr "Chercher un·e utilisateur·rice"
|
||||
|
||||
#: apps/member/views.py:272
|
||||
#: apps/member/views.py:258
|
||||
msgid "Note friendships"
|
||||
msgstr "Amitiés note"
|
||||
|
||||
#: apps/member/views.py:342
|
||||
#: apps/member/views.py:328
|
||||
msgid "Update note picture"
|
||||
msgstr "Modifier la photo de la note"
|
||||
|
||||
#: apps/member/views.py:391
|
||||
#: apps/member/views.py:377
|
||||
msgid "Manage auth token"
|
||||
msgstr "Gérer les jetons d'authentification"
|
||||
|
||||
#: apps/member/views.py:418
|
||||
#: apps/member/views.py:404
|
||||
msgid "Create new club"
|
||||
msgstr "Créer un nouveau club"
|
||||
|
||||
#: apps/member/views.py:437
|
||||
#: apps/member/views.py:423
|
||||
msgid "Search club"
|
||||
msgstr "Chercher un club"
|
||||
|
||||
#: apps/member/views.py:475
|
||||
#: apps/member/views.py:461
|
||||
msgid "Club detail"
|
||||
msgstr "Détails du club"
|
||||
|
||||
#: apps/member/views.py:587
|
||||
#: apps/member/views.py:573
|
||||
msgid "Update club"
|
||||
msgstr "Modifier le club"
|
||||
|
||||
#: apps/member/views.py:621
|
||||
#: apps/member/views.py:607
|
||||
msgid "Add new member to the club"
|
||||
msgstr "Ajouter un·e nouvelleau membre au club"
|
||||
|
||||
#: apps/member/views.py:750 apps/wei/views.py:991
|
||||
#: apps/member/views.py:736 apps/wei/views.py:991
|
||||
msgid ""
|
||||
"This user don't have enough money to join this club, and can't have a "
|
||||
"negative balance."
|
||||
@ -1557,19 +1557,19 @@ msgstr ""
|
||||
"Cet⋅te utilisateur⋅rice n'a pas assez d'argent pour rejoindre ce club et ne "
|
||||
"peut pas avoir un solde négatif."
|
||||
|
||||
#: apps/member/views.py:772
|
||||
#: apps/member/views.py:758
|
||||
msgid "The membership must start after {:%m-%d-%Y}."
|
||||
msgstr "L'adhésion doit commencer après le {:%d/%m/%Y}."
|
||||
|
||||
#: apps/member/views.py:777
|
||||
#: apps/member/views.py:763
|
||||
msgid "The membership must begin before {:%m-%d-%Y}."
|
||||
msgstr "L'adhésion doit commencer avant le {:%d/%m/%Y}."
|
||||
|
||||
#: apps/member/views.py:927
|
||||
#: apps/member/views.py:913
|
||||
msgid "Manage roles of an user in the club"
|
||||
msgstr "Gérer les rôles d'un⋅e utilisateur⋅rice dans le club"
|
||||
|
||||
#: apps/member/views.py:952
|
||||
#: apps/member/views.py:938
|
||||
msgid "Members of the club"
|
||||
msgstr "Membres du club"
|
||||
|
||||
@ -2084,7 +2084,7 @@ msgid "Button displayed"
|
||||
msgstr "Bouton affiché"
|
||||
|
||||
#: apps/note/templates/note/transactiontemplate_list.html:100
|
||||
#: apps/wrapped/templates/wrapped/wrapped_list.html:70
|
||||
#: apps/wrapped/templates/wrapped/wrapped_list.html:63
|
||||
msgid "An error occured"
|
||||
msgstr "Une erreur s'est produite"
|
||||
|
||||
@ -3662,14 +3662,6 @@ msgstr "soirée·s organisée·s"
|
||||
msgid "distinct members"
|
||||
msgstr "Membres distinct·e·s"
|
||||
|
||||
#: apps/wrapped/templates/wrapped/1/wrapped_view_club.html:26
|
||||
msgid "Infortunately, you doesn't have consumer this year"
|
||||
msgstr "Malheureusement, tu n'as pas de consommateur cette année"
|
||||
|
||||
#: apps/wrapped/templates/wrapped/1/wrapped_view_club.html:28
|
||||
msgid "Congratulations you are a real rat !"
|
||||
msgstr "Félicitations, tu es un vrai rat !"
|
||||
|
||||
#: apps/wrapped/templates/wrapped/1/wrapped_view_user.html:13
|
||||
msgid "You participate to the wei: "
|
||||
msgstr "Tu as participé au wei : "
|
||||
@ -3707,15 +3699,7 @@ msgstr "avec"
|
||||
msgid "Your expenses to BDE: "
|
||||
msgstr "Tes dépenses au BDE : "
|
||||
|
||||
#: apps/wrapped/templates/wrapped/wrapped_list.html:13
|
||||
msgid "My wrapped"
|
||||
msgstr "Mes wrapped"
|
||||
|
||||
#: apps/wrapped/templates/wrapped/wrapped_list.html:22
|
||||
msgid "Public wrapped"
|
||||
msgstr "Wrapped public"
|
||||
|
||||
#: apps/wrapped/templates/wrapped/wrapped_list.html:33
|
||||
#: apps/wrapped/templates/wrapped/wrapped_list.html:26
|
||||
msgid ""
|
||||
"Do not forget to ask permission to people who are in your wrapped before to "
|
||||
"make them public"
|
||||
@ -3723,19 +3707,19 @@ msgstr ""
|
||||
"N'oublies pas de demander la permission des personnes apparaissant dans un "
|
||||
"wrapped avant de le rendre public"
|
||||
|
||||
#: apps/wrapped/templates/wrapped/wrapped_list.html:40
|
||||
#: apps/wrapped/templates/wrapped/wrapped_list.html:33
|
||||
msgid "Link copied"
|
||||
msgstr "Lien copié"
|
||||
|
||||
#: apps/wrapped/templates/wrapped/wrapped_list.html:65
|
||||
#: apps/wrapped/templates/wrapped/wrapped_list.html:58
|
||||
msgid "Wrapped is private"
|
||||
msgstr "Le wrapped est privé"
|
||||
|
||||
#: apps/wrapped/templates/wrapped/wrapped_list.html:66
|
||||
#: apps/wrapped/templates/wrapped/wrapped_list.html:59
|
||||
msgid "Wrapped is public"
|
||||
msgstr "Le wrapped est public"
|
||||
|
||||
#: apps/wrapped/views.py:28
|
||||
#: apps/wrapped/views.py:24
|
||||
msgid "List of wrapped"
|
||||
msgstr "Liste des wrapped"
|
||||
|
||||
|
@ -74,7 +74,7 @@ mark {
|
||||
/* MODE VIEUXCON=ON */
|
||||
/* background-color: rgb(166, 0, 2) !important; */
|
||||
background-color: rgb(0, 0, 0);
|
||||
background-image: url('/static/img/rp_bg.png');
|
||||
background-image: url('/static/wrapped/img/1/bg.png');
|
||||
}
|
||||
|
||||
html {
|
||||
@ -136,32 +136,33 @@ body {
|
||||
border-color: rgb(255, 0, 101);
|
||||
}
|
||||
|
||||
.btn-outline-dark-shiny {
|
||||
background-color: #222;
|
||||
border-color: #61605b;
|
||||
color: rgba(255, 0, 101, 75%);
|
||||
.btn-outline-dark:nth-child(even) {
|
||||
color: rgba(255, 203, 32, 75%);
|
||||
}
|
||||
|
||||
.btn-outline-dark-shiny:hover,
|
||||
.btn-outline-dark-shiny:not(:disabled):not(.disabled).active,
|
||||
.btn-outline-dark-shiny:not(:disabled):not(.disabled):active {
|
||||
color: rgb(0, 0, 0);
|
||||
background-color: rgb(255, 203, 32);
|
||||
border-color: rgb(255, 0, 101);
|
||||
.btn-outline-dark:nth-child(odd) {
|
||||
color: rgba(255, 0, 101, 75%);
|
||||
}
|
||||
|
||||
.btn-outline-dark {
|
||||
background-color: #222;
|
||||
border-color: #61605b;
|
||||
color: rgba(255, 203, 32, 75%);
|
||||
}
|
||||
|
||||
.btn-outline-dark:hover,
|
||||
.btn-outline-dark:hover:nth-child(even),
|
||||
.btn-outline-dark:not(:disabled):not(.disabled).active,
|
||||
.btn-outline-dark:not(:disabled):not(.disabled):active {
|
||||
color: rgb(0, 0, 0);
|
||||
background-color: rgb(255, 0, 101);
|
||||
border-color: rgb(255, 203, 32);
|
||||
background-color: rgb(255, 203, 32);
|
||||
border-color: rgb(255, 0, 101);
|
||||
}
|
||||
|
||||
.btn-outline-dark:hover:nth-child(odd),
|
||||
.btn-outline-dark:not(:disabled):not(.disabled).active,
|
||||
.btn-outline-dark:not(:disabled):not(.disabled):active {
|
||||
color: rgb(0, 0, 0);
|
||||
background-color: rgb(255, 203, 32);
|
||||
border-color: rgb(255, 0, 101);
|
||||
}
|
||||
|
||||
a {
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 82 KiB |
@ -26,7 +26,7 @@ function afterKonami () {
|
||||
})
|
||||
rythm.addRythm('d-flex', 'color', 50, 50, {
|
||||
from: [64, 64, 64],
|
||||
to: [255, 0, 101]
|
||||
to: [128, 64, 128]
|
||||
})
|
||||
rythm.addRythm('nav-link', 'jump', 150, 50, {
|
||||
min: 0,
|
||||
|
Reference in New Issue
Block a user