From aeeefc92f7f4fe212168ab149b9a8628f3f23eca Mon Sep 17 00:00:00 2001 From: Tom Teichler <tom.teichler@teckids.org> Date: Sun, 6 Mar 2022 21:07:53 +0100 Subject: [PATCH] Implement registration states --- aleksis/apps/paweljong/forms.py | 29 +++++++------ aleksis/apps/paweljong/menus.py | 11 +++++ .../migrations/0015_registrationstate.py | 33 +++++++++++++++ .../0016_eventregistration_states.py | 18 ++++++++ aleksis/apps/paweljong/models.py | 12 ++++++ aleksis/apps/paweljong/tables.py | 29 +++++++++++++ .../paweljong/event_registration/edit.html | 22 ++++++++++ .../paweljong/registration_state/chip.html | 19 +++++++++ .../paweljong/registration_state/create.html | 19 +++++++++ .../paweljong/registration_state/edit.html | 18 ++++++++ .../paweljong/registration_state/list.html | 14 +++++++ aleksis/apps/paweljong/urls.py | 15 +++++++ aleksis/apps/paweljong/views.py | 41 +++++++++++++++++-- 13 files changed, 262 insertions(+), 18 deletions(-) create mode 100644 aleksis/apps/paweljong/migrations/0015_registrationstate.py create mode 100644 aleksis/apps/paweljong/migrations/0016_eventregistration_states.py create mode 100644 aleksis/apps/paweljong/templates/paweljong/event_registration/edit.html create mode 100644 aleksis/apps/paweljong/templates/paweljong/registration_state/chip.html create mode 100644 aleksis/apps/paweljong/templates/paweljong/registration_state/create.html create mode 100644 aleksis/apps/paweljong/templates/paweljong/registration_state/edit.html create mode 100644 aleksis/apps/paweljong/templates/paweljong/registration_state/list.html diff --git a/aleksis/apps/paweljong/forms.py b/aleksis/apps/paweljong/forms.py index 8a51d71..d710f90 100644 --- a/aleksis/apps/paweljong/forms.py +++ b/aleksis/apps/paweljong/forms.py @@ -11,7 +11,7 @@ from phonenumber_field.formfields import PhoneNumberField from aleksis.core.mixins import ExtensibleForm from aleksis.core.models import Group, Person -from .models import Event, EventRegistration, InfoMailing, Terms, Voucher +from .models import Event, EventRegistration, InfoMailing, Terms, Voucher, RegistrationState COMMENT_CHOICES = [ ("first", _("Only first name")), @@ -404,20 +404,13 @@ class RegisterEventConsent(ExtensibleForm): class EditEventRegistrationForm(forms.ModelForm): layout = Layout( - Fieldset( - _("General event information"), - Row("event", "person"), - Row("comment"), - ), - Fieldset( - _("Financial data"), - "voucher_code", - Row("iban", "donation", "accept_sepa"), - ), - Fieldset( - _("Declaration of consent"), - Row("accept_terms", "accept_data", "accept_general_terms"), - ), + Row("event", "person"), + Row("comment", "medical_information"), + "voucher", + Row("iban", "donation", "accept_sepa"), + "accepted_terms", + Row("school", "school_class", "school_place"), + "states", ) class Meta: @@ -490,3 +483,9 @@ class RegistrationNotificationForm(forms.ModelForm): class Meta: model = InfoMailing exclude = ["sent_to", "active"] + + +class RegistrationStatesForm(forms.ModelForm): + class Meta: + model = RegistrationState + exclude = [] diff --git a/aleksis/apps/paweljong/menus.py b/aleksis/apps/paweljong/menus.py index afe3056..149cd54 100644 --- a/aleksis/apps/paweljong/menus.py +++ b/aleksis/apps/paweljong/menus.py @@ -44,6 +44,17 @@ MENUS = { ) ], }, + { + "name": _("Registration states"), + "url": "registration_states", + "icon": "list", + "validators": [ + ( + "aleksis.core.util.predicates.permission_validator", + "paweljong.view_registration_states_rule", + ) + ], + }, { "name": _("Info mailings"), "url": "info_mailings", diff --git a/aleksis/apps/paweljong/migrations/0015_registrationstate.py b/aleksis/apps/paweljong/migrations/0015_registrationstate.py new file mode 100644 index 0000000..6375c85 --- /dev/null +++ b/aleksis/apps/paweljong/migrations/0015_registrationstate.py @@ -0,0 +1,33 @@ +# Generated by Django 3.2.12 on 2022-03-06 20:09 + +import colorfield.fields +import django.contrib.sites.managers +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('sites', '0002_alter_domain_unique'), + ('paweljong', '0014_move_sent_to_to_through'), + ] + + operations = [ + migrations.CreateModel( + name='RegistrationState', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('extended_data', models.JSONField(default=dict, editable=False)), + ('name', models.CharField(max_length=255, verbose_name='Name of State')), + ('colour', colorfield.fields.ColorField(blank=True, default='', image_field=None, max_length=18, samples=None, verbose_name='Colour')), + ('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.site')), + ], + options={ + 'abstract': False, + }, + managers=[ + ('objects', django.contrib.sites.managers.CurrentSiteManager()), + ], + ), + ] diff --git a/aleksis/apps/paweljong/migrations/0016_eventregistration_states.py b/aleksis/apps/paweljong/migrations/0016_eventregistration_states.py new file mode 100644 index 0000000..28e9964 --- /dev/null +++ b/aleksis/apps/paweljong/migrations/0016_eventregistration_states.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.12 on 2022-03-06 20:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('paweljong', '0015_registrationstate'), + ] + + operations = [ + migrations.AddField( + model_name='eventregistration', + name='states', + field=models.ManyToManyField(related_name='registrations', to='paweljong.RegistrationState', verbose_name='States'), + ), + ] diff --git a/aleksis/apps/paweljong/models.py b/aleksis/apps/paweljong/models.py index 976b744..251dace 100644 --- a/aleksis/apps/paweljong/models.py +++ b/aleksis/apps/paweljong/models.py @@ -8,6 +8,7 @@ from django.utils.translation import gettext_lazy as _ from ckeditor.fields import RichTextField from django_iban.fields import IBANField +from colorfield.fields import ColorField from aleksis.core.mixins import ExtensibleModel from aleksis.core.models import Group, Person @@ -15,6 +16,15 @@ from aleksis.core.util.core_helpers import generate_random_code, get_site_prefer from aleksis.core.util.email import send_email +class RegistrationState(ExtensibleModel): + + name = models.CharField(verbose_name=_("Name of State"), max_length=255) + colour = ColorField(blank=True, verbose_name=_("Colour")) + + def __str__(self) -> str: + return self.name + + class Terms(ExtensibleModel): title = models.CharField(max_length=255, verbose_name=_("Title")) term = RichTextField(verbose_name=_("Term")) @@ -261,6 +271,8 @@ class EventRegistration(ExtensibleModel): blank=True, ) + states = models.ManyToManyField(RegistrationState, verbose_name=_("States"), related_name="registrations") + def __str__(self) -> str: return f"{self.event}, {self.person.first_name} {self.person.last_name}" diff --git a/aleksis/apps/paweljong/tables.py b/aleksis/apps/paweljong/tables.py index 2e7ac69..8795e17 100644 --- a/aleksis/apps/paweljong/tables.py +++ b/aleksis/apps/paweljong/tables.py @@ -1,3 +1,4 @@ +from django.template.loader import render_to_string from django.utils.translation import ugettext_lazy as _ import django_tables2 as tables @@ -56,13 +57,23 @@ class EventRegistrationsTable(tables.Table): person = tables.Column() event = tables.Column() date_registered = tables.Column() + states = tables.Column() view = tables.LinkColumn( "registration_by_pk", args=[A("id")], verbose_name=_("View registration"), text=_("View"), ) + edit = tables.LinkColumn( + "edit_registration_by_pk", + args=[A("pk")], + verbose_name=_("Edit"), + text=_("Edit"), + ) + def render_states(self, value, record): + context = dict(states=value.all()) + return render_to_string("paweljong/registration_state/chip.html", context) class TermsTable(tables.Table): class Meta: @@ -96,3 +107,21 @@ class InfoMailingsTable(tables.Table): verbose_name=_("Delete"), text=_("Delete"), ) + + +class RegistrationStatesTable(tables.Table): + class Meta: + attrs = {"class": "responsive-table highlight"} + + name = tables.Column() + + edit = tables.LinkColumn( + "edit_registration_state_by_pk", + args=[A("id")], + verbose_name=_("Edit"), + text=_("Edit"), + ) + + def render_name(self, value, record): + context = dict(state=record) + return render_to_string("paweljong/registration_state/chip.html", context) diff --git a/aleksis/apps/paweljong/templates/paweljong/event_registration/edit.html b/aleksis/apps/paweljong/templates/paweljong/event_registration/edit.html new file mode 100644 index 0000000..4238fe2 --- /dev/null +++ b/aleksis/apps/paweljong/templates/paweljong/event_registration/edit.html @@ -0,0 +1,22 @@ +{% extends "core/base.html" %} +{% load material_form i18n any_js %} + +{% block page_title %}{% blocktrans %}Edit registration{% endblocktrans %}{% endblock %} +{% block browser_title %}{% blocktrans %}Edit registration{% endblocktrans %}{% endblock %} + +{% block extra_head %} + {{ form.media.css }} + {% include_css "select2-materialize" %} +{% endblock %} + +{% block content %} + + <form method="post"> + {% csrf_token %} + {% form form=form %}{% form %} + {% include "core/partials/save_button.html" %} + </form> + {% include_js "select2-materialize" %} + {{ form.media.js }} + +{% endblock %} diff --git a/aleksis/apps/paweljong/templates/paweljong/registration_state/chip.html b/aleksis/apps/paweljong/templates/paweljong/registration_state/chip.html new file mode 100644 index 0000000..91aa0ef --- /dev/null +++ b/aleksis/apps/paweljong/templates/paweljong/registration_state/chip.html @@ -0,0 +1,19 @@ +{# -*- engine:django -*- #} + +{% if states %} + {% for state in states %} + <div class="chip white-text" style="background-color: {{ state.colour|default:"black" }};"> + {{ state }} + {% if small %} + <small>({{ small }})</small> + {% endif %} + </div> + {% endfor %} +{% else %} + <div class="chip white-text" style="background-color: {{ state.colour|default:"black" }};"> + {{ state.name }} + {% if small %} + <small>({{ small }})</small> + {% endif %} + </div> +{% endif %} diff --git a/aleksis/apps/paweljong/templates/paweljong/registration_state/create.html b/aleksis/apps/paweljong/templates/paweljong/registration_state/create.html new file mode 100644 index 0000000..d8215a9 --- /dev/null +++ b/aleksis/apps/paweljong/templates/paweljong/registration_state/create.html @@ -0,0 +1,19 @@ +{% extends "core/base.html" %} +{% load material_form i18n %} + +{% block page_title %}{% blocktrans %}Create registration state{% endblocktrans %}{% endblock %} +{% block browser_title %}{% blocktrans %}Create registration state{% endblocktrans %}{% endblock %} + +{% block extra_head %} + {{ form.media.css }} +{% endblock %} + +{% block content %} + <form method="post"> + {% csrf_token %} + {% form form=form %}{% endform %} + {% include "core/partials/save_button.html" %} + </form> + + {{ form.media.js }} +{% endblock %} diff --git a/aleksis/apps/paweljong/templates/paweljong/registration_state/edit.html b/aleksis/apps/paweljong/templates/paweljong/registration_state/edit.html new file mode 100644 index 0000000..da8ec67 --- /dev/null +++ b/aleksis/apps/paweljong/templates/paweljong/registration_state/edit.html @@ -0,0 +1,18 @@ +{% extends "core/base.html" %} +{% load material_form i18n %} + +{% block page_title %}{% blocktrans %}Edit registration state{% endblocktrans %}{% endblock %} +{% block browser_title %}{% blocktrans %}Edit registration state{% endblocktrans %}{% endblock %} + +{% block extra_head %} + {{ form.media.css }} +{% endblock %} + +{% block content %} + <form method="post"> + {% csrf_token %} + {% form form=form %}{% endform %} + {% include "core/partials/save_button.html" %} + </form> + {{ form.media.js }} +{% endblock %} diff --git a/aleksis/apps/paweljong/templates/paweljong/registration_state/list.html b/aleksis/apps/paweljong/templates/paweljong/registration_state/list.html new file mode 100644 index 0000000..4077190 --- /dev/null +++ b/aleksis/apps/paweljong/templates/paweljong/registration_state/list.html @@ -0,0 +1,14 @@ +{% extends "core/base.html" %} +{% load material_form i18n %} + +{% load render_table from django_tables2 %} + +{% block page_title %}{% blocktrans %}Registration states{% endblocktrans %}{% endblock %} +{% block browser_title %}{% blocktrans %}Registration states{% endblocktrans %}{% endblock %} + +{% block content %} + + <a class="btn colour-primary waves-effect waves-light" href="{% url 'create_registration_state' %}">{% trans "Create registration state" %}</a> + {% render_table table %} + +{% endblock %} diff --git a/aleksis/apps/paweljong/urls.py b/aleksis/apps/paweljong/urls.py index d2a43fd..5568600 100644 --- a/aleksis/apps/paweljong/urls.py +++ b/aleksis/apps/paweljong/urls.py @@ -107,6 +107,21 @@ urlpatterns = [ views.TermEditView.as_view(), name="edit_term_by_pk", ), + path( + "event/registrations/states/list", + views.RegistrationStateListView.as_view(), + name="registration_states", + ), + path( + "event/registrations/states/create", + views.RegistrationStateCreateView.as_view(), + name="create_registration_state", + ), + path( + "event/registrations/states/<int:pk>/edit", + views.RegistrationStateEditView.as_view(), + name="edit_registration_state_by_pk", + ), path( "info_mailings/list", views.InfoMailingListView.as_view(), diff --git a/aleksis/apps/paweljong/views.py b/aleksis/apps/paweljong/views.py index 9786d31..a5251d9 100644 --- a/aleksis/apps/paweljong/views.py +++ b/aleksis/apps/paweljong/views.py @@ -37,14 +37,16 @@ from .forms import ( EditVoucherForm, GenerateListForm, RegistrationNotificationForm, + RegistrationStatesForm, ) -from .models import Event, EventRegistration, InfoMailing, Terms, Voucher +from .models import Event, EventRegistration, InfoMailing, Terms, Voucher, RegistrationState from .tables import ( EventRegistrationsTable, InfoMailingsTable, ManageEventsTable, TermsTable, VouchersTable, + RegistrationStatesTable, ) User = get_user_model() @@ -160,7 +162,7 @@ class EventRegistrationCreateView(PermissionRequiredMixin, AdvancedCreateView): form_class = EditEventRegistrationForm permission_required = "paweljong.manage_registration" template_name = "paweljong/event_registration/create.html" - success_url = reverse_lazy("event_registrations") + success_url = reverse_lazy("registrations") success_message = _("The event registration has been created.") @@ -172,7 +174,7 @@ class EventRegistrationEditView(PermissionRequiredMixin, AdvancedEditView): form_class = EditEventRegistrationForm permission_required = "paweljong.manage_eventregistration" template_name = "paweljong/event_registration/edit.html" - success_url = reverse_lazy("event_registrations") + success_url = reverse_lazy("registrations") success_message = _("The event registration has been saved.") @@ -860,3 +862,36 @@ class SendMailFromRegistration(PermissionRequiredMixin, FormView): ) return super().form_valid(self) + + +class RegistrationStateListView(PermissionRequiredMixin, SingleTableView): + """Table of all terms.""" + + model = RegistrationState + table_class = RegistrationStatesTable + permission_required = "paweljong.view_registration_states" + template_name = "paweljong/registration_state/list.html" + + +@method_decorator(never_cache, name="dispatch") +class RegistrationStateCreateView(PermissionRequiredMixin, AdvancedCreateView): + """Create view for terms.""" + + model = RegistrationState + form_class = RegistrationStatesForm + permission_required = "paweljong.add_registration_states" + template_name = "paweljong/registration_state/create.html" + success_url = reverse_lazy("registration_states") + success_message = _("The term has been created.") + + +@method_decorator(never_cache, name="dispatch") +class RegistrationStateEditView(PermissionRequiredMixin, AdvancedEditView): + """Edit view for terms.""" + + model = RegistrationState + form_class = RegistrationStatesForm + permission_required = "paweljong.edit_registration_states" + template_name = "paweljong/registration_state/edit.html" + success_url = reverse_lazy("registration_states") + success_message = _("The term has been saved.") -- GitLab