From 8e12fefa2c78dd2a9d5f2fd3687829d83f61df67 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sun, 8 Jul 2018 00:01:06 +0200 Subject: [PATCH] =?UTF-8?q?Documentation=20des=20paiements=20personnalis?= =?UTF-8?q?=C3=A9s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cotisations/payment_methods/__init__.py | 129 ++++++++++++++++++ .../payment_methods/balance/__init__.py | 20 +++ cotisations/payment_methods/balance/models.py | 26 ++++ .../payment_methods/cheque/__init__.py | 20 +++ cotisations/payment_methods/cheque/forms.py | 21 ++- cotisations/payment_methods/cheque/models.py | 25 ++++ cotisations/payment_methods/cheque/urls.py | 20 +++ cotisations/payment_methods/cheque/views.py | 21 +++ .../payment_methods/comnpay/__init__.py | 20 +++ .../payment_methods/comnpay/aes_field.py | 14 +- cotisations/payment_methods/comnpay/models.py | 21 +++ cotisations/payment_methods/comnpay/views.py | 30 +++- cotisations/payment_methods/forms.py | 72 +++++++--- cotisations/payment_methods/mixins.py | 24 +++- cotisations/payment_methods/urls.py | 20 +++ cotisations/utils.py | 23 ++++ 16 files changed, 479 insertions(+), 27 deletions(-) diff --git a/cotisations/payment_methods/__init__.py b/cotisations/payment_methods/__init__.py index 422bd069..b78a86fd 100644 --- a/cotisations/payment_methods/__init__.py +++ b/cotisations/payment_methods/__init__.py @@ -1,3 +1,132 @@ +# -*- 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. +""" +# Custom Payment methods + +When creating an invoice with a classic payment method, the creation view calls +the `end_payment` method of the `Payment` object of the invoice. This method +checks for a payment method associated to the `Payment` and if nothing is +found, adds a message for payment confirmation and redirects the user towards +their profil page. This is fine for most of the payment method, but you might +want to define custom payment methods. As an example for negociating with an +other server for online payment or updating some fields in your models. + +# Defining a custom payment method +To define a custom payment method, you can add a Python module to +`cotisations/payment_methods/`. This module should be organized like +a Django application. +As an example, if you want to add the payment method `foo`. + +## Basic + +The first thing to do is to create a `foo` Python module with a `models.py`. + +``` +payment_methods +├── foo +│ ├── __init__.py +│ └── models.py +├── forms.py +├── __init__.py +├── mixins.py +└── urls.py +``` + +Then, in `models.py` you could add a model like this : +```python +from django.db import models + +from cotisations.models import Paiement +from cotisations.payment_methods.mixins import PaymentMethodMixin + + +# The `PaymentMethodMixin` defines the default `end_payment` +class FooPayment(PaymentMethodMixin, models.Model): + + # This field is required, it is used by `Paiement` in order to + # determine if a payment method is associated to it. + payment = models.OneToOneField( + Paiement, + on_delete=models.CASCADE, + related_name='payment_method', + editable=False + ) +``` + +And in `__init__.py` : +```python +from . import models +NAME = "FOO" # Name displayed when you crate a payment type +PaymentMethod = models.FooPayment # You must define this alias +``` + +Then you just have to register your payment method in +`payment_methods/__init__.py` in the `PAYMENT_METHODS` list : + +``` +from . import ... # Some existing imports +from . import foo + +PAYMENT_METHODS = [ + # Some already registered payment methods... + foo +] +``` + +And... that's it, you can use your new payment method after running +`makemigrations` and `migrate`. + +But this payment method is not really usefull, since it does noting ! + +## A payment method which does something + +You have to redefine the `end_payment` method. Here is its prototype : + +```python +def end_payment(self, invoice, request): + pass +``` + +With `invoice` the invoice being created and `request` the request which +created it. This method has to return an HttpResponse-like object. + +## Additional views + +You can add specific urls for your payment method like in any django app. To +register these urls, modify `payment_methods/urls.py`. + +## Alter the `Paiement` object after creation + +You can do that by adding a `alter_payment(self, payment)` +method to your model. + +## Validate the creation field + +You may want to perform some additionals verifications on the form +creating the payment. You can do that by adding a `valid_form(self, form)` +method to your model, where `form` is an instance of +`cotisations.payment_methods.forms.PaymentMethodForm`. +""" + + from . import comnpay, cheque, balance, urls PAYMENT_METHODS = [ diff --git a/cotisations/payment_methods/balance/__init__.py b/cotisations/payment_methods/balance/__init__.py index adfca187..cacd73f7 100644 --- a/cotisations/payment_methods/balance/__init__.py +++ b/cotisations/payment_methods/balance/__init__.py @@ -1,3 +1,23 @@ +# -*- 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. """ This module contains a method to pay online using user balance. """ diff --git a/cotisations/payment_methods/balance/models.py b/cotisations/payment_methods/balance/models.py index 164136b9..4d2875d8 100644 --- a/cotisations/payment_methods/balance/models.py +++ b/cotisations/payment_methods/balance/models.py @@ -1,3 +1,23 @@ +# -*- 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. from django.db import models from django.shortcuts import redirect from django.urls import reverse @@ -16,6 +36,7 @@ class BalancePayment(PaymentMethodMixin, models.Model): """ payment = models.OneToOneField( Paiement, + on_delete=models.CASCADE, related_name='payment_method', editable=False ) @@ -38,6 +59,9 @@ class BalancePayment(PaymentMethodMixin, models.Model): ) def end_payment(self, invoice, request): + """Changes the user's balance to pay the invoice. If it is not + possible, shows an error and invalidates the invoice. + """ user = invoice.user total_price = invoice.prix_total() if float(user.solde) - float(total_price) < self.minimum_balance: @@ -58,6 +82,7 @@ class BalancePayment(PaymentMethodMixin, models.Model): ) def valid_form(self, form): + """Checks that there is not already a balance payment method.""" p = Paiement.objects.filter(is_balance=True) if len(p) > 0: form.add_error( @@ -66,4 +91,5 @@ class BalancePayment(PaymentMethodMixin, models.Model): ) def alter_payment(self, payment): + """Register the payment as a balance payment.""" self.payment.is_balance = True diff --git a/cotisations/payment_methods/cheque/__init__.py b/cotisations/payment_methods/cheque/__init__.py index a6fef640..9eb17b09 100644 --- a/cotisations/payment_methods/cheque/__init__.py +++ b/cotisations/payment_methods/cheque/__init__.py @@ -1,3 +1,23 @@ +# -*- 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. """ This module contains a method to pay online using cheque. """ diff --git a/cotisations/payment_methods/cheque/forms.py b/cotisations/payment_methods/cheque/forms.py index ae816a4b..37942687 100644 --- a/cotisations/payment_methods/cheque/forms.py +++ b/cotisations/payment_methods/cheque/forms.py @@ -1,5 +1,24 @@ +# -*- 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. from django import forms -from django.utils.translation import ugettext_lazy as _l from re2o.mixins import FormRevMixin from cotisations.models import Facture as Invoice diff --git a/cotisations/payment_methods/cheque/models.py b/cotisations/payment_methods/cheque/models.py index 29c86a41..bdb4e594 100644 --- a/cotisations/payment_methods/cheque/models.py +++ b/cotisations/payment_methods/cheque/models.py @@ -1,3 +1,23 @@ +# -*- 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. from django.db import models from django.shortcuts import redirect from django.urls import reverse @@ -12,10 +32,15 @@ class ChequePayment(PaymentMethodMixin, models.Model): """ payment = models.OneToOneField( Paiement, + on_delete=models.CASCADE, related_name='payment_method', editable=False ) + def end_payment(self, invoice, request): + """Invalidates the invoice then redirect the user towards a view asking + for informations to add to the invoice before validating it. + """ invoice.valid = False invoice.save() return redirect(reverse( diff --git a/cotisations/payment_methods/cheque/urls.py b/cotisations/payment_methods/cheque/urls.py index f7cc39d5..54fe6a50 100644 --- a/cotisations/payment_methods/cheque/urls.py +++ b/cotisations/payment_methods/cheque/urls.py @@ -1,3 +1,23 @@ +# -*- 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. from django.conf.urls import url from . import views diff --git a/cotisations/payment_methods/cheque/views.py b/cotisations/payment_methods/cheque/views.py index bcf707f9..47654990 100644 --- a/cotisations/payment_methods/cheque/views.py +++ b/cotisations/payment_methods/cheque/views.py @@ -1,3 +1,23 @@ +# -*- 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. """Payment Here are defined some views dedicated to cheque payement. @@ -17,6 +37,7 @@ from .forms import InvoiceForm @login_required def cheque(request, invoice_pk): + """This view validate an invoice with the data from a cheque.""" invoice = get_object_or_404(Invoice, pk=invoice_pk) payment_method = getattr(invoice.paiement, 'payment_method', None) if invoice.valid or not isinstance(payment_method, ChequePayment): diff --git a/cotisations/payment_methods/comnpay/__init__.py b/cotisations/payment_methods/comnpay/__init__.py index 58433c80..7c80311d 100644 --- a/cotisations/payment_methods/comnpay/__init__.py +++ b/cotisations/payment_methods/comnpay/__init__.py @@ -1,3 +1,23 @@ +# -*- 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. """ This module contains a method to pay online using comnpay. """ diff --git a/cotisations/payment_methods/comnpay/aes_field.py b/cotisations/payment_methods/comnpay/aes_field.py index 9a59b148..5708eeef 100644 --- a/cotisations/payment_methods/comnpay/aes_field.py +++ b/cotisations/payment_methods/comnpay/aes_field.py @@ -79,14 +79,22 @@ class AESEncryptedField(models.CharField): def to_python(self, value): if value is None: return None - return decrypt(settings.AES_KEY, - binascii.a2b_base64(value)).decode('utf-8') + try: + return decrypt(settings.AES_KEY, + binascii.a2b_base64(value)).decode('utf-8') + except Exception as e: + v = decrypt(settings.AES_KEY, binascii.a2b_base64(value)) + raise ValueError(v) def from_db_value(self, value, *args, **kwargs): if value is None: return value - return decrypt(settings.AES_KEY, + try: + return decrypt(settings.AES_KEY, binascii.a2b_base64(value)).decode('utf-8') + except Exception as e: + v = decrypt(settings.AES_KEY, binascii.a2b_base64(value)) + raise ValueError(v) def get_prep_value(self, value): if value is None: diff --git a/cotisations/payment_methods/comnpay/models.py b/cotisations/payment_methods/comnpay/models.py index fefa3587..cbc93db1 100644 --- a/cotisations/payment_methods/comnpay/models.py +++ b/cotisations/payment_methods/comnpay/models.py @@ -1,3 +1,23 @@ +# -*- 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. from django.db import models from django.shortcuts import render from django.urls import reverse @@ -17,6 +37,7 @@ class ComnpayPayment(PaymentMethodMixin, models.Model): """ payment = models.OneToOneField( Paiement, + on_delete=models.CASCADE, related_name='payment_method', editable=False ) diff --git a/cotisations/payment_methods/comnpay/views.py b/cotisations/payment_methods/comnpay/views.py index 814a51c8..89966b48 100644 --- a/cotisations/payment_methods/comnpay/views.py +++ b/cotisations/payment_methods/comnpay/views.py @@ -1,6 +1,26 @@ +# -*- 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. """Payment -Here are defined some views dedicated to online payement. +Here are the views needed by comnpay """ from collections import OrderedDict @@ -23,7 +43,8 @@ from .models import ComnpayPayment @login_required def accept_payment(request, factureid): """ - The view called when an online payment has been accepted. + The view where the user is redirected when a comnpay payment has been + accepted. """ invoice = get_object_or_404(Facture, id=factureid) if invoice.valid: @@ -55,7 +76,8 @@ def accept_payment(request, factureid): @login_required def refuse_payment(request): """ - The view called when an online payment has been refused. + The view where the user is redirected when a comnpay payment has been + refused. """ messages.error( request, @@ -72,7 +94,7 @@ def ipn(request): """ The view called by Comnpay server to validate the transaction. Verify that we can firmly save the user's action and notify - Comnpay with 400 response if not or with a 200 response if yes + Comnpay with 400 response if not or with a 200 response if yes. """ p = Transaction() order = ('idTpe', 'idTransaction', 'montant', 'result', 'sec', ) diff --git a/cotisations/payment_methods/forms.py b/cotisations/payment_methods/forms.py index 2b712439..be8df2d1 100644 --- a/cotisations/payment_methods/forms.py +++ b/cotisations/payment_methods/forms.py @@ -1,3 +1,23 @@ +# -*- 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. from django import forms from django.utils.translation import ugettext as _ from django.utils.translation import ugettext_lazy as _l @@ -6,6 +26,19 @@ from . import PAYMENT_METHODS from cotisations.utils import find_payment_method def payment_method_factory(payment, *args, creation=True, **kwargs): + """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`. + Else an empty form. + + :param payment: The payment + :param *args: arguments passed to the form + :param creation: Should be True if you are creating the payment + :param **kwargs: passed to the form + + :returns: A form + """ payment_method = kwargs.pop('instance', find_payment_method(payment)) if payment_method is not None: return forms.modelform_factory(type(payment_method), fields='__all__')( @@ -14,16 +47,14 @@ def payment_method_factory(payment, *args, creation=True, **kwargs): **kwargs ) elif creation: - return PaymentMethodForm(payment_method, *args, **kwargs) + return PaymentMethodForm(*args, **kwargs) else: return forms.Form() class PaymentMethodForm(forms.Form): """A special form which allows you to add a payment method to a `Payment` - objects if it hasn't one yet, or to edit the existing payment method. - - To do so it replaces itself with a `modelform_factory`. + object. """ payment_method = forms.ChoiceField( @@ -35,23 +66,24 @@ class PaymentMethodForm(forms.Form): required=False ) - def __init__(self, payment_method, *args, **kwargs): + def __init__(self, *args, **kwargs): super(PaymentMethodForm, self).__init__(*args, **kwargs) - if payment_method is None: - 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 - ] - else: - self.fields = {} + 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 + ] def clean(self): + """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. + """ super(PaymentMethodForm, self).clean() choice = self.cleaned_data['payment_method'] if choice=='': @@ -67,6 +99,10 @@ class PaymentMethodForm(forms.Form): def save(self, payment, *args, **kwargs): + """Saves the payment method. + + Tries to call `payment_method.alter_payment` if it exists. + """ commit = kwargs.pop('commit', True) self.payment_method.payment = payment if hasattr(self.payment_method, 'alter_payment'): diff --git a/cotisations/payment_methods/mixins.py b/cotisations/payment_methods/mixins.py index cbbe1427..12503e05 100644 --- a/cotisations/payment_methods/mixins.py +++ b/cotisations/payment_methods/mixins.py @@ -1,5 +1,27 @@ +# -*- 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. + + class PaymentMethodMixin: - """The base class for payment models. They should inherit from this.""" + """A simple mixin to avoid redefining end_payment if you don't need to""" def end_payment(self, invoice, request): """Redefine this method in order to get a different ending to the diff --git a/cotisations/payment_methods/urls.py b/cotisations/payment_methods/urls.py index 9d35846f..20e50255 100644 --- a/cotisations/payment_methods/urls.py +++ b/cotisations/payment_methods/urls.py @@ -1,3 +1,23 @@ +# -*- 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. from django.conf.urls import include, url from . import comnpay, cheque diff --git a/cotisations/utils.py b/cotisations/utils.py index 01881af3..f36b376f 100644 --- a/cotisations/utils.py +++ b/cotisations/utils.py @@ -1,4 +1,27 @@ +# -*- 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. + + def find_payment_method(payment): + """Finds the payment method associated to the payment if it exists.""" from cotisations.payment_methods import PAYMENT_METHODS for method in PAYMENT_METHODS: try: