gestioCOF/kfet/forms.py
Aurélien Delobelle e89f8fd6a5 Gestion négatif d'un compte
- 3 paramètres ajustables : date jusqu'à, montant max, décalage de
  balance
2016-08-22 20:07:01 +02:00

301 lines
9.8 KiB
Python

from decimal import Decimal
from django import forms
from django.core.exceptions import ValidationError
from django.contrib.auth.models import User, Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.contrib.admin.widgets import FilteredSelectMultiple
from django.forms import modelformset_factory
from django.utils import timezone
from kfet.models import (Account, Checkout, Article, OperationGroup, Operation,
CheckoutStatement, ArticleCategory, Settings, AccountNegative)
from gestioncof.models import CofProfile
# -----
# Widgets
# -----
class DateTimeWidget(forms.DateTimeInput):
def __init__(self, attrs = None):
super(DateTimeWidget, self).__init__(attrs)
self.attrs['format'] = '%Y-%m-%d %H:%M'
class Media:
css = {
'all': ('bootstrap-datetimepicker.min.css',)
}
js = (
'moment.js',
'moment-fr.js',
'bootstrap-datetimepicker.min.js',
)
# -----
# Account forms
# -----
class AccountForm(forms.ModelForm):
# Surcharge pour passer data à Account.save()
def save(self, data = {}, *args, **kwargs):
obj = super(AccountForm, self).save(commit = False, *args, **kwargs)
obj.save(data = data)
return obj
class Meta:
model = Account
fields = ['trigramme', 'promo', 'nickname']
widgets = {
'trigramme': forms.TextInput(attrs={'autocomplete': 'off'}),
}
class AccountTriForm(AccountForm):
class Meta(AccountForm.Meta):
fields = ['trigramme']
class AccountNoTriForm(AccountForm):
class Meta(AccountForm.Meta):
exclude = ['trigramme']
class AccountRestrictForm(AccountForm):
class Meta(AccountForm.Meta):
fields = ['promo']
class CofForm(forms.ModelForm):
def clean_is_cof(self):
instance = getattr(self, 'instance', None)
if instance and instance.pk:
return instance.is_cof
else:
return False
class Meta:
model = CofProfile
fields = ['login_clipper', 'is_cof', 'departement']
class CofRestrictForm(CofForm):
class Meta(CofForm.Meta):
fields = ['departement']
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ['username', 'first_name', 'last_name', 'email']
help_texts = {
'username': ''
}
class UserRestrictForm(UserForm):
class Meta(UserForm.Meta):
fields = ['first_name', 'last_name']
class UserRestrictTeamForm(UserForm):
class Meta(UserForm.Meta):
fields = ['first_name', 'last_name', 'email']
class UserGroupForm(forms.ModelForm):
groups = forms.ModelMultipleChoiceField(
Group.objects.filter(name__icontains='K-Fêt'))
class Meta:
model = User
fields = ['groups']
class GroupForm(forms.ModelForm):
permissions = forms.ModelMultipleChoiceField(
queryset= Permission.objects.filter(content_type__in=
ContentType.objects.filter(app_label='kfet')))
class Meta:
model = Group
fields = ['name', 'permissions']
class AccountNegativeForm(forms.ModelForm):
class Meta:
model = AccountNegative
fields = ['authz_overdraft_amount', 'authz_overdraft_until',
'balance_offset', 'comment']
widgets = {
'authz_overdraft_until': DateTimeWidget(),
}
# -----
# Checkout forms
# -----
class CheckoutForm(forms.ModelForm):
class Meta:
model = Checkout
fields = ['name', 'valid_from', 'valid_to', 'balance', 'is_protected']
widgets = {
'valid_from': DateTimeWidget(),
'valid_to' : DateTimeWidget(),
}
class CheckoutRestrictForm(CheckoutForm):
class Meta(CheckoutForm.Meta):
fields = ['name', 'valid_from', 'valid_to']
class CheckoutStatementForm(forms.ModelForm):
class Meta:
model = CheckoutStatement
fields = ['balance_new', 'amount_taken']
# -----
# Article forms
# -----
class ArticleForm(forms.ModelForm):
category_new = forms.CharField(
max_length=45,
required = False)
category = forms.ModelChoiceField(
queryset = ArticleCategory.objects.all(),
required = False)
def clean(self):
category = self.cleaned_data.get('category')
category_new = self.cleaned_data.get('category_new')
if not category and not category_new:
raise ValidationError('Sélectionnez une catégorie ou créez en une')
elif not category:
category, _ = ArticleCategory.objects.get_or_create(name=category_new)
self.cleaned_data['category'] = category
super(ArticleForm, self).clean()
class Meta:
model = Article
fields = ['name', 'is_sold', 'price', 'stock', 'category']
class ArticleRestrictForm(ArticleForm):
class Meta(ArticleForm.Meta):
fields = ['name', 'is_sold', 'price', 'category']
# -----
# K-Psul forms
# -----
class KPsulOperationGroupForm(forms.ModelForm):
checkout = forms.ModelChoiceField(
queryset = Checkout.objects.filter(
is_protected=False, valid_from__lte=timezone.now(),
valid_to__gte=timezone.now()),
widget = forms.HiddenInput())
class Meta:
model = OperationGroup
fields = ['on_acc', 'checkout']
widgets = {
'on_acc' : forms.HiddenInput(),
}
class KPsulAccountForm(forms.ModelForm):
class Meta:
model = Account
fields = ['trigramme']
widgets = {
'trigramme': forms.TextInput(
attrs={
'autocomplete': 'off',
'spellcheck': 'false',
}),
}
class KPsulCheckoutForm(forms.Form):
checkout = forms.ModelChoiceField(
queryset=Checkout.objects.filter(
is_protected=False, valid_from__lte=timezone.now(),
valid_to__gte=timezone.now()),
widget=forms.Select(attrs={'id':'id_checkout_select'}))
class KPsulOperationForm(forms.ModelForm):
article = forms.ModelChoiceField(
queryset=Article.objects.select_related('category').all(),
required=False,
widget = forms.HiddenInput())
class Meta:
model = Operation
fields = ['type', 'amount', 'is_checkout', 'article', 'article_nb']
widgets = {
'type': forms.HiddenInput(),
'amount': forms.HiddenInput(),
'is_checkout': forms.HiddenInput(),
'article_nb': forms.HiddenInput(),
}
def clean(self):
super(KPsulOperationForm, self).clean()
type_ope = self.cleaned_data.get('type')
amount = self.cleaned_data.get('amount')
article = self.cleaned_data.get('article')
article_nb = self.cleaned_data.get('article_nb')
if type_ope and type_ope == Operation.PURCHASE:
if not article or not article_nb:
raise ValidationError(
"Un achat nécessite un article et une quantité")
if article_nb < 1:
raise ValidationError("Impossible d'acheter moins de 1 article")
self.cleaned_data['is_checkout'] = True
elif type_ope and type_ope in [Operation.DEPOSIT, Operation.WITHDRAW]:
if not amount or article or article_nb:
raise ValidationError("Bad request")
if type_ope == Operation.DEPOSIT and amount <= 0:
raise ValidationError("Charge non positive")
if type_ope == Operation.WITHDRAW and amount >= 0:
raise ValidationError("Retrait non négatif")
self.cleaned_data['article'] = None
self.cleaned_data['article_nb'] = None
KPsulOperationFormSet = modelformset_factory(
Operation,
form = KPsulOperationForm,
can_delete = True,
extra = 0,
min_num = 1, validate_min = True)
class AddcostForm(forms.Form):
trigramme = forms.CharField(required = False)
amount = forms.DecimalField(
required = False,
max_digits=6,decimal_places=2,min_value=Decimal(0))
def clean(self):
trigramme = self.cleaned_data.get('trigramme')
if trigramme:
try:
Account.objects.get(trigramme=trigramme)
except Account.DoesNotExist:
raise ValidationError('Compte invalide')
else:
self.cleaned_data['amount'] = 0
super(AddcostForm, self).clean()
# -----
# Settings forms
# -----
class SettingsForm(forms.ModelForm):
class Meta:
model = Settings
fields = ['value_decimal', 'value_account', 'value_duration']
def clean(self):
name = self.instance.name
value_decimal = self.cleaned_data.get('value_decimal')
value_account = self.cleaned_data.get('value_account')
value_duration = self.cleaned_data.get('value_duration')
type_decimal = ['SUBVENTION_COF', 'ADDCOST_AMOUNT', 'OVERDRAFT_AMOUNT']
type_account = ['ADDCOST_FOR']
type_duration = ['OVERDRAFT_DURATION', 'CANCEL_DURATION']
self.cleaned_data['name'] = name
if name in type_decimal:
if not value_decimal:
raise ValidationError('Renseignez une valeur décimale')
self.cleaned_data['value_account'] = None
self.cleaned_data['value_duration'] = None
elif name in type_account:
self.cleaned_data['value_decimal'] = None
self.cleaned_data['value_duration'] = None
elif name in type_duration:
if not value_duration:
raise ValidationError('Renseignez une durée')
self.cleaned_data['value_decimal'] = None
self.cleaned_data['value_account'] = None
cache.delete(name)
super(SettingsForm, self).clean()