Coverage for website/pizzas/views.py: 14.29%

82 statements  

« prev     ^ index     » next       coverage.py v7.6.7, created at 2025-08-14 10:31 +0000

1from django.contrib import messages 

2from django.contrib.auth.decorators import login_required 

3from django.http import Http404 

4from django.shortcuts import get_object_or_404, redirect, render 

5from django.utils import timezone 

6from django.utils.translation import gettext_lazy as _ 

7from django.views.decorators.http import require_http_methods 

8 

9from payments.exceptions import PaymentError 

10from payments.services import delete_payment 

11 

12from .models import FoodEvent, FoodOrder, Product 

13 

14 

15@login_required 

16def index(request): 

17 """Overview of user order for a pizza event.""" 

18 products = Product.available_products.order_by("name") 

19 if not request.user.has_perm("pizzas.order_restricted_products"): 

20 products = products.exclude(restricted=True) 

21 event = FoodEvent.current() 

22 try: 

23 obj = FoodOrder.objects.get(food_event=event, member=request.member) 

24 except FoodOrder.DoesNotExist: 

25 obj = None 

26 

27 registrated_required = ( 

28 event is not None 

29 and event.event is not None 

30 and event.event.registration_required 

31 ) 

32 not_registered = False 

33 if registrated_required: 

34 registration = event.event.registrations.filter( 

35 member=request.member, date_cancelled=None 

36 ).first() 

37 

38 if registration is None or not registration.is_invited: 

39 not_registered = True 

40 

41 context = { 

42 "event": event, 

43 "products": products, 

44 "order": obj, 

45 "not_registered": not_registered, 

46 } 

47 return render(request, "pizzas/index.html", context) 

48 

49 

50@require_http_methods(["POST"]) 

51def cancel_order(request): 

52 """View that cancels a user's order.""" 

53 if "order" in request.POST: 

54 try: 

55 order = get_object_or_404(FoodOrder, pk=int(request.POST["order"])) 

56 if not order.can_be_changed: 

57 messages.error(request, _("You can no longer cancel.")) 

58 elif order.member == request.member: 

59 try: 

60 order.delete() 

61 messages.success(request, _("Your order has been cancelled.")) 

62 except PaymentError as e: 

63 messages.error(request, str(e)) 

64 except Http404: 

65 messages.error(request, _("Your order could not be found.")) 

66 return redirect("pizzas:index") 

67 

68 

69@login_required 

70def place_order(request): 

71 """View that shows the detail of the current order.""" 

72 event = FoodEvent.current() 

73 

74 if not event: 

75 return redirect("pizzas:index") 

76 

77 if event.start > timezone.now(): 

78 return redirect("pizzas:index") 

79 

80 if event.has_ended: 

81 return redirect("pizzas:index") 

82 

83 if event.event.registration_required: 

84 registration = event.event.registrations.filter( 

85 member=request.member, date_cancelled=None 

86 ).first() 

87 if registration is None or not registration.is_invited: 

88 return redirect("pizzas:index") 

89 

90 try: 

91 obj = FoodOrder.objects.get(food_event=event, member=request.member) 

92 current_order_locked = not obj.can_be_changed 

93 except FoodOrder.DoesNotExist: 

94 obj = None 

95 current_order_locked = False 

96 

97 if "product" in request.POST and not current_order_locked: 

98 productset = Product.available_products.all() 

99 if not request.user.has_perm("pizzas.order_restricted_products"): 

100 productset = productset.exclude(restricted=True) 

101 try: 

102 product = productset.get(pk=int(request.POST["product"])) 

103 except Product.DoesNotExist as e: 

104 raise Http404("Pizza does not exist") from e 

105 if not obj: 

106 obj = FoodOrder(food_event=event, member=request.member) 

107 obj.product = product 

108 if obj.payment: 

109 try: 

110 delete_payment(obj, member=request.member, ignore_change_window=True) 

111 except PaymentError: 

112 messages.error( 

113 request, 

114 _("Your order could not be updated because it was already paid."), 

115 ) 

116 return redirect("pizzas:index") 

117 obj.save() 

118 return redirect("pizzas:index")