Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
R
re2o
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nounous
re2o
Commits
f2f4336e
Commit
f2f4336e
authored
Apr 09, 2018
by
Maël Kervella
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Translation : translate docstrings of cotisations
parent
8da337c5
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
543 additions
and
368 deletions
+543
-368
cotisations/forms.py
cotisations/forms.py
+62
-44
cotisations/models.py
cotisations/models.py
+140
-89
cotisations/payment.py
cotisations/payment.py
+24
-8
cotisations/tex.py
cotisations/tex.py
+13
-0
cotisations/views.py
cotisations/views.py
+304
-227
No files found.
cotisations/forms.py
View file @
f2f4336e
...
...
@@ -20,19 +20,18 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""
Forms de l'application cotisation de re2o. Dépendance avec les models,
importé par les views.
Permet de créer une nouvelle facture pour un user (NewFactureForm),
et de l'editer (soit l'user avec EditFactureForm,
soit le trésorier avec TrezEdit qui a plus de possibilités que self
notamment sur le controle trésorier SelectArticleForm est utilisée
lors de la creation d'une facture en
parrallèle de NewFacture pour le choix des articles désirés.
(la vue correspondante est unique)
ArticleForm, BanqueForm, PaiementForm permettent aux admin d'ajouter,
éditer ou supprimer une banque/moyen de paiement ou un article
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
anything related to 'cotisations' :
* Payments Methods
* Banks
* Invoices
* Articles
See the details for each of these operations in the documentation
of each of the method.
"""
from
__future__
import
unicode_literals
...
...
@@ -51,9 +50,10 @@ from re2o.field_permissions import FieldPermissionFormMixin
from
re2o.mixins
import
FormRevMixin
class
NewFactureForm
(
FormRevMixin
,
ModelForm
):
"""Creation d'une facture, moyen de paiement, banque et numero
de cheque"""
# TODO : translate doc string in English
"""
Form used to create a new invoice by using a payment method, a bank and a
cheque number.
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
prefix
=
kwargs
.
pop
(
'prefix'
,
self
.
Meta
.
model
.
__name__
)
super
(
NewFactureForm
,
self
).
__init__
(
*
args
,
prefix
=
prefix
,
**
kwargs
)
...
...
@@ -91,8 +91,10 @@ class NewFactureForm(FormRevMixin, ModelForm):
class
CreditSoldeForm
(
NewFactureForm
):
"""Permet de faire des opérations sur le solde si il est activé"""
# TODO : translate docstring to English
"""
Form used to make some operations on the user's balance if the option is
activated.
"""
class
Meta
(
NewFactureForm
.
Meta
):
model
=
Facture
fields
=
[
'paiement'
,
'banque'
,
'cheque'
]
...
...
@@ -108,8 +110,9 @@ class CreditSoldeForm(NewFactureForm):
class
SelectUserArticleForm
(
FormRevMixin
,
Form
):
"""Selection d'un article lors de la creation d'une facture"""
# TODO : translate docstring to English
"""
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'
)),
label
=
_l
(
"Article"
),
...
...
@@ -123,8 +126,9 @@ class SelectUserArticleForm(FormRevMixin, Form):
class
SelectClubArticleForm
(
Form
):
"""Selection d'un article lors de la creation d'une facture"""
# TODO : translate docstring to English
"""
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'
)),
label
=
_l
(
"Article"
),
...
...
@@ -138,8 +142,9 @@ class SelectClubArticleForm(Form):
# TODO : change Facture to Invoice
class
NewFactureFormPdf
(
Form
):
"""Creation d'un pdf facture par le trésorier"""
# TODO : translate docstring to English
"""
Form used to create a custom PDF invoice.
"""
article
=
forms
.
ModelMultipleChoiceField
(
queryset
=
Article
.
objects
.
all
(),
label
=
_l
(
"Article"
)
...
...
@@ -162,8 +167,10 @@ class NewFactureFormPdf(Form):
# TODO : change Facture to Invoice
class
EditFactureForm
(
FieldPermissionFormMixin
,
NewFactureForm
):
"""Edition d'une facture : moyen de paiement, banque, user parent"""
# TODO : translate docstring to English
"""
Form used to edit an invoice and its fields : payment method, bank,
user associated, ...
"""
class
Meta
(
NewFactureForm
.
Meta
):
# TODO : change Facture to Invoice
model
=
Facture
...
...
@@ -179,8 +186,9 @@ class EditFactureForm(FieldPermissionFormMixin, NewFactureForm):
class
ArticleForm
(
FormRevMixin
,
ModelForm
):
"""Creation d'un article. Champs : nom, cotisation, durée"""
# TODO : translate docstring to English
"""
Form used to create an article.
"""
class
Meta
:
model
=
Article
fields
=
'__all__'
...
...
@@ -192,9 +200,10 @@ class ArticleForm(FormRevMixin, ModelForm):
class
DelArticleForm
(
FormRevMixin
,
Form
):
"""Suppression d'un ou plusieurs articles en vente. Choix
parmis les modèles"""
# TODO : translate docstring to English
"""
Form used to delete one or more of the currently available articles.
The user must choose the one to delete by checking the boxes.
"""
articles
=
forms
.
ModelMultipleChoiceField
(
queryset
=
Article
.
objects
.
none
(),
label
=
_l
(
"Existing articles"
),
...
...
@@ -212,9 +221,11 @@ class DelArticleForm(FormRevMixin, Form):
# TODO : change Paiement to Payment
class
PaiementForm
(
FormRevMixin
,
ModelForm
):
"""Creation d'un moyen de paiement, champ text moyen et type
permettant d'indiquer si il s'agit d'un chèque ou non pour le form"""
# TODO : translate docstring to English
"""
Form used to create a new payment method.
The 'cheque' type is used to associate a specific behaviour requiring
a cheque number and a bank.
"""
class
Meta
:
model
=
Paiement
# TODO : change moyen to method and type_paiement to payment_type
...
...
@@ -233,9 +244,10 @@ class PaiementForm(FormRevMixin, ModelForm):
# TODO : change paiement to payment
class
DelPaiementForm
(
FormRevMixin
,
Form
):
"""Suppression d'un ou plusieurs moyens de paiements, selection
parmis les models"""
# TODO : translate docstring to English
"""
Form used to delete one or more payment methods.
The user must choose the one to delete by checking the boxes.
"""
# TODO : change paiement to payment
paiements
=
forms
.
ModelMultipleChoiceField
(
queryset
=
Paiement
.
objects
.
none
(),
...
...
@@ -254,8 +266,9 @@ class DelPaiementForm(FormRevMixin, Form):
# TODO : change banque to bank
class
BanqueForm
(
FormRevMixin
,
ModelForm
):
"""Creation d'une banque, field name"""
# TODO : translate docstring to Englishh
"""
Form used to create a bank.
"""
class
Meta
:
# TODO : change banque to bank
model
=
Banque
...
...
@@ -269,8 +282,10 @@ class BanqueForm(FormRevMixin, ModelForm):
# TODO : change banque to bank
class
DelBanqueForm
(
FormRevMixin
,
Form
):
"""Selection d'une ou plusieurs banques, pour suppression"""
# TODO : translate docstrign to English
"""
Form used to delete one or more banks.
The use must choose the one to delete by checking the boxes.
"""
# TODO : change banque to bank
banques
=
forms
.
ModelMultipleChoiceField
(
queryset
=
Banque
.
objects
.
none
(),
...
...
@@ -289,9 +304,9 @@ class DelBanqueForm(FormRevMixin, Form):
# TODO : change facture to Invoice
class
NewFactureSoldeForm
(
NewFactureForm
):
"""
Creation d'une facture, moyen de paiement, banque et numero
de cheque"""
# TODO : translate docstring to English
"""
Form used to create an invoice
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
prefix
=
kwargs
.
pop
(
'prefix'
,
self
.
Meta
.
model
.
__name__
)
self
.
fields
[
'cheque'
].
required
=
False
...
...
@@ -335,6 +350,9 @@ class NewFactureSoldeForm(NewFactureForm):
# TODO : Better name and docstring
class
RechargeForm
(
FormRevMixin
,
Form
):
"""
Form used to refill a user's balance
"""
value
=
forms
.
FloatField
(
label
=
_l
(
"Amount"
),
min_value
=
0.01
,
...
...
cotisations/models.py
View file @
f2f4336e
...
...
@@ -21,28 +21,14 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""
Definition des models bdd pour les factures et cotisation.
Pièce maitresse : l'ensemble du code intelligent se trouve ici,
dans les clean et save des models ainsi que de leur methodes supplémentaires.
The database models for the 'cotisation' app of re2o.
The goal is to keep the main actions here, i.e. the 'clean' and 'save'
function are higly reposnsible for the changes, checking the coherence of the
data and the good behaviour in general for not breaking the database.
Facture : reliée à un user, elle a un moyen de paiement, une banque (option),
une ou plusieurs ventes
Article : liste des articles en vente, leur prix, etc
Vente : ensemble des ventes effectuées, reliées à une facture (foreignkey)
Banque : liste des banques existantes
Cotisation : objets de cotisation, contenant un début et une fin. Reliées
aux ventes, en onetoone entre une vente et une cotisation.
Crées automatiquement au save des ventes.
Post_save et Post_delete : sychronisation des services et régénération
des services d'accès réseau (ex dhcp) lors de la vente d'une cotisation
par exemple
For further details on each of those models, see the documentation details for
each.
"""
# TODO : translate docstring to English
from
__future__
import
unicode_literals
from
dateutil.relativedelta
import
relativedelta
...
...
@@ -65,11 +51,24 @@ from re2o.mixins import AclMixin, RevMixin
# TODO : change facture to invoice
class
Facture
(
RevMixin
,
AclMixin
,
FieldPermissionModelMixin
,
models
.
Model
):
""" Définition du modèle des factures. Une facture regroupe une ou
plusieurs ventes, rattachée à un user, et reliée à un moyen de paiement
et si il y a lieu un numero pour les chèques. Possède les valeurs
valides et controle (trésorerie)"""
# TODO : translate docstrign to English
"""
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)
* a payment method (the one used by the user)
* (if applicable) a bank
* (if applicable) a cheque number.
Every invoice is dated throught the 'date' value.
An invoice has a 'controlled' value (default : False) which means that
someone with high enough rights has controlled that invoice and taken it
into account. It also has a 'valid' value (default : True) which means
that someone with high enough rights has decided that this invoice was not
valid (thus it's like the user never paid for his articles). It may be
necessary in case of non-payment.
"""
user
=
models
.
ForeignKey
(
'users.User'
,
on_delete
=
models
.
PROTECT
)
# TODO : change paiement to payment
...
...
@@ -122,20 +121,21 @@ class Facture(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
# TODO : change prix to price
def
prix
(
self
):
"""
Renvoie le prix brut sans les quantités. Méthode
dépréciée"""
# TODO : translate docstring to English
# TODO : change prix to price
pri
x
=
Vente
.
objects
.
filter
(
"""
Returns: the raw price without the quantities.
Deprecated, use :total_price instead.
"""
pri
ce
=
Vente
.
objects
.
filter
(
facture
=
self
).
aggregate
(
models
.
Sum
(
'prix'
))[
'prix__sum'
]
return
pri
x
return
pri
ce
# TODO : change prix to price
def
prix_total
(
self
):
"""Prix total : somme des produits prix_unitaire et quantité des
ventes de l'objet"""
# TODO : translate docstrign to English
"""
Returns: the total price for an invoice. Sum all the articles' prices
and take the quantities into account.
"""
# TODO : change Vente to somethingelse
return
Vente
.
objects
.
filter
(
facture
=
self
...
...
@@ -147,8 +147,10 @@ class Facture(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
)[
'total'
]
def
name
(
self
):
"""String, somme des name des ventes de self"""
# TODO : translate docstring to English
"""
Returns : a string with the name of all the articles in the invoice.
Used for reprensenting the invoice with a string.
"""
name
=
' - '
.
join
(
Vente
.
objects
.
filter
(
facture
=
self
).
values_list
(
'name'
,
flat
=
True
))
...
...
@@ -204,8 +206,9 @@ class Facture(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
@
receiver
(
post_save
,
sender
=
Facture
)
def
facture_post_save
(
sender
,
**
kwargs
):
"""Post save d'une facture, synchronise l'user ldap"""
# TODO : translate docstrign into English
"""
Synchronise the LDAP user after an invoice has been saved.
"""
facture
=
kwargs
[
'instance'
]
user
=
facture
.
user
user
.
ldap_sync
(
base
=
False
,
access_refresh
=
True
,
mac_refresh
=
False
)
...
...
@@ -213,18 +216,26 @@ def facture_post_save(sender, **kwargs):
@
receiver
(
post_delete
,
sender
=
Facture
)
def
facture_post_delete
(
sender
,
**
kwargs
):
"""Après la suppression d'une facture, on synchronise l'user ldap"""
# TODO : translate docstring into English
"""
Synchronise the LDAP user after an invoice has been deleted.
"""
user
=
kwargs
[
'instance'
].
user
user
.
ldap_sync
(
base
=
False
,
access_refresh
=
True
,
mac_refresh
=
False
)
# TODO : change Vente to Purchase
class
Vente
(
RevMixin
,
AclMixin
,
models
.
Model
):
"""Objet vente, contient une quantité, une facture parente, un nom,
un prix. Peut-être relié à un objet cotisation, via le boolean
iscotisation"""
# TODO : translate docstring into English
"""
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)
* an article
* (if applicable) a cotisation (which holds some informations about
the effect of the purchase on the time agreed for this user)
"""
# TODO : change this to English
COTISATION_TYPE
=
(
...
...
@@ -281,15 +292,16 @@ class Vente(RevMixin, AclMixin, models.Model):
# TODO : change prix_total to total_price
def
prix_total
(
self
):
"""Renvoie le prix_total de self (nombre*prix)"""
# TODO : translate docstring to english
"""
Returns: the total of price for this amount of items.
"""
return
self
.
prix
*
self
.
number
def
update_cotisation
(
self
):
"""
Mets à jour l'objet related cotisation de la vente, si
il existe : update la date de fin à partir de la durée d
e
la vente"""
# TODO : translate docstring to English
"""
Update the related object 'cotisation' if there is one. Based on th
e
duration of the purchase.
"""
if
hasattr
(
self
,
'cotisation'
):
cotisation
=
self
.
cotisation
cotisation
.
date_end
=
cotisation
.
date_start
+
relativedelta
(
...
...
@@ -297,10 +309,11 @@ class Vente(RevMixin, AclMixin, models.Model):
return
def
create_cotis
(
self
,
date_start
=
False
):
"""Update et crée l'objet cotisation associé à une facture, prend
en argument l'user, la facture pour la quantitéi, et l'article pour
la durée"""
# TODO : translate docstring to English
"""
Update and create a 'cotisation' related object if there is a
cotisation_type defined (which means the article sold represents
a cotisation)
"""
if
not
hasattr
(
self
,
'cotisation'
)
and
self
.
type_cotisation
:
cotisation
=
Cotisation
(
vente
=
self
)
cotisation
.
type_cotisation
=
self
.
type_cotisation
...
...
@@ -328,8 +341,12 @@ class Vente(RevMixin, AclMixin, models.Model):
return
def
save
(
self
,
*
args
,
**
kwargs
):
# TODO : ecrire une docstring
# On verifie que si iscotisation, duration est présent
"""
Save a purchase object and check if all the fields are coherents
It also update the associated cotisation in the changes have some
effect on the user's cotisation
"""
# Checking that if a cotisation is specified, there is also a duration
if
self
.
type_cotisation
and
not
self
.
duration
:
raise
ValidationError
(
_
(
"A cotisation should always have a duration."
)
...
...
@@ -372,38 +389,44 @@ class Vente(RevMixin, AclMixin, models.Model):
# TODO : change vente to purchase
@
receiver
(
post_save
,
sender
=
Vente
)
def
vente_post_save
(
sender
,
**
kwargs
):
"""
Post save d'une vente, déclencge la création de l'objet cotisation
si il y a lieu(si iscotisation) """
# TODO : translate docstring to English
# TODO : change vente to purchase
vent
e
=
kwargs
[
'instance'
]
"""
Creates a 'cotisation' related object if needed and synchronise the
LDAP user when a purchase has been saved.
"""
purchas
e
=
kwargs
[
'instance'
]
if
hasattr
(
vente
,
'cotisation'
):
vente
.
cotisation
.
vente
=
vent
e
vent
e
.
cotisation
.
save
()
if
vent
e
.
type_cotisation
:
vent
e
.
create_cotis
()
vent
e
.
cotisation
.
save
()
user
=
vent
e
.
facture
.
user
purchase
.
cotisation
.
vente
=
purchas
e
purchas
e
.
cotisation
.
save
()
if
purchas
e
.
type_cotisation
:
purchas
e
.
create_cotis
()
purchas
e
.
cotisation
.
save
()
user
=
purchas
e
.
facture
.
user
user
.
ldap_sync
(
base
=
False
,
access_refresh
=
True
,
mac_refresh
=
False
)
# TODO : change vente to purchase
@
receiver
(
post_delete
,
sender
=
Vente
)
def
vente_post_delete
(
sender
,
**
kwargs
):
"""Après suppression d'une vente, on synchronise l'user ldap (ex
suppression d'une cotisation"""
# TODO : translate docstring to English
# TODO : change vente to purchase
vente
=
kwargs
[
'instance'
]
if
vente
.
type_cotisation
:
user
=
vente
.
facture
.
user
"""
Synchronise the LDAP user after a purchase has been deleted.
"""
purchase
=
kwargs
[
'instance'
]
if
purchase
.
type_cotisation
:
user
=
purchase
.
facture
.
user
user
.
ldap_sync
(
base
=
False
,
access_refresh
=
True
,
mac_refresh
=
False
)
class
Article
(
RevMixin
,
AclMixin
,
models
.
Model
):
"""Liste des articles en vente : prix, nom, et attribut iscotisation
et duree si c'est une cotisation"""
# TODO : translate docstring to English
"""
The definition of an article model. It represents an 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 duration (if it is a cotisation)
* a type of user (indicating what kind of user can buy this article)
"""
# TODO : Either use TYPE or TYPES in both choices but not both
USER_TYPES
=
(
...
...
@@ -473,8 +496,13 @@ class Article(RevMixin, AclMixin, models.Model):
class
Banque
(
RevMixin
,
AclMixin
,
models
.
Model
):
"""Liste des banques"""
# TODO : translate docstring to English
"""
The model defining a bank. It represents a user's bank. It's mainly used
for statistics by regrouping the user under their bank's name and avoid
the use of a simple name which leads (by experience) to duplicates that
only differs by a capital letter, a space, a misspelling, ... That's why
it's easier to use simple object for the banks.
"""
name
=
models
.
CharField
(
max_length
=
255
,
...
...
@@ -494,8 +522,14 @@ class Banque(RevMixin, AclMixin, models.Model):
# TODO : change Paiement to Payment
class
Paiement
(
RevMixin
,
AclMixin
,
models
.
Model
):
"""Moyens de paiement"""
# TODO : translate docstring to English
"""
The model defining a payment method. It is how the user is paying for the
invoice. It's easier to know this information when doing the accouts.
It is represented by:
* a name
* 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"
)),
...
...
@@ -524,11 +558,16 @@ class Paiement(RevMixin, AclMixin, models.Model):
return
self
.
moyen
def
clean
(
self
):
"""
Override of the herited clean function to get a correct name
"""
self
.
moyen
=
self
.
moyen
.
title
()
def
save
(
self
,
*
args
,
**
kwargs
):
"""Un seul type de paiement peut-etre cheque..."""
# TODO : translate docstring to English
"""
Override of the herited save function to be sure only one payment
method of type 'cheque' exists.
"""
if
Paiement
.
objects
.
filter
(
type_paiement
=
1
).
count
()
>
1
:
raise
ValidationError
(
_
(
"You cannot have multiple payment method of type cheque"
)
...
...
@@ -537,8 +576,16 @@ class Paiement(RevMixin, AclMixin, models.Model):
class
Cotisation
(
RevMixin
,
AclMixin
,
models
.
Model
):
"""Objet cotisation, debut et fin, relié en onetoone à une vente"""
# TODO : translate docstring to English
"""
The model defining a cotisation. It holds information about the time a user
is allowed when he has paid something.
It characterised by :
* a date_start (the date when the cotisaiton begins/began
* a date_end (the date when the cotisation ends/ended
* a type of cotisation (which indicates the implication of such
cotisation)
* a purchase (the related objects this cotisation is linked to)
"""
COTISATION_TYPE
=
(
(
'Connexion'
,
_l
(
"Connexion"
)),
...
...
@@ -602,8 +649,10 @@ class Cotisation(RevMixin, AclMixin, models.Model):
@
receiver
(
post_save
,
sender
=
Cotisation
)
def
cotisation_post_save
(
sender
,
**
kwargs
):
"""Après modification d'une cotisation, regeneration des services"""
# TODO : translate docstring to English
"""
Mark some services as needing a regeneration after the edition of a
cotisation. Indeed the membership status may have changed.
"""
regen
(
'dns'
)
regen
(
'dhcp'
)
regen
(
'mac_ip_list'
)
...
...
@@ -613,8 +662,10 @@ def cotisation_post_save(sender, **kwargs):
# TODO : should be name cotisation_post_delete
@
receiver
(
post_delete
,
sender
=
Cotisation
)
def
vente_post_delete
(
sender
,
**
kwargs
):
"""Après suppression d'une vente, régénération des services"""
# TODO : translate docstring to English
"""
Mark some services as needing a regeneration after the deletion of a
cotisation. Indeed the membership status may have changed.
"""
cotisation
=
kwargs
[
'instance'
]
regen
(
'mac_ip_list'
)
regen
(
'mailing'
)
cotisations/payment.py
View file @
f2f4336e
...
...
@@ -20,6 +20,9 @@ from .payment_utils.comnpay import Payment as ComnpayPayment
@
csrf_exempt
@
login_required
def
accept_payment
(
request
,
factureid
):
"""
The view called when an online payment has been accepted.
"""
facture
=
get_object_or_404
(
Facture
,
id
=
factureid
)
messages
.
success
(
request
,
...
...
@@ -33,6 +36,9 @@ def accept_payment(request, factureid):
@
csrf_exempt
@
login_required
def
refuse_payment
(
request
):
"""
The view called when an online payment has been refused.
"""
messages
.
error
(
request
,
_
(
"The payment has been refused."
)
...
...
@@ -41,6 +47,11 @@ def refuse_payment(request):
@
csrf_exempt
def
ipn
(
request
):
"""
The view called by Comnpay server to validate the transaction.
Verify that we can firmly save the user's action and notify
Comnpay with 400 response if not or with a 200 response if yes
"""
p
=
ComnpayPayment
()
order
=
(
'idTpe'
,
'idTransaction'
,
'montant'
,
'result'
,
'sec'
,
)
try
:
...
...
@@ -55,8 +66,7 @@ def ipn(request):
idTpe
=
request
.
POST
[
'idTpe'
]
idTransaction
=
request
.
POST
[
'idTransaction'
]
# On vérifie que le paiement nous est destiné
# TODO : translate comment to English
# Checking that the payment is actually for us.
if
not
idTpe
==
AssoOption
.
get_cached_value
(
'payment_id'
):
return
HttpResponseBadRequest
(
"HTTP/1.1 400 Bad Request"
)
...
...
@@ -67,23 +77,28 @@ def ipn(request):
facture
=
get_object_or_404
(
Facture
,
id
=
factureid
)
# TODO : translate comments to English
# On vérifie que le paiement est valide
# Checking that the payment is valid
if
not
result
:
#
Le paiement a échoué : on effectue les actions nécessaires (On indique qu'elle a échoué)
#
Payment failed: Cancelling the invoice operation
facture
.
delete
()
#
On notifie au serveur ComNPay qu'on a reçu les données pour traitement
# And send the response to Comnpay indicating we have well
#
received the failure information.
return
HttpResponse
(
"HTTP/1.1 200 OK"
)
facture
.
valid
=
True
facture
.
save
()
# A nouveau, on notifie au serveur qu'on a bien traité les données
# Everything worked we send a reponse to Comnpay indicating that
# it's ok for them to proceed
return
HttpResponse
(
"HTTP/1.0 200 OK"
)
def
comnpay
(
facture
,
request
):
"""
Build a request to start the negociation with Comnpay by using
a facture id, the price and the secret transaction data stored in
the preferences.
"""
host
=
request
.
get_host
()
p
=
ComnpayPayment
(
str
(
AssoOption
.
get_cached_value
(
'payment_id'
)),
...
...
@@ -110,6 +125,7 @@ def comnpay(facture, request):
return
r
# The payment systems supported by re2o
PAYMENT_SYSTEM
=
{
'COMNPAY'
:
comnpay
,
'NONE'
:
None
...
...
cotisations/tex.py
View file @
f2f4336e
...
...
@@ -19,6 +19,10 @@
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""tex.py
Module in charge of rendering some LaTex templates.
Used to generated PDF invoice.
"""
from
django.template.loader
import
get_template
from
django.template
import
Context
...
...
@@ -37,6 +41,10 @@ CACHE_TIMEOUT = getattr(settings, 'TEX_CACHE_TIMEOUT', 86400) # 1 day
def
render_invoice
(
request
,
ctx
=
{}):
"""
Render an invoice using some available information such as the current
date, the user, the articles, the prices, ...
"""