diff --git a/stregsystem.log b/stregsystem.log new file mode 100644 index 00000000..e69de29b diff --git a/stregsystem/admin.py b/stregsystem/admin.py index 36348820..901ece63 100644 --- a/stregsystem/admin.py +++ b/stregsystem/admin.py @@ -14,6 +14,7 @@ Room, Sale, MobilePayment, + Event, NamedProduct, ) from stregsystem.templatetags.stregsystem_extras import money @@ -341,6 +342,18 @@ def has_delete_permission(self, request, obj=None): return False +class EventEntryAdmin(admin.ModelAdmin): + search_fields = ('name', 'id') + list_display = ( + 'activated', + 'id', + 'name', + ) + + def activated(self, event): + return event.is_active() + + admin.site.register(LogEntry, LogEntryAdmin) admin.site.register(Sale, SaleAdmin) admin.site.register(Member, MemberAdmin) @@ -351,3 +364,4 @@ def has_delete_permission(self, request, obj=None): admin.site.register(Category, CategoryAdmin) admin.site.register(Room) admin.site.register(MobilePayment, MobilePaymentAdmin) +admin.site.register(Event, EventEntryAdmin) diff --git a/stregsystem/migrations/0016_event.py b/stregsystem/migrations/0016_event.py new file mode 100644 index 00000000..7b4e18e4 --- /dev/null +++ b/stregsystem/migrations/0016_event.py @@ -0,0 +1,26 @@ +# Generated by Django 2.2.24 on 2022-04-12 17:47 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('stregsystem', '0015_product_caffeine_content_mg'), + ] + + operations = [ + migrations.CreateModel( + name='Event', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=32)), + ('active', models.BooleanField()), + ('time', models.DateTimeField()), + ('ticket_start_threshold', models.DateTimeField()), + ('ticket_end_threshold', models.DateTimeField()), + ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='stregsystem.Product')), + ], + ), + ] diff --git a/stregsystem/models.py b/stregsystem/models.py index afc9d428..b6d9835e 100644 --- a/stregsystem/models.py +++ b/stregsystem/models.py @@ -617,6 +617,22 @@ def __str__(self): return self.product.name + ": " + money(self.price) + " (" + str(self.changed_on) + ")" +# A model to link certain products to events, to facilitate showing of active tickets +class Event(models.Model): + name = models.CharField(max_length=32) + active = models.BooleanField() + product = models.ForeignKey(Product, on_delete=models.CASCADE) + time = models.DateTimeField(null=False, blank=False) + ticket_start_threshold = models.DateTimeField(null=False, blank=False) + ticket_end_threshold = models.DateTimeField(null=False, blank=False) + + def is_active(self): + is_after_start = self.ticket_start_threshold <= timezone.now() + is_before_end = self.ticket_end_threshold >= timezone.now() + + return self.active and is_after_start and is_before_end + + class Sale(models.Model): member = models.ForeignKey(Member, on_delete=models.CASCADE) product = models.ForeignKey(Product, on_delete=models.CASCADE) diff --git a/stregsystem/templates/stregsystem/menu.html b/stregsystem/templates/stregsystem/menu.html index a534f418..8180199e 100644 --- a/stregsystem/templates/stregsystem/menu.html +++ b/stregsystem/templates/stregsystem/menu.html @@ -25,6 +25,9 @@ Indsæt penge + + + Mine billetter Rangliste diff --git a/stregsystem/templates/stregsystem/menu_ticketsview.html b/stregsystem/templates/stregsystem/menu_ticketsview.html new file mode 100644 index 00000000..6d513caf --- /dev/null +++ b/stregsystem/templates/stregsystem/menu_ticketsview.html @@ -0,0 +1,34 @@ +{% extends "stregsystem/base.html" %} + +{% load stregsystem_extras %} + +{% block title %}Treoens stregsystem : Brugerinfo {% endblock %} + +{% block content %} +

{{member.firstname}} {{member.lastname}} ({{member.email}})

+ +

Tilbage til produktmenu

+ +
+Aktive billeter + + + + + + + +{% autoescape off %} +{% for event in bought_events_list %} + + + + + + +{% endfor %} +{% endautoescape %} +
EventProduktPrisStart Tidspunkt
{{event.name}}{{event.product.name}}{{event.product.price|money}}{{event.time}}
+
+ +{% endblock %} \ No newline at end of file diff --git a/stregsystem/templates/stregsystem/menu_userinfo.html b/stregsystem/templates/stregsystem/menu_userinfo.html index bca4c060..64cf56f6 100644 --- a/stregsystem/templates/stregsystem/menu_userinfo.html +++ b/stregsystem/templates/stregsystem/menu_userinfo.html @@ -90,5 +90,6 @@ + {% endblock %} diff --git a/stregsystem/tests.py b/stregsystem/tests.py index 80bb4447..9a625b5c 100644 --- a/stregsystem/tests.py +++ b/stregsystem/tests.py @@ -852,6 +852,100 @@ def test_is_active_deactive_in_stock(self): self.assertFalse(product.is_active()) +class EventTests(TestCase): + def setUp(self): + self.jeff = Member.objects.create( + username="Jeff", + ) + + def test_is_active_active_not_expired(self): + product = Product.objects.create( + active=True, + price=100, + ) + event = Event.objects.create( + name="testEvent", + active=True, + product=product, + time=timezone.now() + datetime.timedelta(hours=1), + ticket_start_threshold=timezone.now() - datetime.timedelta(hours=1), + ticket_end_threshold=timezone.now() + datetime.timedelta(hours=1), + ) + + self.assertTrue(event.is_active()) + + def test_is_active_active_expired_after(self): + product = Product.objects.create( + active=True, + price=100, + ) + event = Event.objects.create( + name="testEvent", + active=True, + product=product, + time=timezone.now() + datetime.timedelta(hours=1), + ticket_start_threshold=timezone.now() - datetime.timedelta(hours=10), + ticket_end_threshold=timezone.now() - datetime.timedelta(hours=1), + ) + + self.assertFalse(event.is_active()) + + def test_is_active_active_before_active(self): + product = Product.objects.create( + active=True, + price=100, + ) + event = Event.objects.create( + name="testEvent", + active=True, + product=product, + time=timezone.now() + datetime.timedelta(hours=1), + ticket_start_threshold=timezone.now() + datetime.timedelta(hours=2), + ticket_end_threshold=timezone.now() + datetime.timedelta(hours=5), + ) + + self.assertFalse(event.is_active()) + + def test_is_active_inactive(self): + product = Product.objects.create( + active=True, + price=100, + ) + event = Event.objects.create( + name="testEvent", + active=False, + product=product, + time=timezone.now() + datetime.timedelta(hours=1), + ticket_start_threshold=timezone.now() - datetime.timedelta(hours=10), + ticket_end_threshold=timezone.now() - datetime.timedelta(hours=1), + ) + + self.assertFalse(event.is_active()) + + def test_is_active_inactive_expired(self): + product = Product.objects.create( + active=False, price=100, deactivate_date=(timezone.now() - datetime.timedelta(hours=1)) + ) + + self.assertFalse(product.is_active()) + + def test_is_active_deactive_out_of_stock(self): + product = Product.objects.create( + active=False, price=100, quantity=1, start_date=datetime.date(year=2017, month=12, day=1) + ) + product.sale_set.create(price=100, member=self.jeff) + + self.assertFalse(product.is_active()) + + def test_is_active_deactive_in_stock(self): + product = Product.objects.create( + active=False, price=100, quantity=2, start_date=datetime.date(year=2017, month=12, day=1) + ) + product.sale_set.create(price=100, member=self.jeff) + + self.assertFalse(product.is_active()) + + class SaleTests(TestCase): def setUp(self): self.member = Member.objects.create(username="jon", balance=100) diff --git a/stregsystem/urls.py b/stregsystem/urls.py index 382e3254..b9740913 100644 --- a/stregsystem/urls.py +++ b/stregsystem/urls.py @@ -28,6 +28,7 @@ re_path(r'^(?P\d+)/sale/\d+/\d+/$', lambda request, room_id: redirect('menu_index', room_id=room_id), name="menu_sale"), re_path(r'^(?P\d+)/user/(?P\d+)/$', views.menu_userinfo, name="userinfo"), re_path(r'^(?P\d+)/user/(?P\d+)/pay$', views.menu_userpay, name="userpay"), + re_path(r'^(?P\d+)/user/(?P\d+)/tickets$', views.menu_ticketsview, name="usertickets"), re_path(r'^(?P\d+)/user/(?P\d+)/rank$', views.menu_userrank, name="userrank"), re_path(r'^api/member/payment/qr$', views.qr_payment, name="payment_qr"), re_path(r'^api/member/active$', views.check_user_active, name="active_member"), diff --git a/stregsystem/views.py b/stregsystem/views.py index e066b8ca..304defaa 100644 --- a/stregsystem/views.py +++ b/stregsystem/views.py @@ -33,6 +33,7 @@ Product, Room, Sale, + Event, StregForbudError, MobilePayment, Category, @@ -242,6 +243,15 @@ def menu_userinfo(request, room_id, member_id): return render(request, 'stregsystem/menu_userinfo.html', locals()) +# Used to see active tickets +def menu_ticketsview(request, room_id, member_id): + room = Room.objects.get(pk=room_id) + member = Member.objects.get(pk=member_id, active=True) + bought_events_list = Event.objects.filter(product__in=member.sale_set.values('product')) + + return render(request, 'stregsystem/menu_ticketsview.html', locals()) + + def menu_userpay(request, room_id, member_id): room = Room.objects.get(pk=room_id) member = Member.objects.get(pk=member_id, active=True)