8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-09-12 01:03:09 +00:00

Pep8 compliance on cotisations

This commit is contained in:
Maël Kervella 2018-04-13 18:58:29 +00:00
parent e56c80b747
commit b25137acf4
8 changed files with 224 additions and 121 deletions

View file

@ -27,6 +27,7 @@ Here are defined some functions to check acl on the application.
"""
from django.utils.translation import ugettext as _
def can_view(user):
"""Check if an user can view the application.
@ -38,4 +39,7 @@ def can_view(user):
viewing is granted and msg is a message (can be None).
"""
can = user.has_module_perms('cotisations')
return can, None if can else _("You don't have the rights to see this application.")
if can:
return can, None
else:
return can, _("You don't have the rights to see this application.")

View file

@ -38,7 +38,7 @@ from __future__ import unicode_literals
from django import forms
from django.db.models import Q
from django.forms import ModelForm, Form
from django.core.validators import MinValueValidator,MaxValueValidator
from django.core.validators import MinValueValidator, MaxValueValidator
from django.utils.translation import ugettext as _
from django.utils.translation import ugettext_lazy as _l
@ -49,6 +49,7 @@ from users.models import User
from re2o.field_permissions import FieldPermissionFormMixin
from re2o.mixins import FormRevMixin
class NewFactureForm(FormRevMixin, ModelForm):
"""
Form used to create a new invoice by using a payment method, a bank and a
@ -109,12 +110,16 @@ class CreditSoldeForm(NewFactureForm):
montant = forms.DecimalField(max_digits=5, decimal_places=2, required=True)
class SelectUserArticleForm(FormRevMixin, Form):
class SelectUserArticleForm(
FormRevMixin, Form):
"""
Form used to select an article during the creation of an invoice for a member.
Form used to select an article during the creation of an invoice for a
member.
"""
article = forms.ModelChoiceField(
queryset=Article.objects.filter(Q(type_user='All') | Q(type_user='Adherent')),
queryset=Article.objects.filter(
Q(type_user='All') | Q(type_user='Adherent')
),
label=_l("Article"),
required=True
)
@ -127,10 +132,13 @@ class SelectUserArticleForm(FormRevMixin, Form):
class SelectClubArticleForm(Form):
"""
Form used to select an article during the creation of an invoice for a club.
Form used to select an article during the creation of an invoice for a
club.
"""
article = forms.ModelChoiceField(
queryset=Article.objects.filter(Q(type_user='All') | Q(type_user='Club')),
queryset=Article.objects.filter(
Q(type_user='All') | Q(type_user='Club')
),
label=_l("Article"),
required=True
)
@ -140,6 +148,7 @@ class SelectClubArticleForm(Form):
required=True
)
# TODO : change Facture to Invoice
class NewFactureFormPdf(Form):
"""
@ -147,9 +156,18 @@ class NewFactureFormPdf(Form):
"""
paid = forms.BooleanField(label=_l("Paid"), required=False)
# TODO : change dest field to recipient
dest = forms.CharField(required=True, max_length=255, label=_l("Recipient"))
dest = forms.CharField(
required=True,
max_length=255,
label=_l("Recipient")
)
# TODO : change chambre field to address
chambre = forms.CharField(required=False, max_length=10, label=_l("Address"))
chambre = forms.CharField(
required=False,
max_length=10,
label=_l("Address")
)
# TODO : change Facture to Invoice
class EditFactureForm(FieldPermissionFormMixin, NewFactureForm):
@ -313,7 +331,6 @@ class NewFactureSoldeForm(NewFactureForm):
# TODO : change paiement to payment and baque to bank
fields = ['paiement', 'banque']
def clean(self):
cleaned_data = super(NewFactureSoldeForm, self).clean()
# TODO : change paiement to payment
@ -342,7 +359,7 @@ class RechargeForm(FormRevMixin, Form):
value = forms.FloatField(
label=_l("Amount"),
min_value=0.01,
validators = []
validators=[]
)
def __init__(self, *args, **kwargs):
@ -360,7 +377,8 @@ class RechargeForm(FormRevMixin, Form):
)
}
)
if value + self.user.solde > OptionalUser.get_cached_value('max_solde'):
if value + self.user.solde > \
OptionalUser.get_cached_value('max_solde'):
raise forms.ValidationError(
_("Requested amount is too high. Your balance can't exceed \
%(max_online_balance)s .") % {

View file

@ -105,11 +105,16 @@ class Facture(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
abstract = False
permissions = (
# TODO : change facture to invoice
('change_facture_control', _l("Can change the \"controlled\" state")),
# TODO : seems more likely to be call create_facture_pdf or create_invoice_pdf
('change_facture_pdf', _l("Can create a custom PDF invoice")),
('view_facture', _l("Can see an invoice's details")),
('change_all_facture', _l("Can edit all the previous invoices")),
('change_facture_control',
_l("Can change the \"controlled\" state")),
# TODO : seems more likely to be call create_facture_pdf
# or create_invoice_pdf
('change_facture_pdf',
_l("Can create a custom PDF invoice")),
('view_facture',
_l("Can see an invoice's details")),
('change_all_facture',
_l("Can edit all the previous invoices")),
)
verbose_name = _l("Invoice")
verbose_name_plural = _l("Invoices")
@ -159,11 +164,14 @@ class Facture(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
def can_edit(self, user_request, *args, **kwargs):
if not user_request.has_perm('cotisations.change_facture'):
return False, _("You don't have the right to edit an invoice.")
elif not user_request.has_perm('cotisations.change_all_facture') and not self.user.can_edit(user_request, *args, **kwargs)[0]:
return False, _("You don't have the right to edit this user's invoices.")
elif not user_request.has_perm('cotisations.change_all_facture') and\
(self.control or not self.valid):
return False, _("You don't have the right to edit an invoice already controlled or invalidated.")
elif not user_request.has_perm('cotisations.change_all_facture') and \
not self.user.can_edit(user_request, *args, **kwargs)[0]:
return False, _("You don't have the right to edit this user's "
"invoices.")
elif not user_request.has_perm('cotisations.change_all_facture') and \
(self.control or not self.valid):
return False, _("You don't have the right to edit an invoice "
"already controlled or invalidated.")
else:
return True, None
@ -171,16 +179,19 @@ class Facture(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
if not user_request.has_perm('cotisations.delete_facture'):
return False, _("You don't have the right to delete an invoice.")
if not self.user.can_edit(user_request, *args, **kwargs)[0]:
return False, _("You don't have the right to delete this user's invoices.")
return False, _("You don't have the right to delete this user's "
"invoices.")
if self.control or not self.valid:
return False, _("You don't have the right to delete an invoice already controlled or invalidated.")
return False, _("You don't have the right to delete an invoice "
"already controlled or invalidated.")
else:
return True, None
def can_view(self, user_request, *args, **kwargs):
if not user_request.has_perm('cotisations.view_facture') and\
self.user != user_request:
return False, _("You don't have the right to see someone else's invoices history.")
if not user_request.has_perm('cotisations.view_facture') and \
self.user != user_request:
return False, _("You don't have the right to see someone else's "
"invoices history.")
elif not self.valid:
return False, _("The invoice has been invalidated.")
else:
@ -188,16 +199,22 @@ class Facture(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
@staticmethod
def can_change_control(user_request, *args, **kwargs):
return user_request.has_perm('cotisations.change_facture_control'), _("You don't have the right to edit the \"controlled\" state.")
return (
user_request.has_perm('cotisations.change_facture_control'),
_("You don't have the right to edit the \"controlled\" state.")
)
@staticmethod
def can_change_pdf(user_request, *args, **kwargs):
return user_request.has_perm('cotisations.change_facture_pdf'), _("You don't have the right to edit an invoice.")
return (
user_request.has_perm('cotisations.change_facture_pdf'),
_("You don't have the right to edit an invoice.")
)
def __init__(self, *args, **kwargs):
super(Facture, self).__init__(*args, **kwargs)
self.field_permissions = {
'control' : self.can_change_control,
'control': self.can_change_control,
}
def __str__(self):
@ -289,7 +306,6 @@ class Vente(RevMixin, AclMixin, models.Model):
verbose_name = _l("Purchase")
verbose_name_plural = _l("Purchases")
# TODO : change prix_total to total_price
def prix_total(self):
"""
@ -323,11 +339,13 @@ class Vente(RevMixin, AclMixin, models.Model):
facture__in=Facture.objects.filter(
user=self.facture.user
).exclude(valid=False))
).filter(Q(type_cotisation='All') | Q(type_cotisation=self.type_cotisation)
).filter(
Q(type_cotisation='All') |
Q(type_cotisation=self.type_cotisation)
).filter(
date_start__lt=date_start
).aggregate(Max('date_end'))['date_end__max']
elif self.type_cotisation=="Adhesion":
elif self.type_cotisation == "Adhesion":
end_cotisation = self.facture.user.end_adhesion()
else:
end_cotisation = self.facture.user.end_connexion()
@ -357,11 +375,15 @@ class Vente(RevMixin, AclMixin, models.Model):
def can_edit(self, user_request, *args, **kwargs):
if not user_request.has_perm('cotisations.change_vente'):
return False, _("You don't have the right to edit the purchases.")
elif not user_request.has_perm('cotisations.change_all_facture') and not self.facture.user.can_edit(user_request, *args, **kwargs)[0]:
return False, _("You don't have the right to edit this user's purchases.")
elif not user_request.has_perm('cotisations.change_all_vente') and\
(self.facture.control or not self.facture.valid):
return False, _("You don't have the right to edit a purchase already controlled or invalidated.")
elif not user_request.has_perm('cotisations.change_all_facture') and \
not self.facture.user.can_edit(
user_request, *args, **kwargs)[0]:
return False, _("You don't have the right to edit this user's "
"purchases.")
elif not user_request.has_perm('cotisations.change_all_vente') and \
(self.facture.control or not self.facture.valid):
return False, _("You don't have the right to edit a purchase "
"already controlled or invalidated.")
else:
return True, None
@ -369,16 +391,19 @@ class Vente(RevMixin, AclMixin, models.Model):
if not user_request.has_perm('cotisations.delete_vente'):
return False, _("You don't have the right to delete a purchase.")
if not self.facture.user.can_edit(user_request, *args, **kwargs)[0]:
return False, _("You don't have the right to delete this user's purchases.")
return False, _("You don't have the right to delete this user's "
"purchases.")
if self.facture.control or not self.facture.valid:
return False, _("You don't have the right to delete a purchase already controlled or invalidated.")
return False, _("You don't have the right to delete a purchase "
"already controlled or invalidated.")
else:
return True, None
def can_view(self, user_request, *args, **kwargs):
if not user_request.has_perm('cotisations.view_vente') and\
self.facture.user != user_request:
return False, _("You don't have the right to see someone else's purchase history.")
if not user_request.has_perm('cotisations.view_vente') and \
self.facture.user != user_request:
return False, _("You don't have the right to see someone "
"else's purchase history.")
else:
return True, None
@ -418,12 +443,14 @@ def vente_post_delete(sender, **kwargs):
class Article(RevMixin, AclMixin, models.Model):
"""
The definition of an article model. It represents an type of object that can be sold to the user.
The definition of an article model. It represents a type of object
that can be sold to the user.
It's represented by:
* a name
* a price
* a cotisation type (indicating if this article reprensents a cotisation or not)
* a cotisation type (indicating if this article reprensents a
cotisation or not)
* a duration (if it is a cotisation)
* a type of user (indicating what kind of user can buy this article)
"""
@ -513,8 +540,8 @@ class Banque(RevMixin, AclMixin, models.Model):
permissions = (
('view_banque', _l("Can see a bank's details")),
)
verbose_name=_l("Bank")
verbose_name_plural=_l("Banks")
verbose_name = _l("Bank")
verbose_name_plural = _l("Banks")
def __str__(self):
return self.name
@ -622,24 +649,29 @@ class Cotisation(RevMixin, AclMixin, models.Model):
def can_edit(self, user_request, *args, **kwargs):
if not user_request.has_perm('cotisations.change_cotisation'):
return False, _("You don't have the right to edit a cotisation.")
elif not user_request.has_perm('cotisations.change_all_cotisation') and\
(self.vente.facture.control or not self.vente.facture.valid):
return False, _("You don't have the right to edit a cotisation already controlled or invalidated.")
elif not user_request.has_perm('cotisations.change_all_cotisation') \
and (self.vente.facture.control or
not self.vente.facture.valid):
return False, _("You don't have the right to edit a cotisation "
"already controlled or invalidated.")
else:
return True, None
def can_delete(self, user_request, *args, **kwargs):
if not user_request.has_perm('cotisations.delete_cotisation'):
return False, _("You don't have the right to delete a cotisation.")
return False, _("You don't have the right to delete a "
"cotisation.")
if self.vente.facture.control or not self.vente.facture.valid:
return False, _("You don't have the right to delete a cotisation already controlled or invalidated.")
return False, _("You don't have the right to delete a cotisation "
"already controlled or invalidated.")
else:
return True, None
def can_view(self, user_request, *args, **kwargs):
if not user_request.has_perm('cotisations.view_cotisation') and\
self.vente.facture.user != user_request:
return False, _("You don't have the right to see someone else's cotisation history.")
self.vente.facture.user != user_request:
return False, _("You don't have the right to see someone else's "
"cotisation history.")
else:
return True, None

View file

@ -17,6 +17,7 @@ from preferences.models import AssoOption
from .models import Facture
from .payment_utils.comnpay import Payment as ComnpayPayment
@csrf_exempt
@login_required
def accept_payment(request, factureid):
@ -30,7 +31,10 @@ def accept_payment(request, factureid):
'amount': facture.prix()
}
)
return redirect(reverse('users:profil', kwargs={'userid':request.user.id}))
return redirect(reverse(
'users:profil',
kwargs={'userid': request.user.id}
))
@csrf_exempt
@ -43,7 +47,11 @@ def refuse_payment(request):
request,
_("The payment has been refused.")
)
return redirect(reverse('users:profil', kwargs={'userid':request.user.id}))
return redirect(reverse(
'users:profil',
kwargs={'userid': request.user.id}
))
@csrf_exempt
def ipn(request):
@ -105,7 +113,7 @@ def comnpay(facture, request):
str(AssoOption.get_cached_value('payment_pass')),
'https://' + host + reverse(
'cotisations:accept_payment',
kwargs={'factureid':facture.id}
kwargs={'factureid': facture.id}
),
'https://' + host + reverse('cotisations:refuse_payment'),
'https://' + host + reverse('cotisations:ipn'),
@ -113,20 +121,20 @@ def comnpay(facture, request):
"D"
)
r = {
'action' : 'https://secure.homologation.comnpay.com',
'method' : 'POST',
'content' : p.buildSecretHTML(
'action': 'https://secure.homologation.comnpay.com',
'method': 'POST',
'content': p.buildSecretHTML(
"Rechargement du solde",
facture.prix(),
idTransaction=str(facture.id)
),
'amount' : facture.prix,
'amount': facture.prix,
}
return r
# The payment systems supported by re2o
PAYMENT_SYSTEM = {
'COMNPAY' : comnpay,
'NONE' : None
'COMNPAY': comnpay,
'NONE': None
}

View file

@ -5,6 +5,7 @@ import hashlib
from collections import OrderedDict
from itertools import chain
class Payment():
vad_number = ""
@ -15,7 +16,8 @@ class Payment():
source = ""
typeTr = "D"
def __init__(self, vad_number = "", secret_key = "", urlRetourOK = "", urlRetourNOK = "", urlIPN = "", source="", typeTr="D"):
def __init__(self, vad_number="", secret_key="", urlRetourOK="",
urlRetourNOK="", urlIPN="", source="", typeTr="D"):
self.vad_number = vad_number
self.secret_key = secret_key
self.urlRetourOK = urlRetourOK
@ -24,36 +26,45 @@ class Payment():
self.source = source
self.typeTr = typeTr
def buildSecretHTML(self, produit="Produit", montant="0.00", idTransaction=""):
def buildSecretHTML(self, produit="Produit", montant="0.00",
idTransaction=""):
if idTransaction == "":
self.idTransaction = str(time.time())+self.vad_number+str(randrange(999))
self.idTransaction = str(time.time())
self.idTransaction += self.vad_number
self.idTransaction += str(randrange(999))
else:
self.idTransaction = idTransaction
array_tpe = OrderedDict(
montant= str(montant),
idTPE= self.vad_number,
idTransaction= self.idTransaction,
devise= "EUR",
lang= 'fr',
nom_produit= produit,
source= self.source,
urlRetourOK= self.urlRetourOK,
urlRetourNOK= self.urlRetourNOK,
typeTr= str(self.typeTr)
array_tpe = OrderedDict(
montant=str(montant),
idTPE=self.vad_number,
idTransaction=self.idTransaction,
devise="EUR",
lang='fr',
nom_produit=produit,
source=self.source,
urlRetourOK=self.urlRetourOK,
urlRetourNOK=self.urlRetourNOK,
typeTr=str(self.typeTr)
)
if self.urlIPN!="":
if self.urlIPN != "":
array_tpe['urlIPN'] = self.urlIPN
array_tpe['key'] = self.secret_key;
strWithKey = base64.b64encode(bytes('|'.join(array_tpe.values()), 'utf-8'))
array_tpe['key'] = self.secret_key
strWithKey = base64.b64encode(bytes(
'|'.join(array_tpe.values()),
'utf-8'
))
del array_tpe["key"]
array_tpe['sec'] = hashlib.sha512(strWithKey).hexdigest()
ret = ""
for key in array_tpe:
ret += '<input type="hidden" name="'+key+'" value="'+array_tpe[key]+'"/>'
ret += '<input type="hidden" name="{k}" value="{v}"/>'.format(
'k'=key,
'v'=array_type[key]
)
return ret
@ -61,8 +72,10 @@ class Payment():
if "sec" in values:
sec = values['sec']
del values["sec"]
strWithKey = hashlib.sha512(base64.b64encode(bytes('|'.join(values.values()) +"|"+secret_key, 'utf-8'))).hexdigest()
strWithKey = hashlib.sha512(base64.b64encode(bytes(
'|'.join(values.values()) + "|" + secret_key,
'utf-8'
))).hexdigest()
return strWithKey.upper() == sec.upper()
else:
return False

View file

@ -54,9 +54,12 @@ def render_invoice(request, ctx={}):
str(ctx['DATE'].day),
])
r = render_tex(request, 'cotisations/factures.tex', ctx)
r['Content-Disposition'] = ''.join(['attachment; filename="',filename,'.pdf"'])
r['Content-Disposition'] = 'attachment; filename="{name}.pdf"'.format(
name=filename
)
return r
def render_tex(request, template, ctx={}):
"""
Creates a PDF from a LaTex templates using pdflatex.
@ -71,8 +74,8 @@ def render_tex(request, template, ctx={}):
for i in range(2):
process = Popen(
['pdflatex', '-output-directory', tempdir],
stdin = PIPE,
stdout = PIPE,
stdin=PIPE,
stdout=PIPE,
)
process.communicate(rendered_tpl)
with open(os.path.join(tempdir, 'texput.pdf'), 'rb') as f:

View file

@ -101,12 +101,11 @@ urlpatterns = [
views.index_paiement,
name='index-paiement'
),
url(
r'history/(?P<object_name>\w+)/(?P<object_id>[0-9]+)$',
url(r'history/(?P<object_name>\w+)/(?P<object_id>[0-9]+)$',
re2o.views.history,
name='history',
kwargs={'application':'cotisations'},
),
kwargs={'application': 'cotisations'},
),
url(r'^control/$',
views.control,
name='control'
@ -122,14 +121,14 @@ urlpatterns = [
url(r'^payment/accept/(?P<factureid>[0-9]+)$',
payment.accept_payment,
name='accept_payment'
),
),
url(r'^payment/refuse/$',
payment.refuse_payment,
name='refuse_payment'
),
),
url(r'^payment/ipn/$',
payment.ipn,
name='ipn'
),
),
url(r'^$', views.index, name='index'),
]

View file

@ -77,7 +77,6 @@ from . import payment as online_payment
from .tex import render_invoice
@login_required
@can_create(Facture)
@can_edit(User)
@ -102,9 +101,13 @@ def new_facture(request, user, userid):
# Building the invocie form and the article formset
invoice_form = NewFactureForm(request.POST or None, instance=invoice)
if request.user.is_class_club:
article_formset = formset_factory(SelectClubArticleForm)(request.POST or None)
article_formset = formset_factory(SelectClubArticleForm)(
request.POST or None
)
else:
article_formset = formset_factory(SelectUserArticleForm)(request.POST or None)
article_formset = formset_factory(SelectUserArticleForm)(
request.POST or None
)
if invoice_form.is_valid() and article_formset.is_valid():
new_invoice_instance = invoice_form.save(commit=False)
@ -118,15 +121,18 @@ def new_facture(request, user, userid):
# the authorized minimum (negative_balance)
if user_balance:
# TODO : change Paiement to Payment
if new_invoice_instance.paiement == Paiement.objects.get_or_create(
moyen='solde'
)[0]:
if new_invoice_instance.paiement == (
Paiement.objects.get_or_create(moyen='solde')[0]
):
total_price = 0
for art_item in articles:
if art_item.cleaned_data:
total_price += art_item.cleaned_data['article']\
.prix*art_item.cleaned_data['quantity']
if float(user.solde) - float(total_price) < negative_balance:
total_price += (
art_item.cleaned_data['article'].prix *
art_item.cleaned_data['quantity']
)
if (float(user.solde) - float(total_price)
< negative_balance):
messages.error(
request,
_("Your balance is too low for this operation.")
@ -205,9 +211,13 @@ def new_facture_pdf(request):
# Building the invocie form and the article formset
invoice_form = NewFactureFormPdf(request.POST or None)
if request.user.is_class_club:
articles_formset = formset_factory(SelectClubArticleForm)(request.POST or None)
articles_formset = formset_factory(SelectClubArticleForm)(
request.POST or None
)
else:
articles_formset = formset_factory(SelectUserArticleForm)(request.POST or None)
articles_formset = formset_factory(SelectUserArticleForm)(
request.POST or None
)
if invoice_form.is_valid() and articles_formset.is_valid():
# Get the article list and build an list out of it
# contiaining (article_name, article_price, quantity, total_price)
@ -303,7 +313,11 @@ def edit_facture(request, facture, factureid):
can be set as desired. This is also the view used to invalidate
an invoice.
"""
invoice_form = EditFactureForm(request.POST or None, instance=facture, user=request.user)
invoice_form = EditFactureForm(
request.POST or None,
instance=facture,
user=request.user
)
purchases_objects = Vente.objects.filter(facture=facture)
purchase_form_set = modelformset_factory(
Vente,
@ -311,7 +325,10 @@ def edit_facture(request, facture, factureid):
extra=0,
max_num=len(purchases_objects)
)
purchase_form = purchase_form_set(request.POST or None, queryset=purchases_objects)
purchase_form = purchase_form_set(
request.POST or None,
queryset=purchases_objects
)
if invoice_form.is_valid() and purchase_form.is_valid():
if invoice_form.changed_data:
invoice_form.save()
@ -613,7 +630,8 @@ def control(request):
View used to control the invoices all at once.
"""
pagination_number = GeneralOption.get_cached_value('pagination_number')
invoice_list = Facture.objects.select_related('user').select_related('paiement')
invoice_list = (Facture.objects.select_related('user').
select_related('paiement'))
invoice_list = SortTable.sort(
invoice_list,
request.GET.get('col'),
@ -725,9 +743,13 @@ def new_facture_solde(request, userid):
Q(type_user='All') | Q(type_user=request.user.class_name)
)
if request.user.is_class_club:
article_formset = formset_factory(SelectClubArticleForm)(request.POST or None)
article_formset = formset_factory(SelectClubArticleForm)(
request.POST or None
)
else:
article_formset = formset_factory(SelectUserArticleForm)(request.POST or None)
article_formset = formset_factory(SelectUserArticleForm)(
request.POST or None
)
if article_formset.is_valid():
articles = article_formset
@ -826,7 +848,9 @@ def recharge(request):
refill_form = RechargeForm(request.POST or None, user=request.user)
if refill_form.is_valid():
invoice = Facture(user=request.user)
payment, _created = Paiement.objects.get_or_create(moyen='Rechargement en ligne')
payment, _created = Paiement.objects.get_or_create(
moyen='Rechargement en ligne'
)
invoice.paiement = payment
invoice.valid = False
invoice.save()
@ -837,7 +861,9 @@ def recharge(request):
number=1
)
purchase.save()
content = online_payment.PAYMENT_SYSTEM[AssoOption.get_cached_value('payment')](invoice, request)
content = online_payment.PAYMENT_SYSTEM[
AssoOption.get_cached_value('payment')
](invoice, request)
return render(request, 'cotisations/payment.html', content)
return form({
'rechargeform': refill_form