|
|
@ -73,7 +73,7 @@ from .forms import ( |
|
|
NewFactureSoldeForm, |
|
|
NewFactureSoldeForm, |
|
|
RechargeForm |
|
|
RechargeForm |
|
|
) |
|
|
) |
|
|
from . import payment |
|
|
from . import payment as online_payment |
|
|
from .tex import render_invoice |
|
|
from .tex import render_invoice |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -82,50 +82,51 @@ from .tex import render_invoice |
|
|
@can_create(Facture) |
|
|
@can_create(Facture) |
|
|
@can_edit(User) |
|
|
@can_edit(User) |
|
|
def new_facture(request, user, userid): |
|
|
def new_facture(request, user, userid): |
|
|
"""Creation d'une facture pour un user. Renvoie la liste des articles |
|
|
""" |
|
|
et crée des factures dans un formset. Utilise un peu de js coté template |
|
|
View called to create a new invoice. |
|
|
pour ajouter des articles. |
|
|
Currently, Send the list of available articles for the user along with |
|
|
Parse les article et boucle dans le formset puis save les ventes, |
|
|
a formset of a new invoice (based on the `:forms:NewFactureForm()` form. |
|
|
enfin sauve la facture parente. |
|
|
A bit of JS is used in the template to add articles in a fancier way. |
|
|
TODO : simplifier cette fonction, déplacer l'intelligence coté models |
|
|
If everything is correct, save each one of the articles, save the |
|
|
Facture et Vente.""" |
|
|
purchase object associated and finally the newly created invoice. |
|
|
# TODO : translate docstring to English |
|
|
|
|
|
# TODO : change facture to invoice |
|
|
TODO : The whole verification process should be moved to the model. This |
|
|
facture = Facture(user=user) |
|
|
function should only act as a dumb interface between the model and the |
|
|
# TODO : change comment to English |
|
|
user. |
|
|
# Le template a besoin de connaitre les articles pour le js |
|
|
""" |
|
|
|
|
|
invoice = Facture(user=user) |
|
|
|
|
|
# The template needs the list of articles (for the JS part) |
|
|
article_list = Article.objects.filter( |
|
|
article_list = Article.objects.filter( |
|
|
Q(type_user='All') | Q(type_user=request.user.class_name) |
|
|
Q(type_user='All') | Q(type_user=request.user.class_name) |
|
|
) |
|
|
) |
|
|
# On envoie la form fature et un formset d'articles |
|
|
# Building the invocie form and the article formset |
|
|
# TODO : change facture to invoice |
|
|
invoice_form = NewFactureForm(request.POST or None, instance=invoice) |
|
|
facture_form = NewFactureForm(request.POST or None, instance=facture) |
|
|
|
|
|
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 facture_form.is_valid() and article_formset.is_valid(): |
|
|
|
|
|
new_facture_instance = facture_form.save(commit=False) |
|
|
if invoice_form.is_valid() and article_formset.is_valid(): |
|
|
|
|
|
new_invoice_instance = invoice_form.save(commit=False) |
|
|
articles = article_formset |
|
|
articles = article_formset |
|
|
# Si au moins un article est rempli |
|
|
# Check if at leat one article has been selected |
|
|
if any(art.cleaned_data for art in articles): |
|
|
if any(art.cleaned_data for art in articles): |
|
|
# TODO : change solde to balance |
|
|
user_balance = OptionalUser.get_cached_value('user_solde') |
|
|
user_solde = OptionalUser.get_cached_value('user_solde') |
|
|
negative_balance = OptionalUser.get_cached_value('solde_negatif') |
|
|
solde_negatif = OptionalUser.get_cached_value('solde_negatif') |
|
|
# If the paiement using balance has been activated, |
|
|
# Si on paye par solde, que l'option est activée, |
|
|
# checking that the total price won't get the user under |
|
|
# on vérifie que le négatif n'est pas atteint |
|
|
# the authorized minimum (negative_balance) |
|
|
if user_solde: |
|
|
if user_balance: |
|
|
# TODO : change Paiement to Payment |
|
|
# TODO : change Paiement to Payment |
|
|
if new_facture_instance.paiement == Paiement.objects.get_or_create( |
|
|
if new_invoice_instance.paiement == Paiement.objects.get_or_create( |
|
|
moyen='solde' |
|
|
moyen='solde' |
|
|
)[0]: |
|
|
)[0]: |
|
|
prix_total = 0 |
|
|
total_price = 0 |
|
|
for art_item in articles: |
|
|
for art_item in articles: |
|
|
if art_item.cleaned_data: |
|
|
if art_item.cleaned_data: |
|
|
# change prix to price |
|
|
total_price += art_item.cleaned_data['article']\ |
|
|
prix_total += art_item.cleaned_data['article']\ |
|
|
|
|
|
.prix*art_item.cleaned_data['quantity'] |
|
|
.prix*art_item.cleaned_data['quantity'] |
|
|
if float(user.solde) - float(prix_total) < solde_negatif: |
|
|
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.") |
|
|
@ -134,20 +135,26 @@ def new_facture(request, user, userid): |
|
|
'users:profil', |
|
|
'users:profil', |
|
|
kwargs={'userid': userid} |
|
|
kwargs={'userid': userid} |
|
|
)) |
|
|
)) |
|
|
new_facture_instance.save() |
|
|
# Saving the invoice |
|
|
|
|
|
new_invoice_instance.save() |
|
|
|
|
|
|
|
|
|
|
|
# Building a purchase for each article sold |
|
|
for art_item in articles: |
|
|
for art_item in articles: |
|
|
if art_item.cleaned_data: |
|
|
if art_item.cleaned_data: |
|
|
article = art_item.cleaned_data['article'] |
|
|
article = art_item.cleaned_data['article'] |
|
|
quantity = art_item.cleaned_data['quantity'] |
|
|
quantity = art_item.cleaned_data['quantity'] |
|
|
new_vente = Vente.objects.create( |
|
|
new_purchase = Vente.objects.create( |
|
|
facture=new_facture_instance, |
|
|
facture=new_invoice_instance, |
|
|
name=article.name, |
|
|
name=article.name, |
|
|
prix=article.prix, |
|
|
prix=article.prix, |
|
|
type_cotisation=article.type_cotisation, |
|
|
type_cotisation=article.type_cotisation, |
|
|
duration=article.duration, |
|
|
duration=article.duration, |
|
|
number=quantity |
|
|
number=quantity |
|
|
) |
|
|
) |
|
|
new_vente.save() |
|
|
new_purchase.save() |
|
|
|
|
|
|
|
|
|
|
|
# In case a cotisation was bought, inform the user, the |
|
|
|
|
|
# cotisation time has been extended too |
|
|
if any(art_item.cleaned_data['article'].type_cotisation |
|
|
if any(art_item.cleaned_data['article'].type_cotisation |
|
|
for art_item in articles if art_item.cleaned_data): |
|
|
for art_item in articles if art_item.cleaned_data): |
|
|
messages.success( |
|
|
messages.success( |
|
|
@ -158,6 +165,7 @@ def new_facture(request, user, userid): |
|
|
end_date: user.end_adhesion() |
|
|
end_date: user.end_adhesion() |
|
|
} |
|
|
} |
|
|
) |
|
|
) |
|
|
|
|
|
# Else, only tell the invoice was created |
|
|
else: |
|
|
else: |
|
|
messages.success( |
|
|
messages.success( |
|
|
request, |
|
|
request, |
|
|
@ -173,7 +181,7 @@ def new_facture(request, user, userid): |
|
|
) |
|
|
) |
|
|
return form( |
|
|
return form( |
|
|
{ |
|
|
{ |
|
|
'factureform': facture_form, |
|
|
'factureform': invoice_form, |
|
|
'venteform': article_formset, |
|
|
'venteform': article_formset, |
|
|
'articlelist': article_list |
|
|
'articlelist': article_list |
|
|
}, |
|
|
}, |
|
|
@ -185,29 +193,30 @@ def new_facture(request, user, userid): |
|
|
@login_required |
|
|
@login_required |
|
|
@can_change(Facture, 'pdf') |
|
|
@can_change(Facture, 'pdf') |
|
|
def new_facture_pdf(request): |
|
|
def new_facture_pdf(request): |
|
|
"""Permet de générer un pdf d'une facture. Réservée |
|
|
""" |
|
|
au trésorier, permet d'emettre des factures sans objet |
|
|
View used to generate a custom PDF invoice. It's mainly used to |
|
|
Vente ou Facture correspondant en bdd""" |
|
|
get invoices that are not taken into account, for the administrative |
|
|
# TODO : translate docstring to English |
|
|
point of view. |
|
|
facture_form = NewFactureFormPdf(request.POST or None) |
|
|
""" |
|
|
if facture_form.is_valid(): |
|
|
invoice_form = NewFactureFormPdf(request.POST or None) |
|
|
|
|
|
if invoice_form.is_valid(): |
|
|
tbl = [] |
|
|
tbl = [] |
|
|
article = facture_form.cleaned_data['article'] |
|
|
article = facture_form.cleaned_data['article'] |
|
|
quantite = facture_form.cleaned_data['number'] |
|
|
quantity = facture_form.cleaned_data['number'] |
|
|
paid = facture_form.cleaned_data['paid'] |
|
|
paid = facture_form.cleaned_data['paid'] |
|
|
destinataire = facture_form.cleaned_data['dest'] |
|
|
recipient = facture_form.cleaned_data['dest'] |
|
|
chambre = facture_form.cleaned_data['chambre'] |
|
|
room = facture_form.cleaned_data['chambre'] |
|
|
fid = facture_form.cleaned_data['fid'] |
|
|
invoice_id = facture_form.cleaned_data['fid'] |
|
|
for art in article: |
|
|
for art in article: |
|
|
tbl.append([art, quantite, art.prix * quantite]) |
|
|
tbl.append([art, quantity, art.prix * quantity]) |
|
|
prix_total = sum(a[2] for a in tbl) |
|
|
total_price = sum(a[2] for a in tbl) |
|
|
user = {'name': destinataire, 'room': chambre} |
|
|
user = {'name': recipient, 'room': room} |
|
|
return render_invoice(request, { |
|
|
return render_invoice(request, { |
|
|
'DATE': timezone.now(), |
|
|
'DATE': timezone.now(), |
|
|
'dest': user, |
|
|
'dest': user, |
|
|
'fid': fid, |
|
|
'fid': invoice_id, |
|
|
'article': tbl, |
|
|
'article': tbl, |
|
|
'total': prix_total, |
|
|
'total': total_price, |
|
|
'paid': paid, |
|
|
'paid': paid, |
|
|
'asso_name': AssoOption.get_cached_value('name'), |
|
|
'asso_name': AssoOption.get_cached_value('name'), |
|
|
'line1': AssoOption.get_cached_value('adresse1'), |
|
|
'line1': AssoOption.get_cached_value('adresse1'), |
|
|
@ -218,8 +227,8 @@ def new_facture_pdf(request): |
|
|
'tpl_path': os.path.join(settings.BASE_DIR, LOGO_PATH) |
|
|
'tpl_path': os.path.join(settings.BASE_DIR, LOGO_PATH) |
|
|
}) |
|
|
}) |
|
|
return form({ |
|
|
return form({ |
|
|
'factureform': facture_form, |
|
|
'factureform': invoice_form, |
|
|
'action_name' : 'Editer' |
|
|
'action_name': _("Edit") |
|
|
}, 'cotisations/facture.html', request) |
|
|
}, 'cotisations/facture.html', request) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -227,22 +236,23 @@ def new_facture_pdf(request): |
|
|
@login_required |
|
|
@login_required |
|
|
@can_view(Facture) |
|
|
@can_view(Facture) |
|
|
def facture_pdf(request, facture, factureid): |
|
|
def facture_pdf(request, facture, factureid): |
|
|
"""Affiche en pdf une facture. Cree une ligne par Vente de la facture, |
|
|
""" |
|
|
et génére une facture avec le total, le moyen de paiement, l'adresse |
|
|
View used to generate a PDF file from an existing invoice in database |
|
|
de l'adhérent, etc. Réservée à self pour un user sans droits, |
|
|
Creates a line for each Purchase (thus article sold) and generate the |
|
|
les droits cableurs permettent d'afficher toute facture""" |
|
|
invoice with the total price, the payment method, the address and the |
|
|
# TODO : translate docstring to English |
|
|
legal information for the user. |
|
|
|
|
|
""" |
|
|
# TODO : change vente to purchase |
|
|
# TODO : change vente to purchase |
|
|
ventes_objects = Vente.objects.all().filter(facture=facture) |
|
|
purchases_objects = Vente.objects.all().filter(facture=facture) |
|
|
ventes = [] |
|
|
purchases = [] |
|
|
for vente in ventes_objects: |
|
|
for purchase in purchases_objects: |
|
|
ventes.append([vente, vente.number, vente.prix_total]) |
|
|
purchases.append([purchase, purchase.number, purchase.prix_total]) |
|
|
return render_invoice(request, { |
|
|
return render_invoice(request, { |
|
|
'paid': True, |
|
|
'paid': True, |
|
|
'fid': facture.id, |
|
|
'fid': facture.id, |
|
|
'DATE': facture.date, |
|
|
'DATE': facture.date, |
|
|
'dest': facture.user, |
|
|
'dest': facture.user, |
|
|
'article': ventes, |
|
|
'article': purchases, |
|
|
'total': facture.prix_total(), |
|
|
'total': facture.prix_total(), |
|
|
'asso_name': AssoOption.get_cached_value('name'), |
|
|
'asso_name': AssoOption.get_cached_value('name'), |
|
|
'line1': AssoOption.get_cached_value('adresse1'), |
|
|
'line1': AssoOption.get_cached_value('adresse1'), |
|
|
@ -258,31 +268,33 @@ def facture_pdf(request, facture, factureid): |
|
|
@login_required |
|
|
@login_required |
|
|
@can_edit(Facture) |
|
|
@can_edit(Facture) |
|
|
def edit_facture(request, facture, factureid): |
|
|
def edit_facture(request, facture, factureid): |
|
|
"""Permet l'édition d'une facture. On peut y éditer les ventes |
|
|
""" |
|
|
déjà effectuer, ou rendre une facture invalide (non payées, chèque |
|
|
View used to edit an existing invoice. |
|
|
en bois etc). Mets à jour les durée de cotisation attenantes""" |
|
|
Articles can be added or remove to the invoice and quantity |
|
|
# TODO : translate docstring to English |
|
|
can be set as desired. This is also the view used to invalidate |
|
|
facture_form = EditFactureForm(request.POST or None, instance=facture, user=request.user) |
|
|
an invoice. |
|
|
ventes_objects = Vente.objects.filter(facture=facture) |
|
|
""" |
|
|
vente_form_set = modelformset_factory( |
|
|
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, |
|
|
Vente, |
|
|
fields=('name', 'number'), |
|
|
fields=('name', 'number'), |
|
|
extra=0, |
|
|
extra=0, |
|
|
max_num=len(ventes_objects) |
|
|
max_num=len(purchases_objects) |
|
|
) |
|
|
) |
|
|
vente_form = vente_form_set(request.POST or None, queryset=ventes_objects) |
|
|
purchase_form = purchase_form_set(request.POST or None, queryset=purchases_objects) |
|
|
if facture_form.is_valid() and vente_form.is_valid(): |
|
|
if invoice_form.is_valid() and purchase_form.is_valid(): |
|
|
if facture_form.changed_data: |
|
|
if invoice_form.changed_data: |
|
|
facture_form.save() |
|
|
invoice_form.save() |
|
|
vente_form.save() |
|
|
purchase_form.save() |
|
|
messages.success( |
|
|
messages.success( |
|
|
request, |
|
|
request, |
|
|
_("The invoice has been successfully edited.") |
|
|
_("The invoice has been successfully edited.") |
|
|
) |
|
|
) |
|
|
return redirect(reverse('cotisations:index')) |
|
|
return redirect(reverse('cotisations:index')) |
|
|
return form({ |
|
|
return form({ |
|
|
'factureform': facture_form, |
|
|
'factureform': invoice_form, |
|
|
'venteform': vente_form |
|
|
'venteform': purchase_form |
|
|
}, 'cotisations/edit_facture.html', request) |
|
|
}, 'cotisations/edit_facture.html', request) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -290,10 +302,11 @@ def edit_facture(request, facture, factureid): |
|
|
@login_required |
|
|
@login_required |
|
|
@can_delete(Facture) |
|
|
@can_delete(Facture) |
|
|
def del_facture(request, facture, factureid): |
|
|
def del_facture(request, facture, factureid): |
|
|
"""Suppression d'une facture. Supprime en cascade les ventes |
|
|
""" |
|
|
et cotisations filles""" |
|
|
View used to delete an existing invocie. |
|
|
# TODO : translate docstring to English |
|
|
""" |
|
|
if request.method == "POST": |
|
|
if request.method == "POST": |
|
|
|
|
|
facture.delete() |
|
|
messages.success( |
|
|
messages.success( |
|
|
request, |
|
|
request, |
|
|
_("The invoice has been successfully deleted.") |
|
|
_("The invoice has been successfully deleted.") |
|
|
@ -301,7 +314,7 @@ def del_facture(request, facture, factureid): |
|
|
return redirect(reverse('cotisations:index')) |
|
|
return redirect(reverse('cotisations:index')) |
|
|
return form({ |
|
|
return form({ |
|
|
'objet': facture, |
|
|
'objet': facture, |
|
|
'objet_name': 'facture' |
|
|
'objet_name': _("Invoice") |
|
|
}, 'cotisations/delete.html', request) |
|
|
}, 'cotisations/delete.html', request) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -310,40 +323,46 @@ def del_facture(request, facture, factureid): |
|
|
@can_create(Facture) |
|
|
@can_create(Facture) |
|
|
@can_edit(User) |
|
|
@can_edit(User) |
|
|
def credit_solde(request, user, userid): |
|
|
def credit_solde(request, user, userid): |
|
|
""" Credit ou débit de solde """ |
|
|
""" |
|
|
# TODO : translate docstring to English |
|
|
View used to edit the balance of a user. |
|
|
|
|
|
Can be use either to increase or decrease a user's balance. |
|
|
|
|
|
""" |
|
|
# TODO : change facture to invoice |
|
|
# TODO : change facture to invoice |
|
|
facture = CreditSoldeForm(request.POST or None) |
|
|
invoice = CreditSoldeForm(request.POST or None) |
|
|
if facture.is_valid(): |
|
|
if invoice.is_valid(): |
|
|
facture_instance = facture.save(commit=False) |
|
|
invoice_instance = invoice.save(commit=False) |
|
|
facture_instance.user = user |
|
|
invoice_instance.user = user |
|
|
facture_instance.save() |
|
|
invoice_instance.save() |
|
|
new_vente = Vente.objects.create( |
|
|
new_purchase = Vente.objects.create( |
|
|
facture=facture_instance, |
|
|
facture=invoice_instance, |
|
|
name="solde", |
|
|
name="solde", |
|
|
prix=facture.cleaned_data['montant'], |
|
|
prix=invoice.cleaned_data['montant'], |
|
|
number=1 |
|
|
number=1 |
|
|
) |
|
|
) |
|
|
new_vente.save() |
|
|
new_purchase.save() |
|
|
messages.success( |
|
|
messages.success( |
|
|
request, |
|
|
request, |
|
|
_("Balance successfully updated.") |
|
|
_("Balance successfully updated.") |
|
|
) |
|
|
) |
|
|
return redirect(reverse('cotisations:index')) |
|
|
return redirect(reverse('cotisations:index')) |
|
|
return form({'factureform': facture, 'action_name' : 'Créditer'}, 'cotisations/facture.html', request) |
|
|
return form({ |
|
|
|
|
|
'factureform': facture, |
|
|
|
|
|
'action_name': _("Edit") |
|
|
|
|
|
}, 'cotisations/facture.html', request) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@login_required |
|
|
@login_required |
|
|
@can_create(Article) |
|
|
@can_create(Article) |
|
|
def add_article(request): |
|
|
def add_article(request): |
|
|
"""Ajoute un article. Champs : désignation, |
|
|
""" |
|
|
prix, est-ce une cotisation et si oui sa durée |
|
|
View used to add an article. |
|
|
Réservé au trésorier |
|
|
|
|
|
Nota bene : les ventes déjà effectuées ne sont pas reliées |
|
|
.. note:: If a purchase has already been sold, the price are calculated |
|
|
aux articles en vente. La désignation, le prix... sont |
|
|
once and for all. That means even if the price of an article is edited |
|
|
copiés à la création de la facture. Un changement de prix n'a |
|
|
later, it won't change the invoice. That is really important to keep |
|
|
PAS de conséquence sur les ventes déjà faites""" |
|
|
this behaviour in order not to modify all the past and already |
|
|
# TODO : translate docstring to English |
|
|
accepted invoices. |
|
|
|
|
|
""" |
|
|
article = ArticleForm(request.POST or None) |
|
|
article = ArticleForm(request.POST or None) |
|
|
if article.is_valid(): |
|
|
if article.is_valid(): |
|
|
article.save() |
|
|
article.save() |
|
|
@ -352,15 +371,18 @@ def add_article(request): |
|
|
_("The article has been successfully created.") |
|
|
_("The article has been successfully created.") |
|
|
) |
|
|
) |
|
|
return redirect(reverse('cotisations:index-article')) |
|
|
return redirect(reverse('cotisations:index-article')) |
|
|
return form({'factureform': article, 'action_name' : 'Ajouter'}, 'cotisations/facture.html', request) |
|
|
return form({ |
|
|
|
|
|
'factureform': article, |
|
|
|
|
|
'action_name': _("Add") |
|
|
|
|
|
}, 'cotisations/facture.html', request) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@login_required |
|
|
@login_required |
|
|
@can_edit(Article) |
|
|
@can_edit(Article) |
|
|
def edit_article(request, article_instance, articleid): |
|
|
def edit_article(request, article_instance, articleid): |
|
|
"""Edition d'un article (designation, prix, etc) |
|
|
""" |
|
|
Réservé au trésorier""" |
|
|
View used to edit an article. |
|
|
# TODO : translate dosctring to English |
|
|
""" |
|
|
article = ArticleForm(request.POST or None, instance=article_instance) |
|
|
article = ArticleForm(request.POST or None, instance=article_instance) |
|
|
if article.is_valid(): |
|
|
if article.is_valid(): |
|
|
if article.changed_data: |
|
|
if article.changed_data: |
|
|
@ -370,14 +392,18 @@ def edit_article(request, article_instance, articleid): |
|
|
_("The article has been successfully edited.") |
|
|
_("The article has been successfully edited.") |
|
|
) |
|
|
) |
|
|
return redirect(reverse('cotisations:index-article')) |
|
|
return redirect(reverse('cotisations:index-article')) |
|
|
return form({'factureform': article, 'action_name' : 'Editer'}, 'cotisations/facture.html', request) |
|
|
return form({ |
|
|
|
|
|
'factureform': article, |
|
|
|
|
|
'action_name': _('Edit') |
|
|
|
|
|
}, 'cotisations/facture.html', request) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@login_required |
|
|
@login_required |
|
|
@can_delete_set(Article) |
|
|
@can_delete_set(Article) |
|
|
def del_article(request, instances): |
|
|
def del_article(request, instances): |
|
|
"""Suppression d'un article en vente""" |
|
|
""" |
|
|
# TODO : translate docstring to English |
|
|
View used to delete one of the articles. |
|
|
|
|
|
""" |
|
|
article = DelArticleForm(request.POST or None, instances=instances) |
|
|
article = DelArticleForm(request.POST or None, instances=instances) |
|
|
if article.is_valid(): |
|
|
if article.is_valid(): |
|
|
article_del = article.cleaned_data['articles'] |
|
|
article_del = article.cleaned_data['articles'] |
|
|
@ -387,63 +413,73 @@ def del_article(request, instances): |
|
|
_("The article(s) have been successfully deleted.") |
|
|
_("The article(s) have been successfully deleted.") |
|
|
) |
|
|
) |
|
|
return redirect(reverse('cotisations:index-article')) |
|
|
return redirect(reverse('cotisations:index-article')) |
|
|
return form({'factureform': article, 'action_name' : 'Supprimer'}, 'cotisations/facture.html', request) |
|
|
return form({ |
|
|
|
|
|
'factureform': article, |
|
|
|
|
|
'action_name': _("Delete") |
|
|
|
|
|
}, 'cotisations/facture.html', request) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO : change paiement to payment |
|
|
# TODO : change paiement to payment |
|
|
@login_required |
|
|
@login_required |
|
|
@can_create(Paiement) |
|
|
@can_create(Paiement) |
|
|
def add_paiement(request): |
|
|
def add_paiement(request): |
|
|
"""Ajoute un moyen de paiement. Relié aux factures |
|
|
""" |
|
|
via foreign key""" |
|
|
View used to add a payment method. |
|
|
# TODO : translate docstring to English |
|
|
""" |
|
|
# TODO : change paiement to Payment |
|
|
payment = PaiementForm(request.POST or None) |
|
|
paiement = PaiementForm(request.POST or None) |
|
|
if payment.is_valid(): |
|
|
if paiement.is_valid(): |
|
|
payment.save() |
|
|
paiement.save() |
|
|
|
|
|
messages.success( |
|
|
messages.success( |
|
|
request, |
|
|
request, |
|
|
_("The payment method has been successfully created.") |
|
|
_("The payment method has been successfully created.") |
|
|
) |
|
|
) |
|
|
return redirect(reverse('cotisations:index-paiement')) |
|
|
return redirect(reverse('cotisations:index-paiement')) |
|
|
return form({'factureform': paiement, 'action_name' : 'Ajouter'}, 'cotisations/facture.html', request) |
|
|
return form({ |
|
|
|
|
|
'factureform': payment, |
|
|
|
|
|
'action_name': _("Add") |
|
|
|
|
|
}, 'cotisations/facture.html', request) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO : chnage paiement to Payment |
|
|
# TODO : chnage paiement to Payment |
|
|
@login_required |
|
|
@login_required |
|
|
@can_edit(Paiement) |
|
|
@can_edit(Paiement) |
|
|
def edit_paiement(request, paiement_instance, paiementid): |
|
|
def edit_paiement(request, paiement_instance, paiementid): |
|
|
"""Edition d'un moyen de paiement""" |
|
|
""" |
|
|
# TODO : translate docstring to English |
|
|
View used to edit a payment method. |
|
|
paiement = PaiementForm(request.POST or None, instance=paiement_instance) |
|
|
""" |
|
|
if paiement.is_valid(): |
|
|
payment = PaiementForm(request.POST or None, instance=paiement_instance) |
|
|
if paiement.changed_data: |
|
|
if payment.is_valid(): |
|
|
paiement.save() |
|
|
if payment.changed_data: |
|
|
|
|
|
payment.save() |
|
|
messages.success( |
|
|
messages.success( |
|
|
request, |
|
|
request, |
|
|
_("The payement method has been successfully edited.") |
|
|
_("The payement method has been successfully edited.") |
|
|
) |
|
|
) |
|
|
return redirect(reverse('cotisations:index-paiement')) |
|
|
return redirect(reverse('cotisations:index-paiement')) |
|
|
return form({'factureform': paiement, 'action_name' : 'Editer'}, 'cotisations/facture.html', request) |
|
|
return form({ |
|
|
|
|
|
'factureform': payment, |
|
|
|
|
|
'action_name': _("Edit") |
|
|
|
|
|
}, 'cotisations/facture.html', request) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO : change paiement to payment |
|
|
# TODO : change paiement to payment |
|
|
@login_required |
|
|
@login_required |
|
|
@can_delete_set(Paiement) |
|
|
@can_delete_set(Paiement) |
|
|
def del_paiement(request, instances): |
|
|
def del_paiement(request, instances): |
|
|
"""Suppression d'un moyen de paiement""" |
|
|
""" |
|
|
# TODO : translate docstring to English |
|
|
View used to delete a set of payment methods. |
|
|
paiement = DelPaiementForm(request.POST or None, instances=instances) |
|
|
""" |
|
|
if paiement.is_valid(): |
|
|
payment = DelPaiementForm(request.POST or None, instances=instances) |
|
|
paiement_dels = paiement.cleaned_data['paiements'] |
|
|
if payment.is_valid(): |
|
|
for paiement_del in paiement_dels: |
|
|
payment_dels = payment.cleaned_data['paiements'] |
|
|
|
|
|
for payment_del in payment_dels: |
|
|
try: |
|
|
try: |
|
|
paiement_del.delete() |
|
|
payment_del.delete() |
|
|
messages.success( |
|
|
messages.success( |
|
|
request, |
|
|
request, |
|
|
_("The payment method %(method_name)s has been \ |
|
|
_("The payment method %(method_name)s has been \ |
|
|
successfully deleted.") % { |
|
|
successfully deleted.") % { |
|
|
method_name: paiement_del |
|
|
method_name: payment_del |
|
|
} |
|
|
} |
|
|
) |
|
|
) |
|
|
except ProtectedError: |
|
|
except ProtectedError: |
|
|
@ -451,65 +487,77 @@ def del_paiement(request, instances): |
|
|
request, |
|
|
request, |
|
|
_("The payment method %(method_name)s can't be deleted \ |
|
|
_("The payment method %(method_name)s can't be deleted \ |
|
|
because there are invoices using it.") % { |
|
|
because there are invoices using it.") % { |
|
|
method_name: paiement_del |
|
|
method_name: payment_del |
|
|
} |
|
|
} |
|
|
) |
|
|
) |
|
|
return redirect(reverse('cotisations:index-paiement')) |
|
|
return redirect(reverse('cotisations:index-paiement')) |
|
|
return form({'factureform': paiement, 'action_name' : 'Supprimer'}, 'cotisations/facture.html', request) |
|
|
return form({ |
|
|
|
|
|
'factureform': payment, |
|
|
|
|
|
'action_name': _("Delete") |
|
|
|
|
|
}, 'cotisations/facture.html', request) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO : change banque to bank |
|
|
# TODO : change banque to bank |
|
|
@login_required |
|
|
@login_required |
|
|
@can_create(Banque) |
|
|
@can_create(Banque) |
|
|
def add_banque(request): |
|
|
def add_banque(request): |
|
|
"""Ajoute une banque à la liste des banques""" |
|
|
""" |
|
|
# TODO : tranlate docstring to English |
|
|
View used to add a bank. |
|
|
banque = BanqueForm(request.POST or None) |
|
|
""" |
|
|
if banque.is_valid(): |
|
|
bank = BanqueForm(request.POST or None) |
|
|
banque.save() |
|
|
if bank.is_valid(): |
|
|
|
|
|
bank.save() |
|
|
messages.success( |
|
|
messages.success( |
|
|
request, |
|
|
request, |
|
|
_("The bank has been successfully created.") |
|
|
_("The bank has been successfully created.") |
|
|
) |
|
|
) |
|
|
return redirect(reverse('cotisations:index-banque')) |
|
|
return redirect(reverse('cotisations:index-banque')) |
|
|
return form({'factureform': banque, 'action_name' : 'Ajouter'}, 'cotisations/facture.html', request) |
|
|
return form({ |
|
|
|
|
|
'factureform': bank, |
|
|
|
|
|
'action_name': _("Add") |
|
|
|
|
|
}, 'cotisations/facture.html', request) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO : change banque to bank |
|
|
# TODO : change banque to bank |
|
|
@login_required |
|
|
@login_required |
|
|
@can_edit(Banque) |
|
|
@can_edit(Banque) |
|
|
def edit_banque(request, banque_instance, banqueid): |
|
|
def edit_banque(request, banque_instance, banqueid): |
|
|
"""Edite le nom d'une banque""" |
|
|
""" |
|
|
# TODO : translate docstring to English |
|
|
View used to edit a bank. |
|
|
banque = BanqueForm(request.POST or None, instance=banque_instance) |
|
|
""" |
|
|
if banque.is_valid(): |
|
|
bank = BanqueForm(request.POST or None, instance=banque_instance) |
|
|
if banque.changed_data: |
|
|
if bank.is_valid(): |
|
|
banque.save() |
|
|
if bank.changed_data: |
|
|
|
|
|
bank.save() |
|
|
messages.success( |
|
|
messages.success( |
|
|
request, |
|
|
request, |
|
|
_("The bank has been successfully edited") |
|
|
_("The bank has been successfully edited") |
|
|
) |
|
|
) |
|
|
return redirect(reverse('cotisations:index-banque')) |
|
|
return redirect(reverse('cotisations:index-banque')) |
|
|
return form({'factureform': banque, 'action_name' : 'Editer'}, 'cotisations/facture.html', request) |
|
|
return form({ |
|
|
|
|
|
'factureform': bank, |
|
|
|
|
|
'action_name': _("Edit") |
|
|
|
|
|
}, 'cotisations/facture.html', request) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO : chnage banque to bank |
|
|
# TODO : chnage banque to bank |
|
|
@login_required |
|
|
@login_required |
|
|
@can_delete_set(Banque) |
|
|
@can_delete_set(Banque) |
|
|
def del_banque(request, instances): |
|
|
def del_banque(request, instances): |
|
|
"""Supprime une banque""" |
|
|
""" |
|
|
# TODO : translate docstring to English |
|
|
View used to delete a set of banks. |
|
|
banque = DelBanqueForm(request.POST or None, instances=instances) |
|
|
""" |
|
|
if banque.is_valid(): |
|
|
bank = DelBanqueForm(request.POST or None, instances=instances) |
|
|
banque_dels = banque.cleaned_data['banques'] |
|
|
if bank.is_valid(): |
|
|
for banque_del in banque_dels: |
|
|
bank_dels = bank.cleaned_data['banques'] |
|
|
|
|
|
for bank_del in bank_dels: |
|
|
try: |
|
|
try: |
|
|
banque_del.delete() |
|
|
bank_del.delete() |
|
|
messages.success( |
|
|
messages.success( |
|
|
request, |
|
|
request, |
|
|
_("The bank %(bank_name)s has been successfully \ |
|
|
_("The bank %(bank_name)s has been successfully \ |
|
|
deleted.") % { |
|
|
deleted.") % { |
|
|
bank_name: banque_del |
|
|
bank_name: bank_del |
|
|
} |
|
|
} |
|
|
) |
|
|
) |
|
|
except ProtectedError: |
|
|
except ProtectedError: |
|
|
@ -517,11 +565,14 @@ def del_banque(request, instances): |
|
|
request, |
|
|
request, |
|
|
_("The bank %(bank_name)s can't be deleted \ |
|
|
_("The bank %(bank_name)s can't be deleted \ |
|
|
because there are invoices using it.") % { |
|
|
because there are invoices using it.") % { |
|
|
bank_name: banque_del |
|
|
bank_name: bank_del |
|
|
} |
|
|
} |
|
|
) |
|
|
) |
|
|
return redirect(reverse('cotisations:index-banque')) |
|
|
return redirect(reverse('cotisations:index-banque')) |
|
|
return form({'factureform': banque, 'action_name' : 'Supprimer'}, 'cotisations/facture.html', request) |
|
|
return form({ |
|
|
|
|
|
'factureform': bank, |
|
|
|
|
|
'action_name': _("Delete") |
|
|
|
|
|
}, 'cotisations/facture.html', request) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO : change facture to invoice |
|
|
# TODO : change facture to invoice |
|
|
@ -529,39 +580,44 @@ def del_banque(request, instances): |
|
|
@can_view_all(Facture) |
|
|
@can_view_all(Facture) |
|
|
@can_change(Facture, 'control') |
|
|
@can_change(Facture, 'control') |
|
|
def control(request): |
|
|
def control(request): |
|
|
"""Pour le trésorier, vue pour controler en masse les |
|
|
""" |
|
|
factures.Case à cocher, pratique""" |
|
|
View used to control the invoices all at once. |
|
|
# TODO : translate docstring to English |
|
|
""" |
|
|
pagination_number = GeneralOption.get_cached_value('pagination_number') |
|
|
pagination_number = GeneralOption.get_cached_value('pagination_number') |
|
|
facture_list = Facture.objects.select_related('user').select_related('paiement') |
|
|
invoice_list = Facture.objects.select_related('user').select_related('paiement') |
|
|
facture_list = SortTable.sort( |
|
|
invoice_list = SortTable.sort( |
|
|
facture_list, |
|
|
invoice_list, |
|
|
request.GET.get('col'), |
|
|
request.GET.get('col'), |
|
|
request.GET.get('order'), |
|
|
request.GET.get('order'), |
|
|
SortTable.COTISATIONS_CONTROL |
|
|
SortTable.COTISATIONS_CONTROL |
|
|
) |
|
|
) |
|
|
controlform_set = modelformset_factory( |
|
|
control_invoices_formset = modelformset_factory( |
|
|
Facture, |
|
|
Facture, |
|
|
fields=('control', 'valid'), |
|
|
fields=('control', 'valid'), |
|
|
extra=0 |
|
|
extra=0 |
|
|
) |
|
|
) |
|
|
facture_list = re2o_paginator(request, facture_list, pagination_number) |
|
|
invoice_list = re2o_paginator(request, invoice_list, pagination_number) |
|
|
controlform = controlform_set(request.POST or None, queryset=facture_list.object_list) |
|
|
control_invoices_form = control_invoices_formset( |
|
|
if controlform.is_valid(): |
|
|
request.POST or None, |
|
|
controlform.save() |
|
|
queryset=invoice_list.object_list |
|
|
|
|
|
) |
|
|
|
|
|
if control_invoices_form.is_valid(): |
|
|
|
|
|
control_invoices_form.save() |
|
|
reversion.set_comment("Controle") |
|
|
reversion.set_comment("Controle") |
|
|
return redirect(reverse('cotisations:control')) |
|
|
return redirect(reverse('cotisations:control')) |
|
|
return render(request, 'cotisations/control.html', { |
|
|
return render(request, 'cotisations/control.html', { |
|
|
'facture_list': facture_list, |
|
|
'facture_list': invoice_list, |
|
|
'controlform': controlform |
|
|
'controlform': control_invoices_form |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@login_required |
|
|
@login_required |
|
|
@can_view_all(Article) |
|
|
@can_view_all(Article) |
|
|
def index_article(request): |
|
|
def index_article(request): |
|
|
"""Affiche l'ensemble des articles en vente""" |
|
|
""" |
|
|
# TODO : translate docstrign to English |
|
|
View used to display the list of all available articles. |
|
|
|
|
|
""" |
|
|
|
|
|
# TODO : Offer other means of sorting |
|
|
article_list = Article.objects.order_by('name') |
|
|
article_list = Article.objects.order_by('name') |
|
|
return render(request, 'cotisations/index_article.html', { |
|
|
return render(request, 'cotisations/index_article.html', { |
|
|
'article_list': article_list |
|
|
'article_list': article_list |
|
|
@ -572,11 +628,12 @@ def index_article(request): |
|
|
@login_required |
|
|
@login_required |
|
|
@can_view_all(Paiement) |
|
|
@can_view_all(Paiement) |
|
|
def index_paiement(request): |
|
|
def index_paiement(request): |
|
|
"""Affiche l'ensemble des moyens de paiement en vente""" |
|
|
""" |
|
|
# TODO : translate docstring to English |
|
|
View used to display the list of all available payment methods. |
|
|
paiement_list = Paiement.objects.order_by('moyen') |
|
|
""" |
|
|
|
|
|
payment_list = Paiement.objects.order_by('moyen') |
|
|
return render(request, 'cotisations/index_paiement.html', { |
|
|
return render(request, 'cotisations/index_paiement.html', { |
|
|
'paiement_list': paiement_list |
|
|
'paiement_list': payment_list |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -584,51 +641,57 @@ def index_paiement(request): |
|
|
@login_required |
|
|
@login_required |
|
|
@can_view_all(Banque) |
|
|
@can_view_all(Banque) |
|
|
def index_banque(request): |
|
|
def index_banque(request): |
|
|
"""Affiche l'ensemble des banques""" |
|
|
""" |
|
|
# TODO : translate docstring to English |
|
|
View used to display the list of all available banks. |
|
|
banque_list = Banque.objects.order_by('name') |
|
|
""" |
|
|
|
|
|
bank_list = Banque.objects.order_by('name') |
|
|
return render(request, 'cotisations/index_banque.html', { |
|
|
return render(request, 'cotisations/index_banque.html', { |
|
|
'banque_list': banque_list |
|
|
'banque_list': bank_list |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@login_required |
|
|
@login_required |
|
|
@can_view_all(Facture) |
|
|
@can_view_all(Facture) |
|
|
def index(request): |
|
|
def index(request): |
|
|
"""Affiche l'ensemble des factures, pour les cableurs et +""" |
|
|
""" |
|
|
# TODO : translate docstring to English |
|
|
View used to display the list of all exisitng invoices. |
|
|
|
|
|
""" |
|
|
pagination_number = GeneralOption.get_cached_value('pagination_number') |
|
|
pagination_number = GeneralOption.get_cached_value('pagination_number') |
|
|
facture_list = Facture.objects.select_related('user')\ |
|
|
invoice_list = Facture.objects.select_related('user')\ |
|
|
.select_related('paiement').prefetch_related('vente_set') |
|
|
.select_related('paiement').prefetch_related('vente_set') |
|
|
facture_list = SortTable.sort( |
|
|
invoice_list = SortTable.sort( |
|
|
facture_list, |
|
|
invoice_list, |
|
|
request.GET.get('col'), |
|
|
request.GET.get('col'), |
|
|
request.GET.get('order'), |
|
|
request.GET.get('order'), |
|
|
SortTable.COTISATIONS_INDEX |
|
|
SortTable.COTISATIONS_INDEX |
|
|
) |
|
|
) |
|
|
facture_list = re2o_paginator(request, facture_list, pagination_number) |
|
|
invoice_list = re2o_paginator(request, invoice_list, pagination_number) |
|
|
return render(request, 'cotisations/index.html', { |
|
|
return render(request, 'cotisations/index.html', { |
|
|
'facture_list': facture_list |
|
|
'facture_list': invoice_list |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO : merge this function with new_facture() which is nearly the same |
|
|
# TODO : change facture to invoice |
|
|
# TODO : change facture to invoice |
|
|
@login_required |
|
|
@login_required |
|
|
def new_facture_solde(request, userid): |
|
|
def new_facture_solde(request, userid): |
|
|
"""Creation d'une facture pour un user. Renvoie la liste des articles |
|
|
""" |
|
|
et crée des factures dans un formset. Utilise un peu de js coté template |
|
|
View called to create a new invoice when using the balance to pay. |
|
|
pour ajouter des articles. |
|
|
Currently, send the list of available articles for the user along with |
|
|
Parse les article et boucle dans le formset puis save les ventes, |
|
|
a formset of a new invoice (based on the `:forms:NewFactureForm()` form. |
|
|
enfin sauve la facture parente. |
|
|
A bit of JS is used in the template to add articles in a fancier way. |
|
|
TODO : simplifier cette fonction, déplacer l'intelligence coté models |
|
|
If everything is correct, save each one of the articles, save the |
|
|
Facture et Vente.""" |
|
|
purchase object associated and finally the newly created invoice. |
|
|
# TODO : translate docstring to English |
|
|
|
|
|
|
|
|
TODO : The whole verification process should be moved to the model. This |
|
|
|
|
|
function should only act as a dumb interface between the model and the |
|
|
|
|
|
user. |
|
|
|
|
|
""" |
|
|
user = request.user |
|
|
user = request.user |
|
|
facture = Facture(user=user) |
|
|
invoice = Facture(user=user) |
|
|
paiement, _created = Paiement.objects.get_or_create(moyen='Solde') |
|
|
payment, _created = Paiement.objects.get_or_create(moyen='Solde') |
|
|
facture.paiement = paiement |
|
|
facture.paiement = payment |
|
|
# TODO : translate comments to English |
|
|
# The template needs the list of articles (for the JS part) |
|
|
# Le template a besoin de connaitre les articles pour le js |
|
|
|
|
|
article_list = Article.objects.filter( |
|
|
article_list = Article.objects.filter( |
|
|
Q(type_user='All') | Q(type_user=request.user.class_name) |
|
|
Q(type_user='All') | Q(type_user=request.user.class_name) |
|
|
) |
|
|
) |
|
|
@ -636,21 +699,23 @@ def new_facture_solde(request, userid): |
|
|
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 |
|
|
# Si au moins un article est rempli |
|
|
# Check if at leat one article has been selected |
|
|
if any(art.cleaned_data for art in articles): |
|
|
if any(art.cleaned_data for art in articles): |
|
|
user_solde = OptionalUser.get_cached_value('user_solde') |
|
|
user_balance = OptionalUser.get_cached_value('user_solde') |
|
|
solde_negatif = OptionalUser.get_cached_value('solde_negatif') |
|
|
negative_balance = OptionalUser.get_cached_value('solde_negatif') |
|
|
# Si on paye par solde, que l'option est activée, |
|
|
# If the paiement using balance has been activated, |
|
|
# on vérifie que le négatif n'est pas atteint |
|
|
# checking that the total price won't get the user under |
|
|
if user_solde: |
|
|
# the authorized minimum (negative_balance) |
|
|
prix_total = 0 |
|
|
if user_balance: |
|
|
|
|
|
total_price = 0 |
|
|
for art_item in articles: |
|
|
for art_item in articles: |
|
|
if art_item.cleaned_data: |
|
|
if art_item.cleaned_data: |
|
|
prix_total += art_item.cleaned_data['article']\ |
|
|
total_price += art_item.cleaned_data['article']\ |
|
|
.prix*art_item.cleaned_data['quantity'] |
|
|
.prix*art_item.cleaned_data['quantity'] |
|
|
if float(user.solde) - float(prix_total) < solde_negatif: |
|
|
if float(user.solde) - float(total_price) < negative_balance: |
|
|
messages.error( |
|
|
messages.error( |
|
|
request, |
|
|
request, |
|
|
_("The balance is too low for this operation.") |
|
|
_("The balance is too low for this operation.") |
|
|
@ -659,20 +724,26 @@ def new_facture_solde(request, userid): |
|
|
'users:profil', |
|
|
'users:profil', |
|
|
kwargs={'userid': userid} |
|
|
kwargs={'userid': userid} |
|
|
)) |
|
|
)) |
|
|
facture.save() |
|
|
# Saving the invoice |
|
|
|
|
|
invoice.save() |
|
|
|
|
|
|
|
|
|
|
|
# Building a purchase for each article sold |
|
|
for art_item in articles: |
|
|
for art_item in articles: |
|
|
if art_item.cleaned_data: |
|
|
if art_item.cleaned_data: |
|
|
article = art_item.cleaned_data['article'] |
|
|
article = art_item.cleaned_data['article'] |
|
|
quantity = art_item.cleaned_data['quantity'] |
|
|
quantity = art_item.cleaned_data['quantity'] |
|
|
new_vente = Vente.objects.create( |
|
|
new_purchase = Vente.objects.create( |
|
|
facture=facture, |
|
|
facture=invoice, |
|
|
name=article.name, |
|
|
name=article.name, |
|
|
prix=article.prix, |
|
|
prix=article.prix, |
|
|
type_cotisation=article.type_cotisation, |
|
|
type_cotisation=article.type_cotisation, |
|
|
duration=article.duration, |
|
|
duration=article.duration, |
|
|
number=quantity |
|
|
number=quantity |
|
|
) |
|
|
) |
|
|
new_vente.save() |
|
|
new_purchase.save() |
|
|
|
|
|
|
|
|
|
|
|
# In case a cotisation was bought, inform the user, the |
|
|
|
|
|
# cotisation time has been extended too |
|
|
if any(art_item.cleaned_data['article'].type_cotisation |
|
|
if any(art_item.cleaned_data['article'].type_cotisation |
|
|
for art_item in articles if art_item.cleaned_data): |
|
|
for art_item in articles if art_item.cleaned_data): |
|
|
messages.success( |
|
|
messages.success( |
|
|
@ -683,6 +754,7 @@ def new_facture_solde(request, userid): |
|
|
end_date: user.end_adhesion() |
|
|
end_date: user.end_adhesion() |
|
|
} |
|
|
} |
|
|
) |
|
|
) |
|
|
|
|
|
# Else, only tell the invoice was created |
|
|
else: |
|
|
else: |
|
|
messages.success( |
|
|
messages.success( |
|
|
request, |
|
|
request, |
|
|
@ -707,9 +779,12 @@ def new_facture_solde(request, userid): |
|
|
}, 'cotisations/new_facture_solde.html', request) |
|
|
}, 'cotisations/new_facture_solde.html', request) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO : change recharge to reload |
|
|
# TODO : change recharge to refill |
|
|
@login_required |
|
|
@login_required |
|
|
def recharge(request): |
|
|
def recharge(request): |
|
|
|
|
|
""" |
|
|
|
|
|
View used to refill the balance by using online payment. |
|
|
|
|
|
""" |
|
|
if AssoOption.get_cached_value('payment') == 'NONE': |
|
|
if AssoOption.get_cached_value('payment') == 'NONE': |
|
|
messages.error( |
|
|
messages.error( |
|
|
request, |
|
|
request, |
|
|
@ -719,20 +794,22 @@ def recharge(request): |
|
|
'users:profil', |
|
|
'users:profil', |
|
|
kwargs={'userid': request.user.id} |
|
|
kwargs={'userid': request.user.id} |
|
|
)) |
|
|
)) |
|
|
f = RechargeForm(request.POST or None, user=request.user) |
|
|
refill_form = RechargeForm(request.POST or None, user=request.user) |
|
|
if f.is_valid(): |
|
|
if refill_form.is_valid(): |
|
|
facture = Facture(user=request.user) |
|
|
invoice = Facture(user=request.user) |
|
|
paiement, _created = Paiement.objects.get_or_create(moyen='Rechargement en ligne') |
|
|
payment, _created = Paiement.objects.get_or_create(moyen='Rechargement en ligne') |
|
|
facture.paiement = paiement |
|
|
facture.paiement = payment |
|
|
facture.valid = False |
|
|
facture.valid = False |
|
|
facture.save() |
|
|
facture.save() |
|
|
v = Vente.objects.create( |
|
|
purchase = Vente.objects.create( |
|
|
facture=facture, |
|
|
facture=invoice, |
|
|
name='solde', |
|
|
name='solde', |
|
|
prix=f.cleaned_data['value'], |
|
|
prix=refill_form.cleaned_data['value'], |
|
|
number=1, |
|
|
number=1 |
|
|
) |
|
|
) |
|
|
v.save() |
|
|
purchase.save() |
|
|
content = payment.PAYMENT_SYSTEM[AssoOption.get_cached_value('payment')](facture, 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({'rechargeform':f}, 'cotisations/recharge.html', request) |
|
|
return form({ |
|
|
|
|
|
'rechargeform': refill_form |
|
|
|
|
|
}, 'cotisations/recharge.html', request) |
|
|
|