gestioCOF/kfet/forms.py
2017-10-26 14:07:45 +02:00

526 lines
17 KiB
Python

from datetime import timedelta
from decimal import Decimal
from djconfig.forms import ConfigForm
from django import forms
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.forms import modelformset_factory
from django.utils import timezone
from gestion.models import Profile
from .auth.forms import UserGroupForm # noqa
from .models import (
Account, Checkout, Article, OperationGroup, Operation,
CheckoutStatement, ArticleCategory, AccountNegative, Transfer,
Supplier, TransferGroup
)
# -----
# Widgets
# -----
class DateTimeWidget(forms.DateTimeInput):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.attrs['format'] = '%Y-%m-%d %H:%M'
class Media:
css = {
'all': ('kfet/css/bootstrap-datetimepicker.min.css',)
}
js = ('kfet/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', 'is_frozen']
widgets = {
'trigramme': forms.TextInput(attrs={'autocomplete': 'off'}),
}
class AccountBalanceForm(forms.ModelForm):
class Meta:
model = Account
fields = ['balance']
class AccountTriForm(AccountForm):
def clean_trigramme(self):
trigramme = self.cleaned_data['trigramme']
return trigramme.upper()
class Meta(AccountForm.Meta):
fields = ['trigramme']
class AccountNoTriForm(AccountForm):
class Meta(AccountForm.Meta):
exclude = ['trigramme']
class AccountRestrictForm(AccountForm):
class Meta(AccountForm.Meta):
fields = ['is_frozen']
class AccountPwdForm(forms.Form):
pwd1 = forms.CharField(
label="Mot de passe K-Fêt",
help_text="Le mot de passe doit contenir au moins huit caractères",
widget=forms.PasswordInput)
pwd2 = forms.CharField(
label="Confirmer le mot de passe",
widget=forms.PasswordInput)
def clean(self):
pwd1 = self.cleaned_data.get('pwd1', '')
pwd2 = self.cleaned_data.get('pwd2', '')
if len(pwd1) < 8:
raise ValidationError("Mot de passe trop court")
if pwd1 != pwd2:
raise ValidationError("Les mots de passes sont différents")
super(AccountPwdForm, self).clean()
class ProfileForm(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 = Profile
# XXX. I am removing is_cof from here.
fields = ['login_clipper', 'departement']
class ProfileRestrictForm(ProfileForm):
class Meta(ProfileForm.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 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 CheckoutStatementCreateForm(forms.ModelForm):
balance_001 = forms.IntegerField(min_value=0, initial=0, required=False)
balance_002 = forms.IntegerField(min_value=0, initial=0, required=False)
balance_005 = forms.IntegerField(min_value=0, initial=0, required=False)
balance_01 = forms.IntegerField(min_value=0, initial=0, required=False)
balance_02 = forms.IntegerField(min_value=0, initial=0, required=False)
balance_05 = forms.IntegerField(min_value=0, initial=0, required=False)
balance_1 = forms.IntegerField(min_value=0, initial=0, required=False)
balance_2 = forms.IntegerField(min_value=0, initial=0, required=False)
balance_5 = forms.IntegerField(min_value=0, initial=0, required=False)
balance_10 = forms.IntegerField(min_value=0, initial=0, required=False)
balance_20 = forms.IntegerField(min_value=0, initial=0, required=False)
balance_50 = forms.IntegerField(min_value=0, initial=0, required=False)
balance_100 = forms.IntegerField(min_value=0, initial=0, required=False)
balance_200 = forms.IntegerField(min_value=0, initial=0, required=False)
balance_500 = forms.IntegerField(min_value=0, initial=0, required=False)
class Meta:
model = CheckoutStatement
exclude = ['by', 'at', 'checkout', 'amount_error', 'amount_taken',
'balance_old', 'balance_new']
def clean(self):
not_count = self.cleaned_data['not_count']
if not not_count and (
self.cleaned_data['balance_001'] is None
or self.cleaned_data['balance_002'] is None
or self.cleaned_data['balance_005'] is None
or self.cleaned_data['balance_01'] is None
or self.cleaned_data['balance_02'] is None
or self.cleaned_data['balance_05'] is None
or self.cleaned_data['balance_1'] is None
or self.cleaned_data['balance_2'] is None
or self.cleaned_data['balance_5'] is None
or self.cleaned_data['balance_10'] is None
or self.cleaned_data['balance_20'] is None
or self.cleaned_data['balance_50'] is None
or self.cleaned_data['balance_100'] is None
or self.cleaned_data['balance_200'] is None
or self.cleaned_data['balance_500'] is None):
raise ValidationError("Y'a un problème. Si tu comptes la caisse, mets au moins des 0 stp (et t'as pas idée de comment c'est long de vérifier que t'as mis des valeurs de partout...)")
super(CheckoutStatementCreateForm, self).clean()
class CheckoutStatementUpdateForm(forms.ModelForm):
class Meta:
model = CheckoutStatement
exclude = ['by', 'at', 'checkout', 'amount_error', 'amount_taken']
# -----
# Category
# -----
class CategoryForm(forms.ModelForm):
class Meta:
model = ArticleCategory
fields = ['name', 'has_addcost']
# -----
# Article forms
# -----
class ArticleForm(forms.ModelForm):
category_new = forms.CharField(
label="Créer une catégorie",
max_length=45,
required = False)
category = forms.ModelChoiceField(
label="Catégorie",
queryset = ArticleCategory.objects.all(),
required = False)
suppliers = forms.ModelMultipleChoiceField(
label="Fournisseurs",
queryset = Supplier.objects.all(),
required = False)
supplier_new = forms.CharField(
label="Créer un fournisseur",
max_length = 45,
required = False)
def __init__(self, *args, **kwargs):
super(ArticleForm, self).__init__(*args, **kwargs)
if self.instance.pk:
self.initial['suppliers'] = self.instance.suppliers.values_list('pk', flat=True)
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', 'hidden', 'price', 'stock', 'category', 'box_type',
'box_capacity']
class ArticleRestrictForm(ArticleForm):
class Meta(ArticleForm.Meta):
fields = ['name', 'is_sold', 'hidden', 'price', 'category', 'box_type',
'box_capacity']
# -----
# 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())
on_acc = forms.ModelChoiceField(
queryset = Account.objects.exclude(trigramme='GNR'),
widget = forms.HiddenInput())
class Meta:
model = OperationGroup
fields = ['on_acc', 'checkout', 'comment']
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', 'article', 'article_nb']
widgets = {
'type': forms.HiddenInput(),
'amount': 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")
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 KFetConfigForm(ConfigForm):
kfet_reduction_cof = forms.DecimalField(
label='Réduction COF', initial=Decimal('20'),
max_digits=6, decimal_places=2,
help_text="Réduction, à donner en pourcentage, appliquée lors d'un "
"achat par un-e membre du COF sur le montant en euros.",
)
kfet_addcost_amount = forms.DecimalField(
label='Montant de la majoration (en €)', initial=Decimal('0'),
required=False,
max_digits=6, decimal_places=2,
)
kfet_addcost_for = forms.ModelChoiceField(
label='Destinataire de la majoration', initial=None, required=False,
help_text='Laissez vide pour désactiver la majoration.',
queryset=(Account.objects
.select_related('profile', 'profile__user')
.all()),
)
kfet_overdraft_duration = forms.DurationField(
label='Durée du découvert autorisé par défaut',
initial=timedelta(days=1),
)
kfet_overdraft_amount = forms.DecimalField(
label='Montant du découvert autorisé par défaut (en €)',
initial=Decimal('20'),
max_digits=6, decimal_places=2,
)
kfet_cancel_duration = forms.DurationField(
label='Durée pour annuler une commande sans mot de passe',
initial=timedelta(minutes=5),
)
class FilterHistoryForm(forms.Form):
checkouts = forms.ModelMultipleChoiceField(queryset=Checkout.objects.all())
accounts = forms.ModelMultipleChoiceField(queryset=Account.objects.all())
from_date = forms.DateTimeField(widget=DateTimeWidget)
to_date = forms.DateTimeField(widget=DateTimeWidget)
# -----
# Transfer forms
# -----
class TransferGroupForm(forms.ModelForm):
class Meta:
model = TransferGroup
fields = ['comment']
class TransferForm(forms.ModelForm):
from_acc = forms.ModelChoiceField(
queryset = Account.objects.exclude(trigramme__in=['LIQ', '#13', 'GNR']),
widget = forms.HiddenInput()
)
to_acc = forms.ModelChoiceField(
queryset = Account.objects.exclude(trigramme__in=['LIQ', '#13', 'GNR']),
widget = forms.HiddenInput()
)
def clean_amount(self):
amount = self.cleaned_data['amount']
if amount <= 0:
raise forms.ValidationError("Montant invalide")
return amount
class Meta:
model = Transfer
fields = ['from_acc', 'to_acc', 'amount']
TransferFormSet = modelformset_factory(
Transfer,
form = TransferForm,
min_num = 1, validate_min = True,
extra = 9,
)
# -----
# Inventory forms
# -----
class InventoryArticleForm(forms.Form):
article = forms.ModelChoiceField(
queryset = Article.objects.all(),
widget = forms.HiddenInput(),
)
stock_new = forms.IntegerField(required=False)
def __init__(self, *args, **kwargs):
super(InventoryArticleForm, self).__init__(*args, **kwargs)
if 'initial' in kwargs:
self.name = kwargs['initial']['name']
self.stock_old = kwargs['initial']['stock_old']
self.category = kwargs['initial']['category']
self.category_name = kwargs['initial']['category__name']
self.box_capacity = kwargs['initial']['box_capacity']
# -----
# Order forms
# -----
class OrderArticleForm(forms.Form):
article = forms.ModelChoiceField(
queryset=Article.objects.all(),
widget=forms.HiddenInput(),
)
quantity_ordered = forms.IntegerField(required=False)
def __init__(self, *args, **kwargs):
super(OrderArticleForm, self).__init__(*args, **kwargs)
if 'initial' in kwargs:
self.name = kwargs['initial']['name']
self.stock = kwargs['initial']['stock']
self.category = kwargs['initial']['category']
self.category_name = kwargs['initial']['category__name']
self.box_capacity = kwargs['initial']['box_capacity']
self.v_all = kwargs['initial']['v_all']
self.v_moy = kwargs['initial']['v_moy']
self.v_et = kwargs['initial']['v_et']
self.v_prev = kwargs['initial']['v_prev']
self.c_rec = kwargs['initial']['c_rec']
class OrderArticleToInventoryForm(forms.Form):
article = forms.ModelChoiceField(
queryset = Article.objects.all(),
widget = forms.HiddenInput(),
)
price_HT = forms.DecimalField(
max_digits = 7, decimal_places = 4,
required = False)
TVA = forms.DecimalField(
max_digits = 7, decimal_places = 2,
required = False)
rights = forms.DecimalField(
max_digits = 7, decimal_places = 4,
required = False)
quantity_received = forms.IntegerField()
def __init__(self, *args, **kwargs):
super(OrderArticleToInventoryForm, self).__init__(*args, **kwargs)
if 'initial' in kwargs:
self.name = kwargs['initial']['name']
self.category = kwargs['initial']['category']
self.category_name = kwargs['initial']['category__name']
self.quantity_ordered = kwargs['initial']['quantity_ordered']