Coverage for donation\views.py: 91%

80 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-06-20 12:38 +0100

1import os 

2from itertools import cycle 

3 

4from django.conf import settings 

5from django.contrib import messages 

6from django.contrib.auth.decorators import login_required 

7from django.contrib.auth.mixins import UserPassesTestMixin 

8from django.contrib.auth.models import User 

9from django.core.paginator import Paginator 

10from django.db.models import Sum, Value 

11from django.db.models.functions import Coalesce 

12from django.shortcuts import render, get_object_or_404, redirect 

13from django.views import View 

14 

15from donate.models import Payment 

16from donation.forms import DonationForm 

17from donation.models import Donation 

18 

19 

20def raised(donation): 

21 return (Payment.objects.filter(donation=donation) 

22 .aggregate(Sum('stripe_payment__amount')) 

23 ['stripe_payment__amount__sum'] or 0) 

24 

25 

26def donations(request): 

27 IMAGE_DIR = 'static/images/causes' 

28 image_cycle = cycle(os.listdir(IMAGE_DIR)) 

29 donations = Donation.objects.all() 

30 for donation in donations: 

31 donation.image = IMAGE_DIR + '/' + next(image_cycle) 

32 donation.raised = raised(donation) 

33 donation.percentage = donation.raised / donation.goal * 100 

34 

35 context = { 

36 'donations': sorted(donations, key=lambda d: d.raised - d.goal) 

37 } 

38 return render(request, 'donation/donations.html', context) 

39 

40 

41@login_required 

42def redirect_to_donate(request, donation_id): 

43 if request.user.is_superuser: 

44 return redirect('donations') 

45 

46 donations = Donation.objects.all() 

47 for donation in donations: 

48 donation.raised = raised(donation) 

49 

50 context = { 

51 'donation_id': donation_id, 

52 'donations': [donation for donation in donations if 

53 donation.raised < donation.goal], 

54 'stripe_public_key': settings.STRIPE_PK 

55 } 

56 return render(request, 'donate/donate.html', context) 

57 

58 

59def history(request): 

60 donors = (User.objects.annotate( 

61 amount=Coalesce(Sum('payment__stripe_payment__amount'), Value(0))) 

62 .values('username', 'amount') 

63 .order_by('-amount')) 

64 

65 total_donation = sum(donor['amount'] for donor in donors) 

66 

67 payments_list = Payment.objects.all().values( 

68 'id', 

69 'user__username', 

70 'donation__title', 

71 'stripe_payment__amount', 

72 'stripe_payment__timestamp', 

73 'stripe_payment__stripe_charge_id' 

74 ).order_by('-stripe_payment__timestamp') 

75 

76 paginator = Paginator(payments_list, 12) 

77 

78 page_number = request.GET.get('page') 

79 payments = paginator.get_page(page_number) 

80 

81 context = { 

82 'payments': payments, 

83 'donors': donors, 

84 'total_donation': total_donation, 

85 } 

86 return render(request, 'donation/history.html', context) 

87 

88 

89class AdminRequiredMixin(UserPassesTestMixin): 

90 def test_func(self): 

91 return self.request.user.is_superuser 

92 

93 def handle_no_permission(self): 

94 messages.error(self.request, 

95 'You are not allowed to access to this page') 

96 return redirect('donations') 

97 

98 

99class DonationCard(AdminRequiredMixin, View): 

100 def get(self, request, donation_id=-1): 

101 if donation_id < 0: 

102 return render(request, 'donation/form.html') 

103 

104 return render(request, 'donation/form.html', 

105 {'donation': Donation.objects.get(id=donation_id)}) 

106 

107 def post(self, request, donation_id=-1): 

108 if donation_id < 0: 

109 donation_form = DonationForm(request.POST) 

110 if donation_form.is_valid(): 

111 title = donation_form.cleaned_data.get('title', '') 

112 message = f'Donation {title.capitalize()} created successfully' 

113 donation_form.save() 

114 messages.success(request, message) 

115 return redirect('donations') 

116 

117 donation = get_object_or_404(Donation, id=donation_id) 

118 donation_form = DonationForm(request.POST, instance=donation) 

119 if donation_form.is_valid(): 

120 title = donation_form.cleaned_data.get('title', '') 

121 message = f'Donation {title.capitalize()} updated successfully' 

122 donation_form.save() 

123 messages.success(request, message) 

124 return redirect('donations') 

125 

126 messages.error(request, donation_form.errors) 

127 

128 

129def delete_donation(request, donation_id): 

130 donation = get_object_or_404(Donation, id=donation_id) 

131 donation.delete() 

132 message = f'Donation {donation.title.capitalize()} deleted successfully' 

133 messages.success(request, message) 

134 return redirect('donations')