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 ugettext 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, "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, "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, "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, "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, "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 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)