Commit 596dd53b authored by Hamza Dely's avatar Hamza Dely

[consos/views] Implémentation des ViewSets pour les boutons et les transactions

parent 1aaa4ff9
......@@ -6,7 +6,7 @@ from django.urls import reverse_lazy
from django.shortcuts import get_object_or_404
from django.contrib import messages
from django.db.models import F
from django.db.models import F, Q
from django.views.generic.base import RedirectView
from django.views.generic.edit import FormView, CreateView, UpdateView
......@@ -17,12 +17,18 @@ from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.decorators import detail_route
from django_filters.rest_framework import DjangoFilterBackend
from note_kfet.utils import to_bool
from note_kfet.droits import D, Acl
from note_kfet.views.mixins import NoteMixin
from note_kfet.views.decorators import requires
from consos.models import Note, Transaction, Bouton
from consos.forms import BoutonConsoForm, CreditConsoForm, RetraitConsoForm, TransfertConsoForm
from consos.serializers import NoteRechercheSerializer, NoteSerializer
from consos.serializers import (
NoteRechercheSerializer, NoteSerializer, BoutonSerializer, TransactionSerializer,
)
####################################################################################################
## Vues de l'interface Web ##
......@@ -309,6 +315,8 @@ class NoteViewSet(viewsets.GenericViewSet):
"""
queryset = Note.objects.all()
serializer_class = NoteSerializer
#filter_backends = (DjangoFilterBackend,)
#filterset_fields = ['aliases']
def list(self, request):
"""
......@@ -339,7 +347,11 @@ class NoteViewSet(viewsets.GenericViewSet):
note_qs = self.get_queryset().filter(**lookup_args)
alias_class = ContentType.objects.get(model="alias").model_class()
qs = alias_class.objects.filter(alias__iregex="^%s" % search, proprietaire__note__in=note_qs).order_by('alias')
qs = (
alias_class.objects
.filter(alias__iregex="^%s" % search, proprietaire__note__in=note_qs)
.order_by('alias')
)
serializer = NoteRechercheSerializer(qs, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
......@@ -353,7 +365,8 @@ class NoteViewSet(viewsets.GenericViewSet):
if not request.user.has_perm("comptes.adherent_detail", Acl.LIMITE):
return Response({}, status=status.HTTP_403_FORBIDDEN)
if (request.user.pk != pk
note = self.get_object()
if (request.user != note.prorietaire
and not request.user.has_perm("comptes.adherent_detail", Acl.BASIQUE)):
return Response(
{
......@@ -362,7 +375,6 @@ class NoteViewSet(viewsets.GenericViewSet):
status=status.HTTP_403_FORBIDDEN,
)
note = self.get_object()
serializer = self.get_serializer(note)
return Response(serializer.data, status=status.HTTP_200_OK)
......@@ -379,7 +391,12 @@ class NoteViewSet(viewsets.GenericViewSet):
adh_id = request.data.get('pk', None)
if adh_id is None:
return Response({"detail" : "Identifiant de l'adhérent manquant"}, status=status.HTTP_400_BAD_REQUEST)
return Response(
{
"detail" : "Identifiant de l'adhérent manquant",
},
status=status.HTTP_400_BAD_REQUEST,
)
adh_class = ContentType.objects.get(model="adherent").model_class()
if get_object_or_404(adh_class, id=adh_id).type == adh_class.DEBIT:
......@@ -391,7 +408,12 @@ class NoteViewSet(viewsets.GenericViewSet):
)
_, created = Note.objects.get_or_create(adherent_id=adh_id)
if not created:
return Response({"detail" : "L'adhérent dispose déjà d'une note"}, status=status.HTTP_304_NOT_MODIFIED)
return Response(
{
"detail" : "L'adhérent dispose déjà d'une note",
},
status=status.HTTP_304_NOT_MODIFIED,
)
else:
return Response({}, status=status.HTTP_201_CREATED)
......@@ -408,9 +430,19 @@ class NoteViewSet(viewsets.GenericViewSet):
protect = request.data.get('protect', None)
if protect is None:
return Response({"detail" : "Paramètre 'protect' manquant"}, status=status.HTTP_400_BAD_REQUEST)
return Response(
{
"detail" : "Paramètre 'protect' manquant",
},
status=status.HTTP_400_BAD_REQUEST,
)
elif protect not in ['true', 'false']:
return Response({"detail" : "Paramètre 'protect' invalide"}, status=status.HTTP_400_BAD_REQUEST)
return Response(
{
"detail" : "Paramètre 'protect' invalide",
},
status=status.HTTP_400_BAD_REQUEST,
)
if protect == 'true':
data = {'soft_lock' : True}
......@@ -419,8 +451,14 @@ class NoteViewSet(viewsets.GenericViewSet):
note = self.get_object()
serializer = self.get_serializer(note, data=data, partial=True)
if note.adherent != request.user and not request.user.has_perm("consos.note_soft_lock", Acl.TOTAL):
return Response({"detail" : "Vous ne pouvez protéger que vôtre propre note"}, status=status.HTTP_403_FORBIDDEN)
if (note.adherent != request.user
and not request.user.has_perm("consos.note_soft_lock", Acl.TOTAL)):
return Response(
{
"detail" : "Vous ne pouvez protéger que vôtre propre note",
},
status=status.HTTP_403_FORBIDDEN,
)
serializer.save()
return Response({}, status=status.HTTP_200_OK)
......@@ -429,7 +467,8 @@ class NoteViewSet(viewsets.GenericViewSet):
def block(self, request, pk=None):
"""
Bloque une note, i.e. empêche que la note ne puisse être utilisée.
Le blocage est posé par un membre de l'association et ne peut être retiré par d'adhérent.
Le blocage est posé par un membre de l'association et ne peut être retiré
par l'adhérent.
Les données doivent :
- être envoyées via une requête PATCH
- contenir un paramètre 'block' pouvant valoir 'true' ou 'false'
......@@ -439,9 +478,19 @@ class NoteViewSet(viewsets.GenericViewSet):
block = request.data.get('block', None)
if block is None:
return Response({"detail" : "Paramètre 'block' manquant"}, status=status.HTTP_400_BAD_REQUEST)
return Response(
{
"detail" : "Paramètre 'block' manquant",
},
status=status.HTTP_400_BAD_REQUEST,
)
elif block not in ['true', 'false']:
return Response({"detail" : "Paramètre 'block' invalide"}, status=status.HTTP_400_BAD_REQUEST)
return Response(
{
"detail" : "Paramètre 'block' invalide",
},
status=status.HTTP_400_BAD_REQUEST,
)
if block == 'true':
data = {'hard_lock' : True}
......@@ -450,8 +499,188 @@ class NoteViewSet(viewsets.GenericViewSet):
note = self.get_object()
serializer = self.get_serializer(note, data=data, partial=True)
if note.adherent.type != note.adherent.PERSONNE and not request.user.has_perm("consos.note_hard_lock", Acl.TOTAL):
return Response({"detail" : "Vous ne pouvez bloquer que les adhérents de type personne"}, status=status.HTTP_403_FORBIDDEN)
if (note.adherent.type != note.adherent.PERSONNE
and not request.user.has_perm("consos.note_hard_lock", Acl.TOTAL)):
return Response(
{
"detail" : "Vous ne pouvez bloquer que les adhérents de type personne",
},
status=status.HTTP_403_FORBIDDEN,
)
serializer.save()
return Response({}, status=status.HTTP_200_OK)
class BoutonViewSet(viewsets.GenericViewSet):
"""
Ensemble de vues pour la gestion des boutons
"""
queryset = Bouton.objects.all()
serializer_class = BoutonSerializer
filter_backends = (DjangoFilterBackend,)
filterset_fields = ('categorie', 'actif',)
def list(self, request):
"""
Renvoie la liste des boutons disponibles dans la base de données
Les données doivent :
- être envoyées via une requête GET
"""
if not request.user.has_perm(
D("consos.bouton_ajouter", Acl.LIMITE)
| D("consos.bouton_modifier", Acl.LIMITE)
| D("consos.bouton_supprimer", Acl.LIMITE)
| D("consos.bouton_desactiver", Acl.LIMITE)
| D("consos.transaction_effectuer", Acl.TOTAL)):
return Response({}, status=status.HTTP_403_FORBIDDEN)
if not request.user.has_perm(
D("consos.bouton_ajouter", Acl.BASIQUE)
| D("consos.bouton_modifier", Acl.BASIQUE)
| D("consos.bouton_supprimer", Acl.BASIQUE)
| D("consos.bouton_desactiver", Acl.BASIQUE)
| D("consos.transaction_effectuer", Acl.TOTAL)):
# L'utilisateur ne peut que consulter les boutons liés à sa note
qs = self.get_queryset().filter(credite=request.user)
else:
qs = self.get_queryset()
qs = self.filter_queryset(qs).order_by('categorie', 'etiquette')
serializer = self.get_serializer(qs, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
def create(self, request):
"""
Ajoute un nouveau bouton dans la base de données
Les données doivent :
- être envoyées via une requête POST
"""
if not request.user.has_perm("consos.bouton_ajouter"):
return Response({}, status=status.HTTP_403_FORBIDDEN)
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
note_id = serializer.validated_data['credite']
if note_id is None and not request.user.has_perm("consos.bouton_ajouter", Acl.BASIQUE):
# Le bouton devrait pointer vers l'association, mais
# l'utilisateur n'a pas le droit qu'il faut
return Response(
{
"detail" : "Vous n'avez pas le droit de lier un bouton à "
"une autre note que la vôtre",
},
status=status.HTTP_403_FORBIDDEN,
)
elif note_id is None:
# Le bouton pointera vers l'association
pass
else:
# Le bouton pointe vers une autre note
if not Note.objects.filter(pk=note_id).exists():
return Response({"detail" : "Note cible inexistante"}, status=status.HTTP_400_BAD_REQUEST)
note = Note.objects.get(pk=note_id)
if note.proprietaire != request.user and not request.user.has_perm("consos.bouton_ajouter", Acl.BASIQUE):
return Response({"detail" : "Vous n'avez pas le droit de lier un bouton à une autre note que la vôtre"}, status=status.HTTP_403_FORBIDDEN)
if note.type not in [note.proprietaire.CLUB, note.proprietaire.SECTION] and not request.user.has_perm("consos.bouton_ajouter", Acl.TOTAL):
return Response({"detail" : "Vous n'avez pas le droit de lier un bouton à autre chose qu'un club ou une section"}, status=status.HTTP_403_FORBIDDEN)
serializer.save()
return Response({}, status=status.HTTP_201_CREATED)
def partial_update(self, request, pk=None):
"""
Modifie un bouton existant
"""
if not request.user.has_perm("consos.bouton_modifier"):
return Response({}, status=status.HTTP_403_FORBIDDEN)
bouton = self.get_object()
serializer = self.get_serializer(bouton, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
if bouton.credite.pk != serializer.validated_data['credite'] and not request.user.has_perm("consos.bouton_modifier", Acl.TOTAL):
return Response({"detail" : "Vous n'avez pas le droit de changer la note liée à un bouton"}, status=status.HTTP_403_FORBIDDEN)
if bouton.credite != request.user and not request.user.has_perm("consos.bouton_modifier", Acl.BASIQUE):
return Response({"detail" : "Vous ne pouvez modifier que les boutons liés à vôtre note"}, status=status.HTTP_403_FORBIDDEN)
serializer.save()
@detail_route(methods=['patch'])
def activate(self, request, pk=None):
"""
Active ou désactive un bouton
"""
if not request.user.has_perm("consos.bouton_activer"):
return Response({},status=status.HTTP_403_FORBIDDEN)
activate = to_bool(request.query_params.get('activate', None))
if activate is None:
return Response({"detail" : "Paramètre 'activate' incorrect"}, status=status.HTTP_400_BAD_REQUEST)
bouton = self.get_object()
bouton.actif = activate
bouton.save()
return Response({}, status=status.HTTP_200_OK)
def destroy(self, request, pk=None):
"""
Supprime un bouton existant
"""
if not request.user.has_perm("consos.bouton_supprimer"):
return Response({}, status=status.HTTP_403_FORBIDDEN)
bouton = self.get_object()
if bouton.credite != request.user and not request.user.has_perm("consos.bouton_supprimer", Acl.BASIQUE):
return Response({"detail" : "Vous ne pouvez supprimer que des boutons liés à vôtre note"}, status=status.HTTP_403_FORBIDDEN)
bouton.delete()
return Response({}, status=status.HTTP_204_NO_CONTENT)
class TransactionViewSet(viewsets.GenericViewSet):
"""
Ensemble de vues pour la gestion des transactions
"""
queryset = Transaction.objects.all()
serializer_class = TransactionSerializer
filter_backends = (DjangoFilterBackend,)
filterset_fields = ('id', 'valide',)
def list(self, request):
"""
Renvoie la liste des transactions existantes
"""
if not request.user.has_perm("consos.transaction_effectuer"):
return Response({}, status=status.HTTP_403_FORBIDDEN)
qs = self.get_queryset()
if not request.user.has_perm("consos.transaction_effectuer", Acl.TOTAL):
qs = qs.filter(Q(emetteur=request.user) | Q(destinataire=request.user))
qs = self.filter_queryset(qs).order_by('-date')
serializer = self.get_serializer(qs, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
def create(self, request):
"""
Ajoute une nouvelle transaction dans la base de données
"""
if not request.user.has_perm("consos.transaction_effectuer"):
return Response({}, status=status.HTTP_403_FORBIDDEN)
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
if serializer.emetteur != request.user.pk and not request.user.has_perm("consos.transaction_effectuer", Acl.TOTAL):
return Response({"detail" : "Vous ne pouvez faire que des transactions depuis vôtre note"}, status=status.HTTP_403_FORBIDDEN)
serializer.save()
return Response({}, status=status.HTTP_201_CREATED)
@detail_route(methods=['patch'])
def valide(self, request, pk=None):
"""
Valide/dévalide une transaction
"""
if not request.user.has_perm("consos.transaction_devalider"):
return Response({}, status=status.HTTP_403_FORBIDDEN)
valide = to_bool(request.query_params.get('valide', None))
if valide is None:
return Response({"detail" : "Paramètre 'valide' manquant"}, status=status.HTTP_400_BAD_REQUEST)
transaction = self.get_object()
transaction.valide = valide
transaction.save()
return Response({}, status=status.HTTP_200_OK)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment