From 5eedb8ff031d4bc49204f75a08ba36b08d2ab701 Mon Sep 17 00:00:00 2001 From: Stephan Telling Date: Thu, 17 Aug 2017 17:52:22 +0200 Subject: [PATCH] update INSTALLED_APPS. add ticket_type and re-add old Ticket model also updates bootstrap script with ticket_type --- src/bornhack/settings.py | 1 + src/shop/admin.py | 4 +- src/shop/models.py | 86 +++++++++++++++++-- src/shop/pdf.py | 17 ++-- .../management/commands/bootstrap-devsite.py | 3 + 5 files changed, 100 insertions(+), 11 deletions(-) diff --git a/src/bornhack/settings.py b/src/bornhack/settings.py index d8c3e20d..1ea67e0d 100644 --- a/src/bornhack/settings.py +++ b/src/bornhack/settings.py @@ -42,6 +42,7 @@ INSTALLED_APPS = [ 'ircbot', 'teams', 'people', + 'tickets', 'allauth', 'allauth.account', diff --git a/src/shop/admin.py b/src/shop/admin.py index cb68b1f2..56520184 100644 --- a/src/shop/admin.py +++ b/src/shop/admin.py @@ -10,6 +10,7 @@ admin.site.register(models.CoinifyAPIRequest) admin.site.register(models.Invoice) admin.site.register(models.CreditNote) + @admin.register(models.CustomOrder) class CustomOrderAdmin(admin.ModelAdmin): list_display = [ @@ -25,6 +26,7 @@ class CustomOrderAdmin(admin.ModelAdmin): 'paid', ] + @admin.register(models.ProductCategory) class ProductCategoryAdmin(admin.ModelAdmin): list_display = [ @@ -37,6 +39,7 @@ class ProductAdmin(admin.ModelAdmin): list_display = [ 'name', 'category', + 'ticket_type', 'price', 'available_in', ] @@ -115,7 +118,6 @@ class TicketModelAdmin(admin.ModelAdmin): list_filter = ['product', 'checked_in'] - actions = ['mark_as_arrived'] def mark_as_arrived(self, request, queryset): diff --git a/src/shop/models.py b/src/shop/models.py index 65d4ed08..5b314554 100644 --- a/src/shop/models.py +++ b/src/shop/models.py @@ -1,3 +1,9 @@ +import io +import logging +import hashlib +import base64 +import qrcode + from django.conf import settings from django.db import models from django.db.models.aggregates import Sum @@ -7,13 +13,17 @@ from django.utils.text import slugify from django.utils.translation import ugettext_lazy as _ from django.utils import timezone from django.core.urlresolvers import reverse_lazy -from utils.models import UUIDModel, CreatedUpdatedModel -from .managers import ProductQuerySet, OrderQuerySet from decimal import Decimal from datetime import timedelta from unidecode import unidecode from django.utils.dateparse import parse_datetime +from utils.models import UUIDModel, CreatedUpdatedModel +from tickets.models import ShopTicket +from .managers import ProductQuerySet, OrderQuerySet + +logger = logging.getLogger("bornhack.%s" % __name__) + class CustomOrder(CreatedUpdatedModel): text = models.TextField( @@ -74,7 +84,7 @@ class Order(CreatedUpdatedModel): CREDIT_CARD = 'credit_card' BLOCKCHAIN = 'blockchain' BANK_TRANSFER = 'bank_transfer' - CASH = 'cash' + CASH = 'cash' PAYMENT_METHODS = [ CREDIT_CARD, @@ -112,7 +122,6 @@ class Order(CreatedUpdatedModel): blank=True, ) - objects = OrderQuerySet.as_manager() def __str__(self): @@ -173,7 +182,8 @@ class Order(CreatedUpdatedModel): for order_product in self.orderproductrelation_set.all(): if order_product.product.category.name == "Tickets": for _ in range(0, order_product.quantity): - ticket = Ticket( + ticket = ShopTicket( + ticket_type=order_product.product.ticket_type, order=self, product=order_product.product, ) @@ -288,6 +298,12 @@ class Product(CreatedUpdatedModel, UUIDModel): ) ) + ticket_type = models.ForeignKey( + 'tickets.TicketType', + null=True, + blank=True + ) + objects = ProductQuerySet.as_manager() def __str__(self): @@ -451,3 +467,63 @@ class CoinifyAPIRequest(CreatedUpdatedModel): def __str__(self): return 'order %s api request %s' % (self.order.id, self.method) + + +class Ticket(CreatedUpdatedModel, UUIDModel): + order = models.ForeignKey('shop.Order', related_name='tickets') + product = models.ForeignKey('shop.Product', related_name='tickets') + qrcode_base64 = models.TextField(null=True, blank=True) + + name = models.CharField( + max_length=100, + help_text=( + 'Name of the person this ticket belongs to. ' + 'This can be different from the buying user.' + ), + null=True, + blank=True, + ) + + email = models.EmailField( + null=True, + blank=True, + ) + + checked_in = models.BooleanField(default=False) + + def __str__(self): + return 'Ticket {user} {product}'.format( + user=self.order.user, + product=self.product + ) + + def save(self, **kwargs): + super(Ticket, self).save(**kwargs) + self.qrcode_base64 = self.get_qr_code() + super(Ticket, self).save(**kwargs) + + def get_token(self): + return hashlib.sha256( + '{ticket_id}{user_id}{secret_key}'.format( + ticket_id=self.pk, + user_id=self.order.user.pk, + secret_key=settings.SECRET_KEY, + ).encode('utf-8') + ).hexdigest() + + def get_qr_code(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_qr_code_url(self): + return 'data:image/png;base64,{}'.format(self.qrcode_base64) + + def get_absolute_url(self): + return str(reverse_lazy('shop:ticket_detail', kwargs={'pk': self.pk})) diff --git a/src/shop/pdf.py b/src/shop/pdf.py index 32cafc92..1d943d94 100644 --- a/src/shop/pdf.py +++ b/src/shop/pdf.py @@ -1,11 +1,12 @@ +import logging +import io +import os + from django.contrib.auth.models import AnonymousUser from wkhtmltopdf.views import PDFTemplateResponse from PyPDF2 import PdfFileWriter, PdfFileReader from django.test.client import RequestFactory from django.conf import settings -import logging -import io -import os logger = logging.getLogger("bornhack.%s" % __name__) @@ -36,7 +37,14 @@ def generate_pdf_letter(filename, template, formatdict): # get watermark from watermark file watermark = PdfFileReader( - open(os.path.join(settings.STATICFILES_DIRS[0], 'pdf', settings.PDF_LETTERHEAD_FILENAME), 'rb') + open( + os.path.join( + settings.STATICFILES_DIRS[0], + 'pdf', + settings.PDF_LETTERHEAD_FILENAME + ), + 'rb' + ) ) # add the watermark to all pages @@ -60,4 +68,3 @@ def generate_pdf_letter(filename, template, formatdict): returnfile = io.BytesIO() finalpdf.write(returnfile) return returnfile - diff --git a/src/utils/management/commands/bootstrap-devsite.py b/src/utils/management/commands/bootstrap-devsite.py index ed9420a4..dba2109f 100644 --- a/src/utils/management/commands/bootstrap-devsite.py +++ b/src/utils/management/commands/bootstrap-devsite.py @@ -48,6 +48,7 @@ class Command(BaseCommand): timezone.datetime(2016, 9, 4, 12, 0, tzinfo=timezone.utc), timezone.datetime(2016, 9, 6, 12, 0, tzinfo=timezone.utc), ), + colour='#000000', ) camp2017 = Camp.objects.create( @@ -66,6 +67,7 @@ class Command(BaseCommand): timezone.datetime(2017, 9, 4, 12, 0, tzinfo=timezone.utc), timezone.datetime(2017, 9, 6, 12, 0, tzinfo=timezone.utc), ), + colour='#000000', ) camp2018 = Camp.objects.create( @@ -84,6 +86,7 @@ class Command(BaseCommand): timezone.datetime(2018, 9, 4, 12, 0, tzinfo=timezone.utc), timezone.datetime(2018, 9, 6, 12, 0, tzinfo=timezone.utc), ), + colour='#000000', ) self.output("Creating users...")