1
|
|
|
""" |
2
|
|
|
byceps.blueprints.admin.dashboard.views |
3
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
4
|
|
|
|
5
|
|
|
:Copyright: 2006-2021 Jochen Kupperschmidt |
6
|
|
|
:License: Revised BSD (see `LICENSE` file for details) |
7
|
|
|
""" |
8
|
|
|
|
9
|
1 |
|
from datetime import date, timedelta |
10
|
|
|
|
11
|
1 |
|
from flask import abort |
12
|
|
|
|
13
|
1 |
|
from ....services.board import board_service |
14
|
1 |
|
from ....services.brand import ( |
15
|
|
|
service as brand_service, |
16
|
|
|
settings_service as brand_settings_service, |
17
|
|
|
) |
18
|
1 |
|
from ....services.consent import subject_service as consent_subject_service |
19
|
1 |
|
from ....services.news import channel_service as news_channel_service |
20
|
1 |
|
from ....services.newsletter import service as newsletter_service |
21
|
1 |
|
from ....services.orga import birthday_service as orga_birthday_service |
22
|
1 |
|
from ....services.orga_team import service as orga_team_service |
23
|
1 |
|
from ....services.party import service as party_service |
24
|
1 |
|
from ....services.seating import ( |
25
|
|
|
area_service as seating_area_service, |
26
|
|
|
seat_service, |
27
|
|
|
) |
28
|
1 |
|
from ....services.shop.order import service as shop_order_service |
29
|
1 |
|
from ....services.shop.shop import service as shop_service |
30
|
1 |
|
from ....services.shop.storefront import service as storefront_service |
31
|
1 |
|
from ....services.site import service as site_service |
32
|
1 |
|
from ....services.ticketing import ticket_service |
33
|
1 |
|
from ....services.user import stats_service as user_stats_service |
34
|
1 |
|
from ....util.framework.blueprint import create_blueprint |
35
|
1 |
|
from ....util.framework.templating import templated |
36
|
1 |
|
from ....util.views import permission_required |
37
|
|
|
|
38
|
1 |
|
from ..brand.authorization import BrandPermission |
39
|
1 |
|
from ..core.authorization import AdminPermission |
40
|
1 |
|
from ..party.authorization import PartyPermission |
41
|
1 |
|
from ..site.authorization import SitePermission |
42
|
1 |
|
from ..user.service import get_users_created_since |
43
|
|
|
|
44
|
|
|
|
45
|
1 |
|
blueprint = create_blueprint('admin_dashboard', __name__) |
46
|
|
|
|
47
|
|
|
|
48
|
1 |
|
@blueprint.get('') |
49
|
1 |
|
@permission_required(AdminPermission.access) |
50
|
1 |
|
@templated |
51
|
|
|
def view_global(): |
52
|
|
|
"""View dashboard for global entities.""" |
53
|
1 |
|
active_brands = brand_service.get_active_brands() |
54
|
|
|
|
55
|
1 |
|
current_sites = site_service.get_current_sites(include_brands=True) |
56
|
|
|
|
57
|
1 |
|
active_parties = party_service.get_active_parties(include_brands=True) |
58
|
1 |
|
active_parties_with_ticket_stats = [ |
59
|
|
|
(party, ticket_service.get_ticket_sale_stats(party.id)) |
60
|
|
|
for party in active_parties |
61
|
|
|
] |
62
|
|
|
|
63
|
1 |
|
all_brands_by_id = {brand.id: brand for brand in brand_service.get_all_brands()} |
64
|
1 |
|
active_shops = shop_service.get_active_shops() |
65
|
1 |
|
active_shops_with_brands_and_open_orders_counts = [ |
66
|
|
|
(shop, all_brands_by_id[shop.brand_id], shop_order_service.count_open_orders(shop.id)) |
67
|
|
|
for shop in active_shops |
68
|
|
|
] |
69
|
|
|
|
70
|
1 |
|
user_count = user_stats_service.count_users() |
71
|
|
|
|
72
|
1 |
|
one_week_ago = timedelta(days=7) |
73
|
1 |
|
recent_users = get_users_created_since(one_week_ago, limit=4) |
74
|
1 |
|
recent_users_count = user_stats_service.count_users_created_since( |
75
|
|
|
one_week_ago |
76
|
|
|
) |
77
|
|
|
|
78
|
1 |
|
uninitialized_user_count = user_stats_service.count_uninitialized_users() |
79
|
|
|
|
80
|
1 |
|
orgas_with_next_birthdays = list( |
81
|
|
|
orga_birthday_service.collect_orgas_with_next_birthdays(limit=3) |
82
|
|
|
) |
83
|
|
|
|
84
|
1 |
|
return { |
85
|
|
|
'active_brands': active_brands, |
86
|
|
|
'current_sites': current_sites, |
87
|
|
|
'active_parties_with_ticket_stats': active_parties_with_ticket_stats, |
88
|
|
|
'active_shops_with_brands_and_open_orders_counts': active_shops_with_brands_and_open_orders_counts, |
89
|
|
|
|
90
|
|
|
'user_count': user_count, |
91
|
|
|
'recent_users': recent_users, |
92
|
|
|
'recent_users_count': recent_users_count, |
93
|
|
|
'uninitialized_user_count': uninitialized_user_count, |
94
|
|
|
|
95
|
|
|
'orgas_with_next_birthdays': orgas_with_next_birthdays, |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
|
99
|
1 |
|
@blueprint.get('/brands/<brand_id>') |
100
|
1 |
|
@permission_required(BrandPermission.view) |
101
|
1 |
|
@templated |
102
|
|
|
def view_brand(brand_id): |
103
|
|
|
"""View dashboard for that brand.""" |
104
|
1 |
|
brand = brand_service.find_brand(brand_id) |
105
|
1 |
|
if brand is None: |
106
|
|
|
abort(404) |
107
|
|
|
|
108
|
1 |
|
current_sites = site_service.get_current_sites( |
109
|
|
|
brand_id=brand.id, include_brands=True |
110
|
|
|
) |
111
|
|
|
|
112
|
1 |
|
active_parties = party_service.get_active_parties( |
113
|
|
|
brand_id=brand.id, include_brands=True |
114
|
|
|
) |
115
|
1 |
|
active_parties_with_ticket_stats = [ |
116
|
|
|
(party, ticket_service.get_ticket_sale_stats(party.id)) |
117
|
|
|
for party in active_parties |
118
|
|
|
] |
119
|
|
|
|
120
|
1 |
|
newsletter_list_id = brand_settings_service.find_setting_value( |
121
|
|
|
brand.id, 'newsletter_list_id' |
122
|
|
|
) |
123
|
1 |
|
newsletter_list = None |
124
|
1 |
|
if newsletter_list_id: |
125
|
|
|
newsletter_list = newsletter_service.find_list(newsletter_list_id) |
126
|
|
|
newsletter_subscriber_count = ( |
127
|
|
|
newsletter_service.count_subscribers_for_list(newsletter_list.id) |
128
|
|
|
) |
129
|
|
|
else: |
130
|
1 |
|
newsletter_subscriber_count = None |
131
|
|
|
|
132
|
1 |
|
consent_subject_ids = ( |
133
|
|
|
consent_subject_service.get_subject_ids_required_for_brand(brand.id) |
134
|
|
|
) |
135
|
1 |
|
consent_subjects_to_consent_counts = ( |
136
|
|
|
consent_subject_service.get_subjects_with_consent_counts( |
137
|
|
|
limit_to_subject_ids=consent_subject_ids |
138
|
|
|
) |
139
|
|
|
) |
140
|
1 |
|
consent_subjects_with_consent_counts = sorted( |
141
|
|
|
consent_subjects_to_consent_counts.items(), key=lambda x: x[0].title |
142
|
|
|
) |
143
|
|
|
|
144
|
1 |
|
shop = shop_service.find_shop_for_brand(brand.id) |
145
|
1 |
|
if shop is not None: |
146
|
|
|
open_order_count = shop_order_service.count_open_orders(shop.id) |
147
|
|
|
else: |
148
|
1 |
|
open_order_count = None |
149
|
|
|
|
150
|
1 |
|
return { |
151
|
|
|
'brand': brand, |
152
|
|
|
|
153
|
|
|
'current_sites': current_sites, |
154
|
|
|
'active_parties_with_ticket_stats': active_parties_with_ticket_stats, |
155
|
|
|
|
156
|
|
|
'newsletter_list': newsletter_list, |
157
|
|
|
'newsletter_subscriber_count': newsletter_subscriber_count, |
158
|
|
|
|
159
|
|
|
'consent_subjects_with_consent_counts': consent_subjects_with_consent_counts, |
160
|
|
|
|
161
|
|
|
'shop': shop, |
162
|
|
|
'open_order_count': open_order_count, |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
|
166
|
1 |
|
@blueprint.get('/parties/<party_id>') |
167
|
1 |
|
@permission_required(PartyPermission.view) |
168
|
1 |
|
@templated |
169
|
|
|
def view_party(party_id): |
170
|
|
|
"""View dashboard for that party.""" |
171
|
1 |
|
party = party_service.find_party(party_id) |
172
|
1 |
|
if party is None: |
173
|
|
|
abort(404) |
174
|
|
|
|
175
|
1 |
|
days_until_party = (party.starts_at.date() - date.today()).days |
176
|
|
|
|
177
|
1 |
|
orga_count = orga_team_service.count_memberships_for_party(party.id) |
178
|
1 |
|
orga_team_count = orga_team_service.count_teams_for_party(party.id) |
179
|
|
|
|
180
|
1 |
|
seating_area_count = seating_area_service.count_areas_for_party(party.id) |
181
|
1 |
|
seat_count = seat_service.count_seats_for_party(party.id) |
182
|
|
|
|
183
|
1 |
|
ticket_sale_stats = ticket_service.get_ticket_sale_stats(party.id) |
184
|
1 |
|
tickets_checked_in = ticket_service.count_tickets_checked_in_for_party( |
185
|
|
|
party.id |
186
|
|
|
) |
187
|
|
|
|
188
|
1 |
|
return { |
189
|
|
|
'party': party, |
190
|
|
|
'days_until_party': days_until_party, |
191
|
|
|
|
192
|
|
|
'orga_count': orga_count, |
193
|
|
|
'orga_team_count': orga_team_count, |
194
|
|
|
|
195
|
|
|
'seating_area_count': seating_area_count, |
196
|
|
|
'seat_count': seat_count, |
197
|
|
|
|
198
|
|
|
'ticket_sale_stats': ticket_sale_stats, |
199
|
|
|
'tickets_checked_in': tickets_checked_in, |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
|
203
|
1 |
|
@blueprint.get('/sites/<site_id>') |
204
|
1 |
|
@permission_required(SitePermission.view) |
205
|
1 |
|
@templated |
206
|
|
|
def view_site(site_id): |
207
|
|
|
"""View dashboard for that site.""" |
208
|
1 |
|
site = site_service.find_site(site_id) |
209
|
1 |
|
if site is None: |
210
|
|
|
abort(404) |
211
|
|
|
|
212
|
1 |
|
news_channels = news_channel_service.get_channels(site.news_channel_ids) |
213
|
|
|
|
214
|
1 |
|
if site.board_id: |
215
|
1 |
|
board = board_service.find_board(site.board_id) |
216
|
|
|
else: |
217
|
|
|
board = None |
218
|
|
|
|
219
|
1 |
|
if site.storefront_id: |
220
|
|
|
storefront = storefront_service.get_storefront(site.storefront_id) |
221
|
|
|
else: |
222
|
1 |
|
storefront = None |
223
|
|
|
|
224
|
1 |
|
return { |
225
|
|
|
'site': site, |
226
|
|
|
'news_channels': news_channels, |
227
|
|
|
'board': board, |
228
|
|
|
'storefront': storefront, |
229
|
|
|
} |
230
|
|
|
|