mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-22 03:13:12 +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 _
|
||||
|
||||
|
||||
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.")
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 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.
|
||||
|
||||
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.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
|
||||
|
||||
|
@ -47,7 +47,8 @@ from preferences.models import OptionalUser
|
|||
from users.models import User
|
||||
|
||||
from re2o.field_permissions import FieldPermissionFormMixin
|
||||
from re2o.mixins import FormRevMixin
|
||||
from re2o.mixins import FormRevMixin
|
||||
|
||||
|
||||
class NewFactureForm(FormRevMixin, ModelForm):
|
||||
"""
|
||||
|
@ -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 €.") % {
|
||||
|
|
|
@ -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
|
||||
something (it can be multiple article paid at once).
|
||||
|
||||
|
||||
An invoice is linked to :
|
||||
* one or more purchases (one for each article sold that time)
|
||||
* a user (the one who bought those articles)
|
||||
|
@ -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):
|
||||
|
@ -228,7 +245,7 @@ class Vente(RevMixin, AclMixin, models.Model):
|
|||
"""
|
||||
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.
|
||||
|
||||
|
||||
It's reprensentated by:
|
||||
* an amount (the number of items sold)
|
||||
* an invoice (whose the purchase is part of)
|
||||
|
@ -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
|
||||
|
@ -530,7 +557,7 @@ class Paiement(RevMixin, AclMixin, models.Model):
|
|||
* a type (used for the type 'cheque' which implies the use of a bank
|
||||
and an account number in related models)
|
||||
"""
|
||||
|
||||
|
||||
PAYMENT_TYPES = (
|
||||
(0, _l("Standard")),
|
||||
(1, _l("Cheque")),
|
||||
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ def render_invoice(request, ctx={}):
|
|||
date, the user, the articles, the prices, ...
|
||||
"""
|
||||
filename = '_'.join([
|
||||
'invoice',
|
||||
'invoice',
|
||||
slugify(ctx['asso_name']),
|
||||
slugify(ctx['recipient_name']),
|
||||
str(ctx['DATE'].year),
|
||||
|
@ -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.
|
||||
|
@ -66,13 +69,13 @@ def render_tex(request, template, ctx={}):
|
|||
context = Context(ctx)
|
||||
template = get_template(template)
|
||||
rendered_tpl = template.render(context).encode('utf-8')
|
||||
|
||||
|
||||
with tempfile.TemporaryDirectory() as tempdir:
|
||||
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:
|
||||
|
|
|
@ -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'),
|
||||
]
|
||||
|
|
|
@ -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.")
|
||||
|
@ -194,7 +200,7 @@ def new_facture(request, user, userid):
|
|||
@can_change(Facture, 'pdf')
|
||||
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
|
||||
point of view.
|
||||
"""
|
||||
|
@ -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()
|
||||
|
@ -385,7 +402,7 @@ def credit_solde(request, user, userid):
|
|||
def add_article(request):
|
||||
"""
|
||||
View used to add an article.
|
||||
|
||||
|
||||
.. 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
|
||||
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.
|
||||
"""
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue