from typing import Optional from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.syndication.views import Feed from django.core.exceptions import ValidationError from django.http import HttpRequest, HttpResponse from django.shortcuts import redirect, render from django.urls import reverse, reverse_lazy from django.utils import timezone from django.utils.decorators import method_decorator from django.utils.text import slugify from django.utils.translation import gettext as _ from django.views.decorators.cache import never_cache from django.views.generic import FormView, TemplateView, View from django.views.generic.detail import DetailView import reversion from django_tables2 import RequestConfig from django_tables2.views import SingleTableView from formtools.wizard.views import SessionWizardView from reversion.views import RevisionMixin from rules.contrib.views import PermissionRequiredMixin, permission_required from templated_email import send_templated_mail from aleksis.apps.postbuero.models import MailAddress from aleksis.core.mixins import AdvancedCreateView, AdvancedDeleteView, AdvancedEditView from aleksis.core.models import Activity, Group, Person from aleksis.core.util import messages from aleksis.core.util.core_helpers import get_site_preferences, objectgetter_optional from .filters import EventFilter, EventRegistrationFilter, VoucherFilter from .forms import ( EditEventForm, EditEventRegistrationForm, EditInfoMailingForm, EditTermForm, EditVoucherForm, GenerateListForm, PersonGroupFormPerson, RegistrationNotificationForm, RegistrationStatesForm, ) from .models import ( Event, EventRegistration, InfoMailing, RegistrationState, Terms, Voucher, ) from .tables import ( ChildGroupsTable, EventAdditionalFieldsTable, EventRegistrationsTable, InfoMailingsTable, ManageEventsTable, RegistrationStatesTable, TermsTable, VouchersTable, ) User = get_user_model() @method_decorator(never_cache, name="dispatch") class CreateEventView(PermissionRequiredMixin, AdvancedCreateView): form_class = EditEventForm model = Event permission_required = "paweljong.create_events_rule" template_name = "paweljong/event/create.html" success_url = reverse_lazy("manage_events") success_message = _("The event has been saved.") @method_decorator(never_cache, name="dispatch") class EditEventView(PermissionRequiredMixin, RevisionMixin, AdvancedEditView): form_class = EditEventForm model = Event slug_field = "slug" permission_required = "paweljong.change_event_rule" context_object_name = "manage_events" template_name = "paweljong/event/edit.html" success_url = reverse_lazy("manage_events") success_message = _("The event has been saved.") @permission_required("paweljong.view_events_rule") def manage_events(request: HttpRequest) -> HttpResponse: """List view listing all registrations.""" context = {} # Get all registrations now = timezone.datetime.today() events = Event.objects.all() # Get filter events_filter = EventFilter(request.GET, queryset=events) context["events_filter"] = events_filter # Build table events_table = ManageEventsTable(events_filter.qs) RequestConfig(request).configure(events_table) context["events_table"] = events_table return render(request, "paweljong/event/manage.html", context) @permission_required("paweljong.view_vouchers_rule") def vouchers(request): context = {} # Get all unused vouchers vouchers = Voucher.objects.filter(used=False, deleted=False) # Get filter vouchers_filter = VoucherFilter(request.GET, queryset=vouchers) context["vouchers_filter"] = vouchers_filter # Build table vouchers_table = VouchersTable(vouchers_filter.qs) RequestConfig(request).configure(vouchers_table) context["vouchers_table"] = vouchers_table return render(request, "paweljong/voucher/list.html", context) @permission_required("paweljong.generate_lists_rule") def generate_lists(request: HttpRequest) -> HttpResponse: context = {} generate_list_form = GenerateListForm() if request.method == "POST": generate_list_form = GenerateListForm(request.POST) if generate_list_form.is_valid(): context["group"] = generate_list_form.cleaned_data["group"] template = generate_list_form.cleaned_data["template"] context["landscape"] = generate_list_form.cleaned_data["landscape"] return render(request, "paweljong/print/%s.html" % (template), context) context["generate_list_form"] = generate_list_form return render(request, "paweljong/print/manage.html", context) @method_decorator(never_cache, name="dispatch") class EventRegistrationCreateView(PermissionRequiredMixin, AdvancedCreateView): """Create view for event registrations.""" model = EventRegistration form_class = EditEventRegistrationForm permission_required = "paweljong.create_registration_rule" template_name = "paweljong/event_registration/create.html" success_url = reverse_lazy("manage_events") success_message = _("The event registration has been created.") @method_decorator(never_cache, name="dispatch") class EventRegistrationEditView(PermissionRequiredMixin, AdvancedEditView): """Edit view for event registrations.""" model = EventRegistration form_class = EditEventRegistrationForm permission_required = "paweljong.change_registration_rule" template_name = "paweljong/event_registration/edit.html" success_url = reverse_lazy("manage_events") success_message = _("The event registration has been saved.") @permission_required( "paweljong.change_registration_rule", fn=objectgetter_optional(EventRegistration, None, False), ) def edit_registration(request: HttpRequest, pk) -> HttpResponse: context = {} registration = objectgetter_optional(EventRegistration, None, False)(request, pk) edit_event_registration_form = EditEventRegistrationForm( request.POST or None, instance=registration ) if request.method == "POST": if edit_event_registration_form.is_valid(): with reversion.create_revision(): edit_event_registration_form.save(commit=True) messages.success(request, _("The registration has been saved.")) return redirect("registration") context["edit_event_registration_form"] = edit_event_registration_form return render(request, "paweljong/event_registration/edit.html", context) @permission_required("paweljong.view_voucher_rule", fn=objectgetter_optional(Voucher, None, False)) def print_voucher(request: HttpRequest, pk) -> HttpResponse: context = {} voucher = Voucher.objects.get(id=pk) context["voucher"] = voucher return render(request, "paweljong/print/voucher.html", context) class EventRegistrationDetailView(PermissionRequiredMixin, DetailView): """Detail view for an application instance.""" context_object_name = "registration" permission_required = "paweljong.view_registration_rule" template_name = "paweljong/event_registration/full.html" def get_queryset(self): return EventRegistration.objects.all() def get_context_data(self, *args, **kwargs): context = super().get_context_data(*args, **kwargs) invoice = self.get_object().get_invoice() context["invoice"] = invoice return context class EventRegistrationDeleteView(PermissionRequiredMixin, AdvancedDeleteView): """Delete view for registrations.""" model = EventRegistration permission_required = "paweljong.delete_eventregistration_rule" template_name = "core/pages/delete.html" success_url = reverse_lazy("manage_events") success_message = _("The registration has been deleted.") @method_decorator(never_cache, name="dispatch") class VoucherCreateView(PermissionRequiredMixin, AdvancedCreateView): """Create view for vouchers.""" model = Voucher form_class = EditVoucherForm permission_required = "paweljong.create_voucher_rule" template_name = "paweljong/voucher/create.html" success_url = reverse_lazy("vouchers") success_message = _("The voucher has been created.") @method_decorator(never_cache, name="dispatch") class VoucherEditView(PermissionRequiredMixin, AdvancedEditView): """Edit view for vouchers.""" model = Voucher form_class = EditVoucherForm permission_required = "paweljong.change_voucher_rule" template_name = "paweljong/voucher/edit.html" success_url = reverse_lazy("vouchers") success_message = _("The voucher has been saved.") class VoucherDeleteView(PermissionRequiredMixin, AdvancedDeleteView): """Delete view for vouchers.""" model = Voucher permission_required = "paweljong.delete_voucher_rule" template_name = "core/pages/delete.html" success_url = reverse_lazy("vouchers") success_message = _("The voucher has been deleted.") def is_person_anonymous(wizard): return wizard.request.user.is_anonymous def set_email_needed(request, slug: Optional[str] = None): request.session["email_needed"] = True if slug: return redirect("register_event_by_slug", slug) else: return redirect("register_account") def is_email_needed(wizard): return wizard.request.session.pop("email_needed", None) TEMPLATES = { "email": "paweljong/event/register_wizard.html", "register": "paweljong/event/register_wizard.html", "contact_details": "paweljong/event/register_wizard.html", "guardians": "paweljong/event/register_wizard.html", "additional": "paweljong/event/register_wizard.html", "financial": "paweljong/event/register_wizard.html", "consent": "paweljong/event/register_wizard_consent.html", } class AccountRegisterWizardView(SessionWizardView): template_name = "paweljong/account_wizard.html" file_storage = settings.DEFAULT_FILE_STORAGE def get_form_kwargs(self, step): kwargs = super().get_form_kwargs() if step == "email": kwargs["request"] = self.request return kwargs def get_form_initial(self, step): initial = self.initial_dict.get(step, {}) if step == "register": cleaned_data_email = self.get_cleaned_data_for_step("email") if cleaned_data_email: domain = cleaned_data_email["domain"] email = f"{cleaned_data_email['local_part']}@{domain.domain}" initial.update( { "email": email, "email2": email, } ) if step == "contact_details": cleaned_data_register = self.get_cleaned_data_for_step("register") if cleaned_data_register: initial.update( { "first_name": cleaned_data_register["first_name"], "last_name": cleaned_data_register["last_name"], "email": cleaned_data_register["email"], "date_of_birth": cleaned_data_register["date_of_birth"], } ) return self.initial_dict.get(step, initial) def done(self, form_list, **kwargs): context = {} cleaned_data_email = self.get_cleaned_data_for_step("email") cleaned_data_register = self.get_cleaned_data_for_step("register") # Create email address _email = None if cleaned_data_email: _email = MailAddress.objects.create( local_part=cleaned_data_email["local_part"], domain=cleaned_data_email["domain"], ) # Create user if cleaned_data_register: user = User.objects.create( username=cleaned_data_register["username"], email=cleaned_data_register["email"], ) user.set_password(cleaned_data_register["password1"]) user.save() else: user = self.request.user person, created = Person.objects.get_or_create( user=user, defaults={ "email": cleaned_data_register["email"], "first_name": cleaned_data_register["first_name"], "last_name": cleaned_data_register["last_name"], "date_of_birth": cleaned_data_register["date_of_birth"], }, ) context["person"] = person send_templated_mail( template_name="account_registered", from_email=get_site_preferences()["mail__address"], recipient_list=["root@teckids.org"], headers={ "reply_to": [ person.email, ], "X-Zammad-Customer-Email": person.email, }, context=context, ) if _email: _email.person = person _email.save() return redirect("index") class RegisterEventWizardView(SessionWizardView): template_name = "paweljong/event/register_wizard.html" file_storage = settings.DEFAULT_FILE_STORAGE def get_template_names(self): return [TEMPLATES[self.steps.current]] def get_context_data(self, form, **kwargs): context = super().get_context_data(form, **kwargs) context["event"] = Event.objects.get(slug=self.kwargs["slug"]) if self.steps.current == "email": context["info_title"] = _("Create e-mail address") context["info_text"] = _( "All participants need a personal e-mail address, which they check and read " "temselves. We offer the possibility to register an e-mail address " "on our secure servers, made for young users. For information about receiving " "mails, see: " "<a href='https://leopard.institute/pages/services.html'>https://leopard.institute/pages/services.html</a>." # noqa ) elif self.steps.current == "register": context["info_title"] = _("Event registration") context["info_text"] = _( "First, please enter some basic information about yourself, and check " "whether all information is correct." ) elif self.steps.current == "contact_details": context["info_title"] = _("Contact information") context["info_text"] = _( "Tell us how we can contact you. You will receive information about " "the event by e-mail. Please use your personal e-mail address " "where you will read mails yourself, not an address of your parents. " "We will always send all important information to your parents as well, " "and you will enter their e-mail address on the next page." ) elif self.steps.current == "guardians": context["info_title"] = _("Legal guardians / parents") context["info_text"] = _( "Tell us how we can reach your parents or other legal guardians. " "This should be the person who was present when you registered for the " "event (which is now). If you want to add another parent, please tell us " "later as a comment." ) elif self.steps.current == "additional": context["info_title"] = _("Additional registration information") context["info_text"] = _( "Please answer the following questions as precisely as you can, so " "we can make sure your event attendance will be organised as wel las possible." ) elif self.steps.current == "financial": context["info_title"] = _("Payment") context["info_text"] = _( "Please decide with your parents how you want to pay. In this step, " "you only select a payment method. The real payment will be done " "in a separate step, after the registration is complete." ) elif self.steps.current == "consent": context["info_title"] = _("Consent") context["info_text"] = _( "Lastly, please read the terms and conditions carefully, together " "with your parents. After that, you will need to confirm that you " "agree with everything yourself, and that your parents also agree." ) return context def get_form_kwargs(self, step): kwargs = super().get_form_kwargs() if step == "email": kwargs["request"] = self.request if step == "additional": event = Event.objects.get(slug=self.kwargs["slug"]) kwargs["event"] = event if step == "consent": event = Event.objects.get(slug=self.kwargs["slug"]) kwargs["event"] = event return kwargs def get_form_initial(self, step): initial = self.initial_dict.get(step, {}) if step == "register": cleaned_data_email = self.get_cleaned_data_for_step("email") if cleaned_data_email: domain = cleaned_data_email["domain"] email = f"{cleaned_data_email['local_part']}@{domain.domain}" initial.update( { "email": email, "email2": email, } ) if step == "guardians": if hasattr(self.request.user, "person"): person = self.request.user.person if person.guardians.first(): initial.update( { "guardian_first_name": person.guardians.first().first_name, "guardian_last_name": person.guardians.first().last_name, "guardian_mobile_number": person.guardians.first().mobile_number, "guardian_email": person.guardians.first().email, } ) if step == "contact_details": if hasattr(self.request.user, "person"): person = self.request.user.person initial.update( { "first_name": person.first_name, "last_name": person.last_name, "mobile_number": person.mobile_number, "email": person.email, "street": person.street, "place": person.place, "housenumber": person.housenumber, "sex": person.sex, "date_of_birth": person.date_of_birth, "postal_code": person.postal_code, } ) else: cleaned_data_register = self.get_cleaned_data_for_step("register") if cleaned_data_register: initial.update( { "first_name": cleaned_data_register["first_name"], "last_name": cleaned_data_register["last_name"], "email": cleaned_data_register["email"], "date_of_birth": cleaned_data_register["date_of_birth"], } ) if step == "financial": if getattr(self.request.user, "person", None): vouchers = Voucher.objects.filter( person=self.request.user.person, event__slug=self.kwargs["slug"], used=False ) if vouchers: initial.update({"voucher_code": vouchers.first().code}) return self.initial_dict.get(step, initial) def done(self, form_list, **kwargs): event = Event.objects.get(slug=self.kwargs["slug"]) try: cleaned_data_email = self.get_cleaned_data_for_step("email") except KeyError: # FIXME cleaned_data_email = False cleaned_data_contact_details = self.get_cleaned_data_for_step("contact_details") cleaned_data_guardians = self.get_cleaned_data_for_step("guardians") try: cleaned_data_register = self.get_cleaned_data_for_step("register") except KeyError: # FIXME cleaned_data_register = False cleaned_data_additional = self.get_cleaned_data_for_step("additional") cleaned_data_financial = self.get_cleaned_data_for_step("financial") cleaned_data_consent = self.get_cleaned_data_for_step("consent") if cleaned_data_financial["voucher_code"]: if getattr(self.request.user, "person", None): vouchers = Voucher.objects.filter( person=self.request.user.person, event=event, used=False, code=cleaned_data_financial["voucher_code"], ) if vouchers: voucher = vouchers.first() else: messages.error(self.request, _("You entered an invalid voucher code!")) # Create email address if cleaned_data_email: _email = MailAddress.objects.create( local_part=cleaned_data_email["local_part"], domain=cleaned_data_email["domain"], ) # Create user if cleaned_data_register: user = User.objects.create( username=cleaned_data_register["username"], email=cleaned_data_register["email"], ) user.set_password(cleaned_data_register["password1"]) user.save() else: user = self.request.user person, created = Person.objects.get_or_create( user=user, defaults={ "email": cleaned_data_contact_details["email"], "first_name": cleaned_data_contact_details["first_name"], "last_name": cleaned_data_contact_details["last_name"], }, ) if ( "mobile_number" in cleaned_data_contact_details or "sex" in cleaned_data_contact_details or "date_of_birth" in cleaned_data_contact_details ): person.mobile_number = cleaned_data_contact_details["mobile_number"] person.sex = cleaned_data_contact_details["sex"] person.date_of_birth = cleaned_data_contact_details["date_of_birth"] person.save() # Store postal address in database if ( "postal_code" in cleaned_data_contact_details or "place" in cleaned_data_contact_details or "street" in cleaned_data_contact_details ): person.street = cleaned_data_contact_details["street"] person.postal_code = cleaned_data_contact_details["postal_code"] person.place = cleaned_data_contact_details["place"] person.housenumber = cleaned_data_contact_details["housenumber"] person.save() if ( "guardian_first_name" in cleaned_data_guardians or "guardian_last_name" in cleaned_data_guardians or "guardian_mobile_number" in cleaned_data_guardians or "guardian_email" in cleaned_data_guardians ): guardian, created = Person.objects.get_or_create( defaults={ "mobile_number": cleaned_data_guardians["guardian_mobile_number"], }, first_name=cleaned_data_guardians["guardian_first_name"], last_name=cleaned_data_guardians["guardian_last_name"], email=cleaned_data_guardians["guardian_email"], ) person.guardians.add(guardian) person.save() if cleaned_data_email: _email.person = person _email.save() registration = EventRegistration.objects.create( managed_by_app_label="", event=event, person=person, medical_information=cleaned_data_additional["medical_information"], donation=cleaned_data_financial["donation"], school=cleaned_data_contact_details["school"], school_class=cleaned_data_contact_details["school_class"], school_place=cleaned_data_contact_details["school_place"], ) for field in event.additional_fields.all(): registration.extended_data[ slugify(field.title).replace("-", "_") ] = cleaned_data_additional[field.title] for field in cleaned_data_consent: if not field.startswith("consent_"): continue pk = int(field.split("_")[1]) term = Terms.objects.get(id=pk) registration.accepted_terms.add(term) registration.save() if cleaned_data_financial["voucher_code"]: vouchers = Voucher.objects.filter( person=person, event=event, used=False, code=cleaned_data_financial["voucher_code"] ) if vouchers: voucher = vouchers.first() registration.voucher = voucher voucher.used = True with reversion.create_revision(): voucher.save() registration.save() else: messages.error(self.request, _("You entered an invalid voucher code!")) invoice = registration.get_invoice() invoice.variant = cleaned_data_financial["payment_method"] invoice.save() context = {} context["registration"] = registration send_templated_mail( template_name="event_registered", from_email=get_site_preferences()["mail__address"], recipient_list=[get_site_preferences()["paweljong__event_notification_recipient"]], headers={ "reply_to": [ person.email, person.guardians.first().email, ], "X-Zammad-Customer-Email": person.email, }, context=context, ) messages.success( self.request, _( "You have successfully registered for the event. Please give us " "up to two days to process your registration. You will then " "receive an email from us." ), ) act = Activity( title=_("You registered for an event"), description=_("You registered for the event %s" % event.display_name), app="Paweljong", user=person, ) return redirect("do_payment", invoice.token) class EventFullView(PermissionRequiredMixin, DetailView): model = Event slug_field = "slug" template_name = "paweljong/event/full.html" object_context_name = "event" permission_required = "paweljong.view_event_rule" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["can_register"] = context["event"].can_register(request=self.request) context["is_authenticated"] = self.request.user.is_authenticated context["individual_cost"] = context["event"].individual_cost(request=self.request) return context class RegisterEventStart(PermissionRequiredMixin, DetailView): model = Event slug_field = "slug" template_name = "paweljong/event/register_start.html" object_context_name = "event" permission_required = "paweljong.view_event_rule" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["can_register"] = context["event"].can_register(request=self.request) return context class TermListView(PermissionRequiredMixin, SingleTableView): """Table of all terms.""" model = Terms table_class = TermsTable permission_required = "paweljong.view_terms_rule" template_name = "paweljong/term/list.html" @method_decorator(never_cache, name="dispatch") class TermCreateView(PermissionRequiredMixin, AdvancedCreateView): """Create view for terms.""" model = Terms form_class = EditTermForm permission_required = "paweljong.create_terms_rule" template_name = "paweljong/term/create.html" success_url = reverse_lazy("terms") success_message = _("The term has been created.") @method_decorator(never_cache, name="dispatch") class TermEditView(PermissionRequiredMixin, AdvancedEditView): """Edit view for terms.""" model = Terms form_class = EditTermForm permission_required = "paweljong.change_terms_rule" template_name = "paweljong/term/edit.html" success_url = reverse_lazy("terms") success_message = _("The term has been saved.") class UpcomingEventsRSSFeed(Feed): """RSS feed for published, upcoming events.""" def title(self): return _("Upcoming events") def link(self): return reverse("index") def feed_url(self): return reverse("upcoming_events_rss_feed") def description(self): return _("Announcement feed of all upcoming events") def ttl(self): date_event = Event.upcoming_published_events().order_by("-date_event").first().date_event date_now = timezone.now().date() return (date_event - date_now).seconds def items(self): return Event.upcoming_published_events() def item_title(self, item): return item.display_name def item_description(self, item): return item.description class AccountRegisterStart(TemplateView): template_name = "paweljong/register_start.html" class InfoMailingListView(PermissionRequiredMixin, SingleTableView): """Table of all info mailings.""" model = InfoMailing table_class = InfoMailingsTable permission_required = "paweljong.view_info_mailings_rule" template_name = "paweljong/info_mailing/list.html" @method_decorator(never_cache, name="dispatch") class InfoMailingCreateView(PermissionRequiredMixin, AdvancedCreateView): """Create view for info mailings.""" model = InfoMailing form_class = EditInfoMailingForm permission_required = "paweljong.create_info_mailing_rule" template_name = "paweljong/info_mailing/create.html" success_url = reverse_lazy("info_mailings") success_message = _("The info mailing has been created.") @method_decorator(never_cache, name="dispatch") class InfoMailingEditView(PermissionRequiredMixin, AdvancedEditView): """Edit view for info mailings.""" model = InfoMailing form_class = EditInfoMailingForm permission_required = "paweljong.change_info_mailing_rule" template_name = "paweljong/info_mailing/edit.html" success_url = reverse_lazy("info_mailings") success_message = _("The info mailing has been saved.") class InfoMailingDeleteView(PermissionRequiredMixin, AdvancedDeleteView): """Delete view for info mailings.""" model = InfoMailing permission_required = "paweljong.delete_info_mailing_rule" template_name = "core/pages/delete.html" success_url = reverse_lazy("info_mailings") success_message = _("The info mailing has been deleted.") class SendMailFromRegistration(PermissionRequiredMixin, FormView): template_name = "paweljong/event_registration/notification.html" permission_required = "paweljong.send_notification_mail_rule" form_class = RegistrationNotificationForm success_url = reverse_lazy("manage_events") def form_valid(self, form): registration = EventRegistration.objects.get(id=self.kwargs["pk"]) context = {} recipient_list = [] context["subject"] = form.cleaned_data["subject"] context["registration"] = registration context["body"] = form.cleaned_data["text"] if form.cleaned_data["reply_to"]: reply_to = form.cleaned_data["reply_to"] else: reply_to = form.cleaned_data["sender"] if form.cleaned_data["send_to_person"]: recipient_list.append(registration.person.email) if form.cleaned_data["send_to_guardians"]: recipient_list.append(registration.person.guardians.first().email) send_templated_mail( template_name="event_notification", from_email=get_site_preferences()["mail__address"], recipient_list=recipient_list, headers={ "reply_to": reply_to, }, context=context, ) return super().form_valid(self) class RegistrationStateListView(PermissionRequiredMixin, SingleTableView): """Table of all terms.""" model = RegistrationState table_class = RegistrationStatesTable permission_required = "paweljong.view_registration_states_rule" 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.create_registration_states_rule" 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.change_registration_states_rule" template_name = "paweljong/registration_state/edit.html" success_url = reverse_lazy("registration_states") success_message = _("The term has been saved.") class RetractRegistration(PermissionRequiredMixin, View): permission_required = "paweljong.can_retract_registration_rule" def get_object(self, *args, **kwargs): return EventRegistration.objects.get(id=self.kwargs["pk"]) def get(self, *args, **kwargs): registration = self.get_object() registration.retract() messages.success(self.request, _("Registration successfully retracted.")) return redirect("event_detail_by_name", slug=registration.event.slug) class EventDetailView(PermissionRequiredMixin, DetailView): """Detail view for an event instance.""" context_object_name = "event" permission_required = "paweljong.view_event_detail_rule" template_name = "paweljong/event/detail.html" model = Event slug_field = "slug" def get_queryset(self): return Event.objects.all() def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) registrations = EventRegistration.objects.filter(event=self.object) registrations_filter = EventRegistrationFilter(self.request.GET, queryset=registrations) context["registrations_filter"] = registrations_filter # Registrations table registrations_table = EventRegistrationsTable(registrations_filter.qs) RequestConfig(self.request).configure(registrations_table) context["registrations_table"] = registrations_table # Child groups table child_groups = self.object.linked_group.child_groups.all() child_groups_table = ChildGroupsTable(child_groups) RequestConfig(self.request).configure(child_groups_table) context["child_groups_table"] = child_groups_table # Additional fields table additional_fields = self.object.additional_fields.all() additional_fields_table = EventAdditionalFieldsTable(additional_fields) RequestConfig(self.request).configure(additional_fields_table) context["additional_fields_table"] = additional_fields_table return context class PersonGroupView(PermissionRequiredMixin, FormView): template_name = "paweljong/event/persons_group.html" permission_required = "paweljong.add_persons_to_group_rule" form_class = PersonGroupFormPerson def form_valid(self, form): group = Group.objects.get(id=self.kwargs["pk"]) try: person = Person.objects.get(user__username=form.cleaned_data["username"]) group.members.add(person) messages.success(self.request, _(f"Person {person} added successfully!")) except Person.DoesNotExist: messages.error(self.request, _("Person does not exist!")) return super().form_valid(self) def get_success_url(self): return reverse("add_persons_to_group", kwargs={"pk": self.kwargs["pk"]}) class ViewTerms(PermissionRequiredMixin, DetailView): context_object_name = "event" template_name = "paweljong/event/terms.html" permission_required = "paweljong.can_view_terms_rule" model = Event slug_field = "slug" class CheckInRegistration(PermissionRequiredMixin, View): permission_required = "paweljong.change_registration_rule" def get_object(self, *args, **kwargs): return EventRegistration.objects.get(id=self.kwargs["pk"]) def get(self, *args, **kwargs): registration = self.get_object() try: registration.mark_checked_in() messages.success(self.request, _("Successfully checked in.")) except ValidationError: messages.error(self.request, _("Person is already checked in!")) return redirect("event_detail_by_name", slug=registration.event.slug) class MarkRegistrationPayed(PermissionRequiredMixin, View): permission_required = "paweljong.mark_payment_payed_rule" def get_object(self, *args, **kwargs): registration = EventRegistration.objects.get(id=self.kwargs["pk"]) invoice = registration.get_invoice() return invoice def get(self, *args, **kwargs): invoice = self.get_object() invoice.status = "confirmed" invoice.save() messages.success(request, _("Successfully marked as payed!")) return redirect("registration_by_pk", pk=invoice.for_object.pk)