It is possible to validate payment status

This commit is contained in:
Yohann D'ANELLO 2021-01-18 20:02:49 +01:00
parent 53a55ee898
commit 4cd1e43564
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
6 changed files with 140 additions and 39 deletions

View File

@ -8,7 +8,7 @@ from django.core.exceptions import ValidationError
from django.forms import FileInput from django.forms import FileInput
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .models import AdminRegistration, CoachRegistration, StudentRegistration, VolunteerRegistration from .models import AdminRegistration, CoachRegistration, Payment, StudentRegistration, VolunteerRegistration
class SignupForm(UserCreationForm): class SignupForm(UserCreationForm):
@ -197,3 +197,34 @@ class AdminRegistrationForm(forms.ModelForm):
class Meta: class Meta:
model = AdminRegistration model = AdminRegistration
fields = ('role', 'give_contact_to_animath', 'email_confirmed',) fields = ('role', 'give_contact_to_animath', 'email_confirmed',)
class PaymentForm(forms.ModelForm):
"""
Indicate payment information
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["valid"].widget.choices[0] = ('unknown', _("Pending"))
def clean_scholarship_file(self):
if "scholarship_file" in self.files:
file = self.files["scholarship_file"]
if file.size > 2e6:
raise ValidationError(_("The uploaded file size must be under 2 Mo."))
if file.content_type not in ["application/pdf", "image/png", "image/jpeg"]:
raise ValidationError(_("The uploaded file must be a PDF, PNG of JPEG file."))
return self.cleaned_data["scholarship_file"]
def clean(self):
cleaned_data = super().clean()
if "type" in cleaned_data and cleaned_data["type"] == "scholarship" \
and "scholarship" not in cleaned_data and not self.instance.scholarship_file:
self.add_error("scholarship_file", _("You must upload your scholarship attestation."))
return cleaned_data
class Meta:
model = Payment
fields = ('type', 'scholarship_file', 'additional_information', 'valid',)

View File

@ -338,6 +338,9 @@ class Payment(models.Model):
default=False, default=False,
) )
def get_absolute_url(self):
return reverse_lazy("registration:user_detail", args=(self.registration.user.id,))
class Meta: class Meta:
verbose_name = _("payment") verbose_name = _("payment")
verbose_name_plural = _("payments") verbose_name_plural = _("payments")

View File

@ -0,0 +1,14 @@
{% extends "base.html" %}
{% load crispy_forms_filters i18n %}
{% block content %}
<form method="post" enctype="multipart/form-data">
<div id="form-content">
{% csrf_token %}
{{ form|crispy }}
</div>
<button class="btn btn-primary" type="submit">{% trans "Update" %}</button>
</form>
{% endblock content %}

View File

@ -53,7 +53,7 @@
{% if user_object.registration.photo_authorization %} {% if user_object.registration.photo_authorization %}
<a href="{{ user_object.registration.photo_authorization.url }}" data-turbolinks="false">{% trans "Download" %}</a> <a href="{{ user_object.registration.photo_authorization.url }}" data-turbolinks="false">{% trans "Download" %}</a>
{% endif %} {% endif %}
{% if user_object.pk == user.pk %} {% if user_object.registration.team and not user_object.registration.team.participation.valid %}
<button class="btn btn-primary" data-toggle="modal" data-target="#uploadPhotoAuthorizationModal">{% trans "Replace" %}</button> <button class="btn btn-primary" data-toggle="modal" data-target="#uploadPhotoAuthorizationModal">{% trans "Replace" %}</button>
{% endif %} {% endif %}
</dd> </dd>
@ -63,7 +63,7 @@
{% if user_object.registration.health_sheet %} {% if user_object.registration.health_sheet %}
<a href="{{ user_object.registration.health_sheet.url }}" data-turbolinks="false">{% trans "Download" %}</a> <a href="{{ user_object.registration.health_sheet.url }}" data-turbolinks="false">{% trans "Download" %}</a>
{% endif %} {% endif %}
{% if user_object.pk == user.pk %} {% if user_object.registration.team and not user_object.registration.team.participation.valid %}
<button class="btn btn-primary" data-toggle="modal" data-target="#uploadHealthSheetModal">{% trans "Replace" %}</button> <button class="btn btn-primary" data-toggle="modal" data-target="#uploadHealthSheetModal">{% trans "Replace" %}</button>
{% endif %} {% endif %}
</dd> </dd>
@ -76,7 +76,7 @@
{% if user_object.registration.parental_authorization %} {% if user_object.registration.parental_authorization %}
<a href="{{ user_object.registration.parental_authorization.url }}" data-turbolinks="false">{% trans "Download" %}</a> <a href="{{ user_object.registration.parental_authorization.url }}" data-turbolinks="false">{% trans "Download" %}</a>
{% endif %} {% endif %}
{% if user_object.pk == user.pk %} {% if user_object.registration.team and not user_object.registration.team.participation.valid %}
<button class="btn btn-primary" data-toggle="modal" data-target="#uploadParentalAuthorizationModal">{% trans "Replace" %}</button> <button class="btn btn-primary" data-toggle="modal" data-target="#uploadParentalAuthorizationModal">{% trans "Replace" %}</button>
{% endif %} {% endif %}
</dd> </dd>
@ -125,6 +125,11 @@
{% else %} {% else %}
{{ user_object.registration.payment.get_type_display }}, {% trans "valid:" %} {{ user_object.registration.payment.valid|yesno:yesnodefault }} {{ user_object.registration.payment.get_type_display }}, {% trans "valid:" %} {{ user_object.registration.payment.valid|yesno:yesnodefault }}
{% endif %} {% endif %}
{% if user.registration.is_admin or user_object.registration.payment.valid is False %}
<button class="btn-sm btn-secondary" data-toggle="modal" data-target="#updatePaymentModal">
<i class="fas fa-money-bill-wave"></i> {% trans "Update payment" %}
</button>
{% endif %}
{% endwith %} {% endwith %}
</dd> </dd>
</dl> </dl>
@ -145,6 +150,7 @@
{% url "registration:update_user" pk=user_object.pk as modal_action %} {% url "registration:update_user" pk=user_object.pk as modal_action %}
{% include "base_modal.html" with modal_id="updateUser" %} {% include "base_modal.html" with modal_id="updateUser" %}
{% if user_object.registration.team and not user_object.registration.team.participation.valid %}
{% trans "Upload photo authorization" as modal_title %} {% trans "Upload photo authorization" as modal_title %}
{% trans "Upload" as modal_button %} {% trans "Upload" as modal_button %}
{% url "registration:upload_user_photo_authorization" pk=user_object.registration.pk as modal_action %} {% url "registration:upload_user_photo_authorization" pk=user_object.registration.pk as modal_action %}
@ -159,6 +165,19 @@
{% trans "Upload" as modal_button %} {% trans "Upload" as modal_button %}
{% url "registration:upload_user_parental_authorization" pk=user_object.registration.pk as modal_action %} {% url "registration:upload_user_parental_authorization" pk=user_object.registration.pk as modal_action %}
{% include "base_modal.html" with modal_id="uploadParentalAuthorization" modal_enctype="multipart/form-data" %} {% include "base_modal.html" with modal_id="uploadParentalAuthorization" modal_enctype="multipart/form-data" %}
{% trans "Upload parental authorization" as modal_title %}
{% trans "Upload" as modal_button %}
{% url "registration:upload_user_parental_authorization" pk=user_object.registration.pk as modal_action %}
{% include "base_modal.html" with modal_id="uploadParentalAuthorization" modal_enctype="multipart/form-data" %}
{% endif %}
{% if user_object.registration.team.participation.valid %}
{% trans "Update payment" as modal_title %}
{% trans "Update" as modal_button %}
{% url "registration:update_payment" pk=user_object.registration.payment.pk as modal_action %}
{% include "base_modal.html" with modal_id="updatePayment" modal_additional_class="modal-xl" modal_enctype="multipart/form-data" %}
{% endif %}
{% endblock %} {% endblock %}
{% block extrajavascript %} {% block extrajavascript %}
@ -169,6 +188,7 @@
if (!modalBody.html().trim()) if (!modalBody.html().trim())
modalBody.load("{% url "registration:update_user" pk=user_object.pk %} #form-content"); modalBody.load("{% url "registration:update_user" pk=user_object.pk %} #form-content");
}); });
{% if user_object.registration.team and not user_object.registration.team.participation.valid %}
$('button[data-target="#uploadPhotoAuthorizationModal"]').click(function() { $('button[data-target="#uploadPhotoAuthorizationModal"]').click(function() {
let modalBody = $("#uploadPhotoAuthorizationModal div.modal-body"); let modalBody = $("#uploadPhotoAuthorizationModal div.modal-body");
if (!modalBody.html().trim()) if (!modalBody.html().trim())
@ -184,6 +204,14 @@
if (!modalBody.html().trim()) if (!modalBody.html().trim())
modalBody.load("{% url "registration:upload_user_parental_authorization" pk=user_object.registration.pk %} #form-content"); modalBody.load("{% url "registration:upload_user_parental_authorization" pk=user_object.registration.pk %} #form-content");
}); });
{% endif %}
{% if user_object.registration.team.participation.valid %}
$('button[data-target="#updatePaymentModal"]').click(function() {
let modalBody = $("#updatePaymentModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "registration:update_payment" pk=user_object.registration.payment.pk %} #form-content");
});
{% endif %}
}); });
</script> </script>
{% endblock %} {% endblock %}

View File

@ -3,10 +3,10 @@
from django.urls import path from django.urls import path
from .views import AddOrganizerView, MyAccountDetailView, ResetAdminView, SignupView, UserDetailView,\ from .views import AddOrganizerView, MyAccountDetailView, PaymentUpdateView, ResetAdminView, SignupView, \
UserImpersonateView, UserListView, UserResendValidationEmailView, UserUpdateView, UserUploadHealthSheetView, \ UserDetailView, UserImpersonateView, UserListView, UserResendValidationEmailView, UserUpdateView, \
UserUploadParentalAuthorizationView, UserUploadPhotoAuthorizationView, UserValidateView, \ UserUploadHealthSheetView, UserUploadParentalAuthorizationView, UserUploadPhotoAuthorizationView, \
UserValidationEmailSentView UserValidateView, UserValidationEmailSentView
app_name = "registration" app_name = "registration"
@ -26,6 +26,7 @@ urlpatterns = [
name="upload_user_health_sheet"), name="upload_user_health_sheet"),
path("user/<int:pk>/upload-parental-authorization/", UserUploadParentalAuthorizationView.as_view(), path("user/<int:pk>/upload-parental-authorization/", UserUploadParentalAuthorizationView.as_view(),
name="upload_user_parental_authorization"), name="upload_user_parental_authorization"),
path("update-payment/<int:pk>/", PaymentUpdateView.as_view(), name="update_payment"),
path("user/<int:pk>/impersonate/", UserImpersonateView.as_view(), name="user_impersonate"), path("user/<int:pk>/impersonate/", UserImpersonateView.as_view(), name="user_impersonate"),
path("user/list/", UserListView.as_view(), name="user_list"), path("user/list/", UserListView.as_view(), name="user_list"),
path("reset-admin/", ResetAdminView.as_view(), name="reset_admin"), path("reset-admin/", ResetAdminView.as_view(), name="reset_admin"),

View File

@ -15,8 +15,7 @@ from django.shortcuts import redirect, resolve_url
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.crypto import get_random_string from django.utils.crypto import get_random_string
from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_decode
from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views.generic import CreateView, DetailView, RedirectView, TemplateView, UpdateView, View from django.views.generic import CreateView, DetailView, RedirectView, TemplateView, UpdateView, View
from django_tables2 import SingleTableView from django_tables2 import SingleTableView
@ -26,9 +25,9 @@ from tfjm.tokens import email_validation_token
from tfjm.views import AdminMixin, UserMixin, VolunteerMixin from tfjm.views import AdminMixin, UserMixin, VolunteerMixin
from .forms import AddOrganizerForm, AdminRegistrationForm, CoachRegistrationForm, HealthSheetForm, \ from .forms import AddOrganizerForm, AdminRegistrationForm, CoachRegistrationForm, HealthSheetForm, \
ParentalAuthorizationForm, PhotoAuthorizationForm, SignupForm, StudentRegistrationForm, UserForm, \ ParentalAuthorizationForm, PaymentForm, PhotoAuthorizationForm, SignupForm, StudentRegistrationForm, UserForm, \
VolunteerRegistrationForm VolunteerRegistrationForm
from .models import ParticipantRegistration, Registration, StudentRegistration from .models import ParticipantRegistration, Payment, Registration, StudentRegistration
from .tables import RegistrationTable from .tables import RegistrationTable
@ -381,6 +380,31 @@ class UserUploadParentalAuthorizationView(UserMixin, UpdateView):
return reverse_lazy("registration:user_detail", args=(self.object.user.pk,)) return reverse_lazy("registration:user_detail", args=(self.object.user.pk,))
class PaymentUpdateView(LoginRequiredMixin, UpdateView):
model = Payment
form_class = PaymentForm
def dispatch(self, request, *args, **kwargs):
if not self.request.user.is_authenticated or \
not self.request.user.registration.is_admin \
and (self.request.user != self.get_object().registration.user
or self.get_object().valid is not False):
return self.handle_no_permission()
return super().dispatch(request, *args, **kwargs)
def get_form(self, form_class=None):
form = super().get_form(form_class)
if not self.request.user.registration.is_admin:
del form.fields["type"].widget.choices[-1]
del form.fields["valid"]
return form
def form_valid(self, form):
if not self.request.user.registration.is_admin:
form.instance.valid = None
return super().form_valid(form)
class PhotoAuthorizationView(LoginRequiredMixin, View): class PhotoAuthorizationView(LoginRequiredMixin, View):
""" """
Display the sent photo authorization. Display the sent photo authorization.