8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-12-24 07:53:47 +00:00

Merge branch 'fix_online_payment' into crans

This commit is contained in:
Gabriel Detraz 2018-07-10 23:30:39 +02:00
commit 7d57715c0c
5 changed files with 46 additions and 196 deletions

View file

@ -49,28 +49,34 @@ from .models import Article, Paiement, Facture, Banque
from .payment_methods import balance from .payment_methods import balance
class NewFactureForm(FormRevMixin, ModelForm): class FactureForm(FieldPermissionFormMixin, FormRevMixin, ModelForm):
""" """
Form used to create a new invoice by using a payment method, a bank and a Form used to manage and create an invoice and its fields.
cheque number.
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, creation=False, **kwargs):
user = kwargs.pop('user') user = kwargs['user']
prefix = kwargs.pop('prefix', self.Meta.model.__name__) prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(NewFactureForm, self).__init__(*args, prefix=prefix, **kwargs) super(FactureForm, self).__init__(*args, prefix=prefix, **kwargs)
self.fields['paiement'].empty_label = \ self.fields['paiement'].empty_label = \
_("Select a payment method") _("Select a payment method")
self.fields['paiement'].queryset = Paiement.objects.filter( self.fields['paiement'].queryset = Paiement.objects.filter(
pk__in=map(lambda x: x.pk, Paiement.find_allowed_payments(user)) pk__in=map(lambda x: x.pk, Paiement.find_allowed_payments(user))
) )
if not creation:
self.fields['user'].label = _("Member")
self.fields['user'].empty_label = \
_("Select the proprietary member")
self.fields['valid'].label = _("Validated invoice")
else:
self.fields = {'paiement': self.fields['paiement']}
class Meta: class Meta:
model = Facture model = Facture
fields = ['paiement'] fields = '__all__'
def clean(self): def clean(self):
cleaned_data = super(NewFactureForm, self).clean() cleaned_data = super(FactureForm, self).clean()
paiement = cleaned_data.get('paiement') paiement = cleaned_data.get('paiement')
if not paiement: if not paiement:
raise forms.ValidationError( raise forms.ValidationError(
@ -151,26 +157,6 @@ class NewFactureFormPdf(Form):
) )
# TODO : change Facture to Invoice
class EditFactureForm(FieldPermissionFormMixin, NewFactureForm):
"""
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
fields = '__all__'
def __init__(self, *args, **kwargs):
# TODO : change Facture to Invoice
super(EditFactureForm, self).__init__(*args, **kwargs)
self.fields['user'].label = _("Member")
self.fields['user'].empty_label = \
_("Select the proprietary member")
self.fields['valid'].label = _("Validated invoice")
class ArticleForm(FormRevMixin, ModelForm): class ArticleForm(FormRevMixin, ModelForm):
""" """
Form used to create an article. Form used to create an article.

View file

@ -695,8 +695,8 @@ class Paiement(RevMixin, AclMixin, models.Model):
request, request,
_("The cotisation of %(member_name)s has been \ _("The cotisation of %(member_name)s has been \
extended to %(end_date)s.") % { extended to %(end_date)s.") % {
'member_name': request.user.pseudo, 'member_name': invoice.user.pseudo,
'end_date': request.user.end_adhesion() 'end_date': invoice.user.end_adhesion()
} }
) )
# Else, only tell the invoice was created # Else, only tell the invoice was created

View file

@ -36,12 +36,22 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endif %} {% endif %}
{% if title %} {% if title %}
<h3>{{title}}</h3> <h3>{{title}}</h3>
{% else %}
<h3>{% trans "New invoice" %}</h3>
{% endif %} {% endif %}
{% if balance %} {% if balance is not None %}
<h4>{% trans "Current balance :" %}{{balance}}€</h4> <p>
{% trans "Current balance :" %} {{ balance }} €
</p>
{% endif %} {% endif %}
<form class="form" method="post"> <form class="form" method="post">
{% csrf_token %} {% csrf_token %}
{% bootstrap_form factureform %}
{% if payment_method %}
{% bootstrap_form payment_method %}
<div id="paymentMethod"></div>
{% endif %}
{% if articlesformset %} {% if articlesformset %}
<h3>{% trans "Invoice's articles" %}</h3> <h3>{% trans "Invoice's articles" %}</h3>
<div id="form_set" class="form-group"> <div id="form_set" class="form-group">
@ -64,11 +74,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endblocktrans %} {% endblocktrans %}
</p> </p>
{% endif %} {% endif %}
{% bootstrap_form factureform %}
{% if payment_method %}
{% bootstrap_form payment_method %}
<div id="paymentMethod"></div>
{% endif %}
{% bootstrap_button action_name button_type='submit' icon='star' %} {% bootstrap_button action_name button_type='submit' icon='star' %}
</form> </form>

View file

@ -1,148 +0,0 @@
{% extends "cotisations/sidebar.html" %}
{% comment %}
Re2o est un logiciel d'administration développé initiallement au rezometz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2017 Gabriel Détraz
Copyright © 2017 Goulven Kermarec
Copyright © 2017 Augustin Lemesle
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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.
{% endcomment %}
{% load bootstrap3 %}
{% load staticfiles%}
{% load i18n %}
{% block title %}{% trans "Invoices creation and edition" %}{% endblock %}
{% block content %}
{% bootstrap_form_errors factureform %}
<form class="form" method="post">
{% csrf_token %}
<h3>{% trans "New invoice" %}</h3>
{% if user.solde %}
<p>
{% blocktrans %}
User's balance : {{ user.solde }} €
{% endblocktrans %}
</p>
{% endif %}
{% bootstrap_form factureform %}
{{ venteform.management_form }}
<h3>{% trans "Invoice's articles" %}</h3>
<div id="form_set" class="form-group">
{% for form in venteform.forms %}
<div class='product_to_sell form-inline'>
{% trans "Article" %} : &nbsp;
{% bootstrap_form form label_class='sr-only' %}
&nbsp;
<button class="btn btn-danger btn-sm" id="id_form-0-article-remove" type="button">
<span class="fa fa-times"></span>
</button>
</div>
{% endfor %}
</div>
<input class="btn btn-primary btn-sm" role="button" value="{% trans "Add an article"%}" id="add_one">
<p>
{% blocktrans %}
Total price : <span id="total_price">0,00</span>
{% endblocktrans %}
</p>
{% trans "Create" as tr_create %}
{% bootstrap_button tr_create button_type='submit' icon='star' %}
</form>
<script type="text/javascript">
var prices = {};
{% for article in articlelist %}
prices[{{ article.id|escapejs }}] = {{ article.prix }};
{% endfor %}
var template = `Article : &nbsp;
{% bootstrap_form venteform.empty_form label_class='sr-only' %}
&nbsp;
<button class="btn btn-danger btn-sm"
id="id_form-__prefix__-article-remove" type="button">
<span class="fa fa-times"></span>
</button>`
function add_article(){
// Index start at 0 => new_index = number of items
var new_index =
document.getElementsByClassName('product_to_sell').length;
document.getElementById('id_form-TOTAL_FORMS').value ++;
var new_article = document.createElement('div');
new_article.className = 'product_to_sell form-inline';
new_article.innerHTML = template.replace(/__prefix__/g, new_index);
document.getElementById('form_set').appendChild(new_article);
add_listenner_for_id(new_index);
}
function update_price(){
var price = 0;
var product_count =
document.getElementsByClassName('product_to_sell').length;
var article, article_price, quantity;
for (i = 0; i < product_count; ++i){
article = document.getElementById(
'id_form-' + i.toString() + '-article').value;
if (article == '') {
continue;
}
article_price = prices[article];
quantity = document.getElementById(
'id_form-' + i.toString() + '-quantity').value;
price += article_price * quantity;
}
document.getElementById('total_price').innerHTML =
price.toFixed(2).toString().replace('.', ',');
}
function add_listenner_for_id(i){
document.getElementById('id_form-' + i.toString() + '-article')
.addEventListener("change", update_price, true);
document.getElementById('id_form-' + i.toString() + '-article')
.addEventListener("onkeypress", update_price, true);
document.getElementById('id_form-' + i.toString() + '-quantity')
.addEventListener("change", update_price, true);
document.getElementById('id_form-' + i.toString() + '-article-remove')
.addEventListener("click", function(event) {
var article = event.target.parentNode;
article.parentNode.removeChild(article);
document.getElementById('id_form-TOTAL_FORMS').value --;
update_price();
}
)
}
// Add events manager when DOM is fully loaded
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("add_one")
.addEventListener("click", add_article, true);
var product_count =
document.getElementsByClassName('product_to_sell').length;
for (i = 0; i < product_count; ++i){
add_listenner_for_id(i);
}
update_price();
});
</script>
{% endblock %}

View file

@ -60,8 +60,7 @@ from re2o.acl import (
from preferences.models import AssoOption, GeneralOption from preferences.models import AssoOption, GeneralOption
from .models import Facture, Article, Vente, Paiement, Banque from .models import Facture, Article, Vente, Paiement, Banque
from .forms import ( from .forms import (
NewFactureForm, FactureForm,
EditFactureForm,
ArticleForm, ArticleForm,
DelArticleForm, DelArticleForm,
PaiementForm, PaiementForm,
@ -84,7 +83,7 @@ def new_facture(request, user, userid):
""" """
View called to create a new invoice. View called to create a new invoice.
Currently, Send the list of available articles for the user along with Currently, Send the list of available articles for the user along with
a formset of a new invoice (based on the `:forms:NewFactureForm()` form. a formset of a new invoice (based on the `:forms:FactureForm()` form.
A bit of JS is used in the template to add articles in a fancier way. A bit of JS is used in the template to add articles in a fancier way.
If everything is correct, save each one of the articles, save the If everything is correct, save each one of the articles, save the
purchase object associated and finally the newly created invoice. purchase object associated and finally the newly created invoice.
@ -95,10 +94,11 @@ def new_facture(request, user, userid):
Q(type_user='All') | Q(type_user=request.user.class_name) Q(type_user='All') | Q(type_user=request.user.class_name)
) )
# Building the invoice form and the article formset # Building the invoice form and the article formset
invoice_form = NewFactureForm( invoice_form = FactureForm(
request.POST or None, request.POST or None,
instance=invoice, instance=invoice,
user=request.user user=request.user,
creation=True
) )
if request.user.is_class_club: if request.user.is_class_club:
@ -143,13 +143,20 @@ def new_facture(request, user, userid):
request, request,
_("You need to choose at least one article.") _("You need to choose at least one article.")
) )
p = Paiement.objects.filter(is_balance=True)
if len(p) and p[0].can_use_payment(request.user):
balance = user.solde
else:
balance = None
return form( return form(
{ {
'factureform': invoice_form, 'factureform': invoice_form,
'venteform': article_formset, 'articlesformset': article_formset,
'articlelist': article_list 'articlelist': article_list,
'balance': balance,
'action_name': _('Create'),
}, },
'cotisations/new_facture.html', request 'cotisations/facture.html', request
) )
@ -271,7 +278,7 @@ def edit_facture(request, facture, **_kwargs):
can be set as desired. This is also the view used to invalidate can be set as desired. This is also the view used to invalidate
an invoice. an invoice.
""" """
invoice_form = EditFactureForm( invoice_form = FactureForm(
request.POST or None, request.POST or None,
instance=facture, instance=facture,
user=request.user user=request.user
@ -677,9 +684,9 @@ def credit_solde(request, user, **_kwargs):
""" """
refill_form = RechargeForm(request.POST or None, user=request.user) refill_form = RechargeForm(request.POST or None, user=request.user)
if refill_form.is_valid(): if refill_form.is_valid():
invoice = Facture(user=request.user) invoice = Facture(user=user)
invoice.paiement = refill_form.cleaned_data['payment'] invoice.paiement = refill_form.cleaned_data['payment']
invoice.valid = False invoice.valid = True
invoice.save() invoice.save()
Vente.objects.create( Vente.objects.create(
facture=invoice, facture=invoice,