Changeset - 4162ba7c3fb0
[Not reviewed]
Merge
0 5 3
James Polley - 6 years ago 2018-04-17 05:54:38
jp@jamezpolley.com
Merge branch 'master' into ticket-testing
5 files changed with 28 insertions and 10 deletions:
0 comments (0 inline, 0 general)
pinaxcon/templates/symposion/schedule/_grid.html
Show inline comments
 

	
 
{% load lca2018_tags %}
 
{% load waffle_tags %}
 
<table class="calendar table table-bordered">
 
  <thead>
 
    <tr>
 
      <th class="time">&nbsp;</th>
 
        {% for room in timetable.rooms %}
 
          <th>{{ room.name }}</th>
 
          {% endfor %}
 
    </tr>
 
    {% with timetable|day_has_tracks:timetable.day as has_tracks %}
 
      {% if has_tracks %}
 
        <tr>
 
          <th class="time">&nbsp;</th>
 
          {% for room in timetable.rooms %}
 
            {% with room|trackname:timetable.day as track_name %}
 
              <th class="track-name">{% if track_name %}<p>{{ track_name }}{% endif %}</th>
 
	        {% endwith %}
 
            {% endwith %}
 
          {% endfor %}
 
        </tr>
 
      {% endif %}
 
    {% endwith %}
 
  </thead>
 
  <tbody>
 
    {% for row in timetable %}
 
      <tr>
 
        <td class="time"><h4>{{ row.time|date:"h:iA" }}</h4></td>
 
        {% for slot in row.slots %}
 
          <td class="slot slot-{{ slot.kind.label }}" colspan="{{ slot.colspan }}" rowspan="{{ slot.rowspan }}">
 
            {% if slot.kind.label == "talk" or slot.kind.label == "tutorial" %}
 
              {% if not slot.content %}
 
              {% else %}
 
                <span class="title">
 
                  <a href="{% url "schedule_presentation_detail" slot.content.pk %}">{{ slot.content.title }}</a>
 
                </span>
 
                <span class="speaker">
 
                  {{ slot.content.speakers|join:", " }}
 
                </span>
 
                {% flag "session_chair" %}
 
                  {% if slot.sessions %}
 
                    <div>
 
                      {% for session in slot.sessions.all %}
 
                        <em>Session chair:
 
                        {% if not session.chair %}
 
                          <a href="{% url "schedule_session_detail" session.id %}">Volunteer! 🙋</a>
 
                        {% else %}
 
                          <a href="{% url "schedule_session_detail" session.id %}">{{ session.chair.user.attendee.attendeeprofilebase.attendeeprofile.name }}</a>
 
                        {% endif %}</em>
 
                      {% endfor %}
 
                    </div>
 
                  {% endif %}
 
                {% endflag %}
 
              {% endif %}
 
            {% elif slot.kind.label == "shortbreak" %}
 
            {% else %}
 
              {% if slot.content_override %}
 
                {{ slot.content_override_html|safe }}
 
              {% else %}
 
                {{ slot.kind.label }}
 
              {% endif %}
 
            {% endif %}
 
            {% if "break" in slot.kind.label %}
 
            {% else %}
 
              <span class="room">
 
                {{ slot.rooms|join:", "}}<span class="endtime"> ends {{ slot.end|date:"h:iA" }}</span>
 
              </span>
 
            {% endif %}
 
          </td>
 
        {% endfor %}
 
        {% if forloop.last %}
 
          <td colspan="{{ timetable.rooms|length }}"></td>
 
        {% endif %}
 
      </tr>
 
    {% endfor %}
 
  </tbody>
 
</table>
vendor/regidesk/regidesk/models.py
Show inline comments
...
 
@@ -53,87 +53,91 @@ class BoardingPass(models.Model):
 

	
 
    def __unicode__(self):
 
        return self.checkin.attendee.attendeeprofilebase.attendeeprofile.name + ' ' + self.timestamp.strftime('%Y-%m-%d %H:%M:%S')
 

	
 
    @property
 
    def email_args(self):
 
        return (self.subject, self.body, self.from_address, self.user.email)
 

	
 
class CheckIn(models.Model):
 

	
 
    user = models.OneToOneField(User)
 
    boardingpass = models.OneToOneField(BoardingPass, null=True,
 
                                        blank=True, on_delete=models.SET_NULL)
 
    seen = models.DateTimeField(null=True,blank=True)
 
    checked_in = models.DateTimeField(null=True,blank=True)
 
    checkin_code = models.CharField(
 
        max_length=6,
 
        unique=True,
 
        db_index=True,
 
    )
 
    _checkin_code_png=models.TextField(max_length=512,null=True,blank=True)
 
    badge_printed = models.BooleanField(default=False)
 
    schwag_given = models.BooleanField(default=False)
 
    checked_in_bool = models.BooleanField(default=False)
 
    needs_review = models.BooleanField(default=False)
 
    review_text = models.TextField(blank=True)
 

	
 
    class Meta:
 
        permissions = (
 
            ("view_checkin_details", "Can view the details of other user's checkins"),
 
        )
 

	
 
    def save(self, *a, **k):
 
        while not self.checkin_code:
 
            checkin_code = generate_code()
 
            if CheckIn.objects.filter(checkin_code=checkin_code).count() == 0:
 
                self.checkin_code = checkin_code
 
        return super(CheckIn, self).save(*a, **k)
 

	
 
    def mark_checked_in(self):
 
        self.checked_in_bool = True
 
        self.checked_in = timezone.now()
 
        self.save()
 

	
 
    def mark_badge_printed(self):
 
        self.badge_printed = True
 
        self.save()
 

	
 
    def unset_badge(self):
 
        self.badge_printed = False
 
        self.save()
 

	
 
    def mark_schwag_given(self):
 
        self.schwag_given = True
 
        self.save()
 

	
 
    def bulk_mark_given(self):
 
        self.badge_printed = True
 
        self.checked_in_bool = True
 
        self.schwag_given = True
 
        self.save()
 

	
 
    def set_exception(self, text):
 
        self.needs_review = True
 
        self.review_text = text
 
        self.save()
 

	
 
    @property
 
    def code(self):
 
        return self.checkin_code
 

	
 
    @property
 
    def qrcode(self):
 
        """Returns the QR Code for this checkin's code.
 

	
 
        If this is the first time the QR code has been generated, cache it on the object.
 
        If a code has already been cached, serve that.
 

	
 
        Returns the raw PNG blob, unless b64=True, in which case the return value
 
        is the base64encoded PNG blob."""
 

	
 
        if not self.code:
 
            return None
 
        if not self._checkin_code_png:
 
            qrcode = pyqrcode.create(self.code)
 
            qr_io = BytesIO()
 
            qrcode.png(qr_io, scale=6)
 
            qr_io.seek(0)
 
            self._checkin_code_png = base64.b64encode(qr_io.read()).decode('UTF-8')
 
            self.save()
 

	
 
        return self._checkin_code_png
vendor/regidesk/regidesk/templates/regidesk/boardingpass_overview.html
Show inline comments
...
 
@@ -23,97 +23,98 @@
 
{% endblock %}
 

	
 
{% block header_title %}
 
    <div>
 
        <a type=button" class="btn btn-primary btn-lg" href="{% url 'regidesk:check_in_scanner' %}">Go to scanning page</a>
 
    </div>
 
{% endblock %}
 

	
 
{% block body %}
 

	
 
    <h1>Boarding Pass Overview</h1>
 

	
 
    <form class="form-horizontal" method="post" action="{% url "regidesk:boarding_prepare" %}">
 

	
 
        {% csrf_token %}
 
        <p>
 
            Select one or more attendees (<span class="action-counter">0</span> currently selected)
 
            <br/>
 
            then pick an email template
 
            <select name="template">
 
                <option value="">[blank]</option>
 
                {% for template in templates %}
 
                    <option value="{{ template.pk }}">{{ template.label }}</option>
 
                {% endfor %}
 
            </select>
 
            <br/>
 
            <button id="next-button" type="submit" class="btn btn-primary" disabled>Next <i class="fa fa-chevron-right"></i></button>
 
        </p>
 

	
 
        <table class="table table-striped table-bordered dataTable">
 
            <thead>
 
                <th><input type="checkbox" id="action-toggle"></th>
 
                <th class="toggle">#</th>
 
                <th>Attendee Name</th>
 
                <th>Ticket Type</th>
 
                <th class="toggle">Attendee email</th>
 
                <th class="toggle">Checkin Code</th>
 
                <th>Notified?</th>
 
            </thead>
 

	
 
            <tbody>
 
                {% for attendee in attendees %}
 
                    <tr>
 
                        <td><input class="action-select" type="checkbox" name="_selected_action" value="{{ attendee.pk }}"></td>
 
                        <td>{{ attendee.id }}</td>
 
                        <td>{{ attendee.attendeeprofilebase.attendeeprofile.name }}</td>
 
                        <td>{{ attendee.ticket_type }}</td>
 
                        <td>{{ attendee.user.email }}</td>
 
                        <td><a href="{% url 'regidesk:check_in_user_view' attendee.user.checkin.code %}">{{ attendee.user.checkin.code }}</a></td>
 
                        <td>{% if attendee.user.checkin.code %}
 
                            <a href="{% url 'regidesk:check_in_user_view' attendee.user.checkin.code %}">{{ attendee.user.checkin.code }}</a>{% endif %}</td>
 
                        <td>
 
                            {% if attendee.user.checkin %}
 
                              {% if attendee.user.checkin.boardingpass %}
 
                                Boarding pass sent<br/>
 
                              {% else %}
 
                                Checkin Created
 
                              {% endif %}
 
                            {% else %}
 
                              Pending
 
                            {% endif %}
 
                        </td>
 
                    </tr>
 
                {% endfor %}
 
            </tbody>
 
        </table>
 
    </form>
 
{% endblock %}
 

	
 
{% block extra_script %}
 
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs/jszip-2.5.0/dt-1.10.16/b-1.4.2/b-colvis-1.4.2/b-flash-1.4.2/b-html5-1.4.2/b-print-1.4.2/cr-1.4.1/fc-3.2.3/fh-3.1.3/r-2.2.0/rg-1.0.2/datatables.min.css"/>
 
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/pdfmake.min.js"></script>
 
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/vfs_fonts.js"></script>
 
<script type="text/javascript" src="https://cdn.datatables.net/v/bs/jszip-2.5.0/dt-1.10.16/b-1.4.2/b-colvis-1.4.2/b-html5-1.4.2/b-print-1.4.2/cr-1.4.1/fc-3.2.3/fh-3.1.3/r-2.2.0/rg-1.0.2/datatables.min.js"></script>
 
    <script type="text/javascript">
 
        (function($) {
 
            $.fn.actions = function(opts) {
 
                var options = $.extend({}, $.fn.actions.defaults, opts);
 
                var actionCheckboxes = $(this);
 
                checker = function(checked) {
 
                    $(actionCheckboxes).prop("checked", checked)
 
                        .parent().parent().toggleClass(options.selectedClass, checked);
 
                }
 
                updateCounter = function() {
 
                    var sel = $(actionCheckboxes).filter(":checked").length;
 
                    $(options.counterContainer).html(sel);
 
                    $(options.allToggle).prop("checked", function() {
 
                        if (sel == actionCheckboxes.length) {
 
                            value = true;
 
                        } else {
 
                            value = false;
 
                        }
 
                        return value;
 
                    });
 
                    if (sel == 0) {
 
                        $("#next-button").prop("disabled", true);
 
                    } else {
 
                        $("#next-button").prop("disabled", false);
 
                    }
vendor/regidesk/regidesk/templates/regidesk/ci_overview.html
Show inline comments
 
{% extends "regidesk/base.html" %}
 

	
 

	
 
{% block header_title %}
 
   <h3>Pre-print check</h3>
 
{% endblock %}
 

	
 

	
 
{% block body %}
 
    {% load registrasion_tags %}
 
    {% load lca2018_tags %}
 
    {% items_purchased as purchased %}
 
    {% items_pending as pending %}
 
    {% items_purchased 1 as ticket %}
 
    {% items_purchased 6 as shirts %}
 
    {% total_items_purchased 3 as penguin_dinner_count %}
 
    {% total_items_purchased 4 as speakers_dinner_count %}
 
    {% total_items_purchased 5 as pdns_count %}
 
    {% ticket_type as ticket_type %}
 

	
 
    <div class="panel panel-default">
 
        <div class="panel-heading">Content Check</div>
 
        <div class="panel-body">
 
            <dl class="dl-horizontal">
 
                <dt>Ticket type</dt><dd>{{ ticket_type }}</dd>
 
                <dt>Name</dt><dd>{{ user.attendee.attendeeprofilebase.attendeeprofile.name }}</dd>
 
                <dt>Company</dt><dd>{% if ticket_type == "Student" or ticket_type == "Hobbyist" or "Only" in ticket_type %}{% else %}{{ user.attendee.attendeeprofilebase.attendeeprofile.company }}{% endif %}</dd>
 
                <dt>Free Text 1</dt><dd>{{ user.attendee.attendeeprofilebase.attendeeprofile.free_text_1 }}</dd>
 
                <dt>Free Text 2</dt><dd>{{ user.attendee.attendeeprofilebase.attendeeprofile.free_text_2 }}</dd>
 
                <dt>Penguin Dinner Tickets</dt><dd>{{ penguin_dinner_count }}</dd>
 
                <dt>Spearker Dinner Tickets</dt><dd>{{ speakers_dinner_count }}</dd>
 
                <dt>PDNS Tickets</dt><dd>{{ pdns_count }}</dd>
 
                <dt>Over 18 years</dt><dd>{% if user.attendee.attendeeprofilebase.attendeeprofile.of_legal_age %}yes{% else %}<strong class="red">NO</strong>{% endif %}</dd>
 
                <dt>Username</dt><dd>{{ user.username }}</dd>
 
            </dl>
 
            <table class="table table-striped">
 
                <tr>
 
                    <th>item</th>
 
                    <th>count</th>
 
                </tr>
 
                {% for shirt in shirts%}
 
                    <tr>
 
                        <td>{{ shirt.product }}</td>
 
                        <td>{{ shirt.quantity }}</td>
 
                    </tr>
 
                {% endfor %}
 
            </table>
 
        </div>
 
    </div>
 

	
 
    <div class="panel {% if check_in.checked_in_bool %}panel-danger{% else %}panel-success{% endif %}">
 
        <div class="panel-heading">Check In</div>
 
        <div class="panel-body">
 
            <dl class="dl-horizontal">
 
                <dt>Status</dt><dd>{% if check_in.checked_in_bool %}Checked in{% else %}Not checked in{% endif %}</dd>
 
            </dl>
 
            <blockquote>
 
                <p>If an attendee sees an error with their contents, please instruct them to change their profile and come back before checking them in.</p>
 
                <p>The attendee will be unable to edit their profile after they have been checked in</p>
 
            </blockquote>
 
            <form method="post">
 
                <input type="checkbox" name="checkin" value="checkin" checked hidden>
 
                <input class="btn {% if check_in.badge_printed %}btn-danger{% else %}btn-success{% endif %} pull-right" type="submit" value="Submit">
 
            </form>
 
        </div>
 
    </div>
 

	
 

	
 
    <div class="panel {% if check_in.badge_printed %}panel-danger{% else %}panel-success{% endif %}">
 
        <div class="panel-heading">Badge</div>
 
        <div class="panel-body">
 
            <dl class="dl-horizontal">
 
                <dt>Status</dt><dd>{% if check_in.badge_printed %}Marked{% else %}Not marked{% endif %} as printed</dd>
 
            </dl>
 
            <form method="post">
 
            <form method="post" hidden>
 
                <input type="checkbox" name="badge" value="badge" checked hidden>
 
                <a type="button" class="btn btn-primary" href="badge">Show Badge</a>
 
                <input class="btn {% if check_in.badge_printed %}btn-danger{% else %}btn-success{% endif %} pull-right" type="submit" value="Submit">
 
            </form>
 
            <form method="post">
 
                <input type="checkbox" name="unbadge" value="unbadge" checked hidden>
 
                <input class="btn btn-danger pull-right" type="submit" value="Force Reprint">
 
            </form>
 
        </div>
 
    </div>
 

	
 
    <div class="panel {% if check_in.schwag_given %}panel-danger{% else %}panel-success{% endif %}">
 
        <div class="panel-heading">Schwag</div>
 
        <div class="panel-body">
 
            <dl class="dl-horizontal">
 
                <dt>Status</dt><dd>{% if check_in.schwag_given %}Marked{% else %}Not marked{% endif %} as given</dd>
 
            </dl>
 
            <form method="post">
 
                <input type="checkbox" name="schwag" value="schwag" checked hidden>
 
                <input class="btn {% if check_in.schwag_given %}btn-danger{% else %}btn-success{% endif %} pull-right" type="submit" value="Submit">
 
            </form>
 
        </div>
 
    </div>
 

	
 
    <div class="panel panel-warning">
 
        <div class="panel-heading">Log Exception</div>
 
        <div class="panel-body">
 
            <form method="post">
 
                <textarea class="form-control" rows="3" name="exception">{{ check_in.review_text }}</textarea>
 
                <p class="help-block">Reminder: Please tell attendee to email boarding@lca2018.org with the details as well</p>
 
                <input class="btn btn-warning pull-right" type="submit" value="Submit">
 
            </form>
 
        </div>
 
    </div>
 

	
 
    <div class="panel {% if check_in.badge_printed or check_in.schwag_given %}panel-danger{% else %}panel-success{% endif %}">
 
    <div class="panel {% if check_in.checked_in_bool or check_in.schwag_given %}panel-danger{% else %}panel-success{% endif %}">
 
        <div class="panel-heading">Bulk actions</div>
 
        <div class="panel-body">
 
            <p>Mark attendee as checked in and schwag given</p>
 
            <dl class="dl-horizontal">
 
                <dt>Status</dt><dd>{% if check_in.badge_printed or check_in.schwag_given %}One of the items in bulk action is marked as given already{% else %}Both items are marked as unrecived{% endif %}</dd>
 
                <dt>Status</dt><dd>{% if check_in.checked_in_bool or check_in.schwag_given %}One of the items in bulk action is marked as given already{% else %}Both items are marked as unrecived{% endif %}</dd>
 
            </dl>
 
            <form method="post">
 
                <input type="checkbox" name="bulk" value="bulk" checked hidden>
 
                <input class="btn  {% if check_in.badge_printed or check_in.schwag_given %}btn-danger{% else %}btn-success{% endif %} pull-right" type="submit" value="Submit">
 
                <input class="btn  {% if check_in.checked_in_bool or check_in.schwag_given %}btn-danger{% else %}btn-success{% endif %} pull-right" type="submit" value="Submit">
 
            </form>
 
        </div>
 
    </div>
 
    <a type=button" class="btn btn-primary btn-lg" href="{% url 'regidesk:check_in_scanner' %}">Return to scanning page</a>
 

	
 
{% endblock %}
vendor/regidesk/regidesk/views.py
Show inline comments
...
 
@@ -7,126 +7,129 @@ 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 permission_required, user_passes_test, login_required
 
from django.contrib.auth.mixins import PermissionRequiredMixin
 
from django.contrib.auth.models import User, Group
 
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, HttpResponseBadRequest
 
from django.shortcuts import redirect, render
 
from django.template import Template, Context
 
from django.urls import reverse
 
from django.views.decorators.csrf import csrf_exempt
 
from django.views.generic import TemplateView
 

	
 
from registrasion import util
 
from registrasion.views import render_badge
 
from registrasion.models import commerce, people
 
from registrasion.templatetags.registrasion_tags import items_purchased, items_pending
 
from registrasion.templatetags.registrasion_tags import invoices, missing_categories
 
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
 

	
 
@login_required
 
def boardingpass(request):
 

	
 
    user=request.user
 
    checkin = CheckIn.objects.get_or_create(user=user)[0]
 
    if not checkin.boardingpass:
 
        templates = BoardingPassTemplate.objects.all()
 
        if not templates:
 
            messages.add_message(request, messages.WARNING,
 
                                 'Your boarding pass has not been prepared and I can\'t find a '
 
                                 'default template to use. This page has similar information to '
 
                                 'the boarding pass - please check back later.')
 
            return redirect('/tickets/review')
 
        prepare_boarding_pass(request, templates[0])
 
        prepare_boarding_pass(request.user, templates[0])
 
        checkin = CheckIn.objects.get_or_create(user=user)[0]
 

	
 
    boardingpass = checkin.boardingpass
 
    qrcode_url = request.build_absolute_uri(reverse("regidesk:checkin_png", args=[checkin.code]))
 
    qrcode = checkin.qrcode
 
    qrcode_string ='<img src="data:image/png;base64,' + qrcode + '"/>'
 
    not_qrcode_string = '<img src="cid:qrcode.png"/>'
 

	
 
    boardingpass_body = boardingpass.html_body.replace(not_qrcode_string, qrcode_string)
 
    ctx = { 'attendee': user.attendee,
 
            'boardingpass_body': boardingpass_body,
 
            'boardingpass': boardingpass
 
    }
 

	
 
    response = render(request, "regidesk/boardingpass.html", ctx)
 
    return response
 

	
 

	
 
@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 }
 
    print(datetime.now())
 
    ticketholders = ( ticket.invoice.user for ticket in tickets )
 
    print(datetime.now())
 

	
 
    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)
 

	
 
def checkin_png(request, checkin_code):
 

	
 
    checkin = CheckIn.objects.get(checkin_code=checkin_code)
 
    if not checkin:
 
        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))
...
 
@@ -149,97 +152,97 @@ def boarding_prepare(request):
 
    bp_template_pk = request.POST.get("template", "")
 
    if not bp_template_pk:
 
        messages.warning(request, "Need to choose a template")
 
        return redirect("/checkin/overview")
 

	
 
    bp_template = BoardingPassTemplate.objects.get(pk=bp_template_pk)
 
    if bp_template:
 
        sample_ctx = {
 
            "user": sample_checkin.user,
 
            "boardingpass": sample_checkin.boardingpass,
 
            "code": sample_checkin.code,
 
            "qrcode": '<img src="data:image/png;base64,' + sample_checkin.qrcode + '"/>',
 
            # "qrcode_url": request.build_absolute_uri(
 
            #     reverse("regidesk:checkin_png", args=[sample_checkin.code])),
 
           "qrcode_url": "https://rego.linux.conf.au/checkin/" + sample_checkin.code + ".png"
 
        }
 
        ctx = Context(sample_ctx)
 
        ctx["invoices"] = invoices(ctx)
 
        ctx["items_pending"] = items_pending(ctx)
 
        ctx["items_purchased"] = items_purchased(ctx)
 
        ctx["missing_categories"] = missing_categories(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)
 
        request.session['template'] = bp_template.pk
 
    else:
 
        subject = None
 
        request.session['template'] = 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
 
    return render(request, "regidesk/boardingpass_prepare.html", ctx)
 

	
 
def prepare_boarding_pass(user, template, attendee=None):
 

	
 
    if attendee:
 
        user = attendee.user
 
    else:
 
        user = request.user
 
        user = user
 
        attendee=user.attendee
 
    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])),
 
        "qrcode_url": "https://rego.linux.conf.au/checkin/" + user.checkin.code + ".png"
 
    }
 
    ctx = Context(ctx)
 
    ctx["invoices"] = invoices(ctx)
 
    ctx["items_pending"] = items_pending(ctx)
 
    ctx["items_purchased"] = items_purchased(ctx)
 
    ctx["missing_categories"] = missing_categories(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()
 

	
 
    return bpass
 

	
 
def send_boarding_pass(bpass, user):
 
    msg = EmailMultiAlternatives(
 
        bpass.subject,
 
        bpass.body,
 
        bpass.from_address,
 
        [bpass.to_address,],
 
    )
 
    msg.content_subtype="plain"
 
    msg.mixed_subtype="related"
 
    if bpass.html_body:
...
 
@@ -267,72 +270,74 @@ def boarding_send(request):
 
    logging.debug(len(attendees))
 
    logging.debug(attendees)
 

	
 
    template_pk = request.session['template']
 
    template = BoardingPassTemplate.objects.get(pk=template_pk)
 

	
 
    for attendee in attendees:
 

	
 
        try:
 
            user = attendee.user
 
            bpass = prepare_boarding_pass(user, template, attendee)
 
            if user in boarding_users:
 
                send_boarding_pass(user, bpass)
 
                messages.success(request, "Sent boarding pass to %s" % attendee)
 
        except:
 
            messages.warning(request, "Could not send boarding pass to %s" % attendee)
 

	
 
        request.session['boarding_attendees'].remove(attendee.pk)
 

	
 
    return redirect("regidesk:boarding_overview")
 

	
 

	
 
class CheckInLanding(PermissionRequiredMixin, TemplateView):
 
    template_name = 'regidesk/ci_landing.html'
 
    permission_required = 'regidesk.view_boarding_pass'
 

	
 

	
 
@csrf_exempt
 
@permission_required("regidesk.view_boarding_pass")
 
def check_in_overview(request, access_code):
 
    check_in = CheckIn.objects.filter(
 
        checkin_code=access_code,
 
    )
 
    if not check_in:
 
        # yea it's a 200...
 
        return render(request, "regidesk/ci_code_404.html", {})
 
    check_in = check_in[0]
 
    if request.method == 'POST':
 
        if 'checkin' in request.POST:
 
            check_in.mark_checked_in()
 
        elif 'badge' in request.POST:
 
            check_in.mark_badge_printed()
 
        elif 'schwag' in request.POST:
 
            check_in.mark_schwag_given()
 
        elif 'bulk' in request.POST:
 
            check_in.bulk_mark_given()
 
        elif 'exception' in request.POST:
 
            check_in.set_exception(request.POST['exception'])
 
        elif 'unbadge' in request.POST:
 
            check_in.unset_badge()
 
        return redirect(request.path)
 
    ctx = {
 
        'check_in': check_in,
 
        'user': check_in.user,
 
    }
 
    return render(request, "regidesk/ci_overview.html", ctx)
 

	
 

	
 
@permission_required("regidesk.view_boarding_pass")
 
def checken_in_badge(request, access_code):
 
    check_in = CheckIn.objects.filter(
 
        checkin_code=access_code,
 
    )
 
    if not check_in:
 
        # yea it's a 200...
 
        return render(request, "regidesk/ci_code_404.html", {})
 
    badge = render_badge(check_in[0].user, format="svg", overlay=True)
 
    return badge
 

	
 
@login_required
 
def redir_main(request):
 
    if request.user.has_perm('regidesk.view_boarding_pass'):
 
        return redirect(reverse('regidesk:boarding_overview'))
 
    return redirect(reverse('regidesk:boardingpass'))
0 comments (0 inline, 0 general)