Commit a466caf5 authored by Hamza Dely's avatar Hamza Dely

[consos] Amélioration de l'API

parent c2bf132d
......@@ -5,6 +5,8 @@
from datetime import timedelta
from django.db import models, transaction
from django.db.models import Q
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError
def releve_freq_validator(value):
......@@ -34,7 +36,8 @@ class Note(models.Model):
# Champs du modèle
adherent = models.OneToOneField(
'comptes.Adherent', on_delete=models.CASCADE, verbose_name="propriétaire", primary_key=True,
'comptes.Adherent', on_delete=models.CASCADE, verbose_name="propriétaire",
primary_key=True, limit_choices_to=~Q(type=get_user_model().DEBIT) & Q(supprime=False),
)
solde = models.DecimalField(max_digits=14, decimal_places=2, null=False, default=0.00)
releve_freq = models.DurationField(
......
......@@ -4,34 +4,36 @@
import itertools
from django.db.models import Q
from django.contrib.auth import get_user_model
from rest_framework import serializers
from note_kfet.serializers import mixins
from consos.models import Note, Bouton, Transaction
class NoteRechercheSerializer(serializers.Serializer):
"""
Sérialiseur spécifique au renvoi des informations de notes lors d'une recherche
de notes par alias.
"""
alias = serializers.CharField(read_only=True)
adherent_id = serializers.IntegerField(source='proprietaire.pk', read_only=True)
pseudo = serializers.CharField(source='proprietaire.pseudo', read_only=True)
solde = serializers.DecimalField(source='proprietaire.note.solde', max_digits=14, decimal_places=2, read_only=True)
UserModel = get_user_model()
class NoteSerializer(mixins.DynamicFieldsMixin, serializers.ModelSerializer):
"""
Sérialiseur pour les objets Note
"""
alias = serializers.CharField(read_only=True)
pseudo = serializers.CharField(source='adherent.pseudo', read_only=True)
class Meta:
model = Note
fields = [
'adherent', 'solde', 'releve_freq',
'dernier_releve', 'soft_lock', 'hard_lock',
'adherent', 'solde', 'releve_freq', 'dernier_releve',
'soft_lock', 'hard_lock', 'alias', 'pseudo',
]
read_only_fields = ['adherent']
read_only_fields = ['alias', 'pseudo', 'solde',]
default_empty = False
extra_kwargs = {
'adherent' : {
'queryset' : UserModel.objects.filter(~Q(type=UserModel.DEBIT) & Q(supprime=False))
},
}
class BoutonSerializer(serializers.ModelSerializer):
"""
......@@ -73,7 +75,7 @@ class TransactionSerializer(serializers.ModelSerializer):
params = {
'action' : validated_data.get('action'),
'quantite' : validated_data.get('quantite'),
'description' : validated_data.get('description'),
'description' : '(%s)' if validated_data.get('description') else "",
'valide' : validated_data.get('valide'),
}
emetteurs = []
......@@ -105,7 +107,7 @@ class TransactionSerializer(serializers.ModelSerializer):
params['moyen'] = validated_data.get('moyen')
params['montant'] = validated_data.get('montant')
params['categorie'] = "Opération de gestion"
params['description'] = "Retrait Note"
params['description'] = "Transfert %s" % params['description']
emetteurs = validated_data.get('emetteurs')
destinataires = validated_data.get('destinataires')
else:
......
......@@ -13,7 +13,7 @@ from django.views.generic.edit import FormView, CreateView, UpdateView
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.contrib.contenttypes.models import ContentType
from rest_framework import viewsets, status
from rest_framework import viewsets, status, filters
from rest_framework.response import Response
from rest_framework.decorators import detail_route
......@@ -26,9 +26,7 @@ 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, BoutonSerializer, TransactionSerializer,
)
from consos.serializers import NoteSerializer, BoutonSerializer, TransactionSerializer
####################################################################################################
## Vues de l'interface Web ##
......@@ -315,8 +313,8 @@ class NoteViewSet(viewsets.GenericViewSet):
"""
queryset = Note.objects.all()
serializer_class = NoteSerializer
#filter_backends = (DjangoFilterBackend,)
#filterset_fields = ['aliases']
filter_backends = (filters.SearchFilter,)
search_fields = ('$alias',)
def list(self, request):
"""
......@@ -329,31 +327,32 @@ class NoteViewSet(viewsets.GenericViewSet):
if not request.user.has_perm("comptes.adherent_chercher", Acl.BASIQUE):
return Response({}, status=status.HTTP_403_FORBIDDEN)
search = request.query_params.get('search', None)
if search is None:
return Response(
{
"detail" : "Paramètre 'search' absent",
},
status=status.HTTP_400_BAD_REQUEST,
)
lookup_args = {}
if not request.user.has_perm("comptes.adherent_chercher", Acl.TOTAL):
lookup_args.update(**{'adherent__supprime' : False})
if not request.user.has_perm("comptes.adherent_chercher", Acl.ETENDU):
lookup_args.update(**{'adherent__is_active' : False})
note_qs = self.get_queryset().filter(**lookup_args)
lookup_args.update(**{'adherent__is_active' : True})
note_qs = self.get_queryset().filter(**lookup_args)
alias_class = ContentType.objects.get(model="alias").model_class()
qs = (
qs = self.filter_queryset(
alias_class.objects
.filter(alias__iregex="^%s" % search, proprietaire__note__in=note_qs)
.filter(proprietaire__note__in=note_qs)
.order_by('alias')
)
serializer = NoteRechercheSerializer(qs, many=True)
qs = qs.select_related('proprietaire__note')
data = [
{
'alias' : alias.alias,
'pseudo' : alias.proprietaire.pseudo,
'solde' : alias.proprietaire.note.solde,
'adherent' : alias.proprietaire.note.adherent,
} for alias in qs
]
fields = ['adherent', 'pseudo', 'alias', 'solde']
serializer = self.get_serializer(data, fields=fields, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
def retrieve(self, request, pk=None):
......@@ -366,7 +365,7 @@ class NoteViewSet(viewsets.GenericViewSet):
return Response({}, status=status.HTTP_403_FORBIDDEN)
note = self.get_object()
if (request.user != note.prorietaire
if (request.user != note.adherent
and not request.user.has_perm("comptes.adherent_detail", Acl.BASIQUE)):
return Response(
{
......@@ -375,7 +374,8 @@ class NoteViewSet(viewsets.GenericViewSet):
status=status.HTTP_403_FORBIDDEN,
)
serializer = self.get_serializer(note)
fields = ['solde', 'releve_freq', 'dernier_releve', 'soft_lock', 'hard_lock',]
serializer = self.get_serializer(note, fields=fields)
return Response(serializer.data, status=status.HTTP_200_OK)
def create(self, request):
......@@ -389,33 +389,10 @@ class NoteViewSet(viewsets.GenericViewSet):
if not request.user.has_perm("consos.note_ouvrir", Acl.BASIQUE):
return Response({}, status=status.HTTP_403_FORBIDDEN)
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,
)
adh_class = ContentType.objects.get(model="adherent").model_class()
if get_object_or_404(adh_class, id=adh_id).type == adh_class.DEBIT:
return Response(
{
"detail" : "Impossible d'ouvrir une note pour un compte de débit",
},
status=status.HTTP_400_BAD_REQUEST,
)
_, 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,
)
else:
return Response({}, status=status.HTTP_201_CREATED)
serializer = self.get_serializer(data=request.data, fields=['adherent'])
serializer.is_valid(raise_exception=True)
serializer.save()
return Response({}, status=status.HTTP_201_CREATED)
@detail_route(methods=['patch'])
def protect(self, request, pk=None):
......@@ -423,34 +400,12 @@ class NoteViewSet(viewsets.GenericViewSet):
Protège une note, i.e. empêche qu'une transaction ne puisse être effectuée dessus
Les données doivent :
- être envoyées via une requête PATCH
- contenir un paramètre 'protect' pouvant valoir 'true' ou 'false'
- contenir un paramètre 'soft_lock' pouvant valoir 'true' ou 'false'
"""
if request.user.has_perm("consos.note_soft_lock", Acl.LIMITE):
if not request.user.has_perm("consos.note_soft_lock", Acl.LIMITE):
return Response({}, status=status.HTTP_403_FORBIDDEN)
protect = request.data.get('protect', None)
if protect is None:
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,
)
if protect == 'true':
data = {'soft_lock' : True}
else:
data = {'soft_lock' : False}
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(
......@@ -460,6 +415,17 @@ class NoteViewSet(viewsets.GenericViewSet):
status=status.HTTP_403_FORBIDDEN,
)
if 'soft_lock' not in request.data:
return Response(
{
"detail" : "Paramètre 'soft_lock' manquant",
},
status=status.HTTP_400_BAD_REQUEST,
)
fields = ['soft_lock']
serializer = self.get_serializer(note, data=request.data, partial=True, fields=fields)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response({}, status=status.HTTP_200_OK)
......@@ -471,34 +437,12 @@ class NoteViewSet(viewsets.GenericViewSet):
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'
- contenir un paramètre 'hard_lock' pouvant valoir 'true' ou 'false'
"""
if request.user.has_perm("consos.note_hard_lock", Acl.BASIQUE):
if not request.user.has_perm("consos.note_hard_lock", Acl.BASIQUE):
return Response({}, status=status.HTTP_403_FORBIDDEN)
block = request.data.get('block', None)
if block is None:
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,
)
if block == 'true':
data = {'hard_lock' : True}
else:
data = {'hard_lock' : False}
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(
......@@ -508,6 +452,17 @@ class NoteViewSet(viewsets.GenericViewSet):
status=status.HTTP_403_FORBIDDEN,
)
if 'hard_lock' not in request.data:
return Response(
{
"detail" : "Paramètre 'hard_lock' manquant",
},
status=status.HTTP_400_BAD_REQUEST,
)
fields = ['hard_lock']
serializer = self.get_serializer(note, data=request.data, partial=True, fields=fields)
serializer.is_valid(raise_exception=True)
serializer.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