diff --git a/apps/wrapped/admin.py b/apps/wrapped/admin.py index 96a2b397..a50ec0ad 100644 --- a/apps/wrapped/admin.py +++ b/apps/wrapped/admin.py @@ -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 diff --git a/apps/wrapped/api/urls.py b/apps/wrapped/api/urls.py index a989bb3c..b06cddb9 100644 --- a/apps/wrapped/api/urls.py +++ b/apps/wrapped/api/urls.py @@ -3,6 +3,7 @@ from .views import WrappedViewSet, BdeViewSet + def register_wrapped_urls(router, path): """ Configure router for Wrapped REST API. diff --git a/apps/wrapped/api/views.py b/apps/wrapped/api/views.py index 5fef0c66..72294230 100644 --- a/apps/wrapped/api/views.py +++ b/apps/wrapped/api/views.py @@ -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. diff --git a/apps/wrapped/management/commands/generate_wrapped.py b/apps/wrapped/management/commands/generate_wrapped.py index f156c989..36842e50 100644 --- a/apps/wrapped/management/commands/generate_wrapped.py +++ b/apps/wrapped/management/commands/generate_wrapped.py @@ -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])): diff --git a/apps/wrapped/models.py b/apps/wrapped/models.py index b29a6183..b9ebc0e2 100644 --- a/apps/wrapped/models.py +++ b/apps/wrapped/models.py @@ -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() diff --git a/apps/wrapped/static/wrapped/css/1/custom.css b/apps/wrapped/static/wrapped/css/1/custom.css index 50415ffb..d4b865c4 100644 --- a/apps/wrapped/static/wrapped/css/1/custom.css +++ b/apps/wrapped/static/wrapped/css/1/custom.css @@ -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; diff --git a/apps/wrapped/static/wrapped/fonts/1/JemroktrialRegular-MVe4B.ttf b/apps/wrapped/static/wrapped/fonts/1/JemroktrialRegular-MVe4B.ttf new file mode 100644 index 00000000..ea30e52e Binary files /dev/null and b/apps/wrapped/static/wrapped/fonts/1/JemroktrialRegular-MVe4B.ttf differ diff --git a/apps/wrapped/static/wrapped/fonts/1/jr-font.ttf b/apps/wrapped/static/wrapped/fonts/1/jr-font.ttf new file mode 100644 index 00000000..7815521b Binary files /dev/null and b/apps/wrapped/static/wrapped/fonts/1/jr-font.ttf differ diff --git a/apps/wrapped/static/wrapped/img/1/bg.png b/apps/wrapped/static/wrapped/img/1/bg.png new file mode 100644 index 00000000..9e78673c Binary files /dev/null and b/apps/wrapped/static/wrapped/img/1/bg.png differ diff --git a/apps/wrapped/tables.py b/apps/wrapped/tables.py index 86428e35..2f97a9a0 100644 --- a/apps/wrapped/tables.py +++ b/apps/wrapped/tables.py @@ -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 - diff --git a/apps/wrapped/templates/wrapped/1/wrapped_base.html b/apps/wrapped/templates/wrapped/1/wrapped_base.html index 23e63339..71deb764 100644 --- a/apps/wrapped/templates/wrapped/1/wrapped_base.html +++ b/apps/wrapped/templates/wrapped/1/wrapped_base.html @@ -55,7 +55,7 @@ SPDX-License-Identifier: GPL-3.0-or-later {% endblock %}
-

{% trans "The NoteKfet this year it's also:" %}

+

{% trans "The NoteKfet this year it's also" %}

+ + +{% block extrajavascript %}{% endblock %} diff --git a/apps/wrapped/templates/wrapped/1/wrapped_view_club.html b/apps/wrapped/templates/wrapped/1/wrapped_view_club.html index 958199fa..be6beb31 100644 --- a/apps/wrapped/templates/wrapped/1/wrapped_view_club.html +++ b/apps/wrapped/templates/wrapped/1/wrapped_view_club.html @@ -8,23 +8,24 @@ SPDX-License-Identifier: GPL-3.0-or-later

{% trans "NoteKfet Wrapped" %}

{{ wrapped.note.club.name }}

- {% trans "Your best consumer:" %} + {% trans "Your best consumer" %}
- {% trans "Your worst creditor:" %} + {% trans "Your worst creditor" %}
{% endblock %} diff --git a/apps/wrapped/templates/wrapped/1/wrapped_view_user.html b/apps/wrapped/templates/wrapped/1/wrapped_view_user.html index 4a457c1d..a7ebe2f3 100644 --- a/apps/wrapped/templates/wrapped/1/wrapped_view_user.html +++ b/apps/wrapped/templates/wrapped/1/wrapped_view_user.html @@ -8,21 +8,24 @@ SPDX-License-Identifier: GPL-3.0-or-later

{% trans "NoteKfet Wrapped" %}

{{ wrapped.note.user.username }}

+ {% if wei %}
- You participate to the wei: {{ wei }} in the bus {{ bus }} + {% trans "You participate to the wei" %} {{ wei }} {% trans "in the" %} {{ bus }}
+ {% endif %}
- {{ nb_pot_entry }}/{{ nb_pots }} pots ! + {{ nb_pot_entry }}/{{ nb_pots }} {% trans "pots" %}
+ {% if first_conso %} + {% endif %}
- Tu as rechargé ta note {{ nb_rechargement }} fois. + {{ nb_rechargement }} {% trans "it's the number of time your reload your note" %}
- Tes dépenses globales + {% if class_conso_all > 0 %} + {% trans "Your overall expenses" %}
- {{ class_conso_all }}/{{ class_part_all }} with {{ amount_conso_all }}€ -
-
-
Tes dépenses au BDE -
-
- {{ class_conso_bde }}/{{ class_part_bde }} with {{ amount_conso_bde }}€ + {{ class_conso_all }}/{{ class_part_all }} {% trans "with" %} {{ amount_conso_all }}€
+ {% endif %} +
+ {% if class_conso_bde > 0 %} + {% trans "Your expenses to BDE" %} +
+
+ {{ class_conso_bde }}/{{ class_part_bde }} {% trans "with" %} {{ amount_conso_bde }}€ +
+
+ + {% endif %}
{% endblock %} diff --git a/apps/wrapped/views.py b/apps/wrapped/views.py index 1529d53a..0a16fd92 100644 --- a/apps/wrapped/views.py +++ b/apps/wrapped/views.py @@ -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]