Completed
Push — main ( 4a0412...b71682 )
by Jochen
03:11
created

export_persons()   B

Complexity

Conditions 2

Size

Total Lines 47
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 3.8204

Importance

Changes 0
Metric Value
cc 2
eloc 37
nop 1
dl 0
loc 47
ccs 3
cts 13
cp 0.2308
crap 3.8204
rs 8.9919
c 0
b 0
f 0
1
"""
2
byceps.blueprints.admin.orga.views
3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
5
:Copyright: 2006-2020 Jochen Kupperschmidt
6
:License: Modified BSD, see LICENSE for details.
7
"""
8
9 1
from operator import attrgetter
10
11 1
from flask import abort, g, request
12
13 1
from ....services.brand import service as brand_service
14 1
from ....services.orga import service as orga_service
15 1
from ....services.orga import birthday_service as orga_birthday_service
16 1
from ....services.user import service as user_service
17 1
from ....util.export import serialize_to_csv
18 1
from ....util.framework.blueprint import create_blueprint
19 1
from ....util.framework.flash import flash_success
20 1
from ....util.framework.templating import templated
21 1
from ....util.views import redirect_to, respond_no_content, textified
22
23 1
from ...authorization.decorators import permission_required
24 1
from ...authorization.registry import permission_registry
25
26 1
from ..orga_team.authorization import OrgaTeamPermission
27
28 1
from .authorization import OrgaBirthdayPermission, OrgaDetailPermission
29 1
from .forms import OrgaFlagCreateForm
30
31
32 1
blueprint = create_blueprint('orga_admin', __name__)
33
34
35 1
permission_registry.register_enum(OrgaBirthdayPermission)
36 1
permission_registry.register_enum(OrgaDetailPermission)
37 1
permission_registry.register_enum(OrgaTeamPermission)
38
39
40 1
@blueprint.route('/persons')
41 1
@permission_required(OrgaDetailPermission.view)
42 1
@templated
43
def persons():
44
    """List brands to choose from."""
45
    brands_with_person_counts = orga_service.get_brands_with_person_counts()
46
47
    return {
48
        'brands_with_person_counts': brands_with_person_counts,
49
    }
50
51
52 1
@blueprint.route('/persons/<brand_id>')
53 1
@permission_required(OrgaDetailPermission.view)
54 1
@templated
55
def persons_for_brand(brand_id):
56
    """List organizers for the brand with details."""
57
    brand = _get_brand_or_404(brand_id)
58
59
    orgas = orga_service.get_orgas_for_brand(brand.id)
60
    orgas.sort(key=user_service.get_sort_key_for_screen_name)
61
62
    return {
63
        'brand': brand,
64
        'orgas': orgas,
65
    }
66
67
68 1
@blueprint.route('/persons/<brand_id>/create')
69 1
@permission_required(OrgaTeamPermission.administrate_memberships)
70 1
@templated
71 1
def create_orgaflag_form(brand_id, erroneous_form=None):
72
    """Show form to give the organizer flag to a user."""
73
    brand = _get_brand_or_404(brand_id)
74
75
    form = erroneous_form if erroneous_form else OrgaFlagCreateForm()
76
77
    return {
78
        'brand': brand,
79
        'form': form,
80
    }
81
82
83 1
@blueprint.route('/persons/<brand_id>', methods=['POST'])
84 1
@permission_required(OrgaTeamPermission.administrate_memberships)
85
def create_orgaflag(brand_id):
86
    """Give the organizer flag to a user."""
87
    brand = _get_brand_or_404(brand_id)
88
89
    form = OrgaFlagCreateForm(request.form, brand_id=brand.id)
90
    if not form.validate():
91
        return create_orgaflag_form(brand.id, form)
92
93
    user = form.user.data
94
    initiator = g.current_user
95
96
    orga_flag = orga_service.add_orga_flag(brand.id, user.id, initiator.id)
97
98
    flash_success(
99
        f'{orga_flag.user.screen_name} wurde das Orga-Flag '
100
        f'für die Marke {orga_flag.brand.title} gegeben.'
101
    )
102
    return redirect_to('.persons_for_brand', brand_id=orga_flag.brand.id)
103
104
105 1
@blueprint.route('/persons/<brand_id>/<uuid:user_id>', methods=['DELETE'])
106 1
@permission_required(OrgaTeamPermission.administrate_memberships)
107 1
@respond_no_content
108
def remove_orgaflag(brand_id, user_id):
109
    """Remove the organizer flag for a brand from a person."""
110
    orga_flag = orga_service.find_orga_flag(brand_id, user_id)
111
112
    if orga_flag is None:
113
        abort(404)
114
115
    brand = orga_flag.brand
116
    user = orga_flag.user
117
    initiator = g.current_user
118
119
    orga_service.remove_orga_flag(orga_flag, initiator.id)
120
121
    flash_success(
122
        f'{user.screen_name} wurde das Orga-Flag '
123
        f'für die Marke {brand.title} entzogen.'
124
    )
125
126
127 1
@blueprint.route('/persons/<brand_id>/export')
128 1
@permission_required(OrgaDetailPermission.view)
129 1
@textified
130
def export_persons(brand_id):
131
    """Export the list of organizers for the brand as a CSV document in
132
    Microsoft Excel dialect.
133
    """
134
    brand = _get_brand_or_404(brand_id)
135
136
    field_names = [
137
        'Benutzername',
138
        'Vorname',
139
        'Nachname',
140
        'Geburtstag',
141
        'Straße',
142
        'PLZ',
143
        'Ort',
144
        'Land',
145
        'E-Mail-Adresse',
146
        'Telefonnummer',
147
    ]
148
149
    def to_dict(user):
150
        date_of_birth = (
151
            user.detail.date_of_birth.strftime('%d.%m.%Y')
152
            if user.detail.date_of_birth
153
            else None
154
        )
155
156
        return {
157
            'Benutzername': user.screen_name,
158
            'Vorname': user.detail.first_names,
159
            'Nachname': user.detail.last_name,
160
            'Geburtstag': date_of_birth,
161
            'Straße': user.detail.street,
162
            'PLZ': user.detail.zip_code,
163
            'Ort': user.detail.city,
164
            'Land': user.detail.country,
165
            'E-Mail-Adresse': user.email_address,
166
            'Telefonnummer': user.detail.phone_number,
167
        }
168
169
    orgas = orga_service.get_orgas_for_brand(brand.id)
170
    orgas = [orga for orga in orgas if not orga.deleted]
171
    orgas.sort(key=user_service.get_sort_key_for_screen_name)
172
    rows = map(to_dict, orgas)
173
    return serialize_to_csv(field_names, rows)
174
175
176 1
@blueprint.route('/birthdays')
177 1
@permission_required(OrgaBirthdayPermission.view)
178 1
@templated
179
def birthdays():
180
    orgas = list(
181
        orga_birthday_service.collect_orgas_with_next_birthdays(limit=5)
182
    )
183
184
    return {
185
        'orgas': orgas,
186
    }
187
188
189 1
def _get_brand_or_404(brand_id):
190
    brand = brand_service.find_brand(brand_id)
191
192
    if brand is None:
193
        abort(404)
194
195
    return brand
196