Verified Commit 49ff02ed authored by Sébastiaan Versteeg's avatar Sébastiaan Versteeg
Browse files

Add documentation for the registrations module

parent cc428fbf
"""Registers admin interfaces for the registrations module"""
from django.contrib import admin, messages
from django.contrib.admin.utils import model_ngettext
from django.utils.html import format_html
......@@ -8,6 +9,7 @@ from .models import Entry, Registration, Renewal
def _show_message(admin, request, n, message, error):
"""Show a message in the Django Admin"""
if n == 0:
admin.message_user(request, error, messages.ERROR)
else:
......@@ -19,6 +21,8 @@ def _show_message(admin, request, n, message, error):
@admin.register(Registration)
class RegistrationAdmin(admin.ModelAdmin):
"""Manage the registrations"""
list_display = ('name', 'email', 'status',
'created_at', 'payment_status')
list_filter = ('status', 'programme', 'payment__processed',
......@@ -59,6 +63,10 @@ class RegistrationAdmin(admin.ModelAdmin):
def changeform_view(self, request, object_id=None, form_url='',
extra_context=None):
"""
Renders the change formview
Only allow when the entry has not been processed yet
"""
obj = None
if (object_id is not None and
request.user.has_perm('registrations.review_entries')):
......@@ -69,6 +77,10 @@ class RegistrationAdmin(admin.ModelAdmin):
request, object_id, form_url, {'entry': obj})
def get_actions(self, request):
"""
Get the actions for the entries
Hide the reviewing actions if the right permissions are missing
"""
actions = super().get_actions(request)
if not request.user.has_perm('registrations.review_entries'):
del(actions['accept_selected'])
......@@ -99,6 +111,7 @@ class RegistrationAdmin(admin.ModelAdmin):
return '-'
def reject_selected(self, request, queryset):
"""Reject the selected entries"""
if request.user.has_perm('registrations.review_entries'):
rows_updated = services.reject_entries(queryset)
_show_message(
......@@ -109,6 +122,7 @@ class RegistrationAdmin(admin.ModelAdmin):
reject_selected.short_description = _('Reject selected registrations')
def accept_selected(self, request, queryset):
"""Accept the selected entries"""
if request.user.has_perm('registrations.review_entries'):
rows_updated = services.accept_entries(queryset)
_show_message(
......@@ -121,6 +135,8 @@ class RegistrationAdmin(admin.ModelAdmin):
@admin.register(Renewal)
class RenewalAdmin(RegistrationAdmin):
"""Manage the renewals"""
list_display = ('name', 'email', 'status',
'created_at', 'payment_status',)
list_filter = ('status', 'payment__processed', 'payment__amount')
......@@ -142,6 +158,7 @@ class RenewalAdmin(RegistrationAdmin):
)
def get_readonly_fields(self, request, obj=None):
"""Make all fields read-only and add member if needed"""
fields = super().get_readonly_fields(request, obj)
if 'member' not in fields and obj is not None:
return fields + ['member']
......
"""Configuration for the newsletters package"""
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _
class RegistrationsConfig(AppConfig):
"""AppConfig for the registrations package"""
name = 'registrations'
verbose_name = _('Registrations')
def ready(self):
"""Imports the signals when the app is ready"""
from . import signals # noqa: F401
"""The emails defined by the registrations package"""
from django.core import mail
from django.template import loader
from django.template.defaultfilters import floatformat
......@@ -10,6 +11,10 @@ from . import models
def send_registration_email_confirmation(registration):
"""
Send the email confirmation message
:param registration: the registration entry
"""
with translation.override(registration.language):
_send_email(
registration.email,
......@@ -27,6 +32,11 @@ def send_registration_email_confirmation(registration):
def send_registration_accepted_message(registration, payment):
"""
Send the registration acceptance email
:param registration: the registration entry
:param payment: the payment entry
"""
with translation.override(registration.language):
_send_email(
registration.email,
......@@ -40,6 +50,10 @@ def send_registration_accepted_message(registration, payment):
def send_registration_rejected_message(registration):
"""
Send the registration rejection email
:param registration: the registration entry
"""
with translation.override(registration.language):
_send_email(
registration.email,
......@@ -52,6 +66,10 @@ def send_registration_rejected_message(registration):
def send_new_registration_board_message(entry):
"""
Send a notification to the board about a new registration
:param entry: the registration entry
"""
try:
_send_email(
settings.BOARD_NOTIFICATION_ADDRESS,
......@@ -68,6 +86,11 @@ def send_new_registration_board_message(entry):
def send_renewal_accepted_message(renewal, payment):
"""
Send the renewal acceptation email
:param renewal: the renewal entry
:param payment: the payment entry
"""
with translation.override(renewal.member.profile.language):
_send_email(
renewal.member.email,
......@@ -81,6 +104,10 @@ def send_renewal_accepted_message(renewal, payment):
def send_renewal_rejected_message(renewal):
"""
Send the renewal rejection email
:param renewal: the renewal entry
"""
with translation.override(renewal.member.profile.language):
_send_email(
renewal.member.email,
......@@ -93,6 +120,10 @@ def send_renewal_rejected_message(renewal):
def send_renewal_complete_message(renewal):
"""
Send the email completing the renewal
:param renewal: the renewal entry
"""
with translation.override(renewal.member.profile.language):
_send_email(
renewal.member.email,
......@@ -105,6 +136,10 @@ def send_renewal_complete_message(renewal):
def send_new_renewal_board_message(renewal):
"""
Send a notification to the board about a new renewal
:param renewal: the renewal entry
"""
_send_email(
settings.BOARD_NOTIFICATION_ADDRESS,
'New renewal',
......@@ -118,6 +153,13 @@ def send_new_renewal_board_message(renewal):
def _send_email(to, subject, body_template, context):
"""
Easily send an email with the right subject and a body template
:param to: where should the email go?
:param subject: what is the email about?
:param body_template: what is the content of the email?
:param context: add some context to the body
"""
mail.EmailMessage(
'[THALIA] {}'.format(subject),
loader.render_to_string(body_template, context),
......
"""The forms defined by the registrations package"""
from django import forms
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
......@@ -6,6 +7,7 @@ from .models import Registration, Renewal
class MemberRegistrationForm(forms.ModelForm):
"""Form for membership registrations"""
birthday = forms.DateField(
widget=forms.widgets.SelectDateWidget(years=[
year for year in range(timezone.now().year - 50,
......@@ -25,6 +27,7 @@ class MemberRegistrationForm(forms.ModelForm):
class MemberRenewalForm(forms.ModelForm):
"""Form for membership renewals"""
class Meta:
model = Renewal
fields = '__all__'
......
"""The models defined by the registrations package"""
import uuid
from django.contrib.auth import get_user_model
......@@ -13,6 +14,7 @@ from . import emails
class Entry(models.Model):
"""Describes a registration entry"""
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
created_at = models.DateTimeField(_('created at'), default=timezone.now)
......@@ -112,6 +114,7 @@ class Entry(models.Model):
class Registration(Entry):
"""Describes a new registration for the association"""
# ---- Personal information -----
username = models.CharField(
......@@ -280,6 +283,7 @@ class Registration(Entry):
class Renewal(Entry):
"""Describes a renewal for the association membership"""
member = models.ForeignKey(
'members.Member',
on_delete=models.CASCADE,
......
"""The services defined by the registrations package"""
import string
import unicodedata
from datetime import timedelta
......
"""The signals checked by the registrations package"""
from django.db.models.signals import post_save
from django.dispatch import receiver
......@@ -7,4 +8,5 @@ from registrations import services
@receiver(post_save, sender='payments.Payment',
dispatch_uid='registrations_payment_process')
def post_payment_save(sender, instance, **kwargs):
"""Process a payment when it is saved"""
services.process_payment(instance)
"""The routes defined by the registrations package"""
from django.urls import path
from django.views.generic import TemplateView
......
"""Views provided by the registrations package"""
from django.contrib import messages
from django.contrib.admin.utils import model_ngettext
from django.contrib.admin.views.decorators import staff_member_required
......@@ -21,6 +22,7 @@ from .models import Entry, Registration, Renewal
class BecomeAMemberView(TemplateView):
"""View that render a HTML template with context data"""
template_name = 'registrations/become_a_member.html'
def get_context_data(self, **kwargs):
......@@ -37,6 +39,9 @@ class BecomeAMemberView(TemplateView):
@method_decorator(permission_required('registrations.review_entries'),
name='dispatch', )
class EntryAdminView(View):
"""
View that handles the review processing of entries
"""
action = None
def get(self, request, *args, **kwargs):
......@@ -76,6 +81,10 @@ class EntryAdminView(View):
class ConfirmEmailView(View, TemplateResponseMixin):
"""
View that renders an HTML template and confirms the email address
of the provided registration
"""
template_name = 'registrations/confirm_email.html'
def get(self, request, *args, **kwargs):
......@@ -99,6 +108,9 @@ class ConfirmEmailView(View, TemplateResponseMixin):
class MemberRegistrationFormView(FormView):
"""
View that renders the membership registration form
"""
form_class = forms.MemberRegistrationForm
template_name = 'registrations/register_member.html'
......@@ -129,6 +141,9 @@ class MemberRegistrationFormView(FormView):
@method_decorator(login_required, name='dispatch')
class RenewalFormView(FormView):
"""
View that renders the membership renewal form
"""
form_class = forms.MemberRenewalForm
template_name = 'registrations/renewal.html'
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment