Skip to content

Commit

Permalink
Fix so that the start_payment correctly associates the tickets with a…
Browse files Browse the repository at this point in the history
… chapter event.

Contains limited functionality that allows foor buying tickets for
several different chapter events at once.
  • Loading branch information
Gabrimari committed Dec 17, 2024
1 parent 3a0ac0f commit fc97f91
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
from datetime import datetime
from django.utils import timezone

from bittan.models import TicketType, ChapterEvent, Payment
from bittan.models import TicketType, ChapterEvent, Ticket, Payment

class StartPaymentTest(TestCase):
def setUp(self):
NOW = timezone.now()
self.test_event = ChapterEvent.objects.create(title="Test Event", description="An event for testing. ", total_seats=10, sales_stop_at=NOW+timezone.timedelta(days=365), event_at=NOW+timezone.timedelta(days=366))
self.test_event = ChapterEvent.objects.create(title="Test Event1", description="An event for testing. ", total_seats=10, sales_stop_at=NOW+timezone.timedelta(days=365), event_at=NOW+timezone.timedelta(days=366))
self.test_event2 = ChapterEvent.objects.create(title="Test Event2", description="An event for testing. ", total_seats=10, sales_stop_at=NOW+timezone.timedelta(days=365), event_at=NOW+timezone.timedelta(days=366), reservation_duration=timezone.timedelta(minutes=30))

self.test_ticket = TicketType.objects.create(price=200, title="Test Ticket", description="A ticket for testing.")
self.test_event.ticket_types.add(self.test_ticket)
Expand All @@ -37,6 +38,26 @@ def setUp(self):
content_type="application/json"
)

# Temporary setup as the reserve_ticket view does not support reserving tickets for several different ChapterEvents at once.
payment_id = self.client.session["reserved_payment"]
payment = Payment.objects.get(pk=payment_id)
second_event_ticket1 = Ticket.objects.create(
external_id = "1234",
time_created = NOW,
payment = payment,
ticket_type = self.test_ticket,
chapter_event = self.test_event2
)
second_event_ticket2 = Ticket.objects.create(
external_id = "1111",
time_created = NOW,
payment = payment,
ticket_type = self.test_ticket2,
chapter_event = self.test_event2
)



def test_start_payment(self):
mail_address = "[email protected]"
response = self.client.post(
Expand Down Expand Up @@ -134,7 +155,7 @@ def test_expired_session_rebook_tickets(self, mock_now):
self.assertEqual(payment.payment_started, True)
self.assertEqual(payment.email, mail_address)
self.assertEqual(payment.status, PaymentStatus.RESERVED)
self.assertEqual(payment.expires_at, now + self.test_event.reservation_duration)
self.assertEqual(payment.expires_at, now + self.test_event2.reservation_duration)

def test_double_payment(self):
mail_address = "[email protected]"
Expand Down
35 changes: 21 additions & 14 deletions backend/bittan/bittan/views/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from bittan.models.payment import PaymentStatus
from bittan.services.swish.swish_payment_request import SwishPaymentRequest, PaymentStatus as SwishPaymentStatus

from ..models import ChapterEvent, Ticket, TicketType, Payment
from bittan.models import ChapterEvent, Ticket, TicketType, Payment

from bittan.services.swish.swish import Swish

Expand All @@ -13,7 +13,7 @@

import random

from django.db import models
from django.db.models import Count, Min
from django.utils import timezone
from django.db.utils import IntegrityError
from django.db.models import Sum
Expand Down Expand Up @@ -91,7 +91,8 @@ def reserve_ticket(request: Request) -> Response:
external_id=''.join(random.choice("ABCDEFGHIJKLMNOPQRSTUVWXYZ") for _ in range(6)),
time_created=timezone.now(),
payment=payment,
ticket_type=ticket_type
ticket_type=ticket_type,
chapter_event=chapter_event
)
except IntegrityError as e:
continue
Expand All @@ -110,6 +111,7 @@ class StartPaymentRequestSerializer(serializers.Serializer):
@api_view(['POST'])
def start_payment(request):
response_data: dict


valid_ser = StartPaymentRequestSerializer(data=request.data)
if valid_ser.is_valid():
Expand All @@ -135,20 +137,24 @@ def start_payment(request):
status=status.HTTP_403_FORBIDDEN
)

tickets = payment.ticket_set

# Gets the chapter event from the users ticket.
chapter_event = tickets.first().ticket_type.chapterevent_set.first()
tickets = payment.ticket_set.all()

# This handles if session expires before payment starts and should be compatible with
# functionality that allows for buying tickets to several different ChapterEvents at once.
grouped_tickets = tickets.values_list("chapter_event", "chapter_event__total_seats").annotate(count=Count("chapter_event__pk"))
if payment.status != PaymentStatus.RESERVED:
if tickets.count() > chapter_event.total_seats - chapter_event.alive_ticket_count:
payment.status = PaymentStatus.FAILED_EXPIRED_RESERVATION
return Response(
"SessionExpired",
status=status.HTTP_408_REQUEST_TIMEOUT
)
payment.expires_at = timezone.now() + chapter_event.reservation_duration
for chapter_event, total_seats, count in grouped_tickets:
chapter_event = ChapterEvent.objects.get(pk=chapter_event)
if count > total_seats - chapter_event.alive_ticket_count:
payment.status = PaymentStatus.FAILED_EXPIRED_RESERVATION
return Response(
"SessionExpired",
status=status.HTTP_408_REQUEST_TIMEOUT
)
payment.expires_at = timezone.now() + grouped_tickets.aggregate(Min("chapter_event__reservation_duration"))["chapter_event__reservation_duration__min"]
payment.status = PaymentStatus.RESERVED
payment.save()

payment.payment_started = True
payment.save()
Expand All @@ -159,7 +165,8 @@ def start_payment(request):

swish = Swish.get_instance() # Detta hämtar swish instansen som är global över hela bittan. I den här kan saker anropas.

payment_request: SwishPaymentRequest = swish.create_swish_payment(total_price, chapter_event.swish_message)
#payment_request: SwishPaymentRequest = swish.create_swish_payment(total_price, chapter_event.swish_message)
payment_request: SwishPaymentRequest = swish.create_swish_payment(total_price, "Test message")

if payment_request.is_failed():
payment.PaymentStatus = PaymentStatus.FAILED_EXPIRED_RESERVATION
Expand Down

0 comments on commit fc97f91

Please sign in to comment.