Adding a badge token to tickets that grant that.
This commit is contained in:
parent
04d858adf3
commit
b7feb96c9b
|
@ -298,7 +298,8 @@ class Order(CreatedUpdatedModel):
|
|||
def is_partially_ticket_generated(self):
|
||||
if (
|
||||
self.orderproductrelation_set.filter(ticket_generated=True).count() != 0
|
||||
and self.orderproductrelation_set.filter(ticket_generated=False).count() != 0
|
||||
and self.orderproductrelation_set.filter(ticket_generated=False).count()
|
||||
!= 0
|
||||
):
|
||||
# some products are handed out, others are not
|
||||
return True
|
||||
|
|
|
@ -1,33 +1,29 @@
|
|||
# Generated by Django 2.2.2 on 2019-07-18 18:52
|
||||
import hashlib
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations
|
||||
|
||||
from tickets.models import create_ticket_token
|
||||
|
||||
|
||||
def save_tokens(apps, schema_editor):
|
||||
ShopTicket = apps.get_model('tickets', 'ShopTicket')
|
||||
SponsorTicket = apps.get_model('tickets', 'SponsorTicket')
|
||||
DiscountTicket = apps.get_model('tickets', 'DiscountTicket')
|
||||
ShopTicket = apps.get_model("tickets", "ShopTicket")
|
||||
SponsorTicket = apps.get_model("tickets", "SponsorTicket")
|
||||
DiscountTicket = apps.get_model("tickets", "DiscountTicket")
|
||||
|
||||
for model in (ShopTicket, SponsorTicket, DiscountTicket):
|
||||
|
||||
for ticket in model.objects.all():
|
||||
token = hashlib.sha256(
|
||||
token = create_ticket_token(
|
||||
"{_id}{secret_key}".format(
|
||||
_id=ticket.uuid, secret_key=settings.SECRET_KEY
|
||||
).encode("utf-8")
|
||||
).hexdigest()
|
||||
)
|
||||
ticket.token = token
|
||||
ticket.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tickets', '0006_auto_20190616_1746'),
|
||||
]
|
||||
dependencies = [("tickets", "0006_auto_20190616_1746")]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(save_tokens)
|
||||
]
|
||||
operations = [migrations.RunPython(save_tokens)]
|
||||
|
|
18
src/tickets/migrations/0009_tickettype_includes_badge.py
Normal file
18
src/tickets/migrations/0009_tickettype_includes_badge.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 2.2.3 on 2019-07-23 20:49
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tickets', '0008_auto_20190718_2055'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='tickettype',
|
||||
name='includes_badge',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
28
src/tickets/migrations/0010_auto_20190724_2037.py
Normal file
28
src/tickets/migrations/0010_auto_20190724_2037.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Generated by Django 2.2.3 on 2019-07-24 18:37
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tickets', '0009_tickettype_includes_badge'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='discountticket',
|
||||
name='badge_token',
|
||||
field=models.CharField(max_length=64, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shopticket',
|
||||
name='badge_token',
|
||||
field=models.CharField(max_length=64, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='sponsorticket',
|
||||
name='badge_token',
|
||||
field=models.CharField(max_length=64, null=True),
|
||||
),
|
||||
]
|
29
src/tickets/migrations/0011_save_badge_token_to_db.py
Normal file
29
src/tickets/migrations/0011_save_badge_token_to_db.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Generated by Django 2.2.3 on 2019-07-24 18:37
|
||||
from django.conf import settings
|
||||
from django.db import migrations
|
||||
|
||||
from tickets.models import create_ticket_token
|
||||
|
||||
|
||||
def save_badge_tokens(apps, schema_editor):
|
||||
ShopTicket = apps.get_model("tickets", "ShopTicket")
|
||||
SponsorTicket = apps.get_model("tickets", "SponsorTicket")
|
||||
DiscountTicket = apps.get_model("tickets", "DiscountTicket")
|
||||
|
||||
for model in (ShopTicket, SponsorTicket, DiscountTicket):
|
||||
|
||||
for ticket in model.objects.all():
|
||||
badge_token = create_ticket_token(
|
||||
"{_id}{secret_key}-badge".format(
|
||||
_id=ticket.uuid, secret_key=settings.SECRET_KEY
|
||||
).encode("utf-8")
|
||||
)
|
||||
ticket.badge_token = badge_token
|
||||
ticket.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [("tickets", "0010_auto_20190724_2037")]
|
||||
|
||||
operations = [migrations.RunPython(save_badge_tokens)]
|
28
src/tickets/migrations/0012_auto_20190724_2037.py
Normal file
28
src/tickets/migrations/0012_auto_20190724_2037.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Generated by Django 2.2.3 on 2019-07-24 18:37
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tickets', '0011_save_badge_token_to_db'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='discountticket',
|
||||
name='badge_token',
|
||||
field=models.CharField(max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='shopticket',
|
||||
name='badge_token',
|
||||
field=models.CharField(max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='sponsorticket',
|
||||
name='badge_token',
|
||||
field=models.CharField(max_length=64),
|
||||
),
|
||||
]
|
|
@ -17,16 +17,32 @@ logger = logging.getLogger("bornhack.%s" % __name__)
|
|||
class TicketType(CampRelatedModel, UUIDModel):
|
||||
name = models.TextField()
|
||||
camp = models.ForeignKey("camps.Camp", on_delete=models.PROTECT)
|
||||
includes_badge = models.BooleanField(default=False)
|
||||
|
||||
def __str__(self):
|
||||
return "{} ({})".format(self.name, self.camp.title)
|
||||
|
||||
|
||||
def create_ticket_token(string):
|
||||
return hashlib.sha256(string).hexdigest()
|
||||
|
||||
|
||||
def qr_code_base64(token):
|
||||
qr = qrcode.make(
|
||||
token, version=1, error_correction=qrcode.constants.ERROR_CORRECT_H
|
||||
).resize((250, 250))
|
||||
file_like = io.BytesIO()
|
||||
qr.save(file_like, format="png")
|
||||
qrcode_base64 = base64.b64encode(file_like.getvalue())
|
||||
return qrcode_base64
|
||||
|
||||
|
||||
class BaseTicket(CampRelatedModel, UUIDModel):
|
||||
ticket_type = models.ForeignKey("TicketType", on_delete=models.PROTECT)
|
||||
used = models.BooleanField(default=False)
|
||||
badge_handed_out = models.BooleanField(default=False)
|
||||
token = models.CharField(max_length=64)
|
||||
badge_token = models.CharField(max_length=64)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
@ -37,29 +53,31 @@ class BaseTicket(CampRelatedModel, UUIDModel):
|
|||
|
||||
def save(self, **kwargs):
|
||||
self.token = self._get_token()
|
||||
self.badge_token = self._get_token()
|
||||
super().save(**kwargs)
|
||||
|
||||
def _get_token(self):
|
||||
return hashlib.sha256(
|
||||
return create_ticket_token(
|
||||
"{_id}{secret_key}".format(
|
||||
_id=self.uuid, secret_key=settings.SECRET_KEY
|
||||
).encode("utf-8")
|
||||
).hexdigest()
|
||||
)
|
||||
|
||||
def get_qr_code_base64(self):
|
||||
qr = qrcode.make(
|
||||
self._get_token(),
|
||||
version=1,
|
||||
error_correction=qrcode.constants.ERROR_CORRECT_H,
|
||||
).resize((250, 250))
|
||||
file_like = io.BytesIO()
|
||||
qr.save(file_like, format="png")
|
||||
qrcode_base64 = base64.b64encode(file_like.getvalue())
|
||||
return qrcode_base64
|
||||
def _get_badge_token(self):
|
||||
return create_ticket_token(
|
||||
"{_id}{secret_key}-badge".format(
|
||||
_id=self.uuid, secret_key=settings.SECRET_KEY
|
||||
).encode("utf-8")
|
||||
)
|
||||
|
||||
def get_qr_code_url(self):
|
||||
return "data:image/png;base64,{}".format(
|
||||
self.get_qr_code_base64().decode("utf-8")
|
||||
qr_code_base64(self._get_token()).decode("utf-8")
|
||||
)
|
||||
|
||||
def get_qr_badge_code_url(self):
|
||||
return "data:image/png;base64,{}".format(
|
||||
qr_code_base64(self._get_badge_token()).decode("utf-8")
|
||||
)
|
||||
|
||||
def generate_pdf(self):
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
{% load static from staticfiles %}
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
|
||||
<table style="width:100%;">
|
||||
<tr>
|
||||
<td style="width: 75%;"> </td>
|
||||
|
@ -25,11 +24,38 @@
|
|||
<h3>Sponsor: {{ ticket.sponsor.name }} </h3>
|
||||
<img src="{% static 'img/sponsors/' %}{{ sponsor.logo_filename }}"></img>
|
||||
{% endif %}
|
||||
|
||||
{% if ticket.used %}
|
||||
<h2>This ticket has been used.</h2>
|
||||
{% endif %}
|
||||
|
||||
<center>
|
||||
<img src="{{ ticket.get_qr_code_url }}"></img>
|
||||
<p>Ticket #{{ ticket.pk }}</p>
|
||||
<p>{{ ticket.token }}</p>
|
||||
</center>
|
||||
|
||||
{% if ticket.ticket_type.includes_badge %}
|
||||
<div style="display:block; clear:both; page-break-after:always;"></div>
|
||||
|
||||
<table style="width:100%;">
|
||||
<tr>
|
||||
<td style="width: 75%;"> </td>
|
||||
<td>
|
||||
<h3>
|
||||
{{ ticket.created|date:"b jS, Y" }}<br>
|
||||
</h3>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br />
|
||||
|
||||
<h2>Badge voucher</h2>
|
||||
|
||||
<center>
|
||||
<img src="{{ ticket.get_qr_badge_code_url }}"></img>
|
||||
<p>{{ ticket.badge_token }}</p>
|
||||
</center>
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
|
|
@ -12,7 +12,9 @@ logger = logging.getLogger("bornhack.%s" % __name__)
|
|||
|
||||
|
||||
def generate_pdf_letter(filename, template, formatdict):
|
||||
logger.debug("Generating PDF with filename %s and template %s" % (filename, template))
|
||||
logger.debug(
|
||||
"Generating PDF with filename %s and template %s" % (filename, template)
|
||||
)
|
||||
|
||||
# conjure up a fake request for PDFTemplateResponse
|
||||
request = RequestFactory().get("/")
|
||||
|
@ -47,9 +49,9 @@ def generate_pdf_letter(filename, template, formatdict):
|
|||
|
||||
# add the watermark to all pages
|
||||
for pagenum in range(pdfreader.getNumPages()):
|
||||
page = watermark.getPage(0)
|
||||
page = pdfreader.getPage(pagenum)
|
||||
try:
|
||||
page.mergePage(pdfreader.getPage(pagenum))
|
||||
page.mergePage(watermark.getPage(0))
|
||||
except ValueError:
|
||||
# watermark pdf might be broken?
|
||||
return False
|
||||
|
@ -65,4 +67,3 @@ def generate_pdf_letter(filename, template, formatdict):
|
|||
returnfile = io.BytesIO()
|
||||
finalpdf.write(returnfile)
|
||||
return returnfile
|
||||
|
||||
|
|
Loading…
Reference in a new issue