mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-04 17:06:27 +00:00
Utilisation de django field permission sur le controle facture
This commit is contained in:
parent
da382fbeb6
commit
784ef5d598
4 changed files with 107 additions and 23 deletions
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
88
re2o/field_permissions.py
Normal 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
|
||||
|
Loading…
Reference in a new issue