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) 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'] # ----- # 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)