Add schedule filter: crisis.
[wolnelektury.git] / src / club / admin.py
1 # This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
3 #
4 import json
5 from django.contrib import admin
6 from django.db.models.functions import Now
7 from django.db.models import Q
8 from django import forms
9 from django.utils.html import conditional_escape
10 from django.utils.safestring import mark_safe
11 from fnpdjango.actions import export_as_csv_action
12 from modeltranslation.admin import TranslationAdmin
13 import annoy.models
14 from wolnelektury.utils import YesNoFilter
15 from . import models
16
17
18 class SingleAmountInline(admin.TabularInline):
19     model = models.SingleAmount
20
21
22 class MonthlyAmountInline(admin.TabularInline):
23     model = models.MonthlyAmount
24
25
26 @admin.register(models.Club)
27 class ClubAdmin(admin.ModelAdmin):
28     inlines = [
29         SingleAmountInline,
30         MonthlyAmountInline
31     ]
32
33
34 class PayUOrderInline(admin.TabularInline):
35     model = models.PayUOrder
36     fields = ['order_id', 'status', 'customer_ip']
37     readonly_fields = fields
38     extra = 0
39     show_change_link = True
40     can_delete = False
41
42     def has_add_permission(self, request, obj):
43         return False
44
45
46 class PayUCardTokenInline(admin.TabularInline):
47     model = models.PayUCardToken
48     fields = ['created_at', 'disposable_token', 'reusable_token']
49     readonly_fields = fields
50     extra = 0
51     show_change_link = True
52     can_delete = False
53     show_change_link = True
54
55     def has_add_permission(self, request, obj):
56         return False
57
58
59 class PayedFilter(YesNoFilter):
60     title = 'płatność zakończona'
61     parameter_name = 'payed'
62     q = ~Q(payed_at=None)
63
64
65 class ExpiredFilter(YesNoFilter):
66     title = 'harmonogram przedawniony'
67     parameter_name = 'expired'
68     q = Q(expires_at__isnull=False, expires_at__lt=Now())
69
70
71 class ActiveFilter(YesNoFilter):
72     title = 'płatność aktualna'
73     parameter_name = 'active'
74     q = Q(expires_at__gt=Now())
75
76
77 class ScheduleForm(forms.ModelForm):
78     def __init__(self, *args, **kwargs):
79         super().__init__(*args, **kwargs)
80         self.fields['email'].required = False
81         self.fields['method'].required = False
82         self.fields['consent'].required = False
83
84     class Meta:
85         model = models.Schedule
86         fields = '__all__'
87
88
89 class SourceFilter(admin.SimpleListFilter):
90     title = 'Źródło' # display title
91     parameter_name = 'source'
92     template = "admin/long_filter.html"
93
94     def lookups(self, request, model_admin):
95         lookups = [
96             (m, m) for m in
97             model_admin.model.objects.exclude(source='').values_list('source', flat=True).distinct()[:10]
98         ]
99         return lookups
100
101     def queryset(self, request, queryset):
102         return queryset
103     
104
105 class CrisisFilter(admin.SimpleListFilter):
106     title = 'czas zbiórki kryzysowej'
107     parameter_name = 'crisis'
108
109     def lookups(self, request, model_admin):
110         lookups = [
111             (b.id, '%s — %s' % (b.since, b.until)) for b in
112             annoy.models.Banner.objects.filter(place='crisis')
113         ]
114         return lookups
115
116     def queryset(self, request, queryset):
117         bid = self.value()
118         if not bid:
119             return
120         try:
121             b = annoy.models.Banner.objects.get(id=self.value())
122         except annoy.models.Banner.DoesNotExist:
123             return
124         return queryset.filter(
125             started_at__gte=b.since,
126             started_at__lte=b.until
127         )
128
129
130
131 class ScheduleAdmin(admin.ModelAdmin):
132     form = ScheduleForm
133
134     list_display = [
135         'email', 'started_at', 'payed_at', 'expires_at', 'amount', 'monthly', 'yearly', 'is_cancelled',
136         'method'
137     ]
138     list_display_links = ['email', 'started_at']
139     search_fields = ['email', 'source']
140     list_filter = [
141         'is_cancelled', 'monthly', 'yearly', 'method',
142         PayedFilter, ActiveFilter, ExpiredFilter,
143         SourceFilter, CrisisFilter
144     ]
145     filter_horizontal = ['consent']
146     date_hierarchy = 'started_at'
147     raw_id_fields = ['membership']
148     inlines = [PayUOrderInline, PayUCardTokenInline]
149     actions = [export_as_csv_action()]
150
151 admin.site.register(models.Schedule, ScheduleAdmin)
152
153
154 class ScheduleInline(admin.TabularInline):
155     model = models.Schedule
156     fields = ['email', 'amount', 'is_cancelled', 'started_at', 'payed_at', 'expires_at', 'email_sent']
157     readonly_fields = fields
158     extra = 0
159     show_change_link = True
160     can_delete = False
161
162     def has_add_permission(self, request, obj):
163         return False
164
165
166 class MembershipAdmin(admin.ModelAdmin):
167     list_display = ['user', 'manual', 'updated_at', 'notes']
168     list_filter = ['manual']
169     date_hierarchy = 'updated_at'
170     raw_id_fields = ['user']
171     search_fields = ['user__username', 'user__email', 'schedule__email', 'notes']
172     inlines = [ScheduleInline]
173
174 admin.site.register(models.Membership, MembershipAdmin)
175
176
177 admin.site.register(models.ReminderEmail, TranslationAdmin)
178
179
180 class PayUNotificationAdmin(admin.ModelAdmin):
181     list_display = ['received_at', 'order']
182     fields = ['received_at', 'order', 'body_']
183     readonly_fields = ['received_at', 'body_']
184     raw_id_fields = ['order']
185
186     def body_(self, obj):
187         return mark_safe(
188                 "<pre>" +
189                 conditional_escape(json.dumps(json.loads(obj.body), indent=4))
190                 + "</pre>")
191
192
193 admin.site.register(models.PayUNotification, PayUNotificationAdmin)
194
195
196 class PayUNotificationInline(admin.TabularInline):
197     model = models.PayUNotification
198     fields = ['received_at', 'body_']
199     readonly_fields = fields
200     extra = 0
201     show_change_link = True
202     can_delete = False
203
204     def body_(self, obj):
205         return mark_safe(
206                 "<pre>" +
207                 conditional_escape(json.dumps(json.loads(obj.body), indent=4))
208                 + "</pre>")
209
210     def has_add_permission(self, request, obj):
211         return False
212
213
214 class PayUOrderAdmin(admin.ModelAdmin):
215     list_display = ['schedule']
216     raw_id_fields = ['schedule']
217     inlines = [PayUNotificationInline]
218
219
220 admin.site.register(models.PayUOrder, PayUOrderAdmin)
221
222
223 admin.site.register(models.Ambassador)
224
225
226     
227
228 @admin.register(models.Consent)
229 class ConsentAdmin(admin.ModelAdmin):
230     list_display = ['text', 'order', 'active', 'required']
231
232     def get_readonly_fields(self, request, obj=None):
233         if obj:
234             return ['text']
235         else:
236             return []