mirror of https://gitlab.crans.org/bde/nk20
parent
b1cd46bf7d
commit
fbc25240e6
|
@ -230,6 +230,7 @@ class Membership(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
date_start = models.DateField(
|
date_start = models.DateField(
|
||||||
|
default=datetime.date.today,
|
||||||
verbose_name=_('membership starts on'),
|
verbose_name=_('membership starts on'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ from polymorphic.admin import PolymorphicChildModelAdmin, \
|
||||||
|
|
||||||
from .models.notes import Alias, Note, NoteClub, NoteSpecial, NoteUser
|
from .models.notes import Alias, Note, NoteClub, NoteSpecial, NoteUser
|
||||||
from .models.transactions import Transaction, TemplateCategory, TransactionTemplate, \
|
from .models.transactions import Transaction, TemplateCategory, TransactionTemplate, \
|
||||||
RecurrentTransaction, MembershipTransaction
|
RecurrentTransaction, MembershipTransaction, SpecialTransaction
|
||||||
|
|
||||||
|
|
||||||
class AliasInlines(admin.TabularInline):
|
class AliasInlines(admin.TabularInline):
|
||||||
|
@ -102,7 +102,7 @@ class TransactionAdmin(PolymorphicParentModelAdmin):
|
||||||
"""
|
"""
|
||||||
Admin customisation for Transaction
|
Admin customisation for Transaction
|
||||||
"""
|
"""
|
||||||
child_models = (RecurrentTransaction, MembershipTransaction)
|
child_models = (RecurrentTransaction, MembershipTransaction, SpecialTransaction)
|
||||||
list_display = ('created_at', 'poly_source', 'poly_destination',
|
list_display = ('created_at', 'poly_source', 'poly_destination',
|
||||||
'quantity', 'amount', 'valid')
|
'quantity', 'amount', 'valid')
|
||||||
list_filter = ('valid',)
|
list_filter = ('valid',)
|
||||||
|
@ -141,7 +141,14 @@ class TransactionAdmin(PolymorphicParentModelAdmin):
|
||||||
@admin.register(MembershipTransaction)
|
@admin.register(MembershipTransaction)
|
||||||
class MembershipTransactionAdmin(PolymorphicChildModelAdmin):
|
class MembershipTransactionAdmin(PolymorphicChildModelAdmin):
|
||||||
"""
|
"""
|
||||||
Admin customisation for Transaction
|
Admin customisation for MembershipTransaction
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(SpecialTransaction)
|
||||||
|
class SpecialTransactionAdmin(PolymorphicChildModelAdmin):
|
||||||
|
"""
|
||||||
|
Admin customisation for SpecialTransaction
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
from django import forms
|
||||||
from django.contrib.auth.forms import UserCreationForm
|
from django.contrib.auth.forms import UserCreationForm
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from note.models import NoteSpecial
|
||||||
|
from note_kfet.inputs import AmountInput
|
||||||
|
|
||||||
|
|
||||||
class SignUpForm(UserCreationForm):
|
class SignUpForm(UserCreationForm):
|
||||||
|
@ -19,3 +22,46 @@ class SignUpForm(UserCreationForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
fields = ('first_name', 'last_name', 'username', 'email', )
|
fields = ('first_name', 'last_name', 'username', 'email', )
|
||||||
|
|
||||||
|
|
||||||
|
class ValidationForm(forms.Form):
|
||||||
|
credit_type = forms.ModelChoiceField(
|
||||||
|
queryset=NoteSpecial.objects,
|
||||||
|
label=_("Credit type"),
|
||||||
|
empty_label=_("No credit"),
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
credit_amount = forms.IntegerField(
|
||||||
|
label=_("Credit amount"),
|
||||||
|
required=False,
|
||||||
|
initial=0,
|
||||||
|
widget=AmountInput(),
|
||||||
|
)
|
||||||
|
|
||||||
|
last_name = forms.CharField(
|
||||||
|
label=_("Last name"),
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
first_name = forms.CharField(
|
||||||
|
label=_("First name"),
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
bank = forms.CharField(
|
||||||
|
label=_("Bank"),
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
join_BDE = forms.BooleanField(
|
||||||
|
label=_("Join BDE"),
|
||||||
|
required=False,
|
||||||
|
initial=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
join_Kfet = forms.BooleanField(
|
||||||
|
label=_("Join Kfet"),
|
||||||
|
required=False,
|
||||||
|
initial=True,
|
||||||
|
)
|
||||||
|
|
|
@ -12,14 +12,16 @@ from django.utils.http import urlsafe_base64_decode
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.views import View
|
from django.views import View
|
||||||
from django.views.decorators.csrf import csrf_protect
|
from django.views.decorators.csrf import csrf_protect
|
||||||
from django.views.generic import CreateView, TemplateView, DetailView
|
from django.views.generic import CreateView, TemplateView, DetailView, FormView
|
||||||
from django_tables2 import SingleTableView
|
from django_tables2 import SingleTableView
|
||||||
from member.forms import ProfileForm
|
from member.forms import ProfileForm
|
||||||
from member.models import Profile
|
from member.models import Membership, Club
|
||||||
|
from note.models import SpecialTransaction
|
||||||
|
from note.templatetags.pretty_money import pretty_money
|
||||||
from permission.backends import PermissionBackend
|
from permission.backends import PermissionBackend
|
||||||
from permission.views import ProtectQuerysetMixin
|
from permission.views import ProtectQuerysetMixin
|
||||||
|
|
||||||
from .forms import SignUpForm
|
from .forms import SignUpForm, ValidationForm
|
||||||
from .tables import FutureUserTable
|
from .tables import FutureUserTable
|
||||||
from .tokens import account_activation_token
|
from .tokens import account_activation_token
|
||||||
|
|
||||||
|
@ -138,11 +140,12 @@ class FutureUserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableVi
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
|
class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView, FormView):
|
||||||
"""
|
"""
|
||||||
Affiche les informations sur un utilisateur, sa note, ses clubs...
|
Affiche les informations sur un utilisateur, sa note, ses clubs...
|
||||||
"""
|
"""
|
||||||
model = User
|
model = User
|
||||||
|
form_class = ValidationForm
|
||||||
context_object_name = "user_object"
|
context_object_name = "user_object"
|
||||||
template_name = "registration/future_profile_detail.html"
|
template_name = "registration/future_profile_detail.html"
|
||||||
|
|
||||||
|
@ -152,6 +155,92 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView)
|
||||||
"""
|
"""
|
||||||
return super().get_queryset().filter(profile__registration_valid=False)
|
return super().get_queryset().filter(profile__registration_valid=False)
|
||||||
|
|
||||||
|
def get_form(self, form_class=None):
|
||||||
|
form = super().get_form(form_class)
|
||||||
|
user = self.get_object()
|
||||||
|
form.fields["last_name"].initial = user.last_name
|
||||||
|
form.fields["first_name"].initial = user.first_name
|
||||||
|
return form
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
user = self.object = self.get_object()
|
||||||
|
|
||||||
|
print(form.cleaned_data)
|
||||||
|
credit_type = form.cleaned_data["credit_type"]
|
||||||
|
credit_amount = form.cleaned_data["credit_amount"]
|
||||||
|
last_name = form.cleaned_data["last_name"]
|
||||||
|
first_name = form.cleaned_data["first_name"]
|
||||||
|
bank = form.cleaned_data["bank"]
|
||||||
|
join_BDE = form.cleaned_data["join_BDE"]
|
||||||
|
join_Kfet = form.cleaned_data["join_Kfet"]
|
||||||
|
|
||||||
|
fee = 0
|
||||||
|
bde = Club.objects.get(name="BDE")
|
||||||
|
bde_fee = bde.membership_fee_paid if user.profile.paid else bde.membership_fee_unpaid
|
||||||
|
if join_BDE:
|
||||||
|
fee += bde_fee
|
||||||
|
kfet = Club.objects.get(name="Kfet")
|
||||||
|
kfet_fee = kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid
|
||||||
|
if join_Kfet:
|
||||||
|
fee += kfet_fee
|
||||||
|
|
||||||
|
if join_Kfet and not join_BDE:
|
||||||
|
form.add_error('join_Kfet', _("You must join BDE club before joining Kfet club."))
|
||||||
|
|
||||||
|
if fee > credit_amount:
|
||||||
|
form.add_error('credit_type',
|
||||||
|
_("The entered amount is not enough for the memberships, should be at least {}")
|
||||||
|
.format(pretty_money(fee)))
|
||||||
|
return self.form_invalid(form)
|
||||||
|
|
||||||
|
if credit_type is not None and credit_amount > 0:
|
||||||
|
if not last_name or not first_name or not bank:
|
||||||
|
if not last_name:
|
||||||
|
form.add_error('last_name', _("This field is required."))
|
||||||
|
if not first_name:
|
||||||
|
form.add_error('first_name', _("This field is required."))
|
||||||
|
if not bank:
|
||||||
|
form.add_error('bank', _("This field is required."))
|
||||||
|
return self.form_invalid(form)
|
||||||
|
|
||||||
|
ret = super().form_valid(form)
|
||||||
|
user.is_active = True
|
||||||
|
user.profile.registration_valid = True
|
||||||
|
user.save()
|
||||||
|
user.profile.save()
|
||||||
|
|
||||||
|
if credit_type is not None and credit_amount > 0:
|
||||||
|
SpecialTransaction.objects.create(
|
||||||
|
source=credit_type,
|
||||||
|
destination=user.note,
|
||||||
|
quantity=1,
|
||||||
|
amount=credit_amount,
|
||||||
|
reason="Crédit " + credit_type.special_type + " (Inscription)",
|
||||||
|
last_name=last_name,
|
||||||
|
first_name=first_name,
|
||||||
|
bank=bank,
|
||||||
|
valid=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
if join_BDE:
|
||||||
|
Membership.objects.create(
|
||||||
|
club=bde,
|
||||||
|
user=user,
|
||||||
|
fee=bde_fee,
|
||||||
|
)
|
||||||
|
|
||||||
|
if join_Kfet:
|
||||||
|
Membership.objects.create(
|
||||||
|
club=kfet,
|
||||||
|
user=user,
|
||||||
|
fee=kfet_fee,
|
||||||
|
)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
return reverse_lazy('member:user_detail', args=(self.get_object().pk, ))
|
||||||
|
|
||||||
|
|
||||||
class FutureUserInvalidateView(ProtectQuerysetMixin, LoginRequiredMixin, View):
|
class FutureUserInvalidateView(ProtectQuerysetMixin, LoginRequiredMixin, View):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -13,7 +13,7 @@ class AmountInput(NumberInput):
|
||||||
template_name = "note/amount_input.html"
|
template_name = "note/amount_input.html"
|
||||||
|
|
||||||
def format_value(self, value):
|
def format_value(self, value):
|
||||||
return None if value is None or value == "" else "{:.02f}".format(value / 100, )
|
return None if value is None or value == "" else "{:.02f}".format(int(value) / 100, )
|
||||||
|
|
||||||
def value_from_datadict(self, data, files, name):
|
def value_from_datadict(self, data, files, name):
|
||||||
val = super().value_from_datadict(data, files, name)
|
val = super().value_from_datadict(data, files, name)
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load render_table from django_tables2 %}
|
{% load crispy_forms_tags %}
|
||||||
{% load pretty_money %}
|
{% load pretty_money %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
<div class="card bg-light shadow">
|
||||||
<div class="card bg-light shadow">
|
|
||||||
<div class="card-header text-center" >
|
<div class="card-header text-center" >
|
||||||
<h4> {% trans "Account #" %} {{ object.pk }}</h4>
|
<h4> {% trans "Account #" %} {{ object.pk }}</h4>
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,15 +39,27 @@
|
||||||
<dt class="col-xl-6">{% trans 'paid'|capfirst %}</dt>
|
<dt class="col-xl-6">{% trans 'paid'|capfirst %}</dt>
|
||||||
<dd class="col-xl-6">{{ object.profile.paid|yesno }}</dd>
|
<dd class="col-xl-6">{{ object.profile.paid|yesno }}</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
{% if object.pk == user.pk %}
|
|
||||||
<a class="small" href="{% url 'member:auth_token' %}">{% trans 'Manage auth token' %}</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer text-center">
|
<div class="card-footer text-center">
|
||||||
<a class="btn btn-primary btn-sm" href="{% url 'member:user_update_profile' object.pk %}">{% trans 'Update Profile' %}</a>
|
<a class="btn btn-primary btn-sm" href="{% url 'member:user_update_profile' object.pk %}">{% trans 'Update Profile' %}</a>
|
||||||
<a class="btn btn-danger btn-sm" href="{% url 'registration:future_user_invalidate' object.pk %}">{% trans 'Delete registration' %}</a>
|
<a class="btn btn-danger btn-sm" href="{% url 'registration:future_user_invalidate' object.pk %}">{% trans 'Delete registration' %}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="card bg-light shadow">
|
||||||
|
<form method="post">
|
||||||
|
<div class="card-header text-center" >
|
||||||
|
<h4> {% trans "Validate account" %}</h4>
|
||||||
|
</div>
|
||||||
|
<div class="card-body" id="profile_infos">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
</div>
|
||||||
|
<div class="card-footer text-center">
|
||||||
|
<button class="btn btn-success btn-sm">{% trans 'Validate registration' %}</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
Loading…
Reference in New Issue