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:
parent
e56c80b747
commit
b25137acf4
8 changed files with 224 additions and 121 deletions
|
@ -27,6 +27,7 @@ Here are defined some functions to check acl on the application.
|
||||||
"""
|
"""
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
|
|
||||||
def can_view(user):
|
def can_view(user):
|
||||||
"""Check if an user can view the application.
|
"""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).
|
viewing is granted and msg is a message (can be None).
|
||||||
"""
|
"""
|
||||||
can = user.has_module_perms('cotisations')
|
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.")
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
"""
|
"""
|
||||||
Forms for the 'cotisation' app of re2o. It highly depends on
|
Forms for the 'cotisation' app of re2o. It highly depends on
|
||||||
:cotisations:models and is mainly used by :cotisations:views.
|
:cotisations:models and is mainly used by :cotisations:views.
|
||||||
|
|
||||||
The following forms are mainly used to create, edit or delete
|
The following forms are mainly used to create, edit or delete
|
||||||
|
@ -38,7 +38,7 @@ from __future__ import unicode_literals
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.forms import ModelForm, Form
|
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 as _
|
||||||
from django.utils.translation import ugettext_lazy as _l
|
from django.utils.translation import ugettext_lazy as _l
|
||||||
|
|
||||||
|
@ -47,7 +47,8 @@ from preferences.models import OptionalUser
|
||||||
from users.models import User
|
from users.models import User
|
||||||
|
|
||||||
from re2o.field_permissions import FieldPermissionFormMixin
|
from re2o.field_permissions import FieldPermissionFormMixin
|
||||||
from re2o.mixins import FormRevMixin
|
from re2o.mixins import FormRevMixin
|
||||||
|
|
||||||
|
|
||||||
class NewFactureForm(FormRevMixin, ModelForm):
|
class NewFactureForm(FormRevMixin, ModelForm):
|
||||||
"""
|
"""
|
||||||
|
@ -109,12 +110,16 @@ class CreditSoldeForm(NewFactureForm):
|
||||||
montant = forms.DecimalField(max_digits=5, decimal_places=2, required=True)
|
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(
|
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"),
|
label=_l("Article"),
|
||||||
required=True
|
required=True
|
||||||
)
|
)
|
||||||
|
@ -127,10 +132,13 @@ class SelectUserArticleForm(FormRevMixin, Form):
|
||||||
|
|
||||||
class SelectClubArticleForm(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(
|
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"),
|
label=_l("Article"),
|
||||||
required=True
|
required=True
|
||||||
)
|
)
|
||||||
|
@ -140,6 +148,7 @@ class SelectClubArticleForm(Form):
|
||||||
required=True
|
required=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# TODO : change Facture to Invoice
|
# TODO : change Facture to Invoice
|
||||||
class NewFactureFormPdf(Form):
|
class NewFactureFormPdf(Form):
|
||||||
"""
|
"""
|
||||||
|
@ -147,9 +156,18 @@ class NewFactureFormPdf(Form):
|
||||||
"""
|
"""
|
||||||
paid = forms.BooleanField(label=_l("Paid"), required=False)
|
paid = forms.BooleanField(label=_l("Paid"), required=False)
|
||||||
# TODO : change dest field to recipient
|
# 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
|
# 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
|
# TODO : change Facture to Invoice
|
||||||
class EditFactureForm(FieldPermissionFormMixin, NewFactureForm):
|
class EditFactureForm(FieldPermissionFormMixin, NewFactureForm):
|
||||||
|
@ -313,7 +331,6 @@ class NewFactureSoldeForm(NewFactureForm):
|
||||||
# TODO : change paiement to payment and baque to bank
|
# TODO : change paiement to payment and baque to bank
|
||||||
fields = ['paiement', 'banque']
|
fields = ['paiement', 'banque']
|
||||||
|
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
cleaned_data = super(NewFactureSoldeForm, self).clean()
|
cleaned_data = super(NewFactureSoldeForm, self).clean()
|
||||||
# TODO : change paiement to payment
|
# TODO : change paiement to payment
|
||||||
|
@ -342,7 +359,7 @@ class RechargeForm(FormRevMixin, Form):
|
||||||
value = forms.FloatField(
|
value = forms.FloatField(
|
||||||
label=_l("Amount"),
|
label=_l("Amount"),
|
||||||
min_value=0.01,
|
min_value=0.01,
|
||||||
validators = []
|
validators=[]
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
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(
|
raise forms.ValidationError(
|
||||||
_("Requested amount is too high. Your balance can't exceed \
|
_("Requested amount is too high. Your balance can't exceed \
|
||||||
%(max_online_balance)s €.") % {
|
%(max_online_balance)s €.") % {
|
||||||
|
|
|
@ -54,7 +54,7 @@ class Facture(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
|
||||||
"""
|
"""
|
||||||
The model for an invoice. It reprensents the fact that a user paid for
|
The model for an invoice. It reprensents the fact that a user paid for
|
||||||
something (it can be multiple article paid at once).
|
something (it can be multiple article paid at once).
|
||||||
|
|
||||||
An invoice is linked to :
|
An invoice is linked to :
|
||||||
* one or more purchases (one for each article sold that time)
|
* one or more purchases (one for each article sold that time)
|
||||||
* a user (the one who bought those articles)
|
* a user (the one who bought those articles)
|
||||||
|
@ -105,11 +105,16 @@ class Facture(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
|
||||||
abstract = False
|
abstract = False
|
||||||
permissions = (
|
permissions = (
|
||||||
# TODO : change facture to invoice
|
# TODO : change facture to invoice
|
||||||
('change_facture_control', _l("Can change the \"controlled\" state")),
|
('change_facture_control',
|
||||||
# TODO : seems more likely to be call create_facture_pdf or create_invoice_pdf
|
_l("Can change the \"controlled\" state")),
|
||||||
('change_facture_pdf', _l("Can create a custom PDF invoice")),
|
# TODO : seems more likely to be call create_facture_pdf
|
||||||
('view_facture', _l("Can see an invoice's details")),
|
# or create_invoice_pdf
|
||||||
('change_all_facture', _l("Can edit all the previous invoices")),
|
('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 = _l("Invoice")
|
||||||
verbose_name_plural = _l("Invoices")
|
verbose_name_plural = _l("Invoices")
|
||||||
|
@ -159,11 +164,14 @@ class Facture(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
|
||||||
def can_edit(self, user_request, *args, **kwargs):
|
def can_edit(self, user_request, *args, **kwargs):
|
||||||
if not user_request.has_perm('cotisations.change_facture'):
|
if not user_request.has_perm('cotisations.change_facture'):
|
||||||
return False, _("You don't have the right to edit an invoice.")
|
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]:
|
elif not user_request.has_perm('cotisations.change_all_facture') and \
|
||||||
return False, _("You don't have the right to edit this user's invoices.")
|
not self.user.can_edit(user_request, *args, **kwargs)[0]:
|
||||||
elif not user_request.has_perm('cotisations.change_all_facture') and\
|
return False, _("You don't have the right to edit this user's "
|
||||||
(self.control or not self.valid):
|
"invoices.")
|
||||||
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 \
|
||||||
|
(self.control or not self.valid):
|
||||||
|
return False, _("You don't have the right to edit an invoice "
|
||||||
|
"already controlled or invalidated.")
|
||||||
else:
|
else:
|
||||||
return True, None
|
return True, None
|
||||||
|
|
||||||
|
@ -171,16 +179,19 @@ class Facture(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
|
||||||
if not user_request.has_perm('cotisations.delete_facture'):
|
if not user_request.has_perm('cotisations.delete_facture'):
|
||||||
return False, _("You don't have the right to delete an invoice.")
|
return False, _("You don't have the right to delete an invoice.")
|
||||||
if not self.user.can_edit(user_request, *args, **kwargs)[0]:
|
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:
|
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:
|
else:
|
||||||
return True, None
|
return True, None
|
||||||
|
|
||||||
def can_view(self, user_request, *args, **kwargs):
|
def can_view(self, user_request, *args, **kwargs):
|
||||||
if not user_request.has_perm('cotisations.view_facture') and\
|
if not user_request.has_perm('cotisations.view_facture') and \
|
||||||
self.user != user_request:
|
self.user != user_request:
|
||||||
return False, _("You don't have the right to see someone else's invoices history.")
|
return False, _("You don't have the right to see someone else's "
|
||||||
|
"invoices history.")
|
||||||
elif not self.valid:
|
elif not self.valid:
|
||||||
return False, _("The invoice has been invalidated.")
|
return False, _("The invoice has been invalidated.")
|
||||||
else:
|
else:
|
||||||
|
@ -188,16 +199,22 @@ class Facture(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def can_change_control(user_request, *args, **kwargs):
|
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
|
@staticmethod
|
||||||
def can_change_pdf(user_request, *args, **kwargs):
|
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):
|
def __init__(self, *args, **kwargs):
|
||||||
super(Facture, self).__init__(*args, **kwargs)
|
super(Facture, self).__init__(*args, **kwargs)
|
||||||
self.field_permissions = {
|
self.field_permissions = {
|
||||||
'control' : self.can_change_control,
|
'control': self.can_change_control,
|
||||||
}
|
}
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -228,7 +245,7 @@ class Vente(RevMixin, AclMixin, models.Model):
|
||||||
"""
|
"""
|
||||||
The model defining a purchase. It consist of one type of article being
|
The model defining a purchase. It consist of one type of article being
|
||||||
sold. In particular there may be multiple purchases in a single invoice.
|
sold. In particular there may be multiple purchases in a single invoice.
|
||||||
|
|
||||||
It's reprensentated by:
|
It's reprensentated by:
|
||||||
* an amount (the number of items sold)
|
* an amount (the number of items sold)
|
||||||
* an invoice (whose the purchase is part of)
|
* an invoice (whose the purchase is part of)
|
||||||
|
@ -289,7 +306,6 @@ class Vente(RevMixin, AclMixin, models.Model):
|
||||||
verbose_name = _l("Purchase")
|
verbose_name = _l("Purchase")
|
||||||
verbose_name_plural = _l("Purchases")
|
verbose_name_plural = _l("Purchases")
|
||||||
|
|
||||||
|
|
||||||
# TODO : change prix_total to total_price
|
# TODO : change prix_total to total_price
|
||||||
def prix_total(self):
|
def prix_total(self):
|
||||||
"""
|
"""
|
||||||
|
@ -323,11 +339,13 @@ class Vente(RevMixin, AclMixin, models.Model):
|
||||||
facture__in=Facture.objects.filter(
|
facture__in=Facture.objects.filter(
|
||||||
user=self.facture.user
|
user=self.facture.user
|
||||||
).exclude(valid=False))
|
).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(
|
).filter(
|
||||||
date_start__lt=date_start
|
date_start__lt=date_start
|
||||||
).aggregate(Max('date_end'))['date_end__max']
|
).aggregate(Max('date_end'))['date_end__max']
|
||||||
elif self.type_cotisation=="Adhesion":
|
elif self.type_cotisation == "Adhesion":
|
||||||
end_cotisation = self.facture.user.end_adhesion()
|
end_cotisation = self.facture.user.end_adhesion()
|
||||||
else:
|
else:
|
||||||
end_cotisation = self.facture.user.end_connexion()
|
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):
|
def can_edit(self, user_request, *args, **kwargs):
|
||||||
if not user_request.has_perm('cotisations.change_vente'):
|
if not user_request.has_perm('cotisations.change_vente'):
|
||||||
return False, _("You don't have the right to edit the purchases.")
|
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]:
|
elif not user_request.has_perm('cotisations.change_all_facture') and \
|
||||||
return False, _("You don't have the right to edit this user's purchases.")
|
not self.facture.user.can_edit(
|
||||||
elif not user_request.has_perm('cotisations.change_all_vente') and\
|
user_request, *args, **kwargs)[0]:
|
||||||
(self.facture.control or not self.facture.valid):
|
return False, _("You don't have the right to edit this user's "
|
||||||
return False, _("You don't have the right to edit a purchase already controlled or invalidated.")
|
"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:
|
else:
|
||||||
return True, None
|
return True, None
|
||||||
|
|
||||||
|
@ -369,16 +391,19 @@ class Vente(RevMixin, AclMixin, models.Model):
|
||||||
if not user_request.has_perm('cotisations.delete_vente'):
|
if not user_request.has_perm('cotisations.delete_vente'):
|
||||||
return False, _("You don't have the right to delete a purchase.")
|
return False, _("You don't have the right to delete a purchase.")
|
||||||
if not self.facture.user.can_edit(user_request, *args, **kwargs)[0]:
|
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:
|
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:
|
else:
|
||||||
return True, None
|
return True, None
|
||||||
|
|
||||||
def can_view(self, user_request, *args, **kwargs):
|
def can_view(self, user_request, *args, **kwargs):
|
||||||
if not user_request.has_perm('cotisations.view_vente') and\
|
if not user_request.has_perm('cotisations.view_vente') and \
|
||||||
self.facture.user != user_request:
|
self.facture.user != user_request:
|
||||||
return False, _("You don't have the right to see someone else's purchase history.")
|
return False, _("You don't have the right to see someone "
|
||||||
|
"else's purchase history.")
|
||||||
else:
|
else:
|
||||||
return True, None
|
return True, None
|
||||||
|
|
||||||
|
@ -418,12 +443,14 @@ def vente_post_delete(sender, **kwargs):
|
||||||
|
|
||||||
class Article(RevMixin, AclMixin, models.Model):
|
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:
|
It's represented by:
|
||||||
* a name
|
* a name
|
||||||
* a price
|
* 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 duration (if it is a cotisation)
|
||||||
* a type of user (indicating what kind of user can buy this article)
|
* a type of user (indicating what kind of user can buy this article)
|
||||||
"""
|
"""
|
||||||
|
@ -513,8 +540,8 @@ class Banque(RevMixin, AclMixin, models.Model):
|
||||||
permissions = (
|
permissions = (
|
||||||
('view_banque', _l("Can see a bank's details")),
|
('view_banque', _l("Can see a bank's details")),
|
||||||
)
|
)
|
||||||
verbose_name=_l("Bank")
|
verbose_name = _l("Bank")
|
||||||
verbose_name_plural=_l("Banks")
|
verbose_name_plural = _l("Banks")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
@ -530,7 +557,7 @@ class Paiement(RevMixin, AclMixin, models.Model):
|
||||||
* a type (used for the type 'cheque' which implies the use of a bank
|
* a type (used for the type 'cheque' which implies the use of a bank
|
||||||
and an account number in related models)
|
and an account number in related models)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
PAYMENT_TYPES = (
|
PAYMENT_TYPES = (
|
||||||
(0, _l("Standard")),
|
(0, _l("Standard")),
|
||||||
(1, _l("Cheque")),
|
(1, _l("Cheque")),
|
||||||
|
@ -622,24 +649,29 @@ class Cotisation(RevMixin, AclMixin, models.Model):
|
||||||
def can_edit(self, user_request, *args, **kwargs):
|
def can_edit(self, user_request, *args, **kwargs):
|
||||||
if not user_request.has_perm('cotisations.change_cotisation'):
|
if not user_request.has_perm('cotisations.change_cotisation'):
|
||||||
return False, _("You don't have the right to edit a cotisation.")
|
return False, _("You don't have the right to edit a cotisation.")
|
||||||
elif not user_request.has_perm('cotisations.change_all_cotisation') and\
|
elif not user_request.has_perm('cotisations.change_all_cotisation') \
|
||||||
(self.vente.facture.control or not self.vente.facture.valid):
|
and (self.vente.facture.control or
|
||||||
return False, _("You don't have the right to edit a cotisation already controlled or invalidated.")
|
not self.vente.facture.valid):
|
||||||
|
return False, _("You don't have the right to edit a cotisation "
|
||||||
|
"already controlled or invalidated.")
|
||||||
else:
|
else:
|
||||||
return True, None
|
return True, None
|
||||||
|
|
||||||
def can_delete(self, user_request, *args, **kwargs):
|
def can_delete(self, user_request, *args, **kwargs):
|
||||||
if not user_request.has_perm('cotisations.delete_cotisation'):
|
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:
|
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:
|
else:
|
||||||
return True, None
|
return True, None
|
||||||
|
|
||||||
def can_view(self, user_request, *args, **kwargs):
|
def can_view(self, user_request, *args, **kwargs):
|
||||||
if not user_request.has_perm('cotisations.view_cotisation') and\
|
if not user_request.has_perm('cotisations.view_cotisation') and\
|
||||||
self.vente.facture.user != user_request:
|
self.vente.facture.user != user_request:
|
||||||
return False, _("You don't have the right to see someone else's cotisation history.")
|
return False, _("You don't have the right to see someone else's "
|
||||||
|
"cotisation history.")
|
||||||
else:
|
else:
|
||||||
return True, None
|
return True, None
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ from preferences.models import AssoOption
|
||||||
from .models import Facture
|
from .models import Facture
|
||||||
from .payment_utils.comnpay import Payment as ComnpayPayment
|
from .payment_utils.comnpay import Payment as ComnpayPayment
|
||||||
|
|
||||||
|
|
||||||
@csrf_exempt
|
@csrf_exempt
|
||||||
@login_required
|
@login_required
|
||||||
def accept_payment(request, factureid):
|
def accept_payment(request, factureid):
|
||||||
|
@ -30,7 +31,10 @@ def accept_payment(request, factureid):
|
||||||
'amount': facture.prix()
|
'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
|
@csrf_exempt
|
||||||
|
@ -43,7 +47,11 @@ def refuse_payment(request):
|
||||||
request,
|
request,
|
||||||
_("The payment has been refused.")
|
_("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
|
@csrf_exempt
|
||||||
def ipn(request):
|
def ipn(request):
|
||||||
|
@ -105,7 +113,7 @@ def comnpay(facture, request):
|
||||||
str(AssoOption.get_cached_value('payment_pass')),
|
str(AssoOption.get_cached_value('payment_pass')),
|
||||||
'https://' + host + reverse(
|
'https://' + host + reverse(
|
||||||
'cotisations:accept_payment',
|
'cotisations:accept_payment',
|
||||||
kwargs={'factureid':facture.id}
|
kwargs={'factureid': facture.id}
|
||||||
),
|
),
|
||||||
'https://' + host + reverse('cotisations:refuse_payment'),
|
'https://' + host + reverse('cotisations:refuse_payment'),
|
||||||
'https://' + host + reverse('cotisations:ipn'),
|
'https://' + host + reverse('cotisations:ipn'),
|
||||||
|
@ -113,20 +121,20 @@ def comnpay(facture, request):
|
||||||
"D"
|
"D"
|
||||||
)
|
)
|
||||||
r = {
|
r = {
|
||||||
'action' : 'https://secure.homologation.comnpay.com',
|
'action': 'https://secure.homologation.comnpay.com',
|
||||||
'method' : 'POST',
|
'method': 'POST',
|
||||||
'content' : p.buildSecretHTML(
|
'content': p.buildSecretHTML(
|
||||||
"Rechargement du solde",
|
"Rechargement du solde",
|
||||||
facture.prix(),
|
facture.prix(),
|
||||||
idTransaction=str(facture.id)
|
idTransaction=str(facture.id)
|
||||||
),
|
),
|
||||||
'amount' : facture.prix,
|
'amount': facture.prix,
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
# The payment systems supported by re2o
|
# The payment systems supported by re2o
|
||||||
PAYMENT_SYSTEM = {
|
PAYMENT_SYSTEM = {
|
||||||
'COMNPAY' : comnpay,
|
'COMNPAY': comnpay,
|
||||||
'NONE' : None
|
'NONE': None
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import hashlib
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
|
|
||||||
class Payment():
|
class Payment():
|
||||||
|
|
||||||
vad_number = ""
|
vad_number = ""
|
||||||
|
@ -15,7 +16,8 @@ class Payment():
|
||||||
source = ""
|
source = ""
|
||||||
typeTr = "D"
|
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.vad_number = vad_number
|
||||||
self.secret_key = secret_key
|
self.secret_key = secret_key
|
||||||
self.urlRetourOK = urlRetourOK
|
self.urlRetourOK = urlRetourOK
|
||||||
|
@ -24,36 +26,45 @@ class Payment():
|
||||||
self.source = source
|
self.source = source
|
||||||
self.typeTr = typeTr
|
self.typeTr = typeTr
|
||||||
|
|
||||||
def buildSecretHTML(self, produit="Produit", montant="0.00", idTransaction=""):
|
def buildSecretHTML(self, produit="Produit", montant="0.00",
|
||||||
|
idTransaction=""):
|
||||||
if 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:
|
else:
|
||||||
self.idTransaction = idTransaction
|
self.idTransaction = idTransaction
|
||||||
|
|
||||||
array_tpe = OrderedDict(
|
array_tpe = OrderedDict(
|
||||||
montant= str(montant),
|
montant=str(montant),
|
||||||
idTPE= self.vad_number,
|
idTPE=self.vad_number,
|
||||||
idTransaction= self.idTransaction,
|
idTransaction=self.idTransaction,
|
||||||
devise= "EUR",
|
devise="EUR",
|
||||||
lang= 'fr',
|
lang='fr',
|
||||||
nom_produit= produit,
|
nom_produit=produit,
|
||||||
source= self.source,
|
source=self.source,
|
||||||
urlRetourOK= self.urlRetourOK,
|
urlRetourOK=self.urlRetourOK,
|
||||||
urlRetourNOK= self.urlRetourNOK,
|
urlRetourNOK=self.urlRetourNOK,
|
||||||
typeTr= str(self.typeTr)
|
typeTr=str(self.typeTr)
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.urlIPN!="":
|
if self.urlIPN != "":
|
||||||
array_tpe['urlIPN'] = self.urlIPN
|
array_tpe['urlIPN'] = self.urlIPN
|
||||||
|
|
||||||
array_tpe['key'] = self.secret_key;
|
array_tpe['key'] = self.secret_key
|
||||||
strWithKey = base64.b64encode(bytes('|'.join(array_tpe.values()), 'utf-8'))
|
strWithKey = base64.b64encode(bytes(
|
||||||
|
'|'.join(array_tpe.values()),
|
||||||
|
'utf-8'
|
||||||
|
))
|
||||||
del array_tpe["key"]
|
del array_tpe["key"]
|
||||||
array_tpe['sec'] = hashlib.sha512(strWithKey).hexdigest()
|
array_tpe['sec'] = hashlib.sha512(strWithKey).hexdigest()
|
||||||
|
|
||||||
ret = ""
|
ret = ""
|
||||||
for key in array_tpe:
|
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
|
return ret
|
||||||
|
|
||||||
|
@ -61,8 +72,10 @@ class Payment():
|
||||||
if "sec" in values:
|
if "sec" in values:
|
||||||
sec = values['sec']
|
sec = values['sec']
|
||||||
del 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()
|
return strWithKey.upper() == sec.upper()
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ def render_invoice(request, ctx={}):
|
||||||
date, the user, the articles, the prices, ...
|
date, the user, the articles, the prices, ...
|
||||||
"""
|
"""
|
||||||
filename = '_'.join([
|
filename = '_'.join([
|
||||||
'invoice',
|
'invoice',
|
||||||
slugify(ctx['asso_name']),
|
slugify(ctx['asso_name']),
|
||||||
slugify(ctx['recipient_name']),
|
slugify(ctx['recipient_name']),
|
||||||
str(ctx['DATE'].year),
|
str(ctx['DATE'].year),
|
||||||
|
@ -54,9 +54,12 @@ def render_invoice(request, ctx={}):
|
||||||
str(ctx['DATE'].day),
|
str(ctx['DATE'].day),
|
||||||
])
|
])
|
||||||
r = render_tex(request, 'cotisations/factures.tex', ctx)
|
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
|
return r
|
||||||
|
|
||||||
|
|
||||||
def render_tex(request, template, ctx={}):
|
def render_tex(request, template, ctx={}):
|
||||||
"""
|
"""
|
||||||
Creates a PDF from a LaTex templates using pdflatex.
|
Creates a PDF from a LaTex templates using pdflatex.
|
||||||
|
@ -66,13 +69,13 @@ def render_tex(request, template, ctx={}):
|
||||||
context = Context(ctx)
|
context = Context(ctx)
|
||||||
template = get_template(template)
|
template = get_template(template)
|
||||||
rendered_tpl = template.render(context).encode('utf-8')
|
rendered_tpl = template.render(context).encode('utf-8')
|
||||||
|
|
||||||
with tempfile.TemporaryDirectory() as tempdir:
|
with tempfile.TemporaryDirectory() as tempdir:
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
process = Popen(
|
process = Popen(
|
||||||
['pdflatex', '-output-directory', tempdir],
|
['pdflatex', '-output-directory', tempdir],
|
||||||
stdin = PIPE,
|
stdin=PIPE,
|
||||||
stdout = PIPE,
|
stdout=PIPE,
|
||||||
)
|
)
|
||||||
process.communicate(rendered_tpl)
|
process.communicate(rendered_tpl)
|
||||||
with open(os.path.join(tempdir, 'texput.pdf'), 'rb') as f:
|
with open(os.path.join(tempdir, 'texput.pdf'), 'rb') as f:
|
||||||
|
|
|
@ -101,12 +101,11 @@ urlpatterns = [
|
||||||
views.index_paiement,
|
views.index_paiement,
|
||||||
name='index-paiement'
|
name='index-paiement'
|
||||||
),
|
),
|
||||||
url(
|
url(r'history/(?P<object_name>\w+)/(?P<object_id>[0-9]+)$',
|
||||||
r'history/(?P<object_name>\w+)/(?P<object_id>[0-9]+)$',
|
|
||||||
re2o.views.history,
|
re2o.views.history,
|
||||||
name='history',
|
name='history',
|
||||||
kwargs={'application':'cotisations'},
|
kwargs={'application': 'cotisations'},
|
||||||
),
|
),
|
||||||
url(r'^control/$',
|
url(r'^control/$',
|
||||||
views.control,
|
views.control,
|
||||||
name='control'
|
name='control'
|
||||||
|
@ -122,14 +121,14 @@ urlpatterns = [
|
||||||
url(r'^payment/accept/(?P<factureid>[0-9]+)$',
|
url(r'^payment/accept/(?P<factureid>[0-9]+)$',
|
||||||
payment.accept_payment,
|
payment.accept_payment,
|
||||||
name='accept_payment'
|
name='accept_payment'
|
||||||
),
|
),
|
||||||
url(r'^payment/refuse/$',
|
url(r'^payment/refuse/$',
|
||||||
payment.refuse_payment,
|
payment.refuse_payment,
|
||||||
name='refuse_payment'
|
name='refuse_payment'
|
||||||
),
|
),
|
||||||
url(r'^payment/ipn/$',
|
url(r'^payment/ipn/$',
|
||||||
payment.ipn,
|
payment.ipn,
|
||||||
name='ipn'
|
name='ipn'
|
||||||
),
|
),
|
||||||
url(r'^$', views.index, name='index'),
|
url(r'^$', views.index, name='index'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -77,7 +77,6 @@ from . import payment as online_payment
|
||||||
from .tex import render_invoice
|
from .tex import render_invoice
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_create(Facture)
|
@can_create(Facture)
|
||||||
@can_edit(User)
|
@can_edit(User)
|
||||||
|
@ -102,9 +101,13 @@ def new_facture(request, user, userid):
|
||||||
# Building the invocie form and the article formset
|
# Building the invocie form and the article formset
|
||||||
invoice_form = NewFactureForm(request.POST or None, instance=invoice)
|
invoice_form = NewFactureForm(request.POST or None, instance=invoice)
|
||||||
if request.user.is_class_club:
|
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:
|
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():
|
if invoice_form.is_valid() and article_formset.is_valid():
|
||||||
new_invoice_instance = invoice_form.save(commit=False)
|
new_invoice_instance = invoice_form.save(commit=False)
|
||||||
|
@ -118,15 +121,18 @@ def new_facture(request, user, userid):
|
||||||
# the authorized minimum (negative_balance)
|
# the authorized minimum (negative_balance)
|
||||||
if user_balance:
|
if user_balance:
|
||||||
# TODO : change Paiement to Payment
|
# TODO : change Paiement to Payment
|
||||||
if new_invoice_instance.paiement == Paiement.objects.get_or_create(
|
if new_invoice_instance.paiement == (
|
||||||
moyen='solde'
|
Paiement.objects.get_or_create(moyen='solde')[0]
|
||||||
)[0]:
|
):
|
||||||
total_price = 0
|
total_price = 0
|
||||||
for art_item in articles:
|
for art_item in articles:
|
||||||
if art_item.cleaned_data:
|
if art_item.cleaned_data:
|
||||||
total_price += art_item.cleaned_data['article']\
|
total_price += (
|
||||||
.prix*art_item.cleaned_data['quantity']
|
art_item.cleaned_data['article'].prix *
|
||||||
if float(user.solde) - float(total_price) < negative_balance:
|
art_item.cleaned_data['quantity']
|
||||||
|
)
|
||||||
|
if (float(user.solde) - float(total_price)
|
||||||
|
< negative_balance):
|
||||||
messages.error(
|
messages.error(
|
||||||
request,
|
request,
|
||||||
_("Your balance is too low for this operation.")
|
_("Your balance is too low for this operation.")
|
||||||
|
@ -194,7 +200,7 @@ def new_facture(request, user, userid):
|
||||||
@can_change(Facture, 'pdf')
|
@can_change(Facture, 'pdf')
|
||||||
def new_facture_pdf(request):
|
def new_facture_pdf(request):
|
||||||
"""
|
"""
|
||||||
View used to generate a custom PDF invoice. It's mainly used to
|
View used to generate a custom PDF invoice. It's mainly used to
|
||||||
get invoices that are not taken into account, for the administrative
|
get invoices that are not taken into account, for the administrative
|
||||||
point of view.
|
point of view.
|
||||||
"""
|
"""
|
||||||
|
@ -205,9 +211,13 @@ def new_facture_pdf(request):
|
||||||
# Building the invocie form and the article formset
|
# Building the invocie form and the article formset
|
||||||
invoice_form = NewFactureFormPdf(request.POST or None)
|
invoice_form = NewFactureFormPdf(request.POST or None)
|
||||||
if request.user.is_class_club:
|
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:
|
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():
|
if invoice_form.is_valid() and articles_formset.is_valid():
|
||||||
# Get the article list and build an list out of it
|
# Get the article list and build an list out of it
|
||||||
# contiaining (article_name, article_price, quantity, total_price)
|
# 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
|
can be set as desired. This is also the view used to invalidate
|
||||||
an invoice.
|
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)
|
purchases_objects = Vente.objects.filter(facture=facture)
|
||||||
purchase_form_set = modelformset_factory(
|
purchase_form_set = modelformset_factory(
|
||||||
Vente,
|
Vente,
|
||||||
|
@ -311,7 +325,10 @@ def edit_facture(request, facture, factureid):
|
||||||
extra=0,
|
extra=0,
|
||||||
max_num=len(purchases_objects)
|
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.is_valid() and purchase_form.is_valid():
|
||||||
if invoice_form.changed_data:
|
if invoice_form.changed_data:
|
||||||
invoice_form.save()
|
invoice_form.save()
|
||||||
|
@ -385,7 +402,7 @@ def credit_solde(request, user, userid):
|
||||||
def add_article(request):
|
def add_article(request):
|
||||||
"""
|
"""
|
||||||
View used to add an article.
|
View used to add an article.
|
||||||
|
|
||||||
.. note:: If a purchase has already been sold, the price are calculated
|
.. note:: If a purchase has already been sold, the price are calculated
|
||||||
once and for all. That means even if the price of an article is edited
|
once and for all. That means even if the price of an article is edited
|
||||||
later, it won't change the invoice. That is really important to keep
|
later, it won't change the invoice. That is really important to keep
|
||||||
|
@ -613,7 +630,8 @@ def control(request):
|
||||||
View used to control the invoices all at once.
|
View used to control the invoices all at once.
|
||||||
"""
|
"""
|
||||||
pagination_number = GeneralOption.get_cached_value('pagination_number')
|
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 = SortTable.sort(
|
||||||
invoice_list,
|
invoice_list,
|
||||||
request.GET.get('col'),
|
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)
|
Q(type_user='All') | Q(type_user=request.user.class_name)
|
||||||
)
|
)
|
||||||
if request.user.is_class_club:
|
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:
|
else:
|
||||||
article_formset = formset_factory(SelectUserArticleForm)(request.POST or None)
|
article_formset = formset_factory(SelectUserArticleForm)(
|
||||||
|
request.POST or None
|
||||||
|
)
|
||||||
|
|
||||||
if article_formset.is_valid():
|
if article_formset.is_valid():
|
||||||
articles = article_formset
|
articles = article_formset
|
||||||
|
@ -826,7 +848,9 @@ def recharge(request):
|
||||||
refill_form = RechargeForm(request.POST or None, user=request.user)
|
refill_form = RechargeForm(request.POST or None, user=request.user)
|
||||||
if refill_form.is_valid():
|
if refill_form.is_valid():
|
||||||
invoice = Facture(user=request.user)
|
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.paiement = payment
|
||||||
invoice.valid = False
|
invoice.valid = False
|
||||||
invoice.save()
|
invoice.save()
|
||||||
|
@ -837,7 +861,9 @@ def recharge(request):
|
||||||
number=1
|
number=1
|
||||||
)
|
)
|
||||||
purchase.save()
|
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 render(request, 'cotisations/payment.html', content)
|
||||||
return form({
|
return form({
|
||||||
'rechargeform': refill_form
|
'rechargeform': refill_form
|
||||||
|
|
Loading…
Reference in a new issue