Files
2022-12-24 21:07:46 +02:00

266 lines
8.7 KiB
Python

from django.shortcuts import render
from django.contrib.auth.decorators import permission_required, login_required
from django.utils.decorators import method_decorator
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import ensure_csrf_cookie
from django.http import (
HttpResponse,
HttpResponseRedirect,
JsonResponse,
HttpResponseForbidden,
)
from django.conf import settings
from django.utils.translation import gettext as _
from django.forms.models import model_to_dict
from dal import autocomplete
from django.utils import timezone
import logging
import datetime
import html
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import authentication, permissions
from members.permissions import CheckByEmailPermission
from members.models import Member, Request, Payment
from members.forms import MemberForm, CSVValidationError
from members.tables import MemberTable
from members.views.utils import *
@ensure_csrf_cookie
@require_http_methods(["GET"])
@login_required(login_url="/admin/login")
@permission_required("members.read_member", raise_exception=True)
def member_list(request, *args, **kwargs):
"""Render members list."""
search = request.GET.get("q", None)
if search:
members = Member.find_members_by_name(search)
else:
members = Member.objects.all()
table = MemberTable(
members,
request=request,
exclude=["id"],
attrs={"class": "table table-bordered table-hover"},
)
table.paginate(page=request.GET.get("page", 1), per_page=25)
table_html = convert_table_to_html(table, request)
queryset = Member.get_members_with_latest_payment(members)
# Member fee is valid from 1.9.-31.8.
f_day = 1
f_month = 9
now = timezone.now()
if now.month >= f_month:
filter_date = timezone.make_aware(datetime.datetime(now.year, f_month, f_day))
else:
filter_date = timezone.make_aware(
datetime.datetime(now.year - 1, f_month, f_day)
)
context = {
"table": table_html,
"member_count": len(members),
"paid_count": len(queryset.filter(last_paid__gte=filter_date)),
"notification": request.GET.get("notification", None),
}
return render(request, "members/member_list.html", context)
@ensure_csrf_cookie
@require_http_methods(["GET"])
@login_required(login_url="/admin/login")
@permission_required("members.add_member", raise_exception=True)
def member_add(request, *args, **kwargs):
"""Render add member page."""
form = MemberForm()
return render(request, "members/member_add.html", {"form": form})
@ensure_csrf_cookie
@require_http_methods(["GET"])
@login_required(login_url="/admin/login")
@permission_required("members.delete_member", raise_exception=True)
def member_delete_confirm(request, *args, **kwargs):
"""Render member deletion confirmation page."""
i = kwargs.pop("index", None)
if i is None:
return error_view(request, _("No member id specified"))
else:
member = Member.objects.get(id=i)
form = MemberForm(instance=member)
return render(
request,
"members/member_delete_confirm.html",
{"member_id": i, "form": form},
)
@ensure_csrf_cookie
@require_http_methods(["GET"])
@login_required(login_url="/admin/login")
@permission_required("members.add_member", raise_exception=True)
def member_add_many(request, *args, **kwargs):
"""Render add multiple members page."""
return render(request, "members/member_add_many.html", {})
@ensure_csrf_cookie
@require_http_methods(["POST"])
@login_required(login_url="/admin/login")
@permission_required("members.add_member", raise_exception=True)
def add_many_confirm(request, *args, **kwargs):
models = request.session["models"]
payment_source = request.session["payment_source"]
try:
members, payments = models.members, models.payments
for member in members:
member.save()
if not member.payments.exists(): # create payment for new members
payment = Payment.objects.create(member=member, source=payment_source)
for payment in payments:
payment.save()
msg = "Successfully imported {} members and {} payments."
notification = _(msg).format(len(members), len(payments))
return HttpResponseRedirect(
"/members/list?notification={}".format(html.escape(notification))
)
except Exception as ex:
logging.exception('Failed to save models after "add many."')
return error_view(request, _("Failed to import members"))
@ensure_csrf_cookie
@require_http_methods(["POST"])
@login_required(login_url="/admin/login")
@permission_required("members.add_member", raise_exception=True)
def member_submit(request, *args, **kwargs):
"""Add member based on data gained from member form."""
form = MemberForm(request.POST)
if form.is_valid():
form.save()
logging.info(
"Saved new member to member register"
"with the following info: {}".format(form.cleaned_data)
)
notification = "{} {} {}.".format(
_("Successfully added member"),
form.cleaned_data["last_name"],
form.cleaned_data["first_name"],
)
return HttpResponseRedirect(
"/members/list?notification={}".format(html.escape(notification))
)
else:
return error_view(request, form.errors)
@ensure_csrf_cookie
@require_http_methods(["POST"])
@login_required(login_url="/admin/login")
@permission_required("members.change_member", raise_exception=True)
def member_update(request, *args, **kwargs):
"""Update member information."""
id = request.POST.get("id", None)
logging.debug(id)
if id is not None:
member = Member.objects.get(id=id)
else:
return error_view(request, _("Member missing 'id' field."))
form = MemberForm(request.POST, instance=member)
if form.is_valid():
form.save()
logging.info(
"Updated member in member register with the following info: {}".format(form)
)
notification = "{} {} {}.".format(
_("Successfully updated member"), member.last_name, member.first_name
)
return HttpResponseRedirect(
"/members/list?notification={}".format(html.escape(notification))
)
else:
return error_view(request, form.errors)
@ensure_csrf_cookie
@require_http_methods(["POST"])
@login_required(login_url="/admin/login")
@permission_required("members.delete_member", raise_exception=True)
def member_delete(request, *args, **kwargs):
"""Delete member."""
try:
id = request.POST["id"]
except KeyError:
return error_view(request, _("No member id specified"))
try:
member = Member.objects.get(id=id)
notification = "{} {} {}.".format(
_("Successfully deleted member"), member.last_name, member.first_name
)
member.delete()
logging.info(
"Delete member in member register with the following id: {}".format(id)
)
return HttpResponseRedirect(
"/members/list?notification={}".format(html.escape(notification))
)
except:
return error_view(request, _("Could not delete member object"))
@ensure_csrf_cookie
@require_http_methods(["GET"])
@login_required(login_url="/admin/login")
@permission_required("members.change_member", raise_exception=True)
def member_edit(request, *args, **kwargs):
"""Edit member information."""
i = kwargs.pop("index", None)
if i is None:
return error_view(request, _("No member id specified"))
else:
member = Member.objects.get(id=i)
form = MemberForm(instance=member)
return render(
request, "members/member_edit.html", {"member_id": i, "form": form}
)
@method_decorator(login_required(login_url="/admin/login"), name="dispatch")
@method_decorator(permission_required("members.change_member"), name="dispatch")
class MemberAutoComplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
qs = Member.objects.all()
if self.q:
qs = Member.find_members_by_name(self.q)
return qs.order_by("last_name")
class CheckByEmail(APIView):
"""Check by email"""
authentication_classes = (authentication.TokenAuthentication,)
permission_classes = (CheckByEmailPermission,)
def get(self, request, format=None):
email = request.query_params.get("email")
exists = bool(email and Member.objects.filter(email=email).exists())
resp = {"exists": exists}
return JsonResponse(resp)