mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-26 14:42:25 +00:00
Ajout de la possibilité de recharger son solde.
This commit is contained in:
parent
5887eb68ae
commit
dbe582238f
7 changed files with 105 additions and 66 deletions
|
@ -42,10 +42,10 @@ from django.core.validators import MinValueValidator
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from django.utils.translation import ugettext_lazy as _l
|
from django.utils.translation import ugettext_lazy as _l
|
||||||
|
|
||||||
from preferences.models import OptionalUser
|
|
||||||
from re2o.field_permissions import FieldPermissionFormMixin
|
from re2o.field_permissions import FieldPermissionFormMixin
|
||||||
from re2o.mixins import FormRevMixin
|
from re2o.mixins import FormRevMixin
|
||||||
from .models import Article, Paiement, Facture, Banque
|
from .models import Article, Paiement, Facture, Banque
|
||||||
|
from .payment_methods import balance
|
||||||
|
|
||||||
|
|
||||||
class NewFactureForm(FormRevMixin, ModelForm):
|
class NewFactureForm(FormRevMixin, ModelForm):
|
||||||
|
@ -362,34 +362,41 @@ class RechargeForm(FormRevMixin, Form):
|
||||||
min_value=0.01,
|
min_value=0.01,
|
||||||
validators=[]
|
validators=[]
|
||||||
)
|
)
|
||||||
|
payment = forms.ModelChoiceField(
|
||||||
|
queryset=Paiement.objects.none(),
|
||||||
|
label=_l("Payment method")
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.user = kwargs.pop('user')
|
self.user = kwargs.pop('user')
|
||||||
super(RechargeForm, self).__init__(*args, **kwargs)
|
super(RechargeForm, self).__init__(*args, **kwargs)
|
||||||
|
self.fields['payment'].empty_label = \
|
||||||
|
_("Select a payment method")
|
||||||
|
self.fields['payment'].queryset = Paiement.objects.filter(
|
||||||
|
pk__in=map(lambda x: x.pk,
|
||||||
|
Paiement.find_allowed_payments(self.user))
|
||||||
|
)
|
||||||
|
|
||||||
def clean_value(self):
|
def clean_value(self):
|
||||||
"""
|
"""
|
||||||
Returns a cleaned vlaue from the received form by validating
|
Returns a cleaned value from the received form by validating
|
||||||
the value is well inside the possible limits
|
the value is well inside the possible limits
|
||||||
"""
|
"""
|
||||||
value = self.cleaned_data['value']
|
value = self.cleaned_data['value']
|
||||||
if value < OptionalUser.get_cached_value('min_online_payment'):
|
balance_method, _created = balance.PaymentMethod\
|
||||||
|
.objects.get_or_create()
|
||||||
|
if value < balance_method.minimum_balance:
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(
|
||||||
_("Requested amount is too small. Minimum amount possible : \
|
_("Requested amount is too small. Minimum amount possible : \
|
||||||
%(min_online_amount)s €.") % {
|
%(min_online_amount)s €.") % {
|
||||||
'min_online_amount': OptionalUser.get_cached_value(
|
'min_online_amount': balance_method.minimum_balance
|
||||||
'min_online_payment'
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if value + self.user.solde > \
|
if value + self.user.solde > balance_method.maximum_balance:
|
||||||
OptionalUser.get_cached_value('max_solde'):
|
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(
|
||||||
_("Requested amount is too high. Your balance can't exceed \
|
_("Requested amount is too high. Your balance can't exceed \
|
||||||
%(max_online_balance)s €.") % {
|
%(max_online_balance)s €.") % {
|
||||||
'max_online_balance': OptionalUser.get_cached_value(
|
'max_online_balance': balance_method.maximum_balance
|
||||||
'max_solde'
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return value
|
return value
|
||||||
|
|
35
cotisations/migrations/0037_auto_20180703_1202.py
Normal file
35
cotisations/migrations/0037_auto_20180703_1202.py
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.7 on 2018-07-03 17:02
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
def create_max_balance(apps, schema_editor):
|
||||||
|
OptionalUser = apps.get_model('preferences', 'OptionalUser')
|
||||||
|
Payment = apps.get_model('cotisations', 'Paiement')
|
||||||
|
|
||||||
|
balance, _created = Payment.objects.get_or_create(moyen='solde')
|
||||||
|
options, _created = OptionalUser.objects.get_or_create()
|
||||||
|
|
||||||
|
balance.maximum_balance = options.max_solde
|
||||||
|
balance.save()
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('cotisations', '0036_auto_20180703_1056'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='paiement',
|
||||||
|
options={'permissions': (('view_paiement', "Can see a payement's details"), ('use_every_payment', 'Can use every payement')), 'verbose_name': 'Payment method', 'verbose_name_plural': 'Payment methods'},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='balancepayment',
|
||||||
|
name='maximum_balance',
|
||||||
|
field=models.DecimalField(decimal_places=2, default=50, help_text='The maximal amount of money allowed for the balance.', max_digits=5, verbose_name='Maximum balance'),
|
||||||
|
),
|
||||||
|
migrations.RunPython(create_max_balance)
|
||||||
|
]
|
|
@ -28,6 +28,13 @@ class BalancePayment(PaymentMethodMixin, models.Model):
|
||||||
max_digits=5,
|
max_digits=5,
|
||||||
decimal_places=2,
|
decimal_places=2,
|
||||||
)
|
)
|
||||||
|
maximum_balance = models.DecimalField(
|
||||||
|
verbose_name=_l("Maximum balance"),
|
||||||
|
help_text=_l("The maximal amount of money allowed for the balance."),
|
||||||
|
max_digits=5,
|
||||||
|
decimal_places=2,
|
||||||
|
default=50
|
||||||
|
)
|
||||||
|
|
||||||
def end_payment(self, invoice, request):
|
def end_payment(self, invoice, request):
|
||||||
user = invoice.user
|
user = invoice.user
|
||||||
|
|
|
@ -37,7 +37,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
</h3>
|
</h3>
|
||||||
<form class="form" method="{{ method }}" action="{{ action }}">
|
<form class="form" method="{{ method }}" action="{{ action }}">
|
||||||
{{ content | safe }}
|
{{ content | safe }}
|
||||||
|
{% if form %}
|
||||||
{% bootstrap_form form %}
|
{% bootstrap_form form %}
|
||||||
|
{% endif %}
|
||||||
{% trans "Pay" as tr_pay %}
|
{% trans "Pay" as tr_pay %}
|
||||||
{% bootstrap_button tr_pay button_type='submit' icon='piggy-bank' %}
|
{% bootstrap_button tr_pay button_type='submit' icon='piggy-bank' %}
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -821,24 +821,11 @@ def recharge(request):
|
||||||
"""
|
"""
|
||||||
View used to refill the balance by using online payment.
|
View used to refill the balance by using online payment.
|
||||||
"""
|
"""
|
||||||
if AssoOption.get_cached_value('payment') == 'NONE':
|
|
||||||
messages.error(
|
|
||||||
request,
|
|
||||||
_("Online payment is disabled.")
|
|
||||||
)
|
|
||||||
return redirect(reverse(
|
|
||||||
'users:profil',
|
|
||||||
kwargs={'userid': request.user.id}
|
|
||||||
))
|
|
||||||
refill_form = RechargeForm(request.POST or None, user=request.user)
|
refill_form = RechargeForm(request.POST or None, user=request.user)
|
||||||
if refill_form.is_valid():
|
if refill_form.is_valid():
|
||||||
invoice = Facture(user=request.user)
|
invoice = Facture(user=request.user)
|
||||||
payment, _created = Paiement.objects.get_or_create(
|
invoice.paiement = refill_form.cleaned_data['payment']
|
||||||
moyen='Rechargement en ligne'
|
|
||||||
)
|
|
||||||
invoice.paiement = payment
|
|
||||||
invoice.valid = False
|
invoice.valid = False
|
||||||
invoice.save()
|
|
||||||
purchase = Vente.objects.create(
|
purchase = Vente.objects.create(
|
||||||
facture=invoice,
|
facture=invoice,
|
||||||
name='solde',
|
name='solde',
|
||||||
|
@ -846,10 +833,8 @@ def recharge(request):
|
||||||
number=1
|
number=1
|
||||||
)
|
)
|
||||||
purchase.save()
|
purchase.save()
|
||||||
# content = online_payment.PAYMENT_SYSTEM[
|
invoice.save()
|
||||||
# AssoOption.get_cached_value('payment')
|
return invoice.paiement.end_payment(invoice, request)
|
||||||
# ](invoice, request)
|
|
||||||
return render(request, 'cotisations/payment.html', content)
|
|
||||||
return form({
|
return form({
|
||||||
'rechargeform': refill_form,
|
'rechargeform': refill_form,
|
||||||
'solde': request.user.solde
|
'solde': request.user.solde
|
||||||
|
|
|
@ -166,7 +166,7 @@ non adhérent</span>{% endif %} et votre connexion est {% if users.has_access %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>Solde</th>
|
<th>Solde</th>
|
||||||
<td>{{ users.solde }} €
|
<td>{{ users.solde }} €
|
||||||
{% if user_solde and allow_online_payment %}
|
{% if user_solde %}
|
||||||
<a class="btn btn-primary btn-sm" style='float:right' role="button" href="{% url 'cotisations:recharge' %}">
|
<a class="btn btn-primary btn-sm" style='float:right' role="button" href="{% url 'cotisations:recharge' %}">
|
||||||
<i class="fa fa-euro-sign"></i>
|
<i class="fa fa-euro-sign"></i>
|
||||||
Recharger
|
Recharger
|
||||||
|
|
|
@ -49,9 +49,9 @@ from django.views.decorators.csrf import csrf_exempt
|
||||||
from rest_framework.renderers import JSONRenderer
|
from rest_framework.renderers import JSONRenderer
|
||||||
from reversion import revisions as reversion
|
from reversion import revisions as reversion
|
||||||
|
|
||||||
from cotisations.models import Facture
|
from cotisations.models import Facture, Paiement
|
||||||
from machines.models import Machine
|
from machines.models import Machine
|
||||||
from preferences.models import OptionalUser, GeneralOption, AssoOption
|
from preferences.models import GeneralOption
|
||||||
from re2o.views import form
|
from re2o.views import form
|
||||||
from re2o.utils import (
|
from re2o.utils import (
|
||||||
all_has_access,
|
all_has_access,
|
||||||
|
@ -246,7 +246,8 @@ def state(request, user, userid):
|
||||||
@can_edit(User, 'groups')
|
@can_edit(User, 'groups')
|
||||||
def groups(request, user, userid):
|
def groups(request, user, userid):
|
||||||
""" View to edit the groups of a user """
|
""" View to edit the groups of a user """
|
||||||
group_form = GroupForm(request.POST or None, instance=user, user=request.user)
|
group_form = GroupForm(request.POST or None,
|
||||||
|
instance=user, user=request.user)
|
||||||
if group_form.is_valid():
|
if group_form.is_valid():
|
||||||
if group_form.changed_data:
|
if group_form.changed_data:
|
||||||
group_form.save()
|
group_form.save()
|
||||||
|
@ -404,23 +405,23 @@ def edit_ban(request, ban_instance, **_kwargs):
|
||||||
request
|
request
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_delete(Ban)
|
@can_delete(Ban)
|
||||||
def del_ban(request, ban, **_kwargs):
|
def del_ban(request, ban, **_kwargs):
|
||||||
""" Supprime un banissement"""
|
""" Supprime un banissement"""
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
ban.delete()
|
ban.delete()
|
||||||
messages.success(request, "Le banissement a été supprimé")
|
messages.success(request, "Le banissement a été supprimé")
|
||||||
return redirect(reverse(
|
return redirect(reverse(
|
||||||
'users:profil',
|
'users:profil',
|
||||||
kwargs={'userid': str(ban.user.id)}
|
kwargs={'userid': str(ban.user.id)}
|
||||||
))
|
))
|
||||||
return form(
|
return form(
|
||||||
{'objet': ban, 'objet_name': 'ban'},
|
{'objet': ban, 'objet_name': 'ban'},
|
||||||
'users/delete.html',
|
'users/delete.html',
|
||||||
request
|
request
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -481,19 +482,20 @@ def edit_whitelist(request, whitelist_instance, **_kwargs):
|
||||||
@login_required
|
@login_required
|
||||||
@can_delete(Whitelist)
|
@can_delete(Whitelist)
|
||||||
def del_whitelist(request, whitelist, **_kwargs):
|
def del_whitelist(request, whitelist, **_kwargs):
|
||||||
""" Supprime un acces gracieux"""
|
""" Supprime un acces gracieux"""
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
whitelist.delete()
|
whitelist.delete()
|
||||||
messages.success(request, "L'accés gracieux a été supprimé")
|
messages.success(request, "L'accés gracieux a été supprimé")
|
||||||
return redirect(reverse(
|
return redirect(reverse(
|
||||||
'users:profil',
|
'users:profil',
|
||||||
kwargs={'userid': str(whitelist.user.id)}
|
kwargs={'userid': str(whitelist.user.id)}
|
||||||
))
|
))
|
||||||
return form(
|
return form(
|
||||||
{'objet': whitelist, 'objet_name': 'whitelist'},
|
{'objet': whitelist, 'objet_name': 'whitelist'},
|
||||||
'users/delete.html',
|
'users/delete.html',
|
||||||
request
|
request
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_create(School)
|
@can_create(School)
|
||||||
|
@ -814,7 +816,7 @@ def index_listright(request):
|
||||||
'users/index_listright.html',
|
'users/index_listright.html',
|
||||||
{
|
{
|
||||||
'listright_list': listright_list,
|
'listright_list': listright_list,
|
||||||
'superuser_right' : superuser_right,
|
'superuser_right': superuser_right,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -837,7 +839,7 @@ def mon_profil(request):
|
||||||
return redirect(reverse(
|
return redirect(reverse(
|
||||||
'users:profil',
|
'users:profil',
|
||||||
kwargs={'userid': str(request.user.id)}
|
kwargs={'userid': str(request.user.id)}
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -881,20 +883,20 @@ def profil(request, users, **_kwargs):
|
||||||
request.GET.get('order'),
|
request.GET.get('order'),
|
||||||
SortTable.USERS_INDEX_WHITE
|
SortTable.USERS_INDEX_WHITE
|
||||||
)
|
)
|
||||||
user_solde = OptionalUser.get_cached_value('user_solde')
|
balance, _created = Paiement.objects.get_or_create(moyen="solde")
|
||||||
allow_online_payment = True# TODO : AssoOption.get_cached_value('payment') != 'NONE'
|
user_solde = Facture.can_create(request.user) \
|
||||||
|
and balance.can_use_payment(request.user)
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
'users/profil.html',
|
'users/profil.html',
|
||||||
{
|
{
|
||||||
'users': users,
|
'users': users,
|
||||||
'machines_list': machines,
|
'machines_list': machines,
|
||||||
'nb_machines' : nb_machines,
|
'nb_machines': nb_machines,
|
||||||
'facture_list': factures,
|
'facture_list': factures,
|
||||||
'ban_list': bans,
|
'ban_list': bans,
|
||||||
'white_list': whitelists,
|
'white_list': whitelists,
|
||||||
'user_solde': user_solde,
|
'user_solde': user_solde,
|
||||||
'allow_online_payment': allow_online_payment,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -959,6 +961,7 @@ def process_passwd(request, req):
|
||||||
|
|
||||||
class JSONResponse(HttpResponse):
|
class JSONResponse(HttpResponse):
|
||||||
""" Framework Rest """
|
""" Framework Rest """
|
||||||
|
|
||||||
def __init__(self, data, **kwargs):
|
def __init__(self, data, **kwargs):
|
||||||
content = JSONRenderer().render(data)
|
content = JSONRenderer().render(data)
|
||||||
kwargs['content_type'] = 'application/json'
|
kwargs['content_type'] = 'application/json'
|
||||||
|
|
Loading…
Reference in a new issue