diff --git a/vendor/regidesk/regidesk/views.py b/vendor/regidesk/regidesk/views.py index c9a594e2d8b34e63a02c522d433e51c39ef8859a..e37ee95d07f762fa4def060e01a564645cc2c7b1 100644 --- a/vendor/regidesk/regidesk/views.py +++ b/vendor/regidesk/regidesk/views.py @@ -1,20 +1,207 @@ -from regidesk import forms -from regidesk import models +import base64 +import logging +from datetime import datetime from django.core.exceptions import ValidationError +from django.core.mail import EmailMultiAlternatives from django.conf import settings from django.contrib import messages -from django.contrib.auth.decorators import user_passes_test +from django.contrib.auth.decorators import permission_required, user_passes_test, login_required from django.db import transaction +from django.db.models import F, Q +from django.db.models import Count, Max, Sum from django.http import Http404 -from django.http import HttpResponse +from django.http import HttpResponse, HttpResponseBadRequest from django.shortcuts import redirect, render +from django.template import Template, Context +from django.urls import reverse -from registrasion.models import commerce - +from registrasion import util +from registrasion.models import commerce, people from symposion.conference.models import Conference +from regidesk import forms +from regidesk.models import BoardingPass, BoardingPassTemplate, CheckIn + + + +AttendeeProfile = util.get_object_from_name(settings.ATTENDEE_PROFILE_MODEL) + def _staff_only(user): ''' Returns true if the user is staff. ''' return user.is_staff +@permission_required("regidesk.view_boarding_pass") +def boarding_overview(request, boarding_state="pending"): + + tickets = commerce.LineItem.objects.select_related( + "invoice","invoice__user__attendee","product__category" + ).filter( + invoice__status=commerce.Invoice.STATUS_PAID, + product__category=settings.TICKET_PRODUCT_CATEGORY, + price__gte=0 + ) + + ticketholders = { ticket.invoice.user: ticket.product.name for ticket in tickets } + + attendees = people.Attendee.objects.select_related( + "attendeeprofilebase", + "attendeeprofilebase__attendeeprofile", + "user", + "user__checkin" + ).filter(user__in=ticketholders) + + profiles = AttendeeProfile.objects.filter( + attendee__in=attendees + ).select_related( + "attendee", "attendee__user", + ) + profiles_by_attendee = dict((i.attendee, i) for i in profiles) + + bp_templates = BoardingPassTemplate.objects.all() + + ctx = { + "boarding_state": boarding_state, + "attendees": attendees, + "profiles": profiles_by_attendee, + "templates": bp_templates, + } + + return render(request, "regidesk/boardingpass_overview.html", ctx) + +@login_required +def checkin_png(request, checkin_code): + + checkin = CheckIn.objects.get(checkin_code=checkin_code) + if not checkin: + raise Http404() + + if not request.user.has_perm("regidesk.view_checkin_details"): + if request.user != checkin.user: + raise Http404() + + response = HttpResponse() + response["Content-Type"] = "image/png" + response["Content-Disposition"] = 'inline; filename="qrcode.png"' + + qrcode = base64.b64decode(checkin.qrcode) + response.write(qrcode) + + return response + +@permission_required("regidesk.send_boarding_pass") +def boarding_prepare(request): + + attendee_pks = [] + try: + for pk in request.POST.getlist("_selected_action"): + attendee_pks.append(int(pk)) + except ValueError: + return HttpResponseBadRequest() + attendees = people.Attendee.objects.filter(pk__in=attendee_pks) + attendees = attendees.select_related( + "user", "attendeeprofilebase", "attendeeprofilebase__attendeeprofile") + + sample_checkin = CheckIn.objects.get_or_create(user=attendees[0].user)[0] + rendered_template = {} + sample_ctx = {} + + bp_template_pk = request.POST.get("template", "") + if bp_template_pk: + bp_template = BoardingPassTemplate.objects.get(pk=bp_template_pk) + + sample_ctx = { + "user": sample_checkin.user, + "boardingpass": sample_checkin.boardingpass, + "code": sample_checkin.code, + "qrcode": sample_checkin.qrcode, + "qrcode_url": request.build_absolute_uri( + reverse("regidesk:checkin_png", args=[sample_checkin.code])), + } + ctx = Context(sample_ctx) + subject = Template(bp_template.subject).render(ctx) + rendered_template['plain'] = Template(bp_template.body).render(ctx) + rendered_template['html'] = Template(bp_template.html_body).render(ctx) + else: + bp_template = None + subject = None + + ctx = { + "attendees": attendees, + "template": bp_template, + "attendee_pks": attendee_pks, + "rendered_template": rendered_template, + "subject": subject, + "sample": sample_ctx, + } + + request.session.set_expiry=(300) + request.session['boarding_attendees'] = attendee_pks + request.session['template'] = bp_template.pk + response = render(request, "regidesk/boardingpass_prepare.html", ctx) + + return response + +@permission_required("regidesk.send_boarding_pass") +def boarding_send(request): + + attendees = people.Attendee.objects.filter(pk__in=request.session['boarding_attendees']) + attendees = attendees.select_related( + "user", "attendeeprofilebase", "attendeeprofilebase__attendeeprofile") + + logging.debug(attendees) + + template_pk = request.session['template'] + template = BoardingPassTemplate.objects.get(pk=template_pk) + + for attendee in attendees: + + user = attendee.user + checkin = CheckIn.objects.get_or_create(user=user) + ctx = { + "user": user, + "checkin": user.checkin, + "code": user.checkin.code, + "qrcode": user.checkin.qrcode, + "qrcode_url": request.build_absolute_uri( + reverse("regidesk:checkin_png", args=[user.checkin.code])), + } + ctx = Context(ctx) + + subject = Template(template.subject).render(ctx) + body = Template(template.body).render(ctx) + if template.html_body: + html_body = Template(template.html_body).render(ctx) + else: + html_body = None + + bpass = BoardingPass(template=template, to_address=user.email, + from_address=template.from_address, + subject=subject, body=body, + html_body=html_body + ) + bpass.save() + if user.checkin.boardingpass: + user.checkin.boardingpass.delete() + user.checkin.boardingpass = bpass + user.checkin.save() + + with transaction.atomic(): + + msg = EmailMultiAlternatives( + bpass.subject, + bpass.body, + bpass.from_address, + [bpass.to_address,], + ) + if bpass.html_body: + msg.attach_alternative(bpass.html_body, "text/html") + + msg.send() + + bpass.sent = datetime.now() + bpass.save() + messages.success(request, "Sent boarding pass to %s" % attendee) + request.session['boarding_attendees'].remove(attendee.pk) + + return redirect("regidesk:boarding_overview")