forms.py 11.3 KB
Newer Older
lhark's avatar
lhark committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017  Gabriel Détraz
# Copyright © 2017  Goulven Kermarec
# Copyright © 2017  Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
chirac's avatar
chirac committed
22 23 24
"""
Forms de l'application cotisation de re2o. Dépendance avec les models,
importé par les views.
lhark's avatar
lhark committed
25

chirac's avatar
chirac committed
26 27 28
Permet de créer une nouvelle facture pour un user (NewFactureForm),
et de l'editer (soit l'user avec EditFactureForm,
soit le trésorier avec TrezEdit qui a plus de possibilités que self
29 30
notamment sur le controle trésorier SelectArticleForm est utilisée
lors de la creation d'une facture en
chirac's avatar
chirac committed
31 32 33 34 35 36
parrallèle de NewFacture pour le choix des articles désirés.
(la vue correspondante est unique)

ArticleForm, BanqueForm, PaiementForm permettent aux admin d'ajouter,
éditer ou supprimer une banque/moyen de paiement ou un article
"""
37 38
from __future__ import unicode_literals

39
from django import forms
40
from django.db.models import Q
Dalahro's avatar
Dalahro committed
41
from django.forms import ModelForm, Form
42
from django.core.validators import MinValueValidator,MaxValueValidator
chirac's avatar
chirac committed
43
from .models import Article, Paiement, Facture, Banque
44 45
from preferences.models import OptionalUser
from users.models import User
46

47
from re2o.field_permissions import FieldPermissionFormMixin
48
from re2o.mixins import FormRevMixin 
49

50
class NewFactureForm(FormRevMixin, ModelForm):
chirac's avatar
chirac committed
51 52
    """Creation d'une facture, moyen de paiement, banque et numero
    de cheque"""
53
    def __init__(self, *args, **kwargs):
54
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
55
        super(NewFactureForm, self).__init__(*args, prefix=prefix, **kwargs)
56 57 58 59
        self.fields['cheque'].required = False
        self.fields['banque'].required = False
        self.fields['cheque'].label = 'Numero de chèque'
        self.fields['banque'].empty_label = "Non renseigné"
chirac's avatar
chirac committed
60 61
        self.fields['paiement'].empty_label = "Séléctionner\
        un moyen de paiement"
chirac's avatar
chirac committed
62 63 64 65
        paiement_list = Paiement.objects.filter(type_paiement=1)
        if paiement_list:
            self.fields['paiement'].widget\
                .attrs['data-cheque'] = paiement_list.first().id
66 67 68

    class Meta:
        model = Facture
chirac's avatar
chirac committed
69
        fields = ['paiement', 'banque', 'cheque']
70 71

    def clean(self):
chirac's avatar
chirac committed
72
        cleaned_data = super(NewFactureForm, self).clean()
73 74 75
        paiement = cleaned_data.get("paiement")
        cheque = cleaned_data.get("cheque")
        banque = cleaned_data.get("banque")
76
        if not paiement:
chirac's avatar
chirac committed
77
            raise forms.ValidationError("Le moyen de paiement est obligatoire")
Gabriel Detraz's avatar
Gabriel Detraz committed
78
        elif paiement.type_paiement == "check" and not (cheque and banque):
chirac's avatar
chirac committed
79 80
            raise forms.ValidationError("Le numéro de chèque et\
                la banque sont obligatoires.")
81 82
        return cleaned_data

chirac's avatar
chirac committed
83

chibrac's avatar
chibrac committed
84
class CreditSoldeForm(NewFactureForm):
chirac's avatar
chirac committed
85
    """Permet de faire des opérations sur le solde si il est activé"""
chibrac's avatar
chibrac committed
86 87
    class Meta(NewFactureForm.Meta):
        model = Facture
chirac's avatar
chirac committed
88
        fields = ['paiement', 'banque', 'cheque']
chibrac's avatar
chibrac committed
89 90 91

    def __init__(self, *args, **kwargs):
        super(CreditSoldeForm, self).__init__(*args, **kwargs)
chirac's avatar
chirac committed
92 93 94
        self.fields['paiement'].queryset = Paiement.objects.exclude(
            moyen='solde'
        ).exclude(moyen="Solde")
chibrac's avatar
chibrac committed
95 96 97

    montant = forms.DecimalField(max_digits=5, decimal_places=2, required=True)

chirac's avatar
chirac committed
98

99
class SelectUserArticleForm(FormRevMixin, Form):
chirac's avatar
chirac committed
100 101
    """Selection d'un article lors de la creation d'une facture"""
    article = forms.ModelChoiceField(
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
        queryset=Article.objects.filter(Q(type_user='All') | Q(type_user='Adherent')),
        label="Article",
        required=True
    )
    quantity = forms.IntegerField(
        label="Quantité",
        validators=[MinValueValidator(1)],
        required=True
    )


class SelectClubArticleForm(Form):
    """Selection d'un article lors de la creation d'une facture"""
    article = forms.ModelChoiceField(
        queryset=Article.objects.filter(Q(type_user='All') | Q(type_user='Club')),
chirac's avatar
chirac committed
117 118 119 120 121 122 123 124 125
        label="Article",
        required=True
    )
    quantity = forms.IntegerField(
        label="Quantité",
        validators=[MinValueValidator(1)],
        required=True
    )

Dalahro's avatar
Dalahro committed
126

Dalahro's avatar
Dalahro committed
127
class NewFactureFormPdf(Form):
chirac's avatar
chirac committed
128 129 130 131 132 133 134 135 136
    """Creation d'un pdf facture par le trésorier"""
    article = forms.ModelMultipleChoiceField(
        queryset=Article.objects.all(),
        label="Article"
    )
    number = forms.IntegerField(
        label="Quantité",
        validators=[MinValueValidator(1)]
    )
Dalahro's avatar
Dalahro committed
137 138
    paid = forms.BooleanField(label="Payé", required=False)
    dest = forms.CharField(required=True, max_length=255, label="Destinataire")
Dalahro's avatar
Dalahro committed
139
    chambre = forms.CharField(required=False, max_length=10, label="Adresse")
chirac's avatar
chirac committed
140 141 142 143 144 145
    fid = forms.CharField(
        required=True,
        max_length=10,
        label="Numéro de la facture"
    )

Dalahro's avatar
Dalahro committed
146

147
class EditFactureForm(FieldPermissionFormMixin, NewFactureForm):
chirac's avatar
chirac committed
148
    """Edition d'une facture : moyen de paiement, banque, user parent"""
149
    class Meta(NewFactureForm.Meta):
150 151
        model = Facture
        fields = '__all__'
152 153 154 155

    def __init__(self, *args, **kwargs):
        super(EditFactureForm, self).__init__(*args, **kwargs)
        self.fields['user'].label = 'Adherent'
chirac's avatar
chirac committed
156 157
        self.fields['user'].empty_label = "Séléctionner\
            l'adhérent propriétaire"
158
        self.fields['valid'].label = 'Validité de la facture'
159

160

161
class ArticleForm(FormRevMixin, ModelForm):
chirac's avatar
chirac committed
162
    """Creation d'un article. Champs : nom, cotisation, durée"""
163 164 165 166 167
    class Meta:
        model = Article
        fields = '__all__'

    def __init__(self, *args, **kwargs):
168
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
169
        super(ArticleForm, self).__init__(*args, prefix=prefix, **kwargs)
170 171
        self.fields['name'].label = "Désignation de l'article"

chirac's avatar
chirac committed
172

173
class DelArticleForm(FormRevMixin, Form):
chirac's avatar
chirac committed
174 175 176
    """Suppression d'un ou plusieurs articles en vente. Choix
    parmis les modèles"""
    articles = forms.ModelMultipleChoiceField(
177
        queryset=Article.objects.none(),
chirac's avatar
chirac committed
178 179 180 181
        label="Articles actuels",
        widget=forms.CheckboxSelectMultiple
    )

182 183 184 185 186 187 188 189
    def __init__(self, *args, **kwargs):
        instances = kwargs.pop('instances', None)
        super(DelArticleForm, self).__init__(*args, **kwargs)
        if instances:
            self.fields['articles'].queryset = instances
        else:
            self.fields['articles'].queryset = Article.objects.all()

190

191
class PaiementForm(FormRevMixin, ModelForm):
chirac's avatar
chirac committed
192 193
    """Creation d'un moyen de paiement, champ text moyen et type
    permettant d'indiquer si il s'agit d'un chèque ou non pour le form"""
194 195
    class Meta:
        model = Paiement
Gabriel Detraz's avatar
Gabriel Detraz committed
196
        fields = ['moyen', 'type_paiement']
197 198

    def __init__(self, *args, **kwargs):
199
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
200
        super(PaiementForm, self).__init__(*args, prefix=prefix, **kwargs)
201
        self.fields['moyen'].label = 'Moyen de paiement à ajouter'
Gabriel Detraz's avatar
Gabriel Detraz committed
202
        self.fields['type_paiement'].label = 'Type de paiement à ajouter'
203

chirac's avatar
chirac committed
204

205
class DelPaiementForm(FormRevMixin, Form):
chirac's avatar
chirac committed
206 207 208
    """Suppression d'un ou plusieurs moyens de paiements, selection
    parmis les models"""
    paiements = forms.ModelMultipleChoiceField(
209
        queryset=Paiement.objects.none(),
chirac's avatar
chirac committed
210 211 212 213
        label="Moyens de paiement actuels",
        widget=forms.CheckboxSelectMultiple
    )

214 215 216 217 218 219 220 221
    def __init__(self, *args, **kwargs):
        instances = kwargs.pop('instances', None)
        super(DelPaiementForm, self).__init__(*args, **kwargs)
        if instances:
            self.fields['paiements'].queryset = instances
        else:
            self.fields['paiements'].queryset = Paiement.objects.all()

222

223
class BanqueForm(FormRevMixin, ModelForm):
chirac's avatar
chirac committed
224
    """Creation d'une banque, field name"""
chirac's avatar
chirac committed
225 226 227 228 229
    class Meta:
        model = Banque
        fields = ['name']

    def __init__(self, *args, **kwargs):
230
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
231
        super(BanqueForm, self).__init__(*args, prefix=prefix, **kwargs)
chirac's avatar
chirac committed
232 233
        self.fields['name'].label = 'Banque à ajouter'

chirac's avatar
chirac committed
234

235
class DelBanqueForm(FormRevMixin, Form):
chirac's avatar
chirac committed
236 237
    """Selection d'une ou plusieurs banques, pour suppression"""
    banques = forms.ModelMultipleChoiceField(
238
        queryset=Banque.objects.none(),
chirac's avatar
chirac committed
239 240 241
        label="Banques actuelles",
        widget=forms.CheckboxSelectMultiple
    )
242 243 244 245 246 247 248 249

    def __init__(self, *args, **kwargs):
        instances = kwargs.pop('instances', None)
        super(DelBanqueForm, self).__init__(*args, **kwargs)
        if instances:
            self.fields['banques'].queryset = instances
        else:
            self.fields['banques'].queryset = Banque.objects.all()
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283


class NewFactureSoldeForm(NewFactureForm):
    """Creation d'une facture, moyen de paiement, banque et numero
    de cheque"""
    def __init__(self, *args, **kwargs):
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
        self.fields['cheque'].required = False
        self.fields['banque'].required = False
        self.fields['cheque'].label = 'Numero de chèque'
        self.fields['banque'].empty_label = "Non renseigné"
        self.fields['paiement'].empty_label = "Séléctionner\
        une bite de paiement"
        paiement_list = Paiement.objects.filter(type_paiement=1)
        if paiement_list:
            self.fields['paiement'].widget\
                .attrs['data-cheque'] = paiement_list.first().id

    class Meta:
        model = Facture
        fields = ['paiement', 'banque']


    def clean(self):
        cleaned_data = super(NewFactureSoldeForm, self).clean()
        paiement = cleaned_data.get("paiement")
        cheque = cleaned_data.get("cheque")
        banque = cleaned_data.get("banque")
        if not paiement:
            raise forms.ValidationError("Le moyen de paiement est obligatoire")
        elif paiement.type_paiement == "check" and not (cheque and banque):
            raise forms.ValidationError("Le numéro de chèque et\
                la banque sont obligatoires.")
        return cleaned_data
284 285


286
class RechargeForm(FormRevMixin, Form):
287 288 289 290 291
    value = forms.FloatField(
        label='Valeur',
        min_value=0.01,
        validators = []
    )
292 293 294 295 296 297 298

    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user')
        super(RechargeForm, self).__init__(*args, **kwargs)

    def clean_value(self):
        value = self.cleaned_data['value']
299 300 301 302
        if value < OptionalUser.get_cached_value('min_online_payment'):
            raise forms.ValidationError("Montant inférieur au montant minimal de paiement en ligne (%s) €" % OptionalUser.get_cached_value('min_online_payment'))
        if value + self.user.solde > OptionalUser.get_cached_value('max_solde'):
            raise forms.ValidationError("Le solde ne peux excéder %s " % OptionalUser.get_cached_value('max_solde'))
303
        return value