Skip to content
Snippets Groups Projects
views.py 19.9 KiB
Newer Older
Tom Teichler's avatar
Tom Teichler committed
from typing import Optional

from django.contrib.auth.decorators import login_required
from django.http import HttpRequest, HttpResponse
Tom Teichler's avatar
Tom Teichler committed
from django.shortcuts import redirect, render
from django.utils import timezone
from django.utils.translation import ugettext as _
from django.views.generic.list import ListView

import reversion
from django_tables2 import RequestConfig
from reversion.views import create_revision
from rules.contrib.views import PermissionRequiredMixin, permission_required
from templated_email import send_templated_mail

from aleksis.core.models import Activity, Person
from aleksis.core.util import messages
from aleksis.core.util.core_helpers import lazy_preference, objectgetter_optional

from .filters import EventRegistrationFilter, FeedbackAspectsFilter, VoucherFilter
from .forms import (
    EditEventForm,
    EditEventRegistrationForm,
    EditFeedbackAspectForm,
    EditVoucherForm,
    EventFeedbackForm,
    GenerateListForm,
    RegisterEventForm,
)
from .models import Event, EventRegistration, FeedbackAspect, Voucher
from .tables import (
    EventRegistrationsTable,
    EventsTable,
    FeedbackAspectsTable,
    ParticipatedEventsTable,
    VouchersTable,
)
from .util import generate_code


def events(request):
    context = {}

    # Get all upcoming events
    now = timezone.datetime.today()
    events = Event.objects.filter(date_event__gte=now, published=True)

    # Build table
    events_table = EventsTable(events)
    RequestConfig(request).configure(events_table)
    context["events_table"] = events_table

    if request.user.is_authenticated:
        # Get all events the person participated in.
        current_person = Person.objects.get(user__username=request.user.username)
        participated_events = Event.objects.filter(group__members=current_person)
Tom Teichler's avatar
Tom Teichler committed
        # Build table
        participated_events_table = ParticipatedEventsTable(participated_events)
        RequestConfig(request).configure(participated_events_table)
        context["participated_events_table"] = participated_events_table
Tom Teichler's avatar
Tom Teichler committed
    return render(request, "paweljong/_event/list.html", context)


@create_revision
@login_required
Tom Teichler's avatar
Tom Teichler committed
def register_event(request, id_):
    context = {}

    # Get current person and event
    event = Event.objects.get(id=id_)
    context["event"] = event

    initial = {
        "person": request.user.person,
        "event": event,
        "school": request.user.person.school,
        "school_place": request.user.person.school_place,
        "school_class": request.user.person.school_class,
        "mobile_number": request.user.person.mobile_number,
        "email": request.user.person.email,
        "street": request.user.person.street,
        "place": request.user.person.place,
        "housenumber": request.user.person.housenumber,
        "sex": request.user.person.sex,
        "date_of_birth": request.user.person.date_of_birth,
        "postal_code": request.user.person.postal_code,
    }

    if request.user.person.guardians.first():
        initial.update(
            {
                "guardian_first_name": request.user.person.guardians.first().first_name,
                "guardian_last_name": request.user.person.guardians.first().last_name,
                "guardian_mobile_number": request.user.person.guardians.first().mobile_number,
                "guardian_email": request.user.person.guardians.first().email,
            }
        )

    register_form = RegisterEventForm(initial=initial)

    # Produce error if registration is not possible
    if not event.can_register(request):
        messages.error(request, _("Registration is no longer possible"))
        return redirect("events")

    # Check whether person is already a member of the event
    if request.user.person in event.group.members.all():
        messages.success(request, _("You are already registred."))
        return redirect("events")

    if request.method == "POST":
        register_form = RegisterEventForm(request.POST, initial=initial)
        if register_form.is_valid():
            # Update person information if changed
            if (
                "school" in register_form.changed_data
                or "school_class" in register_form.changed_data
                or "school_place" in register_form.changed_data
                or "mobile" in register_form.changed_data
                or "sex" in register_form.changed_data
                or "date_of_birth" in register_form.changed_data
            ):
                request.user.person.school = register_form.cleaned_data["school"]
                request.user.person.school_class = register_form.cleaned_data["school_class"]
                request.user.person.school_place = register_form.cleaned_data["school_place"]
                request.user.person.mobile_number = register_form.cleaned_data["mobile_number"]
                request.user.person.sex = register_form.cleaned_data["sex"]
                request.user.person.date_of_birth = register_form.cleaned_data["date_of_birth"]

                request.user.person.save()

            # Store postal address in database
            if (
                "postal_code" in register_form.changed_data
                or "place" in register_form.changed_data
                or "street" in register_form.changed_data
            ):

                request.user.person.street = register_form.cleaned_data["steet"]
                request.user.person.postal_code = register_form.cleaned_data["postal_code"]
                request.user.person.place = register_form.cleaned_data["place"]

                request.user.person.save()

            if (
                "guardian_first_name" in register_form.changed_data
                or "guardian_last_name" in register_form.changed_data
                or "guardian_mobile_number" in register_form.changed_data
                or "guardian_email" in register_form.changed_data
            ):
                guardian = Person.objects.get_or_create(
                    defaults={
                        "first_name": register_form.cleaned_data["guardian_first_name"],
                        "last_name": register_form.cleaned_data["guardian_last_name"],
                        "mobile_number": register_form.cleaned_data["guardian_mobile_number"],
                    },
                    email=register_form.cleaned_data["guardian_email"],
                )

                request.user.person.guardians.add(guardian[0])
                request.user.person.save()

            # Add the current person to the event
            event.add_member(request.user.person)
            event.save()

            registration = register_form.save(commit=True)
            if "voucher_code" in register_form.changed_data:
                voucher = Voucher.objects.get(code=register_form.cleaned_data["voucher_code"])
                if voucher:
                    registration.voucher = voucher
                    with reversion.create_revision():
                        registration.save()
                else:
                    messages.error(request, _("You entered an invalid voucher code!"))

            send_templated_mail(
                template_name="event_registred",
                from_email=lazy_preference("mail", "address"),
                recipient_list=["orga@.org"],
                headers={
                    "reply_to": [
                        request.person.email,
                        request.person.guardians.first().email,
                    ],
                },
                context=context,
            )

            messages.success(
                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 registred for an event"),
                description=_("You registred for the event %s" % event.display_name),
                app="TIC-Desk",
                user=request.user.person,
            )
            act.save()

    context["register_form"] = register_form

    return render(request, "paweljong/_event/register.html", context)


@login_required
def feedback_event(request, id_):
    context = {}

    # Get current person and event
    current_person = Person.objects.get(user__username=request.user.username)
    event = Event.objects.get(id=id_)
    context["event"] = event

    # Prepare the form
    initial = {
        "event": event,
        "person": current_person,
    }

    feedback_form = EventFeedbackForm(event, initial=initial)

    # Check whether person is a member of the event
    if current_person not in event.group.members.all():
        return redirect("events")
        messages.error(request, _("You did not take part in this event."))

    if request.method == "POST":
        if feedback_form.is_valid():
            feedback = feedback_form.save(commit=True)
            context["feedback"] = feedback
            # Handle photo uploads, if any

            send_templated_mail(
                template_name="event_feedback",
                from_email=lazy_preference("mail", "address"),
                recipient_list=["verein@.org"],
                headers={
                    "reply_to": [
                        request.person.email,
                    ],
                },
                context=context,
            )

            # Set success
            messages.success(request, _("Feedback successfully submitted."))
            return redirect("events")

            act = Activity(
                title=_("You submitted feedback"),
                description=_("You submitted feedback for %s" % event.display_name),
                app="TIC-Desk",
                user=request.user.person,
            )
            act.save()

    context["feedback_form"] = feedback_form

    return render(request, "paweljong/_event/feedback.html", context)


@permission_required("paweljong.change_event", fn=objectgetter_optional(Event, None, False))
def edit_event(request: HttpRequest, id_: Optional[int] = None) -> HttpResponse:
    """View to edit or create an event."""
Tom Teichler's avatar
Tom Teichler committed
    event = objectgetter_optional(Event, None, False)(request, id_)
    context["event"] = event

    if event:
        # Edit form for existing event
        edit_event_form = EditEventForm(request.POST or None, instance=event)
    else:
        # Empty form to create a new event
        edit_event_form = EditEventForm(request.POST or None)

    if request.method == "POST":
        if edit_event_form.is_valid():
            with reversion.create_revision():
                new_event = edit_event_form.save()
                context["new_event"] = new_event
                context["person"] = request.user.person
                send_templated_mail(
                    template_name="event_created",
                    from_email=lazy_preference("mail", "address"),
                    recipient_list=["orga@.org"],
                    context=context,
                )
            messages.success(request, _("The event has been saved."))

            return redirect("events")

    context["edit_event_form"] = edit_event_form

    return render(request, "paweljong/_event/edit.html", context)


class ManageEvents(ListView, PermissionRequiredMixin):
    """View listing upcoming events."""

    template_name = "paweljong/_event/manage.html"
    permission_required = "paweljong.change_events"
    context = {}

    def get_queryset(self):
        now = timezone.datetime.today()
        return Event.objects.filter(date_event__gte=now)


@permission_required("paweljong.view_vouchers")
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.delete_voucher")
def delete_voucher(request, id_):
    context = {}

    current_voucher = Voucher.objects.get(id=id_)
    current_voucher.deleted = True
    with reversion.create_revision():
        current_voucher.save()

    act = Activity(
        title=_("You deleted a voucher!"),
        description=_("You deleted the voucher with ID %s" % current_voucher.id),
        app="TIC-Desk",
        user=request.user.person,
    )
    act.save()

    messages.success(request, _("The voucher was successfully deleted."))

    return redirect("vouchers")


@permission_required("paweljong.change_voucher", fn=objectgetter_optional(Voucher, None, False))
def edit_voucher(request: HttpRequest, id_: Optional[int] = None) -> HttpResponse:
    """View to edit or create a voucher."""
    context = {}

    voucher = objectgetter_optional(Voucher, None, False)(request, id_)
    context["voucher"] = voucher

    if id_:
        # Edit form for existing voucher
        edit_voucher_form = EditVoucherForm(request.POST or None, instance=voucher)
    else:
        # Empty form to create a new voucher
        edit_voucher_form = EditVoucherForm(request.POST or None)

    if request.method == "POST":
        if edit_voucher_form.is_valid():
            voucher = edit_voucher_form.save(commit=True)
            if not voucher.code:
                voucher.code = generate_code()
            with reversion.create_revision():
                voucher.save()

            act = Activity(
                title=_("You have created a voucher."),
                description=_(
                    "You have created a voucher for %s for %s" % (voucher.person, voucher.event)
                ),
                app="TIC-Desk",
                user=request.user.person,
            )
            act.save()

            messages.success(request, _("The voucher has been saved."))

            return redirect("vouchers")

    context["edit_voucher_form"] = edit_voucher_form

    return render(request, "paweljong/voucher/edit.html", context)


@permission_required("paweljong.generate_lists")
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)


@permission_required("paweljong.view_registrations")
def registrations(request: HttpRequest) -> HttpResponse:
    """List view listing all registrations."""
    context = {}

    # Get all registrations
    registrations = EventRegistration.objects.all()

    # Get filter
    registrations_filter = EventRegistrationFilter(request.GET, queryset=registrations)
    context["registrations_filter"] = registrations_filter

    # Build table
    registrations_table = EventRegistrationsTable(registrations_filter.qs)
    RequestConfig(request).configure(registrations_table)
    context["registrations_table"] = registrations_table

    return render(request, "paweljong/event_registration/list.html", context)


@permission_required(
    "paweljong.view_registration",
    fn=objectgetter_optional(EventRegistration, "request.user.person", True),
)
def registration(request: HttpRequest, id_) -> HttpResponse:
    context = {}

    registration = objectgetter_optional(EventRegistration, "request.user.person", True)(
        request, id_
    )

    context["registration"] = registration

    return render(request, "paweljong/event_registration/full.html", context)


@permission_required(
    "paweljong.delete_registrations",
    fn=objectgetter_optional(EventRegistration, None, False),
)
def delete_registration(request: HttpRequest, id_) -> HttpResponse:
    context = {}

    registration = EventRegistration.objects.get(id=id_)

    person = registration.person

    registration.event.remove_member(registration.person)
    registration.event.save()

    registration.delete()

    messages.success(request, _("Registration was successfully deleted."))

    return redirect("registrations")


@permission_required(
    "paweljong.manage_registrations",
    fn=objectgetter_optional(EventRegistration, None, False),
)
def edit_registration(request: HttpRequest, id_) -> HttpResponse:
    context = {}

    registration = objectgetter_optional(EventRegistration, None, False)(request, id_)

    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.is_own_voucher", fn=objectgetter_optional(Voucher, None, False))
def print_voucher(request: HttpRequest, id_) -> HttpResponse:
    context = {}

    voucher = Voucher.objects.get(id=id_)
    context["voucher"] = voucher

    return render(request, "paweljong/print/voucher.html", context)


@permission_required("paweljong.view_feedback_aspects")
def feedback_aspects(request: HttpRequest) -> HttpResponse:
    """List view listing all feedback_aspects."""
    context = {}

    # Get all feedback_aspects
    feedback_aspects = FeedbackAspect.objects.all()

    # Get filter
    feedback_aspects_filter = FeedbackAspectsFilter(request.GET, queryset=feedback_aspects)
    context["feedback_aspects_filter"] = feedback_aspects_filter

    # Build table
    feedback_aspects_table = FeedbackAspectsTable(feedback_aspects_filter.qs)
    RequestConfig(request).configure(feedback_aspects_table)
    context["feedback_aspects_table"] = feedback_aspects_table

    return render(request, "paweljong/feedback_aspect/list.html", context)


@permission_required(
    "paweljong.change_feedback_aspect",
    fn=objectgetter_optional(FeedbackAspect, None, False),
)
def edit_feedback_aspect(request: HttpRequest, id_: Optional[int] = None) -> HttpResponse:
    """View to edit or create an feedback_aspect."""
    context = {}

    feedback_aspect = objectgetter_optional(FeedbackAspect, None, False)(request, id_)
    context["feedback_aspect"] = feedback_aspect

    if id_:
        # Edit form for existing feedback_aspect
        edit_feedback_aspect_form = EditFeedbackAspectForm(
            request.POST or None, instance=feedback_aspect
        )
    else:
        # Empty form to create a new feedback_aspect
        edit_feedback_aspect_form = EditFeedbackAspectForm(request.POST or None)

    if request.method == "POST":
        if edit_feedback_aspect_form.is_valid():
            with reversion.create_revision():
                aspect = edit_feedback_aspect_form.save(commit=True)

                act = Activity(
                    title=_("You have create a feedback aspect."),
                    description=_("You have created the feedback aspect: %s" % aspect),
                    app="TIC-Desk",
                    user=request.user.person,
                )
                act.save()

            messages.success(request, _("The feedback aspect has been saved."))

            return redirect("feedback_aspects")

    context["edit_feedback_aspect_form"] = edit_feedback_aspect_form

    return render(request, "paweljong/feedback_aspect/edit.html", context)