8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-11-27 07:02:26 +00:00

Utilisation de django field permission sur le controle facture

This commit is contained in:
Gabriel Detraz 2017-12-28 02:08:02 +01:00 committed by root
parent da382fbeb6
commit 784ef5d598
4 changed files with 107 additions and 23 deletions

View file

@ -43,6 +43,8 @@ from django.forms import ModelForm, Form
from django.core.validators import MinValueValidator
from .models import Article, Paiement, Facture, Banque
from re2o.field_permissions import FieldPermissionFormMixin
class NewFactureForm(ModelForm):
"""Creation d'une facture, moyen de paiement, banque et numero
@ -141,27 +143,18 @@ class NewFactureFormPdf(Form):
)
class EditFactureForm(NewFactureForm):
class EditFactureForm(FieldPermissionFormMixin, NewFactureForm):
"""Edition d'une facture : moyen de paiement, banque, user parent"""
class Meta(NewFactureForm.Meta):
fields = ['paiement', 'banque', 'cheque', 'user']
model = Facture
fields = '__all__'
def __init__(self, *args, **kwargs):
super(EditFactureForm, self).__init__(*args, **kwargs)
self.fields['user'].label = 'Adherent'
self.fields['user'].empty_label = "Séléctionner\
l'adhérent propriétaire"
class TrezEditFactureForm(EditFactureForm):
"""Vue pour édition controle trésorier"""
class Meta(EditFactureForm.Meta):
fields = '__all__'
def __init__(self, *args, **kwargs):
super(TrezEditFactureForm, self).__init__(*args, **kwargs)
self.fields['valid'].label = 'Validité de la facture'
self.fields['control'].label = 'Contrôle de la facture'
class ArticleForm(ModelForm):

View file

@ -56,8 +56,10 @@ from django.db.models import Max
from django.utils import timezone
from machines.models import regen
from re2o.field_permissions import FieldPermissionModelMixin
class Facture(models.Model):
class Facture(FieldPermissionModelMixin, models.Model):
""" Définition du modèle des factures. Une facture regroupe une ou
plusieurs ventes, rattachée à un user, et reliée à un moyen de paiement
et si il y a lieu un numero pour les chèques. Possède les valeurs
@ -76,6 +78,9 @@ class Facture(models.Model):
valid = models.BooleanField(default=True)
control = models.BooleanField(default=False)
class Meta:
abstract = False
def prix(self):
"""Renvoie le prix brut sans les quantités. Méthode
dépréciée"""
@ -144,12 +149,16 @@ class Facture(models.Model):
else:
return True, None
def can_change_control(user_request, *args, **kwargs):
return user_request.has_perms(('tresorier',)), "Vous ne pouvez pas éditer le controle sans droit trésorier"
def can_change_control(user, *args, **kwargs):
return user.has_perms(('tresorier',)), "Vous ne pouvez pas éditer le controle sans droit trésorier"
def can_change_pdf(user_request, *args, **kwargs):
return user_request.has_perms(('tresorier',)), "Vous ne pouvez pas éditer une facture sans droit trésorier"
field_permissions = {
'control': can_change_control,
}
def __str__(self):
return str(self.user) + ' ' + str(self.date)

View file

@ -57,7 +57,6 @@ from preferences.models import OptionalUser, AssoOption, GeneralOption
from .models import Facture, Article, Vente, Paiement, Banque
from .forms import (
NewFactureForm,
TrezEditFactureForm,
EditFactureForm,
ArticleForm,
DelArticleForm,
@ -73,6 +72,7 @@ from .forms import (
from .tex import render_invoice
@login_required
@can_create(Facture)
@can_edit(User)
@ -243,13 +243,7 @@ def edit_facture(request, facture, factureid):
"""Permet l'édition d'une facture. On peut y éditer les ventes
déjà effectuer, ou rendre une facture invalide (non payées, chèque
en bois etc). Mets à jour les durée de cotisation attenantes"""
if request.user.has_perms(['tresorier']):
facture_form = TrezEditFactureForm(
request.POST or None,
instance=facture
)
else:
facture_form = EditFactureForm(request.POST or None, instance=facture)
facture_form = EditFactureForm(request.POST or None, instance=facture, user=request.user)
ventes_objects = Vente.objects.filter(facture=facture)
vente_form_set = modelformset_factory(
Vente,

88
re2o/field_permissions.py Normal file
View file

@ -0,0 +1,88 @@
from django.db import models
from django import forms
from functools import partial
class FieldPermissionModelMixin:
field_permissions = {} # {'field_name': callable}
FIELD_PERM_CODENAME = 'can_change_{model}_{name}'
FIELD_PERMISSION_GETTER = 'can_change_{name}'
FIELD_PERMISSION_MISSING_DEFAULT = True
class Meta:
abstract = True
def has_perm(self, user, perm):
return user.has_perm(perm) # Never give 'obj' argument here
def has_field_perm(self, user, field):
if field in self.field_permissions:
checks = self.field_permissions[field]
if not isinstance(checks, (list, tuple)):
checks = [checks]
for i, perm in enumerate(checks):
if callable(perm):
checks[i] = partial(perm, field=field)
else:
checks = []
# Consult the optional field-specific hook.
getter_name = self.FIELD_PERMISSION_GETTER.format(name=field)
if hasattr(self, getter_name):
checks.append(getattr(self, getter_name))
# Try to find a static permission for the field
else:
perm_label = self.FIELD_PERM_CODENAME.format(**{
'model': self._meta.model_name,
'name': field,
})
if perm_label in dict(self._meta.permissions):
checks.append(perm_label)
# No requirements means no restrictions.
if not len(checks):
return self.FIELD_PERMISSION_MISSING_DEFAULT
# Try to find a user setting that qualifies them for permission.
for perm in checks:
if callable(perm):
result, plop = perm(user=user)
if result is not None:
return result
else:
result = user.has_perm(perm) # Don't supply 'obj', or else infinite recursion.
if result:
return True
# If no requirement can be met, then permission is denied.
return False
class FieldPermissionModel(FieldPermissionModelMixin, models.Model):
class Meta:
abstract = True
class FieldPermissionFormMixin:
"""
ModelForm logic for removing fields when a user is found not to have change permissions.
"""
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
super(FieldPermissionFormMixin, self).__init__(*args, **kwargs)
model = self.Meta.model
model_field_names = [f.name for f in model._meta.get_fields()] # this might be too broad
for name in model_field_names:
if name in self.fields and not self.instance.has_field_perm(user, field=name):
self.remove_unauthorized_field(name)
def remove_unauthorized_field(self, name):
del self.fields[name]
class FieldPermissionForm(FieldPermissionFormMixin, forms.ModelForm):
pass