1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2025-03-14 17:57:39 +00:00
This commit is contained in:
quark 2025-02-24 16:10:58 +01:00
parent 5f1b698d58
commit 587314e03c
14 changed files with 344 additions and 299 deletions

View File

@ -11,6 +11,7 @@ from .models import Bde, Wrapped
class BdeAdmin(admin.ModelAdmin):
pass
@admin.register(Wrapped, site=admin_site)
class WrappedAdmin(admin.ModelAdmin):
pass

View File

@ -3,6 +3,7 @@
from .views import WrappedViewSet, BdeViewSet
def register_wrapped_urls(router, path):
"""
Configure router for Wrapped REST API.

View File

@ -8,6 +8,7 @@ from rest_framework.filters import SearchFilter
from .serializers import WrappedSerializer, BdeSerializer
from ..models import Wrapped, Bde
class WrappedViewSet(ReadProtectedModelViewSet):
"""
REST API View set.
@ -20,6 +21,7 @@ class WrappedViewSet(ReadProtectedModelViewSet):
filterset_fields = ['note', 'bde', ]
search_fields = ['$note', ]
class BdeViewSet(ReadProtectedModelViewSet):
"""
REST API View set.

View File

@ -3,13 +3,14 @@
import json
from argparse import ArgumentParser
from django.core.management import BaseCommand
from django.db.models import Q
from note.models import Note, Transaction
from member.models import User, Club, Membership
from activity.models import Activity, Entry
from wei.models import WEIClub
from ...models import Bde, Wrapped
@ -18,58 +19,57 @@ class Command(BaseCommand):
def add_arguments(self, parser: ArgumentParser):
parser.add_argument(
'-b', '--bde',
type=str,
required=False,
help="A list of BDE name, BDE1,BDE2,... (a BDE name cannot have ',')",
dest='bde',
'-b', '--bde',
type=str,
required=False,
help="A list of BDE name, BDE1,BDE2,... (a BDE name cannot have ',')",
dest='bde',
)
parser.add_argument(
'-i', '--id',
type=str,
required=False,
help="A list of BDE id, id1,id2,...",
dest='bde_id',
'-i', '--id',
type=str,
required=False,
help="A list of BDE id, id1,id2,...",
dest='bde_id',
)
parser.add_argument(
'-u', '--users',
type=str,
required=False,
help="""User will have their(s) wrapped generated,
all = all users
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""",
dest='user',
'-u', '--users',
type=str,
required=False,
help="""User will have their(s) wrapped generated,
all = all users
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""",
dest='user',
)
parser.add_argument(
'-c', '--club',
type=str,
required=False,
help="""Club will have their(s) wrapped generated,
all = all clubs,
active = all clubs with at least one transaction during the BDE mandate considered,
custom club1,club2,... = a list of club name,
custom_id id1,id2,... = a list of club id""",
dest='club',
'-c', '--club',
type=str,
required=False,
help="""Club will have their(s) wrapped generated,
all = all clubs,
active = all clubs with at least one transaction during the BDE mandate considered,
custom club1,club2,... = a list of club name,
custom_id id1,id2,... = a list of club id""",
dest='club',
)
parser.add_argument(
'-f', '--force-change',
required=False,
action='store_true',
help="if wrapped already exist change data_json",
dest='change',
'-f', '--force-change',
required=False,
action='store_true',
help="if wrapped already exist change data_json",
dest='change',
)
parser.add_argument(
'-n', '--no-creation',
required=False,
action='store_false',
help="if wrapped don't already exist, don't generate it",
dest='create',
'-n', '--no-creation',
required=False,
action='store_false',
help="if wrapped don't already exist, don't generate it",
dest='create',
)
def handle(self, *args, **options):
# useful string for output
red = '\033[31;1m'
@ -78,33 +78,34 @@ class Command(BaseCommand):
abort = red + 'ABORT'
warning = yellow + 'WARNING'
success = green + 'SUCCESS'
# Traitement des paramètres
verb = options['verbosity']
bde = []
if options['bde']:
bde_list = options['bde'].split(',')
bde = [Bde.objects.get(name=bde_name) for bde_name in bde_list]
if options['bde_id']:
if bde:
if bde:
if verb >= 1:
print(warning)
print(yellow + 'You already defined bde with their name !')
if verb >= 0: print(abort)
if verb >= 0:
print(abort)
return
bde_id = options['bde_id'].split(',')
bde = [Bde.objects.get(pk=i) for i in bde_id]
user = []
if options['user']:
if options['user'] == 'all':
user = ['all',None]
user = ['all', None]
elif options['user'] == 'adh':
user = ['adh',None]
user = ['adh', None]
elif options['user'] == 'superuser':
user = ['superuser',None]
elif options['user'].split(' ')[0] == 'custom':
user = ['superuser', None]
elif options['user'].split(' ')[0] == 'custom':
user_list = options['user'].split(' ')[1].split(',')
user = ['custom', [User.objects.get(username=u) for u in user_list]]
elif options['user'].split(' ')[0] == 'custom_id':
@ -114,15 +115,16 @@ class Command(BaseCommand):
if verb >= 1:
print(warning)
print(yellow + 'You user option is not recognized')
if verb >= 0: print(abort)
if verb >= 0:
print(abort)
return
club = []
if options['club']:
if options['club'] == 'all':
club = ['all',None]
club = ['all', None]
elif options['club'] == 'active':
club = ['active',None]
club = ['active', None]
elif options['club'].split(' ')[0] == 'custom':
club_list = options['club'].split(' ')[1].split(',')
club = ['custom', [Club.objects.get(name=club_name) for club_name in club_list]]
@ -133,7 +135,8 @@ class Command(BaseCommand):
if verb >= 1:
print(warning)
print(yellow + 'You club option is not recognized')
if verb >= 0: print(abort)
if verb >= 0:
print(abort)
return
change = options['change']
@ -144,22 +147,27 @@ class Command(BaseCommand):
if verb >= 1:
print(warning)
print(yellow + 'You have not selectionned a BDE !')
if verb >= 0 : print(abort)
if verb >= 0:
print(abort)
return
if not (user or club):
if verb >= 1:
print(warning)
print(yellow + 'No club or user selected !')
if verb >= 0 : print(abort)
if verb >= 0:
print(abort)
return
if verb >= 3:
print('\033[1mOptions:\033[m')
bde_str = ''
for b in bde: bde_str += str(b)
for b in bde:
bde_str += str(b)
print('BDE: ' + bde_str)
if user: print('User: ' + user[0])
if club: print('Club: ' + club[0])
if user:
print('User: ' + user[0])
if club:
print('Club: ' + club[0])
print('change: ' + str(change))
print('create: ' + str(create))
print('')
@ -170,34 +178,40 @@ class Command(BaseCommand):
if verb >= 0:
print(abort)
return
if verb >=1 and change:
if verb >= 1 and change:
print(warning)
print(yellow + 'change is set to true, some wrapped may be replaced !')
if verb >=1 and not create:
if verb >= 1 and not create:
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: print(abort)
if a in ['n', 'no', 'non', '0']:
if verb >= 0:
print(abort)
return
note = self.convert_to_note(change, create, bde=bde, user=user, club=club, verb=verb)
if verb >= 1: print("\033[32mUser and/or Club given has successfully convert in their note\033[m")
if verb >= 1:
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: print("\033[32mGlobal data has been successfully generated\033[m")
if verb >= 1:
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: print("\033[32mUnique data has been successfully generated\033[m")
if verb >= 1:
print("\033[32mUnique data has been successfully generated\033[m")
self.make_wrapped(unique_data, note, bde, change, create, verb=verb)
if verb >= 1: print(green + "The wrapped has been generated !")
if verb >= 0: print(success)
if verb >= 1:
print(green + "The wrapped has been generated !")
if verb >= 0:
print(success)
return
def convert_to_note(self, change, create, bde=None, user=None, club=None, verb=1):
N = []
n = []
for b in bde:
note = Note.objects.filter(pk__lte=-1)
if user:
@ -209,12 +223,12 @@ class Command(BaseCommand):
query = Q(noteuser__user__pk__gte=-1)
note |= Note.objects.filter(query)
elif user[0] == 'adh':
M = Membership.objects.filter(club=1,
m = Membership.objects.filter(club=1,
date_start__lt=b.date_end,
date_end__gt=b.date_start,
).distinct('user')
for m in M:
note |= Note.objects.filter(noteuser__user=m.user)
for membership in m:
note |= Note.objects.filter(noteuser__user=membership.user)
elif user[0] == 'superuser':
query |= Q(noteuser__user__is_superuser=True)
@ -230,111 +244,125 @@ class Command(BaseCommand):
note |= Note.objects.filter(query)
elif club[0] == 'active':
nc = Note.objects.filter(noteclub__club__pk__gte=-1)
for n in nc:
for noteclub in nc:
if Transaction.objects.filter(
Q(created_at__gte=b.date_start,
created_at__lte=b.date_end) &
(Q(source=n) | Q(destination=n))):
created_at__lte=b.date_end) & (Q(source=noteclub) | Q(destination=noteclub))):
note |= Note.objects.filter(pk=n.pk)
note = self.filter_note(b, note, change, create, verb=verb)
N.append(note)
n.append(note)
if verb >= 2:
print("\033[m{nb} note selectionned for bde {bde}".format(nb=len(note) ,bde=b.name))
return N
print("\033[m{nb} note selectionned for bde {bde}".format(nb=len(note), bde=b.name))
return n
def global_data(self, bde, verb=1):
data = {}
for b in bde:
if b.name == 'Rave Part[list]':
if verb >= 2: print("Begin to make global data")
if verb >= 3: print('nb_transaction')
if verb >= 2:
print("Begin to make global data")
if verb >= 3:
print('nb_transaction')
# nb total de transactions
data['nb_transaction'] = Transaction.objects.filter(
created_at__gte=b.date_start,
created_at__lte=b.date_end,
valid=True).count()
if verb >= 3: print('nb_vieux_con')
created_at__gte=b.date_start,
created_at__lte=b.date_end,
valid=True).count()
if verb >= 3:
print('nb_vieux_con')
# nb total de vielleux con·ne·s derrière le bar
button_id = [2884,2585]
T = Transaction.objects.filter(
created_at__gte=b.date_start,
created_at__lte=b.date_end,
valid=True,
recurrenttransaction__template__pk__in=button_id)
button_id = [2884, 2585]
transactions = Transaction.objects.filter(
created_at__gte=b.date_start,
created_at__lte=b.date_end,
valid=True,
recurrenttransaction__template__pk__in=button_id)
q = 0
for t in T: q += t.quantity
for t in transactions:
q += t.quantity
data['nb_vieux_con'] = q
if verb >= 3: print('nb_soiree')
if verb >= 3:
print('nb_soiree')
# nb total de soirée
a_type_id = [1, 2, 4, 5, 7, 10]
data['nb_soiree'] = Activity.objects.filter(
date_end__gte=b.date_start,
date_start__lte=b.date_end,
valid=True,
activity_type__pk__in=a_type_id).count()
if verb >= 3: print('pots, nb_entree_pot')
date_end__gte=b.date_start,
date_start__lte=b.date_end,
valid=True,
activity_type__pk__in=a_type_id).count()
if verb >= 3:
print('pots, nb_entree_pot')
# nb d'entrée totale aux pots
pot_id = [1, 4, 10]
pots = Activity.objects.filter(
date_end__gte=b.date_start,
date_start__lte=b.date_end,
activity_type__pk__in=pot_id)
data['pots'] = pots # utile dans unique_data
date_end__gte=b.date_start,
date_start__lte=b.date_end,
valid=True,
activity_type__pk__in=pot_id)
data['pots'] = pots # utile dans unique_data
data['nb_entree_pot'] = 0
for pot in pots:
data['nb_entree_pot'] += Entry.objects.filter(activity=pot).count()
if verb >= 3: print('top3_buttons')
if verb >= 3:
print('top3_buttons')
# top 3 des boutons les plus cliqués
T = Transaction.objects.filter(
created_at__gte=b.date_start,
created_at__lte=b.date_end,
valid=True,
amount__gt=0,
recurrenttransaction__template__pk__gte=-1)
transactions = Transaction.objects.filter(
created_at__gte=b.date_start,
created_at__lte=b.date_end,
valid=True,
amount__gt=0,
recurrenttransaction__template__pk__gte=-1)
d = {}
for t in T:
for t in transactions:
if t.recurrenttransaction.template.name in d:
d[t.recurrenttransaction.template.name] += t.quantity
else : d[t.recurrenttransaction.template.name] = t.quantity
else:
d[t.recurrenttransaction.template.name] = t.quantity
data['top3_buttons'] = list(sorted(d.items(), key=lambda item: item[1], reverse=True))[:3]
if verb >= 3: print('class_conso_all')
if verb >= 3:
print('class_conso_all')
# le classement des plus gros consommateurs (BDE + club)
T = Transaction.objects.filter(
created_at__gte=b.date_start,
created_at__lte=b.date_end,
valid=True,
source__noteuser__user__pk__gte=-1,
destination__noteclub__club__pk__gte=-1)
transactions = Transaction.objects.filter(
created_at__gte=b.date_start,
created_at__lte=b.date_end,
valid=True,
source__noteuser__user__pk__gte=-1,
destination__noteclub__club__pk__gte=-1)
d = {}
for t in T:
if t.source in d: d[t.source] += t.total
else : d[t.source] = t.total
for t in transactions:
if t.source in d:
d[t.source] += t.total
else:
d[t.source] = t.total
data['class_conso_all'] = dict(sorted(d.items(), key=lambda item: item[1], reverse=True))
if verb >= 3: print('class_conso_bde')
# le classement des plus gros consommateurs BDE
T = Transaction.objects.filter(
created_at__gte=b.date_start,
created_at__lte=b.date_end,
valid=True,
source__noteuser__user__pk__gte=-1,
destination=5)
if verb >= 3:
print('class_conso_bde')
# le classement des plus gros consommateurs BDE
transactions = Transaction.objects.filter(
created_at__gte=b.date_start,
created_at__lte=b.date_end,
valid=True,
source__noteuser__user__pk__gte=-1,
destination=5)
d = {}
for t in T:
if t.source in d: d[t.source] += t.total
else : d[t.source] = t.total
for t in transactions:
if t.source in d:
d[t.source] += t.total
else:
d[t.source] = t.total
data['class_conso_bde'] = dict(sorted(d.items(), key=lambda item: item[1], reverse=True))
@ -358,52 +386,56 @@ class Command(BaseCommand):
d = {}
if 'user' in n.__dir__():
# première conso du mandat
T = Transaction.objects.filter(
valid=True,
recurrenttransaction__template__id__gte=-1,
created_at__gte=bde[i].date_start,
created_at__lte=bde[i].date_end,
source=n,
destination=5).order_by('created_at')
if T:
d['first_conso'] = T[0].template.name
transactions = Transaction.objects.filter(
valid=True,
recurrenttransaction__template__id__gte=-1,
created_at__gte=bde[i].date_start,
created_at__lte=bde[i].date_end,
source=n,
destination=5).order_by('created_at')
if transactions:
d['first_conso'] = transactions[0].template.name
else:
d['first_conso'] = ''
# Wei + bus
W = WEIClub.objects.filter(
date_start__lte=bde[i].date_end,
date_end__gte=bde[i].date_start)
if not W:
wei = WEIClub.objects.filter(
date_start__lte=bde[i].date_end,
date_end__gte=bde[i].date_start)
if not wei:
d['wei'] = ''
d['bus'] = ''
else:
w = W[0]
M = Membership.objects.filter(club=w, user=n.user)
if not M:
w = wei[0]
memberships = Membership.objects.filter(club=w, user=n.user)
if not memberships:
d['wei'] = ''
d['bus'] = ''
else :
A = []
else:
alias = []
for a in w.note.alias.iterator():
A.append(str(a))
d['wei'] = A[-1]
d['bus'] = M[0].weimembership.bus.name
alias.append(str(a))
d['wei'] = alias[-1]
d['bus'] = memberships[0].weimembership.bus.name
# top3 conso
T = Transaction.objects.filter(
valid=True,
created_at__gte=bde[i].date_start,
created_at__lte=bde[i].date_end,
source=n,
amount__gt=0,
recurrenttransaction__template__id__gte=-1)
transactions = Transaction.objects.filter(
valid=True,
created_at__gte=bde[i].date_start,
created_at__lte=bde[i].date_end,
source=n,
amount__gt=0,
recurrenttransaction__template__id__gte=-1)
dt = {}
dc = {}
for t in T:
if t.template.name in dt: dt[t.template.name] += t.quantity
else : dt[t.template.name] = t.quantity
if t.template.category.name in dc: dc[t.template.category.name] += t.quantity
else : dc[t.template.category.name] = t.quantity
for t in transactions:
if t.template.name in dt:
dt[t.template.name] += t.quantity
else:
dt[t.template.name] = t.quantity
if t.template.category.name in dc:
dc[t.template.category.name] += t.quantity
else:
dc[t.template.category.name] = t.quantity
d['top3_conso'] = list(sorted(dt.items(), key=lambda item: item[1], reverse=True))[:3]
# catégorie de bouton préférée
if dc:
@ -413,25 +445,25 @@ class Command(BaseCommand):
# nombre de pot, et nombre d'entrée pot
pots = global_data['pots']
d['nb_pots'] = pots.count()
p = 0
for pot in pots:
if Entry.objects.filter(activity=pot,note=n):
if Entry.objects.filter(activity=pot, note=n):
p += 1
d['nb_pot_entry'] = p
# ton nombre de rechargement
d['nb_rechargement'] = Transaction.objects.filter(
valid=True,
created_at__gte=bde[i].date_start,
created_at__lte=bde[i].date_end,
destination=n,
source__pk__in=[1,2,3,4]).count()
valid=True,
created_at__gte=bde[i].date_start,
created_at__lte=bde[i].date_end,
destination=n,
source__pk__in=[1, 2, 3, 4]).count()
# ajout info globale spécifique user
# classement et montant conso all
d['class_part_all'] = len(global_data['class_conso_all'])
if n in global_data['class_conso_all']:
d['class_conso_all'] = list(global_data['class_conso_all']).index(n) + 1
d['amount_conso_all'] = global_data['class_conso_all'][n]/100
d['amount_conso_all'] = global_data['class_conso_all'][n] / 100
else:
d['class_conso_all'] = 0
d['amount_conso_all'] = 0
@ -439,57 +471,61 @@ class Command(BaseCommand):
d['class_part_bde'] = len(global_data['class_conso_bde'])
if n in global_data['class_conso_bde']:
d['class_conso_bde'] = list(global_data['class_conso_bde']).index(n) + 1
d['amount_conso_bde'] = global_data['class_conso_bde'][n]/100
d['amount_conso_bde'] = global_data['class_conso_bde'][n] / 100
else:
d['class_conso_bde'] = 0
d['amount_conso_bde'] = 0
if 'club' in n.__dir__():
# plus gros consommateur
T = Transaction.objects.filter(
valid=True,
created_at__lte=bde[i].date_end,
created_at__gte=bde[i].date_start,
destination=n,
source__noteuser__user__pk__gte=-1)
transactions = Transaction.objects.filter(
valid=True,
created_at__lte=bde[i].date_end,
created_at__gte=bde[i].date_start,
destination=n,
source__noteuser__user__pk__gte=-1)
dt = {}
for t in T:
if t.source.user.username in dt: dt[t.source.user.username] += t.total
else : dt[t.source.user.username] = t.total
for t in transactions:
if t.source.user.username in dt:
dt[t.source.user.username] += t.total
else:
dt[t.source.user.username] = t.total
if dt:
d['big_consumer'] = list(sorted(dt.items(), key=lambda item: item[1], reverse=True))[0]
d['big_consumer'] = (d['big_consumer'][0], d['big_consumer'][1]/100)
d['big_consumer'] = (d['big_consumer'][0], d['big_consumer'][1] / 100)
else:
d['big_consumer'] = ''
# plus gros créancier
T = Transaction.objects.filter(
valid=True,
created_at__lte=bde[i].date_end,
created_at__gte=bde[i].date_start,
source=n,
destination__noteuser__user__pk__gte=-1)
transactions = Transaction.objects.filter(
valid=True,
created_at__lte=bde[i].date_end,
created_at__gte=bde[i].date_start,
source=n,
destination__noteuser__user__pk__gte=-1)
dt = {}
for t in T:
if t.destination.user.username in dt: dt[t.destination.user.username] += t.total
else : dt[t.destination.user.username] = t.total
for t in transactions:
if t.destination.user.username in dt:
dt[t.destination.user.username] += t.total
else:
dt[t.destination.user.username] = t.total
if dt:
d['big_creancier'] = list(sorted(dt.items(), key=lambda item: item[1], reverse=True))[0]
d['big_creancier'] = (d['big_creancier'][0], d['big_creancier'][1]/100)
d['big_creancier'] = (d['big_creancier'][0], d['big_creancier'][1] / 100)
else:
d['big_creancier'] = ''
# nb de soirée organisée
d['nb_soiree_orga'] = Activity.objects.filter(
valid=True,
date_start__lte=bde[i].date_end,
date_end__gte=bde[i].date_start,
organizer=n.club).count()
valid=True,
date_start__lte=bde[i].date_end,
date_end__gte=bde[i].date_start,
organizer=n.club).count()
# nb de membres cumulé
d['nb_member'] = Membership.objects.filter(
date_start__lte=bde[i].date_end,
date_end__gte=bde[i].date_start,
club=n.club).distinct('user').count()
date_start__lte=bde[i].date_end,
date_end__gte=bde[i].date_start,
club=n.club).distinct('user').count()
# ajout info globale
# top3 button
@ -519,8 +555,8 @@ class Command(BaseCommand):
if verb >= 3:
current = 0
total = 0
for l in note:
total += len(l)
for n in note:
total += len(n)
print('\033[mMake {nb} wrapped'.format(nb=total))
for i in range(len(bde)):
for j in range(len(note[i])):

View File

@ -1,8 +1,6 @@
# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import os
from django.db import models
from django.utils.translation import gettext_lazy as _
from note.models import Note
@ -27,8 +25,8 @@ class Bde(models.Model):
)
class Meta:
verbose_name=_('BDE')
verbose_name_plural=_('BDE')
verbose_name = _('BDE')
verbose_name_plural = _('BDE')
def __str__(self):
return self.name
@ -36,7 +34,7 @@ class Bde(models.Model):
class Wrapped(models.Model):
"""
A Wrapped is associated to a note, a BDE year,
A Wrapped is associated to a note, a BDE year,
"""
generated = models.BooleanField(
verbose_name=_('generated'),
@ -69,12 +67,13 @@ class Wrapped(models.Model):
)
class Meta:
verbose_name=_('Wrapped')
verbose_name_plural=_('Wrappeds')
unique_together=('note','bde')
verbose_name = _('Wrapped')
verbose_name_plural = _('Wrappeds')
unique_together = ('note', 'bde')
def __str__(self):
return 'NoteKfet Wrapped of {note} sponsored by {bde}'.format(bde=str(self.bde),note=str(self.note))
return 'NoteKfet Wrapped of {note} sponsored by {bde}'.format(bde=str(self.bde), note=str(self.note))
def makepublic(self):
self.public = not self.public
self.save()

View File

@ -2,9 +2,13 @@
--accent-primary: #FF0065;
--accent-secondary: #FFCB20;
}
@font-face {
font-family: "JEMROKtrial-Regular";
src: url("/static/wrapped/fonts/1/jr-font.ttf");
}
body {
font-family: Arial, sans-serif;
background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
font-family: "JEMROKtrial-Regular", sans-serif;
background: url("/static/wrapped/img/1/bg.png");
color: white;
text-align: center;
padding: 50px;

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 732 KiB

View File

@ -1,17 +1,15 @@
# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.utils import timezone
from django.utils.html import escape, format_html
from django.utils.safestring import mark_safe
from django.utils.html import format_html
from django.utils.translation import gettext_lazy as _
from note_kfet.middlewares import get_current_request
import django_tables2 as tables
from django_tables2 import A
from permission.backends import PermissionBackend
from note.templatetags.pretty_money import pretty_money
from .models import Wrapped, Bde
from .models import Wrapped
class WrappedTable(tables.Table):
"""
@ -30,35 +28,34 @@ class WrappedTable(tables.Table):
fields = ('note', 'bde', 'public', )
view = tables.LinkColumn(
'wrapped:wrapped_detail',
args=[A('pk')],
attrs={
'td': {'class': 'col-sm-2'},
'a': {
'class': 'btn btn-sm btn-primary',
'data-turbolinks': 'false',
}
},
text=_('view the wrapped'),
accessor='pk',
verbose_name=_('View'),
orderable=False,
)
'wrapped:wrapped_detail',
args=[A('pk')],
attrs={
'td': {'class': 'col-sm-2'},
'a': {
'class': 'btn btn-sm btn-primary',
'data-turbolinks': 'false',
}
},
text=_('view the wrapped'),
accessor='pk',
verbose_name=_('View'),
orderable=False,
)
public = tables.Column(
accessor="pk",
orderable=False,
attrs={
"td": {
"id": lambda record: "makepublic_"+ str(record.pk),
"class" : 'col-sm-1',
"id": lambda record: "makepublic_" + str(record.pk),
"class": 'col-sm-1',
"data-toggle": "tooltip",
"title": lambda record:
(_("Click to make this wrapped private") if record.public else
_("Click to make this wrapped public")) if PermissionBackend.check_perm(
_("Click to make this wrapped public")) if PermissionBackend.check_perm(
get_current_request(), "wrapped.change_wrapped_public", record) else None,
"onclick" : lambda record:
"onclick": lambda record:
'makepublic(' + str(record.id) + ', ' + str(not record.public).lower() + ')'
if PermissionBackend.check_perm(get_current_request(), "wrapped.change_wrapped_public",
record) else None
@ -85,6 +82,5 @@ class WrappedTable(tables.Table):
return format_html(val)
def render_public(self, value, record):
val = "" if record.public else ""
val = "" if record.public else ""
return val

View File

@ -55,7 +55,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% endblock %}
<br>
<div class="wrap-container">
<h2>{% trans "The NoteKfet this year it's also:" %}</h2>
<h2>{% trans "The NoteKfet this year it's also" %}</h2>
<ul class="list" id="glob_top3_conso">
<li>{{ glob_nb_transaction }} {% trans " transactions" %}</li>
<li>{{ glob_nb_soiree }} {% trans " party" %}</li>
@ -72,5 +72,11 @@ SPDX-License-Identifier: GPL-3.0-or-later
<li>{{ glob_nb_vieux_con }} {% trans " old asshole behind the bar" %} </li>
</ul>
</div>
<script>
CSRF_TOKEN = "{{ csrf_token }}";
$(".invalid-feedback").addClass("d-block");
</script>
{% block extrajavascript %}{% endblock %}
</body>
</html>

View File

@ -8,23 +8,24 @@ SPDX-License-Identifier: GPL-3.0-or-later
<div class="wrap-container">
<h2>{% trans "NoteKfet Wrapped" %}</h2>
<h1 id="name">{{ wrapped.note.club.name }}</h1>
{% trans "Your best consumer:" %}
{% trans "Your best consumer" %}
<div class="category" id="consumer"></div>
{% trans "Your worst creditor:" %}
{% trans "Your worst creditor" %}
<div class="category" id="creditor"></div>
<ul class="list">
<li>{{ nb_soiree_orga }}{% trans " party organised" %}</li>
<li>{{ nb_member }}{% trans " distinct members" %}</li>
<li>{{ nb_soiree_orga }} {% trans "party organised" %}</li>
<li>{{ nb_member }} {% trans "distinct members" %}</li>
</ul>
</div>
<script>
let con = {{ big_consumer | safe }};
let cre = {{ big_creancier | safe }};
let con = Boolean({{ big_consumer | safe }});
let cre = Boolean({{ big_creancier | safe }});
let d1 = document.getElementById("consumer");
let d2 = document.getElementById("creditor");
if (con) { d1.textContent = con[0] + " with " + con[1] + "€";}
else { d1.textContent = "Infortunately, you doesn't have consumer this year...";};
if (cre) { d2.textContent = cre[0] + " with " + cre[1] + "€";}
else { d2.textContent = "Congratulations you are a real rat !" };
if (con) { d1.textContent = {{ big_consumer | safe }}[0] + " with " + {{ big_consumer | safe}}[1] + "€";}
else { d1.textContent = gettext("Infortunately, you doesn't have consumer this year");};
if (cre) { d2.textContent = {{ big_creancier | safe}}[0] + " with " + {{ big_creancier | safe}}[1] + "€";}
else { d2.textContent = gettext("Congratulations you are a real rat !"); };
</script>
{% endblock %}

View File

@ -8,21 +8,24 @@ SPDX-License-Identifier: GPL-3.0-or-later
<div class="wrap-container">
<h2>{% trans "NoteKfet Wrapped" %}</h2>
<h1 id="name">{{ wrapped.note.user.username }}</h1>
{% if wei %}
<div class="category" id="wei">
You participate to the wei: {{ wei }} in the bus {{ bus }}
{% trans "You participate to the wei" %} {{ wei }} {% trans "in the" %} {{ bus }}
</div>
{% endif %}
<div class="ranking-bar">
<div class="ranking-progress" id="pot_bar">
{{ nb_pot_entry }}/{{ nb_pots }} pots !
{{ nb_pot_entry }}/{{ nb_pots }} {% trans "pots" %}
</div>
<script>
const percentage = ({{ nb_pot_entry }} / {{ nb_pots }}) *100;
document.getElementById("pot_bar").style.width = percentage + '%';
</script>
</div>
{% if first_conso %}
<ul class="list" id="user_conso">
<li>Your first conso: {{ first_conso }}</li>
<li>Ta catégorie de conso préférée: {{ top_category }}</li>
<li>{% trans "Your first conso of the year" %} {{ first_conso }}</li>
<li>{% trans "Your prefered consumtion category" %} {{ top_category }}</li>
<script>
let top3 = {{ top3_conso | safe }};
let l = document.getElementById("user_conso");
@ -33,26 +36,34 @@ SPDX-License-Identifier: GPL-3.0-or-later
});
</script>
</ul>
{% endif %}
<div class="category">
Tu as rechargé ta note {{ nb_rechargement }} fois.
{{ nb_rechargement }} {% trans "it's the number of time your reload your note" %}
</div>
Tes dépenses globales
{% if class_conso_all > 0 %}
{% trans "Your overall expenses" %}
<div class="ranking-bar">
<div class="ranking-progress" id="all_bar">
{{ class_conso_all }}/{{ class_part_all }} with {{ amount_conso_all }}€
</div>
</div>
<br>Tes dépenses au BDE
<div class="ranking-bar">
<div class="ranking-progress" id="bde_bar">
{{ class_conso_bde }}/{{ class_part_bde }} with {{ amount_conso_bde }}€
{{ class_conso_all }}/{{ class_part_all }} {% trans "with" %} {{ amount_conso_all }}€
</div>
</div>
<script>
const p_all = 100 - ({{ class_conso_all }} / {{ class_part_all }}) * 100;
const p_bde = 100 - ({{ class_conso_bde }} / {{ class_part_bde }}) * 100;
document.getElementById("all_bar").style.width = p_all + '%';
const p_all = 100 - (({{ class_conso_all }} - 1) / {{ class_part_all }}) * 100;
document.getElementById("all_bar").style.width = p_all + '%';
</script>
{% endif %}
<br>
{% if class_conso_bde > 0 %}
{% trans "Your expenses to BDE" %}
<div class="ranking-bar">
<div class="ranking-progress" id="bde_bar">
{{ class_conso_bde }}/{{ class_part_bde }} {% trans "with" %} {{ amount_conso_bde }}€
</div>
</div>
<script>
const p_bde = 100 - (({{ class_conso_bde }} - 1) / {{ class_part_all }}) * 100;
document.getElementById("bde_bar").style.width = p_bde + '%';
</script>
{% endif %}
</div>
{% endblock %}

View File

@ -1,33 +1,19 @@
# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from hashlib import md5
import json
from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import PermissionDenied
from django.db import transaction
from django.db.models import F, Q
from django.http import HttpResponse
from django.urls import reverse_lazy
from django.utils import timezone
from django.utils.decorators import method_decorator
from django.utils.translation import gettext_lazy as _
from django.views import View
from django.views.decorators.cache import cache_page
from django.views.generic import DetailView, TemplateView, UpdateView
from django.views.generic.list import ListView
from django_tables2.views import MultiTableMixin, SingleTableMixin, SingleTableView
from api.viewsets import is_regex
from note.models import Alias, NoteSpecial, NoteUser
from django.views.generic import DetailView
from django_tables2.views import SingleTableView
from permission.backends import PermissionBackend
from permission.views import ProtectQuerysetMixin, ProtectedCreateView
from permission.views import ProtectQuerysetMixin
from .models import Wrapped
from .tables import WrappedTable
class WrappedListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
"""
Display all Wrapped, and classify by year
@ -46,18 +32,20 @@ class WrappedListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
W = self.object_list.filter(note__noteclub__club__pk__gte=-1, public=False)
if W:
w = self.object_list.filter(note__noteclub__club__pk__gte=-1, public=False)
if w:
context['club_not_public'] = 'true'
else: context['club_not_public'] = 'false'
else:
context['club_not_public'] = 'false'
return context
class WrappedDetailView(ProtectQuerysetMixin, DetailView):
class WrappedDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
"""
View a wrapped
"""
model = Wrapped
template_name = 'wrapped/0/wrapped_view.html' #by default
template_name = 'wrapped/0/wrapped_view.html' # by default
def get(self, *args, **kwargs):
bde_id = Wrapped.objects.get(pk=kwargs['pk']).bde.id
@ -66,7 +54,7 @@ class WrappedDetailView(ProtectQuerysetMixin, DetailView):
return super().get(*args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data( **kwargs)
context = super().get_context_data(**kwargs)
d = json.loads(self.object.data_json)
for key in d:
context[key] = d[key]