Added helper functions to checkin (admin only)
This commit is contained in:
parent
a811965504
commit
3c4d31e1b9
|
@ -0,0 +1,72 @@
|
||||||
|
from sanic.response import html, redirect, text
|
||||||
|
from sanic import Blueprint, exceptions, response
|
||||||
|
from random import choice
|
||||||
|
from ext import *
|
||||||
|
from config import headers, base_url
|
||||||
|
from PIL import Image
|
||||||
|
from os.path import isfile
|
||||||
|
from os import unlink
|
||||||
|
from io import BytesIO
|
||||||
|
from hashlib import sha224
|
||||||
|
from time import time
|
||||||
|
from urllib.parse import unquote
|
||||||
|
import json
|
||||||
|
|
||||||
|
bp = Blueprint("checkin", url_prefix="/checkin")
|
||||||
|
|
||||||
|
@bp.get("/")
|
||||||
|
async def redirect_start(request):
|
||||||
|
return response.redirect("start")
|
||||||
|
|
||||||
|
@bp.get("/start")
|
||||||
|
async def start_checkin(request):
|
||||||
|
orders = request.app.ctx.om.cache.values()
|
||||||
|
tpl = request.app.ctx.tpl.get_template('checkin_1.html')
|
||||||
|
return html(tpl.render(orders=orders))
|
||||||
|
|
||||||
|
@bp.get("/order")
|
||||||
|
async def show_order(request):
|
||||||
|
|
||||||
|
max_id = 0
|
||||||
|
for o in request.app.ctx.om.cache.values():
|
||||||
|
if not o.badge_id: continue
|
||||||
|
max_id = max(o.badge_id, max_id)
|
||||||
|
|
||||||
|
order = await request.app.ctx.om.get_order(code=request.args.get('order'))
|
||||||
|
|
||||||
|
if order.room_id == order.code:
|
||||||
|
room_owner = order
|
||||||
|
else:
|
||||||
|
room_owner = await request.app.ctx.om.get_order(code=order.room_id)
|
||||||
|
|
||||||
|
tpl = request.app.ctx.tpl.get_template('checkin_2.html')
|
||||||
|
return html(tpl.render(order=order, room_owner=room_owner, max_id=max_id))
|
||||||
|
|
||||||
|
@bp.post("/checkin")
|
||||||
|
async def do_checkin(request):
|
||||||
|
|
||||||
|
# Update room info
|
||||||
|
order = await request.app.ctx.om.get_order(code=request.form.get('code'))
|
||||||
|
if order.room_id == order.code:
|
||||||
|
room_owner = order
|
||||||
|
await order.edit_answer('actual_room', request.form.get('actual_room'))
|
||||||
|
else:
|
||||||
|
room_owner = await request.app.ctx.om.get_order(code=order.room_id)
|
||||||
|
await room_owner.edit_answer('actual_room', request.form.get('actual_room'))
|
||||||
|
await room_owner.send_answers()
|
||||||
|
|
||||||
|
roommates = [await request.app.ctx.om.get_order(code=code, cached=True) for code in room_owner.room_members]
|
||||||
|
|
||||||
|
# Update nfc and badge id
|
||||||
|
await order.edit_answer('nfc_id', request.form.get('nfc_id'))
|
||||||
|
await order.edit_answer('badge_id', request.form.get('badge_id'))
|
||||||
|
await order.send_answers()
|
||||||
|
|
||||||
|
if not order.checked_in:
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
|
res = await client.post(base_url.replace('events/beyond/', 'checkinrpc/redeem/'), json={'secret': order.barcode, 'source_type': 'barcode', 'type': 'entry', 'lists': [3,]}, headers=headers)
|
||||||
|
|
||||||
|
tpl = request.app.ctx.tpl.get_template('checkin_3.html')
|
||||||
|
return html(tpl.render(order=order, room_owner=room_owner, roommates=roommates))
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block main %}
|
||||||
|
<main class="container">
|
||||||
|
<h1>Cerca ordine</h1>
|
||||||
|
<input id="search" type="text" onchange="updateSearch();" onclick="this.value = '';" />
|
||||||
|
<form method="get" id="actionform" style="font-family:monospace;" action="order">
|
||||||
|
<select id="badgelist" name="order" id="order" multiple>
|
||||||
|
{% for o in orders %}
|
||||||
|
<option value="{{o.code}}" data-nfc="{{o.nfc_id}}" data-secret="{{o.secret}}" style="">{{o.code}} · {{o.nfc_id or (' '*14)|safe}} · {{o.name}} ({{o.first_name}} {{o.last_name}})</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<input type="submit" value="Search" />
|
||||||
|
</form>
|
||||||
|
<script type="text/javascript">
|
||||||
|
function filterOptions(textInputId, optionInputId) {
|
||||||
|
const textInput = document.getElementById(textInputId);
|
||||||
|
const optionInput = document.getElementById(optionInputId);
|
||||||
|
|
||||||
|
textInput.addEventListener('input', () => {
|
||||||
|
const searchText = textInput.value.toLowerCase();
|
||||||
|
const options = optionInput.getElementsByTagName('option');
|
||||||
|
|
||||||
|
let visible = 0;
|
||||||
|
let last_visible;
|
||||||
|
|
||||||
|
for (let i = 0; i < options.length; i++) {
|
||||||
|
const optionText = options[i].textContent.toLowerCase();
|
||||||
|
if (!searchText||optionText.includes(searchText)||options[i].getAttribute('data-secret').includes(searchText)) {
|
||||||
|
options[i].style.display = '';
|
||||||
|
last_visible = options[i]
|
||||||
|
visible++;
|
||||||
|
} else {
|
||||||
|
options[i].style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(visible == 1) {
|
||||||
|
last_visible.selected = 'selected';
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
filterOptions('search', 'badgelist');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</main>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,56 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block main %}
|
||||||
|
<main class="container">
|
||||||
|
<h1><kbd>{{order.code}}</kbd> {{order.name}} ({{order.first_name}} {{order.last_name}})</h1>
|
||||||
|
<p><strong>Commento:</strong> {{order.comment or '--'}}<br />
|
||||||
|
<strong>Note ordine:</strong> {{order.notes or '--'}}<br />
|
||||||
|
<strong>Stato ordine: <span style="color: {{'#900' if order.status == 'unpaid' else '#090'}}">{{order.status}}</span></strong><br />
|
||||||
|
<strong>Sponsor: <span style="color: {{'#fa0' if order.sponsorship == 'super' else ('#e8e' if order.sponsorship else 'initial')}}">{{order.sponsorship}}</span></strong><br />
|
||||||
|
<strong>Compagni di stanza:</strong> {% for code in room_owner.room_members %}<kbd><a href="order?order={{code}}">{{code}}</a></kbd> {% endfor %}<br />
|
||||||
|
<a target="_blank" href="https://reg.furizon.net/control/event/furizon/beyond/orders/{{order.code}}/">Apri su pretix</a><br /></p>
|
||||||
|
<form method="post" id="actionform" action="checkin">
|
||||||
|
<input type="hidden" value="{{order.code}}" name="code" />
|
||||||
|
<label for="actual_room">Numero Stanza Reale</label>
|
||||||
|
<input type="text" value="{{room_owner.actual_room or ''}}" name="actual_room" required />
|
||||||
|
<label for="nfc_id">NFC Badge</label>
|
||||||
|
<input type="text" value="{{order.nfc_id or ''}}" name="nfc_id" pattern="[A-F0-9]{14}" title="NFC Tag id must be 14 chars" required />
|
||||||
|
<label for="badge_id">Badge ID</label>
|
||||||
|
<input type="text" value="{{order.badge_id or (max_id+1)}}" name="badge_id" required />
|
||||||
|
<input type="submit" value="Checkin!" />
|
||||||
|
</form>
|
||||||
|
<script type="text/javascript">
|
||||||
|
function filterOptions(textInputId, optionInputId) {
|
||||||
|
const textInput = document.getElementById(textInputId);
|
||||||
|
const optionInput = document.getElementById(optionInputId);
|
||||||
|
|
||||||
|
textInput.addEventListener('input', () => {
|
||||||
|
const searchText = textInput.value.toLowerCase();
|
||||||
|
const options = optionInput.getElementsByTagName('option');
|
||||||
|
|
||||||
|
let visible = 0;
|
||||||
|
let last_visible;
|
||||||
|
|
||||||
|
for (let i = 0; i < options.length; i++) {
|
||||||
|
const optionText = options[i].textContent.toLowerCase();
|
||||||
|
if (!searchText||optionText.includes(searchText)||options[i].getAttribute('data-secret').includes(searchText)) {
|
||||||
|
options[i].style.display = '';
|
||||||
|
last_visible = options[i]
|
||||||
|
visible++;
|
||||||
|
} else {
|
||||||
|
options[i].style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(visible == 1) {
|
||||||
|
last_visible.selected = 'selected';
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
filterOptions('search', 'badgelist');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</main>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,19 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block main %}
|
||||||
|
<main class="container">
|
||||||
|
<h1>✅ Checkin effettuato!</h1>
|
||||||
|
<p><strong>Ricorda di apporre il numero sul badge! Numero: {{order.badge_id}}</strong></p>
|
||||||
|
|
||||||
|
<h2>Altri membri della stessa stanza ({{room_owner.actual_room}})</h2>
|
||||||
|
<table>
|
||||||
|
{% for o in roommates %}
|
||||||
|
<tr>
|
||||||
|
<td><a href="order?order={{o.code}}">{{o.code}}</a></td>
|
||||||
|
<td>{{o.name}}</td>
|
||||||
|
<td><a href="order?order={{o.code}}">{{'Effettua Checkin' if not o.checked_in else '✅'}}</a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
<h3><a href="start">Effettua un altro checkin ➡️</a></h3>
|
||||||
|
</main>
|
||||||
|
{% endblock %}
|
Loading…
Reference in New Issue