forms.py 4.31 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
# -*- mode: python; coding: utf-8 -*-
# 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 © 2018  Hugo Levy-Falk
#
# 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.
21 22 23 24
from django import forms
from django.utils.translation import ugettext as _
from django.utils.translation import ugettext_lazy as _l

25 26
from . import PAYMENT_METHODS
from cotisations.utils import find_payment_method
27

28
def payment_method_factory(payment, *args, creation=True, **kwargs):
29 30 31 32
    """This function finds the right payment method form for a given payment.

    If the payment has a payment method, returns a ModelForm of it. Else if
    it is the creation of the payment, a `PaymentMethodForm`.
33
    Else `None`.
34

35 36 37 38 39
    Args:
        payment: The payment
        *args: arguments passed to the form
        creation: Should be True if you are creating the payment
        **kwargs: passed to the form
40

41
    Returns:
42
        A form or None
43
    """
44 45 46 47 48 49 50
    payment_method = kwargs.pop('instance', find_payment_method(payment))
    if payment_method is not None:
        return forms.modelform_factory(type(payment_method), fields='__all__')(
            *args,
            instance=payment_method,
            **kwargs
        )
51
    elif creation:
52
        return PaymentMethodForm(*args, **kwargs)
53 54 55 56


class PaymentMethodForm(forms.Form):
    """A special form which allows you to add a payment method to a `Payment`
57
    object.
58 59 60 61
    """

    payment_method = forms.ChoiceField(
        label=_l("Special payment method"),
62
        help_text=_l("Warning : You will not be able to change the payment "
63
                     "method later. But you will be allowed to edit the other "
64 65
                     "options."
        ),
66 67 68
        required=False
    )

69
    def __init__(self, *args, **kwargs):
70
        super(PaymentMethodForm, self).__init__(*args, **kwargs)
71 72 73 74 75 76 77 78 79 80
        prefix = kwargs.get('prefix', None)
        self.fields['payment_method'].choices = [(i,p.NAME) for (i,p) in enumerate(PAYMENT_METHODS)]
        self.fields['payment_method'].choices.insert(0, ('', _l('no')))
        self.fields['payment_method'].widget.attrs = {
            'id': 'paymentMethodSelect'
        }
        self.templates = [
            forms.modelform_factory(p.PaymentMethod, fields='__all__')(prefix=prefix)
            for p in PAYMENT_METHODS
        ]
81

82
    def clean(self):
83 84 85 86
        """A classic `clean` method, except that it replaces
        `self.payment_method` by the payment method object if one has been
        found. Tries to call `payment_method.valid_form` if it exists.
        """
87
        super(PaymentMethodForm, self).clean()
88 89 90 91 92 93
        choice = self.cleaned_data['payment_method']
        if choice=='':
            return
        choice = int(choice)
        model = PAYMENT_METHODS[choice].PaymentMethod
        form = forms.modelform_factory(model, fields='__all__')(self.data, prefix=self.prefix)
94 95 96 97 98 99 100 101
        self.payment_method = form.save(commit=False)
        if hasattr(self.payment_method, 'valid_form'):
            self.payment_method.valid_form(self)
        return self.cleaned_data



    def save(self, payment, *args, **kwargs):
102 103 104 105
        """Saves the payment method.

        Tries to call `payment_method.alter_payment` if it exists.
        """
106
        commit = kwargs.pop('commit', True)
107 108
        if not hasattr(self, 'payment_method'):
            return None
109 110 111
        self.payment_method.payment = payment
        if hasattr(self.payment_method, 'alter_payment'):
            self.payment_method.alter_payment(payment)
112
        if commit:
113 114 115
            payment.save()
            self.payment_method.save()
        return self.payment_method