Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
BDE
Note Kfet 2018
Commits
a466caf5
Commit
a466caf5
authored
Aug 26, 2018
by
Hamza Dely
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[consos] Amélioration de l'API
parent
c2bf132d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
73 additions
and
113 deletions
+73
-113
consos/models.py
consos/models.py
+4
-1
consos/serializers.py
consos/serializers.py
+16
-14
consos/views.py
consos/views.py
+53
-98
No files found.
consos/models.py
View file @
a466caf5
...
...
@@ -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
(
...
...
consos/serializers.py
View file @
a466caf5
...
...
@@ -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
=
[
'a
dherent'
]
read_only_fields
=
[
'a
lias'
,
'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
:
...
...
consos/views.py
View file @
a466caf5
...
...
@@ -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 =
['
alias
es']
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 '
b
lock' 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
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment